diff options
37 files changed, 10317 insertions, 16154 deletions
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index fb32aead5a0b..bd6fee22c4dd 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl | |||
@@ -871,9 +871,8 @@ | |||
871 | <para> | 871 | <para> |
872 | This function itself doesn't allocate the data space. The data | 872 | This function itself doesn't allocate the data space. The data |
873 | must be allocated manually beforehand, and its pointer is passed | 873 | must be allocated manually beforehand, and its pointer is passed |
874 | as the argument. This pointer is used as the | 874 | as the argument. This pointer (<parameter>chip</parameter> in the |
875 | (<parameter>chip</parameter> identifier in the above example) | 875 | above example) is used as the identifier for the instance. |
876 | for the instance. | ||
877 | </para> | 876 | </para> |
878 | 877 | ||
879 | <para> | 878 | <para> |
@@ -2304,7 +2303,7 @@ struct _snd_pcm_runtime { | |||
2304 | <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you | 2303 | <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you |
2305 | have to specify whether the mmap is supported and which | 2304 | have to specify whether the mmap is supported and which |
2306 | interleaved format is supported. | 2305 | interleaved format is supported. |
2307 | When the is supported, add the | 2306 | When the hardware supports mmap, add the |
2308 | <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the | 2307 | <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the |
2309 | hardware supports the interleaved or the non-interleaved | 2308 | hardware supports the interleaved or the non-interleaved |
2310 | formats, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or | 2309 | formats, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or |
@@ -2898,7 +2897,7 @@ struct _snd_pcm_runtime { | |||
2898 | 2897 | ||
2899 | <para> | 2898 | <para> |
2900 | When the pcm supports the pause operation (given in the info | 2899 | When the pcm supports the pause operation (given in the info |
2901 | field of the hardware table), the <constant>PAUSE_PUSE</constant> | 2900 | field of the hardware table), the <constant>PAUSE_PUSH</constant> |
2902 | and <constant>PAUSE_RELEASE</constant> commands must be | 2901 | and <constant>PAUSE_RELEASE</constant> commands must be |
2903 | handled here, too. The former is the command to pause the pcm, | 2902 | handled here, too. The former is the command to pause the pcm, |
2904 | and the latter to restart the pcm again. | 2903 | and the latter to restart the pcm again. |
@@ -3085,7 +3084,7 @@ struct _snd_pcm_runtime { | |||
3085 | <section id="pcm-interface-interrupt-handler-timer"> | 3084 | <section id="pcm-interface-interrupt-handler-timer"> |
3086 | <title>High frequency timer interrupts</title> | 3085 | <title>High frequency timer interrupts</title> |
3087 | <para> | 3086 | <para> |
3088 | This happense when the hardware doesn't generate interrupts | 3087 | This happens when the hardware doesn't generate interrupts |
3089 | at the period boundary but issues timer interrupts at a fixed | 3088 | at the period boundary but issues timer interrupts at a fixed |
3090 | timer rate (e.g. es1968 or ymfpci drivers). | 3089 | timer rate (e.g. es1968 or ymfpci drivers). |
3091 | In this case, you need to check the current hardware | 3090 | In this case, you need to check the current hardware |
@@ -3251,18 +3250,19 @@ struct _snd_pcm_runtime { | |||
3251 | <title>Example of Hardware Constraints for Channels</title> | 3250 | <title>Example of Hardware Constraints for Channels</title> |
3252 | <programlisting> | 3251 | <programlisting> |
3253 | <![CDATA[ | 3252 | <![CDATA[ |
3254 | static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params, | 3253 | static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params, |
3255 | struct snd_pcm_hw_rule *rule) | 3254 | struct snd_pcm_hw_rule *rule) |
3256 | { | 3255 | { |
3257 | struct snd_interval *c = hw_param_interval(params, | 3256 | struct snd_interval *c = hw_param_interval(params, |
3258 | SNDRV_PCM_HW_PARAM_CHANNELS); | 3257 | SNDRV_PCM_HW_PARAM_CHANNELS); |
3259 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 3258 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
3260 | struct snd_mask fmt; | 3259 | struct snd_interval ch; |
3261 | 3260 | ||
3262 | snd_mask_any(&fmt); /* Init the struct */ | 3261 | snd_interval_any(&ch); |
3263 | if (c->min < 2) { | 3262 | if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) { |
3264 | fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE; | 3263 | ch.min = ch.max = 1; |
3265 | return snd_mask_refine(f, &fmt); | 3264 | ch.integer = 1; |
3265 | return snd_interval_refine(c, &ch); | ||
3266 | } | 3266 | } |
3267 | return 0; | 3267 | return 0; |
3268 | } | 3268 | } |
@@ -3278,35 +3278,35 @@ struct _snd_pcm_runtime { | |||
3278 | <programlisting> | 3278 | <programlisting> |
3279 | <![CDATA[ | 3279 | <![CDATA[ |
3280 | snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 3280 | snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
3281 | hw_rule_channels_by_format, 0, SNDRV_PCM_HW_PARAM_FORMAT, | 3281 | hw_rule_channels_by_format, NULL, |
3282 | -1); | 3282 | SNDRV_PCM_HW_PARAM_FORMAT, -1); |
3283 | ]]> | 3283 | ]]> |
3284 | </programlisting> | 3284 | </programlisting> |
3285 | </informalexample> | 3285 | </informalexample> |
3286 | </para> | 3286 | </para> |
3287 | 3287 | ||
3288 | <para> | 3288 | <para> |
3289 | The rule function is called when an application sets the number of | 3289 | The rule function is called when an application sets the PCM |
3290 | channels. But an application can set the format before the number of | 3290 | format, and it refines the number of channels accordingly. |
3291 | channels. Thus you also need to define the inverse rule: | 3291 | But an application may set the number of channels before |
3292 | setting the format. Thus you also need to define the inverse rule: | ||
3292 | 3293 | ||
3293 | <example> | 3294 | <example> |
3294 | <title>Example of Hardware Constraints for Channels</title> | 3295 | <title>Example of Hardware Constraints for Formats</title> |
3295 | <programlisting> | 3296 | <programlisting> |
3296 | <![CDATA[ | 3297 | <![CDATA[ |
3297 | static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params, | 3298 | static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params, |
3298 | struct snd_pcm_hw_rule *rule) | 3299 | struct snd_pcm_hw_rule *rule) |
3299 | { | 3300 | { |
3300 | struct snd_interval *c = hw_param_interval(params, | 3301 | struct snd_interval *c = hw_param_interval(params, |
3301 | SNDRV_PCM_HW_PARAM_CHANNELS); | 3302 | SNDRV_PCM_HW_PARAM_CHANNELS); |
3302 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 3303 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
3303 | struct snd_interval ch; | 3304 | struct snd_mask fmt; |
3304 | 3305 | ||
3305 | snd_interval_any(&ch); | 3306 | snd_mask_any(&fmt); /* Init the struct */ |
3306 | if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) { | 3307 | if (c->min < 2) { |
3307 | ch.min = ch.max = 1; | 3308 | fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE; |
3308 | ch.integer = 1; | 3309 | return snd_mask_refine(f, &fmt); |
3309 | return snd_interval_refine(c, &ch); | ||
3310 | } | 3310 | } |
3311 | return 0; | 3311 | return 0; |
3312 | } | 3312 | } |
@@ -3321,8 +3321,8 @@ struct _snd_pcm_runtime { | |||
3321 | <programlisting> | 3321 | <programlisting> |
3322 | <![CDATA[ | 3322 | <![CDATA[ |
3323 | snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, | 3323 | snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, |
3324 | hw_rule_format_by_channels, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 3324 | hw_rule_format_by_channels, NULL, |
3325 | -1); | 3325 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
3326 | ]]> | 3326 | ]]> |
3327 | </programlisting> | 3327 | </programlisting> |
3328 | </informalexample> | 3328 | </informalexample> |
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index b9cfd339a6fa..ce6581c8ca26 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -890,8 +890,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
890 | enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) | 890 | enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) |
891 | power_save - Automatic power-saving timeout (in second, 0 = | 891 | power_save - Automatic power-saving timeout (in second, 0 = |
892 | disable) | 892 | disable) |
893 | power_save_controller - Reset HD-audio controller in power-saving mode | 893 | power_save_controller - Support runtime D3 of HD-audio controller |
894 | (default = on) | 894 | (-1 = on for supported chip (default), false = off, |
895 | true = force to on even for unsupported hardware) | ||
895 | align_buffer_size - Force rounding of buffer/period sizes to multiples | 896 | align_buffer_size - Force rounding of buffer/period sizes to multiples |
896 | of 128 bytes. This is more efficient in terms of memory | 897 | of 128 bytes. This is more efficient in terms of memory |
897 | access but isn't required by the HDA spec and prevents | 898 | access but isn't required by the HDA spec and prevents |
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt index 7813c06a5c71..d4faa63ff352 100644 --- a/Documentation/sound/alsa/HD-Audio.txt +++ b/Documentation/sound/alsa/HD-Audio.txt | |||
@@ -176,14 +176,14 @@ support the automatic probing (yet as of 2.6.28). And, BIOS is often, | |||
176 | yes, pretty often broken. It sets up wrong values and screws up the | 176 | yes, pretty often broken. It sets up wrong values and screws up the |
177 | driver. | 177 | driver. |
178 | 178 | ||
179 | The preset model is provided basically to overcome such a situation. | 179 | The preset model (or recently called as "fix-up") is provided |
180 | When the matching preset model is found in the white-list, the driver | 180 | basically to overcome such a situation. When the matching preset |
181 | assumes the static configuration of that preset and builds the mixer | 181 | model is found in the white-list, the driver assumes the static |
182 | elements and PCM streams based on the static information. Thus, if | 182 | configuration of that preset with the correct pin setup, etc. |
183 | you have a newer machine with a slightly different PCI SSID from the | 183 | Thus, if you have a newer machine with a slightly different PCI SSID |
184 | existing one, you may have a good chance to re-use the same model. | 184 | (or codec SSID) from the existing one, you may have a good chance to |
185 | You can pass the `model` option to specify the preset model instead of | 185 | re-use the same model. You can pass the `model` option to specify the |
186 | PCI SSID look-up. | 186 | preset model instead of PCI (and codec-) SSID look-up. |
187 | 187 | ||
188 | What `model` option values are available depends on the codec chip. | 188 | What `model` option values are available depends on the codec chip. |
189 | Check your codec chip from the codec proc file (see "Codec Proc-File" | 189 | Check your codec chip from the codec proc file (see "Codec Proc-File" |
@@ -199,17 +199,12 @@ non-working HD-audio hardware is to check HD-audio codec and several | |||
199 | different `model` option values. If you have any luck, some of them | 199 | different `model` option values. If you have any luck, some of them |
200 | might suit with your device well. | 200 | might suit with your device well. |
201 | 201 | ||
202 | Some codecs such as ALC880 have a special model option `model=test`. | 202 | There are a few special model option values: |
203 | This configures the driver to provide as many mixer controls as | 203 | - when 'nofixup' is passed, the device-specific fixups in the codec |
204 | possible for every single pin feature except for the unsolicited | 204 | parser are skipped. |
205 | events (and maybe some other specials). Adjust each mixer element and | 205 | - when `generic` is passed, the codec-specific parser is skipped and |
206 | try the I/O in the way of trial-and-error until figuring out the whole | 206 | only the generic parser is used. |
207 | I/O pin mappings. | ||
208 | 207 | ||
209 | Note that `model=generic` has a special meaning. It means to use the | ||
210 | generic parser regardless of the codec. Usually the codec-specific | ||
211 | parser is much better than the generic parser (as now). Thus this | ||
212 | option is more about the debugging purpose. | ||
213 | 208 | ||
214 | Speaker and Headphone Output | 209 | Speaker and Headphone Output |
215 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 210 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
@@ -387,9 +382,8 @@ init_verbs:: | |||
387 | (separated with a space). | 382 | (separated with a space). |
388 | hints:: | 383 | hints:: |
389 | Shows / stores hint strings for codec parsers for any use. | 384 | Shows / stores hint strings for codec parsers for any use. |
390 | Its format is `key = value`. For example, passing `hp_detect = yes` | 385 | Its format is `key = value`. For example, passing `jack_detect = no` |
391 | to IDT/STAC codec parser will result in the disablement of the | 386 | will disable the jack detection of the machine completely. |
392 | headphone detection. | ||
393 | init_pin_configs:: | 387 | init_pin_configs:: |
394 | Shows the initial pin default config values set by BIOS. | 388 | Shows the initial pin default config values set by BIOS. |
395 | driver_pin_configs:: | 389 | driver_pin_configs:: |
@@ -421,6 +415,61 @@ re-configure based on that state, run like below: | |||
421 | ------------------------------------------------------------------------ | 415 | ------------------------------------------------------------------------ |
422 | 416 | ||
423 | 417 | ||
418 | Hint Strings | ||
419 | ~~~~~~~~~~~~ | ||
420 | The codec parser have several switches and adjustment knobs for | ||
421 | matching better with the actual codec or device behavior. Many of | ||
422 | them can be adjusted dynamically via "hints" strings as mentioned in | ||
423 | the section above. For example, by passing `jack_detect = no` string | ||
424 | via sysfs or a patch file, you can disable the jack detection, thus | ||
425 | the codec parser will skip the features like auto-mute or mic | ||
426 | auto-switch. As a boolean value, either `yes`, `no`, `true`, `false`, | ||
427 | `1` or `0` can be passed. | ||
428 | |||
429 | The generic parser supports the following hints: | ||
430 | |||
431 | - jack_detect (bool): specify whether the jack detection is available | ||
432 | at all on this machine; default true | ||
433 | - inv_jack_detect (bool): indicates that the jack detection logic is | ||
434 | inverted | ||
435 | - trigger_sense (bool): indicates that the jack detection needs the | ||
436 | explicit call of AC_VERB_SET_PIN_SENSE verb | ||
437 | - inv_eapd (bool): indicates that the EAPD is implemented in the | ||
438 | inverted logic | ||
439 | - pcm_format_first (bool): sets the PCM format before the stream tag | ||
440 | and channel ID | ||
441 | - sticky_stream (bool): keep the PCM format, stream tag and ID as long | ||
442 | as possible; default true | ||
443 | - spdif_status_reset (bool): reset the SPDIF status bits at each time | ||
444 | the SPDIF stream is set up | ||
445 | - pin_amp_workaround (bool): the output pin may have multiple amp | ||
446 | values | ||
447 | - single_adc_amp (bool): ADCs can have only single input amps | ||
448 | - auto_mute (bool): enable/disable the headphone auto-mute feature; | ||
449 | default true | ||
450 | - auto_mic (bool): enable/disable the mic auto-switch feature; default | ||
451 | true | ||
452 | - line_in_auto_switch (bool): enable/disable the line-in auto-switch | ||
453 | feature; default false | ||
454 | - need_dac_fix (bool): limits the DACs depending on the channel count | ||
455 | - primary_hp (bool): probe headphone jacks as the primary outputs; | ||
456 | default true | ||
457 | - multi_cap_vol (bool): provide multiple capture volumes | ||
458 | - inv_dmic_split (bool): provide split internal mic volume/switch for | ||
459 | phase-inverted digital mics | ||
460 | - indep_hp (bool): provide the independent headphone PCM stream and | ||
461 | the corresponding mixer control, if available | ||
462 | - add_stereo_mix_input (bool): add the stereo mix (analog-loopback | ||
463 | mix) to the input mux if available | ||
464 | - add_out_jack_modes (bool): add "xxx Jack Mode" enum controls to each | ||
465 | output jack for allowing to change the headphone amp capability | ||
466 | - add_in_jack_modes (bool): add "xxx Jack Mode" enum controls to each | ||
467 | input jack for allowing to change the mic bias vref | ||
468 | - power_down_unused (bool): power down the unused widgets | ||
469 | - mixer_nid (int): specifies the widget NID of the analog-loopback | ||
470 | mixer | ||
471 | |||
472 | |||
424 | Early Patching | 473 | Early Patching |
425 | ~~~~~~~~~~~~~~ | 474 | ~~~~~~~~~~~~~~ |
426 | When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a | 475 | When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a |
@@ -445,7 +494,7 @@ A patch file is a plain text file which looks like below: | |||
445 | 0x20 0x400 0xff | 494 | 0x20 0x400 0xff |
446 | 495 | ||
447 | [hint] | 496 | [hint] |
448 | hp_detect = yes | 497 | jack_detect = no |
449 | ------------------------------------------------------------------------ | 498 | ------------------------------------------------------------------------ |
450 | 499 | ||
451 | The file needs to have a line `[codec]`. The next line should contain | 500 | The file needs to have a line `[codec]`. The next line should contain |
@@ -531,6 +580,13 @@ cable is unplugged. Thus, if you hear noises, suspect first the | |||
531 | power-saving. See /sys/module/snd_hda_intel/parameters/power_save to | 580 | power-saving. See /sys/module/snd_hda_intel/parameters/power_save to |
532 | check the current value. If it's non-zero, the feature is turned on. | 581 | check the current value. If it's non-zero, the feature is turned on. |
533 | 582 | ||
583 | The recent kernel supports the runtime PM for the HD-audio controller | ||
584 | chip, too. It means that the HD-audio controller is also powered up / | ||
585 | down dynamically. The feature is enabled only for certain controller | ||
586 | chips like Intel LynxPoint. You can enable/disable this feature | ||
587 | forcibly by setting `power_save_controller` option, which is also | ||
588 | available at /sys/module/snd_hda_intel/parameters directory. | ||
589 | |||
534 | 590 | ||
535 | Tracepoints | 591 | Tracepoints |
536 | ~~~~~~~~~~~ | 592 | ~~~~~~~~~~~ |
@@ -587,8 +643,9 @@ The latest development codes for HD-audio are found on sound git tree: | |||
587 | - git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 643 | - git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
588 | 644 | ||
589 | The master branch or for-next branches can be used as the main | 645 | The master branch or for-next branches can be used as the main |
590 | development branches in general while the HD-audio specific patches | 646 | development branches in general while the development for the current |
591 | are committed in topic/hda branch. | 647 | and next kernels are found in for-linus and for-next branches, |
648 | respectively. | ||
592 | 649 | ||
593 | If you are using the latest Linus tree, it'd be better to pull the | 650 | If you are using the latest Linus tree, it'd be better to pull the |
594 | above GIT tree onto it. If you are using the older kernels, an easy | 651 | above GIT tree onto it. If you are using the older kernels, an easy |
@@ -699,7 +756,11 @@ won't be always updated. For example, the volume values are usually | |||
699 | cached in the driver, and thus changing the widget amp value directly | 756 | cached in the driver, and thus changing the widget amp value directly |
700 | via hda-verb won't change the mixer value. | 757 | via hda-verb won't change the mixer value. |
701 | 758 | ||
702 | The hda-verb program is found in the ftp directory: | 759 | The hda-verb program is included now in alsa-tools: |
760 | |||
761 | - git://git.alsa-project.org/alsa-tools.git | ||
762 | |||
763 | Also, the old stand-alone package is found in the ftp directory: | ||
703 | 764 | ||
704 | - ftp://ftp.suse.com/pub/people/tiwai/misc/ | 765 | - ftp://ftp.suse.com/pub/people/tiwai/misc/ |
705 | 766 | ||
@@ -777,3 +838,18 @@ A git repository is available: | |||
777 | 838 | ||
778 | See README file in the tarball for more details about hda-emu | 839 | See README file in the tarball for more details about hda-emu |
779 | program. | 840 | program. |
841 | |||
842 | |||
843 | hda-jack-retask | ||
844 | ~~~~~~~~~~~~~~~ | ||
845 | hda-jack-retask is a user-friendly GUI program to manipulate the | ||
846 | HD-audio pin control for jack retasking. If you have a problem about | ||
847 | the jack assignment, try this program and check whether you can get | ||
848 | useful results. Once when you figure out the proper pin assignment, | ||
849 | it can be fixed either in the driver code statically or via passing a | ||
850 | firmware patch file (see "Early Patching" section). | ||
851 | |||
852 | The program is included in alsa-tools now: | ||
853 | |||
854 | - git://git.alsa-project.org/alsa-tools.git | ||
855 | |||
diff --git a/include/sound/core.h b/include/sound/core.h index 93896ad1fcdd..7cede2d6aa86 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -394,8 +394,11 @@ void __snd_printk(unsigned int level, const char *file, int line, | |||
394 | 394 | ||
395 | #else /* !CONFIG_SND_DEBUG */ | 395 | #else /* !CONFIG_SND_DEBUG */ |
396 | 396 | ||
397 | #define snd_printd(fmt, args...) do { } while (0) | 397 | __printf(1, 2) |
398 | #define _snd_printd(level, fmt, args...) do { } while (0) | 398 | static inline void snd_printd(const char *format, ...) {} |
399 | __printf(2, 3) | ||
400 | static inline void _snd_printd(int level, const char *format, ...) {} | ||
401 | |||
399 | #define snd_BUG() do { } while (0) | 402 | #define snd_BUG() do { } while (0) |
400 | static inline int __snd_bug_on(int cond) | 403 | static inline int __snd_bug_on(int cond) |
401 | { | 404 | { |
@@ -416,7 +419,8 @@ static inline int __snd_bug_on(int cond) | |||
416 | #define snd_printdd(format, args...) \ | 419 | #define snd_printdd(format, args...) \ |
417 | __snd_printk(2, __FILE__, __LINE__, format, ##args) | 420 | __snd_printk(2, __FILE__, __LINE__, format, ##args) |
418 | #else | 421 | #else |
419 | #define snd_printdd(format, args...) do { } while (0) | 422 | __printf(1, 2) |
423 | static inline void snd_printdd(const char *format, ...) {} | ||
420 | #endif | 424 | #endif |
421 | 425 | ||
422 | 426 | ||
@@ -454,6 +458,7 @@ struct snd_pci_quirk { | |||
454 | #define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val) \ | 458 | #define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val) \ |
455 | {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), \ | 459 | {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), \ |
456 | .value = (val), .name = (xname)} | 460 | .value = (val), .name = (xname)} |
461 | #define snd_pci_quirk_name(q) ((q)->name) | ||
457 | #else | 462 | #else |
458 | #define SND_PCI_QUIRK(vend,dev,xname,val) \ | 463 | #define SND_PCI_QUIRK(vend,dev,xname,val) \ |
459 | {_SND_PCI_QUIRK_ID(vend, dev), .value = (val)} | 464 | {_SND_PCI_QUIRK_ID(vend, dev), .value = (val)} |
@@ -461,6 +466,7 @@ struct snd_pci_quirk { | |||
461 | {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), .value = (val)} | 466 | {_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), .value = (val)} |
462 | #define SND_PCI_QUIRK_VENDOR(vend, xname, val) \ | 467 | #define SND_PCI_QUIRK_VENDOR(vend, xname, val) \ |
463 | {_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val)} | 468 | {_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val)} |
469 | #define snd_pci_quirk_name(q) "" | ||
464 | #endif | 470 | #endif |
465 | 471 | ||
466 | const struct snd_pci_quirk * | 472 | const struct snd_pci_quirk * |
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h index 844af65af626..cf15b8213df7 100644 --- a/include/sound/memalloc.h +++ b/include/sound/memalloc.h | |||
@@ -37,7 +37,7 @@ struct snd_dma_device { | |||
37 | #ifndef snd_dma_pci_data | 37 | #ifndef snd_dma_pci_data |
38 | #define snd_dma_pci_data(pci) (&(pci)->dev) | 38 | #define snd_dma_pci_data(pci) (&(pci)->dev) |
39 | #define snd_dma_isa_data() NULL | 39 | #define snd_dma_isa_data() NULL |
40 | #define snd_dma_continuous_data(x) ((struct device *)(unsigned long)(x)) | 40 | #define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x)) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | 43 | ||
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index de5055a3b0d0..c39961c11401 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c | |||
@@ -52,7 +52,6 @@ MODULE_LICENSE("GPL"); | |||
52 | int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time) | 52 | int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time) |
53 | { | 53 | { |
54 | unsigned long end_time = jiffies + (time * HZ + 999) / 1000; | 54 | unsigned long end_time = jiffies + (time * HZ + 999) / 1000; |
55 | #ifdef CONFIG_SND_DEBUG | ||
56 | static char *reg_names[VX_REG_MAX] = { | 55 | static char *reg_names[VX_REG_MAX] = { |
57 | "ICR", "CVR", "ISR", "IVR", "RXH", "RXM", "RXL", | 56 | "ICR", "CVR", "ISR", "IVR", "RXH", "RXM", "RXL", |
58 | "DMA", "CDSP", "RFREQ", "RUER/V2", "DATA", "MEMIRQ", | 57 | "DMA", "CDSP", "RFREQ", "RUER/V2", "DATA", "MEMIRQ", |
@@ -60,7 +59,7 @@ int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int t | |||
60 | "MIC3", "INTCSR", "CNTRL", "GPIOC", | 59 | "MIC3", "INTCSR", "CNTRL", "GPIOC", |
61 | "LOFREQ", "HIFREQ", "CSUER", "RUER" | 60 | "LOFREQ", "HIFREQ", "CSUER", "RUER" |
62 | }; | 61 | }; |
63 | #endif | 62 | |
64 | do { | 63 | do { |
65 | if ((snd_vx_inb(chip, reg) & mask) == bit) | 64 | if ((snd_vx_inb(chip, reg) & mask) == bit) |
66 | return 0; | 65 | return 0; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index a67743183aaf..6e78c6789858 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -567,8 +567,9 @@ static int ac97_probing_bugs(struct pci_dev *pci) | |||
567 | 567 | ||
568 | q = snd_pci_quirk_lookup(pci, atiixp_quirks); | 568 | q = snd_pci_quirk_lookup(pci, atiixp_quirks); |
569 | if (q) { | 569 | if (q) { |
570 | snd_printdd(KERN_INFO "Atiixp quirk for %s. " | 570 | snd_printdd(KERN_INFO |
571 | "Forcing codec %d\n", q->name, q->value); | 571 | "Atiixp quirk for %s. Forcing codec %d\n", |
572 | snd_pci_quirk_name(q), q->value); | ||
572 | return q->value; | 573 | return q->value; |
573 | } | 574 | } |
574 | /* this hardware doesn't need workarounds. Probe for codec */ | 575 | /* this hardware doesn't need workarounds. Probe for codec */ |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 6eeb8897624b..4466bf63d6bf 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -86,6 +86,7 @@ config SND_HDA_PATCH_LOADER | |||
86 | config SND_HDA_CODEC_REALTEK | 86 | config SND_HDA_CODEC_REALTEK |
87 | bool "Build Realtek HD-audio codec support" | 87 | bool "Build Realtek HD-audio codec support" |
88 | default y | 88 | default y |
89 | select SND_HDA_GENERIC | ||
89 | help | 90 | help |
90 | Say Y here to include Realtek HD-audio codec support in | 91 | Say Y here to include Realtek HD-audio codec support in |
91 | snd-hda-intel driver, such as ALC880. | 92 | snd-hda-intel driver, such as ALC880. |
@@ -98,6 +99,7 @@ config SND_HDA_CODEC_REALTEK | |||
98 | config SND_HDA_CODEC_ANALOG | 99 | config SND_HDA_CODEC_ANALOG |
99 | bool "Build Analog Device HD-audio codec support" | 100 | bool "Build Analog Device HD-audio codec support" |
100 | default y | 101 | default y |
102 | select SND_HDA_GENERIC | ||
101 | help | 103 | help |
102 | Say Y here to include Analog Device HD-audio codec support in | 104 | Say Y here to include Analog Device HD-audio codec support in |
103 | snd-hda-intel driver, such as AD1986A. | 105 | snd-hda-intel driver, such as AD1986A. |
@@ -110,6 +112,7 @@ config SND_HDA_CODEC_ANALOG | |||
110 | config SND_HDA_CODEC_SIGMATEL | 112 | config SND_HDA_CODEC_SIGMATEL |
111 | bool "Build IDT/Sigmatel HD-audio codec support" | 113 | bool "Build IDT/Sigmatel HD-audio codec support" |
112 | default y | 114 | default y |
115 | select SND_HDA_GENERIC | ||
113 | help | 116 | help |
114 | Say Y here to include IDT (Sigmatel) HD-audio codec support in | 117 | Say Y here to include IDT (Sigmatel) HD-audio codec support in |
115 | snd-hda-intel driver, such as STAC9200. | 118 | snd-hda-intel driver, such as STAC9200. |
@@ -122,6 +125,7 @@ config SND_HDA_CODEC_SIGMATEL | |||
122 | config SND_HDA_CODEC_VIA | 125 | config SND_HDA_CODEC_VIA |
123 | bool "Build VIA HD-audio codec support" | 126 | bool "Build VIA HD-audio codec support" |
124 | default y | 127 | default y |
128 | select SND_HDA_GENERIC | ||
125 | help | 129 | help |
126 | Say Y here to include VIA HD-audio codec support in | 130 | Say Y here to include VIA HD-audio codec support in |
127 | snd-hda-intel driver, such as VT1708. | 131 | snd-hda-intel driver, such as VT1708. |
@@ -147,8 +151,8 @@ config SND_HDA_CODEC_HDMI | |||
147 | 151 | ||
148 | config SND_HDA_CODEC_CIRRUS | 152 | config SND_HDA_CODEC_CIRRUS |
149 | bool "Build Cirrus Logic codec support" | 153 | bool "Build Cirrus Logic codec support" |
150 | depends on SND_HDA_INTEL | ||
151 | default y | 154 | default y |
155 | select SND_HDA_GENERIC | ||
152 | help | 156 | help |
153 | Say Y here to include Cirrus Logic codec support in | 157 | Say Y here to include Cirrus Logic codec support in |
154 | snd-hda-intel driver, such as CS4206. | 158 | snd-hda-intel driver, such as CS4206. |
@@ -161,6 +165,7 @@ config SND_HDA_CODEC_CIRRUS | |||
161 | config SND_HDA_CODEC_CONEXANT | 165 | config SND_HDA_CODEC_CONEXANT |
162 | bool "Build Conexant HD-audio codec support" | 166 | bool "Build Conexant HD-audio codec support" |
163 | default y | 167 | default y |
168 | select SND_HDA_GENERIC | ||
164 | help | 169 | help |
165 | Say Y here to include Conexant HD-audio codec support in | 170 | Say Y here to include Conexant HD-audio codec support in |
166 | snd-hda-intel driver, such as CX20549. | 171 | snd-hda-intel driver, such as CX20549. |
@@ -172,8 +177,8 @@ config SND_HDA_CODEC_CONEXANT | |||
172 | 177 | ||
173 | config SND_HDA_CODEC_CA0110 | 178 | config SND_HDA_CODEC_CA0110 |
174 | bool "Build Creative CA0110-IBG codec support" | 179 | bool "Build Creative CA0110-IBG codec support" |
175 | depends on SND_HDA_INTEL | ||
176 | default y | 180 | default y |
181 | select SND_HDA_GENERIC | ||
177 | help | 182 | help |
178 | Say Y here to include Creative CA0110-IBG codec support in | 183 | Say Y here to include Creative CA0110-IBG codec support in |
179 | snd-hda-intel driver, found on some Creative X-Fi cards. | 184 | snd-hda-intel driver, found on some Creative X-Fi cards. |
@@ -185,7 +190,6 @@ config SND_HDA_CODEC_CA0110 | |||
185 | 190 | ||
186 | config SND_HDA_CODEC_CA0132 | 191 | config SND_HDA_CODEC_CA0132 |
187 | bool "Build Creative CA0132 codec support" | 192 | bool "Build Creative CA0132 codec support" |
188 | depends on SND_HDA_INTEL | ||
189 | default y | 193 | default y |
190 | help | 194 | help |
191 | Say Y here to include Creative CA0132 codec support in | 195 | Say Y here to include Creative CA0132 codec support in |
@@ -199,6 +203,7 @@ config SND_HDA_CODEC_CA0132 | |||
199 | config SND_HDA_CODEC_CMEDIA | 203 | config SND_HDA_CODEC_CMEDIA |
200 | bool "Build C-Media HD-audio codec support" | 204 | bool "Build C-Media HD-audio codec support" |
201 | default y | 205 | default y |
206 | select SND_HDA_GENERIC | ||
202 | help | 207 | help |
203 | Say Y here to include C-Media HD-audio codec support in | 208 | Say Y here to include C-Media HD-audio codec support in |
204 | snd-hda-intel driver, such as CMI9880. | 209 | snd-hda-intel driver, such as CMI9880. |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 7da883a464e3..a3ea76a4c9d2 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -97,6 +97,28 @@ static void reorder_outputs(unsigned int nums, hda_nid_t *pins) | |||
97 | } | 97 | } |
98 | } | 98 | } |
99 | 99 | ||
100 | /* check whether the given pin has a proper pin I/O capability bit */ | ||
101 | static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin, | ||
102 | unsigned int dev) | ||
103 | { | ||
104 | unsigned int pincap = snd_hda_query_pin_caps(codec, pin); | ||
105 | |||
106 | /* some old hardware don't return the proper pincaps */ | ||
107 | if (!pincap) | ||
108 | return true; | ||
109 | |||
110 | switch (dev) { | ||
111 | case AC_JACK_LINE_OUT: | ||
112 | case AC_JACK_SPEAKER: | ||
113 | case AC_JACK_HP_OUT: | ||
114 | case AC_JACK_SPDIF_OUT: | ||
115 | case AC_JACK_DIG_OTHER_OUT: | ||
116 | return !!(pincap & AC_PINCAP_OUT); | ||
117 | default: | ||
118 | return !!(pincap & AC_PINCAP_IN); | ||
119 | } | ||
120 | } | ||
121 | |||
100 | /* | 122 | /* |
101 | * Parse all pin widgets and store the useful pin nids to cfg | 123 | * Parse all pin widgets and store the useful pin nids to cfg |
102 | * | 124 | * |
@@ -126,6 +148,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
126 | struct auto_out_pin hp_out[ARRAY_SIZE(cfg->hp_pins)]; | 148 | struct auto_out_pin hp_out[ARRAY_SIZE(cfg->hp_pins)]; |
127 | int i; | 149 | int i; |
128 | 150 | ||
151 | if (!snd_hda_get_int_hint(codec, "parser_flags", &i)) | ||
152 | cond_flags = i; | ||
153 | |||
129 | memset(cfg, 0, sizeof(*cfg)); | 154 | memset(cfg, 0, sizeof(*cfg)); |
130 | 155 | ||
131 | memset(line_out, 0, sizeof(line_out)); | 156 | memset(line_out, 0, sizeof(line_out)); |
@@ -156,10 +181,14 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
156 | 181 | ||
157 | /* workaround for buggy BIOS setups */ | 182 | /* workaround for buggy BIOS setups */ |
158 | if (dev == AC_JACK_LINE_OUT) { | 183 | if (dev == AC_JACK_LINE_OUT) { |
159 | if (conn == AC_JACK_PORT_FIXED) | 184 | if (conn == AC_JACK_PORT_FIXED || |
185 | conn == AC_JACK_PORT_BOTH) | ||
160 | dev = AC_JACK_SPEAKER; | 186 | dev = AC_JACK_SPEAKER; |
161 | } | 187 | } |
162 | 188 | ||
189 | if (!check_pincap_validity(codec, nid, dev)) | ||
190 | continue; | ||
191 | |||
163 | switch (dev) { | 192 | switch (dev) { |
164 | case AC_JACK_LINE_OUT: | 193 | case AC_JACK_LINE_OUT: |
165 | seq = get_defcfg_sequence(def_conf); | 194 | seq = get_defcfg_sequence(def_conf); |
@@ -363,7 +392,7 @@ static const char *hda_get_input_pin_label(struct hda_codec *codec, | |||
363 | { | 392 | { |
364 | unsigned int def_conf; | 393 | unsigned int def_conf; |
365 | static const char * const mic_names[] = { | 394 | static const char * const mic_names[] = { |
366 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | 395 | "Internal Mic", "Dock Mic", "Mic", "Rear Mic", "Front Mic" |
367 | }; | 396 | }; |
368 | int attr; | 397 | int attr; |
369 | 398 | ||
@@ -394,6 +423,8 @@ static const char *hda_get_input_pin_label(struct hda_codec *codec, | |||
394 | return "SPDIF In"; | 423 | return "SPDIF In"; |
395 | case AC_JACK_DIG_OTHER_IN: | 424 | case AC_JACK_DIG_OTHER_IN: |
396 | return "Digital In"; | 425 | return "Digital In"; |
426 | case AC_JACK_HP_OUT: | ||
427 | return "Headphone Mic"; | ||
397 | default: | 428 | default: |
398 | return "Misc"; | 429 | return "Misc"; |
399 | } | 430 | } |
@@ -552,6 +583,9 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | |||
552 | return 1; | 583 | return 1; |
553 | } | 584 | } |
554 | 585 | ||
586 | #define is_hdmi_cfg(conf) \ | ||
587 | (get_defcfg_location(conf) == AC_JACK_LOC_HDMI) | ||
588 | |||
555 | /** | 589 | /** |
556 | * snd_hda_get_pin_label - Get a label for the given I/O pin | 590 | * snd_hda_get_pin_label - Get a label for the given I/O pin |
557 | * | 591 | * |
@@ -572,6 +606,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
572 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 606 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
573 | const char *name = NULL; | 607 | const char *name = NULL; |
574 | int i; | 608 | int i; |
609 | bool hdmi; | ||
575 | 610 | ||
576 | if (indexp) | 611 | if (indexp) |
577 | *indexp = 0; | 612 | *indexp = 0; |
@@ -590,16 +625,18 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
590 | label, maxlen, indexp); | 625 | label, maxlen, indexp); |
591 | case AC_JACK_SPDIF_OUT: | 626 | case AC_JACK_SPDIF_OUT: |
592 | case AC_JACK_DIG_OTHER_OUT: | 627 | case AC_JACK_DIG_OTHER_OUT: |
593 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | 628 | hdmi = is_hdmi_cfg(def_conf); |
594 | name = "HDMI"; | 629 | name = hdmi ? "HDMI" : "SPDIF"; |
595 | else | 630 | if (cfg && indexp) |
596 | name = "SPDIF"; | 631 | for (i = 0; i < cfg->dig_outs; i++) { |
597 | if (cfg && indexp) { | 632 | hda_nid_t pin = cfg->dig_out_pins[i]; |
598 | i = find_idx_in_nid_list(nid, cfg->dig_out_pins, | 633 | unsigned int c; |
599 | cfg->dig_outs); | 634 | if (pin == nid) |
600 | if (i >= 0) | 635 | break; |
601 | *indexp = i; | 636 | c = snd_hda_codec_get_pincfg(codec, pin); |
602 | } | 637 | if (hdmi == is_hdmi_cfg(c)) |
638 | (*indexp)++; | ||
639 | } | ||
603 | break; | 640 | break; |
604 | default: | 641 | default: |
605 | if (cfg) { | 642 | if (cfg) { |
@@ -622,28 +659,27 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
622 | } | 659 | } |
623 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | 660 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); |
624 | 661 | ||
625 | int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, | 662 | int snd_hda_add_verbs(struct hda_codec *codec, |
626 | const struct hda_verb *list) | 663 | const struct hda_verb *list) |
627 | { | 664 | { |
628 | const struct hda_verb **v; | 665 | const struct hda_verb **v; |
629 | v = snd_array_new(&spec->verbs); | 666 | v = snd_array_new(&codec->verbs); |
630 | if (!v) | 667 | if (!v) |
631 | return -ENOMEM; | 668 | return -ENOMEM; |
632 | *v = list; | 669 | *v = list; |
633 | return 0; | 670 | return 0; |
634 | } | 671 | } |
635 | EXPORT_SYMBOL_HDA(snd_hda_gen_add_verbs); | 672 | EXPORT_SYMBOL_HDA(snd_hda_add_verbs); |
636 | 673 | ||
637 | void snd_hda_gen_apply_verbs(struct hda_codec *codec) | 674 | void snd_hda_apply_verbs(struct hda_codec *codec) |
638 | { | 675 | { |
639 | struct hda_gen_spec *spec = codec->spec; | ||
640 | int i; | 676 | int i; |
641 | for (i = 0; i < spec->verbs.used; i++) { | 677 | for (i = 0; i < codec->verbs.used; i++) { |
642 | struct hda_verb **v = snd_array_elem(&spec->verbs, i); | 678 | struct hda_verb **v = snd_array_elem(&codec->verbs, i); |
643 | snd_hda_sequence_write(codec, *v); | 679 | snd_hda_sequence_write(codec, *v); |
644 | } | 680 | } |
645 | } | 681 | } |
646 | EXPORT_SYMBOL_HDA(snd_hda_gen_apply_verbs); | 682 | EXPORT_SYMBOL_HDA(snd_hda_apply_verbs); |
647 | 683 | ||
648 | void snd_hda_apply_pincfgs(struct hda_codec *codec, | 684 | void snd_hda_apply_pincfgs(struct hda_codec *codec, |
649 | const struct hda_pintbl *cfg) | 685 | const struct hda_pintbl *cfg) |
@@ -653,20 +689,22 @@ void snd_hda_apply_pincfgs(struct hda_codec *codec, | |||
653 | } | 689 | } |
654 | EXPORT_SYMBOL_HDA(snd_hda_apply_pincfgs); | 690 | EXPORT_SYMBOL_HDA(snd_hda_apply_pincfgs); |
655 | 691 | ||
656 | void snd_hda_apply_fixup(struct hda_codec *codec, int action) | 692 | static void set_pin_targets(struct hda_codec *codec, |
693 | const struct hda_pintbl *cfg) | ||
657 | { | 694 | { |
658 | struct hda_gen_spec *spec = codec->spec; | 695 | for (; cfg->nid; cfg++) |
659 | int id = spec->fixup_id; | 696 | snd_hda_set_pin_ctl_cache(codec, cfg->nid, cfg->val); |
660 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 697 | } |
661 | const char *modelname = spec->fixup_name; | ||
662 | #endif | ||
663 | int depth = 0; | ||
664 | 698 | ||
665 | if (!spec->fixup_list) | 699 | static void apply_fixup(struct hda_codec *codec, int id, int action, int depth) |
666 | return; | 700 | { |
701 | const char *modelname = codec->fixup_name; | ||
667 | 702 | ||
668 | while (id >= 0) { | 703 | while (id >= 0) { |
669 | const struct hda_fixup *fix = spec->fixup_list + id; | 704 | const struct hda_fixup *fix = codec->fixup_list + id; |
705 | |||
706 | if (fix->chained_before) | ||
707 | apply_fixup(codec, fix->chain_id, action, depth + 1); | ||
670 | 708 | ||
671 | switch (fix->type) { | 709 | switch (fix->type) { |
672 | case HDA_FIXUP_PINS: | 710 | case HDA_FIXUP_PINS: |
@@ -683,7 +721,7 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action) | |||
683 | snd_printdd(KERN_INFO SFX | 721 | snd_printdd(KERN_INFO SFX |
684 | "%s: Apply fix-verbs for %s\n", | 722 | "%s: Apply fix-verbs for %s\n", |
685 | codec->chip_name, modelname); | 723 | codec->chip_name, modelname); |
686 | snd_hda_gen_add_verbs(codec->spec, fix->v.verbs); | 724 | snd_hda_add_verbs(codec, fix->v.verbs); |
687 | break; | 725 | break; |
688 | case HDA_FIXUP_FUNC: | 726 | case HDA_FIXUP_FUNC: |
689 | if (!fix->v.func) | 727 | if (!fix->v.func) |
@@ -693,19 +731,33 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action) | |||
693 | codec->chip_name, modelname); | 731 | codec->chip_name, modelname); |
694 | fix->v.func(codec, fix, action); | 732 | fix->v.func(codec, fix, action); |
695 | break; | 733 | break; |
734 | case HDA_FIXUP_PINCTLS: | ||
735 | if (action != HDA_FIXUP_ACT_PROBE || !fix->v.pins) | ||
736 | break; | ||
737 | snd_printdd(KERN_INFO SFX | ||
738 | "%s: Apply pinctl for %s\n", | ||
739 | codec->chip_name, modelname); | ||
740 | set_pin_targets(codec, fix->v.pins); | ||
741 | break; | ||
696 | default: | 742 | default: |
697 | snd_printk(KERN_ERR SFX | 743 | snd_printk(KERN_ERR SFX |
698 | "%s: Invalid fixup type %d\n", | 744 | "%s: Invalid fixup type %d\n", |
699 | codec->chip_name, fix->type); | 745 | codec->chip_name, fix->type); |
700 | break; | 746 | break; |
701 | } | 747 | } |
702 | if (!fix->chained) | 748 | if (!fix->chained || fix->chained_before) |
703 | break; | 749 | break; |
704 | if (++depth > 10) | 750 | if (++depth > 10) |
705 | break; | 751 | break; |
706 | id = fix->chain_id; | 752 | id = fix->chain_id; |
707 | } | 753 | } |
708 | } | 754 | } |
755 | |||
756 | void snd_hda_apply_fixup(struct hda_codec *codec, int action) | ||
757 | { | ||
758 | if (codec->fixup_list) | ||
759 | apply_fixup(codec, codec->fixup_id, action, 0); | ||
760 | } | ||
709 | EXPORT_SYMBOL_HDA(snd_hda_apply_fixup); | 761 | EXPORT_SYMBOL_HDA(snd_hda_apply_fixup); |
710 | 762 | ||
711 | void snd_hda_pick_fixup(struct hda_codec *codec, | 763 | void snd_hda_pick_fixup(struct hda_codec *codec, |
@@ -713,15 +765,14 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
713 | const struct snd_pci_quirk *quirk, | 765 | const struct snd_pci_quirk *quirk, |
714 | const struct hda_fixup *fixlist) | 766 | const struct hda_fixup *fixlist) |
715 | { | 767 | { |
716 | struct hda_gen_spec *spec = codec->spec; | ||
717 | const struct snd_pci_quirk *q; | 768 | const struct snd_pci_quirk *q; |
718 | int id = -1; | 769 | int id = -1; |
719 | const char *name = NULL; | 770 | const char *name = NULL; |
720 | 771 | ||
721 | /* when model=nofixup is given, don't pick up any fixups */ | 772 | /* when model=nofixup is given, don't pick up any fixups */ |
722 | if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { | 773 | if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { |
723 | spec->fixup_list = NULL; | 774 | codec->fixup_list = NULL; |
724 | spec->fixup_id = -1; | 775 | codec->fixup_id = -1; |
725 | return; | 776 | return; |
726 | } | 777 | } |
727 | 778 | ||
@@ -759,10 +810,10 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
759 | } | 810 | } |
760 | } | 811 | } |
761 | 812 | ||
762 | spec->fixup_id = id; | 813 | codec->fixup_id = id; |
763 | if (id >= 0) { | 814 | if (id >= 0) { |
764 | spec->fixup_list = fixlist; | 815 | codec->fixup_list = fixlist; |
765 | spec->fixup_name = name; | 816 | codec->fixup_name = name; |
766 | } | 817 | } |
767 | } | 818 | } |
768 | EXPORT_SYMBOL_HDA(snd_hda_pick_fixup); | 819 | EXPORT_SYMBOL_HDA(snd_hda_pick_fixup); |
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index 632ad0ad3007..f74807138b49 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h | |||
@@ -51,8 +51,9 @@ enum { | |||
51 | INPUT_PIN_ATTR_INT, /* internal mic/line-in */ | 51 | INPUT_PIN_ATTR_INT, /* internal mic/line-in */ |
52 | INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */ | 52 | INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */ |
53 | INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */ | 53 | INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */ |
54 | INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */ | ||
55 | INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */ | 54 | INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */ |
55 | INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */ | ||
56 | INPUT_PIN_ATTR_LAST = INPUT_PIN_ATTR_FRONT, | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | int snd_hda_get_input_pin_attr(unsigned int def_conf); | 59 | int snd_hda_get_input_pin_attr(unsigned int def_conf); |
@@ -89,82 +90,4 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
89 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ | 90 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ |
90 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) | 91 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) |
91 | 92 | ||
92 | /* | ||
93 | */ | ||
94 | |||
95 | struct hda_gen_spec { | ||
96 | /* fix-up list */ | ||
97 | int fixup_id; | ||
98 | const struct hda_fixup *fixup_list; | ||
99 | const char *fixup_name; | ||
100 | |||
101 | /* additional init verbs */ | ||
102 | struct snd_array verbs; | ||
103 | }; | ||
104 | |||
105 | |||
106 | /* | ||
107 | * Fix-up pin default configurations and add default verbs | ||
108 | */ | ||
109 | |||
110 | struct hda_pintbl { | ||
111 | hda_nid_t nid; | ||
112 | u32 val; | ||
113 | }; | ||
114 | |||
115 | struct hda_model_fixup { | ||
116 | const int id; | ||
117 | const char *name; | ||
118 | }; | ||
119 | |||
120 | struct hda_fixup { | ||
121 | int type; | ||
122 | bool chained; | ||
123 | int chain_id; | ||
124 | union { | ||
125 | const struct hda_pintbl *pins; | ||
126 | const struct hda_verb *verbs; | ||
127 | void (*func)(struct hda_codec *codec, | ||
128 | const struct hda_fixup *fix, | ||
129 | int action); | ||
130 | } v; | ||
131 | }; | ||
132 | |||
133 | /* fixup types */ | ||
134 | enum { | ||
135 | HDA_FIXUP_INVALID, | ||
136 | HDA_FIXUP_PINS, | ||
137 | HDA_FIXUP_VERBS, | ||
138 | HDA_FIXUP_FUNC, | ||
139 | }; | ||
140 | |||
141 | /* fixup action definitions */ | ||
142 | enum { | ||
143 | HDA_FIXUP_ACT_PRE_PROBE, | ||
144 | HDA_FIXUP_ACT_PROBE, | ||
145 | HDA_FIXUP_ACT_INIT, | ||
146 | HDA_FIXUP_ACT_BUILD, | ||
147 | }; | ||
148 | |||
149 | int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, | ||
150 | const struct hda_verb *list); | ||
151 | void snd_hda_gen_apply_verbs(struct hda_codec *codec); | ||
152 | void snd_hda_apply_pincfgs(struct hda_codec *codec, | ||
153 | const struct hda_pintbl *cfg); | ||
154 | void snd_hda_apply_fixup(struct hda_codec *codec, int action); | ||
155 | void snd_hda_pick_fixup(struct hda_codec *codec, | ||
156 | const struct hda_model_fixup *models, | ||
157 | const struct snd_pci_quirk *quirk, | ||
158 | const struct hda_fixup *fixlist); | ||
159 | |||
160 | static inline void snd_hda_gen_init(struct hda_gen_spec *spec) | ||
161 | { | ||
162 | snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8); | ||
163 | } | ||
164 | |||
165 | static inline void snd_hda_gen_free(struct hda_gen_spec *spec) | ||
166 | { | ||
167 | snd_array_free(&spec->verbs); | ||
168 | } | ||
169 | |||
170 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ | 93 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 822df971972c..f82a64da2f1b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -222,8 +222,14 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
222 | again: | 222 | again: |
223 | snd_hda_power_up(codec); | 223 | snd_hda_power_up(codec); |
224 | mutex_lock(&bus->cmd_mutex); | 224 | mutex_lock(&bus->cmd_mutex); |
225 | trace_hda_send_cmd(codec, cmd); | 225 | for (;;) { |
226 | err = bus->ops.command(bus, cmd); | 226 | trace_hda_send_cmd(codec, cmd); |
227 | err = bus->ops.command(bus, cmd); | ||
228 | if (err != -EAGAIN) | ||
229 | break; | ||
230 | /* process pending verbs */ | ||
231 | bus->ops.get_response(bus, codec->addr); | ||
232 | } | ||
227 | if (!err && res) { | 233 | if (!err && res) { |
228 | *res = bus->ops.get_response(bus, codec->addr); | 234 | *res = bus->ops.get_response(bus, codec->addr); |
229 | trace_hda_get_response(codec, *res); | 235 | trace_hda_get_response(codec, *res); |
@@ -328,20 +334,51 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, | |||
328 | } | 334 | } |
329 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); | 335 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); |
330 | 336 | ||
337 | /* connection list element */ | ||
338 | struct hda_conn_list { | ||
339 | struct list_head list; | ||
340 | int len; | ||
341 | hda_nid_t nid; | ||
342 | hda_nid_t conns[0]; | ||
343 | }; | ||
344 | |||
331 | /* look up the cached results */ | 345 | /* look up the cached results */ |
332 | static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid) | 346 | static struct hda_conn_list * |
347 | lookup_conn_list(struct hda_codec *codec, hda_nid_t nid) | ||
333 | { | 348 | { |
334 | int i, len; | 349 | struct hda_conn_list *p; |
335 | for (i = 0; i < array->used; ) { | 350 | list_for_each_entry(p, &codec->conn_list, list) { |
336 | hda_nid_t *p = snd_array_elem(array, i); | 351 | if (p->nid == nid) |
337 | if (nid == *p) | ||
338 | return p; | 352 | return p; |
339 | len = p[1]; | ||
340 | i += len + 2; | ||
341 | } | 353 | } |
342 | return NULL; | 354 | return NULL; |
343 | } | 355 | } |
344 | 356 | ||
357 | static int add_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, | ||
358 | const hda_nid_t *list) | ||
359 | { | ||
360 | struct hda_conn_list *p; | ||
361 | |||
362 | p = kmalloc(sizeof(*p) + len * sizeof(hda_nid_t), GFP_KERNEL); | ||
363 | if (!p) | ||
364 | return -ENOMEM; | ||
365 | p->len = len; | ||
366 | p->nid = nid; | ||
367 | memcpy(p->conns, list, len * sizeof(hda_nid_t)); | ||
368 | list_add(&p->list, &codec->conn_list); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static void remove_conn_list(struct hda_codec *codec) | ||
373 | { | ||
374 | while (!list_empty(&codec->conn_list)) { | ||
375 | struct hda_conn_list *p; | ||
376 | p = list_first_entry(&codec->conn_list, typeof(*p), list); | ||
377 | list_del(&p->list); | ||
378 | kfree(p); | ||
379 | } | ||
380 | } | ||
381 | |||
345 | /* read the connection and add to the cache */ | 382 | /* read the connection and add to the cache */ |
346 | static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) | 383 | static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) |
347 | { | 384 | { |
@@ -355,6 +392,49 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) | |||
355 | } | 392 | } |
356 | 393 | ||
357 | /** | 394 | /** |
395 | * snd_hda_get_conn_list - get connection list | ||
396 | * @codec: the HDA codec | ||
397 | * @nid: NID to parse | ||
398 | * @len: number of connection list entries | ||
399 | * @listp: the pointer to store NID list | ||
400 | * | ||
401 | * Parses the connection list of the given widget and stores the pointer | ||
402 | * to the list of NIDs. | ||
403 | * | ||
404 | * Returns the number of connections, or a negative error code. | ||
405 | * | ||
406 | * Note that the returned pointer isn't protected against the list | ||
407 | * modification. If snd_hda_override_conn_list() might be called | ||
408 | * concurrently, protect with a mutex appropriately. | ||
409 | */ | ||
410 | int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, | ||
411 | const hda_nid_t **listp) | ||
412 | { | ||
413 | bool added = false; | ||
414 | |||
415 | for (;;) { | ||
416 | int err; | ||
417 | const struct hda_conn_list *p; | ||
418 | |||
419 | /* if the connection-list is already cached, read it */ | ||
420 | p = lookup_conn_list(codec, nid); | ||
421 | if (p) { | ||
422 | if (listp) | ||
423 | *listp = p->conns; | ||
424 | return p->len; | ||
425 | } | ||
426 | if (snd_BUG_ON(added)) | ||
427 | return -EINVAL; | ||
428 | |||
429 | err = read_and_add_raw_conns(codec, nid); | ||
430 | if (err < 0) | ||
431 | return err; | ||
432 | added = true; | ||
433 | } | ||
434 | } | ||
435 | EXPORT_SYMBOL_HDA(snd_hda_get_conn_list); | ||
436 | |||
437 | /** | ||
358 | * snd_hda_get_connections - copy connection list | 438 | * snd_hda_get_connections - copy connection list |
359 | * @codec: the HDA codec | 439 | * @codec: the HDA codec |
360 | * @nid: NID to parse | 440 | * @nid: NID to parse |
@@ -369,39 +449,20 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) | |||
369 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | 449 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, |
370 | hda_nid_t *conn_list, int max_conns) | 450 | hda_nid_t *conn_list, int max_conns) |
371 | { | 451 | { |
372 | struct snd_array *array = &codec->conn_lists; | 452 | const hda_nid_t *list; |
373 | int len; | 453 | int len = snd_hda_get_conn_list(codec, nid, &list); |
374 | hda_nid_t *p; | ||
375 | bool added = false; | ||
376 | 454 | ||
377 | again: | 455 | if (len > 0 && conn_list) { |
378 | mutex_lock(&codec->hash_mutex); | 456 | if (len > max_conns) { |
379 | len = -1; | ||
380 | /* if the connection-list is already cached, read it */ | ||
381 | p = lookup_conn_list(array, nid); | ||
382 | if (p) { | ||
383 | len = p[1]; | ||
384 | if (conn_list && len > max_conns) { | ||
385 | snd_printk(KERN_ERR "hda_codec: " | 457 | snd_printk(KERN_ERR "hda_codec: " |
386 | "Too many connections %d for NID 0x%x\n", | 458 | "Too many connections %d for NID 0x%x\n", |
387 | len, nid); | 459 | len, nid); |
388 | mutex_unlock(&codec->hash_mutex); | ||
389 | return -EINVAL; | 460 | return -EINVAL; |
390 | } | 461 | } |
391 | if (conn_list && len) | 462 | memcpy(conn_list, list, len * sizeof(hda_nid_t)); |
392 | memcpy(conn_list, p + 2, len * sizeof(hda_nid_t)); | ||
393 | } | 463 | } |
394 | mutex_unlock(&codec->hash_mutex); | ||
395 | if (len >= 0) | ||
396 | return len; | ||
397 | if (snd_BUG_ON(added)) | ||
398 | return -EINVAL; | ||
399 | 464 | ||
400 | len = read_and_add_raw_conns(codec, nid); | 465 | return len; |
401 | if (len < 0) | ||
402 | return len; | ||
403 | added = true; | ||
404 | goto again; | ||
405 | } | 466 | } |
406 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | 467 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); |
407 | 468 | ||
@@ -424,6 +485,7 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid, | |||
424 | unsigned int shift, num_elems, mask; | 485 | unsigned int shift, num_elems, mask; |
425 | unsigned int wcaps; | 486 | unsigned int wcaps; |
426 | hda_nid_t prev_nid; | 487 | hda_nid_t prev_nid; |
488 | int null_count = 0; | ||
427 | 489 | ||
428 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) | 490 | if (snd_BUG_ON(!conn_list || max_conns <= 0)) |
429 | return -EINVAL; | 491 | return -EINVAL; |
@@ -474,7 +536,7 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid, | |||
474 | } | 536 | } |
475 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ | 537 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ |
476 | val = parm & mask; | 538 | val = parm & mask; |
477 | if (val == 0) { | 539 | if (val == 0 && null_count++) { /* no second chance */ |
478 | snd_printk(KERN_WARNING "hda_codec: " | 540 | snd_printk(KERN_WARNING "hda_codec: " |
479 | "invalid CONNECT_LIST verb %x[%i]:%x\n", | 541 | "invalid CONNECT_LIST verb %x[%i]:%x\n", |
480 | nid, i, parm); | 542 | nid, i, parm); |
@@ -512,15 +574,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid, | |||
512 | return conns; | 574 | return conns; |
513 | } | 575 | } |
514 | 576 | ||
515 | static bool add_conn_list(struct snd_array *array, hda_nid_t nid) | ||
516 | { | ||
517 | hda_nid_t *p = snd_array_new(array); | ||
518 | if (!p) | ||
519 | return false; | ||
520 | *p = nid; | ||
521 | return true; | ||
522 | } | ||
523 | |||
524 | /** | 577 | /** |
525 | * snd_hda_override_conn_list - add/modify the connection-list to cache | 578 | * snd_hda_override_conn_list - add/modify the connection-list to cache |
526 | * @codec: the HDA codec | 579 | * @codec: the HDA codec |
@@ -536,28 +589,15 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid) | |||
536 | int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, | 589 | int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, |
537 | const hda_nid_t *list) | 590 | const hda_nid_t *list) |
538 | { | 591 | { |
539 | struct snd_array *array = &codec->conn_lists; | 592 | struct hda_conn_list *p; |
540 | hda_nid_t *p; | ||
541 | int i, old_used; | ||
542 | 593 | ||
543 | mutex_lock(&codec->hash_mutex); | 594 | p = lookup_conn_list(codec, nid); |
544 | p = lookup_conn_list(array, nid); | 595 | if (p) { |
545 | if (p) | 596 | list_del(&p->list); |
546 | *p = -1; /* invalidate the old entry */ | 597 | kfree(p); |
547 | 598 | } | |
548 | old_used = array->used; | ||
549 | if (!add_conn_list(array, nid) || !add_conn_list(array, len)) | ||
550 | goto error_add; | ||
551 | for (i = 0; i < len; i++) | ||
552 | if (!add_conn_list(array, list[i])) | ||
553 | goto error_add; | ||
554 | mutex_unlock(&codec->hash_mutex); | ||
555 | return 0; | ||
556 | 599 | ||
557 | error_add: | 600 | return add_conn_list(codec, nid, len, list); |
558 | array->used = old_used; | ||
559 | mutex_unlock(&codec->hash_mutex); | ||
560 | return -ENOMEM; | ||
561 | } | 601 | } |
562 | EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); | 602 | EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); |
563 | 603 | ||
@@ -575,16 +615,16 @@ EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); | |||
575 | int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, | 615 | int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, |
576 | hda_nid_t nid, int recursive) | 616 | hda_nid_t nid, int recursive) |
577 | { | 617 | { |
578 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | 618 | const hda_nid_t *conn; |
579 | int i, nums; | 619 | int i, nums; |
580 | 620 | ||
581 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | 621 | nums = snd_hda_get_conn_list(codec, mux, &conn); |
582 | for (i = 0; i < nums; i++) | 622 | for (i = 0; i < nums; i++) |
583 | if (conn[i] == nid) | 623 | if (conn[i] == nid) |
584 | return i; | 624 | return i; |
585 | if (!recursive) | 625 | if (!recursive) |
586 | return -1; | 626 | return -1; |
587 | if (recursive > 5) { | 627 | if (recursive > 10) { |
588 | snd_printd("hda_codec: too deep connection for 0x%x\n", nid); | 628 | snd_printd("hda_codec: too deep connection for 0x%x\n", nid); |
589 | return -1; | 629 | return -1; |
590 | } | 630 | } |
@@ -1046,9 +1086,16 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) | |||
1046 | struct hda_pincfg *pin; | 1086 | struct hda_pincfg *pin; |
1047 | 1087 | ||
1048 | #ifdef CONFIG_SND_HDA_HWDEP | 1088 | #ifdef CONFIG_SND_HDA_HWDEP |
1049 | pin = look_up_pincfg(codec, &codec->user_pins, nid); | 1089 | { |
1050 | if (pin) | 1090 | unsigned int cfg = 0; |
1051 | return pin->cfg; | 1091 | mutex_lock(&codec->user_mutex); |
1092 | pin = look_up_pincfg(codec, &codec->user_pins, nid); | ||
1093 | if (pin) | ||
1094 | cfg = pin->cfg; | ||
1095 | mutex_unlock(&codec->user_mutex); | ||
1096 | if (cfg) | ||
1097 | return cfg; | ||
1098 | } | ||
1052 | #endif | 1099 | #endif |
1053 | pin = look_up_pincfg(codec, &codec->driver_pins, nid); | 1100 | pin = look_up_pincfg(codec, &codec->driver_pins, nid); |
1054 | if (pin) | 1101 | if (pin) |
@@ -1060,6 +1107,32 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) | |||
1060 | } | 1107 | } |
1061 | EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg); | 1108 | EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg); |
1062 | 1109 | ||
1110 | /* remember the current pinctl target value */ | ||
1111 | int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, | ||
1112 | unsigned int val) | ||
1113 | { | ||
1114 | struct hda_pincfg *pin; | ||
1115 | |||
1116 | pin = look_up_pincfg(codec, &codec->init_pins, nid); | ||
1117 | if (!pin) | ||
1118 | return -EINVAL; | ||
1119 | pin->target = val; | ||
1120 | return 0; | ||
1121 | } | ||
1122 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_pin_target); | ||
1123 | |||
1124 | /* return the current pinctl target value */ | ||
1125 | int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) | ||
1126 | { | ||
1127 | struct hda_pincfg *pin; | ||
1128 | |||
1129 | pin = look_up_pincfg(codec, &codec->init_pins, nid); | ||
1130 | if (!pin) | ||
1131 | return 0; | ||
1132 | return pin->target; | ||
1133 | } | ||
1134 | EXPORT_SYMBOL_HDA(snd_hda_codec_get_pin_target); | ||
1135 | |||
1063 | /** | 1136 | /** |
1064 | * snd_hda_shutup_pins - Shut up all pins | 1137 | * snd_hda_shutup_pins - Shut up all pins |
1065 | * @codec: the HDA codec | 1138 | * @codec: the HDA codec |
@@ -1179,8 +1252,8 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1179 | snd_array_free(&codec->mixers); | 1252 | snd_array_free(&codec->mixers); |
1180 | snd_array_free(&codec->nids); | 1253 | snd_array_free(&codec->nids); |
1181 | snd_array_free(&codec->cvt_setups); | 1254 | snd_array_free(&codec->cvt_setups); |
1182 | snd_array_free(&codec->conn_lists); | ||
1183 | snd_array_free(&codec->spdif_out); | 1255 | snd_array_free(&codec->spdif_out); |
1256 | remove_conn_list(codec); | ||
1184 | codec->bus->caddr_tbl[codec->addr] = NULL; | 1257 | codec->bus->caddr_tbl[codec->addr] = NULL; |
1185 | if (codec->patch_ops.free) | 1258 | if (codec->patch_ops.free) |
1186 | codec->patch_ops.free(codec); | 1259 | codec->patch_ops.free(codec); |
@@ -1203,6 +1276,8 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, | |||
1203 | 1276 | ||
1204 | static unsigned int hda_set_power_state(struct hda_codec *codec, | 1277 | static unsigned int hda_set_power_state(struct hda_codec *codec, |
1205 | unsigned int power_state); | 1278 | unsigned int power_state); |
1279 | static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid, | ||
1280 | unsigned int power_state); | ||
1206 | 1281 | ||
1207 | /** | 1282 | /** |
1208 | * snd_hda_codec_new - create a HDA codec | 1283 | * snd_hda_codec_new - create a HDA codec |
@@ -1250,9 +1325,11 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1250 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); | 1325 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); |
1251 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); | 1326 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); |
1252 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); | 1327 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); |
1253 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); | ||
1254 | snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); | 1328 | snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); |
1255 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); | 1329 | snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); |
1330 | snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); | ||
1331 | INIT_LIST_HEAD(&codec->conn_list); | ||
1332 | |||
1256 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); | 1333 | INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); |
1257 | 1334 | ||
1258 | #ifdef CONFIG_PM | 1335 | #ifdef CONFIG_PM |
@@ -1321,6 +1398,7 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1321 | #endif | 1398 | #endif |
1322 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, | 1399 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, |
1323 | AC_PWRST_EPSS); | 1400 | AC_PWRST_EPSS); |
1401 | codec->power_filter = default_power_filter; | ||
1324 | 1402 | ||
1325 | /* power-up all before initialization */ | 1403 | /* power-up all before initialization */ |
1326 | hda_set_power_state(codec, AC_PWRST_D0); | 1404 | hda_set_power_state(codec, AC_PWRST_D0); |
@@ -1451,7 +1529,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1451 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | 1529 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", |
1452 | nid, stream_tag, channel_id, format); | 1530 | nid, stream_tag, channel_id, format); |
1453 | p = get_hda_cvt_setup(codec, nid); | 1531 | p = get_hda_cvt_setup(codec, nid); |
1454 | if (!p) | 1532 | if (!p || p->active) |
1455 | return; | 1533 | return; |
1456 | 1534 | ||
1457 | if (codec->pcm_format_first) | 1535 | if (codec->pcm_format_first) |
@@ -1498,7 +1576,7 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1498 | 1576 | ||
1499 | snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); | 1577 | snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); |
1500 | p = get_hda_cvt_setup(codec, nid); | 1578 | p = get_hda_cvt_setup(codec, nid); |
1501 | if (p) { | 1579 | if (p && p->active) { |
1502 | /* here we just clear the active flag when do_now isn't set; | 1580 | /* here we just clear the active flag when do_now isn't set; |
1503 | * actual clean-ups will be done later in | 1581 | * actual clean-ups will be done later in |
1504 | * purify_inactive_streams() called from snd_hda_codec_prpapre() | 1582 | * purify_inactive_streams() called from snd_hda_codec_prpapre() |
@@ -1610,6 +1688,7 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, | |||
1610 | cur = snd_array_index(&cache->buf, info); | 1688 | cur = snd_array_index(&cache->buf, info); |
1611 | info->key = key; | 1689 | info->key = key; |
1612 | info->val = 0; | 1690 | info->val = 0; |
1691 | info->dirty = 0; | ||
1613 | idx = key % (u16)ARRAY_SIZE(cache->hash); | 1692 | idx = key % (u16)ARRAY_SIZE(cache->hash); |
1614 | info->next = cache->hash[idx]; | 1693 | info->next = cache->hash[idx]; |
1615 | cache->hash[idx] = cur; | 1694 | cache->hash[idx] = cur; |
@@ -1764,7 +1843,7 @@ EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | |||
1764 | */ | 1843 | */ |
1765 | static struct hda_amp_info * | 1844 | static struct hda_amp_info * |
1766 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, | 1845 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, |
1767 | int direction, int index) | 1846 | int direction, int index, bool init_only) |
1768 | { | 1847 | { |
1769 | struct hda_amp_info *info; | 1848 | struct hda_amp_info *info; |
1770 | unsigned int parm, val = 0; | 1849 | unsigned int parm, val = 0; |
@@ -1790,14 +1869,15 @@ update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1790 | } | 1869 | } |
1791 | info->vol[ch] = val; | 1870 | info->vol[ch] = val; |
1792 | info->head.val |= INFO_AMP_VOL(ch); | 1871 | info->head.val |= INFO_AMP_VOL(ch); |
1793 | } | 1872 | } else if (init_only) |
1873 | return NULL; | ||
1794 | return info; | 1874 | return info; |
1795 | } | 1875 | } |
1796 | 1876 | ||
1797 | /* | 1877 | /* |
1798 | * write the current volume in info to the h/w | 1878 | * write the current volume in info to the h/w |
1799 | */ | 1879 | */ |
1800 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | 1880 | static void put_vol_mute(struct hda_codec *codec, unsigned int amp_caps, |
1801 | hda_nid_t nid, int ch, int direction, int index, | 1881 | hda_nid_t nid, int ch, int direction, int index, |
1802 | int val) | 1882 | int val) |
1803 | { | 1883 | { |
@@ -1806,8 +1886,8 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
1806 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; | 1886 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; |
1807 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; | 1887 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; |
1808 | parm |= index << AC_AMP_SET_INDEX_SHIFT; | 1888 | parm |= index << AC_AMP_SET_INDEX_SHIFT; |
1809 | if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) && | 1889 | if ((val & HDA_AMP_MUTE) && !(amp_caps & AC_AMPCAP_MUTE) && |
1810 | (info->amp_caps & AC_AMPCAP_MIN_MUTE)) | 1890 | (amp_caps & AC_AMPCAP_MIN_MUTE)) |
1811 | ; /* set the zero value as a fake mute */ | 1891 | ; /* set the zero value as a fake mute */ |
1812 | else | 1892 | else |
1813 | parm |= val; | 1893 | parm |= val; |
@@ -1831,7 +1911,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1831 | unsigned int val = 0; | 1911 | unsigned int val = 0; |
1832 | 1912 | ||
1833 | mutex_lock(&codec->hash_mutex); | 1913 | mutex_lock(&codec->hash_mutex); |
1834 | info = update_amp_hash(codec, nid, ch, direction, index); | 1914 | info = update_amp_hash(codec, nid, ch, direction, index, false); |
1835 | if (info) | 1915 | if (info) |
1836 | val = info->vol[ch]; | 1916 | val = info->vol[ch]; |
1837 | mutex_unlock(&codec->hash_mutex); | 1917 | mutex_unlock(&codec->hash_mutex); |
@@ -1839,30 +1919,20 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1839 | } | 1919 | } |
1840 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); | 1920 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); |
1841 | 1921 | ||
1842 | /** | 1922 | static int codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
1843 | * snd_hda_codec_amp_update - update the AMP value | 1923 | int direction, int idx, int mask, int val, |
1844 | * @codec: HD-audio codec | 1924 | bool init_only) |
1845 | * @nid: NID to read the AMP value | ||
1846 | * @ch: channel (left=0 or right=1) | ||
1847 | * @direction: #HDA_INPUT or #HDA_OUTPUT | ||
1848 | * @idx: the index value (only for input direction) | ||
1849 | * @mask: bit mask to set | ||
1850 | * @val: the bits value to set | ||
1851 | * | ||
1852 | * Update the AMP value with a bit mask. | ||
1853 | * Returns 0 if the value is unchanged, 1 if changed. | ||
1854 | */ | ||
1855 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
1856 | int direction, int idx, int mask, int val) | ||
1857 | { | 1925 | { |
1858 | struct hda_amp_info *info; | 1926 | struct hda_amp_info *info; |
1927 | unsigned int caps; | ||
1928 | unsigned int cache_only; | ||
1859 | 1929 | ||
1860 | if (snd_BUG_ON(mask & ~0xff)) | 1930 | if (snd_BUG_ON(mask & ~0xff)) |
1861 | mask &= 0xff; | 1931 | mask &= 0xff; |
1862 | val &= mask; | 1932 | val &= mask; |
1863 | 1933 | ||
1864 | mutex_lock(&codec->hash_mutex); | 1934 | mutex_lock(&codec->hash_mutex); |
1865 | info = update_amp_hash(codec, nid, ch, direction, idx); | 1935 | info = update_amp_hash(codec, nid, ch, direction, idx, init_only); |
1866 | if (!info) { | 1936 | if (!info) { |
1867 | mutex_unlock(&codec->hash_mutex); | 1937 | mutex_unlock(&codec->hash_mutex); |
1868 | return 0; | 1938 | return 0; |
@@ -1873,10 +1943,32 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1873 | return 0; | 1943 | return 0; |
1874 | } | 1944 | } |
1875 | info->vol[ch] = val; | 1945 | info->vol[ch] = val; |
1946 | cache_only = info->head.dirty = codec->cached_write; | ||
1947 | caps = info->amp_caps; | ||
1876 | mutex_unlock(&codec->hash_mutex); | 1948 | mutex_unlock(&codec->hash_mutex); |
1877 | put_vol_mute(codec, info, nid, ch, direction, idx, val); | 1949 | if (!cache_only) |
1950 | put_vol_mute(codec, caps, nid, ch, direction, idx, val); | ||
1878 | return 1; | 1951 | return 1; |
1879 | } | 1952 | } |
1953 | |||
1954 | /** | ||
1955 | * snd_hda_codec_amp_update - update the AMP value | ||
1956 | * @codec: HD-audio codec | ||
1957 | * @nid: NID to read the AMP value | ||
1958 | * @ch: channel (left=0 or right=1) | ||
1959 | * @direction: #HDA_INPUT or #HDA_OUTPUT | ||
1960 | * @idx: the index value (only for input direction) | ||
1961 | * @mask: bit mask to set | ||
1962 | * @val: the bits value to set | ||
1963 | * | ||
1964 | * Update the AMP value with a bit mask. | ||
1965 | * Returns 0 if the value is unchanged, 1 if changed. | ||
1966 | */ | ||
1967 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
1968 | int direction, int idx, int mask, int val) | ||
1969 | { | ||
1970 | return codec_amp_update(codec, nid, ch, direction, idx, mask, val, false); | ||
1971 | } | ||
1880 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); | 1972 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); |
1881 | 1973 | ||
1882 | /** | 1974 | /** |
@@ -1905,7 +1997,31 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | |||
1905 | } | 1997 | } |
1906 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); | 1998 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); |
1907 | 1999 | ||
1908 | #ifdef CONFIG_PM | 2000 | /* Works like snd_hda_codec_amp_update() but it writes the value only at |
2001 | * the first access. If the amp was already initialized / updated beforehand, | ||
2002 | * this does nothing. | ||
2003 | */ | ||
2004 | int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
2005 | int dir, int idx, int mask, int val) | ||
2006 | { | ||
2007 | return codec_amp_update(codec, nid, ch, dir, idx, mask, val, true); | ||
2008 | } | ||
2009 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init); | ||
2010 | |||
2011 | int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
2012 | int dir, int idx, int mask, int val) | ||
2013 | { | ||
2014 | int ch, ret = 0; | ||
2015 | |||
2016 | if (snd_BUG_ON(mask & ~0xff)) | ||
2017 | mask &= 0xff; | ||
2018 | for (ch = 0; ch < 2; ch++) | ||
2019 | ret |= snd_hda_codec_amp_init(codec, nid, ch, dir, | ||
2020 | idx, mask, val); | ||
2021 | return ret; | ||
2022 | } | ||
2023 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init_stereo); | ||
2024 | |||
1909 | /** | 2025 | /** |
1910 | * snd_hda_codec_resume_amp - Resume all AMP commands from the cache | 2026 | * snd_hda_codec_resume_amp - Resume all AMP commands from the cache |
1911 | * @codec: HD-audio codec | 2027 | * @codec: HD-audio codec |
@@ -1914,28 +2030,40 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); | |||
1914 | */ | 2030 | */ |
1915 | void snd_hda_codec_resume_amp(struct hda_codec *codec) | 2031 | void snd_hda_codec_resume_amp(struct hda_codec *codec) |
1916 | { | 2032 | { |
1917 | struct hda_amp_info *buffer = codec->amp_cache.buf.list; | ||
1918 | int i; | 2033 | int i; |
1919 | 2034 | ||
1920 | for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) { | 2035 | mutex_lock(&codec->hash_mutex); |
1921 | u32 key = buffer->head.key; | 2036 | codec->cached_write = 0; |
2037 | for (i = 0; i < codec->amp_cache.buf.used; i++) { | ||
2038 | struct hda_amp_info *buffer; | ||
2039 | u32 key; | ||
1922 | hda_nid_t nid; | 2040 | hda_nid_t nid; |
1923 | unsigned int idx, dir, ch; | 2041 | unsigned int idx, dir, ch; |
2042 | struct hda_amp_info info; | ||
2043 | |||
2044 | buffer = snd_array_elem(&codec->amp_cache.buf, i); | ||
2045 | if (!buffer->head.dirty) | ||
2046 | continue; | ||
2047 | buffer->head.dirty = 0; | ||
2048 | info = *buffer; | ||
2049 | key = info.head.key; | ||
1924 | if (!key) | 2050 | if (!key) |
1925 | continue; | 2051 | continue; |
1926 | nid = key & 0xff; | 2052 | nid = key & 0xff; |
1927 | idx = (key >> 16) & 0xff; | 2053 | idx = (key >> 16) & 0xff; |
1928 | dir = (key >> 24) & 0xff; | 2054 | dir = (key >> 24) & 0xff; |
1929 | for (ch = 0; ch < 2; ch++) { | 2055 | for (ch = 0; ch < 2; ch++) { |
1930 | if (!(buffer->head.val & INFO_AMP_VOL(ch))) | 2056 | if (!(info.head.val & INFO_AMP_VOL(ch))) |
1931 | continue; | 2057 | continue; |
1932 | put_vol_mute(codec, buffer, nid, ch, dir, idx, | 2058 | mutex_unlock(&codec->hash_mutex); |
1933 | buffer->vol[ch]); | 2059 | put_vol_mute(codec, info.amp_caps, nid, ch, dir, idx, |
2060 | info.vol[ch]); | ||
2061 | mutex_lock(&codec->hash_mutex); | ||
1934 | } | 2062 | } |
1935 | } | 2063 | } |
2064 | mutex_unlock(&codec->hash_mutex); | ||
1936 | } | 2065 | } |
1937 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); | 2066 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); |
1938 | #endif /* CONFIG_PM */ | ||
1939 | 2067 | ||
1940 | static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, | 2068 | static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, |
1941 | unsigned int ofs) | 2069 | unsigned int ofs) |
@@ -2362,6 +2490,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2362 | snd_array_free(&codec->driver_pins); | 2490 | snd_array_free(&codec->driver_pins); |
2363 | snd_array_free(&codec->cvt_setups); | 2491 | snd_array_free(&codec->cvt_setups); |
2364 | snd_array_free(&codec->spdif_out); | 2492 | snd_array_free(&codec->spdif_out); |
2493 | snd_array_free(&codec->verbs); | ||
2365 | codec->num_pcms = 0; | 2494 | codec->num_pcms = 0; |
2366 | codec->pcm_info = NULL; | 2495 | codec->pcm_info = NULL; |
2367 | codec->preset = NULL; | 2496 | codec->preset = NULL; |
@@ -3375,12 +3504,11 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
3375 | } | 3504 | } |
3376 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); | 3505 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); |
3377 | 3506 | ||
3378 | #ifdef CONFIG_PM | ||
3379 | /* | 3507 | /* |
3380 | * command cache | 3508 | * command cache |
3381 | */ | 3509 | */ |
3382 | 3510 | ||
3383 | /* build a 32bit cache key with the widget id and the command parameter */ | 3511 | /* build a 31bit cache key with the widget id and the command parameter */ |
3384 | #define build_cmd_cache_key(nid, verb) ((verb << 8) | nid) | 3512 | #define build_cmd_cache_key(nid, verb) ((verb << 8) | nid) |
3385 | #define get_cmd_cache_nid(key) ((key) & 0xff) | 3513 | #define get_cmd_cache_nid(key) ((key) & 0xff) |
3386 | #define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff) | 3514 | #define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff) |
@@ -3400,20 +3528,28 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); | |||
3400 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | 3528 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, |
3401 | int direct, unsigned int verb, unsigned int parm) | 3529 | int direct, unsigned int verb, unsigned int parm) |
3402 | { | 3530 | { |
3403 | int err = snd_hda_codec_write(codec, nid, direct, verb, parm); | 3531 | int err; |
3404 | struct hda_cache_head *c; | 3532 | struct hda_cache_head *c; |
3405 | u32 key; | 3533 | u32 key; |
3534 | unsigned int cache_only; | ||
3535 | |||
3536 | cache_only = codec->cached_write; | ||
3537 | if (!cache_only) { | ||
3538 | err = snd_hda_codec_write(codec, nid, direct, verb, parm); | ||
3539 | if (err < 0) | ||
3540 | return err; | ||
3541 | } | ||
3406 | 3542 | ||
3407 | if (err < 0) | ||
3408 | return err; | ||
3409 | /* parm may contain the verb stuff for get/set amp */ | 3543 | /* parm may contain the verb stuff for get/set amp */ |
3410 | verb = verb | (parm >> 8); | 3544 | verb = verb | (parm >> 8); |
3411 | parm &= 0xff; | 3545 | parm &= 0xff; |
3412 | key = build_cmd_cache_key(nid, verb); | 3546 | key = build_cmd_cache_key(nid, verb); |
3413 | mutex_lock(&codec->bus->cmd_mutex); | 3547 | mutex_lock(&codec->bus->cmd_mutex); |
3414 | c = get_alloc_hash(&codec->cmd_cache, key); | 3548 | c = get_alloc_hash(&codec->cmd_cache, key); |
3415 | if (c) | 3549 | if (c) { |
3416 | c->val = parm; | 3550 | c->val = parm; |
3551 | c->dirty = cache_only; | ||
3552 | } | ||
3417 | mutex_unlock(&codec->bus->cmd_mutex); | 3553 | mutex_unlock(&codec->bus->cmd_mutex); |
3418 | return 0; | 3554 | return 0; |
3419 | } | 3555 | } |
@@ -3462,16 +3598,27 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache); | |||
3462 | */ | 3598 | */ |
3463 | void snd_hda_codec_resume_cache(struct hda_codec *codec) | 3599 | void snd_hda_codec_resume_cache(struct hda_codec *codec) |
3464 | { | 3600 | { |
3465 | struct hda_cache_head *buffer = codec->cmd_cache.buf.list; | ||
3466 | int i; | 3601 | int i; |
3467 | 3602 | ||
3468 | for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) { | 3603 | mutex_lock(&codec->hash_mutex); |
3469 | u32 key = buffer->key; | 3604 | codec->cached_write = 0; |
3605 | for (i = 0; i < codec->cmd_cache.buf.used; i++) { | ||
3606 | struct hda_cache_head *buffer; | ||
3607 | u32 key; | ||
3608 | |||
3609 | buffer = snd_array_elem(&codec->cmd_cache.buf, i); | ||
3610 | key = buffer->key; | ||
3470 | if (!key) | 3611 | if (!key) |
3471 | continue; | 3612 | continue; |
3613 | if (!buffer->dirty) | ||
3614 | continue; | ||
3615 | buffer->dirty = 0; | ||
3616 | mutex_unlock(&codec->hash_mutex); | ||
3472 | snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0, | 3617 | snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0, |
3473 | get_cmd_cache_cmd(key), buffer->val); | 3618 | get_cmd_cache_cmd(key), buffer->val); |
3619 | mutex_lock(&codec->hash_mutex); | ||
3474 | } | 3620 | } |
3621 | mutex_unlock(&codec->hash_mutex); | ||
3475 | } | 3622 | } |
3476 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache); | 3623 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache); |
3477 | 3624 | ||
@@ -3492,32 +3639,36 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, | |||
3492 | seq->param); | 3639 | seq->param); |
3493 | } | 3640 | } |
3494 | EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache); | 3641 | EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache); |
3495 | #endif /* CONFIG_PM */ | 3642 | |
3643 | /** | ||
3644 | * snd_hda_codec_flush_cache - Execute all pending (cached) amps / verbs | ||
3645 | * @codec: HD-audio codec | ||
3646 | */ | ||
3647 | void snd_hda_codec_flush_cache(struct hda_codec *codec) | ||
3648 | { | ||
3649 | snd_hda_codec_resume_amp(codec); | ||
3650 | snd_hda_codec_resume_cache(codec); | ||
3651 | } | ||
3652 | EXPORT_SYMBOL_HDA(snd_hda_codec_flush_cache); | ||
3496 | 3653 | ||
3497 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 3654 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, |
3498 | unsigned int power_state, | 3655 | unsigned int power_state) |
3499 | bool eapd_workaround) | ||
3500 | { | 3656 | { |
3501 | hda_nid_t nid = codec->start_nid; | 3657 | hda_nid_t nid = codec->start_nid; |
3502 | int i; | 3658 | int i; |
3503 | 3659 | ||
3504 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 3660 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
3505 | unsigned int wcaps = get_wcaps(codec, nid); | 3661 | unsigned int wcaps = get_wcaps(codec, nid); |
3662 | unsigned int state = power_state; | ||
3506 | if (!(wcaps & AC_WCAP_POWER)) | 3663 | if (!(wcaps & AC_WCAP_POWER)) |
3507 | continue; | 3664 | continue; |
3508 | /* don't power down the widget if it controls eapd and | 3665 | if (codec->power_filter) { |
3509 | * EAPD_BTLENABLE is set. | 3666 | state = codec->power_filter(codec, nid, power_state); |
3510 | */ | 3667 | if (state != power_state && power_state == AC_PWRST_D3) |
3511 | if (eapd_workaround && power_state == AC_PWRST_D3 && | ||
3512 | get_wcaps_type(wcaps) == AC_WID_PIN && | ||
3513 | (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) { | ||
3514 | int eapd = snd_hda_codec_read(codec, nid, 0, | ||
3515 | AC_VERB_GET_EAPD_BTLENABLE, 0); | ||
3516 | if (eapd & 0x02) | ||
3517 | continue; | 3668 | continue; |
3518 | } | 3669 | } |
3519 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, | 3670 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, |
3520 | power_state); | 3671 | state); |
3521 | } | 3672 | } |
3522 | } | 3673 | } |
3523 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); | 3674 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); |
@@ -3564,6 +3715,21 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec, | |||
3564 | return state; | 3715 | return state; |
3565 | } | 3716 | } |
3566 | 3717 | ||
3718 | /* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */ | ||
3719 | static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid, | ||
3720 | unsigned int power_state) | ||
3721 | { | ||
3722 | if (power_state == AC_PWRST_D3 && | ||
3723 | get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && | ||
3724 | (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) { | ||
3725 | int eapd = snd_hda_codec_read(codec, nid, 0, | ||
3726 | AC_VERB_GET_EAPD_BTLENABLE, 0); | ||
3727 | if (eapd & 0x02) | ||
3728 | return AC_PWRST_D0; | ||
3729 | } | ||
3730 | return power_state; | ||
3731 | } | ||
3732 | |||
3567 | /* | 3733 | /* |
3568 | * set power state of the codec, and return the power state | 3734 | * set power state of the codec, and return the power state |
3569 | */ | 3735 | */ |
@@ -3589,8 +3755,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, | |||
3589 | snd_hda_codec_read(codec, fg, 0, | 3755 | snd_hda_codec_read(codec, fg, 0, |
3590 | AC_VERB_SET_POWER_STATE, | 3756 | AC_VERB_SET_POWER_STATE, |
3591 | power_state); | 3757 | power_state); |
3592 | snd_hda_codec_set_power_to_all(codec, fg, power_state, | 3758 | snd_hda_codec_set_power_to_all(codec, fg, power_state); |
3593 | true); | ||
3594 | } | 3759 | } |
3595 | state = hda_sync_power_state(codec, fg, power_state); | 3760 | state = hda_sync_power_state(codec, fg, power_state); |
3596 | if (!(state & AC_PWRST_ERROR)) | 3761 | if (!(state & AC_PWRST_ERROR)) |
@@ -3600,6 +3765,32 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, | |||
3600 | return state; | 3765 | return state; |
3601 | } | 3766 | } |
3602 | 3767 | ||
3768 | /* sync power states of all widgets; | ||
3769 | * this is called at the end of codec parsing | ||
3770 | */ | ||
3771 | static void sync_power_up_states(struct hda_codec *codec) | ||
3772 | { | ||
3773 | hda_nid_t nid = codec->start_nid; | ||
3774 | int i; | ||
3775 | |||
3776 | /* don't care if no or standard filter is used */ | ||
3777 | if (!codec->power_filter || codec->power_filter == default_power_filter) | ||
3778 | return; | ||
3779 | |||
3780 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
3781 | unsigned int wcaps = get_wcaps(codec, nid); | ||
3782 | unsigned int target; | ||
3783 | if (!(wcaps & AC_WCAP_POWER)) | ||
3784 | continue; | ||
3785 | target = codec->power_filter(codec, nid, AC_PWRST_D0); | ||
3786 | if (target == AC_PWRST_D0) | ||
3787 | continue; | ||
3788 | if (!snd_hda_check_power_state(codec, nid, target)) | ||
3789 | snd_hda_codec_write(codec, nid, 0, | ||
3790 | AC_VERB_SET_POWER_STATE, target); | ||
3791 | } | ||
3792 | } | ||
3793 | |||
3603 | #ifdef CONFIG_SND_HDA_HWDEP | 3794 | #ifdef CONFIG_SND_HDA_HWDEP |
3604 | /* execute additional init verbs */ | 3795 | /* execute additional init verbs */ |
3605 | static void hda_exec_init_verbs(struct hda_codec *codec) | 3796 | static void hda_exec_init_verbs(struct hda_codec *codec) |
@@ -3640,6 +3831,22 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) | |||
3640 | return state; | 3831 | return state; |
3641 | } | 3832 | } |
3642 | 3833 | ||
3834 | /* mark all entries of cmd and amp caches dirty */ | ||
3835 | static void hda_mark_cmd_cache_dirty(struct hda_codec *codec) | ||
3836 | { | ||
3837 | int i; | ||
3838 | for (i = 0; i < codec->cmd_cache.buf.used; i++) { | ||
3839 | struct hda_cache_head *cmd; | ||
3840 | cmd = snd_array_elem(&codec->cmd_cache.buf, i); | ||
3841 | cmd->dirty = 1; | ||
3842 | } | ||
3843 | for (i = 0; i < codec->amp_cache.buf.used; i++) { | ||
3844 | struct hda_amp_info *amp; | ||
3845 | amp = snd_array_elem(&codec->amp_cache.buf, i); | ||
3846 | amp->head.dirty = 1; | ||
3847 | } | ||
3848 | } | ||
3849 | |||
3643 | /* | 3850 | /* |
3644 | * kick up codec; used both from PM and power-save | 3851 | * kick up codec; used both from PM and power-save |
3645 | */ | 3852 | */ |
@@ -3647,6 +3854,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3647 | { | 3854 | { |
3648 | codec->in_pm = 1; | 3855 | codec->in_pm = 1; |
3649 | 3856 | ||
3857 | hda_mark_cmd_cache_dirty(codec); | ||
3858 | |||
3650 | /* set as if powered on for avoiding re-entering the resume | 3859 | /* set as if powered on for avoiding re-entering the resume |
3651 | * in the resume / power-save sequence | 3860 | * in the resume / power-save sequence |
3652 | */ | 3861 | */ |
@@ -3769,6 +3978,7 @@ int snd_hda_codec_build_controls(struct hda_codec *codec) | |||
3769 | hda_jackpoll_work(&codec->jackpoll_work.work); | 3978 | hda_jackpoll_work(&codec->jackpoll_work.work); |
3770 | else | 3979 | else |
3771 | snd_hda_jack_report_sync(codec); /* call at the last init point */ | 3980 | snd_hda_jack_report_sync(codec); /* call at the last init point */ |
3981 | sync_power_up_states(codec); | ||
3772 | return 0; | 3982 | return 0; |
3773 | } | 3983 | } |
3774 | 3984 | ||
@@ -5120,23 +5330,62 @@ unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) | |||
5120 | } | 5330 | } |
5121 | EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); | 5331 | EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); |
5122 | 5332 | ||
5123 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, | 5333 | /* correct the pin ctl value for matching with the pin cap */ |
5124 | unsigned int val, bool cached) | 5334 | unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, |
5335 | hda_nid_t pin, unsigned int val) | ||
5125 | { | 5336 | { |
5126 | if (val) { | 5337 | static unsigned int cap_lists[][2] = { |
5127 | unsigned int cap = snd_hda_query_pin_caps(codec, pin); | 5338 | { AC_PINCTL_VREF_100, AC_PINCAP_VREF_100 }, |
5128 | if (cap && (val & AC_PINCTL_OUT_EN)) { | 5339 | { AC_PINCTL_VREF_80, AC_PINCAP_VREF_80 }, |
5129 | if (!(cap & AC_PINCAP_OUT)) | 5340 | { AC_PINCTL_VREF_50, AC_PINCAP_VREF_50 }, |
5130 | val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | 5341 | { AC_PINCTL_VREF_GRD, AC_PINCAP_VREF_GRD }, |
5131 | else if ((val & AC_PINCTL_HP_EN) && | 5342 | }; |
5132 | !(cap & AC_PINCAP_HP_DRV)) | 5343 | unsigned int cap; |
5133 | val &= ~AC_PINCTL_HP_EN; | 5344 | |
5134 | } | 5345 | if (!val) |
5135 | if (cap && (val & AC_PINCTL_IN_EN)) { | 5346 | return 0; |
5136 | if (!(cap & AC_PINCAP_IN)) | 5347 | cap = snd_hda_query_pin_caps(codec, pin); |
5137 | val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN); | 5348 | if (!cap) |
5349 | return val; /* don't know what to do... */ | ||
5350 | |||
5351 | if (val & AC_PINCTL_OUT_EN) { | ||
5352 | if (!(cap & AC_PINCAP_OUT)) | ||
5353 | val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
5354 | else if ((val & AC_PINCTL_HP_EN) && !(cap & AC_PINCAP_HP_DRV)) | ||
5355 | val &= ~AC_PINCTL_HP_EN; | ||
5356 | } | ||
5357 | |||
5358 | if (val & AC_PINCTL_IN_EN) { | ||
5359 | if (!(cap & AC_PINCAP_IN)) | ||
5360 | val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN); | ||
5361 | else { | ||
5362 | unsigned int vcap, vref; | ||
5363 | int i; | ||
5364 | vcap = (cap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | ||
5365 | vref = val & AC_PINCTL_VREFEN; | ||
5366 | for (i = 0; i < ARRAY_SIZE(cap_lists); i++) { | ||
5367 | if (vref == cap_lists[i][0] && | ||
5368 | !(vcap & cap_lists[i][1])) { | ||
5369 | if (i == ARRAY_SIZE(cap_lists) - 1) | ||
5370 | vref = AC_PINCTL_VREF_HIZ; | ||
5371 | else | ||
5372 | vref = cap_lists[i + 1][0]; | ||
5373 | } | ||
5374 | } | ||
5375 | val &= ~AC_PINCTL_VREFEN; | ||
5376 | val |= vref; | ||
5138 | } | 5377 | } |
5139 | } | 5378 | } |
5379 | |||
5380 | return val; | ||
5381 | } | ||
5382 | EXPORT_SYMBOL_HDA(snd_hda_correct_pin_ctl); | ||
5383 | |||
5384 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, | ||
5385 | unsigned int val, bool cached) | ||
5386 | { | ||
5387 | val = snd_hda_correct_pin_ctl(codec, pin, val); | ||
5388 | snd_hda_codec_set_pin_target(codec, pin, val); | ||
5140 | if (cached) | 5389 | if (cached) |
5141 | return snd_hda_codec_update_cache(codec, pin, 0, | 5390 | return snd_hda_codec_update_cache(codec, pin, 0, |
5142 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | 5391 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 8665540e55aa..fbedcf3c9d0b 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -719,9 +719,10 @@ struct hda_codec_ops { | |||
719 | 719 | ||
720 | /* record for amp information cache */ | 720 | /* record for amp information cache */ |
721 | struct hda_cache_head { | 721 | struct hda_cache_head { |
722 | u32 key; /* hash key */ | 722 | u32 key:31; /* hash key */ |
723 | u32 dirty:1; | ||
723 | u16 val; /* assigned value */ | 724 | u16 val; /* assigned value */ |
724 | u16 next; /* next link; -1 = terminal */ | 725 | u16 next; |
725 | }; | 726 | }; |
726 | 727 | ||
727 | struct hda_amp_info { | 728 | struct hda_amp_info { |
@@ -830,7 +831,7 @@ struct hda_codec { | |||
830 | struct hda_cache_rec amp_cache; /* cache for amp access */ | 831 | struct hda_cache_rec amp_cache; /* cache for amp access */ |
831 | struct hda_cache_rec cmd_cache; /* cache for other commands */ | 832 | struct hda_cache_rec cmd_cache; /* cache for other commands */ |
832 | 833 | ||
833 | struct snd_array conn_lists; /* connection-list array */ | 834 | struct list_head conn_list; /* linked-list of connection-list */ |
834 | 835 | ||
835 | struct mutex spdif_mutex; | 836 | struct mutex spdif_mutex; |
836 | struct mutex control_mutex; | 837 | struct mutex control_mutex; |
@@ -844,6 +845,7 @@ struct hda_codec { | |||
844 | struct snd_array cvt_setups; /* audio convert setups */ | 845 | struct snd_array cvt_setups; /* audio convert setups */ |
845 | 846 | ||
846 | #ifdef CONFIG_SND_HDA_HWDEP | 847 | #ifdef CONFIG_SND_HDA_HWDEP |
848 | struct mutex user_mutex; | ||
847 | struct snd_hwdep *hwdep; /* assigned hwdep device */ | 849 | struct snd_hwdep *hwdep; /* assigned hwdep device */ |
848 | struct snd_array init_verbs; /* additional init verbs */ | 850 | struct snd_array init_verbs; /* additional init verbs */ |
849 | struct snd_array hints; /* additional hints */ | 851 | struct snd_array hints; /* additional hints */ |
@@ -865,8 +867,11 @@ struct hda_codec { | |||
865 | unsigned int pins_shutup:1; /* pins are shut up */ | 867 | unsigned int pins_shutup:1; /* pins are shut up */ |
866 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 868 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
867 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | 869 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ |
870 | unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */ | ||
871 | unsigned int inv_jack_detect:1; /* broken h/w: inverted detection bit */ | ||
868 | unsigned int pcm_format_first:1; /* PCM format must be set first */ | 872 | unsigned int pcm_format_first:1; /* PCM format must be set first */ |
869 | unsigned int epss:1; /* supporting EPSS? */ | 873 | unsigned int epss:1; /* supporting EPSS? */ |
874 | unsigned int cached_write:1; /* write only to caches */ | ||
870 | #ifdef CONFIG_PM | 875 | #ifdef CONFIG_PM |
871 | unsigned int power_on :1; /* current (global) power-state */ | 876 | unsigned int power_on :1; /* current (global) power-state */ |
872 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ | 877 | unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ |
@@ -881,6 +886,10 @@ struct hda_codec { | |||
881 | spinlock_t power_lock; | 886 | spinlock_t power_lock; |
882 | #endif | 887 | #endif |
883 | 888 | ||
889 | /* filter the requested power state per nid */ | ||
890 | unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid, | ||
891 | unsigned int power_state); | ||
892 | |||
884 | /* codec-specific additional proc output */ | 893 | /* codec-specific additional proc output */ |
885 | void (*proc_widget_hook)(struct snd_info_buffer *buffer, | 894 | void (*proc_widget_hook)(struct snd_info_buffer *buffer, |
886 | struct hda_codec *codec, hda_nid_t nid); | 895 | struct hda_codec *codec, hda_nid_t nid); |
@@ -894,6 +903,14 @@ struct hda_codec { | |||
894 | /* jack detection */ | 903 | /* jack detection */ |
895 | struct snd_array jacks; | 904 | struct snd_array jacks; |
896 | #endif | 905 | #endif |
906 | |||
907 | /* fix-up list */ | ||
908 | int fixup_id; | ||
909 | const struct hda_fixup *fixup_list; | ||
910 | const char *fixup_name; | ||
911 | |||
912 | /* additional init verbs */ | ||
913 | struct snd_array verbs; | ||
897 | }; | 914 | }; |
898 | 915 | ||
899 | /* direction */ | 916 | /* direction */ |
@@ -932,6 +949,8 @@ snd_hda_get_num_conns(struct hda_codec *codec, hda_nid_t nid) | |||
932 | } | 949 | } |
933 | int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid, | 950 | int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid, |
934 | hda_nid_t *conn_list, int max_conns); | 951 | hda_nid_t *conn_list, int max_conns); |
952 | int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, | ||
953 | const hda_nid_t **listp); | ||
935 | int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums, | 954 | int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums, |
936 | const hda_nid_t *list); | 955 | const hda_nid_t *list); |
937 | int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, | 956 | int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, |
@@ -952,7 +971,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, | |||
952 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); | 971 | int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); |
953 | 972 | ||
954 | /* cached write */ | 973 | /* cached write */ |
955 | #ifdef CONFIG_PM | ||
956 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | 974 | int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, |
957 | int direct, unsigned int verb, unsigned int parm); | 975 | int direct, unsigned int verb, unsigned int parm); |
958 | void snd_hda_sequence_write_cache(struct hda_codec *codec, | 976 | void snd_hda_sequence_write_cache(struct hda_codec *codec, |
@@ -960,17 +978,14 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, | |||
960 | int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, | 978 | int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, |
961 | int direct, unsigned int verb, unsigned int parm); | 979 | int direct, unsigned int verb, unsigned int parm); |
962 | void snd_hda_codec_resume_cache(struct hda_codec *codec); | 980 | void snd_hda_codec_resume_cache(struct hda_codec *codec); |
963 | #else | 981 | /* both for cmd & amp caches */ |
964 | #define snd_hda_codec_write_cache snd_hda_codec_write | 982 | void snd_hda_codec_flush_cache(struct hda_codec *codec); |
965 | #define snd_hda_codec_update_cache snd_hda_codec_write | ||
966 | #define snd_hda_sequence_write_cache snd_hda_sequence_write | ||
967 | #endif | ||
968 | 983 | ||
969 | /* the struct for codec->pin_configs */ | 984 | /* the struct for codec->pin_configs */ |
970 | struct hda_pincfg { | 985 | struct hda_pincfg { |
971 | hda_nid_t nid; | 986 | hda_nid_t nid; |
972 | unsigned char ctrl; /* current pin control value */ | 987 | unsigned char ctrl; /* original pin control value */ |
973 | unsigned char pad; /* reserved */ | 988 | unsigned char target; /* target pin control value */ |
974 | unsigned int cfg; /* default configuration */ | 989 | unsigned int cfg; /* default configuration */ |
975 | }; | 990 | }; |
976 | 991 | ||
@@ -1036,8 +1051,7 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[]; | |||
1036 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); | 1051 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); |
1037 | void snd_hda_bus_reboot_notify(struct hda_bus *bus); | 1052 | void snd_hda_bus_reboot_notify(struct hda_bus *bus); |
1038 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 1053 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, |
1039 | unsigned int power_state, | 1054 | unsigned int power_state); |
1040 | bool eapd_workaround); | ||
1041 | 1055 | ||
1042 | int snd_hda_lock_devices(struct hda_bus *bus); | 1056 | int snd_hda_lock_devices(struct hda_bus *bus); |
1043 | void snd_hda_unlock_devices(struct hda_bus *bus); | 1057 | void snd_hda_unlock_devices(struct hda_bus *bus); |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index b81d3d0b952d..c4ba3066a013 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -23,836 +23,3210 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/export.h> | 25 | #include <linux/export.h> |
26 | #include <linux/sort.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/ctype.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/bitops.h> | ||
26 | #include <sound/core.h> | 31 | #include <sound/core.h> |
32 | #include <sound/jack.h> | ||
27 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_auto_parser.h" | ||
36 | #include "hda_jack.h" | ||
37 | #include "hda_generic.h" | ||
29 | 38 | ||
30 | /* widget node for parsing */ | ||
31 | struct hda_gnode { | ||
32 | hda_nid_t nid; /* NID of this widget */ | ||
33 | unsigned short nconns; /* number of input connections */ | ||
34 | hda_nid_t *conn_list; | ||
35 | hda_nid_t slist[2]; /* temporay list */ | ||
36 | unsigned int wid_caps; /* widget capabilities */ | ||
37 | unsigned char type; /* widget type */ | ||
38 | unsigned char pin_ctl; /* pin controls */ | ||
39 | unsigned char checked; /* the flag indicates that the node is already parsed */ | ||
40 | unsigned int pin_caps; /* pin widget capabilities */ | ||
41 | unsigned int def_cfg; /* default configuration */ | ||
42 | unsigned int amp_out_caps; /* AMP out capabilities */ | ||
43 | unsigned int amp_in_caps; /* AMP in capabilities */ | ||
44 | struct list_head list; | ||
45 | }; | ||
46 | 39 | ||
47 | /* patch-specific record */ | 40 | /* initialize hda_gen_spec struct */ |
41 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec) | ||
42 | { | ||
43 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | ||
44 | snd_array_init(&spec->paths, sizeof(struct nid_path), 8); | ||
45 | mutex_init(&spec->pcm_mutex); | ||
46 | return 0; | ||
47 | } | ||
48 | EXPORT_SYMBOL_HDA(snd_hda_gen_spec_init); | ||
48 | 49 | ||
49 | #define MAX_PCM_VOLS 2 | 50 | struct snd_kcontrol_new * |
50 | struct pcm_vol { | 51 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, |
51 | struct hda_gnode *node; /* Node for PCM volume */ | 52 | const struct snd_kcontrol_new *temp) |
52 | unsigned int index; /* connection of PCM volume */ | 53 | { |
53 | }; | 54 | struct snd_kcontrol_new *knew = snd_array_new(&spec->kctls); |
55 | if (!knew) | ||
56 | return NULL; | ||
57 | *knew = *temp; | ||
58 | if (name) | ||
59 | knew->name = kstrdup(name, GFP_KERNEL); | ||
60 | else if (knew->name) | ||
61 | knew->name = kstrdup(knew->name, GFP_KERNEL); | ||
62 | if (!knew->name) | ||
63 | return NULL; | ||
64 | return knew; | ||
65 | } | ||
66 | EXPORT_SYMBOL_HDA(snd_hda_gen_add_kctl); | ||
54 | 67 | ||
55 | struct hda_gspec { | 68 | static void free_kctls(struct hda_gen_spec *spec) |
56 | struct hda_gnode *dac_node[2]; /* DAC node */ | 69 | { |
57 | struct hda_gnode *out_pin_node[2]; /* Output pin (Line-Out) node */ | 70 | if (spec->kctls.list) { |
58 | struct pcm_vol pcm_vol[MAX_PCM_VOLS]; /* PCM volumes */ | 71 | struct snd_kcontrol_new *kctl = spec->kctls.list; |
59 | unsigned int pcm_vol_nodes; /* number of PCM volumes */ | 72 | int i; |
73 | for (i = 0; i < spec->kctls.used; i++) | ||
74 | kfree(kctl[i].name); | ||
75 | } | ||
76 | snd_array_free(&spec->kctls); | ||
77 | } | ||
60 | 78 | ||
61 | struct hda_gnode *adc_node; /* ADC node */ | 79 | void snd_hda_gen_spec_free(struct hda_gen_spec *spec) |
62 | struct hda_gnode *cap_vol_node; /* Node for capture volume */ | 80 | { |
63 | unsigned int cur_cap_src; /* current capture source */ | 81 | if (!spec) |
64 | struct hda_input_mux input_mux; | 82 | return; |
83 | free_kctls(spec); | ||
84 | snd_array_free(&spec->paths); | ||
85 | } | ||
86 | EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free); | ||
65 | 87 | ||
66 | unsigned int def_amp_in_caps; | 88 | /* |
67 | unsigned int def_amp_out_caps; | 89 | * store user hints |
90 | */ | ||
91 | static void parse_user_hints(struct hda_codec *codec) | ||
92 | { | ||
93 | struct hda_gen_spec *spec = codec->spec; | ||
94 | int val; | ||
68 | 95 | ||
69 | struct hda_pcm pcm_rec; /* PCM information */ | 96 | val = snd_hda_get_bool_hint(codec, "jack_detect"); |
97 | if (val >= 0) | ||
98 | codec->no_jack_detect = !val; | ||
99 | val = snd_hda_get_bool_hint(codec, "inv_jack_detect"); | ||
100 | if (val >= 0) | ||
101 | codec->inv_jack_detect = !!val; | ||
102 | val = snd_hda_get_bool_hint(codec, "trigger_sense"); | ||
103 | if (val >= 0) | ||
104 | codec->no_trigger_sense = !val; | ||
105 | val = snd_hda_get_bool_hint(codec, "inv_eapd"); | ||
106 | if (val >= 0) | ||
107 | codec->inv_eapd = !!val; | ||
108 | val = snd_hda_get_bool_hint(codec, "pcm_format_first"); | ||
109 | if (val >= 0) | ||
110 | codec->pcm_format_first = !!val; | ||
111 | val = snd_hda_get_bool_hint(codec, "sticky_stream"); | ||
112 | if (val >= 0) | ||
113 | codec->no_sticky_stream = !val; | ||
114 | val = snd_hda_get_bool_hint(codec, "spdif_status_reset"); | ||
115 | if (val >= 0) | ||
116 | codec->spdif_status_reset = !!val; | ||
117 | val = snd_hda_get_bool_hint(codec, "pin_amp_workaround"); | ||
118 | if (val >= 0) | ||
119 | codec->pin_amp_workaround = !!val; | ||
120 | val = snd_hda_get_bool_hint(codec, "single_adc_amp"); | ||
121 | if (val >= 0) | ||
122 | codec->single_adc_amp = !!val; | ||
70 | 123 | ||
71 | struct list_head nid_list; /* list of widgets */ | 124 | val = snd_hda_get_bool_hint(codec, "auto_mute"); |
125 | if (val >= 0) | ||
126 | spec->suppress_auto_mute = !val; | ||
127 | val = snd_hda_get_bool_hint(codec, "auto_mic"); | ||
128 | if (val >= 0) | ||
129 | spec->suppress_auto_mic = !val; | ||
130 | val = snd_hda_get_bool_hint(codec, "line_in_auto_switch"); | ||
131 | if (val >= 0) | ||
132 | spec->line_in_auto_switch = !!val; | ||
133 | val = snd_hda_get_bool_hint(codec, "need_dac_fix"); | ||
134 | if (val >= 0) | ||
135 | spec->need_dac_fix = !!val; | ||
136 | val = snd_hda_get_bool_hint(codec, "primary_hp"); | ||
137 | if (val >= 0) | ||
138 | spec->no_primary_hp = !val; | ||
139 | val = snd_hda_get_bool_hint(codec, "multi_cap_vol"); | ||
140 | if (val >= 0) | ||
141 | spec->multi_cap_vol = !!val; | ||
142 | val = snd_hda_get_bool_hint(codec, "inv_dmic_split"); | ||
143 | if (val >= 0) | ||
144 | spec->inv_dmic_split = !!val; | ||
145 | val = snd_hda_get_bool_hint(codec, "indep_hp"); | ||
146 | if (val >= 0) | ||
147 | spec->indep_hp = !!val; | ||
148 | val = snd_hda_get_bool_hint(codec, "add_stereo_mix_input"); | ||
149 | if (val >= 0) | ||
150 | spec->add_stereo_mix_input = !!val; | ||
151 | val = snd_hda_get_bool_hint(codec, "add_out_jack_modes"); | ||
152 | if (val >= 0) | ||
153 | spec->add_out_jack_modes = !!val; | ||
154 | val = snd_hda_get_bool_hint(codec, "add_in_jack_modes"); | ||
155 | if (val >= 0) | ||
156 | spec->add_in_jack_modes = !!val; | ||
157 | val = snd_hda_get_bool_hint(codec, "power_down_unused"); | ||
158 | if (val >= 0) | ||
159 | spec->power_down_unused = !!val; | ||
72 | 160 | ||
73 | #ifdef CONFIG_PM | 161 | if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) |
74 | #define MAX_LOOPBACK_AMPS 7 | 162 | spec->mixer_nid = val; |
75 | struct hda_loopback_check loopback; | 163 | } |
76 | int num_loopbacks; | ||
77 | struct hda_amp_list loopback_list[MAX_LOOPBACK_AMPS + 1]; | ||
78 | #endif | ||
79 | }; | ||
80 | 164 | ||
81 | /* | 165 | /* |
82 | * retrieve the default device type from the default config value | 166 | * pin control value accesses |
83 | */ | 167 | */ |
84 | #define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> \ | ||
85 | AC_DEFCFG_DEVICE_SHIFT) | ||
86 | #define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> \ | ||
87 | AC_DEFCFG_LOCATION_SHIFT) | ||
88 | #define defcfg_port_conn(node) (((node)->def_cfg & AC_DEFCFG_PORT_CONN) >> \ | ||
89 | AC_DEFCFG_PORT_CONN_SHIFT) | ||
90 | 168 | ||
91 | /* | 169 | #define update_pin_ctl(codec, pin, val) \ |
92 | * destructor | 170 | snd_hda_codec_update_cache(codec, pin, 0, \ |
93 | */ | 171 | AC_VERB_SET_PIN_WIDGET_CONTROL, val) |
94 | static void snd_hda_generic_free(struct hda_codec *codec) | 172 | |
173 | /* restore the pinctl based on the cached value */ | ||
174 | static inline void restore_pin_ctl(struct hda_codec *codec, hda_nid_t pin) | ||
95 | { | 175 | { |
96 | struct hda_gspec *spec = codec->spec; | 176 | update_pin_ctl(codec, pin, snd_hda_codec_get_pin_target(codec, pin)); |
97 | struct hda_gnode *node, *n; | 177 | } |
98 | 178 | ||
99 | if (! spec) | 179 | /* set the pinctl target value and write it if requested */ |
180 | static void set_pin_target(struct hda_codec *codec, hda_nid_t pin, | ||
181 | unsigned int val, bool do_write) | ||
182 | { | ||
183 | if (!pin) | ||
100 | return; | 184 | return; |
101 | /* free all widgets */ | 185 | val = snd_hda_correct_pin_ctl(codec, pin, val); |
102 | list_for_each_entry_safe(node, n, &spec->nid_list, list) { | 186 | snd_hda_codec_set_pin_target(codec, pin, val); |
103 | if (node->conn_list != node->slist) | 187 | if (do_write) |
104 | kfree(node->conn_list); | 188 | update_pin_ctl(codec, pin, val); |
105 | kfree(node); | ||
106 | } | ||
107 | kfree(spec); | ||
108 | } | 189 | } |
109 | 190 | ||
191 | /* set pinctl target values for all given pins */ | ||
192 | static void set_pin_targets(struct hda_codec *codec, int num_pins, | ||
193 | hda_nid_t *pins, unsigned int val) | ||
194 | { | ||
195 | int i; | ||
196 | for (i = 0; i < num_pins; i++) | ||
197 | set_pin_target(codec, pins[i], val, false); | ||
198 | } | ||
110 | 199 | ||
111 | /* | 200 | /* |
112 | * add a new widget node and read its attributes | 201 | * parsing paths |
113 | */ | 202 | */ |
114 | static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid_t nid) | 203 | |
204 | /* return the position of NID in the list, or -1 if not found */ | ||
205 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
115 | { | 206 | { |
116 | struct hda_gnode *node; | 207 | int i; |
117 | int nconns; | 208 | for (i = 0; i < nums; i++) |
118 | hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; | 209 | if (list[i] == nid) |
210 | return i; | ||
211 | return -1; | ||
212 | } | ||
119 | 213 | ||
120 | node = kzalloc(sizeof(*node), GFP_KERNEL); | 214 | /* return true if the given NID is contained in the path */ |
121 | if (node == NULL) | 215 | static bool is_nid_contained(struct nid_path *path, hda_nid_t nid) |
122 | return -ENOMEM; | 216 | { |
123 | node->nid = nid; | 217 | return find_idx_in_nid_list(nid, path->path, path->depth) >= 0; |
124 | node->wid_caps = get_wcaps(codec, nid); | 218 | } |
125 | node->type = get_wcaps_type(node->wid_caps); | 219 | |
126 | if (node->wid_caps & AC_WCAP_CONN_LIST) { | 220 | static struct nid_path *get_nid_path(struct hda_codec *codec, |
127 | nconns = snd_hda_get_connections(codec, nid, conn_list, | 221 | hda_nid_t from_nid, hda_nid_t to_nid, |
128 | HDA_MAX_CONNECTIONS); | 222 | int anchor_nid) |
129 | if (nconns < 0) { | 223 | { |
130 | kfree(node); | 224 | struct hda_gen_spec *spec = codec->spec; |
131 | return nconns; | 225 | int i; |
132 | } | 226 | |
133 | } else { | 227 | for (i = 0; i < spec->paths.used; i++) { |
134 | nconns = 0; | 228 | struct nid_path *path = snd_array_elem(&spec->paths, i); |
135 | } | 229 | if (path->depth <= 0) |
136 | if (nconns <= ARRAY_SIZE(node->slist)) | 230 | continue; |
137 | node->conn_list = node->slist; | 231 | if ((!from_nid || path->path[0] == from_nid) && |
138 | else { | 232 | (!to_nid || path->path[path->depth - 1] == to_nid)) { |
139 | node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns, | 233 | if (!anchor_nid || |
140 | GFP_KERNEL); | 234 | (anchor_nid > 0 && is_nid_contained(path, anchor_nid)) || |
141 | if (! node->conn_list) { | 235 | (anchor_nid < 0 && !is_nid_contained(path, anchor_nid))) |
142 | snd_printk(KERN_ERR "hda-generic: cannot malloc\n"); | 236 | return path; |
143 | kfree(node); | ||
144 | return -ENOMEM; | ||
145 | } | 237 | } |
146 | } | 238 | } |
147 | memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); | 239 | return NULL; |
148 | node->nconns = nconns; | 240 | } |
149 | 241 | ||
150 | if (node->type == AC_WID_PIN) { | 242 | /* get the path between the given NIDs; |
151 | node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); | 243 | * passing 0 to either @pin or @dac behaves as a wildcard |
152 | node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 244 | */ |
153 | node->def_cfg = snd_hda_codec_get_pincfg(codec, node->nid); | 245 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, |
246 | hda_nid_t from_nid, hda_nid_t to_nid) | ||
247 | { | ||
248 | return get_nid_path(codec, from_nid, to_nid, 0); | ||
249 | } | ||
250 | EXPORT_SYMBOL_HDA(snd_hda_get_nid_path); | ||
251 | |||
252 | /* get the index number corresponding to the path instance; | ||
253 | * the index starts from 1, for easier checking the invalid value | ||
254 | */ | ||
255 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) | ||
256 | { | ||
257 | struct hda_gen_spec *spec = codec->spec; | ||
258 | struct nid_path *array = spec->paths.list; | ||
259 | ssize_t idx; | ||
260 | |||
261 | if (!spec->paths.used) | ||
262 | return 0; | ||
263 | idx = path - array; | ||
264 | if (idx < 0 || idx >= spec->paths.used) | ||
265 | return 0; | ||
266 | return idx + 1; | ||
267 | } | ||
268 | EXPORT_SYMBOL_HDA(snd_hda_get_path_idx); | ||
269 | |||
270 | /* get the path instance corresponding to the given index number */ | ||
271 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) | ||
272 | { | ||
273 | struct hda_gen_spec *spec = codec->spec; | ||
274 | |||
275 | if (idx <= 0 || idx > spec->paths.used) | ||
276 | return NULL; | ||
277 | return snd_array_elem(&spec->paths, idx - 1); | ||
278 | } | ||
279 | EXPORT_SYMBOL_HDA(snd_hda_get_path_from_idx); | ||
280 | |||
281 | /* check whether the given DAC is already found in any existing paths */ | ||
282 | static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) | ||
283 | { | ||
284 | struct hda_gen_spec *spec = codec->spec; | ||
285 | int i; | ||
286 | |||
287 | for (i = 0; i < spec->paths.used; i++) { | ||
288 | struct nid_path *path = snd_array_elem(&spec->paths, i); | ||
289 | if (path->path[0] == nid) | ||
290 | return true; | ||
154 | } | 291 | } |
292 | return false; | ||
293 | } | ||
155 | 294 | ||
156 | if (node->wid_caps & AC_WCAP_OUT_AMP) { | 295 | /* check whether the given two widgets can be connected */ |
157 | if (node->wid_caps & AC_WCAP_AMP_OVRD) | 296 | static bool is_reachable_path(struct hda_codec *codec, |
158 | node->amp_out_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_OUT_CAP); | 297 | hda_nid_t from_nid, hda_nid_t to_nid) |
159 | if (! node->amp_out_caps) | 298 | { |
160 | node->amp_out_caps = spec->def_amp_out_caps; | 299 | if (!from_nid || !to_nid) |
300 | return false; | ||
301 | return snd_hda_get_conn_index(codec, to_nid, from_nid, true) >= 0; | ||
302 | } | ||
303 | |||
304 | /* nid, dir and idx */ | ||
305 | #define AMP_VAL_COMPARE_MASK (0xffff | (1U << 18) | (0x0f << 19)) | ||
306 | |||
307 | /* check whether the given ctl is already assigned in any path elements */ | ||
308 | static bool is_ctl_used(struct hda_codec *codec, unsigned int val, int type) | ||
309 | { | ||
310 | struct hda_gen_spec *spec = codec->spec; | ||
311 | int i; | ||
312 | |||
313 | val &= AMP_VAL_COMPARE_MASK; | ||
314 | for (i = 0; i < spec->paths.used; i++) { | ||
315 | struct nid_path *path = snd_array_elem(&spec->paths, i); | ||
316 | if ((path->ctls[type] & AMP_VAL_COMPARE_MASK) == val) | ||
317 | return true; | ||
161 | } | 318 | } |
162 | if (node->wid_caps & AC_WCAP_IN_AMP) { | 319 | return false; |
163 | if (node->wid_caps & AC_WCAP_AMP_OVRD) | 320 | } |
164 | node->amp_in_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_IN_CAP); | 321 | |
165 | if (! node->amp_in_caps) | 322 | /* check whether a control with the given (nid, dir, idx) was assigned */ |
166 | node->amp_in_caps = spec->def_amp_in_caps; | 323 | static bool is_ctl_associated(struct hda_codec *codec, hda_nid_t nid, |
324 | int dir, int idx, int type) | ||
325 | { | ||
326 | unsigned int val = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir); | ||
327 | return is_ctl_used(codec, val, type); | ||
328 | } | ||
329 | |||
330 | static void print_nid_path(const char *pfx, struct nid_path *path) | ||
331 | { | ||
332 | char buf[40]; | ||
333 | int i; | ||
334 | |||
335 | |||
336 | buf[0] = 0; | ||
337 | for (i = 0; i < path->depth; i++) { | ||
338 | char tmp[4]; | ||
339 | sprintf(tmp, ":%02x", path->path[i]); | ||
340 | strlcat(buf, tmp, sizeof(buf)); | ||
167 | } | 341 | } |
168 | list_add_tail(&node->list, &spec->nid_list); | 342 | snd_printdd("%s path: depth=%d %s\n", pfx, path->depth, buf); |
169 | return 0; | ||
170 | } | 343 | } |
171 | 344 | ||
345 | /* called recursively */ | ||
346 | static bool __parse_nid_path(struct hda_codec *codec, | ||
347 | hda_nid_t from_nid, hda_nid_t to_nid, | ||
348 | int anchor_nid, struct nid_path *path, | ||
349 | int depth) | ||
350 | { | ||
351 | const hda_nid_t *conn; | ||
352 | int i, nums; | ||
353 | |||
354 | if (to_nid == anchor_nid) | ||
355 | anchor_nid = 0; /* anchor passed */ | ||
356 | else if (to_nid == (hda_nid_t)(-anchor_nid)) | ||
357 | return false; /* hit the exclusive nid */ | ||
358 | |||
359 | nums = snd_hda_get_conn_list(codec, to_nid, &conn); | ||
360 | for (i = 0; i < nums; i++) { | ||
361 | if (conn[i] != from_nid) { | ||
362 | /* special case: when from_nid is 0, | ||
363 | * try to find an empty DAC | ||
364 | */ | ||
365 | if (from_nid || | ||
366 | get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT || | ||
367 | is_dac_already_used(codec, conn[i])) | ||
368 | continue; | ||
369 | } | ||
370 | /* anchor is not requested or already passed? */ | ||
371 | if (anchor_nid <= 0) | ||
372 | goto found; | ||
373 | } | ||
374 | if (depth >= MAX_NID_PATH_DEPTH) | ||
375 | return false; | ||
376 | for (i = 0; i < nums; i++) { | ||
377 | unsigned int type; | ||
378 | type = get_wcaps_type(get_wcaps(codec, conn[i])); | ||
379 | if (type == AC_WID_AUD_OUT || type == AC_WID_AUD_IN || | ||
380 | type == AC_WID_PIN) | ||
381 | continue; | ||
382 | if (__parse_nid_path(codec, from_nid, conn[i], | ||
383 | anchor_nid, path, depth + 1)) | ||
384 | goto found; | ||
385 | } | ||
386 | return false; | ||
387 | |||
388 | found: | ||
389 | path->path[path->depth] = conn[i]; | ||
390 | path->idx[path->depth + 1] = i; | ||
391 | if (nums > 1 && get_wcaps_type(get_wcaps(codec, to_nid)) != AC_WID_AUD_MIX) | ||
392 | path->multi[path->depth + 1] = 1; | ||
393 | path->depth++; | ||
394 | return true; | ||
395 | } | ||
396 | |||
397 | /* parse the widget path from the given nid to the target nid; | ||
398 | * when @from_nid is 0, try to find an empty DAC; | ||
399 | * when @anchor_nid is set to a positive value, only paths through the widget | ||
400 | * with the given value are evaluated. | ||
401 | * when @anchor_nid is set to a negative value, paths through the widget | ||
402 | * with the negative of given value are excluded, only other paths are chosen. | ||
403 | * when @anchor_nid is zero, no special handling about path selection. | ||
404 | */ | ||
405 | bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, | ||
406 | hda_nid_t to_nid, int anchor_nid, | ||
407 | struct nid_path *path) | ||
408 | { | ||
409 | if (__parse_nid_path(codec, from_nid, to_nid, anchor_nid, path, 1)) { | ||
410 | path->path[path->depth] = to_nid; | ||
411 | path->depth++; | ||
412 | return true; | ||
413 | } | ||
414 | return false; | ||
415 | } | ||
416 | EXPORT_SYMBOL_HDA(snd_hda_parse_nid_path); | ||
417 | |||
172 | /* | 418 | /* |
173 | * build the AFG subtree | 419 | * parse the path between the given NIDs and add to the path list. |
420 | * if no valid path is found, return NULL | ||
174 | */ | 421 | */ |
175 | static int build_afg_tree(struct hda_codec *codec) | 422 | struct nid_path * |
423 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, | ||
424 | hda_nid_t to_nid, int anchor_nid) | ||
176 | { | 425 | { |
177 | struct hda_gspec *spec = codec->spec; | 426 | struct hda_gen_spec *spec = codec->spec; |
178 | int i, nodes, err; | 427 | struct nid_path *path; |
179 | hda_nid_t nid; | ||
180 | 428 | ||
181 | if (snd_BUG_ON(!spec)) | 429 | if (from_nid && to_nid && !is_reachable_path(codec, from_nid, to_nid)) |
182 | return -EINVAL; | 430 | return NULL; |
183 | 431 | ||
184 | spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP); | 432 | /* check whether the path has been already added */ |
185 | spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP); | 433 | path = get_nid_path(codec, from_nid, to_nid, anchor_nid); |
434 | if (path) | ||
435 | return path; | ||
186 | 436 | ||
187 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); | 437 | path = snd_array_new(&spec->paths); |
188 | if (! nid || nodes < 0) { | 438 | if (!path) |
189 | printk(KERN_ERR "Invalid AFG subtree\n"); | 439 | return NULL; |
190 | return -EINVAL; | 440 | memset(path, 0, sizeof(*path)); |
191 | } | 441 | if (snd_hda_parse_nid_path(codec, from_nid, to_nid, anchor_nid, path)) |
442 | return path; | ||
443 | /* push back */ | ||
444 | spec->paths.used--; | ||
445 | return NULL; | ||
446 | } | ||
447 | EXPORT_SYMBOL_HDA(snd_hda_add_new_path); | ||
192 | 448 | ||
193 | /* parse all nodes belonging to the AFG */ | 449 | /* clear the given path as invalid so that it won't be picked up later */ |
194 | for (i = 0; i < nodes; i++, nid++) { | 450 | static void invalidate_nid_path(struct hda_codec *codec, int idx) |
195 | if ((err = add_new_node(codec, spec, nid)) < 0) | 451 | { |
196 | return err; | 452 | struct nid_path *path = snd_hda_get_path_from_idx(codec, idx); |
453 | if (!path) | ||
454 | return; | ||
455 | memset(path, 0, sizeof(*path)); | ||
456 | } | ||
457 | |||
458 | /* look for an empty DAC slot */ | ||
459 | static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin, | ||
460 | bool is_digital) | ||
461 | { | ||
462 | struct hda_gen_spec *spec = codec->spec; | ||
463 | bool cap_digital; | ||
464 | int i; | ||
465 | |||
466 | for (i = 0; i < spec->num_all_dacs; i++) { | ||
467 | hda_nid_t nid = spec->all_dacs[i]; | ||
468 | if (!nid || is_dac_already_used(codec, nid)) | ||
469 | continue; | ||
470 | cap_digital = !!(get_wcaps(codec, nid) & AC_WCAP_DIGITAL); | ||
471 | if (is_digital != cap_digital) | ||
472 | continue; | ||
473 | if (is_reachable_path(codec, nid, pin)) | ||
474 | return nid; | ||
197 | } | 475 | } |
476 | return 0; | ||
477 | } | ||
478 | |||
479 | /* replace the channels in the composed amp value with the given number */ | ||
480 | static unsigned int amp_val_replace_channels(unsigned int val, unsigned int chs) | ||
481 | { | ||
482 | val &= ~(0x3U << 16); | ||
483 | val |= chs << 16; | ||
484 | return val; | ||
485 | } | ||
486 | |||
487 | /* check whether the widget has the given amp capability for the direction */ | ||
488 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, | ||
489 | int dir, unsigned int bits) | ||
490 | { | ||
491 | if (!nid) | ||
492 | return false; | ||
493 | if (get_wcaps(codec, nid) & (1 << (dir + 1))) | ||
494 | if (query_amp_caps(codec, nid, dir) & bits) | ||
495 | return true; | ||
496 | return false; | ||
497 | } | ||
498 | |||
499 | static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, | ||
500 | hda_nid_t nid2, int dir) | ||
501 | { | ||
502 | if (!(get_wcaps(codec, nid1) & (1 << (dir + 1)))) | ||
503 | return !(get_wcaps(codec, nid2) & (1 << (dir + 1))); | ||
504 | return (query_amp_caps(codec, nid1, dir) == | ||
505 | query_amp_caps(codec, nid2, dir)); | ||
506 | } | ||
507 | |||
508 | #define nid_has_mute(codec, nid, dir) \ | ||
509 | check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) | ||
510 | #define nid_has_volume(codec, nid, dir) \ | ||
511 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) | ||
198 | 512 | ||
513 | /* look for a widget suitable for assigning a mute switch in the path */ | ||
514 | static hda_nid_t look_for_out_mute_nid(struct hda_codec *codec, | ||
515 | struct nid_path *path) | ||
516 | { | ||
517 | int i; | ||
518 | |||
519 | for (i = path->depth - 1; i >= 0; i--) { | ||
520 | if (nid_has_mute(codec, path->path[i], HDA_OUTPUT)) | ||
521 | return path->path[i]; | ||
522 | if (i != path->depth - 1 && i != 0 && | ||
523 | nid_has_mute(codec, path->path[i], HDA_INPUT)) | ||
524 | return path->path[i]; | ||
525 | } | ||
199 | return 0; | 526 | return 0; |
200 | } | 527 | } |
201 | 528 | ||
529 | /* look for a widget suitable for assigning a volume ctl in the path */ | ||
530 | static hda_nid_t look_for_out_vol_nid(struct hda_codec *codec, | ||
531 | struct nid_path *path) | ||
532 | { | ||
533 | int i; | ||
534 | |||
535 | for (i = path->depth - 1; i >= 0; i--) { | ||
536 | if (nid_has_volume(codec, path->path[i], HDA_OUTPUT)) | ||
537 | return path->path[i]; | ||
538 | } | ||
539 | return 0; | ||
540 | } | ||
202 | 541 | ||
203 | /* | 542 | /* |
204 | * look for the node record for the given NID | 543 | * path activation / deactivation |
205 | */ | 544 | */ |
206 | /* FIXME: should avoid the braindead linear search */ | 545 | |
207 | static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid) | 546 | /* can have the amp-in capability? */ |
547 | static bool has_amp_in(struct hda_codec *codec, struct nid_path *path, int idx) | ||
208 | { | 548 | { |
209 | struct hda_gnode *node; | 549 | hda_nid_t nid = path->path[idx]; |
550 | unsigned int caps = get_wcaps(codec, nid); | ||
551 | unsigned int type = get_wcaps_type(caps); | ||
210 | 552 | ||
211 | list_for_each_entry(node, &spec->nid_list, list) { | 553 | if (!(caps & AC_WCAP_IN_AMP)) |
212 | if (node->nid == nid) | 554 | return false; |
213 | return node; | 555 | if (type == AC_WID_PIN && idx > 0) /* only for input pins */ |
556 | return false; | ||
557 | return true; | ||
558 | } | ||
559 | |||
560 | /* can have the amp-out capability? */ | ||
561 | static bool has_amp_out(struct hda_codec *codec, struct nid_path *path, int idx) | ||
562 | { | ||
563 | hda_nid_t nid = path->path[idx]; | ||
564 | unsigned int caps = get_wcaps(codec, nid); | ||
565 | unsigned int type = get_wcaps_type(caps); | ||
566 | |||
567 | if (!(caps & AC_WCAP_OUT_AMP)) | ||
568 | return false; | ||
569 | if (type == AC_WID_PIN && !idx) /* only for output pins */ | ||
570 | return false; | ||
571 | return true; | ||
572 | } | ||
573 | |||
574 | /* check whether the given (nid,dir,idx) is active */ | ||
575 | static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid, | ||
576 | unsigned int dir, unsigned int idx) | ||
577 | { | ||
578 | struct hda_gen_spec *spec = codec->spec; | ||
579 | int i, n; | ||
580 | |||
581 | for (n = 0; n < spec->paths.used; n++) { | ||
582 | struct nid_path *path = snd_array_elem(&spec->paths, n); | ||
583 | if (!path->active) | ||
584 | continue; | ||
585 | for (i = 0; i < path->depth; i++) { | ||
586 | if (path->path[i] == nid) { | ||
587 | if (dir == HDA_OUTPUT || path->idx[i] == idx) | ||
588 | return true; | ||
589 | break; | ||
590 | } | ||
591 | } | ||
214 | } | 592 | } |
215 | return NULL; | 593 | return false; |
216 | } | 594 | } |
217 | 595 | ||
218 | /* | 596 | /* get the default amp value for the target state */ |
219 | * unmute (and set max vol) the output amplifier | 597 | static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid, |
598 | int dir, unsigned int caps, bool enable) | ||
599 | { | ||
600 | unsigned int val = 0; | ||
601 | |||
602 | if (caps & AC_AMPCAP_NUM_STEPS) { | ||
603 | /* set to 0dB */ | ||
604 | if (enable) | ||
605 | val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | ||
606 | } | ||
607 | if (caps & AC_AMPCAP_MUTE) { | ||
608 | if (!enable) | ||
609 | val |= HDA_AMP_MUTE; | ||
610 | } | ||
611 | return val; | ||
612 | } | ||
613 | |||
614 | /* initialize the amp value (only at the first time) */ | ||
615 | static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx) | ||
616 | { | ||
617 | unsigned int caps = query_amp_caps(codec, nid, dir); | ||
618 | int val = get_amp_val_to_activate(codec, nid, dir, caps, false); | ||
619 | snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val); | ||
620 | } | ||
621 | |||
622 | /* calculate amp value mask we can modify; | ||
623 | * if the given amp is controlled by mixers, don't touch it | ||
220 | */ | 624 | */ |
221 | static int unmute_output(struct hda_codec *codec, struct hda_gnode *node) | 625 | static unsigned int get_amp_mask_to_modify(struct hda_codec *codec, |
222 | { | 626 | hda_nid_t nid, int dir, int idx, |
223 | unsigned int val, ofs; | 627 | unsigned int caps) |
224 | snd_printdd("UNMUTE OUT: NID=0x%x\n", node->nid); | 628 | { |
225 | val = (node->amp_out_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | 629 | unsigned int mask = 0xff; |
226 | ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | 630 | |
227 | if (val >= ofs) | 631 | if (caps & AC_AMPCAP_MUTE) { |
228 | val -= ofs; | 632 | if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_MUTE_CTL)) |
229 | snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val); | 633 | mask &= ~0x80; |
230 | return 0; | 634 | } |
635 | if (caps & AC_AMPCAP_NUM_STEPS) { | ||
636 | if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_VOL_CTL) || | ||
637 | is_ctl_associated(codec, nid, dir, idx, NID_PATH_BOOST_CTL)) | ||
638 | mask &= ~0x7f; | ||
639 | } | ||
640 | return mask; | ||
231 | } | 641 | } |
232 | 642 | ||
233 | /* | 643 | static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir, |
234 | * unmute (and set max vol) the input amplifier | 644 | int idx, int idx_to_check, bool enable) |
645 | { | ||
646 | unsigned int caps; | ||
647 | unsigned int mask, val; | ||
648 | |||
649 | if (!enable && is_active_nid(codec, nid, dir, idx_to_check)) | ||
650 | return; | ||
651 | |||
652 | caps = query_amp_caps(codec, nid, dir); | ||
653 | val = get_amp_val_to_activate(codec, nid, dir, caps, enable); | ||
654 | mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps); | ||
655 | if (!mask) | ||
656 | return; | ||
657 | |||
658 | val &= mask; | ||
659 | snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val); | ||
660 | } | ||
661 | |||
662 | static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, | ||
663 | int i, bool enable) | ||
664 | { | ||
665 | hda_nid_t nid = path->path[i]; | ||
666 | init_amp(codec, nid, HDA_OUTPUT, 0); | ||
667 | activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable); | ||
668 | } | ||
669 | |||
670 | static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, | ||
671 | int i, bool enable, bool add_aamix) | ||
672 | { | ||
673 | struct hda_gen_spec *spec = codec->spec; | ||
674 | const hda_nid_t *conn; | ||
675 | int n, nums, idx; | ||
676 | int type; | ||
677 | hda_nid_t nid = path->path[i]; | ||
678 | |||
679 | nums = snd_hda_get_conn_list(codec, nid, &conn); | ||
680 | type = get_wcaps_type(get_wcaps(codec, nid)); | ||
681 | if (type == AC_WID_PIN || | ||
682 | (type == AC_WID_AUD_IN && codec->single_adc_amp)) { | ||
683 | nums = 1; | ||
684 | idx = 0; | ||
685 | } else | ||
686 | idx = path->idx[i]; | ||
687 | |||
688 | for (n = 0; n < nums; n++) | ||
689 | init_amp(codec, nid, HDA_INPUT, n); | ||
690 | |||
691 | /* here is a little bit tricky in comparison with activate_amp_out(); | ||
692 | * when aa-mixer is available, we need to enable the path as well | ||
693 | */ | ||
694 | for (n = 0; n < nums; n++) { | ||
695 | if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid)) | ||
696 | continue; | ||
697 | activate_amp(codec, nid, HDA_INPUT, n, idx, enable); | ||
698 | } | ||
699 | } | ||
700 | |||
701 | /* activate or deactivate the given path | ||
702 | * if @add_aamix is set, enable the input from aa-mix NID as well (if any) | ||
235 | */ | 703 | */ |
236 | static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigned int index) | 704 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, |
237 | { | 705 | bool enable, bool add_aamix) |
238 | unsigned int val, ofs; | 706 | { |
239 | snd_printdd("UNMUTE IN: NID=0x%x IDX=0x%x\n", node->nid, index); | 707 | struct hda_gen_spec *spec = codec->spec; |
240 | val = (node->amp_in_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | 708 | int i; |
241 | ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | 709 | |
242 | if (val >= ofs) | 710 | if (!enable) |
243 | val -= ofs; | 711 | path->active = false; |
244 | snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val); | 712 | |
245 | return 0; | 713 | for (i = path->depth - 1; i >= 0; i--) { |
714 | hda_nid_t nid = path->path[i]; | ||
715 | if (enable && spec->power_down_unused) { | ||
716 | /* make sure the widget is powered up */ | ||
717 | if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0)) | ||
718 | snd_hda_codec_write(codec, nid, 0, | ||
719 | AC_VERB_SET_POWER_STATE, | ||
720 | AC_PWRST_D0); | ||
721 | } | ||
722 | if (enable && path->multi[i]) | ||
723 | snd_hda_codec_write_cache(codec, nid, 0, | ||
724 | AC_VERB_SET_CONNECT_SEL, | ||
725 | path->idx[i]); | ||
726 | if (has_amp_in(codec, path, i)) | ||
727 | activate_amp_in(codec, path, i, enable, add_aamix); | ||
728 | if (has_amp_out(codec, path, i)) | ||
729 | activate_amp_out(codec, path, i, enable); | ||
730 | } | ||
731 | |||
732 | if (enable) | ||
733 | path->active = true; | ||
246 | } | 734 | } |
735 | EXPORT_SYMBOL_HDA(snd_hda_activate_path); | ||
736 | |||
737 | /* if the given path is inactive, put widgets into D3 (only if suitable) */ | ||
738 | static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) | ||
739 | { | ||
740 | struct hda_gen_spec *spec = codec->spec; | ||
741 | bool changed; | ||
742 | int i; | ||
743 | |||
744 | if (!spec->power_down_unused || path->active) | ||
745 | return; | ||
746 | |||
747 | for (i = 0; i < path->depth; i++) { | ||
748 | hda_nid_t nid = path->path[i]; | ||
749 | if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3)) { | ||
750 | snd_hda_codec_write(codec, nid, 0, | ||
751 | AC_VERB_SET_POWER_STATE, | ||
752 | AC_PWRST_D3); | ||
753 | changed = true; | ||
754 | } | ||
755 | } | ||
756 | |||
757 | if (changed) { | ||
758 | msleep(10); | ||
759 | snd_hda_codec_read(codec, path->path[0], 0, | ||
760 | AC_VERB_GET_POWER_STATE, 0); | ||
761 | } | ||
762 | } | ||
763 | |||
764 | /* turn on/off EAPD on the given pin */ | ||
765 | static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable) | ||
766 | { | ||
767 | struct hda_gen_spec *spec = codec->spec; | ||
768 | if (spec->own_eapd_ctl || | ||
769 | !(snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)) | ||
770 | return; | ||
771 | if (codec->inv_eapd) | ||
772 | enable = !enable; | ||
773 | snd_hda_codec_update_cache(codec, pin, 0, | ||
774 | AC_VERB_SET_EAPD_BTLENABLE, | ||
775 | enable ? 0x02 : 0x00); | ||
776 | } | ||
777 | |||
778 | /* re-initialize the path specified by the given path index */ | ||
779 | static void resume_path_from_idx(struct hda_codec *codec, int path_idx) | ||
780 | { | ||
781 | struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx); | ||
782 | if (path) | ||
783 | snd_hda_activate_path(codec, path, path->active, false); | ||
784 | } | ||
785 | |||
247 | 786 | ||
248 | /* | 787 | /* |
249 | * select the input connection of the given node. | 788 | * Helper functions for creating mixer ctl elements |
250 | */ | 789 | */ |
251 | static int select_input_connection(struct hda_codec *codec, struct hda_gnode *node, | 790 | |
252 | unsigned int index) | 791 | enum { |
792 | HDA_CTL_WIDGET_VOL, | ||
793 | HDA_CTL_WIDGET_MUTE, | ||
794 | HDA_CTL_BIND_MUTE, | ||
795 | }; | ||
796 | static const struct snd_kcontrol_new control_templates[] = { | ||
797 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
798 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
799 | HDA_BIND_MUTE(NULL, 0, 0, 0), | ||
800 | }; | ||
801 | |||
802 | /* add dynamic controls from template */ | ||
803 | static struct snd_kcontrol_new * | ||
804 | add_control(struct hda_gen_spec *spec, int type, const char *name, | ||
805 | int cidx, unsigned long val) | ||
253 | { | 806 | { |
254 | snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index); | 807 | struct snd_kcontrol_new *knew; |
255 | return snd_hda_codec_write_cache(codec, node->nid, 0, | 808 | |
256 | AC_VERB_SET_CONNECT_SEL, index); | 809 | knew = snd_hda_gen_add_kctl(spec, name, &control_templates[type]); |
810 | if (!knew) | ||
811 | return NULL; | ||
812 | knew->index = cidx; | ||
813 | if (get_amp_nid_(val)) | ||
814 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
815 | knew->private_value = val; | ||
816 | return knew; | ||
257 | } | 817 | } |
258 | 818 | ||
259 | /* | 819 | static int add_control_with_pfx(struct hda_gen_spec *spec, int type, |
260 | * clear checked flag of each node in the node list | 820 | const char *pfx, const char *dir, |
821 | const char *sfx, int cidx, unsigned long val) | ||
822 | { | ||
823 | char name[32]; | ||
824 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); | ||
825 | if (!add_control(spec, type, name, cidx, val)) | ||
826 | return -ENOMEM; | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ | ||
831 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) | ||
832 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ | ||
833 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) | ||
834 | #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ | ||
835 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) | ||
836 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ | ||
837 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) | ||
838 | |||
839 | static int add_vol_ctl(struct hda_codec *codec, const char *pfx, int cidx, | ||
840 | unsigned int chs, struct nid_path *path) | ||
841 | { | ||
842 | unsigned int val; | ||
843 | if (!path) | ||
844 | return 0; | ||
845 | val = path->ctls[NID_PATH_VOL_CTL]; | ||
846 | if (!val) | ||
847 | return 0; | ||
848 | val = amp_val_replace_channels(val, chs); | ||
849 | return __add_pb_vol_ctrl(codec->spec, HDA_CTL_WIDGET_VOL, pfx, cidx, val); | ||
850 | } | ||
851 | |||
852 | /* return the channel bits suitable for the given path->ctls[] */ | ||
853 | static int get_default_ch_nums(struct hda_codec *codec, struct nid_path *path, | ||
854 | int type) | ||
855 | { | ||
856 | int chs = 1; /* mono (left only) */ | ||
857 | if (path) { | ||
858 | hda_nid_t nid = get_amp_nid_(path->ctls[type]); | ||
859 | if (nid && (get_wcaps(codec, nid) & AC_WCAP_STEREO)) | ||
860 | chs = 3; /* stereo */ | ||
861 | } | ||
862 | return chs; | ||
863 | } | ||
864 | |||
865 | static int add_stereo_vol(struct hda_codec *codec, const char *pfx, int cidx, | ||
866 | struct nid_path *path) | ||
867 | { | ||
868 | int chs = get_default_ch_nums(codec, path, NID_PATH_VOL_CTL); | ||
869 | return add_vol_ctl(codec, pfx, cidx, chs, path); | ||
870 | } | ||
871 | |||
872 | /* create a mute-switch for the given mixer widget; | ||
873 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute | ||
261 | */ | 874 | */ |
262 | static void clear_check_flags(struct hda_gspec *spec) | 875 | static int add_sw_ctl(struct hda_codec *codec, const char *pfx, int cidx, |
876 | unsigned int chs, struct nid_path *path) | ||
877 | { | ||
878 | unsigned int val; | ||
879 | int type = HDA_CTL_WIDGET_MUTE; | ||
880 | |||
881 | if (!path) | ||
882 | return 0; | ||
883 | val = path->ctls[NID_PATH_MUTE_CTL]; | ||
884 | if (!val) | ||
885 | return 0; | ||
886 | val = amp_val_replace_channels(val, chs); | ||
887 | if (get_amp_direction_(val) == HDA_INPUT) { | ||
888 | hda_nid_t nid = get_amp_nid_(val); | ||
889 | int nums = snd_hda_get_num_conns(codec, nid); | ||
890 | if (nums > 1) { | ||
891 | type = HDA_CTL_BIND_MUTE; | ||
892 | val |= nums << 19; | ||
893 | } | ||
894 | } | ||
895 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); | ||
896 | } | ||
897 | |||
898 | static int add_stereo_sw(struct hda_codec *codec, const char *pfx, | ||
899 | int cidx, struct nid_path *path) | ||
900 | { | ||
901 | int chs = get_default_ch_nums(codec, path, NID_PATH_MUTE_CTL); | ||
902 | return add_sw_ctl(codec, pfx, cidx, chs, path); | ||
903 | } | ||
904 | |||
905 | /* any ctl assigned to the path with the given index? */ | ||
906 | static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) | ||
907 | { | ||
908 | struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx); | ||
909 | return path && path->ctls[ctl_type]; | ||
910 | } | ||
911 | |||
912 | static const char * const channel_name[4] = { | ||
913 | "Front", "Surround", "CLFE", "Side" | ||
914 | }; | ||
915 | |||
916 | /* give some appropriate ctl name prefix for the given line out channel */ | ||
917 | static const char *get_line_out_pfx(struct hda_codec *codec, int ch, | ||
918 | int *index, int ctl_type) | ||
263 | { | 919 | { |
264 | struct hda_gnode *node; | 920 | struct hda_gen_spec *spec = codec->spec; |
921 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
922 | |||
923 | *index = 0; | ||
924 | if (cfg->line_outs == 1 && !spec->multi_ios && | ||
925 | !cfg->hp_outs && !cfg->speaker_outs) | ||
926 | return spec->vmaster_mute.hook ? "PCM" : "Master"; | ||
927 | |||
928 | /* if there is really a single DAC used in the whole output paths, | ||
929 | * use it master (or "PCM" if a vmaster hook is present) | ||
930 | */ | ||
931 | if (spec->multiout.num_dacs == 1 && !spec->mixer_nid && | ||
932 | !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) | ||
933 | return spec->vmaster_mute.hook ? "PCM" : "Master"; | ||
934 | |||
935 | /* multi-io channels */ | ||
936 | if (ch >= cfg->line_outs) | ||
937 | return channel_name[ch]; | ||
938 | |||
939 | switch (cfg->line_out_type) { | ||
940 | case AUTO_PIN_SPEAKER_OUT: | ||
941 | /* if the primary channel vol/mute is shared with HP volume, | ||
942 | * don't name it as Speaker | ||
943 | */ | ||
944 | if (!ch && cfg->hp_outs && | ||
945 | !path_has_mixer(codec, spec->hp_paths[0], ctl_type)) | ||
946 | break; | ||
947 | if (cfg->line_outs == 1) | ||
948 | return "Speaker"; | ||
949 | if (cfg->line_outs == 2) | ||
950 | return ch ? "Bass Speaker" : "Speaker"; | ||
951 | break; | ||
952 | case AUTO_PIN_HP_OUT: | ||
953 | /* if the primary channel vol/mute is shared with spk volume, | ||
954 | * don't name it as Headphone | ||
955 | */ | ||
956 | if (!ch && cfg->speaker_outs && | ||
957 | !path_has_mixer(codec, spec->speaker_paths[0], ctl_type)) | ||
958 | break; | ||
959 | /* for multi-io case, only the primary out */ | ||
960 | if (ch && spec->multi_ios) | ||
961 | break; | ||
962 | *index = ch; | ||
963 | return "Headphone"; | ||
964 | } | ||
965 | |||
966 | /* for a single channel output, we don't have to name the channel */ | ||
967 | if (cfg->line_outs == 1 && !spec->multi_ios) | ||
968 | return "PCM"; | ||
265 | 969 | ||
266 | list_for_each_entry(node, &spec->nid_list, list) { | 970 | if (ch >= ARRAY_SIZE(channel_name)) { |
267 | node->checked = 0; | 971 | snd_BUG(); |
972 | return "PCM"; | ||
268 | } | 973 | } |
974 | |||
975 | return channel_name[ch]; | ||
269 | } | 976 | } |
270 | 977 | ||
271 | /* | 978 | /* |
272 | * parse the output path recursively until reach to an audio output widget | 979 | * Parse output paths |
980 | */ | ||
981 | |||
982 | /* badness definition */ | ||
983 | enum { | ||
984 | /* No primary DAC is found for the main output */ | ||
985 | BAD_NO_PRIMARY_DAC = 0x10000, | ||
986 | /* No DAC is found for the extra output */ | ||
987 | BAD_NO_DAC = 0x4000, | ||
988 | /* No possible multi-ios */ | ||
989 | BAD_MULTI_IO = 0x103, | ||
990 | /* No individual DAC for extra output */ | ||
991 | BAD_NO_EXTRA_DAC = 0x102, | ||
992 | /* No individual DAC for extra surrounds */ | ||
993 | BAD_NO_EXTRA_SURR_DAC = 0x101, | ||
994 | /* Primary DAC shared with main surrounds */ | ||
995 | BAD_SHARED_SURROUND = 0x100, | ||
996 | /* Primary DAC shared with main CLFE */ | ||
997 | BAD_SHARED_CLFE = 0x10, | ||
998 | /* Primary DAC shared with extra surrounds */ | ||
999 | BAD_SHARED_EXTRA_SURROUND = 0x10, | ||
1000 | /* Volume widget is shared */ | ||
1001 | BAD_SHARED_VOL = 0x10, | ||
1002 | }; | ||
1003 | |||
1004 | /* look for widgets in the given path which are appropriate for | ||
1005 | * volume and mute controls, and assign the values to ctls[]. | ||
273 | * | 1006 | * |
274 | * returns 0 if not found, 1 if found, or a negative error code. | 1007 | * When no appropriate widget is found in the path, the badness value |
1008 | * is incremented depending on the situation. The function returns the | ||
1009 | * total badness for both volume and mute controls. | ||
275 | */ | 1010 | */ |
276 | static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, | 1011 | static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path) |
277 | struct hda_gnode *node, int dac_idx) | ||
278 | { | 1012 | { |
279 | int i, err; | 1013 | hda_nid_t nid; |
280 | struct hda_gnode *child; | 1014 | unsigned int val; |
1015 | int badness = 0; | ||
1016 | |||
1017 | if (!path) | ||
1018 | return BAD_SHARED_VOL * 2; | ||
1019 | |||
1020 | if (path->ctls[NID_PATH_VOL_CTL] || | ||
1021 | path->ctls[NID_PATH_MUTE_CTL]) | ||
1022 | return 0; /* already evaluated */ | ||
281 | 1023 | ||
282 | if (node->checked) | 1024 | nid = look_for_out_vol_nid(codec, path); |
1025 | if (nid) { | ||
1026 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
1027 | if (is_ctl_used(codec, val, NID_PATH_VOL_CTL)) | ||
1028 | badness += BAD_SHARED_VOL; | ||
1029 | else | ||
1030 | path->ctls[NID_PATH_VOL_CTL] = val; | ||
1031 | } else | ||
1032 | badness += BAD_SHARED_VOL; | ||
1033 | nid = look_for_out_mute_nid(codec, path); | ||
1034 | if (nid) { | ||
1035 | unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid)); | ||
1036 | if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT || | ||
1037 | nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
1038 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
1039 | else | ||
1040 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT); | ||
1041 | if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL)) | ||
1042 | badness += BAD_SHARED_VOL; | ||
1043 | else | ||
1044 | path->ctls[NID_PATH_MUTE_CTL] = val; | ||
1045 | } else | ||
1046 | badness += BAD_SHARED_VOL; | ||
1047 | return badness; | ||
1048 | } | ||
1049 | |||
1050 | struct badness_table { | ||
1051 | int no_primary_dac; /* no primary DAC */ | ||
1052 | int no_dac; /* no secondary DACs */ | ||
1053 | int shared_primary; /* primary DAC is shared with main output */ | ||
1054 | int shared_surr; /* secondary DAC shared with main or primary */ | ||
1055 | int shared_clfe; /* third DAC shared with main or primary */ | ||
1056 | int shared_surr_main; /* secondary DAC sahred with main/DAC0 */ | ||
1057 | }; | ||
1058 | |||
1059 | static struct badness_table main_out_badness = { | ||
1060 | .no_primary_dac = BAD_NO_PRIMARY_DAC, | ||
1061 | .no_dac = BAD_NO_DAC, | ||
1062 | .shared_primary = BAD_NO_PRIMARY_DAC, | ||
1063 | .shared_surr = BAD_SHARED_SURROUND, | ||
1064 | .shared_clfe = BAD_SHARED_CLFE, | ||
1065 | .shared_surr_main = BAD_SHARED_SURROUND, | ||
1066 | }; | ||
1067 | |||
1068 | static struct badness_table extra_out_badness = { | ||
1069 | .no_primary_dac = BAD_NO_DAC, | ||
1070 | .no_dac = BAD_NO_DAC, | ||
1071 | .shared_primary = BAD_NO_EXTRA_DAC, | ||
1072 | .shared_surr = BAD_SHARED_EXTRA_SURROUND, | ||
1073 | .shared_clfe = BAD_SHARED_EXTRA_SURROUND, | ||
1074 | .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, | ||
1075 | }; | ||
1076 | |||
1077 | /* get the DAC of the primary output corresponding to the given array index */ | ||
1078 | static hda_nid_t get_primary_out(struct hda_codec *codec, int idx) | ||
1079 | { | ||
1080 | struct hda_gen_spec *spec = codec->spec; | ||
1081 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1082 | |||
1083 | if (cfg->line_outs > idx) | ||
1084 | return spec->private_dac_nids[idx]; | ||
1085 | idx -= cfg->line_outs; | ||
1086 | if (spec->multi_ios > idx) | ||
1087 | return spec->multi_io[idx].dac; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | /* return the DAC if it's reachable, otherwise zero */ | ||
1092 | static inline hda_nid_t try_dac(struct hda_codec *codec, | ||
1093 | hda_nid_t dac, hda_nid_t pin) | ||
1094 | { | ||
1095 | return is_reachable_path(codec, dac, pin) ? dac : 0; | ||
1096 | } | ||
1097 | |||
1098 | /* try to assign DACs to pins and return the resultant badness */ | ||
1099 | static int try_assign_dacs(struct hda_codec *codec, int num_outs, | ||
1100 | const hda_nid_t *pins, hda_nid_t *dacs, | ||
1101 | int *path_idx, | ||
1102 | const struct badness_table *bad) | ||
1103 | { | ||
1104 | struct hda_gen_spec *spec = codec->spec; | ||
1105 | int i, j; | ||
1106 | int badness = 0; | ||
1107 | hda_nid_t dac; | ||
1108 | |||
1109 | if (!num_outs) | ||
283 | return 0; | 1110 | return 0; |
284 | 1111 | ||
285 | node->checked = 1; | 1112 | for (i = 0; i < num_outs; i++) { |
286 | if (node->type == AC_WID_AUD_OUT) { | 1113 | struct nid_path *path; |
287 | if (node->wid_caps & AC_WCAP_DIGITAL) { | 1114 | hda_nid_t pin = pins[i]; |
288 | snd_printdd("Skip Digital OUT node %x\n", node->nid); | 1115 | |
289 | return 0; | 1116 | path = snd_hda_get_path_from_idx(codec, path_idx[i]); |
1117 | if (path) { | ||
1118 | badness += assign_out_path_ctls(codec, path); | ||
1119 | continue; | ||
1120 | } | ||
1121 | |||
1122 | dacs[i] = look_for_dac(codec, pin, false); | ||
1123 | if (!dacs[i] && !i) { | ||
1124 | /* try to steal the DAC of surrounds for the front */ | ||
1125 | for (j = 1; j < num_outs; j++) { | ||
1126 | if (is_reachable_path(codec, dacs[j], pin)) { | ||
1127 | dacs[0] = dacs[j]; | ||
1128 | dacs[j] = 0; | ||
1129 | invalidate_nid_path(codec, path_idx[j]); | ||
1130 | path_idx[j] = 0; | ||
1131 | break; | ||
1132 | } | ||
1133 | } | ||
1134 | } | ||
1135 | dac = dacs[i]; | ||
1136 | if (!dac) { | ||
1137 | if (num_outs > 2) | ||
1138 | dac = try_dac(codec, get_primary_out(codec, i), pin); | ||
1139 | if (!dac) | ||
1140 | dac = try_dac(codec, dacs[0], pin); | ||
1141 | if (!dac) | ||
1142 | dac = try_dac(codec, get_primary_out(codec, i), pin); | ||
1143 | if (dac) { | ||
1144 | if (!i) | ||
1145 | badness += bad->shared_primary; | ||
1146 | else if (i == 1) | ||
1147 | badness += bad->shared_surr; | ||
1148 | else | ||
1149 | badness += bad->shared_clfe; | ||
1150 | } else if (is_reachable_path(codec, spec->private_dac_nids[0], pin)) { | ||
1151 | dac = spec->private_dac_nids[0]; | ||
1152 | badness += bad->shared_surr_main; | ||
1153 | } else if (!i) | ||
1154 | badness += bad->no_primary_dac; | ||
1155 | else | ||
1156 | badness += bad->no_dac; | ||
290 | } | 1157 | } |
291 | snd_printdd("AUD_OUT found %x\n", node->nid); | 1158 | if (!dac) |
292 | if (spec->dac_node[dac_idx]) { | 1159 | continue; |
293 | /* already DAC node is assigned, just unmute & connect */ | 1160 | path = snd_hda_add_new_path(codec, dac, pin, -spec->mixer_nid); |
294 | return node == spec->dac_node[dac_idx]; | 1161 | if (!path && !i && spec->mixer_nid) { |
1162 | /* try with aamix */ | ||
1163 | path = snd_hda_add_new_path(codec, dac, pin, 0); | ||
295 | } | 1164 | } |
296 | spec->dac_node[dac_idx] = node; | 1165 | if (!path) { |
297 | if ((node->wid_caps & AC_WCAP_OUT_AMP) && | 1166 | dac = dacs[i] = 0; |
298 | spec->pcm_vol_nodes < MAX_PCM_VOLS) { | 1167 | badness += bad->no_dac; |
299 | spec->pcm_vol[spec->pcm_vol_nodes].node = node; | 1168 | } else { |
300 | spec->pcm_vol[spec->pcm_vol_nodes].index = 0; | 1169 | /* print_nid_path("output", path); */ |
301 | spec->pcm_vol_nodes++; | 1170 | path->active = true; |
1171 | path_idx[i] = snd_hda_get_path_idx(codec, path); | ||
1172 | badness += assign_out_path_ctls(codec, path); | ||
302 | } | 1173 | } |
303 | return 1; /* found */ | ||
304 | } | 1174 | } |
305 | 1175 | ||
306 | for (i = 0; i < node->nconns; i++) { | 1176 | return badness; |
307 | child = hda_get_node(spec, node->conn_list[i]); | 1177 | } |
308 | if (! child) | 1178 | |
1179 | /* return NID if the given pin has only a single connection to a certain DAC */ | ||
1180 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | ||
1181 | { | ||
1182 | struct hda_gen_spec *spec = codec->spec; | ||
1183 | int i; | ||
1184 | hda_nid_t nid_found = 0; | ||
1185 | |||
1186 | for (i = 0; i < spec->num_all_dacs; i++) { | ||
1187 | hda_nid_t nid = spec->all_dacs[i]; | ||
1188 | if (!nid || is_dac_already_used(codec, nid)) | ||
309 | continue; | 1189 | continue; |
310 | err = parse_output_path(codec, spec, child, dac_idx); | 1190 | if (is_reachable_path(codec, nid, pin)) { |
311 | if (err < 0) | 1191 | if (nid_found) |
312 | return err; | 1192 | return 0; |
313 | else if (err > 0) { | 1193 | nid_found = nid; |
314 | /* found one, | ||
315 | * select the path, unmute both input and output | ||
316 | */ | ||
317 | if (node->nconns > 1) | ||
318 | select_input_connection(codec, node, i); | ||
319 | unmute_input(codec, node, i); | ||
320 | unmute_output(codec, node); | ||
321 | if (spec->dac_node[dac_idx] && | ||
322 | spec->pcm_vol_nodes < MAX_PCM_VOLS && | ||
323 | !(spec->dac_node[dac_idx]->wid_caps & | ||
324 | AC_WCAP_OUT_AMP)) { | ||
325 | if ((node->wid_caps & AC_WCAP_IN_AMP) || | ||
326 | (node->wid_caps & AC_WCAP_OUT_AMP)) { | ||
327 | int n = spec->pcm_vol_nodes; | ||
328 | spec->pcm_vol[n].node = node; | ||
329 | spec->pcm_vol[n].index = i; | ||
330 | spec->pcm_vol_nodes++; | ||
331 | } | ||
332 | } | ||
333 | return 1; | ||
334 | } | 1194 | } |
335 | } | 1195 | } |
336 | return 0; | 1196 | return nid_found; |
1197 | } | ||
1198 | |||
1199 | /* check whether the given pin can be a multi-io pin */ | ||
1200 | static bool can_be_multiio_pin(struct hda_codec *codec, | ||
1201 | unsigned int location, hda_nid_t nid) | ||
1202 | { | ||
1203 | unsigned int defcfg, caps; | ||
1204 | |||
1205 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
1206 | if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) | ||
1207 | return false; | ||
1208 | if (location && get_defcfg_location(defcfg) != location) | ||
1209 | return false; | ||
1210 | caps = snd_hda_query_pin_caps(codec, nid); | ||
1211 | if (!(caps & AC_PINCAP_OUT)) | ||
1212 | return false; | ||
1213 | return true; | ||
1214 | } | ||
1215 | |||
1216 | /* count the number of input pins that are capable to be multi-io */ | ||
1217 | static int count_multiio_pins(struct hda_codec *codec, hda_nid_t reference_pin) | ||
1218 | { | ||
1219 | struct hda_gen_spec *spec = codec->spec; | ||
1220 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1221 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); | ||
1222 | unsigned int location = get_defcfg_location(defcfg); | ||
1223 | int type, i; | ||
1224 | int num_pins = 0; | ||
1225 | |||
1226 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
1227 | for (i = 0; i < cfg->num_inputs; i++) { | ||
1228 | if (cfg->inputs[i].type != type) | ||
1229 | continue; | ||
1230 | if (can_be_multiio_pin(codec, location, | ||
1231 | cfg->inputs[i].pin)) | ||
1232 | num_pins++; | ||
1233 | } | ||
1234 | } | ||
1235 | return num_pins; | ||
337 | } | 1236 | } |
338 | 1237 | ||
339 | /* | 1238 | /* |
340 | * Look for the output PIN widget with the given jack type | 1239 | * multi-io helper |
341 | * and parse the output path to that PIN. | ||
342 | * | 1240 | * |
343 | * Returns the PIN node when the path to DAC is established. | 1241 | * When hardwired is set, try to fill ony hardwired pins, and returns |
1242 | * zero if any pins are filled, non-zero if nothing found. | ||
1243 | * When hardwired is off, try to fill possible input pins, and returns | ||
1244 | * the badness value. | ||
344 | */ | 1245 | */ |
345 | static struct hda_gnode *parse_output_jack(struct hda_codec *codec, | 1246 | static int fill_multi_ios(struct hda_codec *codec, |
346 | struct hda_gspec *spec, | 1247 | hda_nid_t reference_pin, |
347 | int jack_type) | 1248 | bool hardwired) |
348 | { | 1249 | { |
349 | struct hda_gnode *node; | 1250 | struct hda_gen_spec *spec = codec->spec; |
350 | int err; | 1251 | struct auto_pin_cfg *cfg = &spec->autocfg; |
1252 | int type, i, j, num_pins, old_pins; | ||
1253 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); | ||
1254 | unsigned int location = get_defcfg_location(defcfg); | ||
1255 | int badness = 0; | ||
1256 | struct nid_path *path; | ||
351 | 1257 | ||
352 | list_for_each_entry(node, &spec->nid_list, list) { | 1258 | old_pins = spec->multi_ios; |
353 | if (node->type != AC_WID_PIN) | 1259 | if (old_pins >= 2) |
354 | continue; | 1260 | goto end_fill; |
355 | /* output capable? */ | 1261 | |
356 | if (! (node->pin_caps & AC_PINCAP_OUT)) | 1262 | num_pins = count_multiio_pins(codec, reference_pin); |
357 | continue; | 1263 | if (num_pins < 2) |
358 | if (defcfg_port_conn(node) == AC_JACK_PORT_NONE) | 1264 | goto end_fill; |
359 | continue; /* unconnected */ | 1265 | |
360 | if (jack_type >= 0) { | 1266 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { |
361 | if (jack_type != defcfg_type(node)) | 1267 | for (i = 0; i < cfg->num_inputs; i++) { |
1268 | hda_nid_t nid = cfg->inputs[i].pin; | ||
1269 | hda_nid_t dac = 0; | ||
1270 | |||
1271 | if (cfg->inputs[i].type != type) | ||
362 | continue; | 1272 | continue; |
363 | if (node->wid_caps & AC_WCAP_DIGITAL) | 1273 | if (!can_be_multiio_pin(codec, location, nid)) |
364 | continue; /* skip SPDIF */ | 1274 | continue; |
365 | } else { | 1275 | for (j = 0; j < spec->multi_ios; j++) { |
366 | /* output as default? */ | 1276 | if (nid == spec->multi_io[j].pin) |
367 | if (! (node->pin_ctl & AC_PINCTL_OUT_EN)) | 1277 | break; |
1278 | } | ||
1279 | if (j < spec->multi_ios) | ||
368 | continue; | 1280 | continue; |
1281 | |||
1282 | if (hardwired) | ||
1283 | dac = get_dac_if_single(codec, nid); | ||
1284 | else if (!dac) | ||
1285 | dac = look_for_dac(codec, nid, false); | ||
1286 | if (!dac) { | ||
1287 | badness++; | ||
1288 | continue; | ||
1289 | } | ||
1290 | path = snd_hda_add_new_path(codec, dac, nid, | ||
1291 | -spec->mixer_nid); | ||
1292 | if (!path) { | ||
1293 | badness++; | ||
1294 | continue; | ||
1295 | } | ||
1296 | /* print_nid_path("multiio", path); */ | ||
1297 | spec->multi_io[spec->multi_ios].pin = nid; | ||
1298 | spec->multi_io[spec->multi_ios].dac = dac; | ||
1299 | spec->out_paths[cfg->line_outs + spec->multi_ios] = | ||
1300 | snd_hda_get_path_idx(codec, path); | ||
1301 | spec->multi_ios++; | ||
1302 | if (spec->multi_ios >= 2) | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | end_fill: | ||
1307 | if (badness) | ||
1308 | badness = BAD_MULTI_IO; | ||
1309 | if (old_pins == spec->multi_ios) { | ||
1310 | if (hardwired) | ||
1311 | return 1; /* nothing found */ | ||
1312 | else | ||
1313 | return badness; /* no badness if nothing found */ | ||
1314 | } | ||
1315 | if (!hardwired && spec->multi_ios < 2) { | ||
1316 | /* cancel newly assigned paths */ | ||
1317 | spec->paths.used -= spec->multi_ios - old_pins; | ||
1318 | spec->multi_ios = old_pins; | ||
1319 | return badness; | ||
1320 | } | ||
1321 | |||
1322 | /* assign volume and mute controls */ | ||
1323 | for (i = old_pins; i < spec->multi_ios; i++) { | ||
1324 | path = snd_hda_get_path_from_idx(codec, spec->out_paths[cfg->line_outs + i]); | ||
1325 | badness += assign_out_path_ctls(codec, path); | ||
1326 | } | ||
1327 | |||
1328 | return badness; | ||
1329 | } | ||
1330 | |||
1331 | /* map DACs for all pins in the list if they are single connections */ | ||
1332 | static bool map_singles(struct hda_codec *codec, int outs, | ||
1333 | const hda_nid_t *pins, hda_nid_t *dacs, int *path_idx) | ||
1334 | { | ||
1335 | struct hda_gen_spec *spec = codec->spec; | ||
1336 | int i; | ||
1337 | bool found = false; | ||
1338 | for (i = 0; i < outs; i++) { | ||
1339 | struct nid_path *path; | ||
1340 | hda_nid_t dac; | ||
1341 | if (dacs[i]) | ||
1342 | continue; | ||
1343 | dac = get_dac_if_single(codec, pins[i]); | ||
1344 | if (!dac) | ||
1345 | continue; | ||
1346 | path = snd_hda_add_new_path(codec, dac, pins[i], | ||
1347 | -spec->mixer_nid); | ||
1348 | if (!path && !i && spec->mixer_nid) | ||
1349 | path = snd_hda_add_new_path(codec, dac, pins[i], 0); | ||
1350 | if (path) { | ||
1351 | dacs[i] = dac; | ||
1352 | found = true; | ||
1353 | /* print_nid_path("output", path); */ | ||
1354 | path->active = true; | ||
1355 | path_idx[i] = snd_hda_get_path_idx(codec, path); | ||
369 | } | 1356 | } |
370 | clear_check_flags(spec); | 1357 | } |
371 | err = parse_output_path(codec, spec, node, 0); | 1358 | return found; |
1359 | } | ||
1360 | |||
1361 | /* create a new path including aamix if available, and return its index */ | ||
1362 | static int check_aamix_out_path(struct hda_codec *codec, int path_idx) | ||
1363 | { | ||
1364 | struct hda_gen_spec *spec = codec->spec; | ||
1365 | struct nid_path *path; | ||
1366 | hda_nid_t dac, pin; | ||
1367 | |||
1368 | path = snd_hda_get_path_from_idx(codec, path_idx); | ||
1369 | if (!path || !path->depth || | ||
1370 | is_nid_contained(path, spec->mixer_nid)) | ||
1371 | return 0; | ||
1372 | dac = path->path[0]; | ||
1373 | pin = path->path[path->depth - 1]; | ||
1374 | path = snd_hda_add_new_path(codec, dac, pin, spec->mixer_nid); | ||
1375 | if (!path) { | ||
1376 | if (dac != spec->multiout.dac_nids[0]) | ||
1377 | dac = spec->multiout.dac_nids[0]; | ||
1378 | else if (spec->multiout.hp_out_nid[0]) | ||
1379 | dac = spec->multiout.hp_out_nid[0]; | ||
1380 | else if (spec->multiout.extra_out_nid[0]) | ||
1381 | dac = spec->multiout.extra_out_nid[0]; | ||
1382 | if (dac) | ||
1383 | path = snd_hda_add_new_path(codec, dac, pin, | ||
1384 | spec->mixer_nid); | ||
1385 | } | ||
1386 | if (!path) | ||
1387 | return 0; | ||
1388 | /* print_nid_path("output-aamix", path); */ | ||
1389 | path->active = false; /* unused as default */ | ||
1390 | return snd_hda_get_path_idx(codec, path); | ||
1391 | } | ||
1392 | |||
1393 | /* fill the empty entries in the dac array for speaker/hp with the | ||
1394 | * shared dac pointed by the paths | ||
1395 | */ | ||
1396 | static void refill_shared_dacs(struct hda_codec *codec, int num_outs, | ||
1397 | hda_nid_t *dacs, int *path_idx) | ||
1398 | { | ||
1399 | struct nid_path *path; | ||
1400 | int i; | ||
1401 | |||
1402 | for (i = 0; i < num_outs; i++) { | ||
1403 | if (dacs[i]) | ||
1404 | continue; | ||
1405 | path = snd_hda_get_path_from_idx(codec, path_idx[i]); | ||
1406 | if (!path) | ||
1407 | continue; | ||
1408 | dacs[i] = path->path[0]; | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1412 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
1413 | static int fill_and_eval_dacs(struct hda_codec *codec, | ||
1414 | bool fill_hardwired, | ||
1415 | bool fill_mio_first) | ||
1416 | { | ||
1417 | struct hda_gen_spec *spec = codec->spec; | ||
1418 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1419 | int i, err, badness; | ||
1420 | |||
1421 | /* set num_dacs once to full for look_for_dac() */ | ||
1422 | spec->multiout.num_dacs = cfg->line_outs; | ||
1423 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
1424 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | ||
1425 | memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid)); | ||
1426 | memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid)); | ||
1427 | spec->multi_ios = 0; | ||
1428 | snd_array_free(&spec->paths); | ||
1429 | |||
1430 | /* clear path indices */ | ||
1431 | memset(spec->out_paths, 0, sizeof(spec->out_paths)); | ||
1432 | memset(spec->hp_paths, 0, sizeof(spec->hp_paths)); | ||
1433 | memset(spec->speaker_paths, 0, sizeof(spec->speaker_paths)); | ||
1434 | memset(spec->aamix_out_paths, 0, sizeof(spec->aamix_out_paths)); | ||
1435 | memset(spec->digout_paths, 0, sizeof(spec->digout_paths)); | ||
1436 | memset(spec->input_paths, 0, sizeof(spec->input_paths)); | ||
1437 | memset(spec->loopback_paths, 0, sizeof(spec->loopback_paths)); | ||
1438 | memset(&spec->digin_path, 0, sizeof(spec->digin_path)); | ||
1439 | |||
1440 | badness = 0; | ||
1441 | |||
1442 | /* fill hard-wired DACs first */ | ||
1443 | if (fill_hardwired) { | ||
1444 | bool mapped; | ||
1445 | do { | ||
1446 | mapped = map_singles(codec, cfg->line_outs, | ||
1447 | cfg->line_out_pins, | ||
1448 | spec->private_dac_nids, | ||
1449 | spec->out_paths); | ||
1450 | mapped |= map_singles(codec, cfg->hp_outs, | ||
1451 | cfg->hp_pins, | ||
1452 | spec->multiout.hp_out_nid, | ||
1453 | spec->hp_paths); | ||
1454 | mapped |= map_singles(codec, cfg->speaker_outs, | ||
1455 | cfg->speaker_pins, | ||
1456 | spec->multiout.extra_out_nid, | ||
1457 | spec->speaker_paths); | ||
1458 | if (fill_mio_first && cfg->line_outs == 1 && | ||
1459 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
1460 | err = fill_multi_ios(codec, cfg->line_out_pins[0], true); | ||
1461 | if (!err) | ||
1462 | mapped = true; | ||
1463 | } | ||
1464 | } while (mapped); | ||
1465 | } | ||
1466 | |||
1467 | badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins, | ||
1468 | spec->private_dac_nids, spec->out_paths, | ||
1469 | &main_out_badness); | ||
1470 | |||
1471 | if (fill_mio_first && | ||
1472 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
1473 | /* try to fill multi-io first */ | ||
1474 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false); | ||
1475 | if (err < 0) | ||
1476 | return err; | ||
1477 | /* we don't count badness at this stage yet */ | ||
1478 | } | ||
1479 | |||
1480 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { | ||
1481 | err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins, | ||
1482 | spec->multiout.hp_out_nid, | ||
1483 | spec->hp_paths, | ||
1484 | &extra_out_badness); | ||
1485 | if (err < 0) | ||
1486 | return err; | ||
1487 | badness += err; | ||
1488 | } | ||
1489 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
1490 | err = try_assign_dacs(codec, cfg->speaker_outs, | ||
1491 | cfg->speaker_pins, | ||
1492 | spec->multiout.extra_out_nid, | ||
1493 | spec->speaker_paths, | ||
1494 | &extra_out_badness); | ||
1495 | if (err < 0) | ||
1496 | return err; | ||
1497 | badness += err; | ||
1498 | } | ||
1499 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
1500 | err = fill_multi_ios(codec, cfg->line_out_pins[0], false); | ||
372 | if (err < 0) | 1501 | if (err < 0) |
373 | return NULL; | 1502 | return err; |
374 | if (! err && spec->out_pin_node[0]) { | 1503 | badness += err; |
375 | err = parse_output_path(codec, spec, node, 1); | 1504 | } |
1505 | |||
1506 | if (spec->mixer_nid) { | ||
1507 | spec->aamix_out_paths[0] = | ||
1508 | check_aamix_out_path(codec, spec->out_paths[0]); | ||
1509 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | ||
1510 | spec->aamix_out_paths[1] = | ||
1511 | check_aamix_out_path(codec, spec->hp_paths[0]); | ||
1512 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
1513 | spec->aamix_out_paths[2] = | ||
1514 | check_aamix_out_path(codec, spec->speaker_paths[0]); | ||
1515 | } | ||
1516 | |||
1517 | if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1518 | if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) | ||
1519 | spec->multi_ios = 1; /* give badness */ | ||
1520 | |||
1521 | /* re-count num_dacs and squash invalid entries */ | ||
1522 | spec->multiout.num_dacs = 0; | ||
1523 | for (i = 0; i < cfg->line_outs; i++) { | ||
1524 | if (spec->private_dac_nids[i]) | ||
1525 | spec->multiout.num_dacs++; | ||
1526 | else { | ||
1527 | memmove(spec->private_dac_nids + i, | ||
1528 | spec->private_dac_nids + i + 1, | ||
1529 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | ||
1530 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
1531 | } | ||
1532 | } | ||
1533 | |||
1534 | spec->ext_channel_count = spec->min_channel_count = | ||
1535 | spec->multiout.num_dacs * 2; | ||
1536 | |||
1537 | if (spec->multi_ios == 2) { | ||
1538 | for (i = 0; i < 2; i++) | ||
1539 | spec->private_dac_nids[spec->multiout.num_dacs++] = | ||
1540 | spec->multi_io[i].dac; | ||
1541 | } else if (spec->multi_ios) { | ||
1542 | spec->multi_ios = 0; | ||
1543 | badness += BAD_MULTI_IO; | ||
1544 | } | ||
1545 | |||
1546 | /* re-fill the shared DAC for speaker / headphone */ | ||
1547 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | ||
1548 | refill_shared_dacs(codec, cfg->hp_outs, | ||
1549 | spec->multiout.hp_out_nid, | ||
1550 | spec->hp_paths); | ||
1551 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
1552 | refill_shared_dacs(codec, cfg->speaker_outs, | ||
1553 | spec->multiout.extra_out_nid, | ||
1554 | spec->speaker_paths); | ||
1555 | |||
1556 | return badness; | ||
1557 | } | ||
1558 | |||
1559 | #define DEBUG_BADNESS | ||
1560 | |||
1561 | #ifdef DEBUG_BADNESS | ||
1562 | #define debug_badness snd_printdd | ||
1563 | #else | ||
1564 | #define debug_badness(...) | ||
1565 | #endif | ||
1566 | |||
1567 | #ifdef DEBUG_BADNESS | ||
1568 | static inline void print_nid_path_idx(struct hda_codec *codec, | ||
1569 | const char *pfx, int idx) | ||
1570 | { | ||
1571 | struct nid_path *path; | ||
1572 | |||
1573 | path = snd_hda_get_path_from_idx(codec, idx); | ||
1574 | if (path) | ||
1575 | print_nid_path(pfx, path); | ||
1576 | } | ||
1577 | |||
1578 | static void debug_show_configs(struct hda_codec *codec, | ||
1579 | struct auto_pin_cfg *cfg) | ||
1580 | { | ||
1581 | struct hda_gen_spec *spec = codec->spec; | ||
1582 | static const char * const lo_type[3] = { "LO", "SP", "HP" }; | ||
1583 | int i; | ||
1584 | |||
1585 | debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x (type %s)\n", | ||
1586 | cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
1587 | cfg->line_out_pins[2], cfg->line_out_pins[3], | ||
1588 | spec->multiout.dac_nids[0], | ||
1589 | spec->multiout.dac_nids[1], | ||
1590 | spec->multiout.dac_nids[2], | ||
1591 | spec->multiout.dac_nids[3], | ||
1592 | lo_type[cfg->line_out_type]); | ||
1593 | for (i = 0; i < cfg->line_outs; i++) | ||
1594 | print_nid_path_idx(codec, " out", spec->out_paths[i]); | ||
1595 | if (spec->multi_ios > 0) | ||
1596 | debug_badness("multi_ios(%d) = %x/%x : %x/%x\n", | ||
1597 | spec->multi_ios, | ||
1598 | spec->multi_io[0].pin, spec->multi_io[1].pin, | ||
1599 | spec->multi_io[0].dac, spec->multi_io[1].dac); | ||
1600 | for (i = 0; i < spec->multi_ios; i++) | ||
1601 | print_nid_path_idx(codec, " mio", | ||
1602 | spec->out_paths[cfg->line_outs + i]); | ||
1603 | if (cfg->hp_outs) | ||
1604 | debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
1605 | cfg->hp_pins[0], cfg->hp_pins[1], | ||
1606 | cfg->hp_pins[2], cfg->hp_pins[3], | ||
1607 | spec->multiout.hp_out_nid[0], | ||
1608 | spec->multiout.hp_out_nid[1], | ||
1609 | spec->multiout.hp_out_nid[2], | ||
1610 | spec->multiout.hp_out_nid[3]); | ||
1611 | for (i = 0; i < cfg->hp_outs; i++) | ||
1612 | print_nid_path_idx(codec, " hp ", spec->hp_paths[i]); | ||
1613 | if (cfg->speaker_outs) | ||
1614 | debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
1615 | cfg->speaker_pins[0], cfg->speaker_pins[1], | ||
1616 | cfg->speaker_pins[2], cfg->speaker_pins[3], | ||
1617 | spec->multiout.extra_out_nid[0], | ||
1618 | spec->multiout.extra_out_nid[1], | ||
1619 | spec->multiout.extra_out_nid[2], | ||
1620 | spec->multiout.extra_out_nid[3]); | ||
1621 | for (i = 0; i < cfg->speaker_outs; i++) | ||
1622 | print_nid_path_idx(codec, " spk", spec->speaker_paths[i]); | ||
1623 | for (i = 0; i < 3; i++) | ||
1624 | print_nid_path_idx(codec, " mix", spec->aamix_out_paths[i]); | ||
1625 | } | ||
1626 | #else | ||
1627 | #define debug_show_configs(codec, cfg) /* NOP */ | ||
1628 | #endif | ||
1629 | |||
1630 | /* find all available DACs of the codec */ | ||
1631 | static void fill_all_dac_nids(struct hda_codec *codec) | ||
1632 | { | ||
1633 | struct hda_gen_spec *spec = codec->spec; | ||
1634 | int i; | ||
1635 | hda_nid_t nid = codec->start_nid; | ||
1636 | |||
1637 | spec->num_all_dacs = 0; | ||
1638 | memset(spec->all_dacs, 0, sizeof(spec->all_dacs)); | ||
1639 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
1640 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_OUT) | ||
1641 | continue; | ||
1642 | if (spec->num_all_dacs >= ARRAY_SIZE(spec->all_dacs)) { | ||
1643 | snd_printk(KERN_ERR "hda: Too many DACs!\n"); | ||
1644 | break; | ||
1645 | } | ||
1646 | spec->all_dacs[spec->num_all_dacs++] = nid; | ||
1647 | } | ||
1648 | } | ||
1649 | |||
1650 | static int parse_output_paths(struct hda_codec *codec) | ||
1651 | { | ||
1652 | struct hda_gen_spec *spec = codec->spec; | ||
1653 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1654 | struct auto_pin_cfg *best_cfg; | ||
1655 | unsigned int val; | ||
1656 | int best_badness = INT_MAX; | ||
1657 | int badness; | ||
1658 | bool fill_hardwired = true, fill_mio_first = true; | ||
1659 | bool best_wired = true, best_mio = true; | ||
1660 | bool hp_spk_swapped = false; | ||
1661 | |||
1662 | best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL); | ||
1663 | if (!best_cfg) | ||
1664 | return -ENOMEM; | ||
1665 | *best_cfg = *cfg; | ||
1666 | |||
1667 | for (;;) { | ||
1668 | badness = fill_and_eval_dacs(codec, fill_hardwired, | ||
1669 | fill_mio_first); | ||
1670 | if (badness < 0) { | ||
1671 | kfree(best_cfg); | ||
1672 | return badness; | ||
1673 | } | ||
1674 | debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", | ||
1675 | cfg->line_out_type, fill_hardwired, fill_mio_first, | ||
1676 | badness); | ||
1677 | debug_show_configs(codec, cfg); | ||
1678 | if (badness < best_badness) { | ||
1679 | best_badness = badness; | ||
1680 | *best_cfg = *cfg; | ||
1681 | best_wired = fill_hardwired; | ||
1682 | best_mio = fill_mio_first; | ||
1683 | } | ||
1684 | if (!badness) | ||
1685 | break; | ||
1686 | fill_mio_first = !fill_mio_first; | ||
1687 | if (!fill_mio_first) | ||
1688 | continue; | ||
1689 | fill_hardwired = !fill_hardwired; | ||
1690 | if (!fill_hardwired) | ||
1691 | continue; | ||
1692 | if (hp_spk_swapped) | ||
1693 | break; | ||
1694 | hp_spk_swapped = true; | ||
1695 | if (cfg->speaker_outs > 0 && | ||
1696 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
1697 | cfg->hp_outs = cfg->line_outs; | ||
1698 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
1699 | sizeof(cfg->hp_pins)); | ||
1700 | cfg->line_outs = cfg->speaker_outs; | ||
1701 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
1702 | sizeof(cfg->speaker_pins)); | ||
1703 | cfg->speaker_outs = 0; | ||
1704 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
1705 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
1706 | fill_hardwired = true; | ||
1707 | continue; | ||
1708 | } | ||
1709 | if (cfg->hp_outs > 0 && | ||
1710 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
1711 | cfg->speaker_outs = cfg->line_outs; | ||
1712 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
1713 | sizeof(cfg->speaker_pins)); | ||
1714 | cfg->line_outs = cfg->hp_outs; | ||
1715 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
1716 | sizeof(cfg->hp_pins)); | ||
1717 | cfg->hp_outs = 0; | ||
1718 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
1719 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
1720 | fill_hardwired = true; | ||
1721 | continue; | ||
1722 | } | ||
1723 | break; | ||
1724 | } | ||
1725 | |||
1726 | if (badness) { | ||
1727 | debug_badness("==> restoring best_cfg\n"); | ||
1728 | *cfg = *best_cfg; | ||
1729 | fill_and_eval_dacs(codec, best_wired, best_mio); | ||
1730 | } | ||
1731 | debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n", | ||
1732 | cfg->line_out_type, best_wired, best_mio); | ||
1733 | debug_show_configs(codec, cfg); | ||
1734 | |||
1735 | if (cfg->line_out_pins[0]) { | ||
1736 | struct nid_path *path; | ||
1737 | path = snd_hda_get_path_from_idx(codec, spec->out_paths[0]); | ||
1738 | if (path) | ||
1739 | spec->vmaster_nid = look_for_out_vol_nid(codec, path); | ||
1740 | if (spec->vmaster_nid) | ||
1741 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | ||
1742 | HDA_OUTPUT, spec->vmaster_tlv); | ||
1743 | } | ||
1744 | |||
1745 | /* set initial pinctl targets */ | ||
1746 | if (spec->prefer_hp_amp || cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
1747 | val = PIN_HP; | ||
1748 | else | ||
1749 | val = PIN_OUT; | ||
1750 | set_pin_targets(codec, cfg->line_outs, cfg->line_out_pins, val); | ||
1751 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | ||
1752 | set_pin_targets(codec, cfg->hp_outs, cfg->hp_pins, PIN_HP); | ||
1753 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
1754 | val = spec->prefer_hp_amp ? PIN_HP : PIN_OUT; | ||
1755 | set_pin_targets(codec, cfg->speaker_outs, | ||
1756 | cfg->speaker_pins, val); | ||
1757 | } | ||
1758 | |||
1759 | kfree(best_cfg); | ||
1760 | return 0; | ||
1761 | } | ||
1762 | |||
1763 | /* add playback controls from the parsed DAC table */ | ||
1764 | static int create_multi_out_ctls(struct hda_codec *codec, | ||
1765 | const struct auto_pin_cfg *cfg) | ||
1766 | { | ||
1767 | struct hda_gen_spec *spec = codec->spec; | ||
1768 | int i, err, noutputs; | ||
1769 | |||
1770 | noutputs = cfg->line_outs; | ||
1771 | if (spec->multi_ios > 0 && cfg->line_outs < 3) | ||
1772 | noutputs += spec->multi_ios; | ||
1773 | |||
1774 | for (i = 0; i < noutputs; i++) { | ||
1775 | const char *name; | ||
1776 | int index; | ||
1777 | struct nid_path *path; | ||
1778 | |||
1779 | path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]); | ||
1780 | if (!path) | ||
1781 | continue; | ||
1782 | |||
1783 | name = get_line_out_pfx(codec, i, &index, NID_PATH_VOL_CTL); | ||
1784 | if (!name || !strcmp(name, "CLFE")) { | ||
1785 | /* Center/LFE */ | ||
1786 | err = add_vol_ctl(codec, "Center", 0, 1, path); | ||
1787 | if (err < 0) | ||
1788 | return err; | ||
1789 | err = add_vol_ctl(codec, "LFE", 0, 2, path); | ||
1790 | if (err < 0) | ||
1791 | return err; | ||
1792 | } else { | ||
1793 | err = add_stereo_vol(codec, name, index, path); | ||
376 | if (err < 0) | 1794 | if (err < 0) |
377 | return NULL; | 1795 | return err; |
378 | } | 1796 | } |
379 | if (err > 0) { | 1797 | |
380 | /* unmute the PIN output */ | 1798 | name = get_line_out_pfx(codec, i, &index, NID_PATH_MUTE_CTL); |
381 | unmute_output(codec, node); | 1799 | if (!name || !strcmp(name, "CLFE")) { |
382 | /* set PIN-Out enable */ | 1800 | err = add_sw_ctl(codec, "Center", 0, 1, path); |
383 | snd_hda_codec_write_cache(codec, node->nid, 0, | 1801 | if (err < 0) |
384 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1802 | return err; |
385 | AC_PINCTL_OUT_EN | | 1803 | err = add_sw_ctl(codec, "LFE", 0, 2, path); |
386 | ((node->pin_caps & AC_PINCAP_HP_DRV) ? | 1804 | if (err < 0) |
387 | AC_PINCTL_HP_EN : 0)); | 1805 | return err; |
388 | return node; | 1806 | } else { |
1807 | err = add_stereo_sw(codec, name, index, path); | ||
1808 | if (err < 0) | ||
1809 | return err; | ||
389 | } | 1810 | } |
390 | } | 1811 | } |
391 | return NULL; | 1812 | return 0; |
1813 | } | ||
1814 | |||
1815 | static int create_extra_out(struct hda_codec *codec, int path_idx, | ||
1816 | const char *pfx, int cidx) | ||
1817 | { | ||
1818 | struct nid_path *path; | ||
1819 | int err; | ||
1820 | |||
1821 | path = snd_hda_get_path_from_idx(codec, path_idx); | ||
1822 | if (!path) | ||
1823 | return 0; | ||
1824 | err = add_stereo_vol(codec, pfx, cidx, path); | ||
1825 | if (err < 0) | ||
1826 | return err; | ||
1827 | err = add_stereo_sw(codec, pfx, cidx, path); | ||
1828 | if (err < 0) | ||
1829 | return err; | ||
1830 | return 0; | ||
1831 | } | ||
1832 | |||
1833 | /* add playback controls for speaker and HP outputs */ | ||
1834 | static int create_extra_outs(struct hda_codec *codec, int num_pins, | ||
1835 | const int *paths, const char *pfx) | ||
1836 | { | ||
1837 | int i; | ||
1838 | |||
1839 | for (i = 0; i < num_pins; i++) { | ||
1840 | const char *name; | ||
1841 | char tmp[44]; | ||
1842 | int err, idx = 0; | ||
1843 | |||
1844 | if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) | ||
1845 | name = "Bass Speaker"; | ||
1846 | else if (num_pins >= 3) { | ||
1847 | snprintf(tmp, sizeof(tmp), "%s %s", | ||
1848 | pfx, channel_name[i]); | ||
1849 | name = tmp; | ||
1850 | } else { | ||
1851 | name = pfx; | ||
1852 | idx = i; | ||
1853 | } | ||
1854 | err = create_extra_out(codec, paths[i], name, idx); | ||
1855 | if (err < 0) | ||
1856 | return err; | ||
1857 | } | ||
1858 | return 0; | ||
1859 | } | ||
1860 | |||
1861 | static int create_hp_out_ctls(struct hda_codec *codec) | ||
1862 | { | ||
1863 | struct hda_gen_spec *spec = codec->spec; | ||
1864 | return create_extra_outs(codec, spec->autocfg.hp_outs, | ||
1865 | spec->hp_paths, | ||
1866 | "Headphone"); | ||
392 | } | 1867 | } |
393 | 1868 | ||
1869 | static int create_speaker_out_ctls(struct hda_codec *codec) | ||
1870 | { | ||
1871 | struct hda_gen_spec *spec = codec->spec; | ||
1872 | return create_extra_outs(codec, spec->autocfg.speaker_outs, | ||
1873 | spec->speaker_paths, | ||
1874 | "Speaker"); | ||
1875 | } | ||
394 | 1876 | ||
395 | /* | 1877 | /* |
396 | * parse outputs | 1878 | * independent HP controls |
397 | */ | 1879 | */ |
398 | static int parse_output(struct hda_codec *codec) | 1880 | |
1881 | static int indep_hp_info(struct snd_kcontrol *kcontrol, | ||
1882 | struct snd_ctl_elem_info *uinfo) | ||
399 | { | 1883 | { |
400 | struct hda_gspec *spec = codec->spec; | 1884 | return snd_hda_enum_bool_helper_info(kcontrol, uinfo); |
401 | struct hda_gnode *node; | 1885 | } |
402 | 1886 | ||
403 | /* | 1887 | static int indep_hp_get(struct snd_kcontrol *kcontrol, |
404 | * Look for the output PIN widget | 1888 | struct snd_ctl_elem_value *ucontrol) |
405 | */ | 1889 | { |
406 | /* first, look for the line-out pin */ | 1890 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
407 | node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT); | 1891 | struct hda_gen_spec *spec = codec->spec; |
408 | if (node) /* found, remember the PIN node */ | 1892 | ucontrol->value.enumerated.item[0] = spec->indep_hp_enabled; |
409 | spec->out_pin_node[0] = node; | 1893 | return 0; |
410 | else { | 1894 | } |
411 | /* if no line-out is found, try speaker out */ | 1895 | |
412 | node = parse_output_jack(codec, spec, AC_JACK_SPEAKER); | 1896 | static void update_aamix_paths(struct hda_codec *codec, bool do_mix, |
413 | if (node) | 1897 | int nomix_path_idx, int mix_path_idx, |
414 | spec->out_pin_node[0] = node; | 1898 | int out_type); |
415 | } | 1899 | |
416 | /* look for the HP-out pin */ | 1900 | static int indep_hp_put(struct snd_kcontrol *kcontrol, |
417 | node = parse_output_jack(codec, spec, AC_JACK_HP_OUT); | 1901 | struct snd_ctl_elem_value *ucontrol) |
418 | if (node) { | 1902 | { |
419 | if (! spec->out_pin_node[0]) | 1903 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
420 | spec->out_pin_node[0] = node; | 1904 | struct hda_gen_spec *spec = codec->spec; |
1905 | unsigned int select = ucontrol->value.enumerated.item[0]; | ||
1906 | int ret = 0; | ||
1907 | |||
1908 | mutex_lock(&spec->pcm_mutex); | ||
1909 | if (spec->active_streams) { | ||
1910 | ret = -EBUSY; | ||
1911 | goto unlock; | ||
1912 | } | ||
1913 | |||
1914 | if (spec->indep_hp_enabled != select) { | ||
1915 | hda_nid_t *dacp; | ||
1916 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
1917 | dacp = &spec->private_dac_nids[0]; | ||
1918 | else | ||
1919 | dacp = &spec->multiout.hp_out_nid[0]; | ||
1920 | |||
1921 | /* update HP aamix paths in case it conflicts with indep HP */ | ||
1922 | if (spec->have_aamix_ctl) { | ||
1923 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
1924 | update_aamix_paths(codec, spec->aamix_mode, | ||
1925 | spec->out_paths[0], | ||
1926 | spec->aamix_out_paths[0], | ||
1927 | spec->autocfg.line_out_type); | ||
1928 | else | ||
1929 | update_aamix_paths(codec, spec->aamix_mode, | ||
1930 | spec->hp_paths[0], | ||
1931 | spec->aamix_out_paths[1], | ||
1932 | AUTO_PIN_HP_OUT); | ||
1933 | } | ||
1934 | |||
1935 | spec->indep_hp_enabled = select; | ||
1936 | if (spec->indep_hp_enabled) | ||
1937 | *dacp = 0; | ||
421 | else | 1938 | else |
422 | spec->out_pin_node[1] = node; | 1939 | *dacp = spec->alt_dac_nid; |
1940 | |||
1941 | /* update HP auto-mute state too */ | ||
1942 | if (spec->hp_automute_hook) | ||
1943 | spec->hp_automute_hook(codec, NULL); | ||
1944 | else | ||
1945 | snd_hda_gen_hp_automute(codec, NULL); | ||
1946 | |||
1947 | ret = 1; | ||
423 | } | 1948 | } |
1949 | unlock: | ||
1950 | mutex_unlock(&spec->pcm_mutex); | ||
1951 | return ret; | ||
1952 | } | ||
424 | 1953 | ||
425 | if (! spec->out_pin_node[0]) { | 1954 | static const struct snd_kcontrol_new indep_hp_ctl = { |
426 | /* no line-out or HP pins found, | 1955 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
427 | * then choose for the first output pin | 1956 | .name = "Independent HP", |
428 | */ | 1957 | .info = indep_hp_info, |
429 | spec->out_pin_node[0] = parse_output_jack(codec, spec, -1); | 1958 | .get = indep_hp_get, |
430 | if (! spec->out_pin_node[0]) | 1959 | .put = indep_hp_put, |
431 | snd_printd("hda_generic: no proper output path found\n"); | 1960 | }; |
1961 | |||
1962 | |||
1963 | static int create_indep_hp_ctls(struct hda_codec *codec) | ||
1964 | { | ||
1965 | struct hda_gen_spec *spec = codec->spec; | ||
1966 | hda_nid_t dac; | ||
1967 | |||
1968 | if (!spec->indep_hp) | ||
1969 | return 0; | ||
1970 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
1971 | dac = spec->multiout.dac_nids[0]; | ||
1972 | else | ||
1973 | dac = spec->multiout.hp_out_nid[0]; | ||
1974 | if (!dac) { | ||
1975 | spec->indep_hp = 0; | ||
1976 | return 0; | ||
432 | } | 1977 | } |
433 | 1978 | ||
1979 | spec->indep_hp_enabled = false; | ||
1980 | spec->alt_dac_nid = dac; | ||
1981 | if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl)) | ||
1982 | return -ENOMEM; | ||
434 | return 0; | 1983 | return 0; |
435 | } | 1984 | } |
436 | 1985 | ||
437 | /* | 1986 | /* |
438 | * input MUX | 1987 | * channel mode enum control |
439 | */ | 1988 | */ |
440 | 1989 | ||
441 | /* control callbacks */ | 1990 | static int ch_mode_info(struct snd_kcontrol *kcontrol, |
442 | static int capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1991 | struct snd_ctl_elem_info *uinfo) |
443 | { | 1992 | { |
444 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1993 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
445 | struct hda_gspec *spec = codec->spec; | 1994 | struct hda_gen_spec *spec = codec->spec; |
446 | return snd_hda_input_mux_info(&spec->input_mux, uinfo); | 1995 | int chs; |
1996 | |||
1997 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1998 | uinfo->count = 1; | ||
1999 | uinfo->value.enumerated.items = spec->multi_ios + 1; | ||
2000 | if (uinfo->value.enumerated.item > spec->multi_ios) | ||
2001 | uinfo->value.enumerated.item = spec->multi_ios; | ||
2002 | chs = uinfo->value.enumerated.item * 2 + spec->min_channel_count; | ||
2003 | sprintf(uinfo->value.enumerated.name, "%dch", chs); | ||
2004 | return 0; | ||
447 | } | 2005 | } |
448 | 2006 | ||
449 | static int capture_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2007 | static int ch_mode_get(struct snd_kcontrol *kcontrol, |
2008 | struct snd_ctl_elem_value *ucontrol) | ||
450 | { | 2009 | { |
451 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2010 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
452 | struct hda_gspec *spec = codec->spec; | 2011 | struct hda_gen_spec *spec = codec->spec; |
2012 | ucontrol->value.enumerated.item[0] = | ||
2013 | (spec->ext_channel_count - spec->min_channel_count) / 2; | ||
2014 | return 0; | ||
2015 | } | ||
2016 | |||
2017 | static inline struct nid_path * | ||
2018 | get_multiio_path(struct hda_codec *codec, int idx) | ||
2019 | { | ||
2020 | struct hda_gen_spec *spec = codec->spec; | ||
2021 | return snd_hda_get_path_from_idx(codec, | ||
2022 | spec->out_paths[spec->autocfg.line_outs + idx]); | ||
2023 | } | ||
2024 | |||
2025 | static void update_automute_all(struct hda_codec *codec); | ||
2026 | |||
2027 | static int set_multi_io(struct hda_codec *codec, int idx, bool output) | ||
2028 | { | ||
2029 | struct hda_gen_spec *spec = codec->spec; | ||
2030 | hda_nid_t nid = spec->multi_io[idx].pin; | ||
2031 | struct nid_path *path; | ||
2032 | |||
2033 | path = get_multiio_path(codec, idx); | ||
2034 | if (!path) | ||
2035 | return -EINVAL; | ||
2036 | |||
2037 | if (path->active == output) | ||
2038 | return 0; | ||
2039 | |||
2040 | if (output) { | ||
2041 | set_pin_target(codec, nid, PIN_OUT, true); | ||
2042 | snd_hda_activate_path(codec, path, true, true); | ||
2043 | set_pin_eapd(codec, nid, true); | ||
2044 | } else { | ||
2045 | set_pin_eapd(codec, nid, false); | ||
2046 | snd_hda_activate_path(codec, path, false, true); | ||
2047 | set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true); | ||
2048 | path_power_down_sync(codec, path); | ||
2049 | } | ||
2050 | |||
2051 | /* update jack retasking in case it modifies any of them */ | ||
2052 | update_automute_all(codec); | ||
453 | 2053 | ||
454 | ucontrol->value.enumerated.item[0] = spec->cur_cap_src; | ||
455 | return 0; | 2054 | return 0; |
456 | } | 2055 | } |
457 | 2056 | ||
458 | static int capture_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2057 | static int ch_mode_put(struct snd_kcontrol *kcontrol, |
2058 | struct snd_ctl_elem_value *ucontrol) | ||
459 | { | 2059 | { |
460 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2060 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
461 | struct hda_gspec *spec = codec->spec; | 2061 | struct hda_gen_spec *spec = codec->spec; |
462 | return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol, | 2062 | int i, ch; |
463 | spec->adc_node->nid, &spec->cur_cap_src); | 2063 | |
2064 | ch = ucontrol->value.enumerated.item[0]; | ||
2065 | if (ch < 0 || ch > spec->multi_ios) | ||
2066 | return -EINVAL; | ||
2067 | if (ch == (spec->ext_channel_count - spec->min_channel_count) / 2) | ||
2068 | return 0; | ||
2069 | spec->ext_channel_count = ch * 2 + spec->min_channel_count; | ||
2070 | for (i = 0; i < spec->multi_ios; i++) | ||
2071 | set_multi_io(codec, i, i < ch); | ||
2072 | spec->multiout.max_channels = max(spec->ext_channel_count, | ||
2073 | spec->const_channel_count); | ||
2074 | if (spec->need_dac_fix) | ||
2075 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
2076 | return 1; | ||
464 | } | 2077 | } |
465 | 2078 | ||
466 | /* | 2079 | static const struct snd_kcontrol_new channel_mode_enum = { |
467 | * return the string name of the given input PIN widget | 2080 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
468 | */ | 2081 | .name = "Channel Mode", |
469 | static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl) | 2082 | .info = ch_mode_info, |
470 | { | 2083 | .get = ch_mode_get, |
471 | unsigned int location = defcfg_location(node); | 2084 | .put = ch_mode_put, |
472 | switch (defcfg_type(node)) { | 2085 | }; |
473 | case AC_JACK_LINE_IN: | 2086 | |
474 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | 2087 | static int create_multi_channel_mode(struct hda_codec *codec) |
475 | return "Front Line"; | 2088 | { |
476 | return "Line"; | 2089 | struct hda_gen_spec *spec = codec->spec; |
477 | case AC_JACK_CD: | 2090 | |
478 | #if 0 | 2091 | if (spec->multi_ios > 0) { |
479 | if (pinctl) | 2092 | if (!snd_hda_gen_add_kctl(spec, NULL, &channel_mode_enum)) |
480 | *pinctl |= AC_PINCTL_VREF_GRD; | 2093 | return -ENOMEM; |
481 | #endif | ||
482 | return "CD"; | ||
483 | case AC_JACK_AUX: | ||
484 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | ||
485 | return "Front Aux"; | ||
486 | return "Aux"; | ||
487 | case AC_JACK_MIC_IN: | ||
488 | if (pinctl && | ||
489 | (node->pin_caps & | ||
490 | (AC_PINCAP_VREF_80 << AC_PINCAP_VREF_SHIFT))) | ||
491 | *pinctl |= AC_PINCTL_VREF_80; | ||
492 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | ||
493 | return "Front Mic"; | ||
494 | return "Mic"; | ||
495 | case AC_JACK_SPDIF_IN: | ||
496 | return "SPDIF"; | ||
497 | case AC_JACK_DIG_OTHER_IN: | ||
498 | return "Digital"; | ||
499 | } | 2094 | } |
500 | return NULL; | 2095 | return 0; |
501 | } | 2096 | } |
502 | 2097 | ||
503 | /* | 2098 | /* |
504 | * parse the nodes recursively until reach to the input PIN | 2099 | * aamix loopback enable/disable switch |
505 | * | ||
506 | * returns 0 if not found, 1 if found, or a negative error code. | ||
507 | */ | 2100 | */ |
508 | static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec, | 2101 | |
509 | struct hda_gnode *node, int idx) | 2102 | #define loopback_mixing_info indep_hp_info |
2103 | |||
2104 | static int loopback_mixing_get(struct snd_kcontrol *kcontrol, | ||
2105 | struct snd_ctl_elem_value *ucontrol) | ||
510 | { | 2106 | { |
511 | int i, err; | 2107 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
512 | unsigned int pinctl; | 2108 | struct hda_gen_spec *spec = codec->spec; |
513 | const char *type; | 2109 | ucontrol->value.enumerated.item[0] = spec->aamix_mode; |
2110 | return 0; | ||
2111 | } | ||
2112 | |||
2113 | static void update_aamix_paths(struct hda_codec *codec, bool do_mix, | ||
2114 | int nomix_path_idx, int mix_path_idx, | ||
2115 | int out_type) | ||
2116 | { | ||
2117 | struct hda_gen_spec *spec = codec->spec; | ||
2118 | struct nid_path *nomix_path, *mix_path; | ||
2119 | |||
2120 | nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx); | ||
2121 | mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx); | ||
2122 | if (!nomix_path || !mix_path) | ||
2123 | return; | ||
2124 | |||
2125 | /* if HP aamix path is driven from a different DAC and the | ||
2126 | * independent HP mode is ON, can't turn on aamix path | ||
2127 | */ | ||
2128 | if (out_type == AUTO_PIN_HP_OUT && spec->indep_hp_enabled && | ||
2129 | mix_path->path[0] != spec->alt_dac_nid) | ||
2130 | do_mix = false; | ||
2131 | |||
2132 | if (do_mix) { | ||
2133 | snd_hda_activate_path(codec, nomix_path, false, true); | ||
2134 | snd_hda_activate_path(codec, mix_path, true, true); | ||
2135 | path_power_down_sync(codec, nomix_path); | ||
2136 | } else { | ||
2137 | snd_hda_activate_path(codec, mix_path, false, true); | ||
2138 | snd_hda_activate_path(codec, nomix_path, true, true); | ||
2139 | path_power_down_sync(codec, mix_path); | ||
2140 | } | ||
2141 | } | ||
2142 | |||
2143 | static int loopback_mixing_put(struct snd_kcontrol *kcontrol, | ||
2144 | struct snd_ctl_elem_value *ucontrol) | ||
2145 | { | ||
2146 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2147 | struct hda_gen_spec *spec = codec->spec; | ||
2148 | unsigned int val = ucontrol->value.enumerated.item[0]; | ||
514 | 2149 | ||
515 | if (node->checked) | 2150 | if (val == spec->aamix_mode) |
516 | return 0; | 2151 | return 0; |
2152 | spec->aamix_mode = val; | ||
2153 | update_aamix_paths(codec, val, spec->out_paths[0], | ||
2154 | spec->aamix_out_paths[0], | ||
2155 | spec->autocfg.line_out_type); | ||
2156 | update_aamix_paths(codec, val, spec->hp_paths[0], | ||
2157 | spec->aamix_out_paths[1], | ||
2158 | AUTO_PIN_HP_OUT); | ||
2159 | update_aamix_paths(codec, val, spec->speaker_paths[0], | ||
2160 | spec->aamix_out_paths[2], | ||
2161 | AUTO_PIN_SPEAKER_OUT); | ||
2162 | return 1; | ||
2163 | } | ||
517 | 2164 | ||
518 | node->checked = 1; | 2165 | static const struct snd_kcontrol_new loopback_mixing_enum = { |
519 | if (node->type != AC_WID_PIN) { | 2166 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
520 | for (i = 0; i < node->nconns; i++) { | 2167 | .name = "Loopback Mixing", |
521 | struct hda_gnode *child; | 2168 | .info = loopback_mixing_info, |
522 | child = hda_get_node(spec, node->conn_list[i]); | 2169 | .get = loopback_mixing_get, |
523 | if (! child) | 2170 | .put = loopback_mixing_put, |
524 | continue; | 2171 | }; |
525 | err = parse_adc_sub_nodes(codec, spec, child, idx); | 2172 | |
526 | if (err < 0) | 2173 | static int create_loopback_mixing_ctl(struct hda_codec *codec) |
527 | return err; | 2174 | { |
528 | if (err > 0) { | 2175 | struct hda_gen_spec *spec = codec->spec; |
529 | /* found one, | 2176 | |
530 | * select the path, unmute both input and output | 2177 | if (!spec->mixer_nid) |
531 | */ | ||
532 | if (node->nconns > 1) | ||
533 | select_input_connection(codec, node, i); | ||
534 | unmute_input(codec, node, i); | ||
535 | unmute_output(codec, node); | ||
536 | return err; | ||
537 | } | ||
538 | } | ||
539 | return 0; | 2178 | return 0; |
2179 | if (!(spec->aamix_out_paths[0] || spec->aamix_out_paths[1] || | ||
2180 | spec->aamix_out_paths[2])) | ||
2181 | return 0; | ||
2182 | if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) | ||
2183 | return -ENOMEM; | ||
2184 | spec->have_aamix_ctl = 1; | ||
2185 | return 0; | ||
2186 | } | ||
2187 | |||
2188 | /* | ||
2189 | * shared headphone/mic handling | ||
2190 | */ | ||
2191 | |||
2192 | static void call_update_outputs(struct hda_codec *codec); | ||
2193 | |||
2194 | /* for shared I/O, change the pin-control accordingly */ | ||
2195 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | ||
2196 | { | ||
2197 | struct hda_gen_spec *spec = codec->spec; | ||
2198 | unsigned int val; | ||
2199 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
2200 | /* NOTE: this assumes that there are only two inputs, the | ||
2201 | * first is the real internal mic and the second is HP/mic jack. | ||
2202 | */ | ||
2203 | |||
2204 | val = snd_hda_get_default_vref(codec, pin); | ||
2205 | |||
2206 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | ||
2207 | instead, as suggested by Realtek */ | ||
2208 | if (val == AC_PINCTL_VREF_HIZ && spec->shared_mic_vref_pin) { | ||
2209 | const hda_nid_t vref_pin = spec->shared_mic_vref_pin; | ||
2210 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | ||
2211 | if (vref_val != AC_PINCTL_VREF_HIZ) | ||
2212 | snd_hda_set_pin_ctl_cache(codec, vref_pin, | ||
2213 | PIN_IN | (set_as_mic ? vref_val : 0)); | ||
540 | } | 2214 | } |
541 | 2215 | ||
542 | /* input capable? */ | 2216 | val = set_as_mic ? val | PIN_IN : PIN_HP; |
543 | if (! (node->pin_caps & AC_PINCAP_IN)) | 2217 | set_pin_target(codec, pin, val, true); |
2218 | |||
2219 | spec->automute_speaker = !set_as_mic; | ||
2220 | call_update_outputs(codec); | ||
2221 | } | ||
2222 | |||
2223 | /* create a shared input with the headphone out */ | ||
2224 | static int create_shared_input(struct hda_codec *codec) | ||
2225 | { | ||
2226 | struct hda_gen_spec *spec = codec->spec; | ||
2227 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2228 | unsigned int defcfg; | ||
2229 | hda_nid_t nid; | ||
2230 | |||
2231 | /* only one internal input pin? */ | ||
2232 | if (cfg->num_inputs != 1) | ||
2233 | return 0; | ||
2234 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); | ||
2235 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | ||
544 | return 0; | 2236 | return 0; |
545 | 2237 | ||
546 | if (defcfg_port_conn(node) == AC_JACK_PORT_NONE) | 2238 | if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) |
547 | return 0; /* unconnected */ | 2239 | nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ |
2240 | else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
2241 | nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ | ||
2242 | else | ||
2243 | return 0; /* both not available */ | ||
548 | 2244 | ||
549 | if (node->wid_caps & AC_WCAP_DIGITAL) | 2245 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) |
550 | return 0; /* skip SPDIF */ | 2246 | return 0; /* no input */ |
551 | 2247 | ||
552 | if (spec->input_mux.num_items >= HDA_MAX_NUM_INPUTS) { | 2248 | cfg->inputs[1].pin = nid; |
553 | snd_printk(KERN_ERR "hda_generic: Too many items for capture\n"); | 2249 | cfg->inputs[1].type = AUTO_PIN_MIC; |
554 | return -EINVAL; | 2250 | cfg->num_inputs = 2; |
555 | } | 2251 | spec->shared_mic_hp = 1; |
2252 | snd_printdd("hda-codec: Enable shared I/O jack on NID 0x%x\n", nid); | ||
2253 | return 0; | ||
2254 | } | ||
556 | 2255 | ||
557 | pinctl = AC_PINCTL_IN_EN; | 2256 | /* |
558 | /* create a proper capture source label */ | 2257 | * output jack mode |
559 | type = get_input_type(node, &pinctl); | 2258 | */ |
560 | if (! type) { | 2259 | static int out_jack_mode_info(struct snd_kcontrol *kcontrol, |
561 | /* input as default? */ | 2260 | struct snd_ctl_elem_info *uinfo) |
562 | if (! (node->pin_ctl & AC_PINCTL_IN_EN)) | 2261 | { |
563 | return 0; | 2262 | static const char * const texts[] = { |
564 | type = "Input"; | 2263 | "Line Out", "Headphone Out", |
2264 | }; | ||
2265 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts); | ||
2266 | } | ||
2267 | |||
2268 | static int out_jack_mode_get(struct snd_kcontrol *kcontrol, | ||
2269 | struct snd_ctl_elem_value *ucontrol) | ||
2270 | { | ||
2271 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2272 | hda_nid_t nid = kcontrol->private_value; | ||
2273 | if (snd_hda_codec_get_pin_target(codec, nid) == PIN_HP) | ||
2274 | ucontrol->value.enumerated.item[0] = 1; | ||
2275 | else | ||
2276 | ucontrol->value.enumerated.item[0] = 0; | ||
2277 | return 0; | ||
2278 | } | ||
2279 | |||
2280 | static int out_jack_mode_put(struct snd_kcontrol *kcontrol, | ||
2281 | struct snd_ctl_elem_value *ucontrol) | ||
2282 | { | ||
2283 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2284 | hda_nid_t nid = kcontrol->private_value; | ||
2285 | unsigned int val; | ||
2286 | |||
2287 | val = ucontrol->value.enumerated.item[0] ? PIN_HP : PIN_OUT; | ||
2288 | if (snd_hda_codec_get_pin_target(codec, nid) == val) | ||
2289 | return 0; | ||
2290 | snd_hda_set_pin_ctl_cache(codec, nid, val); | ||
2291 | return 1; | ||
2292 | } | ||
2293 | |||
2294 | static const struct snd_kcontrol_new out_jack_mode_enum = { | ||
2295 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2296 | .info = out_jack_mode_info, | ||
2297 | .get = out_jack_mode_get, | ||
2298 | .put = out_jack_mode_put, | ||
2299 | }; | ||
2300 | |||
2301 | static bool find_kctl_name(struct hda_codec *codec, const char *name, int idx) | ||
2302 | { | ||
2303 | struct hda_gen_spec *spec = codec->spec; | ||
2304 | int i; | ||
2305 | |||
2306 | for (i = 0; i < spec->kctls.used; i++) { | ||
2307 | struct snd_kcontrol_new *kctl = snd_array_elem(&spec->kctls, i); | ||
2308 | if (!strcmp(kctl->name, name) && kctl->index == idx) | ||
2309 | return true; | ||
565 | } | 2310 | } |
566 | snd_hda_add_imux_item(&spec->input_mux, type, idx, NULL); | 2311 | return false; |
2312 | } | ||
567 | 2313 | ||
568 | /* unmute the PIN external input */ | 2314 | static void get_jack_mode_name(struct hda_codec *codec, hda_nid_t pin, |
569 | unmute_input(codec, node, 0); /* index = 0? */ | 2315 | char *name, size_t name_len) |
570 | /* set PIN-In enable */ | 2316 | { |
571 | snd_hda_codec_write_cache(codec, node->nid, 0, | 2317 | struct hda_gen_spec *spec = codec->spec; |
572 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); | 2318 | int idx = 0; |
2319 | |||
2320 | snd_hda_get_pin_label(codec, pin, &spec->autocfg, name, name_len, &idx); | ||
2321 | strlcat(name, " Jack Mode", name_len); | ||
573 | 2322 | ||
574 | return 1; /* found */ | 2323 | for (; find_kctl_name(codec, name, idx); idx++) |
2324 | ; | ||
2325 | } | ||
2326 | |||
2327 | static int create_out_jack_modes(struct hda_codec *codec, int num_pins, | ||
2328 | hda_nid_t *pins) | ||
2329 | { | ||
2330 | struct hda_gen_spec *spec = codec->spec; | ||
2331 | int i; | ||
2332 | |||
2333 | for (i = 0; i < num_pins; i++) { | ||
2334 | hda_nid_t pin = pins[i]; | ||
2335 | unsigned int pincap = snd_hda_query_pin_caps(codec, pin); | ||
2336 | if ((pincap & AC_PINCAP_OUT) && (pincap & AC_PINCAP_HP_DRV)) { | ||
2337 | struct snd_kcontrol_new *knew; | ||
2338 | char name[44]; | ||
2339 | get_jack_mode_name(codec, pin, name, sizeof(name)); | ||
2340 | knew = snd_hda_gen_add_kctl(spec, name, | ||
2341 | &out_jack_mode_enum); | ||
2342 | if (!knew) | ||
2343 | return -ENOMEM; | ||
2344 | knew->private_value = pin; | ||
2345 | } | ||
2346 | } | ||
2347 | |||
2348 | return 0; | ||
575 | } | 2349 | } |
576 | 2350 | ||
577 | /* | 2351 | /* |
578 | * parse input | 2352 | * input jack mode |
579 | */ | 2353 | */ |
580 | static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node) | 2354 | |
2355 | /* from AC_PINCTL_VREF_HIZ to AC_PINCTL_VREF_100 */ | ||
2356 | #define NUM_VREFS 6 | ||
2357 | |||
2358 | static const char * const vref_texts[NUM_VREFS] = { | ||
2359 | "Line In", "Mic 50pc Bias", "Mic 0V Bias", | ||
2360 | "", "Mic 80pc Bias", "Mic 100pc Bias" | ||
2361 | }; | ||
2362 | |||
2363 | static unsigned int get_vref_caps(struct hda_codec *codec, hda_nid_t pin) | ||
581 | { | 2364 | { |
582 | struct hda_gspec *spec = codec->spec; | 2365 | unsigned int pincap; |
583 | struct hda_gnode *node; | ||
584 | int i, err; | ||
585 | 2366 | ||
586 | snd_printdd("AUD_IN = %x\n", adc_node->nid); | 2367 | pincap = snd_hda_query_pin_caps(codec, pin); |
587 | clear_check_flags(spec); | 2368 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
2369 | /* filter out unusual vrefs */ | ||
2370 | pincap &= ~(AC_PINCAP_VREF_GRD | AC_PINCAP_VREF_100); | ||
2371 | return pincap; | ||
2372 | } | ||
588 | 2373 | ||
589 | // awk added - fixed no recording due to muted widget | 2374 | /* convert from the enum item index to the vref ctl index (0=HIZ, 1=50%...) */ |
590 | unmute_input(codec, adc_node, 0); | 2375 | static int get_vref_idx(unsigned int vref_caps, unsigned int item_idx) |
591 | 2376 | { | |
592 | /* | 2377 | unsigned int i, n = 0; |
593 | * check each connection of the ADC | 2378 | |
594 | * if it reaches to a proper input PIN, add the path as the | 2379 | for (i = 0; i < NUM_VREFS; i++) { |
595 | * input path. | 2380 | if (vref_caps & (1 << i)) { |
596 | */ | 2381 | if (n == item_idx) |
597 | /* first, check the direct connections to PIN widgets */ | 2382 | return i; |
598 | for (i = 0; i < adc_node->nconns; i++) { | 2383 | n++; |
599 | node = hda_get_node(spec, adc_node->conn_list[i]); | ||
600 | if (node && node->type == AC_WID_PIN) { | ||
601 | err = parse_adc_sub_nodes(codec, spec, node, i); | ||
602 | if (err < 0) | ||
603 | return err; | ||
604 | } | 2384 | } |
605 | } | 2385 | } |
606 | /* ... then check the rests, more complicated connections */ | 2386 | return 0; |
607 | for (i = 0; i < adc_node->nconns; i++) { | 2387 | } |
608 | node = hda_get_node(spec, adc_node->conn_list[i]); | 2388 | |
609 | if (node && node->type != AC_WID_PIN) { | 2389 | /* convert back from the vref ctl index to the enum item index */ |
610 | err = parse_adc_sub_nodes(codec, spec, node, i); | 2390 | static int cvt_from_vref_idx(unsigned int vref_caps, unsigned int idx) |
611 | if (err < 0) | 2391 | { |
612 | return err; | 2392 | unsigned int i, n = 0; |
613 | } | 2393 | |
2394 | for (i = 0; i < NUM_VREFS; i++) { | ||
2395 | if (i == idx) | ||
2396 | return n; | ||
2397 | if (vref_caps & (1 << i)) | ||
2398 | n++; | ||
614 | } | 2399 | } |
2400 | return 0; | ||
2401 | } | ||
2402 | |||
2403 | static int in_jack_mode_info(struct snd_kcontrol *kcontrol, | ||
2404 | struct snd_ctl_elem_info *uinfo) | ||
2405 | { | ||
2406 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2407 | hda_nid_t nid = kcontrol->private_value; | ||
2408 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2409 | |||
2410 | snd_hda_enum_helper_info(kcontrol, uinfo, hweight32(vref_caps), | ||
2411 | vref_texts); | ||
2412 | /* set the right text */ | ||
2413 | strcpy(uinfo->value.enumerated.name, | ||
2414 | vref_texts[get_vref_idx(vref_caps, uinfo->value.enumerated.item)]); | ||
2415 | return 0; | ||
2416 | } | ||
2417 | |||
2418 | static int in_jack_mode_get(struct snd_kcontrol *kcontrol, | ||
2419 | struct snd_ctl_elem_value *ucontrol) | ||
2420 | { | ||
2421 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2422 | hda_nid_t nid = kcontrol->private_value; | ||
2423 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2424 | unsigned int idx; | ||
2425 | |||
2426 | idx = snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_VREFEN; | ||
2427 | ucontrol->value.enumerated.item[0] = cvt_from_vref_idx(vref_caps, idx); | ||
2428 | return 0; | ||
2429 | } | ||
615 | 2430 | ||
616 | if (! spec->input_mux.num_items) | 2431 | static int in_jack_mode_put(struct snd_kcontrol *kcontrol, |
617 | return 0; /* no input path found... */ | 2432 | struct snd_ctl_elem_value *ucontrol) |
2433 | { | ||
2434 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2435 | hda_nid_t nid = kcontrol->private_value; | ||
2436 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2437 | unsigned int val, idx; | ||
618 | 2438 | ||
619 | snd_printdd("[Capture Source] NID=0x%x, #SRC=%d\n", adc_node->nid, spec->input_mux.num_items); | 2439 | val = snd_hda_codec_get_pin_target(codec, nid); |
620 | for (i = 0; i < spec->input_mux.num_items; i++) | 2440 | idx = cvt_from_vref_idx(vref_caps, val & AC_PINCTL_VREFEN); |
621 | snd_printdd(" [%s] IDX=0x%x\n", spec->input_mux.items[i].label, | 2441 | if (idx == ucontrol->value.enumerated.item[0]) |
622 | spec->input_mux.items[i].index); | 2442 | return 0; |
623 | 2443 | ||
624 | spec->adc_node = adc_node; | 2444 | val &= ~AC_PINCTL_VREFEN; |
2445 | val |= get_vref_idx(vref_caps, ucontrol->value.enumerated.item[0]); | ||
2446 | snd_hda_set_pin_ctl_cache(codec, nid, val); | ||
625 | return 1; | 2447 | return 1; |
626 | } | 2448 | } |
627 | 2449 | ||
628 | /* | 2450 | static const struct snd_kcontrol_new in_jack_mode_enum = { |
629 | * parse input | 2451 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
630 | */ | 2452 | .info = in_jack_mode_info, |
631 | static int parse_input(struct hda_codec *codec) | 2453 | .get = in_jack_mode_get, |
2454 | .put = in_jack_mode_put, | ||
2455 | }; | ||
2456 | |||
2457 | static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin) | ||
632 | { | 2458 | { |
633 | struct hda_gspec *spec = codec->spec; | 2459 | struct hda_gen_spec *spec = codec->spec; |
634 | struct hda_gnode *node; | 2460 | unsigned int defcfg; |
635 | int err; | 2461 | struct snd_kcontrol_new *knew; |
2462 | char name[44]; | ||
636 | 2463 | ||
637 | /* | 2464 | /* no jack mode for fixed pins */ |
638 | * At first we look for an audio input widget. | 2465 | defcfg = snd_hda_codec_get_pincfg(codec, pin); |
639 | * If it reaches to certain input PINs, we take it as the | 2466 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) |
640 | * input path. | 2467 | return 0; |
641 | */ | 2468 | |
642 | list_for_each_entry(node, &spec->nid_list, list) { | 2469 | /* no multiple vref caps? */ |
643 | if (node->wid_caps & AC_WCAP_DIGITAL) | 2470 | if (hweight32(get_vref_caps(codec, pin)) <= 1) |
644 | continue; /* skip SPDIF */ | 2471 | return 0; |
645 | if (node->type == AC_WID_AUD_IN) { | 2472 | |
646 | err = parse_input_path(codec, node); | 2473 | get_jack_mode_name(codec, pin, name, sizeof(name)); |
647 | if (err < 0) | 2474 | knew = snd_hda_gen_add_kctl(spec, name, &in_jack_mode_enum); |
648 | return err; | 2475 | if (!knew) |
649 | else if (err > 0) | 2476 | return -ENOMEM; |
650 | return 0; | 2477 | knew->private_value = pin; |
651 | } | ||
652 | } | ||
653 | snd_printd("hda_generic: no proper input path found\n"); | ||
654 | return 0; | 2478 | return 0; |
655 | } | 2479 | } |
656 | 2480 | ||
2481 | |||
2482 | /* | ||
2483 | * Parse input paths | ||
2484 | */ | ||
2485 | |||
657 | #ifdef CONFIG_PM | 2486 | #ifdef CONFIG_PM |
658 | static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid, | 2487 | /* add the powersave loopback-list entry */ |
659 | int dir, int idx) | 2488 | static void add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx) |
660 | { | 2489 | { |
661 | struct hda_gspec *spec = codec->spec; | 2490 | struct hda_amp_list *list; |
662 | struct hda_amp_list *p; | ||
663 | 2491 | ||
664 | if (spec->num_loopbacks >= MAX_LOOPBACK_AMPS) { | 2492 | if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1) |
665 | snd_printk(KERN_ERR "hda_generic: Too many loopback ctls\n"); | ||
666 | return; | 2493 | return; |
667 | } | 2494 | list = spec->loopback_list + spec->num_loopbacks; |
668 | p = &spec->loopback_list[spec->num_loopbacks++]; | 2495 | list->nid = mix; |
669 | p->nid = nid; | 2496 | list->dir = HDA_INPUT; |
670 | p->dir = dir; | 2497 | list->idx = idx; |
671 | p->idx = idx; | 2498 | spec->num_loopbacks++; |
672 | spec->loopback.amplist = spec->loopback_list; | 2499 | spec->loopback.amplist = spec->loopback_list; |
673 | } | 2500 | } |
674 | #else | 2501 | #else |
675 | #define add_input_loopback(codec,nid,dir,idx) | 2502 | #define add_loopback_list(spec, mix, idx) /* NOP */ |
676 | #endif | 2503 | #endif |
677 | 2504 | ||
678 | /* | 2505 | /* create input playback/capture controls for the given pin */ |
679 | * create mixer controls if possible | 2506 | static int new_analog_input(struct hda_codec *codec, int input_idx, |
680 | */ | 2507 | hda_nid_t pin, const char *ctlname, int ctlidx, |
681 | static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, | 2508 | hda_nid_t mix_nid) |
682 | unsigned int index, const char *type, | ||
683 | const char *dir_sfx, int is_loopback) | ||
684 | { | 2509 | { |
685 | char name[32]; | 2510 | struct hda_gen_spec *spec = codec->spec; |
686 | int err; | 2511 | struct nid_path *path; |
687 | int created = 0; | 2512 | unsigned int val; |
688 | struct snd_kcontrol_new knew; | 2513 | int err, idx; |
689 | 2514 | ||
690 | if (type) | 2515 | if (!nid_has_volume(codec, mix_nid, HDA_INPUT) && |
691 | sprintf(name, "%s %s Switch", type, dir_sfx); | 2516 | !nid_has_mute(codec, mix_nid, HDA_INPUT)) |
692 | else | 2517 | return 0; /* no need for analog loopback */ |
693 | sprintf(name, "%s Switch", dir_sfx); | 2518 | |
694 | if ((node->wid_caps & AC_WCAP_IN_AMP) && | 2519 | path = snd_hda_add_new_path(codec, pin, mix_nid, 0); |
695 | (node->amp_in_caps & AC_AMPCAP_MUTE)) { | 2520 | if (!path) |
696 | knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT); | 2521 | return -EINVAL; |
697 | if (is_loopback) | 2522 | print_nid_path("loopback", path); |
698 | add_input_loopback(codec, node->nid, HDA_INPUT, index); | 2523 | spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); |
699 | snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); | 2524 | |
700 | err = snd_hda_ctl_add(codec, node->nid, | 2525 | idx = path->idx[path->depth - 1]; |
701 | snd_ctl_new1(&knew, codec)); | 2526 | if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { |
2527 | val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); | ||
2528 | err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val); | ||
702 | if (err < 0) | 2529 | if (err < 0) |
703 | return err; | 2530 | return err; |
704 | created = 1; | 2531 | path->ctls[NID_PATH_VOL_CTL] = val; |
705 | } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && | 2532 | } |
706 | (node->amp_out_caps & AC_AMPCAP_MUTE)) { | 2533 | |
707 | knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT); | 2534 | if (nid_has_mute(codec, mix_nid, HDA_INPUT)) { |
708 | if (is_loopback) | 2535 | val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); |
709 | add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); | 2536 | err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val); |
710 | snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); | ||
711 | err = snd_hda_ctl_add(codec, node->nid, | ||
712 | snd_ctl_new1(&knew, codec)); | ||
713 | if (err < 0) | 2537 | if (err < 0) |
714 | return err; | 2538 | return err; |
715 | created = 1; | 2539 | path->ctls[NID_PATH_MUTE_CTL] = val; |
716 | } | 2540 | } |
717 | 2541 | ||
718 | if (type) | 2542 | path->active = true; |
719 | sprintf(name, "%s %s Volume", type, dir_sfx); | 2543 | add_loopback_list(spec, mix_nid, idx); |
720 | else | 2544 | |
721 | sprintf(name, "%s Volume", dir_sfx); | 2545 | if (spec->mixer_nid != spec->mixer_merge_nid && |
722 | if ((node->wid_caps & AC_WCAP_IN_AMP) && | 2546 | !spec->loopback_merge_path) { |
723 | (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { | 2547 | path = snd_hda_add_new_path(codec, spec->mixer_nid, |
724 | knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); | 2548 | spec->mixer_merge_nid, 0); |
725 | snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); | 2549 | if (path) { |
726 | err = snd_hda_ctl_add(codec, node->nid, | 2550 | print_nid_path("loopback-merge", path); |
727 | snd_ctl_new1(&knew, codec)); | 2551 | path->active = true; |
2552 | spec->loopback_merge_path = | ||
2553 | snd_hda_get_path_idx(codec, path); | ||
2554 | } | ||
2555 | } | ||
2556 | |||
2557 | return 0; | ||
2558 | } | ||
2559 | |||
2560 | static int is_input_pin(struct hda_codec *codec, hda_nid_t nid) | ||
2561 | { | ||
2562 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | ||
2563 | return (pincap & AC_PINCAP_IN) != 0; | ||
2564 | } | ||
2565 | |||
2566 | /* Parse the codec tree and retrieve ADCs */ | ||
2567 | static int fill_adc_nids(struct hda_codec *codec) | ||
2568 | { | ||
2569 | struct hda_gen_spec *spec = codec->spec; | ||
2570 | hda_nid_t nid; | ||
2571 | hda_nid_t *adc_nids = spec->adc_nids; | ||
2572 | int max_nums = ARRAY_SIZE(spec->adc_nids); | ||
2573 | int i, nums = 0; | ||
2574 | |||
2575 | nid = codec->start_nid; | ||
2576 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
2577 | unsigned int caps = get_wcaps(codec, nid); | ||
2578 | int type = get_wcaps_type(caps); | ||
2579 | |||
2580 | if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL)) | ||
2581 | continue; | ||
2582 | adc_nids[nums] = nid; | ||
2583 | if (++nums >= max_nums) | ||
2584 | break; | ||
2585 | } | ||
2586 | spec->num_adc_nids = nums; | ||
2587 | |||
2588 | /* copy the detected ADCs to all_adcs[] */ | ||
2589 | spec->num_all_adcs = nums; | ||
2590 | memcpy(spec->all_adcs, spec->adc_nids, nums * sizeof(hda_nid_t)); | ||
2591 | |||
2592 | return nums; | ||
2593 | } | ||
2594 | |||
2595 | /* filter out invalid adc_nids that don't give all active input pins; | ||
2596 | * if needed, check whether dynamic ADC-switching is available | ||
2597 | */ | ||
2598 | static int check_dyn_adc_switch(struct hda_codec *codec) | ||
2599 | { | ||
2600 | struct hda_gen_spec *spec = codec->spec; | ||
2601 | struct hda_input_mux *imux = &spec->input_mux; | ||
2602 | unsigned int ok_bits; | ||
2603 | int i, n, nums; | ||
2604 | |||
2605 | again: | ||
2606 | nums = 0; | ||
2607 | ok_bits = 0; | ||
2608 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
2609 | for (i = 0; i < imux->num_items; i++) { | ||
2610 | if (!spec->input_paths[i][n]) | ||
2611 | break; | ||
2612 | } | ||
2613 | if (i >= imux->num_items) { | ||
2614 | ok_bits |= (1 << n); | ||
2615 | nums++; | ||
2616 | } | ||
2617 | } | ||
2618 | |||
2619 | if (!ok_bits) { | ||
2620 | if (spec->shared_mic_hp) { | ||
2621 | spec->shared_mic_hp = 0; | ||
2622 | imux->num_items = 1; | ||
2623 | goto again; | ||
2624 | } | ||
2625 | |||
2626 | /* check whether ADC-switch is possible */ | ||
2627 | for (i = 0; i < imux->num_items; i++) { | ||
2628 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
2629 | if (spec->input_paths[i][n]) { | ||
2630 | spec->dyn_adc_idx[i] = n; | ||
2631 | break; | ||
2632 | } | ||
2633 | } | ||
2634 | } | ||
2635 | |||
2636 | snd_printdd("hda-codec: enabling ADC switching\n"); | ||
2637 | spec->dyn_adc_switch = 1; | ||
2638 | } else if (nums != spec->num_adc_nids) { | ||
2639 | /* shrink the invalid adcs and input paths */ | ||
2640 | nums = 0; | ||
2641 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
2642 | if (!(ok_bits & (1 << n))) | ||
2643 | continue; | ||
2644 | if (n != nums) { | ||
2645 | spec->adc_nids[nums] = spec->adc_nids[n]; | ||
2646 | for (i = 0; i < imux->num_items; i++) { | ||
2647 | invalidate_nid_path(codec, | ||
2648 | spec->input_paths[i][nums]); | ||
2649 | spec->input_paths[i][nums] = | ||
2650 | spec->input_paths[i][n]; | ||
2651 | } | ||
2652 | } | ||
2653 | nums++; | ||
2654 | } | ||
2655 | spec->num_adc_nids = nums; | ||
2656 | } | ||
2657 | |||
2658 | if (imux->num_items == 1 || spec->shared_mic_hp) { | ||
2659 | snd_printdd("hda-codec: reducing to a single ADC\n"); | ||
2660 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | ||
2661 | } | ||
2662 | |||
2663 | /* single index for individual volumes ctls */ | ||
2664 | if (!spec->dyn_adc_switch && spec->multi_cap_vol) | ||
2665 | spec->num_adc_nids = 1; | ||
2666 | |||
2667 | return 0; | ||
2668 | } | ||
2669 | |||
2670 | /* parse capture source paths from the given pin and create imux items */ | ||
2671 | static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin, | ||
2672 | int cfg_idx, int num_adcs, | ||
2673 | const char *label, int anchor) | ||
2674 | { | ||
2675 | struct hda_gen_spec *spec = codec->spec; | ||
2676 | struct hda_input_mux *imux = &spec->input_mux; | ||
2677 | int imux_idx = imux->num_items; | ||
2678 | bool imux_added = false; | ||
2679 | int c; | ||
2680 | |||
2681 | for (c = 0; c < num_adcs; c++) { | ||
2682 | struct nid_path *path; | ||
2683 | hda_nid_t adc = spec->adc_nids[c]; | ||
2684 | |||
2685 | if (!is_reachable_path(codec, pin, adc)) | ||
2686 | continue; | ||
2687 | path = snd_hda_add_new_path(codec, pin, adc, anchor); | ||
2688 | if (!path) | ||
2689 | continue; | ||
2690 | print_nid_path("input", path); | ||
2691 | spec->input_paths[imux_idx][c] = | ||
2692 | snd_hda_get_path_idx(codec, path); | ||
2693 | |||
2694 | if (!imux_added) { | ||
2695 | spec->imux_pins[imux->num_items] = pin; | ||
2696 | snd_hda_add_imux_item(imux, label, cfg_idx, NULL); | ||
2697 | imux_added = true; | ||
2698 | } | ||
2699 | } | ||
2700 | |||
2701 | return 0; | ||
2702 | } | ||
2703 | |||
2704 | /* | ||
2705 | * create playback/capture controls for input pins | ||
2706 | */ | ||
2707 | |||
2708 | /* fill the label for each input at first */ | ||
2709 | static int fill_input_pin_labels(struct hda_codec *codec) | ||
2710 | { | ||
2711 | struct hda_gen_spec *spec = codec->spec; | ||
2712 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2713 | int i; | ||
2714 | |||
2715 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2716 | hda_nid_t pin = cfg->inputs[i].pin; | ||
2717 | const char *label; | ||
2718 | int j, idx; | ||
2719 | |||
2720 | if (!is_input_pin(codec, pin)) | ||
2721 | continue; | ||
2722 | |||
2723 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
2724 | idx = 0; | ||
2725 | for (j = i - 1; j >= 0; j--) { | ||
2726 | if (spec->input_labels[j] && | ||
2727 | !strcmp(spec->input_labels[j], label)) { | ||
2728 | idx = spec->input_label_idxs[j] + 1; | ||
2729 | break; | ||
2730 | } | ||
2731 | } | ||
2732 | |||
2733 | spec->input_labels[i] = label; | ||
2734 | spec->input_label_idxs[i] = idx; | ||
2735 | } | ||
2736 | |||
2737 | return 0; | ||
2738 | } | ||
2739 | |||
2740 | #define CFG_IDX_MIX 99 /* a dummy cfg->input idx for stereo mix */ | ||
2741 | |||
2742 | static int create_input_ctls(struct hda_codec *codec) | ||
2743 | { | ||
2744 | struct hda_gen_spec *spec = codec->spec; | ||
2745 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2746 | hda_nid_t mixer = spec->mixer_nid; | ||
2747 | int num_adcs; | ||
2748 | int i, err; | ||
2749 | unsigned int val; | ||
2750 | |||
2751 | num_adcs = fill_adc_nids(codec); | ||
2752 | if (num_adcs < 0) | ||
2753 | return 0; | ||
2754 | |||
2755 | err = fill_input_pin_labels(codec); | ||
2756 | if (err < 0) | ||
2757 | return err; | ||
2758 | |||
2759 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2760 | hda_nid_t pin; | ||
2761 | |||
2762 | pin = cfg->inputs[i].pin; | ||
2763 | if (!is_input_pin(codec, pin)) | ||
2764 | continue; | ||
2765 | |||
2766 | val = PIN_IN; | ||
2767 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | ||
2768 | val |= snd_hda_get_default_vref(codec, pin); | ||
2769 | set_pin_target(codec, pin, val, false); | ||
2770 | |||
2771 | if (mixer) { | ||
2772 | if (is_reachable_path(codec, pin, mixer)) { | ||
2773 | err = new_analog_input(codec, i, pin, | ||
2774 | spec->input_labels[i], | ||
2775 | spec->input_label_idxs[i], | ||
2776 | mixer); | ||
2777 | if (err < 0) | ||
2778 | return err; | ||
2779 | } | ||
2780 | } | ||
2781 | |||
2782 | err = parse_capture_source(codec, pin, i, num_adcs, | ||
2783 | spec->input_labels[i], -mixer); | ||
728 | if (err < 0) | 2784 | if (err < 0) |
729 | return err; | 2785 | return err; |
730 | created = 1; | 2786 | |
731 | } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && | 2787 | if (spec->add_in_jack_modes) { |
732 | (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { | 2788 | err = create_in_jack_mode(codec, pin); |
733 | knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); | 2789 | if (err < 0) |
734 | snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); | 2790 | return err; |
735 | err = snd_hda_ctl_add(codec, node->nid, | 2791 | } |
736 | snd_ctl_new1(&knew, codec)); | 2792 | } |
2793 | |||
2794 | if (mixer && spec->add_stereo_mix_input) { | ||
2795 | err = parse_capture_source(codec, mixer, CFG_IDX_MIX, num_adcs, | ||
2796 | "Stereo Mix", 0); | ||
737 | if (err < 0) | 2797 | if (err < 0) |
738 | return err; | 2798 | return err; |
739 | created = 1; | ||
740 | } | 2799 | } |
741 | 2800 | ||
742 | return created; | 2801 | return 0; |
743 | } | 2802 | } |
744 | 2803 | ||
2804 | |||
745 | /* | 2805 | /* |
746 | * check whether the controls with the given name and direction suffix already exist | 2806 | * input source mux |
747 | */ | 2807 | */ |
748 | static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir) | 2808 | |
749 | { | 2809 | /* get the input path specified by the given adc and imux indices */ |
750 | struct snd_ctl_elem_id id; | 2810 | static struct nid_path *get_input_path(struct hda_codec *codec, int adc_idx, int imux_idx) |
751 | memset(&id, 0, sizeof(id)); | 2811 | { |
752 | sprintf(id.name, "%s %s Volume", type, dir); | 2812 | struct hda_gen_spec *spec = codec->spec; |
753 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2813 | if (imux_idx < 0 || imux_idx >= HDA_MAX_NUM_INPUTS) { |
754 | if (snd_ctl_find_id(codec->bus->card, &id)) | 2814 | snd_BUG(); |
755 | return 1; | 2815 | return NULL; |
756 | sprintf(id.name, "%s %s Switch", type, dir); | 2816 | } |
757 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2817 | if (spec->dyn_adc_switch) |
758 | if (snd_ctl_find_id(codec->bus->card, &id)) | 2818 | adc_idx = spec->dyn_adc_idx[imux_idx]; |
759 | return 1; | 2819 | if (adc_idx < 0 || adc_idx >= AUTO_CFG_MAX_INS) { |
2820 | snd_BUG(); | ||
2821 | return NULL; | ||
2822 | } | ||
2823 | return snd_hda_get_path_from_idx(codec, spec->input_paths[imux_idx][adc_idx]); | ||
2824 | } | ||
2825 | |||
2826 | static int mux_select(struct hda_codec *codec, unsigned int adc_idx, | ||
2827 | unsigned int idx); | ||
2828 | |||
2829 | static int mux_enum_info(struct snd_kcontrol *kcontrol, | ||
2830 | struct snd_ctl_elem_info *uinfo) | ||
2831 | { | ||
2832 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2833 | struct hda_gen_spec *spec = codec->spec; | ||
2834 | return snd_hda_input_mux_info(&spec->input_mux, uinfo); | ||
2835 | } | ||
2836 | |||
2837 | static int mux_enum_get(struct snd_kcontrol *kcontrol, | ||
2838 | struct snd_ctl_elem_value *ucontrol) | ||
2839 | { | ||
2840 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2841 | struct hda_gen_spec *spec = codec->spec; | ||
2842 | /* the ctls are created at once with multiple counts */ | ||
2843 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2844 | |||
2845 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; | ||
760 | return 0; | 2846 | return 0; |
761 | } | 2847 | } |
762 | 2848 | ||
2849 | static int mux_enum_put(struct snd_kcontrol *kcontrol, | ||
2850 | struct snd_ctl_elem_value *ucontrol) | ||
2851 | { | ||
2852 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2853 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2854 | return mux_select(codec, adc_idx, | ||
2855 | ucontrol->value.enumerated.item[0]); | ||
2856 | } | ||
2857 | |||
2858 | static const struct snd_kcontrol_new cap_src_temp = { | ||
2859 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2860 | .name = "Input Source", | ||
2861 | .info = mux_enum_info, | ||
2862 | .get = mux_enum_get, | ||
2863 | .put = mux_enum_put, | ||
2864 | }; | ||
2865 | |||
763 | /* | 2866 | /* |
764 | * build output mixer controls | 2867 | * capture volume and capture switch ctls |
765 | */ | 2868 | */ |
766 | static int create_output_mixers(struct hda_codec *codec, | 2869 | |
767 | const char * const *names) | 2870 | typedef int (*put_call_t)(struct snd_kcontrol *kcontrol, |
2871 | struct snd_ctl_elem_value *ucontrol); | ||
2872 | |||
2873 | /* call the given amp update function for all amps in the imux list at once */ | ||
2874 | static int cap_put_caller(struct snd_kcontrol *kcontrol, | ||
2875 | struct snd_ctl_elem_value *ucontrol, | ||
2876 | put_call_t func, int type) | ||
768 | { | 2877 | { |
769 | struct hda_gspec *spec = codec->spec; | 2878 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
770 | int i, err; | 2879 | struct hda_gen_spec *spec = codec->spec; |
2880 | const struct hda_input_mux *imux; | ||
2881 | struct nid_path *path; | ||
2882 | int i, adc_idx, err = 0; | ||
771 | 2883 | ||
772 | for (i = 0; i < spec->pcm_vol_nodes; i++) { | 2884 | imux = &spec->input_mux; |
773 | err = create_mixer(codec, spec->pcm_vol[i].node, | 2885 | adc_idx = kcontrol->id.index; |
774 | spec->pcm_vol[i].index, | 2886 | mutex_lock(&codec->control_mutex); |
775 | names[i], "Playback", 0); | 2887 | /* we use the cache-only update at first since multiple input paths |
2888 | * may shared the same amp; by updating only caches, the redundant | ||
2889 | * writes to hardware can be reduced. | ||
2890 | */ | ||
2891 | codec->cached_write = 1; | ||
2892 | for (i = 0; i < imux->num_items; i++) { | ||
2893 | path = get_input_path(codec, adc_idx, i); | ||
2894 | if (!path || !path->ctls[type]) | ||
2895 | continue; | ||
2896 | kcontrol->private_value = path->ctls[type]; | ||
2897 | err = func(kcontrol, ucontrol); | ||
776 | if (err < 0) | 2898 | if (err < 0) |
777 | return err; | 2899 | goto error; |
778 | } | 2900 | } |
779 | return 0; | 2901 | error: |
2902 | codec->cached_write = 0; | ||
2903 | mutex_unlock(&codec->control_mutex); | ||
2904 | snd_hda_codec_flush_cache(codec); /* flush the updates */ | ||
2905 | if (err >= 0 && spec->cap_sync_hook) | ||
2906 | spec->cap_sync_hook(codec, ucontrol); | ||
2907 | return err; | ||
780 | } | 2908 | } |
781 | 2909 | ||
782 | static int build_output_controls(struct hda_codec *codec) | 2910 | /* capture volume ctl callbacks */ |
2911 | #define cap_vol_info snd_hda_mixer_amp_volume_info | ||
2912 | #define cap_vol_get snd_hda_mixer_amp_volume_get | ||
2913 | #define cap_vol_tlv snd_hda_mixer_amp_tlv | ||
2914 | |||
2915 | static int cap_vol_put(struct snd_kcontrol *kcontrol, | ||
2916 | struct snd_ctl_elem_value *ucontrol) | ||
783 | { | 2917 | { |
784 | struct hda_gspec *spec = codec->spec; | 2918 | return cap_put_caller(kcontrol, ucontrol, |
785 | static const char * const types_speaker[] = { "Speaker", "Headphone" }; | 2919 | snd_hda_mixer_amp_volume_put, |
786 | static const char * const types_line[] = { "Front", "Headphone" }; | 2920 | NID_PATH_VOL_CTL); |
2921 | } | ||
787 | 2922 | ||
788 | switch (spec->pcm_vol_nodes) { | 2923 | static const struct snd_kcontrol_new cap_vol_temp = { |
789 | case 1: | 2924 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
790 | return create_mixer(codec, spec->pcm_vol[0].node, | 2925 | .name = "Capture Volume", |
791 | spec->pcm_vol[0].index, | 2926 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
792 | "Master", "Playback", 0); | 2927 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
793 | case 2: | 2928 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), |
794 | if (defcfg_type(spec->out_pin_node[0]) == AC_JACK_SPEAKER) | 2929 | .info = cap_vol_info, |
795 | return create_output_mixers(codec, types_speaker); | 2930 | .get = cap_vol_get, |
796 | else | 2931 | .put = cap_vol_put, |
797 | return create_output_mixers(codec, types_line); | 2932 | .tlv = { .c = cap_vol_tlv }, |
2933 | }; | ||
2934 | |||
2935 | /* capture switch ctl callbacks */ | ||
2936 | #define cap_sw_info snd_ctl_boolean_stereo_info | ||
2937 | #define cap_sw_get snd_hda_mixer_amp_switch_get | ||
2938 | |||
2939 | static int cap_sw_put(struct snd_kcontrol *kcontrol, | ||
2940 | struct snd_ctl_elem_value *ucontrol) | ||
2941 | { | ||
2942 | return cap_put_caller(kcontrol, ucontrol, | ||
2943 | snd_hda_mixer_amp_switch_put, | ||
2944 | NID_PATH_MUTE_CTL); | ||
2945 | } | ||
2946 | |||
2947 | static const struct snd_kcontrol_new cap_sw_temp = { | ||
2948 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2949 | .name = "Capture Switch", | ||
2950 | .info = cap_sw_info, | ||
2951 | .get = cap_sw_get, | ||
2952 | .put = cap_sw_put, | ||
2953 | }; | ||
2954 | |||
2955 | static int parse_capvol_in_path(struct hda_codec *codec, struct nid_path *path) | ||
2956 | { | ||
2957 | hda_nid_t nid; | ||
2958 | int i, depth; | ||
2959 | |||
2960 | path->ctls[NID_PATH_VOL_CTL] = path->ctls[NID_PATH_MUTE_CTL] = 0; | ||
2961 | for (depth = 0; depth < 3; depth++) { | ||
2962 | if (depth >= path->depth) | ||
2963 | return -EINVAL; | ||
2964 | i = path->depth - depth - 1; | ||
2965 | nid = path->path[i]; | ||
2966 | if (!path->ctls[NID_PATH_VOL_CTL]) { | ||
2967 | if (nid_has_volume(codec, nid, HDA_OUTPUT)) | ||
2968 | path->ctls[NID_PATH_VOL_CTL] = | ||
2969 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2970 | else if (nid_has_volume(codec, nid, HDA_INPUT)) { | ||
2971 | int idx = path->idx[i]; | ||
2972 | if (!depth && codec->single_adc_amp) | ||
2973 | idx = 0; | ||
2974 | path->ctls[NID_PATH_VOL_CTL] = | ||
2975 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT); | ||
2976 | } | ||
2977 | } | ||
2978 | if (!path->ctls[NID_PATH_MUTE_CTL]) { | ||
2979 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
2980 | path->ctls[NID_PATH_MUTE_CTL] = | ||
2981 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2982 | else if (nid_has_mute(codec, nid, HDA_INPUT)) { | ||
2983 | int idx = path->idx[i]; | ||
2984 | if (!depth && codec->single_adc_amp) | ||
2985 | idx = 0; | ||
2986 | path->ctls[NID_PATH_MUTE_CTL] = | ||
2987 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT); | ||
2988 | } | ||
2989 | } | ||
798 | } | 2990 | } |
799 | return 0; | 2991 | return 0; |
800 | } | 2992 | } |
801 | 2993 | ||
802 | /* create capture volume/switch */ | 2994 | static bool is_inv_dmic_pin(struct hda_codec *codec, hda_nid_t nid) |
803 | static int build_input_controls(struct hda_codec *codec) | ||
804 | { | 2995 | { |
805 | struct hda_gspec *spec = codec->spec; | 2996 | struct hda_gen_spec *spec = codec->spec; |
806 | struct hda_gnode *adc_node = spec->adc_node; | 2997 | struct auto_pin_cfg *cfg = &spec->autocfg; |
807 | int i, err; | 2998 | unsigned int val; |
808 | static struct snd_kcontrol_new cap_sel = { | 2999 | int i; |
809 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3000 | |
810 | .name = "Capture Source", | 3001 | if (!spec->inv_dmic_split) |
811 | .info = capture_source_info, | 3002 | return false; |
812 | .get = capture_source_get, | 3003 | for (i = 0; i < cfg->num_inputs; i++) { |
813 | .put = capture_source_put, | 3004 | if (cfg->inputs[i].pin != nid) |
814 | }; | 3005 | continue; |
3006 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
3007 | return false; | ||
3008 | val = snd_hda_codec_get_pincfg(codec, nid); | ||
3009 | return snd_hda_get_input_pin_attr(val) == INPUT_PIN_ATTR_INT; | ||
3010 | } | ||
3011 | return false; | ||
3012 | } | ||
815 | 3013 | ||
816 | if (! adc_node || ! spec->input_mux.num_items) | 3014 | /* capture switch put callback for a single control with hook call */ |
817 | return 0; /* not found */ | 3015 | static int cap_single_sw_put(struct snd_kcontrol *kcontrol, |
3016 | struct snd_ctl_elem_value *ucontrol) | ||
3017 | { | ||
3018 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3019 | struct hda_gen_spec *spec = codec->spec; | ||
3020 | int ret; | ||
818 | 3021 | ||
819 | spec->cur_cap_src = 0; | 3022 | ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
820 | select_input_connection(codec, adc_node, | 3023 | if (ret < 0) |
821 | spec->input_mux.items[0].index); | 3024 | return ret; |
822 | 3025 | ||
823 | /* create capture volume and switch controls if the ADC has an amp */ | 3026 | if (spec->cap_sync_hook) |
824 | /* do we have only a single item? */ | 3027 | spec->cap_sync_hook(codec, ucontrol); |
825 | if (spec->input_mux.num_items == 1) { | 3028 | |
826 | err = create_mixer(codec, adc_node, | 3029 | return ret; |
827 | spec->input_mux.items[0].index, | 3030 | } |
828 | NULL, "Capture", 0); | 3031 | |
829 | if (err < 0) | 3032 | static int add_single_cap_ctl(struct hda_codec *codec, const char *label, |
830 | return err; | 3033 | int idx, bool is_switch, unsigned int ctl, |
3034 | bool inv_dmic) | ||
3035 | { | ||
3036 | struct hda_gen_spec *spec = codec->spec; | ||
3037 | char tmpname[44]; | ||
3038 | int type = is_switch ? HDA_CTL_WIDGET_MUTE : HDA_CTL_WIDGET_VOL; | ||
3039 | const char *sfx = is_switch ? "Switch" : "Volume"; | ||
3040 | unsigned int chs = inv_dmic ? 1 : 3; | ||
3041 | struct snd_kcontrol_new *knew; | ||
3042 | |||
3043 | if (!ctl) | ||
831 | return 0; | 3044 | return 0; |
832 | } | ||
833 | 3045 | ||
834 | /* create input MUX if multiple sources are available */ | 3046 | if (label) |
835 | err = snd_hda_ctl_add(codec, spec->adc_node->nid, | 3047 | snprintf(tmpname, sizeof(tmpname), |
836 | snd_ctl_new1(&cap_sel, codec)); | 3048 | "%s Capture %s", label, sfx); |
3049 | else | ||
3050 | snprintf(tmpname, sizeof(tmpname), | ||
3051 | "Capture %s", sfx); | ||
3052 | knew = add_control(spec, type, tmpname, idx, | ||
3053 | amp_val_replace_channels(ctl, chs)); | ||
3054 | if (!knew) | ||
3055 | return -ENOMEM; | ||
3056 | if (is_switch) | ||
3057 | knew->put = cap_single_sw_put; | ||
3058 | if (!inv_dmic) | ||
3059 | return 0; | ||
3060 | |||
3061 | /* Make independent right kcontrol */ | ||
3062 | if (label) | ||
3063 | snprintf(tmpname, sizeof(tmpname), | ||
3064 | "Inverted %s Capture %s", label, sfx); | ||
3065 | else | ||
3066 | snprintf(tmpname, sizeof(tmpname), | ||
3067 | "Inverted Capture %s", sfx); | ||
3068 | knew = add_control(spec, type, tmpname, idx, | ||
3069 | amp_val_replace_channels(ctl, 2)); | ||
3070 | if (!knew) | ||
3071 | return -ENOMEM; | ||
3072 | if (is_switch) | ||
3073 | knew->put = cap_single_sw_put; | ||
3074 | return 0; | ||
3075 | } | ||
3076 | |||
3077 | /* create single (and simple) capture volume and switch controls */ | ||
3078 | static int create_single_cap_vol_ctl(struct hda_codec *codec, int idx, | ||
3079 | unsigned int vol_ctl, unsigned int sw_ctl, | ||
3080 | bool inv_dmic) | ||
3081 | { | ||
3082 | int err; | ||
3083 | err = add_single_cap_ctl(codec, NULL, idx, false, vol_ctl, inv_dmic); | ||
837 | if (err < 0) | 3084 | if (err < 0) |
838 | return err; | 3085 | return err; |
3086 | err = add_single_cap_ctl(codec, NULL, idx, true, sw_ctl, inv_dmic); | ||
3087 | if (err < 0) | ||
3088 | return err; | ||
3089 | return 0; | ||
3090 | } | ||
3091 | |||
3092 | /* create bound capture volume and switch controls */ | ||
3093 | static int create_bind_cap_vol_ctl(struct hda_codec *codec, int idx, | ||
3094 | unsigned int vol_ctl, unsigned int sw_ctl) | ||
3095 | { | ||
3096 | struct hda_gen_spec *spec = codec->spec; | ||
3097 | struct snd_kcontrol_new *knew; | ||
839 | 3098 | ||
840 | /* no volume control? */ | 3099 | if (vol_ctl) { |
841 | if (! (adc_node->wid_caps & AC_WCAP_IN_AMP) || | 3100 | knew = snd_hda_gen_add_kctl(spec, NULL, &cap_vol_temp); |
842 | ! (adc_node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) | 3101 | if (!knew) |
3102 | return -ENOMEM; | ||
3103 | knew->index = idx; | ||
3104 | knew->private_value = vol_ctl; | ||
3105 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
3106 | } | ||
3107 | if (sw_ctl) { | ||
3108 | knew = snd_hda_gen_add_kctl(spec, NULL, &cap_sw_temp); | ||
3109 | if (!knew) | ||
3110 | return -ENOMEM; | ||
3111 | knew->index = idx; | ||
3112 | knew->private_value = sw_ctl; | ||
3113 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
3114 | } | ||
3115 | return 0; | ||
3116 | } | ||
3117 | |||
3118 | /* return the vol ctl when used first in the imux list */ | ||
3119 | static unsigned int get_first_cap_ctl(struct hda_codec *codec, int idx, int type) | ||
3120 | { | ||
3121 | struct nid_path *path; | ||
3122 | unsigned int ctl; | ||
3123 | int i; | ||
3124 | |||
3125 | path = get_input_path(codec, 0, idx); | ||
3126 | if (!path) | ||
843 | return 0; | 3127 | return 0; |
3128 | ctl = path->ctls[type]; | ||
3129 | if (!ctl) | ||
3130 | return 0; | ||
3131 | for (i = 0; i < idx - 1; i++) { | ||
3132 | path = get_input_path(codec, 0, i); | ||
3133 | if (path && path->ctls[type] == ctl) | ||
3134 | return 0; | ||
3135 | } | ||
3136 | return ctl; | ||
3137 | } | ||
3138 | |||
3139 | /* create individual capture volume and switch controls per input */ | ||
3140 | static int create_multi_cap_vol_ctl(struct hda_codec *codec) | ||
3141 | { | ||
3142 | struct hda_gen_spec *spec = codec->spec; | ||
3143 | struct hda_input_mux *imux = &spec->input_mux; | ||
3144 | int i, err, type; | ||
3145 | |||
3146 | for (i = 0; i < imux->num_items; i++) { | ||
3147 | bool inv_dmic; | ||
3148 | int idx; | ||
3149 | |||
3150 | idx = imux->items[i].index; | ||
3151 | if (idx >= spec->autocfg.num_inputs) | ||
3152 | continue; | ||
3153 | inv_dmic = is_inv_dmic_pin(codec, spec->imux_pins[i]); | ||
844 | 3154 | ||
845 | for (i = 0; i < spec->input_mux.num_items; i++) { | 3155 | for (type = 0; type < 2; type++) { |
846 | struct snd_kcontrol_new knew; | 3156 | err = add_single_cap_ctl(codec, |
847 | char name[32]; | 3157 | spec->input_labels[idx], |
848 | sprintf(name, "%s Capture Volume", | 3158 | spec->input_label_idxs[idx], |
849 | spec->input_mux.items[i].label); | 3159 | type, |
850 | knew = (struct snd_kcontrol_new) | 3160 | get_first_cap_ctl(codec, i, type), |
851 | HDA_CODEC_VOLUME(name, adc_node->nid, | 3161 | inv_dmic); |
852 | spec->input_mux.items[i].index, | 3162 | if (err < 0) |
853 | HDA_INPUT); | 3163 | return err; |
854 | err = snd_hda_ctl_add(codec, adc_node->nid, | 3164 | } |
855 | snd_ctl_new1(&knew, codec)); | 3165 | } |
3166 | return 0; | ||
3167 | } | ||
3168 | |||
3169 | static int create_capture_mixers(struct hda_codec *codec) | ||
3170 | { | ||
3171 | struct hda_gen_spec *spec = codec->spec; | ||
3172 | struct hda_input_mux *imux = &spec->input_mux; | ||
3173 | int i, n, nums, err; | ||
3174 | |||
3175 | if (spec->dyn_adc_switch) | ||
3176 | nums = 1; | ||
3177 | else | ||
3178 | nums = spec->num_adc_nids; | ||
3179 | |||
3180 | if (!spec->auto_mic && imux->num_items > 1) { | ||
3181 | struct snd_kcontrol_new *knew; | ||
3182 | const char *name; | ||
3183 | name = nums > 1 ? "Input Source" : "Capture Source"; | ||
3184 | knew = snd_hda_gen_add_kctl(spec, name, &cap_src_temp); | ||
3185 | if (!knew) | ||
3186 | return -ENOMEM; | ||
3187 | knew->count = nums; | ||
3188 | } | ||
3189 | |||
3190 | for (n = 0; n < nums; n++) { | ||
3191 | bool multi = false; | ||
3192 | bool multi_cap_vol = spec->multi_cap_vol; | ||
3193 | bool inv_dmic = false; | ||
3194 | int vol, sw; | ||
3195 | |||
3196 | vol = sw = 0; | ||
3197 | for (i = 0; i < imux->num_items; i++) { | ||
3198 | struct nid_path *path; | ||
3199 | path = get_input_path(codec, n, i); | ||
3200 | if (!path) | ||
3201 | continue; | ||
3202 | parse_capvol_in_path(codec, path); | ||
3203 | if (!vol) | ||
3204 | vol = path->ctls[NID_PATH_VOL_CTL]; | ||
3205 | else if (vol != path->ctls[NID_PATH_VOL_CTL]) { | ||
3206 | multi = true; | ||
3207 | if (!same_amp_caps(codec, vol, | ||
3208 | path->ctls[NID_PATH_VOL_CTL], HDA_INPUT)) | ||
3209 | multi_cap_vol = true; | ||
3210 | } | ||
3211 | if (!sw) | ||
3212 | sw = path->ctls[NID_PATH_MUTE_CTL]; | ||
3213 | else if (sw != path->ctls[NID_PATH_MUTE_CTL]) { | ||
3214 | multi = true; | ||
3215 | if (!same_amp_caps(codec, sw, | ||
3216 | path->ctls[NID_PATH_MUTE_CTL], HDA_INPUT)) | ||
3217 | multi_cap_vol = true; | ||
3218 | } | ||
3219 | if (is_inv_dmic_pin(codec, spec->imux_pins[i])) | ||
3220 | inv_dmic = true; | ||
3221 | } | ||
3222 | |||
3223 | if (!multi) | ||
3224 | err = create_single_cap_vol_ctl(codec, n, vol, sw, | ||
3225 | inv_dmic); | ||
3226 | else if (!multi_cap_vol) | ||
3227 | err = create_bind_cap_vol_ctl(codec, n, vol, sw); | ||
3228 | else | ||
3229 | err = create_multi_cap_vol_ctl(codec); | ||
856 | if (err < 0) | 3230 | if (err < 0) |
857 | return err; | 3231 | return err; |
858 | } | 3232 | } |
@@ -860,226 +3234,1696 @@ static int build_input_controls(struct hda_codec *codec) | |||
860 | return 0; | 3234 | return 0; |
861 | } | 3235 | } |
862 | 3236 | ||
3237 | /* | ||
3238 | * add mic boosts if needed | ||
3239 | */ | ||
3240 | |||
3241 | /* check whether the given amp is feasible as a boost volume */ | ||
3242 | static bool check_boost_vol(struct hda_codec *codec, hda_nid_t nid, | ||
3243 | int dir, int idx) | ||
3244 | { | ||
3245 | unsigned int step; | ||
3246 | |||
3247 | if (!nid_has_volume(codec, nid, dir) || | ||
3248 | is_ctl_associated(codec, nid, dir, idx, NID_PATH_VOL_CTL) || | ||
3249 | is_ctl_associated(codec, nid, dir, idx, NID_PATH_BOOST_CTL)) | ||
3250 | return false; | ||
3251 | |||
3252 | step = (query_amp_caps(codec, nid, dir) & AC_AMPCAP_STEP_SIZE) | ||
3253 | >> AC_AMPCAP_STEP_SIZE_SHIFT; | ||
3254 | if (step < 0x20) | ||
3255 | return false; | ||
3256 | return true; | ||
3257 | } | ||
3258 | |||
3259 | /* look for a boost amp in a widget close to the pin */ | ||
3260 | static unsigned int look_for_boost_amp(struct hda_codec *codec, | ||
3261 | struct nid_path *path) | ||
3262 | { | ||
3263 | unsigned int val = 0; | ||
3264 | hda_nid_t nid; | ||
3265 | int depth; | ||
3266 | |||
3267 | for (depth = 0; depth < 3; depth++) { | ||
3268 | if (depth >= path->depth - 1) | ||
3269 | break; | ||
3270 | nid = path->path[depth]; | ||
3271 | if (depth && check_boost_vol(codec, nid, HDA_OUTPUT, 0)) { | ||
3272 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3273 | break; | ||
3274 | } else if (check_boost_vol(codec, nid, HDA_INPUT, | ||
3275 | path->idx[depth])) { | ||
3276 | val = HDA_COMPOSE_AMP_VAL(nid, 3, path->idx[depth], | ||
3277 | HDA_INPUT); | ||
3278 | break; | ||
3279 | } | ||
3280 | } | ||
3281 | |||
3282 | return val; | ||
3283 | } | ||
3284 | |||
3285 | static int parse_mic_boost(struct hda_codec *codec) | ||
3286 | { | ||
3287 | struct hda_gen_spec *spec = codec->spec; | ||
3288 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3289 | struct hda_input_mux *imux = &spec->input_mux; | ||
3290 | int i; | ||
3291 | |||
3292 | if (!spec->num_adc_nids) | ||
3293 | return 0; | ||
3294 | |||
3295 | for (i = 0; i < imux->num_items; i++) { | ||
3296 | struct nid_path *path; | ||
3297 | unsigned int val; | ||
3298 | int idx; | ||
3299 | char boost_label[44]; | ||
3300 | |||
3301 | idx = imux->items[i].index; | ||
3302 | if (idx >= imux->num_items) | ||
3303 | continue; | ||
3304 | |||
3305 | /* check only line-in and mic pins */ | ||
3306 | if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN) | ||
3307 | continue; | ||
3308 | |||
3309 | path = get_input_path(codec, 0, i); | ||
3310 | if (!path) | ||
3311 | continue; | ||
3312 | |||
3313 | val = look_for_boost_amp(codec, path); | ||
3314 | if (!val) | ||
3315 | continue; | ||
3316 | |||
3317 | /* create a boost control */ | ||
3318 | snprintf(boost_label, sizeof(boost_label), | ||
3319 | "%s Boost Volume", spec->input_labels[idx]); | ||
3320 | if (!add_control(spec, HDA_CTL_WIDGET_VOL, boost_label, | ||
3321 | spec->input_label_idxs[idx], val)) | ||
3322 | return -ENOMEM; | ||
3323 | |||
3324 | path->ctls[NID_PATH_BOOST_CTL] = val; | ||
3325 | } | ||
3326 | return 0; | ||
3327 | } | ||
3328 | |||
3329 | /* | ||
3330 | * parse digital I/Os and set up NIDs in BIOS auto-parse mode | ||
3331 | */ | ||
3332 | static void parse_digital(struct hda_codec *codec) | ||
3333 | { | ||
3334 | struct hda_gen_spec *spec = codec->spec; | ||
3335 | struct nid_path *path; | ||
3336 | int i, nums; | ||
3337 | hda_nid_t dig_nid, pin; | ||
3338 | |||
3339 | /* support multiple SPDIFs; the secondary is set up as a slave */ | ||
3340 | nums = 0; | ||
3341 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
3342 | pin = spec->autocfg.dig_out_pins[i]; | ||
3343 | dig_nid = look_for_dac(codec, pin, true); | ||
3344 | if (!dig_nid) | ||
3345 | continue; | ||
3346 | path = snd_hda_add_new_path(codec, dig_nid, pin, 0); | ||
3347 | if (!path) | ||
3348 | continue; | ||
3349 | print_nid_path("digout", path); | ||
3350 | path->active = true; | ||
3351 | spec->digout_paths[i] = snd_hda_get_path_idx(codec, path); | ||
3352 | set_pin_target(codec, pin, PIN_OUT, false); | ||
3353 | if (!nums) { | ||
3354 | spec->multiout.dig_out_nid = dig_nid; | ||
3355 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
3356 | } else { | ||
3357 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
3358 | if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
3359 | break; | ||
3360 | spec->slave_dig_outs[nums - 1] = dig_nid; | ||
3361 | } | ||
3362 | nums++; | ||
3363 | } | ||
3364 | |||
3365 | if (spec->autocfg.dig_in_pin) { | ||
3366 | pin = spec->autocfg.dig_in_pin; | ||
3367 | dig_nid = codec->start_nid; | ||
3368 | for (i = 0; i < codec->num_nodes; i++, dig_nid++) { | ||
3369 | unsigned int wcaps = get_wcaps(codec, dig_nid); | ||
3370 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) | ||
3371 | continue; | ||
3372 | if (!(wcaps & AC_WCAP_DIGITAL)) | ||
3373 | continue; | ||
3374 | path = snd_hda_add_new_path(codec, pin, dig_nid, 0); | ||
3375 | if (path) { | ||
3376 | print_nid_path("digin", path); | ||
3377 | path->active = true; | ||
3378 | spec->dig_in_nid = dig_nid; | ||
3379 | spec->digin_path = snd_hda_get_path_idx(codec, path); | ||
3380 | set_pin_target(codec, pin, PIN_IN, false); | ||
3381 | break; | ||
3382 | } | ||
3383 | } | ||
3384 | } | ||
3385 | } | ||
3386 | |||
863 | 3387 | ||
864 | /* | 3388 | /* |
865 | * parse the nodes recursively until reach to the output PIN. | 3389 | * input MUX handling |
866 | * | 3390 | */ |
867 | * returns 0 - if not found, | 3391 | |
868 | * 1 - if found, but no mixer is created | 3392 | static bool dyn_adc_pcm_resetup(struct hda_codec *codec, int cur); |
869 | * 2 - if found and mixer was already created, (just skip) | 3393 | |
870 | * a negative error code | 3394 | /* select the given imux item; either unmute exclusively or select the route */ |
3395 | static int mux_select(struct hda_codec *codec, unsigned int adc_idx, | ||
3396 | unsigned int idx) | ||
3397 | { | ||
3398 | struct hda_gen_spec *spec = codec->spec; | ||
3399 | const struct hda_input_mux *imux; | ||
3400 | struct nid_path *old_path, *path; | ||
3401 | |||
3402 | imux = &spec->input_mux; | ||
3403 | if (!imux->num_items) | ||
3404 | return 0; | ||
3405 | |||
3406 | if (idx >= imux->num_items) | ||
3407 | idx = imux->num_items - 1; | ||
3408 | if (spec->cur_mux[adc_idx] == idx) | ||
3409 | return 0; | ||
3410 | |||
3411 | old_path = get_input_path(codec, adc_idx, spec->cur_mux[adc_idx]); | ||
3412 | if (!old_path) | ||
3413 | return 0; | ||
3414 | if (old_path->active) | ||
3415 | snd_hda_activate_path(codec, old_path, false, false); | ||
3416 | |||
3417 | spec->cur_mux[adc_idx] = idx; | ||
3418 | |||
3419 | if (spec->shared_mic_hp) | ||
3420 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); | ||
3421 | |||
3422 | if (spec->dyn_adc_switch) | ||
3423 | dyn_adc_pcm_resetup(codec, idx); | ||
3424 | |||
3425 | path = get_input_path(codec, adc_idx, idx); | ||
3426 | if (!path) | ||
3427 | return 0; | ||
3428 | if (path->active) | ||
3429 | return 0; | ||
3430 | snd_hda_activate_path(codec, path, true, false); | ||
3431 | if (spec->cap_sync_hook) | ||
3432 | spec->cap_sync_hook(codec, NULL); | ||
3433 | path_power_down_sync(codec, old_path); | ||
3434 | return 1; | ||
3435 | } | ||
3436 | |||
3437 | |||
3438 | /* | ||
3439 | * Jack detections for HP auto-mute and mic-switch | ||
3440 | */ | ||
3441 | |||
3442 | /* check each pin in the given array; returns true if any of them is plugged */ | ||
3443 | static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | ||
3444 | { | ||
3445 | int i, present = 0; | ||
3446 | |||
3447 | for (i = 0; i < num_pins; i++) { | ||
3448 | hda_nid_t nid = pins[i]; | ||
3449 | if (!nid) | ||
3450 | break; | ||
3451 | /* don't detect pins retasked as inputs */ | ||
3452 | if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN) | ||
3453 | continue; | ||
3454 | present |= snd_hda_jack_detect(codec, nid); | ||
3455 | } | ||
3456 | return present; | ||
3457 | } | ||
3458 | |||
3459 | /* standard HP/line-out auto-mute helper */ | ||
3460 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | ||
3461 | bool mute) | ||
3462 | { | ||
3463 | struct hda_gen_spec *spec = codec->spec; | ||
3464 | int i; | ||
3465 | |||
3466 | for (i = 0; i < num_pins; i++) { | ||
3467 | hda_nid_t nid = pins[i]; | ||
3468 | unsigned int val; | ||
3469 | if (!nid) | ||
3470 | break; | ||
3471 | /* don't reset VREF value in case it's controlling | ||
3472 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
3473 | */ | ||
3474 | if (spec->keep_vref_in_automute) | ||
3475 | val = snd_hda_codec_get_pin_target(codec, nid) & ~PIN_HP; | ||
3476 | else | ||
3477 | val = 0; | ||
3478 | if (!mute) | ||
3479 | val |= snd_hda_codec_get_pin_target(codec, nid); | ||
3480 | /* here we call update_pin_ctl() so that the pinctl is changed | ||
3481 | * without changing the pinctl target value; | ||
3482 | * the original target value will be still referred at the | ||
3483 | * init / resume again | ||
3484 | */ | ||
3485 | update_pin_ctl(codec, nid, val); | ||
3486 | set_pin_eapd(codec, nid, !mute); | ||
3487 | } | ||
3488 | } | ||
3489 | |||
3490 | /* Toggle outputs muting */ | ||
3491 | void snd_hda_gen_update_outputs(struct hda_codec *codec) | ||
3492 | { | ||
3493 | struct hda_gen_spec *spec = codec->spec; | ||
3494 | int on; | ||
3495 | |||
3496 | /* Control HP pins/amps depending on master_mute state; | ||
3497 | * in general, HP pins/amps control should be enabled in all cases, | ||
3498 | * but currently set only for master_mute, just to be safe | ||
3499 | */ | ||
3500 | if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ | ||
3501 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
3502 | spec->autocfg.hp_pins, spec->master_mute); | ||
3503 | |||
3504 | if (!spec->automute_speaker) | ||
3505 | on = 0; | ||
3506 | else | ||
3507 | on = spec->hp_jack_present | spec->line_jack_present; | ||
3508 | on |= spec->master_mute; | ||
3509 | spec->speaker_muted = on; | ||
3510 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | ||
3511 | spec->autocfg.speaker_pins, on); | ||
3512 | |||
3513 | /* toggle line-out mutes if needed, too */ | ||
3514 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
3515 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || | ||
3516 | spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) | ||
3517 | return; | ||
3518 | if (!spec->automute_lo) | ||
3519 | on = 0; | ||
3520 | else | ||
3521 | on = spec->hp_jack_present; | ||
3522 | on |= spec->master_mute; | ||
3523 | spec->line_out_muted = on; | ||
3524 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
3525 | spec->autocfg.line_out_pins, on); | ||
3526 | } | ||
3527 | EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); | ||
3528 | |||
3529 | static void call_update_outputs(struct hda_codec *codec) | ||
3530 | { | ||
3531 | struct hda_gen_spec *spec = codec->spec; | ||
3532 | if (spec->automute_hook) | ||
3533 | spec->automute_hook(codec); | ||
3534 | else | ||
3535 | snd_hda_gen_update_outputs(codec); | ||
3536 | } | ||
3537 | |||
3538 | /* standard HP-automute helper */ | ||
3539 | void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3540 | { | ||
3541 | struct hda_gen_spec *spec = codec->spec; | ||
3542 | hda_nid_t *pins = spec->autocfg.hp_pins; | ||
3543 | int num_pins = ARRAY_SIZE(spec->autocfg.hp_pins); | ||
3544 | |||
3545 | /* No detection for the first HP jack during indep-HP mode */ | ||
3546 | if (spec->indep_hp_enabled) { | ||
3547 | pins++; | ||
3548 | num_pins--; | ||
3549 | } | ||
3550 | |||
3551 | spec->hp_jack_present = detect_jacks(codec, num_pins, pins); | ||
3552 | if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo)) | ||
3553 | return; | ||
3554 | call_update_outputs(codec); | ||
3555 | } | ||
3556 | EXPORT_SYMBOL_HDA(snd_hda_gen_hp_automute); | ||
3557 | |||
3558 | /* standard line-out-automute helper */ | ||
3559 | void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3560 | { | ||
3561 | struct hda_gen_spec *spec = codec->spec; | ||
3562 | |||
3563 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
3564 | return; | ||
3565 | /* check LO jack only when it's different from HP */ | ||
3566 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) | ||
3567 | return; | ||
3568 | |||
3569 | spec->line_jack_present = | ||
3570 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
3571 | spec->autocfg.line_out_pins); | ||
3572 | if (!spec->automute_speaker || !spec->detect_lo) | ||
3573 | return; | ||
3574 | call_update_outputs(codec); | ||
3575 | } | ||
3576 | EXPORT_SYMBOL_HDA(snd_hda_gen_line_automute); | ||
3577 | |||
3578 | /* standard mic auto-switch helper */ | ||
3579 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3580 | { | ||
3581 | struct hda_gen_spec *spec = codec->spec; | ||
3582 | int i; | ||
3583 | |||
3584 | if (!spec->auto_mic) | ||
3585 | return; | ||
3586 | |||
3587 | for (i = spec->am_num_entries - 1; i > 0; i--) { | ||
3588 | hda_nid_t pin = spec->am_entry[i].pin; | ||
3589 | /* don't detect pins retasked as outputs */ | ||
3590 | if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) | ||
3591 | continue; | ||
3592 | if (snd_hda_jack_detect(codec, pin)) { | ||
3593 | mux_select(codec, 0, spec->am_entry[i].idx); | ||
3594 | return; | ||
3595 | } | ||
3596 | } | ||
3597 | mux_select(codec, 0, spec->am_entry[0].idx); | ||
3598 | } | ||
3599 | EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch); | ||
3600 | |||
3601 | /* update jack retasking */ | ||
3602 | static void update_automute_all(struct hda_codec *codec) | ||
3603 | { | ||
3604 | struct hda_gen_spec *spec = codec->spec; | ||
3605 | |||
3606 | if (spec->hp_automute_hook) | ||
3607 | spec->hp_automute_hook(codec, NULL); | ||
3608 | else | ||
3609 | snd_hda_gen_hp_automute(codec, NULL); | ||
3610 | if (spec->line_automute_hook) | ||
3611 | spec->line_automute_hook(codec, NULL); | ||
3612 | else | ||
3613 | snd_hda_gen_line_automute(codec, NULL); | ||
3614 | if (spec->mic_autoswitch_hook) | ||
3615 | spec->mic_autoswitch_hook(codec, NULL); | ||
3616 | else | ||
3617 | snd_hda_gen_mic_autoswitch(codec, NULL); | ||
3618 | } | ||
3619 | |||
3620 | /* | ||
3621 | * Auto-Mute mode mixer enum support | ||
3622 | */ | ||
3623 | static int automute_mode_info(struct snd_kcontrol *kcontrol, | ||
3624 | struct snd_ctl_elem_info *uinfo) | ||
3625 | { | ||
3626 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3627 | struct hda_gen_spec *spec = codec->spec; | ||
3628 | static const char * const texts3[] = { | ||
3629 | "Disabled", "Speaker Only", "Line Out+Speaker" | ||
3630 | }; | ||
3631 | |||
3632 | if (spec->automute_speaker_possible && spec->automute_lo_possible) | ||
3633 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | ||
3634 | return snd_hda_enum_bool_helper_info(kcontrol, uinfo); | ||
3635 | } | ||
3636 | |||
3637 | static int automute_mode_get(struct snd_kcontrol *kcontrol, | ||
3638 | struct snd_ctl_elem_value *ucontrol) | ||
3639 | { | ||
3640 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3641 | struct hda_gen_spec *spec = codec->spec; | ||
3642 | unsigned int val = 0; | ||
3643 | if (spec->automute_speaker) | ||
3644 | val++; | ||
3645 | if (spec->automute_lo) | ||
3646 | val++; | ||
3647 | |||
3648 | ucontrol->value.enumerated.item[0] = val; | ||
3649 | return 0; | ||
3650 | } | ||
3651 | |||
3652 | static int automute_mode_put(struct snd_kcontrol *kcontrol, | ||
3653 | struct snd_ctl_elem_value *ucontrol) | ||
3654 | { | ||
3655 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3656 | struct hda_gen_spec *spec = codec->spec; | ||
3657 | |||
3658 | switch (ucontrol->value.enumerated.item[0]) { | ||
3659 | case 0: | ||
3660 | if (!spec->automute_speaker && !spec->automute_lo) | ||
3661 | return 0; | ||
3662 | spec->automute_speaker = 0; | ||
3663 | spec->automute_lo = 0; | ||
3664 | break; | ||
3665 | case 1: | ||
3666 | if (spec->automute_speaker_possible) { | ||
3667 | if (!spec->automute_lo && spec->automute_speaker) | ||
3668 | return 0; | ||
3669 | spec->automute_speaker = 1; | ||
3670 | spec->automute_lo = 0; | ||
3671 | } else if (spec->automute_lo_possible) { | ||
3672 | if (spec->automute_lo) | ||
3673 | return 0; | ||
3674 | spec->automute_lo = 1; | ||
3675 | } else | ||
3676 | return -EINVAL; | ||
3677 | break; | ||
3678 | case 2: | ||
3679 | if (!spec->automute_lo_possible || !spec->automute_speaker_possible) | ||
3680 | return -EINVAL; | ||
3681 | if (spec->automute_speaker && spec->automute_lo) | ||
3682 | return 0; | ||
3683 | spec->automute_speaker = 1; | ||
3684 | spec->automute_lo = 1; | ||
3685 | break; | ||
3686 | default: | ||
3687 | return -EINVAL; | ||
3688 | } | ||
3689 | call_update_outputs(codec); | ||
3690 | return 1; | ||
3691 | } | ||
3692 | |||
3693 | static const struct snd_kcontrol_new automute_mode_enum = { | ||
3694 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3695 | .name = "Auto-Mute Mode", | ||
3696 | .info = automute_mode_info, | ||
3697 | .get = automute_mode_get, | ||
3698 | .put = automute_mode_put, | ||
3699 | }; | ||
3700 | |||
3701 | static int add_automute_mode_enum(struct hda_codec *codec) | ||
3702 | { | ||
3703 | struct hda_gen_spec *spec = codec->spec; | ||
3704 | |||
3705 | if (!snd_hda_gen_add_kctl(spec, NULL, &automute_mode_enum)) | ||
3706 | return -ENOMEM; | ||
3707 | return 0; | ||
3708 | } | ||
3709 | |||
3710 | /* | ||
3711 | * Check the availability of HP/line-out auto-mute; | ||
3712 | * Set up appropriately if really supported | ||
871 | */ | 3713 | */ |
872 | static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec, | 3714 | static int check_auto_mute_availability(struct hda_codec *codec) |
873 | struct hda_gnode *node, struct hda_gnode *dest_node, | ||
874 | const char *type) | ||
875 | { | 3715 | { |
3716 | struct hda_gen_spec *spec = codec->spec; | ||
3717 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3718 | int present = 0; | ||
876 | int i, err; | 3719 | int i, err; |
877 | 3720 | ||
878 | if (node->checked) | 3721 | if (spec->suppress_auto_mute) |
879 | return 0; | 3722 | return 0; |
880 | 3723 | ||
881 | node->checked = 1; | 3724 | if (cfg->hp_pins[0]) |
882 | if (node == dest_node) { | 3725 | present++; |
883 | /* loopback connection found */ | 3726 | if (cfg->line_out_pins[0]) |
884 | return 1; | 3727 | present++; |
3728 | if (cfg->speaker_pins[0]) | ||
3729 | present++; | ||
3730 | if (present < 2) /* need two different output types */ | ||
3731 | return 0; | ||
3732 | |||
3733 | if (!cfg->speaker_pins[0] && | ||
3734 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
3735 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
3736 | sizeof(cfg->speaker_pins)); | ||
3737 | cfg->speaker_outs = cfg->line_outs; | ||
3738 | } | ||
3739 | |||
3740 | if (!cfg->hp_pins[0] && | ||
3741 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3742 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3743 | sizeof(cfg->hp_pins)); | ||
3744 | cfg->hp_outs = cfg->line_outs; | ||
885 | } | 3745 | } |
886 | 3746 | ||
887 | for (i = 0; i < node->nconns; i++) { | 3747 | for (i = 0; i < cfg->hp_outs; i++) { |
888 | struct hda_gnode *child = hda_get_node(spec, node->conn_list[i]); | 3748 | hda_nid_t nid = cfg->hp_pins[i]; |
889 | if (! child) | 3749 | if (!is_jack_detectable(codec, nid)) |
890 | continue; | 3750 | continue; |
891 | err = parse_loopback_path(codec, spec, child, dest_node, type); | 3751 | snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n", |
892 | if (err < 0) | 3752 | nid); |
893 | return err; | 3753 | snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT, |
894 | else if (err >= 1) { | 3754 | spec->hp_automute_hook ? |
895 | if (err == 1) { | 3755 | spec->hp_automute_hook : |
896 | err = create_mixer(codec, node, i, type, | 3756 | snd_hda_gen_hp_automute); |
897 | "Playback", 1); | 3757 | spec->detect_hp = 1; |
898 | if (err < 0) | 3758 | } |
899 | return err; | 3759 | |
900 | if (err > 0) | 3760 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) { |
901 | return 2; /* ok, created */ | 3761 | if (cfg->speaker_outs) |
902 | /* not created, maybe in the lower path */ | 3762 | for (i = 0; i < cfg->line_outs; i++) { |
903 | err = 1; | 3763 | hda_nid_t nid = cfg->line_out_pins[i]; |
3764 | if (!is_jack_detectable(codec, nid)) | ||
3765 | continue; | ||
3766 | snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid); | ||
3767 | snd_hda_jack_detect_enable_callback(codec, nid, | ||
3768 | HDA_GEN_FRONT_EVENT, | ||
3769 | spec->line_automute_hook ? | ||
3770 | spec->line_automute_hook : | ||
3771 | snd_hda_gen_line_automute); | ||
3772 | spec->detect_lo = 1; | ||
904 | } | 3773 | } |
905 | /* connect and unmute */ | 3774 | spec->automute_lo_possible = spec->detect_hp; |
906 | if (node->nconns > 1) | 3775 | } |
907 | select_input_connection(codec, node, i); | 3776 | |
908 | unmute_input(codec, node, i); | 3777 | spec->automute_speaker_possible = cfg->speaker_outs && |
909 | unmute_output(codec, node); | 3778 | (spec->detect_hp || spec->detect_lo); |
3779 | |||
3780 | spec->automute_lo = spec->automute_lo_possible; | ||
3781 | spec->automute_speaker = spec->automute_speaker_possible; | ||
3782 | |||
3783 | if (spec->automute_speaker_possible || spec->automute_lo_possible) { | ||
3784 | /* create a control for automute mode */ | ||
3785 | err = add_automute_mode_enum(codec); | ||
3786 | if (err < 0) | ||
910 | return err; | 3787 | return err; |
911 | } | ||
912 | } | 3788 | } |
913 | return 0; | 3789 | return 0; |
914 | } | 3790 | } |
915 | 3791 | ||
3792 | /* check whether all auto-mic pins are valid; setup indices if OK */ | ||
3793 | static bool auto_mic_check_imux(struct hda_codec *codec) | ||
3794 | { | ||
3795 | struct hda_gen_spec *spec = codec->spec; | ||
3796 | const struct hda_input_mux *imux; | ||
3797 | int i; | ||
3798 | |||
3799 | imux = &spec->input_mux; | ||
3800 | for (i = 0; i < spec->am_num_entries; i++) { | ||
3801 | spec->am_entry[i].idx = | ||
3802 | find_idx_in_nid_list(spec->am_entry[i].pin, | ||
3803 | spec->imux_pins, imux->num_items); | ||
3804 | if (spec->am_entry[i].idx < 0) | ||
3805 | return false; /* no corresponding imux */ | ||
3806 | } | ||
3807 | |||
3808 | /* we don't need the jack detection for the first pin */ | ||
3809 | for (i = 1; i < spec->am_num_entries; i++) | ||
3810 | snd_hda_jack_detect_enable_callback(codec, | ||
3811 | spec->am_entry[i].pin, | ||
3812 | HDA_GEN_MIC_EVENT, | ||
3813 | spec->mic_autoswitch_hook ? | ||
3814 | spec->mic_autoswitch_hook : | ||
3815 | snd_hda_gen_mic_autoswitch); | ||
3816 | return true; | ||
3817 | } | ||
3818 | |||
3819 | static int compare_attr(const void *ap, const void *bp) | ||
3820 | { | ||
3821 | const struct automic_entry *a = ap; | ||
3822 | const struct automic_entry *b = bp; | ||
3823 | return (int)(a->attr - b->attr); | ||
3824 | } | ||
3825 | |||
916 | /* | 3826 | /* |
917 | * parse the tree and build the loopback controls | 3827 | * Check the availability of auto-mic switch; |
3828 | * Set up if really supported | ||
918 | */ | 3829 | */ |
919 | static int build_loopback_controls(struct hda_codec *codec) | 3830 | static int check_auto_mic_availability(struct hda_codec *codec) |
920 | { | 3831 | { |
921 | struct hda_gspec *spec = codec->spec; | 3832 | struct hda_gen_spec *spec = codec->spec; |
922 | struct hda_gnode *node; | 3833 | struct auto_pin_cfg *cfg = &spec->autocfg; |
923 | int err; | 3834 | unsigned int types; |
924 | const char *type; | 3835 | int i, num_pins; |
925 | 3836 | ||
926 | if (! spec->out_pin_node[0]) | 3837 | if (spec->suppress_auto_mic) |
927 | return 0; | 3838 | return 0; |
928 | 3839 | ||
929 | list_for_each_entry(node, &spec->nid_list, list) { | 3840 | types = 0; |
930 | if (node->type != AC_WID_PIN) | 3841 | num_pins = 0; |
931 | continue; | 3842 | for (i = 0; i < cfg->num_inputs; i++) { |
932 | /* input capable? */ | 3843 | hda_nid_t nid = cfg->inputs[i].pin; |
933 | if (! (node->pin_caps & AC_PINCAP_IN)) | 3844 | unsigned int attr; |
3845 | attr = snd_hda_codec_get_pincfg(codec, nid); | ||
3846 | attr = snd_hda_get_input_pin_attr(attr); | ||
3847 | if (types & (1 << attr)) | ||
3848 | return 0; /* already occupied */ | ||
3849 | switch (attr) { | ||
3850 | case INPUT_PIN_ATTR_INT: | ||
3851 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
3852 | return 0; /* invalid type */ | ||
3853 | break; | ||
3854 | case INPUT_PIN_ATTR_UNUSED: | ||
3855 | return 0; /* invalid entry */ | ||
3856 | default: | ||
3857 | if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) | ||
3858 | return 0; /* invalid type */ | ||
3859 | if (!spec->line_in_auto_switch && | ||
3860 | cfg->inputs[i].type != AUTO_PIN_MIC) | ||
3861 | return 0; /* only mic is allowed */ | ||
3862 | if (!is_jack_detectable(codec, nid)) | ||
3863 | return 0; /* no unsol support */ | ||
3864 | break; | ||
3865 | } | ||
3866 | if (num_pins >= MAX_AUTO_MIC_PINS) | ||
934 | return 0; | 3867 | return 0; |
935 | type = get_input_type(node, NULL); | 3868 | types |= (1 << attr); |
936 | if (type) { | 3869 | spec->am_entry[num_pins].pin = nid; |
937 | if (check_existing_control(codec, type, "Playback")) | 3870 | spec->am_entry[num_pins].attr = attr; |
938 | continue; | 3871 | num_pins++; |
939 | clear_check_flags(spec); | 3872 | } |
940 | err = parse_loopback_path(codec, spec, | 3873 | |
941 | spec->out_pin_node[0], | 3874 | if (num_pins < 2) |
942 | node, type); | 3875 | return 0; |
3876 | |||
3877 | spec->am_num_entries = num_pins; | ||
3878 | /* sort the am_entry in the order of attr so that the pin with a | ||
3879 | * higher attr will be selected when the jack is plugged. | ||
3880 | */ | ||
3881 | sort(spec->am_entry, num_pins, sizeof(spec->am_entry[0]), | ||
3882 | compare_attr, NULL); | ||
3883 | |||
3884 | if (!auto_mic_check_imux(codec)) | ||
3885 | return 0; | ||
3886 | |||
3887 | spec->auto_mic = 1; | ||
3888 | spec->num_adc_nids = 1; | ||
3889 | spec->cur_mux[0] = spec->am_entry[0].idx; | ||
3890 | snd_printdd("hda-codec: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | ||
3891 | spec->am_entry[0].pin, | ||
3892 | spec->am_entry[1].pin, | ||
3893 | spec->am_entry[2].pin); | ||
3894 | |||
3895 | return 0; | ||
3896 | } | ||
3897 | |||
3898 | /* power_filter hook; make inactive widgets into power down */ | ||
3899 | static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | ||
3900 | hda_nid_t nid, | ||
3901 | unsigned int power_state) | ||
3902 | { | ||
3903 | if (power_state != AC_PWRST_D0) | ||
3904 | return power_state; | ||
3905 | if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER) | ||
3906 | return power_state; | ||
3907 | if (is_active_nid(codec, nid, HDA_OUTPUT, 0)) | ||
3908 | return power_state; | ||
3909 | return AC_PWRST_D3; | ||
3910 | } | ||
3911 | |||
3912 | |||
3913 | /* | ||
3914 | * Parse the given BIOS configuration and set up the hda_gen_spec | ||
3915 | * | ||
3916 | * return 1 if successful, 0 if the proper config is not found, | ||
3917 | * or a negative error code | ||
3918 | */ | ||
3919 | int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | ||
3920 | struct auto_pin_cfg *cfg) | ||
3921 | { | ||
3922 | struct hda_gen_spec *spec = codec->spec; | ||
3923 | int err; | ||
3924 | |||
3925 | parse_user_hints(codec); | ||
3926 | |||
3927 | if (spec->mixer_nid && !spec->mixer_merge_nid) | ||
3928 | spec->mixer_merge_nid = spec->mixer_nid; | ||
3929 | |||
3930 | if (cfg != &spec->autocfg) { | ||
3931 | spec->autocfg = *cfg; | ||
3932 | cfg = &spec->autocfg; | ||
3933 | } | ||
3934 | |||
3935 | fill_all_dac_nids(codec); | ||
3936 | |||
3937 | if (!cfg->line_outs) { | ||
3938 | if (cfg->dig_outs || cfg->dig_in_pin) { | ||
3939 | spec->multiout.max_channels = 2; | ||
3940 | spec->no_analog = 1; | ||
3941 | goto dig_only; | ||
3942 | } | ||
3943 | return 0; /* can't find valid BIOS pin config */ | ||
3944 | } | ||
3945 | |||
3946 | if (!spec->no_primary_hp && | ||
3947 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
3948 | cfg->line_outs <= cfg->hp_outs) { | ||
3949 | /* use HP as primary out */ | ||
3950 | cfg->speaker_outs = cfg->line_outs; | ||
3951 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
3952 | sizeof(cfg->speaker_pins)); | ||
3953 | cfg->line_outs = cfg->hp_outs; | ||
3954 | memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); | ||
3955 | cfg->hp_outs = 0; | ||
3956 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
3957 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
3958 | } | ||
3959 | |||
3960 | err = parse_output_paths(codec); | ||
3961 | if (err < 0) | ||
3962 | return err; | ||
3963 | err = create_multi_channel_mode(codec); | ||
3964 | if (err < 0) | ||
3965 | return err; | ||
3966 | err = create_multi_out_ctls(codec, cfg); | ||
3967 | if (err < 0) | ||
3968 | return err; | ||
3969 | err = create_hp_out_ctls(codec); | ||
3970 | if (err < 0) | ||
3971 | return err; | ||
3972 | err = create_speaker_out_ctls(codec); | ||
3973 | if (err < 0) | ||
3974 | return err; | ||
3975 | err = create_indep_hp_ctls(codec); | ||
3976 | if (err < 0) | ||
3977 | return err; | ||
3978 | err = create_loopback_mixing_ctl(codec); | ||
3979 | if (err < 0) | ||
3980 | return err; | ||
3981 | err = create_shared_input(codec); | ||
3982 | if (err < 0) | ||
3983 | return err; | ||
3984 | err = create_input_ctls(codec); | ||
3985 | if (err < 0) | ||
3986 | return err; | ||
3987 | |||
3988 | spec->const_channel_count = spec->ext_channel_count; | ||
3989 | /* check the multiple speaker and headphone pins */ | ||
3990 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
3991 | spec->const_channel_count = max(spec->const_channel_count, | ||
3992 | cfg->speaker_outs * 2); | ||
3993 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | ||
3994 | spec->const_channel_count = max(spec->const_channel_count, | ||
3995 | cfg->hp_outs * 2); | ||
3996 | spec->multiout.max_channels = max(spec->ext_channel_count, | ||
3997 | spec->const_channel_count); | ||
3998 | |||
3999 | err = check_auto_mute_availability(codec); | ||
4000 | if (err < 0) | ||
4001 | return err; | ||
4002 | |||
4003 | err = check_dyn_adc_switch(codec); | ||
4004 | if (err < 0) | ||
4005 | return err; | ||
4006 | |||
4007 | if (!spec->shared_mic_hp) { | ||
4008 | err = check_auto_mic_availability(codec); | ||
4009 | if (err < 0) | ||
4010 | return err; | ||
4011 | } | ||
4012 | |||
4013 | err = create_capture_mixers(codec); | ||
4014 | if (err < 0) | ||
4015 | return err; | ||
4016 | |||
4017 | err = parse_mic_boost(codec); | ||
4018 | if (err < 0) | ||
4019 | return err; | ||
4020 | |||
4021 | if (spec->add_out_jack_modes) { | ||
4022 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
4023 | err = create_out_jack_modes(codec, cfg->line_outs, | ||
4024 | cfg->line_out_pins); | ||
4025 | if (err < 0) | ||
4026 | return err; | ||
4027 | } | ||
4028 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { | ||
4029 | err = create_out_jack_modes(codec, cfg->hp_outs, | ||
4030 | cfg->hp_pins); | ||
943 | if (err < 0) | 4031 | if (err < 0) |
944 | return err; | 4032 | return err; |
945 | if (! err) | ||
946 | continue; | ||
947 | } | 4033 | } |
948 | } | 4034 | } |
949 | return 0; | 4035 | |
4036 | dig_only: | ||
4037 | parse_digital(codec); | ||
4038 | |||
4039 | if (spec->power_down_unused) | ||
4040 | codec->power_filter = snd_hda_gen_path_power_filter; | ||
4041 | |||
4042 | return 1; | ||
950 | } | 4043 | } |
4044 | EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config); | ||
4045 | |||
951 | 4046 | ||
952 | /* | 4047 | /* |
953 | * build mixer controls | 4048 | * Build control elements |
954 | */ | 4049 | */ |
955 | static int build_generic_controls(struct hda_codec *codec) | 4050 | |
4051 | /* slave controls for virtual master */ | ||
4052 | static const char * const slave_pfxs[] = { | ||
4053 | "Front", "Surround", "Center", "LFE", "Side", | ||
4054 | "Headphone", "Speaker", "Mono", "Line Out", | ||
4055 | "CLFE", "Bass Speaker", "PCM", | ||
4056 | "Speaker Front", "Speaker Surround", "Speaker CLFE", "Speaker Side", | ||
4057 | "Headphone Front", "Headphone Surround", "Headphone CLFE", | ||
4058 | "Headphone Side", | ||
4059 | NULL, | ||
4060 | }; | ||
4061 | |||
4062 | int snd_hda_gen_build_controls(struct hda_codec *codec) | ||
956 | { | 4063 | { |
4064 | struct hda_gen_spec *spec = codec->spec; | ||
957 | int err; | 4065 | int err; |
958 | 4066 | ||
959 | if ((err = build_input_controls(codec)) < 0 || | 4067 | if (spec->kctls.used) { |
960 | (err = build_output_controls(codec)) < 0 || | 4068 | err = snd_hda_add_new_ctls(codec, spec->kctls.list); |
961 | (err = build_loopback_controls(codec)) < 0) | 4069 | if (err < 0) |
4070 | return err; | ||
4071 | } | ||
4072 | |||
4073 | if (spec->multiout.dig_out_nid) { | ||
4074 | err = snd_hda_create_dig_out_ctls(codec, | ||
4075 | spec->multiout.dig_out_nid, | ||
4076 | spec->multiout.dig_out_nid, | ||
4077 | spec->pcm_rec[1].pcm_type); | ||
4078 | if (err < 0) | ||
4079 | return err; | ||
4080 | if (!spec->no_analog) { | ||
4081 | err = snd_hda_create_spdif_share_sw(codec, | ||
4082 | &spec->multiout); | ||
4083 | if (err < 0) | ||
4084 | return err; | ||
4085 | spec->multiout.share_spdif = 1; | ||
4086 | } | ||
4087 | } | ||
4088 | if (spec->dig_in_nid) { | ||
4089 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
4090 | if (err < 0) | ||
4091 | return err; | ||
4092 | } | ||
4093 | |||
4094 | /* if we have no master control, let's create it */ | ||
4095 | if (!spec->no_analog && | ||
4096 | !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | ||
4097 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | ||
4098 | spec->vmaster_tlv, slave_pfxs, | ||
4099 | "Playback Volume"); | ||
4100 | if (err < 0) | ||
4101 | return err; | ||
4102 | } | ||
4103 | if (!spec->no_analog && | ||
4104 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | ||
4105 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", | ||
4106 | NULL, slave_pfxs, | ||
4107 | "Playback Switch", | ||
4108 | true, &spec->vmaster_mute.sw_kctl); | ||
4109 | if (err < 0) | ||
4110 | return err; | ||
4111 | if (spec->vmaster_mute.hook) | ||
4112 | snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, | ||
4113 | spec->vmaster_mute_enum); | ||
4114 | } | ||
4115 | |||
4116 | free_kctls(spec); /* no longer needed */ | ||
4117 | |||
4118 | if (spec->shared_mic_hp) { | ||
4119 | int err; | ||
4120 | int nid = spec->autocfg.inputs[1].pin; | ||
4121 | err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); | ||
4122 | if (err < 0) | ||
4123 | return err; | ||
4124 | err = snd_hda_jack_detect_enable(codec, nid, 0); | ||
4125 | if (err < 0) | ||
4126 | return err; | ||
4127 | } | ||
4128 | |||
4129 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
4130 | if (err < 0) | ||
962 | return err; | 4131 | return err; |
963 | 4132 | ||
964 | return 0; | 4133 | return 0; |
965 | } | 4134 | } |
4135 | EXPORT_SYMBOL_HDA(snd_hda_gen_build_controls); | ||
4136 | |||
966 | 4137 | ||
967 | /* | 4138 | /* |
968 | * PCM | 4139 | * PCM definitions |
969 | */ | 4140 | */ |
970 | static struct hda_pcm_stream generic_pcm_playback = { | ||
971 | .substreams = 1, | ||
972 | .channels_min = 2, | ||
973 | .channels_max = 2, | ||
974 | }; | ||
975 | 4141 | ||
976 | static int generic_pcm2_prepare(struct hda_pcm_stream *hinfo, | 4142 | static void call_pcm_playback_hook(struct hda_pcm_stream *hinfo, |
4143 | struct hda_codec *codec, | ||
4144 | struct snd_pcm_substream *substream, | ||
4145 | int action) | ||
4146 | { | ||
4147 | struct hda_gen_spec *spec = codec->spec; | ||
4148 | if (spec->pcm_playback_hook) | ||
4149 | spec->pcm_playback_hook(hinfo, codec, substream, action); | ||
4150 | } | ||
4151 | |||
4152 | static void call_pcm_capture_hook(struct hda_pcm_stream *hinfo, | ||
4153 | struct hda_codec *codec, | ||
4154 | struct snd_pcm_substream *substream, | ||
4155 | int action) | ||
4156 | { | ||
4157 | struct hda_gen_spec *spec = codec->spec; | ||
4158 | if (spec->pcm_capture_hook) | ||
4159 | spec->pcm_capture_hook(hinfo, codec, substream, action); | ||
4160 | } | ||
4161 | |||
4162 | /* | ||
4163 | * Analog playback callbacks | ||
4164 | */ | ||
4165 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
4166 | struct hda_codec *codec, | ||
4167 | struct snd_pcm_substream *substream) | ||
4168 | { | ||
4169 | struct hda_gen_spec *spec = codec->spec; | ||
4170 | int err; | ||
4171 | |||
4172 | mutex_lock(&spec->pcm_mutex); | ||
4173 | err = snd_hda_multi_out_analog_open(codec, | ||
4174 | &spec->multiout, substream, | ||
4175 | hinfo); | ||
4176 | if (!err) { | ||
4177 | spec->active_streams |= 1 << STREAM_MULTI_OUT; | ||
4178 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4179 | HDA_GEN_PCM_ACT_OPEN); | ||
4180 | } | ||
4181 | mutex_unlock(&spec->pcm_mutex); | ||
4182 | return err; | ||
4183 | } | ||
4184 | |||
4185 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
977 | struct hda_codec *codec, | 4186 | struct hda_codec *codec, |
978 | unsigned int stream_tag, | 4187 | unsigned int stream_tag, |
979 | unsigned int format, | 4188 | unsigned int format, |
980 | struct snd_pcm_substream *substream) | 4189 | struct snd_pcm_substream *substream) |
981 | { | 4190 | { |
982 | struct hda_gspec *spec = codec->spec; | 4191 | struct hda_gen_spec *spec = codec->spec; |
4192 | int err; | ||
983 | 4193 | ||
984 | snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); | 4194 | err = snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
985 | snd_hda_codec_setup_stream(codec, spec->dac_node[1]->nid, | 4195 | stream_tag, format, substream); |
986 | stream_tag, 0, format); | 4196 | if (!err) |
987 | return 0; | 4197 | call_pcm_playback_hook(hinfo, codec, substream, |
4198 | HDA_GEN_PCM_ACT_PREPARE); | ||
4199 | return err; | ||
988 | } | 4200 | } |
989 | 4201 | ||
990 | static int generic_pcm2_cleanup(struct hda_pcm_stream *hinfo, | 4202 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
991 | struct hda_codec *codec, | 4203 | struct hda_codec *codec, |
992 | struct snd_pcm_substream *substream) | 4204 | struct snd_pcm_substream *substream) |
993 | { | 4205 | { |
994 | struct hda_gspec *spec = codec->spec; | 4206 | struct hda_gen_spec *spec = codec->spec; |
4207 | int err; | ||
4208 | |||
4209 | err = snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
4210 | if (!err) | ||
4211 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4212 | HDA_GEN_PCM_ACT_CLEANUP); | ||
4213 | return err; | ||
4214 | } | ||
4215 | |||
4216 | static int playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
4217 | struct hda_codec *codec, | ||
4218 | struct snd_pcm_substream *substream) | ||
4219 | { | ||
4220 | struct hda_gen_spec *spec = codec->spec; | ||
4221 | mutex_lock(&spec->pcm_mutex); | ||
4222 | spec->active_streams &= ~(1 << STREAM_MULTI_OUT); | ||
4223 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4224 | HDA_GEN_PCM_ACT_CLOSE); | ||
4225 | mutex_unlock(&spec->pcm_mutex); | ||
4226 | return 0; | ||
4227 | } | ||
4228 | |||
4229 | static int capture_pcm_open(struct hda_pcm_stream *hinfo, | ||
4230 | struct hda_codec *codec, | ||
4231 | struct snd_pcm_substream *substream) | ||
4232 | { | ||
4233 | call_pcm_capture_hook(hinfo, codec, substream, HDA_GEN_PCM_ACT_OPEN); | ||
4234 | return 0; | ||
4235 | } | ||
4236 | |||
4237 | static int capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
4238 | struct hda_codec *codec, | ||
4239 | unsigned int stream_tag, | ||
4240 | unsigned int format, | ||
4241 | struct snd_pcm_substream *substream) | ||
4242 | { | ||
4243 | snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); | ||
4244 | call_pcm_capture_hook(hinfo, codec, substream, | ||
4245 | HDA_GEN_PCM_ACT_PREPARE); | ||
4246 | return 0; | ||
4247 | } | ||
995 | 4248 | ||
4249 | static int capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
4250 | struct hda_codec *codec, | ||
4251 | struct snd_pcm_substream *substream) | ||
4252 | { | ||
996 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | 4253 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); |
997 | snd_hda_codec_cleanup_stream(codec, spec->dac_node[1]->nid); | 4254 | call_pcm_capture_hook(hinfo, codec, substream, |
4255 | HDA_GEN_PCM_ACT_CLEANUP); | ||
4256 | return 0; | ||
4257 | } | ||
4258 | |||
4259 | static int capture_pcm_close(struct hda_pcm_stream *hinfo, | ||
4260 | struct hda_codec *codec, | ||
4261 | struct snd_pcm_substream *substream) | ||
4262 | { | ||
4263 | call_pcm_capture_hook(hinfo, codec, substream, HDA_GEN_PCM_ACT_CLOSE); | ||
998 | return 0; | 4264 | return 0; |
999 | } | 4265 | } |
1000 | 4266 | ||
1001 | static int build_generic_pcms(struct hda_codec *codec) | 4267 | static int alt_playback_pcm_open(struct hda_pcm_stream *hinfo, |
4268 | struct hda_codec *codec, | ||
4269 | struct snd_pcm_substream *substream) | ||
1002 | { | 4270 | { |
1003 | struct hda_gspec *spec = codec->spec; | 4271 | struct hda_gen_spec *spec = codec->spec; |
1004 | struct hda_pcm *info = &spec->pcm_rec; | 4272 | int err = 0; |
1005 | 4273 | ||
1006 | if (! spec->dac_node[0] && ! spec->adc_node) { | 4274 | mutex_lock(&spec->pcm_mutex); |
1007 | snd_printd("hda_generic: no PCM found\n"); | 4275 | if (!spec->indep_hp_enabled) |
1008 | return 0; | 4276 | err = -EBUSY; |
4277 | else | ||
4278 | spec->active_streams |= 1 << STREAM_INDEP_HP; | ||
4279 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4280 | HDA_GEN_PCM_ACT_OPEN); | ||
4281 | mutex_unlock(&spec->pcm_mutex); | ||
4282 | return err; | ||
4283 | } | ||
4284 | |||
4285 | static int alt_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
4286 | struct hda_codec *codec, | ||
4287 | struct snd_pcm_substream *substream) | ||
4288 | { | ||
4289 | struct hda_gen_spec *spec = codec->spec; | ||
4290 | mutex_lock(&spec->pcm_mutex); | ||
4291 | spec->active_streams &= ~(1 << STREAM_INDEP_HP); | ||
4292 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4293 | HDA_GEN_PCM_ACT_CLOSE); | ||
4294 | mutex_unlock(&spec->pcm_mutex); | ||
4295 | return 0; | ||
4296 | } | ||
4297 | |||
4298 | static int alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
4299 | struct hda_codec *codec, | ||
4300 | unsigned int stream_tag, | ||
4301 | unsigned int format, | ||
4302 | struct snd_pcm_substream *substream) | ||
4303 | { | ||
4304 | snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); | ||
4305 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4306 | HDA_GEN_PCM_ACT_PREPARE); | ||
4307 | return 0; | ||
4308 | } | ||
4309 | |||
4310 | static int alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
4311 | struct hda_codec *codec, | ||
4312 | struct snd_pcm_substream *substream) | ||
4313 | { | ||
4314 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | ||
4315 | call_pcm_playback_hook(hinfo, codec, substream, | ||
4316 | HDA_GEN_PCM_ACT_CLEANUP); | ||
4317 | return 0; | ||
4318 | } | ||
4319 | |||
4320 | /* | ||
4321 | * Digital out | ||
4322 | */ | ||
4323 | static int dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
4324 | struct hda_codec *codec, | ||
4325 | struct snd_pcm_substream *substream) | ||
4326 | { | ||
4327 | struct hda_gen_spec *spec = codec->spec; | ||
4328 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
4329 | } | ||
4330 | |||
4331 | static int dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
4332 | struct hda_codec *codec, | ||
4333 | unsigned int stream_tag, | ||
4334 | unsigned int format, | ||
4335 | struct snd_pcm_substream *substream) | ||
4336 | { | ||
4337 | struct hda_gen_spec *spec = codec->spec; | ||
4338 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
4339 | stream_tag, format, substream); | ||
4340 | } | ||
4341 | |||
4342 | static int dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
4343 | struct hda_codec *codec, | ||
4344 | struct snd_pcm_substream *substream) | ||
4345 | { | ||
4346 | struct hda_gen_spec *spec = codec->spec; | ||
4347 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
4348 | } | ||
4349 | |||
4350 | static int dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
4351 | struct hda_codec *codec, | ||
4352 | struct snd_pcm_substream *substream) | ||
4353 | { | ||
4354 | struct hda_gen_spec *spec = codec->spec; | ||
4355 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
4356 | } | ||
4357 | |||
4358 | /* | ||
4359 | * Analog capture | ||
4360 | */ | ||
4361 | #define alt_capture_pcm_open capture_pcm_open | ||
4362 | #define alt_capture_pcm_close capture_pcm_close | ||
4363 | |||
4364 | static int alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
4365 | struct hda_codec *codec, | ||
4366 | unsigned int stream_tag, | ||
4367 | unsigned int format, | ||
4368 | struct snd_pcm_substream *substream) | ||
4369 | { | ||
4370 | struct hda_gen_spec *spec = codec->spec; | ||
4371 | |||
4372 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], | ||
4373 | stream_tag, 0, format); | ||
4374 | call_pcm_capture_hook(hinfo, codec, substream, | ||
4375 | HDA_GEN_PCM_ACT_PREPARE); | ||
4376 | return 0; | ||
4377 | } | ||
4378 | |||
4379 | static int alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
4380 | struct hda_codec *codec, | ||
4381 | struct snd_pcm_substream *substream) | ||
4382 | { | ||
4383 | struct hda_gen_spec *spec = codec->spec; | ||
4384 | |||
4385 | snd_hda_codec_cleanup_stream(codec, | ||
4386 | spec->adc_nids[substream->number + 1]); | ||
4387 | call_pcm_capture_hook(hinfo, codec, substream, | ||
4388 | HDA_GEN_PCM_ACT_CLEANUP); | ||
4389 | return 0; | ||
4390 | } | ||
4391 | |||
4392 | /* | ||
4393 | */ | ||
4394 | static const struct hda_pcm_stream pcm_analog_playback = { | ||
4395 | .substreams = 1, | ||
4396 | .channels_min = 2, | ||
4397 | .channels_max = 8, | ||
4398 | /* NID is set in build_pcms */ | ||
4399 | .ops = { | ||
4400 | .open = playback_pcm_open, | ||
4401 | .close = playback_pcm_close, | ||
4402 | .prepare = playback_pcm_prepare, | ||
4403 | .cleanup = playback_pcm_cleanup | ||
4404 | }, | ||
4405 | }; | ||
4406 | |||
4407 | static const struct hda_pcm_stream pcm_analog_capture = { | ||
4408 | .substreams = 1, | ||
4409 | .channels_min = 2, | ||
4410 | .channels_max = 2, | ||
4411 | /* NID is set in build_pcms */ | ||
4412 | .ops = { | ||
4413 | .open = capture_pcm_open, | ||
4414 | .close = capture_pcm_close, | ||
4415 | .prepare = capture_pcm_prepare, | ||
4416 | .cleanup = capture_pcm_cleanup | ||
4417 | }, | ||
4418 | }; | ||
4419 | |||
4420 | static const struct hda_pcm_stream pcm_analog_alt_playback = { | ||
4421 | .substreams = 1, | ||
4422 | .channels_min = 2, | ||
4423 | .channels_max = 2, | ||
4424 | /* NID is set in build_pcms */ | ||
4425 | .ops = { | ||
4426 | .open = alt_playback_pcm_open, | ||
4427 | .close = alt_playback_pcm_close, | ||
4428 | .prepare = alt_playback_pcm_prepare, | ||
4429 | .cleanup = alt_playback_pcm_cleanup | ||
4430 | }, | ||
4431 | }; | ||
4432 | |||
4433 | static const struct hda_pcm_stream pcm_analog_alt_capture = { | ||
4434 | .substreams = 2, /* can be overridden */ | ||
4435 | .channels_min = 2, | ||
4436 | .channels_max = 2, | ||
4437 | /* NID is set in build_pcms */ | ||
4438 | .ops = { | ||
4439 | .open = alt_capture_pcm_open, | ||
4440 | .close = alt_capture_pcm_close, | ||
4441 | .prepare = alt_capture_pcm_prepare, | ||
4442 | .cleanup = alt_capture_pcm_cleanup | ||
4443 | }, | ||
4444 | }; | ||
4445 | |||
4446 | static const struct hda_pcm_stream pcm_digital_playback = { | ||
4447 | .substreams = 1, | ||
4448 | .channels_min = 2, | ||
4449 | .channels_max = 2, | ||
4450 | /* NID is set in build_pcms */ | ||
4451 | .ops = { | ||
4452 | .open = dig_playback_pcm_open, | ||
4453 | .close = dig_playback_pcm_close, | ||
4454 | .prepare = dig_playback_pcm_prepare, | ||
4455 | .cleanup = dig_playback_pcm_cleanup | ||
4456 | }, | ||
4457 | }; | ||
4458 | |||
4459 | static const struct hda_pcm_stream pcm_digital_capture = { | ||
4460 | .substreams = 1, | ||
4461 | .channels_min = 2, | ||
4462 | .channels_max = 2, | ||
4463 | /* NID is set in build_pcms */ | ||
4464 | }; | ||
4465 | |||
4466 | /* Used by build_pcms to flag that a PCM has no playback stream */ | ||
4467 | static const struct hda_pcm_stream pcm_null_stream = { | ||
4468 | .substreams = 0, | ||
4469 | .channels_min = 0, | ||
4470 | .channels_max = 0, | ||
4471 | }; | ||
4472 | |||
4473 | /* | ||
4474 | * dynamic changing ADC PCM streams | ||
4475 | */ | ||
4476 | static bool dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | ||
4477 | { | ||
4478 | struct hda_gen_spec *spec = codec->spec; | ||
4479 | hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]]; | ||
4480 | |||
4481 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
4482 | /* stream is running, let's swap the current ADC */ | ||
4483 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
4484 | spec->cur_adc = new_adc; | ||
4485 | snd_hda_codec_setup_stream(codec, new_adc, | ||
4486 | spec->cur_adc_stream_tag, 0, | ||
4487 | spec->cur_adc_format); | ||
4488 | return true; | ||
1009 | } | 4489 | } |
4490 | return false; | ||
4491 | } | ||
4492 | |||
4493 | /* analog capture with dynamic dual-adc changes */ | ||
4494 | static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
4495 | struct hda_codec *codec, | ||
4496 | unsigned int stream_tag, | ||
4497 | unsigned int format, | ||
4498 | struct snd_pcm_substream *substream) | ||
4499 | { | ||
4500 | struct hda_gen_spec *spec = codec->spec; | ||
4501 | spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]]; | ||
4502 | spec->cur_adc_stream_tag = stream_tag; | ||
4503 | spec->cur_adc_format = format; | ||
4504 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
4505 | return 0; | ||
4506 | } | ||
4507 | |||
4508 | static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
4509 | struct hda_codec *codec, | ||
4510 | struct snd_pcm_substream *substream) | ||
4511 | { | ||
4512 | struct hda_gen_spec *spec = codec->spec; | ||
4513 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
4514 | spec->cur_adc = 0; | ||
4515 | return 0; | ||
4516 | } | ||
4517 | |||
4518 | static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = { | ||
4519 | .substreams = 1, | ||
4520 | .channels_min = 2, | ||
4521 | .channels_max = 2, | ||
4522 | .nid = 0, /* fill later */ | ||
4523 | .ops = { | ||
4524 | .prepare = dyn_adc_capture_pcm_prepare, | ||
4525 | .cleanup = dyn_adc_capture_pcm_cleanup | ||
4526 | }, | ||
4527 | }; | ||
4528 | |||
4529 | static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, | ||
4530 | const char *chip_name) | ||
4531 | { | ||
4532 | char *p; | ||
4533 | |||
4534 | if (*str) | ||
4535 | return; | ||
4536 | strlcpy(str, chip_name, len); | ||
4537 | |||
4538 | /* drop non-alnum chars after a space */ | ||
4539 | for (p = strchr(str, ' '); p; p = strchr(p + 1, ' ')) { | ||
4540 | if (!isalnum(p[1])) { | ||
4541 | *p = 0; | ||
4542 | break; | ||
4543 | } | ||
4544 | } | ||
4545 | strlcat(str, sfx, len); | ||
4546 | } | ||
4547 | |||
4548 | /* build PCM streams based on the parsed results */ | ||
4549 | int snd_hda_gen_build_pcms(struct hda_codec *codec) | ||
4550 | { | ||
4551 | struct hda_gen_spec *spec = codec->spec; | ||
4552 | struct hda_pcm *info = spec->pcm_rec; | ||
4553 | const struct hda_pcm_stream *p; | ||
4554 | bool have_multi_adcs; | ||
1010 | 4555 | ||
1011 | codec->num_pcms = 1; | 4556 | codec->num_pcms = 1; |
1012 | codec->pcm_info = info; | 4557 | codec->pcm_info = info; |
1013 | 4558 | ||
1014 | info->name = "HDA Generic"; | 4559 | if (spec->no_analog) |
1015 | if (spec->dac_node[0]) { | 4560 | goto skip_analog; |
1016 | info->stream[0] = generic_pcm_playback; | 4561 | |
1017 | info->stream[0].nid = spec->dac_node[0]->nid; | 4562 | fill_pcm_stream_name(spec->stream_name_analog, |
1018 | if (spec->dac_node[1]) { | 4563 | sizeof(spec->stream_name_analog), |
1019 | info->stream[0].ops.prepare = generic_pcm2_prepare; | 4564 | " Analog", codec->chip_name); |
1020 | info->stream[0].ops.cleanup = generic_pcm2_cleanup; | 4565 | info->name = spec->stream_name_analog; |
4566 | |||
4567 | if (spec->multiout.num_dacs > 0) { | ||
4568 | p = spec->stream_analog_playback; | ||
4569 | if (!p) | ||
4570 | p = &pcm_analog_playback; | ||
4571 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
4572 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; | ||
4573 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
4574 | spec->multiout.max_channels; | ||
4575 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
4576 | spec->autocfg.line_outs == 2) | ||
4577 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
4578 | snd_pcm_2_1_chmaps; | ||
4579 | } | ||
4580 | if (spec->num_adc_nids) { | ||
4581 | p = spec->stream_analog_capture; | ||
4582 | if (!p) { | ||
4583 | if (spec->dyn_adc_switch) | ||
4584 | p = &dyn_adc_pcm_analog_capture; | ||
4585 | else | ||
4586 | p = &pcm_analog_capture; | ||
4587 | } | ||
4588 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
4589 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
4590 | } | ||
4591 | |||
4592 | skip_analog: | ||
4593 | /* SPDIF for stream index #1 */ | ||
4594 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | ||
4595 | fill_pcm_stream_name(spec->stream_name_digital, | ||
4596 | sizeof(spec->stream_name_digital), | ||
4597 | " Digital", codec->chip_name); | ||
4598 | codec->num_pcms = 2; | ||
4599 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | ||
4600 | info = spec->pcm_rec + 1; | ||
4601 | info->name = spec->stream_name_digital; | ||
4602 | if (spec->dig_out_type) | ||
4603 | info->pcm_type = spec->dig_out_type; | ||
4604 | else | ||
4605 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
4606 | if (spec->multiout.dig_out_nid) { | ||
4607 | p = spec->stream_digital_playback; | ||
4608 | if (!p) | ||
4609 | p = &pcm_digital_playback; | ||
4610 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
4611 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | ||
4612 | } | ||
4613 | if (spec->dig_in_nid) { | ||
4614 | p = spec->stream_digital_capture; | ||
4615 | if (!p) | ||
4616 | p = &pcm_digital_capture; | ||
4617 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
4618 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
4619 | } | ||
4620 | } | ||
4621 | |||
4622 | if (spec->no_analog) | ||
4623 | return 0; | ||
4624 | |||
4625 | /* If the use of more than one ADC is requested for the current | ||
4626 | * model, configure a second analog capture-only PCM. | ||
4627 | */ | ||
4628 | have_multi_adcs = (spec->num_adc_nids > 1) && | ||
4629 | !spec->dyn_adc_switch && !spec->auto_mic; | ||
4630 | /* Additional Analaog capture for index #2 */ | ||
4631 | if (spec->alt_dac_nid || have_multi_adcs) { | ||
4632 | fill_pcm_stream_name(spec->stream_name_alt_analog, | ||
4633 | sizeof(spec->stream_name_alt_analog), | ||
4634 | " Alt Analog", codec->chip_name); | ||
4635 | codec->num_pcms = 3; | ||
4636 | info = spec->pcm_rec + 2; | ||
4637 | info->name = spec->stream_name_alt_analog; | ||
4638 | if (spec->alt_dac_nid) { | ||
4639 | p = spec->stream_analog_alt_playback; | ||
4640 | if (!p) | ||
4641 | p = &pcm_analog_alt_playback; | ||
4642 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
4643 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
4644 | spec->alt_dac_nid; | ||
4645 | } else { | ||
4646 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
4647 | pcm_null_stream; | ||
4648 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; | ||
4649 | } | ||
4650 | if (have_multi_adcs) { | ||
4651 | p = spec->stream_analog_alt_capture; | ||
4652 | if (!p) | ||
4653 | p = &pcm_analog_alt_capture; | ||
4654 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
4655 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
4656 | spec->adc_nids[1]; | ||
4657 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
4658 | spec->num_adc_nids - 1; | ||
4659 | } else { | ||
4660 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
4661 | pcm_null_stream; | ||
4662 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; | ||
4663 | } | ||
4664 | } | ||
4665 | |||
4666 | return 0; | ||
4667 | } | ||
4668 | EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms); | ||
4669 | |||
4670 | |||
4671 | /* | ||
4672 | * Standard auto-parser initializations | ||
4673 | */ | ||
4674 | |||
4675 | /* configure the given path as a proper output */ | ||
4676 | static void set_output_and_unmute(struct hda_codec *codec, int path_idx) | ||
4677 | { | ||
4678 | struct nid_path *path; | ||
4679 | hda_nid_t pin; | ||
4680 | |||
4681 | path = snd_hda_get_path_from_idx(codec, path_idx); | ||
4682 | if (!path || !path->depth) | ||
4683 | return; | ||
4684 | pin = path->path[path->depth - 1]; | ||
4685 | restore_pin_ctl(codec, pin); | ||
4686 | snd_hda_activate_path(codec, path, path->active, true); | ||
4687 | set_pin_eapd(codec, pin, path->active); | ||
4688 | } | ||
4689 | |||
4690 | /* initialize primary output paths */ | ||
4691 | static void init_multi_out(struct hda_codec *codec) | ||
4692 | { | ||
4693 | struct hda_gen_spec *spec = codec->spec; | ||
4694 | int i; | ||
4695 | |||
4696 | for (i = 0; i < spec->autocfg.line_outs; i++) | ||
4697 | set_output_and_unmute(codec, spec->out_paths[i]); | ||
4698 | } | ||
4699 | |||
4700 | |||
4701 | static void __init_extra_out(struct hda_codec *codec, int num_outs, int *paths) | ||
4702 | { | ||
4703 | int i; | ||
4704 | |||
4705 | for (i = 0; i < num_outs; i++) | ||
4706 | set_output_and_unmute(codec, paths[i]); | ||
4707 | } | ||
4708 | |||
4709 | /* initialize hp and speaker paths */ | ||
4710 | static void init_extra_out(struct hda_codec *codec) | ||
4711 | { | ||
4712 | struct hda_gen_spec *spec = codec->spec; | ||
4713 | |||
4714 | if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) | ||
4715 | __init_extra_out(codec, spec->autocfg.hp_outs, spec->hp_paths); | ||
4716 | if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
4717 | __init_extra_out(codec, spec->autocfg.speaker_outs, | ||
4718 | spec->speaker_paths); | ||
4719 | } | ||
4720 | |||
4721 | /* initialize multi-io paths */ | ||
4722 | static void init_multi_io(struct hda_codec *codec) | ||
4723 | { | ||
4724 | struct hda_gen_spec *spec = codec->spec; | ||
4725 | int i; | ||
4726 | |||
4727 | for (i = 0; i < spec->multi_ios; i++) { | ||
4728 | hda_nid_t pin = spec->multi_io[i].pin; | ||
4729 | struct nid_path *path; | ||
4730 | path = get_multiio_path(codec, i); | ||
4731 | if (!path) | ||
4732 | continue; | ||
4733 | if (!spec->multi_io[i].ctl_in) | ||
4734 | spec->multi_io[i].ctl_in = | ||
4735 | snd_hda_codec_get_pin_target(codec, pin); | ||
4736 | snd_hda_activate_path(codec, path, path->active, true); | ||
4737 | } | ||
4738 | } | ||
4739 | |||
4740 | /* set up input pins and loopback paths */ | ||
4741 | static void init_analog_input(struct hda_codec *codec) | ||
4742 | { | ||
4743 | struct hda_gen_spec *spec = codec->spec; | ||
4744 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4745 | int i; | ||
4746 | |||
4747 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4748 | hda_nid_t nid = cfg->inputs[i].pin; | ||
4749 | if (is_input_pin(codec, nid)) | ||
4750 | restore_pin_ctl(codec, nid); | ||
4751 | |||
4752 | /* init loopback inputs */ | ||
4753 | if (spec->mixer_nid) { | ||
4754 | resume_path_from_idx(codec, spec->loopback_paths[i]); | ||
4755 | resume_path_from_idx(codec, spec->loopback_merge_path); | ||
4756 | } | ||
4757 | } | ||
4758 | } | ||
4759 | |||
4760 | /* initialize ADC paths */ | ||
4761 | static void init_input_src(struct hda_codec *codec) | ||
4762 | { | ||
4763 | struct hda_gen_spec *spec = codec->spec; | ||
4764 | struct hda_input_mux *imux = &spec->input_mux; | ||
4765 | struct nid_path *path; | ||
4766 | int i, c, nums; | ||
4767 | |||
4768 | if (spec->dyn_adc_switch) | ||
4769 | nums = 1; | ||
4770 | else | ||
4771 | nums = spec->num_adc_nids; | ||
4772 | |||
4773 | for (c = 0; c < nums; c++) { | ||
4774 | for (i = 0; i < imux->num_items; i++) { | ||
4775 | path = get_input_path(codec, c, i); | ||
4776 | if (path) { | ||
4777 | bool active = path->active; | ||
4778 | if (i == spec->cur_mux[c]) | ||
4779 | active = true; | ||
4780 | snd_hda_activate_path(codec, path, active, false); | ||
4781 | } | ||
1021 | } | 4782 | } |
1022 | } | 4783 | } |
1023 | if (spec->adc_node) { | 4784 | |
1024 | info->stream[1] = generic_pcm_playback; | 4785 | if (spec->shared_mic_hp) |
1025 | info->stream[1].nid = spec->adc_node->nid; | 4786 | update_shared_mic_hp(codec, spec->cur_mux[0]); |
4787 | |||
4788 | if (spec->cap_sync_hook) | ||
4789 | spec->cap_sync_hook(codec, NULL); | ||
4790 | } | ||
4791 | |||
4792 | /* set right pin controls for digital I/O */ | ||
4793 | static void init_digital(struct hda_codec *codec) | ||
4794 | { | ||
4795 | struct hda_gen_spec *spec = codec->spec; | ||
4796 | int i; | ||
4797 | hda_nid_t pin; | ||
4798 | |||
4799 | for (i = 0; i < spec->autocfg.dig_outs; i++) | ||
4800 | set_output_and_unmute(codec, spec->digout_paths[i]); | ||
4801 | pin = spec->autocfg.dig_in_pin; | ||
4802 | if (pin) { | ||
4803 | restore_pin_ctl(codec, pin); | ||
4804 | resume_path_from_idx(codec, spec->digin_path); | ||
4805 | } | ||
4806 | } | ||
4807 | |||
4808 | /* clear unsol-event tags on unused pins; Conexant codecs seem to leave | ||
4809 | * invalid unsol tags by some reason | ||
4810 | */ | ||
4811 | static void clear_unsol_on_unused_pins(struct hda_codec *codec) | ||
4812 | { | ||
4813 | int i; | ||
4814 | |||
4815 | for (i = 0; i < codec->init_pins.used; i++) { | ||
4816 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
4817 | hda_nid_t nid = pin->nid; | ||
4818 | if (is_jack_detectable(codec, nid) && | ||
4819 | !snd_hda_jack_tbl_get(codec, nid)) | ||
4820 | snd_hda_codec_update_cache(codec, nid, 0, | ||
4821 | AC_VERB_SET_UNSOLICITED_ENABLE, 0); | ||
1026 | } | 4822 | } |
4823 | } | ||
4824 | |||
4825 | /* | ||
4826 | * initialize the generic spec; | ||
4827 | * this can be put as patch_ops.init function | ||
4828 | */ | ||
4829 | int snd_hda_gen_init(struct hda_codec *codec) | ||
4830 | { | ||
4831 | struct hda_gen_spec *spec = codec->spec; | ||
4832 | |||
4833 | if (spec->init_hook) | ||
4834 | spec->init_hook(codec); | ||
4835 | |||
4836 | snd_hda_apply_verbs(codec); | ||
4837 | |||
4838 | codec->cached_write = 1; | ||
4839 | |||
4840 | init_multi_out(codec); | ||
4841 | init_extra_out(codec); | ||
4842 | init_multi_io(codec); | ||
4843 | init_analog_input(codec); | ||
4844 | init_input_src(codec); | ||
4845 | init_digital(codec); | ||
1027 | 4846 | ||
4847 | clear_unsol_on_unused_pins(codec); | ||
4848 | |||
4849 | /* call init functions of standard auto-mute helpers */ | ||
4850 | update_automute_all(codec); | ||
4851 | |||
4852 | snd_hda_codec_flush_cache(codec); | ||
4853 | |||
4854 | if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook) | ||
4855 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
4856 | |||
4857 | hda_call_check_power_status(codec, 0x01); | ||
1028 | return 0; | 4858 | return 0; |
1029 | } | 4859 | } |
4860 | EXPORT_SYMBOL_HDA(snd_hda_gen_init); | ||
4861 | |||
4862 | /* | ||
4863 | * free the generic spec; | ||
4864 | * this can be put as patch_ops.free function | ||
4865 | */ | ||
4866 | void snd_hda_gen_free(struct hda_codec *codec) | ||
4867 | { | ||
4868 | snd_hda_gen_spec_free(codec->spec); | ||
4869 | kfree(codec->spec); | ||
4870 | codec->spec = NULL; | ||
4871 | } | ||
4872 | EXPORT_SYMBOL_HDA(snd_hda_gen_free); | ||
1030 | 4873 | ||
1031 | #ifdef CONFIG_PM | 4874 | #ifdef CONFIG_PM |
1032 | static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 4875 | /* |
4876 | * check the loopback power save state; | ||
4877 | * this can be put as patch_ops.check_power_status function | ||
4878 | */ | ||
4879 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) | ||
1033 | { | 4880 | { |
1034 | struct hda_gspec *spec = codec->spec; | 4881 | struct hda_gen_spec *spec = codec->spec; |
1035 | return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); | 4882 | return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); |
1036 | } | 4883 | } |
4884 | EXPORT_SYMBOL_HDA(snd_hda_gen_check_power_status); | ||
1037 | #endif | 4885 | #endif |
1038 | 4886 | ||
1039 | 4887 | ||
1040 | /* | 4888 | /* |
4889 | * the generic codec support | ||
1041 | */ | 4890 | */ |
1042 | static struct hda_codec_ops generic_patch_ops = { | 4891 | |
1043 | .build_controls = build_generic_controls, | 4892 | static const struct hda_codec_ops generic_patch_ops = { |
1044 | .build_pcms = build_generic_pcms, | 4893 | .build_controls = snd_hda_gen_build_controls, |
1045 | .free = snd_hda_generic_free, | 4894 | .build_pcms = snd_hda_gen_build_pcms, |
4895 | .init = snd_hda_gen_init, | ||
4896 | .free = snd_hda_gen_free, | ||
4897 | .unsol_event = snd_hda_jack_unsol_event, | ||
1046 | #ifdef CONFIG_PM | 4898 | #ifdef CONFIG_PM |
1047 | .check_power_status = generic_check_power_status, | 4899 | .check_power_status = snd_hda_gen_check_power_status, |
1048 | #endif | 4900 | #endif |
1049 | }; | 4901 | }; |
1050 | 4902 | ||
1051 | /* | ||
1052 | * the generic parser | ||
1053 | */ | ||
1054 | int snd_hda_parse_generic_codec(struct hda_codec *codec) | 4903 | int snd_hda_parse_generic_codec(struct hda_codec *codec) |
1055 | { | 4904 | { |
1056 | struct hda_gspec *spec; | 4905 | struct hda_gen_spec *spec; |
1057 | int err; | 4906 | int err; |
1058 | 4907 | ||
1059 | if(!codec->afg) | ||
1060 | return 0; | ||
1061 | |||
1062 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4908 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1063 | if (spec == NULL) { | 4909 | if (!spec) |
1064 | printk(KERN_ERR "hda_generic: can't allocate spec\n"); | ||
1065 | return -ENOMEM; | 4910 | return -ENOMEM; |
1066 | } | 4911 | snd_hda_gen_spec_init(spec); |
1067 | codec->spec = spec; | 4912 | codec->spec = spec; |
1068 | INIT_LIST_HEAD(&spec->nid_list); | ||
1069 | 4913 | ||
1070 | if ((err = build_afg_tree(codec)) < 0) | 4914 | err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0); |
1071 | goto error; | 4915 | if (err < 0) |
4916 | return err; | ||
1072 | 4917 | ||
1073 | if ((err = parse_input(codec)) < 0 || | 4918 | err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg); |
1074 | (err = parse_output(codec)) < 0) | 4919 | if (err < 0) |
1075 | goto error; | 4920 | goto error; |
1076 | 4921 | ||
1077 | codec->patch_ops = generic_patch_ops; | 4922 | codec->patch_ops = generic_patch_ops; |
1078 | |||
1079 | return 0; | 4923 | return 0; |
1080 | 4924 | ||
1081 | error: | 4925 | error: |
1082 | snd_hda_generic_free(codec); | 4926 | snd_hda_gen_free(codec); |
1083 | return err; | 4927 | return err; |
1084 | } | 4928 | } |
1085 | EXPORT_SYMBOL(snd_hda_parse_generic_codec); | 4929 | EXPORT_SYMBOL_HDA(snd_hda_parse_generic_codec); |
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h new file mode 100644 index 000000000000..065fcc77b860 --- /dev/null +++ b/sound/pci/hda/hda_generic.h | |||
@@ -0,0 +1,305 @@ | |||
1 | /* | ||
2 | * Generic BIOS auto-parser helper functions for HD-audio | ||
3 | * | ||
4 | * Copyright (c) 2012 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This driver is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __SOUND_HDA_GENERIC_H | ||
13 | #define __SOUND_HDA_GENERIC_H | ||
14 | |||
15 | /* unsol event tags */ | ||
16 | enum { | ||
17 | HDA_GEN_HP_EVENT = 1, HDA_GEN_FRONT_EVENT, HDA_GEN_MIC_EVENT, | ||
18 | HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT | ||
19 | }; | ||
20 | |||
21 | /* table entry for multi-io paths */ | ||
22 | struct hda_multi_io { | ||
23 | hda_nid_t pin; /* multi-io widget pin NID */ | ||
24 | hda_nid_t dac; /* DAC to be connected */ | ||
25 | unsigned int ctl_in; /* cached input-pin control value */ | ||
26 | }; | ||
27 | |||
28 | /* Widget connection path | ||
29 | * | ||
30 | * For output, stored in the order of DAC -> ... -> pin, | ||
31 | * for input, pin -> ... -> ADC. | ||
32 | * | ||
33 | * idx[i] contains the source index number to select on of the widget path[i]; | ||
34 | * e.g. idx[1] is the index of the DAC (path[0]) selected by path[1] widget | ||
35 | * multi[] indicates whether it's a selector widget with multi-connectors | ||
36 | * (i.e. the connection selection is mandatory) | ||
37 | * vol_ctl and mute_ctl contains the NIDs for the assigned mixers | ||
38 | */ | ||
39 | |||
40 | #define MAX_NID_PATH_DEPTH 10 | ||
41 | |||
42 | enum { | ||
43 | NID_PATH_VOL_CTL, | ||
44 | NID_PATH_MUTE_CTL, | ||
45 | NID_PATH_BOOST_CTL, | ||
46 | NID_PATH_NUM_CTLS | ||
47 | }; | ||
48 | |||
49 | struct nid_path { | ||
50 | int depth; | ||
51 | hda_nid_t path[MAX_NID_PATH_DEPTH]; | ||
52 | unsigned char idx[MAX_NID_PATH_DEPTH]; | ||
53 | unsigned char multi[MAX_NID_PATH_DEPTH]; | ||
54 | unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */ | ||
55 | bool active; | ||
56 | }; | ||
57 | |||
58 | /* mic/line-in auto switching entry */ | ||
59 | |||
60 | #define MAX_AUTO_MIC_PINS 3 | ||
61 | |||
62 | struct automic_entry { | ||
63 | hda_nid_t pin; /* pin */ | ||
64 | int idx; /* imux index, -1 = invalid */ | ||
65 | unsigned int attr; /* pin attribute (INPUT_PIN_ATTR_*) */ | ||
66 | }; | ||
67 | |||
68 | /* active stream id */ | ||
69 | enum { STREAM_MULTI_OUT, STREAM_INDEP_HP }; | ||
70 | |||
71 | /* PCM hook action */ | ||
72 | enum { | ||
73 | HDA_GEN_PCM_ACT_OPEN, | ||
74 | HDA_GEN_PCM_ACT_PREPARE, | ||
75 | HDA_GEN_PCM_ACT_CLEANUP, | ||
76 | HDA_GEN_PCM_ACT_CLOSE, | ||
77 | }; | ||
78 | |||
79 | struct hda_gen_spec { | ||
80 | char stream_name_analog[32]; /* analog PCM stream */ | ||
81 | const struct hda_pcm_stream *stream_analog_playback; | ||
82 | const struct hda_pcm_stream *stream_analog_capture; | ||
83 | |||
84 | char stream_name_alt_analog[32]; /* alternative analog PCM stream */ | ||
85 | const struct hda_pcm_stream *stream_analog_alt_playback; | ||
86 | const struct hda_pcm_stream *stream_analog_alt_capture; | ||
87 | |||
88 | char stream_name_digital[32]; /* digital PCM stream */ | ||
89 | const struct hda_pcm_stream *stream_digital_playback; | ||
90 | const struct hda_pcm_stream *stream_digital_capture; | ||
91 | |||
92 | /* PCM */ | ||
93 | unsigned int active_streams; | ||
94 | struct mutex pcm_mutex; | ||
95 | |||
96 | /* playback */ | ||
97 | struct hda_multi_out multiout; /* playback set-up | ||
98 | * max_channels, dacs must be set | ||
99 | * dig_out_nid and hp_nid are optional | ||
100 | */ | ||
101 | hda_nid_t alt_dac_nid; | ||
102 | hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ | ||
103 | int dig_out_type; | ||
104 | |||
105 | /* capture */ | ||
106 | unsigned int num_adc_nids; | ||
107 | hda_nid_t adc_nids[AUTO_CFG_MAX_INS]; | ||
108 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | ||
109 | hda_nid_t mixer_nid; /* analog-mixer NID */ | ||
110 | hda_nid_t mixer_merge_nid; /* aamix merge-point NID (optional) */ | ||
111 | const char *input_labels[HDA_MAX_NUM_INPUTS]; | ||
112 | int input_label_idxs[HDA_MAX_NUM_INPUTS]; | ||
113 | |||
114 | /* capture setup for dynamic dual-adc switch */ | ||
115 | hda_nid_t cur_adc; | ||
116 | unsigned int cur_adc_stream_tag; | ||
117 | unsigned int cur_adc_format; | ||
118 | |||
119 | /* capture source */ | ||
120 | struct hda_input_mux input_mux; | ||
121 | unsigned int cur_mux[3]; | ||
122 | |||
123 | /* channel model */ | ||
124 | /* min_channel_count contains the minimum channel count for primary | ||
125 | * outputs. When multi_ios is set, the channels can be configured | ||
126 | * between min_channel_count and (min_channel_count + multi_ios * 2). | ||
127 | * | ||
128 | * ext_channel_count contains the current channel count of the primary | ||
129 | * out. This varies in the range above. | ||
130 | * | ||
131 | * Meanwhile, const_channel_count is the channel count for all outputs | ||
132 | * including headphone and speakers. It's a constant value, and the | ||
133 | * PCM is set up as max(ext_channel_count, const_channel_count). | ||
134 | */ | ||
135 | int min_channel_count; /* min. channel count for primary out */ | ||
136 | int ext_channel_count; /* current channel count for primary */ | ||
137 | int const_channel_count; /* channel count for all */ | ||
138 | |||
139 | /* PCM information */ | ||
140 | struct hda_pcm pcm_rec[3]; /* used in build_pcms() */ | ||
141 | |||
142 | /* dynamic controls, init_verbs and input_mux */ | ||
143 | struct auto_pin_cfg autocfg; | ||
144 | struct snd_array kctls; | ||
145 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | ||
146 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; | ||
147 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; | ||
148 | hda_nid_t shared_mic_vref_pin; | ||
149 | |||
150 | /* DAC/ADC lists */ | ||
151 | int num_all_dacs; | ||
152 | hda_nid_t all_dacs[16]; | ||
153 | int num_all_adcs; | ||
154 | hda_nid_t all_adcs[AUTO_CFG_MAX_INS]; | ||
155 | |||
156 | /* path list */ | ||
157 | struct snd_array paths; | ||
158 | |||
159 | /* path indices */ | ||
160 | int out_paths[AUTO_CFG_MAX_OUTS]; | ||
161 | int hp_paths[AUTO_CFG_MAX_OUTS]; | ||
162 | int speaker_paths[AUTO_CFG_MAX_OUTS]; | ||
163 | int aamix_out_paths[3]; | ||
164 | int digout_paths[AUTO_CFG_MAX_OUTS]; | ||
165 | int input_paths[HDA_MAX_NUM_INPUTS][AUTO_CFG_MAX_INS]; | ||
166 | int loopback_paths[HDA_MAX_NUM_INPUTS]; | ||
167 | int loopback_merge_path; | ||
168 | int digin_path; | ||
169 | |||
170 | /* auto-mic stuff */ | ||
171 | int am_num_entries; | ||
172 | struct automic_entry am_entry[MAX_AUTO_MIC_PINS]; | ||
173 | |||
174 | /* for pin sensing */ | ||
175 | /* current status; set in hda_geneic.c */ | ||
176 | unsigned int hp_jack_present:1; | ||
177 | unsigned int line_jack_present:1; | ||
178 | unsigned int speaker_muted:1; /* current status of speaker mute */ | ||
179 | unsigned int line_out_muted:1; /* current status of LO mute */ | ||
180 | |||
181 | /* internal states of automute / autoswitch behavior */ | ||
182 | unsigned int auto_mic:1; | ||
183 | unsigned int automute_speaker:1; /* automute speaker outputs */ | ||
184 | unsigned int automute_lo:1; /* automute LO outputs */ | ||
185 | |||
186 | /* capabilities detected by parser */ | ||
187 | unsigned int detect_hp:1; /* Headphone detection enabled */ | ||
188 | unsigned int detect_lo:1; /* Line-out detection enabled */ | ||
189 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | ||
190 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | ||
191 | |||
192 | /* additional parameters set by codec drivers */ | ||
193 | unsigned int master_mute:1; /* master mute over all */ | ||
194 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
195 | unsigned int line_in_auto_switch:1; /* allow line-in auto switch */ | ||
196 | |||
197 | /* parser behavior flags; set before snd_hda_gen_parse_auto_config() */ | ||
198 | unsigned int suppress_auto_mute:1; /* suppress input jack auto mute */ | ||
199 | unsigned int suppress_auto_mic:1; /* suppress input jack auto switch */ | ||
200 | |||
201 | /* other parse behavior flags */ | ||
202 | unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */ | ||
203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | ||
204 | unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ | ||
205 | unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ | ||
206 | unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ | ||
207 | unsigned int own_eapd_ctl:1; /* set EAPD by own function */ | ||
208 | unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */ | ||
209 | unsigned int indep_hp:1; /* independent HP supported */ | ||
210 | unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ | ||
211 | unsigned int add_stereo_mix_input:1; /* add aamix as a capture src */ | ||
212 | unsigned int add_out_jack_modes:1; /* add output jack mode enum ctls */ | ||
213 | unsigned int add_in_jack_modes:1; /* add input jack mode enum ctls */ | ||
214 | unsigned int power_down_unused:1; /* power down unused widgets */ | ||
215 | |||
216 | /* other internal flags */ | ||
217 | unsigned int no_analog:1; /* digital I/O only */ | ||
218 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ | ||
219 | unsigned int indep_hp_enabled:1; /* independent HP enabled */ | ||
220 | unsigned int have_aamix_ctl:1; | ||
221 | |||
222 | /* loopback mixing mode */ | ||
223 | bool aamix_mode; | ||
224 | |||
225 | /* for virtual master */ | ||
226 | hda_nid_t vmaster_nid; | ||
227 | unsigned int vmaster_tlv[4]; | ||
228 | struct hda_vmaster_mute_hook vmaster_mute; | ||
229 | #ifdef CONFIG_PM | ||
230 | struct hda_loopback_check loopback; | ||
231 | int num_loopbacks; | ||
232 | struct hda_amp_list loopback_list[8]; | ||
233 | #endif | ||
234 | |||
235 | /* multi-io */ | ||
236 | int multi_ios; | ||
237 | struct hda_multi_io multi_io[4]; | ||
238 | |||
239 | /* hooks */ | ||
240 | void (*init_hook)(struct hda_codec *codec); | ||
241 | void (*automute_hook)(struct hda_codec *codec); | ||
242 | void (*cap_sync_hook)(struct hda_codec *codec, | ||
243 | struct snd_ctl_elem_value *ucontrol); | ||
244 | |||
245 | /* PCM hooks */ | ||
246 | void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo, | ||
247 | struct hda_codec *codec, | ||
248 | struct snd_pcm_substream *substream, | ||
249 | int action); | ||
250 | void (*pcm_capture_hook)(struct hda_pcm_stream *hinfo, | ||
251 | struct hda_codec *codec, | ||
252 | struct snd_pcm_substream *substream, | ||
253 | int action); | ||
254 | |||
255 | /* automute / autoswitch hooks */ | ||
256 | void (*hp_automute_hook)(struct hda_codec *codec, | ||
257 | struct hda_jack_tbl *tbl); | ||
258 | void (*line_automute_hook)(struct hda_codec *codec, | ||
259 | struct hda_jack_tbl *tbl); | ||
260 | void (*mic_autoswitch_hook)(struct hda_codec *codec, | ||
261 | struct hda_jack_tbl *tbl); | ||
262 | }; | ||
263 | |||
264 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec); | ||
265 | void snd_hda_gen_spec_free(struct hda_gen_spec *spec); | ||
266 | |||
267 | int snd_hda_gen_init(struct hda_codec *codec); | ||
268 | void snd_hda_gen_free(struct hda_codec *codec); | ||
269 | |||
270 | struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, | ||
271 | hda_nid_t from_nid, hda_nid_t to_nid); | ||
272 | int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path); | ||
273 | struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx); | ||
274 | bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, | ||
275 | hda_nid_t to_nid, int anchor_nid, | ||
276 | struct nid_path *path); | ||
277 | struct nid_path * | ||
278 | snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, | ||
279 | hda_nid_t to_nid, int anchor_nid); | ||
280 | void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, | ||
281 | bool enable, bool add_aamix); | ||
282 | |||
283 | struct snd_kcontrol_new * | ||
284 | snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, | ||
285 | const struct snd_kcontrol_new *temp); | ||
286 | |||
287 | int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | ||
288 | struct auto_pin_cfg *cfg); | ||
289 | int snd_hda_gen_build_controls(struct hda_codec *codec); | ||
290 | int snd_hda_gen_build_pcms(struct hda_codec *codec); | ||
291 | |||
292 | /* standard jack event callbacks */ | ||
293 | void snd_hda_gen_hp_automute(struct hda_codec *codec, | ||
294 | struct hda_jack_tbl *jack); | ||
295 | void snd_hda_gen_line_automute(struct hda_codec *codec, | ||
296 | struct hda_jack_tbl *jack); | ||
297 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, | ||
298 | struct hda_jack_tbl *jack); | ||
299 | void snd_hda_gen_update_outputs(struct hda_codec *codec); | ||
300 | |||
301 | #ifdef CONFIG_PM | ||
302 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid); | ||
303 | #endif | ||
304 | |||
305 | #endif /* __SOUND_HDA_GENERIC_H */ | ||
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index a5c9411bb367..ce67608734b5 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -148,6 +148,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec) | |||
148 | hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; | 148 | hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | mutex_init(&codec->user_mutex); | ||
151 | snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32); | 152 | snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32); |
152 | snd_array_init(&codec->hints, sizeof(struct hda_hint), 32); | 153 | snd_array_init(&codec->hints, sizeof(struct hda_hint), 32); |
153 | snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16); | 154 | snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16); |
@@ -346,12 +347,14 @@ static ssize_t init_verbs_show(struct device *dev, | |||
346 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); | 347 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); |
347 | struct hda_codec *codec = hwdep->private_data; | 348 | struct hda_codec *codec = hwdep->private_data; |
348 | int i, len = 0; | 349 | int i, len = 0; |
350 | mutex_lock(&codec->user_mutex); | ||
349 | for (i = 0; i < codec->init_verbs.used; i++) { | 351 | for (i = 0; i < codec->init_verbs.used; i++) { |
350 | struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); | 352 | struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); |
351 | len += snprintf(buf + len, PAGE_SIZE - len, | 353 | len += snprintf(buf + len, PAGE_SIZE - len, |
352 | "0x%02x 0x%03x 0x%04x\n", | 354 | "0x%02x 0x%03x 0x%04x\n", |
353 | v->nid, v->verb, v->param); | 355 | v->nid, v->verb, v->param); |
354 | } | 356 | } |
357 | mutex_unlock(&codec->user_mutex); | ||
355 | return len; | 358 | return len; |
356 | } | 359 | } |
357 | 360 | ||
@@ -364,12 +367,16 @@ static int parse_init_verbs(struct hda_codec *codec, const char *buf) | |||
364 | return -EINVAL; | 367 | return -EINVAL; |
365 | if (!nid || !verb) | 368 | if (!nid || !verb) |
366 | return -EINVAL; | 369 | return -EINVAL; |
370 | mutex_lock(&codec->user_mutex); | ||
367 | v = snd_array_new(&codec->init_verbs); | 371 | v = snd_array_new(&codec->init_verbs); |
368 | if (!v) | 372 | if (!v) { |
373 | mutex_unlock(&codec->user_mutex); | ||
369 | return -ENOMEM; | 374 | return -ENOMEM; |
375 | } | ||
370 | v->nid = nid; | 376 | v->nid = nid; |
371 | v->verb = verb; | 377 | v->verb = verb; |
372 | v->param = param; | 378 | v->param = param; |
379 | mutex_unlock(&codec->user_mutex); | ||
373 | return 0; | 380 | return 0; |
374 | } | 381 | } |
375 | 382 | ||
@@ -392,11 +399,13 @@ static ssize_t hints_show(struct device *dev, | |||
392 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); | 399 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); |
393 | struct hda_codec *codec = hwdep->private_data; | 400 | struct hda_codec *codec = hwdep->private_data; |
394 | int i, len = 0; | 401 | int i, len = 0; |
402 | mutex_lock(&codec->user_mutex); | ||
395 | for (i = 0; i < codec->hints.used; i++) { | 403 | for (i = 0; i < codec->hints.used; i++) { |
396 | struct hda_hint *hint = snd_array_elem(&codec->hints, i); | 404 | struct hda_hint *hint = snd_array_elem(&codec->hints, i); |
397 | len += snprintf(buf + len, PAGE_SIZE - len, | 405 | len += snprintf(buf + len, PAGE_SIZE - len, |
398 | "%s = %s\n", hint->key, hint->val); | 406 | "%s = %s\n", hint->key, hint->val); |
399 | } | 407 | } |
408 | mutex_unlock(&codec->user_mutex); | ||
400 | return len; | 409 | return len; |
401 | } | 410 | } |
402 | 411 | ||
@@ -431,6 +440,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf) | |||
431 | { | 440 | { |
432 | char *key, *val; | 441 | char *key, *val; |
433 | struct hda_hint *hint; | 442 | struct hda_hint *hint; |
443 | int err = 0; | ||
434 | 444 | ||
435 | buf = skip_spaces(buf); | 445 | buf = skip_spaces(buf); |
436 | if (!*buf || *buf == '#' || *buf == '\n') | 446 | if (!*buf || *buf == '#' || *buf == '\n') |
@@ -450,26 +460,31 @@ static int parse_hints(struct hda_codec *codec, const char *buf) | |||
450 | val = skip_spaces(val); | 460 | val = skip_spaces(val); |
451 | remove_trail_spaces(key); | 461 | remove_trail_spaces(key); |
452 | remove_trail_spaces(val); | 462 | remove_trail_spaces(val); |
463 | mutex_lock(&codec->user_mutex); | ||
453 | hint = get_hint(codec, key); | 464 | hint = get_hint(codec, key); |
454 | if (hint) { | 465 | if (hint) { |
455 | /* replace */ | 466 | /* replace */ |
456 | kfree(hint->key); | 467 | kfree(hint->key); |
457 | hint->key = key; | 468 | hint->key = key; |
458 | hint->val = val; | 469 | hint->val = val; |
459 | return 0; | 470 | goto unlock; |
460 | } | 471 | } |
461 | /* allocate a new hint entry */ | 472 | /* allocate a new hint entry */ |
462 | if (codec->hints.used >= MAX_HINTS) | 473 | if (codec->hints.used >= MAX_HINTS) |
463 | hint = NULL; | 474 | hint = NULL; |
464 | else | 475 | else |
465 | hint = snd_array_new(&codec->hints); | 476 | hint = snd_array_new(&codec->hints); |
466 | if (!hint) { | 477 | if (hint) { |
467 | kfree(key); | 478 | hint->key = key; |
468 | return -ENOMEM; | 479 | hint->val = val; |
480 | } else { | ||
481 | err = -ENOMEM; | ||
469 | } | 482 | } |
470 | hint->key = key; | 483 | unlock: |
471 | hint->val = val; | 484 | mutex_unlock(&codec->user_mutex); |
472 | return 0; | 485 | if (err) |
486 | kfree(key); | ||
487 | return err; | ||
473 | } | 488 | } |
474 | 489 | ||
475 | static ssize_t hints_store(struct device *dev, | 490 | static ssize_t hints_store(struct device *dev, |
@@ -489,11 +504,13 @@ static ssize_t pin_configs_show(struct hda_codec *codec, | |||
489 | char *buf) | 504 | char *buf) |
490 | { | 505 | { |
491 | int i, len = 0; | 506 | int i, len = 0; |
507 | mutex_lock(&codec->user_mutex); | ||
492 | for (i = 0; i < list->used; i++) { | 508 | for (i = 0; i < list->used; i++) { |
493 | struct hda_pincfg *pin = snd_array_elem(list, i); | 509 | struct hda_pincfg *pin = snd_array_elem(list, i); |
494 | len += sprintf(buf + len, "0x%02x 0x%08x\n", | 510 | len += sprintf(buf + len, "0x%02x 0x%08x\n", |
495 | pin->nid, pin->cfg); | 511 | pin->nid, pin->cfg); |
496 | } | 512 | } |
513 | mutex_unlock(&codec->user_mutex); | ||
497 | return len; | 514 | return len; |
498 | } | 515 | } |
499 | 516 | ||
@@ -528,13 +545,16 @@ static ssize_t driver_pin_configs_show(struct device *dev, | |||
528 | 545 | ||
529 | static int parse_user_pin_configs(struct hda_codec *codec, const char *buf) | 546 | static int parse_user_pin_configs(struct hda_codec *codec, const char *buf) |
530 | { | 547 | { |
531 | int nid, cfg; | 548 | int nid, cfg, err; |
532 | 549 | ||
533 | if (sscanf(buf, "%i %i", &nid, &cfg) != 2) | 550 | if (sscanf(buf, "%i %i", &nid, &cfg) != 2) |
534 | return -EINVAL; | 551 | return -EINVAL; |
535 | if (!nid) | 552 | if (!nid) |
536 | return -EINVAL; | 553 | return -EINVAL; |
537 | return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); | 554 | mutex_lock(&codec->user_mutex); |
555 | err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); | ||
556 | mutex_unlock(&codec->user_mutex); | ||
557 | return err; | ||
538 | } | 558 | } |
539 | 559 | ||
540 | static ssize_t user_pin_configs_store(struct device *dev, | 560 | static ssize_t user_pin_configs_store(struct device *dev, |
@@ -600,19 +620,50 @@ EXPORT_SYMBOL_HDA(snd_hda_get_hint); | |||
600 | 620 | ||
601 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) | 621 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) |
602 | { | 622 | { |
603 | const char *p = snd_hda_get_hint(codec, key); | 623 | const char *p; |
624 | int ret; | ||
625 | |||
626 | mutex_lock(&codec->user_mutex); | ||
627 | p = snd_hda_get_hint(codec, key); | ||
604 | if (!p || !*p) | 628 | if (!p || !*p) |
605 | return -ENOENT; | 629 | ret = -ENOENT; |
606 | switch (toupper(*p)) { | 630 | else { |
607 | case 'T': /* true */ | 631 | switch (toupper(*p)) { |
608 | case 'Y': /* yes */ | 632 | case 'T': /* true */ |
609 | case '1': | 633 | case 'Y': /* yes */ |
610 | return 1; | 634 | case '1': |
635 | ret = 1; | ||
636 | break; | ||
637 | default: | ||
638 | ret = 0; | ||
639 | break; | ||
640 | } | ||
611 | } | 641 | } |
612 | return 0; | 642 | mutex_unlock(&codec->user_mutex); |
643 | return ret; | ||
613 | } | 644 | } |
614 | EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); | 645 | EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); |
615 | 646 | ||
647 | int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) | ||
648 | { | ||
649 | const char *p; | ||
650 | unsigned long val; | ||
651 | int ret; | ||
652 | |||
653 | mutex_lock(&codec->user_mutex); | ||
654 | p = snd_hda_get_hint(codec, key); | ||
655 | if (!p) | ||
656 | ret = -ENOENT; | ||
657 | else if (strict_strtoul(p, 0, &val)) | ||
658 | ret = -EINVAL; | ||
659 | else { | ||
660 | *valp = val; | ||
661 | ret = 0; | ||
662 | } | ||
663 | mutex_unlock(&codec->user_mutex); | ||
664 | return ret; | ||
665 | } | ||
666 | EXPORT_SYMBOL_HDA(snd_hda_get_int_hint); | ||
616 | #endif /* CONFIG_SND_HDA_RECONFIG */ | 667 | #endif /* CONFIG_SND_HDA_RECONFIG */ |
617 | 668 | ||
618 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 669 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c78286f6e5d8..d9e37ffdb048 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -134,8 +134,8 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " | |||
134 | * this may give more power-saving, but will take longer time to | 134 | * this may give more power-saving, but will take longer time to |
135 | * wake up. | 135 | * wake up. |
136 | */ | 136 | */ |
137 | static bool power_save_controller = 1; | 137 | static int power_save_controller = -1; |
138 | module_param(power_save_controller, bool, 0644); | 138 | module_param(power_save_controller, bint, 0644); |
139 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 139 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
140 | #endif /* CONFIG_PM */ | 140 | #endif /* CONFIG_PM */ |
141 | 141 | ||
@@ -811,7 +811,7 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val) | |||
811 | { | 811 | { |
812 | struct azx *chip = bus->private_data; | 812 | struct azx *chip = bus->private_data; |
813 | unsigned int addr = azx_command_addr(val); | 813 | unsigned int addr = azx_command_addr(val); |
814 | unsigned int wp; | 814 | unsigned int wp, rp; |
815 | 815 | ||
816 | spin_lock_irq(&chip->reg_lock); | 816 | spin_lock_irq(&chip->reg_lock); |
817 | 817 | ||
@@ -820,11 +820,18 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val) | |||
820 | if (wp == 0xffff) { | 820 | if (wp == 0xffff) { |
821 | /* something wrong, controller likely turned to D3 */ | 821 | /* something wrong, controller likely turned to D3 */ |
822 | spin_unlock_irq(&chip->reg_lock); | 822 | spin_unlock_irq(&chip->reg_lock); |
823 | return -1; | 823 | return -EIO; |
824 | } | 824 | } |
825 | wp++; | 825 | wp++; |
826 | wp %= ICH6_MAX_CORB_ENTRIES; | 826 | wp %= ICH6_MAX_CORB_ENTRIES; |
827 | 827 | ||
828 | rp = azx_readw(chip, CORBRP); | ||
829 | if (wp == rp) { | ||
830 | /* oops, it's full */ | ||
831 | spin_unlock_irq(&chip->reg_lock); | ||
832 | return -EAGAIN; | ||
833 | } | ||
834 | |||
828 | chip->rirb.cmds[addr]++; | 835 | chip->rirb.cmds[addr]++; |
829 | chip->corb.buf[wp] = cpu_to_le32(val); | 836 | chip->corb.buf[wp] = cpu_to_le32(val); |
830 | azx_writel(chip, CORBWP, wp); | 837 | azx_writel(chip, CORBWP, wp); |
@@ -2726,6 +2733,8 @@ static int azx_runtime_idle(struct device *dev) | |||
2726 | struct snd_card *card = dev_get_drvdata(dev); | 2733 | struct snd_card *card = dev_get_drvdata(dev); |
2727 | struct azx *chip = card->private_data; | 2734 | struct azx *chip = card->private_data; |
2728 | 2735 | ||
2736 | if (power_save_controller > 0) | ||
2737 | return 0; | ||
2729 | if (!power_save_controller || | 2738 | if (!power_save_controller || |
2730 | !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) | 2739 | !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) |
2731 | return -EBUSY; | 2740 | return -EBUSY; |
@@ -3618,6 +3627,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3618 | { PCI_DEVICE(0x8086, 0x9c21), | 3627 | { PCI_DEVICE(0x8086, 0x9c21), |
3619 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, | 3628 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, |
3620 | /* Haswell */ | 3629 | /* Haswell */ |
3630 | { PCI_DEVICE(0x8086, 0x0a0c), | ||
3631 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, | ||
3621 | { PCI_DEVICE(0x8086, 0x0c0c), | 3632 | { PCI_DEVICE(0x8086, 0x0c0c), |
3622 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, | 3633 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, |
3623 | { PCI_DEVICE(0x8086, 0x0d0c), | 3634 | { PCI_DEVICE(0x8086, 0x0d0c), |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 6e9f57bbe667..1d035efeff4f 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -29,7 +29,8 @@ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | |||
29 | if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | 29 | if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & |
30 | AC_DEFCFG_MISC_NO_PRESENCE) | 30 | AC_DEFCFG_MISC_NO_PRESENCE) |
31 | return false; | 31 | return false; |
32 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | 32 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) && |
33 | !codec->jackpoll_interval) | ||
33 | return false; | 34 | return false; |
34 | return true; | 35 | return true; |
35 | } | 36 | } |
@@ -39,6 +40,7 @@ EXPORT_SYMBOL_HDA(is_jack_detectable); | |||
39 | static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) | 40 | static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) |
40 | { | 41 | { |
41 | u32 pincap; | 42 | u32 pincap; |
43 | u32 val; | ||
42 | 44 | ||
43 | if (!codec->no_trigger_sense) { | 45 | if (!codec->no_trigger_sense) { |
44 | pincap = snd_hda_query_pin_caps(codec, nid); | 46 | pincap = snd_hda_query_pin_caps(codec, nid); |
@@ -46,8 +48,11 @@ static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) | |||
46 | snd_hda_codec_read(codec, nid, 0, | 48 | snd_hda_codec_read(codec, nid, 0, |
47 | AC_VERB_SET_PIN_SENSE, 0); | 49 | AC_VERB_SET_PIN_SENSE, 0); |
48 | } | 50 | } |
49 | return snd_hda_codec_read(codec, nid, 0, | 51 | val = snd_hda_codec_read(codec, nid, 0, |
50 | AC_VERB_GET_PIN_SENSE, 0); | 52 | AC_VERB_GET_PIN_SENSE, 0); |
53 | if (codec->inv_jack_detect) | ||
54 | val ^= AC_PINSENSE_PRESENCE; | ||
55 | return val; | ||
51 | } | 56 | } |
52 | 57 | ||
53 | /** | 58 | /** |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 4b40a5e7a8f5..05f1d594d17b 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -133,9 +133,11 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
133 | int direction, int idx, int mask, int val); | 133 | int direction, int idx, int mask, int val); |
134 | int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | 134 | int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, |
135 | int dir, int idx, int mask, int val); | 135 | int dir, int idx, int mask, int val); |
136 | #ifdef CONFIG_PM | 136 | int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, |
137 | int direction, int idx, int mask, int val); | ||
138 | int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
139 | int dir, int idx, int mask, int val); | ||
137 | void snd_hda_codec_resume_amp(struct hda_codec *codec); | 140 | void snd_hda_codec_resume_amp(struct hda_codec *codec); |
138 | #endif | ||
139 | 141 | ||
140 | void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, | 142 | void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, |
141 | unsigned int *tlv); | 143 | unsigned int *tlv); |
@@ -384,6 +386,61 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, | |||
384 | const struct snd_kcontrol_new *knew); | 386 | const struct snd_kcontrol_new *knew); |
385 | 387 | ||
386 | /* | 388 | /* |
389 | * Fix-up pin default configurations and add default verbs | ||
390 | */ | ||
391 | |||
392 | struct hda_pintbl { | ||
393 | hda_nid_t nid; | ||
394 | u32 val; | ||
395 | }; | ||
396 | |||
397 | struct hda_model_fixup { | ||
398 | const int id; | ||
399 | const char *name; | ||
400 | }; | ||
401 | |||
402 | struct hda_fixup { | ||
403 | int type; | ||
404 | bool chained:1; /* call the chained fixup(s) after this */ | ||
405 | bool chained_before:1; /* call the chained fixup(s) before this */ | ||
406 | int chain_id; | ||
407 | union { | ||
408 | const struct hda_pintbl *pins; | ||
409 | const struct hda_verb *verbs; | ||
410 | void (*func)(struct hda_codec *codec, | ||
411 | const struct hda_fixup *fix, | ||
412 | int action); | ||
413 | } v; | ||
414 | }; | ||
415 | |||
416 | /* fixup types */ | ||
417 | enum { | ||
418 | HDA_FIXUP_INVALID, | ||
419 | HDA_FIXUP_PINS, | ||
420 | HDA_FIXUP_VERBS, | ||
421 | HDA_FIXUP_FUNC, | ||
422 | HDA_FIXUP_PINCTLS, | ||
423 | }; | ||
424 | |||
425 | /* fixup action definitions */ | ||
426 | enum { | ||
427 | HDA_FIXUP_ACT_PRE_PROBE, | ||
428 | HDA_FIXUP_ACT_PROBE, | ||
429 | HDA_FIXUP_ACT_INIT, | ||
430 | HDA_FIXUP_ACT_BUILD, | ||
431 | }; | ||
432 | |||
433 | int snd_hda_add_verbs(struct hda_codec *codec, const struct hda_verb *list); | ||
434 | void snd_hda_apply_verbs(struct hda_codec *codec); | ||
435 | void snd_hda_apply_pincfgs(struct hda_codec *codec, | ||
436 | const struct hda_pintbl *cfg); | ||
437 | void snd_hda_apply_fixup(struct hda_codec *codec, int action); | ||
438 | void snd_hda_pick_fixup(struct hda_codec *codec, | ||
439 | const struct hda_model_fixup *models, | ||
440 | const struct snd_pci_quirk *quirk, | ||
441 | const struct hda_fixup *fixlist); | ||
442 | |||
443 | /* | ||
387 | * unsolicited event handler | 444 | * unsolicited event handler |
388 | */ | 445 | */ |
389 | 446 | ||
@@ -431,6 +488,8 @@ struct hda_bus_unsolicited { | |||
431 | #define PIN_HP_AMP (AC_PINCTL_HP_EN) | 488 | #define PIN_HP_AMP (AC_PINCTL_HP_EN) |
432 | 489 | ||
433 | unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin); | 490 | unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin); |
491 | unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, | ||
492 | hda_nid_t pin, unsigned int val); | ||
434 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, | 493 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, |
435 | unsigned int val, bool cached); | 494 | unsigned int val, bool cached); |
436 | 495 | ||
@@ -470,6 +529,10 @@ snd_hda_set_pin_ctl_cache(struct hda_codec *codec, hda_nid_t pin, | |||
470 | return _snd_hda_set_pin_ctl(codec, pin, val, true); | 529 | return _snd_hda_set_pin_ctl(codec, pin, val, true); |
471 | } | 530 | } |
472 | 531 | ||
532 | int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid); | ||
533 | int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, | ||
534 | unsigned int val); | ||
535 | |||
473 | /* | 536 | /* |
474 | * get widget capabilities | 537 | * get widget capabilities |
475 | */ | 538 | */ |
@@ -552,6 +615,7 @@ static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec) | |||
552 | #ifdef CONFIG_SND_HDA_RECONFIG | 615 | #ifdef CONFIG_SND_HDA_RECONFIG |
553 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key); | 616 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key); |
554 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key); | 617 | int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key); |
618 | int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp); | ||
555 | #else | 619 | #else |
556 | static inline | 620 | static inline |
557 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) | 621 | const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) |
@@ -564,6 +628,12 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) | |||
564 | { | 628 | { |
565 | return -ENOENT; | 629 | return -ENOENT; |
566 | } | 630 | } |
631 | |||
632 | static inline | ||
633 | int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) | ||
634 | { | ||
635 | return -ENOENT; | ||
636 | } | ||
567 | #endif | 637 | #endif |
568 | 638 | ||
569 | /* | 639 | /* |
@@ -587,6 +657,19 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
587 | struct hda_loopback_check *check, | 657 | struct hda_loopback_check *check, |
588 | hda_nid_t nid); | 658 | hda_nid_t nid); |
589 | 659 | ||
660 | /* check whether the actual power state matches with the target state */ | ||
661 | static inline bool | ||
662 | snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, | ||
663 | unsigned int target_state) | ||
664 | { | ||
665 | unsigned int state = snd_hda_codec_read(codec, nid, 0, | ||
666 | AC_VERB_GET_POWER_STATE, 0); | ||
667 | if (state & AC_PWRST_ERROR) | ||
668 | return true; | ||
669 | state = (state >> 4) & 0x0f; | ||
670 | return (state != target_state); | ||
671 | } | ||
672 | |||
590 | /* | 673 | /* |
591 | * AMP control callbacks | 674 | * AMP control callbacks |
592 | */ | 675 | */ |
@@ -596,7 +679,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
596 | #define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) | 679 | #define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) |
597 | #define get_amp_direction_(pv) (((pv) >> 18) & 0x1) | 680 | #define get_amp_direction_(pv) (((pv) >> 18) & 0x1) |
598 | #define get_amp_direction(kc) get_amp_direction_((kc)->private_value) | 681 | #define get_amp_direction(kc) get_amp_direction_((kc)->private_value) |
599 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | 682 | #define get_amp_index_(pv) (((pv) >> 19) & 0xf) |
683 | #define get_amp_index(kc) get_amp_index_((kc)->private_value) | ||
600 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) | 684 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) |
601 | #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) | 685 | #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) |
602 | 686 | ||
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 045e5d32f5de..5e02f26606b6 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -138,16 +138,17 @@ static void print_amp_vals(struct snd_info_buffer *buffer, | |||
138 | dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | 138 | dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; |
139 | for (i = 0; i < indices; i++) { | 139 | for (i = 0; i < indices; i++) { |
140 | snd_iprintf(buffer, " ["); | 140 | snd_iprintf(buffer, " ["); |
141 | val = snd_hda_codec_read(codec, nid, 0, | ||
142 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
143 | AC_AMP_GET_LEFT | dir | i); | ||
144 | snd_iprintf(buffer, "0x%02x", val); | ||
141 | if (stereo) { | 145 | if (stereo) { |
142 | val = snd_hda_codec_read(codec, nid, 0, | 146 | val = snd_hda_codec_read(codec, nid, 0, |
143 | AC_VERB_GET_AMP_GAIN_MUTE, | 147 | AC_VERB_GET_AMP_GAIN_MUTE, |
144 | AC_AMP_GET_LEFT | dir | i); | 148 | AC_AMP_GET_RIGHT | dir | i); |
145 | snd_iprintf(buffer, "0x%02x ", val); | 149 | snd_iprintf(buffer, " 0x%02x", val); |
146 | } | 150 | } |
147 | val = snd_hda_codec_read(codec, nid, 0, | 151 | snd_iprintf(buffer, "]"); |
148 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
149 | AC_AMP_GET_RIGHT | dir | i); | ||
150 | snd_iprintf(buffer, "0x%02x]", val); | ||
151 | } | 152 | } |
152 | snd_iprintf(buffer, "\n"); | 153 | snd_iprintf(buffer, "\n"); |
153 | } | 154 | } |
@@ -603,6 +604,8 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
603 | print_amp_caps(buffer, codec, codec->afg, HDA_INPUT); | 604 | print_amp_caps(buffer, codec, codec->afg, HDA_INPUT); |
604 | snd_iprintf(buffer, "Default Amp-Out caps: "); | 605 | snd_iprintf(buffer, "Default Amp-Out caps: "); |
605 | print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT); | 606 | print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT); |
607 | snd_iprintf(buffer, "State of AFG node 0x%02x:\n", codec->afg); | ||
608 | print_power_state(buffer, codec, codec->afg); | ||
606 | 609 | ||
607 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); | 610 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); |
608 | if (! nid || nodes < 0) { | 611 | if (! nid || nodes < 0) { |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 89fc5030ec79..df8014b27596 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -20,7 +20,6 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/delay.h> | ||
24 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
25 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
26 | #include <linux/module.h> | 25 | #include <linux/module.h> |
@@ -31,11 +30,24 @@ | |||
31 | #include "hda_auto_parser.h" | 30 | #include "hda_auto_parser.h" |
32 | #include "hda_beep.h" | 31 | #include "hda_beep.h" |
33 | #include "hda_jack.h" | 32 | #include "hda_jack.h" |
33 | #include "hda_generic.h" | ||
34 | |||
35 | #define ENABLE_AD_STATIC_QUIRKS | ||
34 | 36 | ||
35 | struct ad198x_spec { | 37 | struct ad198x_spec { |
38 | struct hda_gen_spec gen; | ||
39 | |||
40 | /* for auto parser */ | ||
41 | int smux_paths[4]; | ||
42 | unsigned int cur_smux; | ||
43 | hda_nid_t eapd_nid; | ||
44 | |||
45 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | ||
46 | hda_nid_t beep_dev_nid; | ||
47 | |||
48 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
36 | const struct snd_kcontrol_new *mixers[6]; | 49 | const struct snd_kcontrol_new *mixers[6]; |
37 | int num_mixers; | 50 | int num_mixers; |
38 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | ||
39 | const struct hda_verb *init_verbs[6]; /* initialization verbs | 51 | const struct hda_verb *init_verbs[6]; /* initialization verbs |
40 | * don't forget NULL termination! | 52 | * don't forget NULL termination! |
41 | */ | 53 | */ |
@@ -49,11 +61,6 @@ struct ad198x_spec { | |||
49 | unsigned int cur_eapd; | 61 | unsigned int cur_eapd; |
50 | unsigned int need_dac_fix; | 62 | unsigned int need_dac_fix; |
51 | 63 | ||
52 | const hda_nid_t *alt_dac_nid; | ||
53 | const struct hda_pcm_stream *stream_analog_alt_playback; | ||
54 | int independent_hp; | ||
55 | int num_active_streams; | ||
56 | |||
57 | /* capture */ | 64 | /* capture */ |
58 | unsigned int num_adc_nids; | 65 | unsigned int num_adc_nids; |
59 | const hda_nid_t *adc_nids; | 66 | const hda_nid_t *adc_nids; |
@@ -73,15 +80,8 @@ struct ad198x_spec { | |||
73 | 80 | ||
74 | unsigned int spdif_route; | 81 | unsigned int spdif_route; |
75 | 82 | ||
76 | /* dynamic controls, init_verbs and input_mux */ | ||
77 | struct auto_pin_cfg autocfg; | ||
78 | struct snd_array kctls; | ||
79 | struct hda_input_mux private_imux; | ||
80 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | ||
81 | |||
82 | unsigned int jack_present: 1; | 83 | unsigned int jack_present: 1; |
83 | unsigned int inv_jack_detect: 1;/* inverted jack-detection */ | 84 | unsigned int inv_jack_detect: 1;/* inverted jack-detection */ |
84 | unsigned int inv_eapd: 1; /* inverted EAPD implementation */ | ||
85 | unsigned int analog_beep: 1; /* analog beep input present */ | 85 | unsigned int analog_beep: 1; /* analog beep input present */ |
86 | unsigned int avoid_init_slave_vol:1; | 86 | unsigned int avoid_init_slave_vol:1; |
87 | 87 | ||
@@ -92,8 +92,10 @@ struct ad198x_spec { | |||
92 | hda_nid_t vmaster_nid; | 92 | hda_nid_t vmaster_nid; |
93 | const char * const *slave_vols; | 93 | const char * const *slave_vols; |
94 | const char * const *slave_sws; | 94 | const char * const *slave_sws; |
95 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
95 | }; | 96 | }; |
96 | 97 | ||
98 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
97 | /* | 99 | /* |
98 | * input MUX handling (common part) | 100 | * input MUX handling (common part) |
99 | */ | 101 | */ |
@@ -149,8 +151,7 @@ static const char * const ad1988_6stack_fp_slave_pfxs[] = { | |||
149 | "Front", "Surround", "Center", "LFE", "Side", "IEC958", | 151 | "Front", "Surround", "Center", "LFE", "Side", "IEC958", |
150 | NULL | 152 | NULL |
151 | }; | 153 | }; |
152 | 154 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | |
153 | static void ad198x_free_kctls(struct hda_codec *codec); | ||
154 | 155 | ||
155 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 156 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
156 | /* additional beep mixers; the actual parameters are overwritten at build */ | 157 | /* additional beep mixers; the actual parameters are overwritten at build */ |
@@ -172,6 +173,34 @@ static const struct snd_kcontrol_new ad_beep2_mixer[] = { | |||
172 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 173 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
173 | #endif | 174 | #endif |
174 | 175 | ||
176 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
177 | static int create_beep_ctls(struct hda_codec *codec) | ||
178 | { | ||
179 | struct ad198x_spec *spec = codec->spec; | ||
180 | const struct snd_kcontrol_new *knew; | ||
181 | |||
182 | if (!spec->beep_amp) | ||
183 | return 0; | ||
184 | |||
185 | knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; | ||
186 | for ( ; knew->name; knew++) { | ||
187 | int err; | ||
188 | struct snd_kcontrol *kctl; | ||
189 | kctl = snd_ctl_new1(knew, codec); | ||
190 | if (!kctl) | ||
191 | return -ENOMEM; | ||
192 | kctl->private_value = spec->beep_amp; | ||
193 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
194 | if (err < 0) | ||
195 | return err; | ||
196 | } | ||
197 | return 0; | ||
198 | } | ||
199 | #else | ||
200 | #define create_beep_ctls(codec) 0 | ||
201 | #endif | ||
202 | |||
203 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
175 | static int ad198x_build_controls(struct hda_codec *codec) | 204 | static int ad198x_build_controls(struct hda_codec *codec) |
176 | { | 205 | { |
177 | struct ad198x_spec *spec = codec->spec; | 206 | struct ad198x_spec *spec = codec->spec; |
@@ -203,22 +232,9 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
203 | } | 232 | } |
204 | 233 | ||
205 | /* create beep controls if needed */ | 234 | /* create beep controls if needed */ |
206 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 235 | err = create_beep_ctls(codec); |
207 | if (spec->beep_amp) { | 236 | if (err < 0) |
208 | const struct snd_kcontrol_new *knew; | 237 | return err; |
209 | knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; | ||
210 | for ( ; knew->name; knew++) { | ||
211 | struct snd_kcontrol *kctl; | ||
212 | kctl = snd_ctl_new1(knew, codec); | ||
213 | if (!kctl) | ||
214 | return -ENOMEM; | ||
215 | kctl->private_value = spec->beep_amp; | ||
216 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
217 | if (err < 0) | ||
218 | return err; | ||
219 | } | ||
220 | } | ||
221 | #endif | ||
222 | 238 | ||
223 | /* if we have no master control, let's create it */ | 239 | /* if we have no master control, let's create it */ |
224 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | 240 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { |
@@ -244,8 +260,6 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
244 | return err; | 260 | return err; |
245 | } | 261 | } |
246 | 262 | ||
247 | ad198x_free_kctls(codec); /* no longer needed */ | ||
248 | |||
249 | /* assign Capture Source enums to NID */ | 263 | /* assign Capture Source enums to NID */ |
250 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | 264 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); |
251 | if (!kctl) | 265 | if (!kctl) |
@@ -277,72 +291,6 @@ static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid) | |||
277 | } | 291 | } |
278 | #endif | 292 | #endif |
279 | 293 | ||
280 | static void activate_ctl(struct hda_codec *codec, const char *name, int active) | ||
281 | { | ||
282 | struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); | ||
283 | if (ctl) { | ||
284 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
285 | ctl->vd[0].access |= active ? 0 : | ||
286 | SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
287 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE; | ||
288 | ctl->vd[0].access |= active ? | ||
289 | SNDRV_CTL_ELEM_ACCESS_WRITE : 0; | ||
290 | snd_ctl_notify(codec->bus->card, | ||
291 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
292 | } | ||
293 | } | ||
294 | |||
295 | static void set_stream_active(struct hda_codec *codec, bool active) | ||
296 | { | ||
297 | struct ad198x_spec *spec = codec->spec; | ||
298 | if (active) | ||
299 | spec->num_active_streams++; | ||
300 | else | ||
301 | spec->num_active_streams--; | ||
302 | activate_ctl(codec, "Independent HP", spec->num_active_streams == 0); | ||
303 | } | ||
304 | |||
305 | static int ad1988_independent_hp_info(struct snd_kcontrol *kcontrol, | ||
306 | struct snd_ctl_elem_info *uinfo) | ||
307 | { | ||
308 | static const char * const texts[] = { "OFF", "ON", NULL}; | ||
309 | int index; | ||
310 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
311 | uinfo->count = 1; | ||
312 | uinfo->value.enumerated.items = 2; | ||
313 | index = uinfo->value.enumerated.item; | ||
314 | if (index >= 2) | ||
315 | index = 1; | ||
316 | strcpy(uinfo->value.enumerated.name, texts[index]); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int ad1988_independent_hp_get(struct snd_kcontrol *kcontrol, | ||
321 | struct snd_ctl_elem_value *ucontrol) | ||
322 | { | ||
323 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
324 | struct ad198x_spec *spec = codec->spec; | ||
325 | ucontrol->value.enumerated.item[0] = spec->independent_hp; | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int ad1988_independent_hp_put(struct snd_kcontrol *kcontrol, | ||
330 | struct snd_ctl_elem_value *ucontrol) | ||
331 | { | ||
332 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
333 | struct ad198x_spec *spec = codec->spec; | ||
334 | unsigned int select = ucontrol->value.enumerated.item[0]; | ||
335 | if (spec->independent_hp != select) { | ||
336 | spec->independent_hp = select; | ||
337 | if (spec->independent_hp) | ||
338 | spec->multiout.hp_nid = 0; | ||
339 | else | ||
340 | spec->multiout.hp_nid = spec->alt_dac_nid[0]; | ||
341 | return 1; | ||
342 | } | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* | 294 | /* |
347 | * Analog playback callbacks | 295 | * Analog playback callbacks |
348 | */ | 296 | */ |
@@ -351,15 +299,8 @@ static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
351 | struct snd_pcm_substream *substream) | 299 | struct snd_pcm_substream *substream) |
352 | { | 300 | { |
353 | struct ad198x_spec *spec = codec->spec; | 301 | struct ad198x_spec *spec = codec->spec; |
354 | int err; | 302 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
355 | set_stream_active(codec, true); | ||
356 | err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
357 | hinfo); | 303 | hinfo); |
358 | if (err < 0) { | ||
359 | set_stream_active(codec, false); | ||
360 | return err; | ||
361 | } | ||
362 | return 0; | ||
363 | } | 304 | } |
364 | 305 | ||
365 | static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 306 | static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
@@ -381,43 +322,6 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
381 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 322 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
382 | } | 323 | } |
383 | 324 | ||
384 | static int ad198x_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
385 | struct hda_codec *codec, | ||
386 | struct snd_pcm_substream *substream) | ||
387 | { | ||
388 | set_stream_active(codec, false); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int ad1988_alt_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
393 | struct hda_codec *codec, | ||
394 | struct snd_pcm_substream *substream) | ||
395 | { | ||
396 | struct ad198x_spec *spec = codec->spec; | ||
397 | if (!spec->independent_hp) | ||
398 | return -EBUSY; | ||
399 | set_stream_active(codec, true); | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static int ad1988_alt_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
404 | struct hda_codec *codec, | ||
405 | struct snd_pcm_substream *substream) | ||
406 | { | ||
407 | set_stream_active(codec, false); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { | ||
412 | .substreams = 1, | ||
413 | .channels_min = 2, | ||
414 | .channels_max = 2, | ||
415 | .ops = { | ||
416 | .open = ad1988_alt_playback_pcm_open, | ||
417 | .close = ad1988_alt_playback_pcm_close | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | /* | 325 | /* |
422 | * Digital out | 326 | * Digital out |
423 | */ | 327 | */ |
@@ -491,7 +395,6 @@ static const struct hda_pcm_stream ad198x_pcm_analog_playback = { | |||
491 | .open = ad198x_playback_pcm_open, | 395 | .open = ad198x_playback_pcm_open, |
492 | .prepare = ad198x_playback_pcm_prepare, | 396 | .prepare = ad198x_playback_pcm_prepare, |
493 | .cleanup = ad198x_playback_pcm_cleanup, | 397 | .cleanup = ad198x_playback_pcm_cleanup, |
494 | .close = ad198x_playback_pcm_close | ||
495 | }, | 398 | }, |
496 | }; | 399 | }; |
497 | 400 | ||
@@ -556,43 +459,19 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
556 | } | 459 | } |
557 | } | 460 | } |
558 | 461 | ||
559 | if (spec->alt_dac_nid && spec->stream_analog_alt_playback) { | ||
560 | codec->num_pcms++; | ||
561 | info = spec->pcm_rec + 2; | ||
562 | info->name = "AD198x Headphone"; | ||
563 | info->pcm_type = HDA_PCM_TYPE_AUDIO; | ||
564 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
565 | *spec->stream_analog_alt_playback; | ||
566 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
567 | spec->alt_dac_nid[0]; | ||
568 | } | ||
569 | |||
570 | return 0; | 462 | return 0; |
571 | } | 463 | } |
572 | 464 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | |
573 | static void ad198x_free_kctls(struct hda_codec *codec) | ||
574 | { | ||
575 | struct ad198x_spec *spec = codec->spec; | ||
576 | |||
577 | if (spec->kctls.list) { | ||
578 | struct snd_kcontrol_new *kctl = spec->kctls.list; | ||
579 | int i; | ||
580 | for (i = 0; i < spec->kctls.used; i++) | ||
581 | kfree(kctl[i].name); | ||
582 | } | ||
583 | snd_array_free(&spec->kctls); | ||
584 | } | ||
585 | 465 | ||
586 | static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, | 466 | static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, |
587 | hda_nid_t hp) | 467 | hda_nid_t hp) |
588 | { | 468 | { |
589 | struct ad198x_spec *spec = codec->spec; | ||
590 | if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) | 469 | if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) |
591 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, | 470 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, |
592 | !spec->inv_eapd ? 0x00 : 0x02); | 471 | !codec->inv_eapd ? 0x00 : 0x02); |
593 | if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) | 472 | if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) |
594 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, | 473 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, |
595 | !spec->inv_eapd ? 0x00 : 0x02); | 474 | !codec->inv_eapd ? 0x00 : 0x02); |
596 | } | 475 | } |
597 | 476 | ||
598 | static void ad198x_power_eapd(struct hda_codec *codec) | 477 | static void ad198x_power_eapd(struct hda_codec *codec) |
@@ -636,7 +515,7 @@ static void ad198x_free(struct hda_codec *codec) | |||
636 | if (!spec) | 515 | if (!spec) |
637 | return; | 516 | return; |
638 | 517 | ||
639 | ad198x_free_kctls(codec); | 518 | snd_hda_gen_spec_free(&spec->gen); |
640 | kfree(spec); | 519 | kfree(spec); |
641 | snd_hda_detach_beep_device(codec); | 520 | snd_hda_detach_beep_device(codec); |
642 | } | 521 | } |
@@ -649,6 +528,7 @@ static int ad198x_suspend(struct hda_codec *codec) | |||
649 | } | 528 | } |
650 | #endif | 529 | #endif |
651 | 530 | ||
531 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
652 | static const struct hda_codec_ops ad198x_patch_ops = { | 532 | static const struct hda_codec_ops ad198x_patch_ops = { |
653 | .build_controls = ad198x_build_controls, | 533 | .build_controls = ad198x_build_controls, |
654 | .build_pcms = ad198x_build_pcms, | 534 | .build_pcms = ad198x_build_pcms, |
@@ -673,7 +553,7 @@ static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, | |||
673 | { | 553 | { |
674 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 554 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
675 | struct ad198x_spec *spec = codec->spec; | 555 | struct ad198x_spec *spec = codec->spec; |
676 | if (spec->inv_eapd) | 556 | if (codec->inv_eapd) |
677 | ucontrol->value.integer.value[0] = ! spec->cur_eapd; | 557 | ucontrol->value.integer.value[0] = ! spec->cur_eapd; |
678 | else | 558 | else |
679 | ucontrol->value.integer.value[0] = spec->cur_eapd; | 559 | ucontrol->value.integer.value[0] = spec->cur_eapd; |
@@ -688,7 +568,7 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, | |||
688 | hda_nid_t nid = kcontrol->private_value & 0xff; | 568 | hda_nid_t nid = kcontrol->private_value & 0xff; |
689 | unsigned int eapd; | 569 | unsigned int eapd; |
690 | eapd = !!ucontrol->value.integer.value[0]; | 570 | eapd = !!ucontrol->value.integer.value[0]; |
691 | if (spec->inv_eapd) | 571 | if (codec->inv_eapd) |
692 | eapd = !eapd; | 572 | eapd = !eapd; |
693 | if (eapd == spec->cur_eapd) | 573 | if (eapd == spec->cur_eapd) |
694 | return 0; | 574 | return 0; |
@@ -705,12 +585,75 @@ static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, | |||
705 | struct snd_ctl_elem_value *ucontrol); | 585 | struct snd_ctl_elem_value *ucontrol); |
706 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | 586 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, |
707 | struct snd_ctl_elem_value *ucontrol); | 587 | struct snd_ctl_elem_value *ucontrol); |
588 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
589 | |||
590 | |||
591 | /* | ||
592 | * Automatic parse of I/O pins from the BIOS configuration | ||
593 | */ | ||
594 | |||
595 | static int ad198x_auto_build_controls(struct hda_codec *codec) | ||
596 | { | ||
597 | int err; | ||
598 | |||
599 | err = snd_hda_gen_build_controls(codec); | ||
600 | if (err < 0) | ||
601 | return err; | ||
602 | err = create_beep_ctls(codec); | ||
603 | if (err < 0) | ||
604 | return err; | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static const struct hda_codec_ops ad198x_auto_patch_ops = { | ||
609 | .build_controls = ad198x_auto_build_controls, | ||
610 | .build_pcms = snd_hda_gen_build_pcms, | ||
611 | .init = snd_hda_gen_init, | ||
612 | .free = ad198x_free, | ||
613 | .unsol_event = snd_hda_jack_unsol_event, | ||
614 | #ifdef CONFIG_PM | ||
615 | .check_power_status = snd_hda_gen_check_power_status, | ||
616 | .suspend = ad198x_suspend, | ||
617 | #endif | ||
618 | .reboot_notify = ad198x_shutup, | ||
619 | }; | ||
620 | |||
621 | |||
622 | static int ad198x_parse_auto_config(struct hda_codec *codec) | ||
623 | { | ||
624 | struct ad198x_spec *spec = codec->spec; | ||
625 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
626 | int err; | ||
627 | |||
628 | codec->spdif_status_reset = 1; | ||
629 | codec->no_trigger_sense = 1; | ||
630 | codec->no_sticky_stream = 1; | ||
631 | |||
632 | spec->gen.indep_hp = 1; | ||
633 | |||
634 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); | ||
635 | if (err < 0) | ||
636 | return err; | ||
637 | err = snd_hda_gen_parse_auto_config(codec, cfg); | ||
638 | if (err < 0) | ||
639 | return err; | ||
640 | |||
641 | if (spec->beep_dev_nid) { | ||
642 | err = snd_hda_attach_beep_device(codec, spec->beep_dev_nid); | ||
643 | if (err < 0) | ||
644 | return err; | ||
645 | } | ||
708 | 646 | ||
647 | codec->patch_ops = ad198x_auto_patch_ops; | ||
648 | |||
649 | return 0; | ||
650 | } | ||
709 | 651 | ||
710 | /* | 652 | /* |
711 | * AD1986A specific | 653 | * AD1986A specific |
712 | */ | 654 | */ |
713 | 655 | ||
656 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
714 | #define AD1986A_SPDIF_OUT 0x02 | 657 | #define AD1986A_SPDIF_OUT 0x02 |
715 | #define AD1986A_FRONT_DAC 0x03 | 658 | #define AD1986A_FRONT_DAC 0x03 |
716 | #define AD1986A_SURR_DAC 0x04 | 659 | #define AD1986A_SURR_DAC 0x04 |
@@ -995,15 +938,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
995 | struct snd_ctl_elem_value *ucontrol) | 938 | struct snd_ctl_elem_value *ucontrol) |
996 | { | 939 | { |
997 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 940 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
998 | long *valp = ucontrol->value.integer.value; | 941 | int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
999 | int change; | ||
1000 | |||
1001 | change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, | ||
1002 | HDA_AMP_MUTE, | ||
1003 | valp[0] ? 0 : HDA_AMP_MUTE); | ||
1004 | change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, | ||
1005 | HDA_AMP_MUTE, | ||
1006 | valp[1] ? 0 : HDA_AMP_MUTE); | ||
1007 | if (change) | 942 | if (change) |
1008 | ad1986a_update_hp(codec); | 943 | ad1986a_update_hp(codec); |
1009 | return change; | 944 | return change; |
@@ -1176,6 +1111,7 @@ static int ad1986a_samsung_p50_init(struct hda_codec *codec) | |||
1176 | 1111 | ||
1177 | /* models */ | 1112 | /* models */ |
1178 | enum { | 1113 | enum { |
1114 | AD1986A_AUTO, | ||
1179 | AD1986A_6STACK, | 1115 | AD1986A_6STACK, |
1180 | AD1986A_3STACK, | 1116 | AD1986A_3STACK, |
1181 | AD1986A_LAPTOP, | 1117 | AD1986A_LAPTOP, |
@@ -1188,6 +1124,7 @@ enum { | |||
1188 | }; | 1124 | }; |
1189 | 1125 | ||
1190 | static const char * const ad1986a_models[AD1986A_MODELS] = { | 1126 | static const char * const ad1986a_models[AD1986A_MODELS] = { |
1127 | [AD1986A_AUTO] = "auto", | ||
1191 | [AD1986A_6STACK] = "6stack", | 1128 | [AD1986A_6STACK] = "6stack", |
1192 | [AD1986A_3STACK] = "3stack", | 1129 | [AD1986A_3STACK] = "3stack", |
1193 | [AD1986A_LAPTOP] = "laptop", | 1130 | [AD1986A_LAPTOP] = "laptop", |
@@ -1245,6 +1182,7 @@ static int is_jack_available(struct hda_codec *codec, hda_nid_t nid) | |||
1245 | unsigned int conf = snd_hda_codec_get_pincfg(codec, nid); | 1182 | unsigned int conf = snd_hda_codec_get_pincfg(codec, nid); |
1246 | return get_defcfg_connect(conf) != AC_JACK_PORT_NONE; | 1183 | return get_defcfg_connect(conf) != AC_JACK_PORT_NONE; |
1247 | } | 1184 | } |
1185 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1248 | 1186 | ||
1249 | static int alloc_ad_spec(struct hda_codec *codec) | 1187 | static int alloc_ad_spec(struct hda_codec *codec) |
1250 | { | 1188 | { |
@@ -1254,15 +1192,97 @@ static int alloc_ad_spec(struct hda_codec *codec) | |||
1254 | if (!spec) | 1192 | if (!spec) |
1255 | return -ENOMEM; | 1193 | return -ENOMEM; |
1256 | codec->spec = spec; | 1194 | codec->spec = spec; |
1257 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | 1195 | snd_hda_gen_spec_init(&spec->gen); |
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | /* | ||
1200 | * AD1986A fixup codes | ||
1201 | */ | ||
1202 | |||
1203 | /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ | ||
1204 | static void ad_fixup_inv_jack_detect(struct hda_codec *codec, | ||
1205 | const struct hda_fixup *fix, int action) | ||
1206 | { | ||
1207 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
1208 | codec->inv_jack_detect = 1; | ||
1209 | } | ||
1210 | |||
1211 | enum { | ||
1212 | AD1986A_FIXUP_INV_JACK_DETECT, | ||
1213 | }; | ||
1214 | |||
1215 | static const struct hda_fixup ad1986a_fixups[] = { | ||
1216 | [AD1986A_FIXUP_INV_JACK_DETECT] = { | ||
1217 | .type = HDA_FIXUP_FUNC, | ||
1218 | .v.func = ad_fixup_inv_jack_detect, | ||
1219 | }, | ||
1220 | }; | ||
1221 | |||
1222 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | ||
1223 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), | ||
1224 | {} | ||
1225 | }; | ||
1226 | |||
1227 | /* | ||
1228 | */ | ||
1229 | static int ad1986a_parse_auto_config(struct hda_codec *codec) | ||
1230 | { | ||
1231 | int err; | ||
1232 | struct ad198x_spec *spec; | ||
1233 | |||
1234 | err = alloc_ad_spec(codec); | ||
1235 | if (err < 0) | ||
1236 | return err; | ||
1237 | spec = codec->spec; | ||
1238 | |||
1239 | /* AD1986A has the inverted EAPD implementation */ | ||
1240 | codec->inv_eapd = 1; | ||
1241 | |||
1242 | spec->gen.mixer_nid = 0x07; | ||
1243 | spec->beep_dev_nid = 0x19; | ||
1244 | set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); | ||
1245 | |||
1246 | /* AD1986A has a hardware problem that it can't share a stream | ||
1247 | * with multiple output pins. The copy of front to surrounds | ||
1248 | * causes noisy or silent outputs at a certain timing, e.g. | ||
1249 | * changing the volume. | ||
1250 | * So, let's disable the shared stream. | ||
1251 | */ | ||
1252 | spec->gen.multiout.no_share_stream = 1; | ||
1253 | |||
1254 | snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); | ||
1255 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
1256 | |||
1257 | err = ad198x_parse_auto_config(codec); | ||
1258 | if (err < 0) { | ||
1259 | ad198x_free(codec); | ||
1260 | return err; | ||
1261 | } | ||
1262 | |||
1263 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
1264 | |||
1258 | return 0; | 1265 | return 0; |
1259 | } | 1266 | } |
1260 | 1267 | ||
1268 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1261 | static int patch_ad1986a(struct hda_codec *codec) | 1269 | static int patch_ad1986a(struct hda_codec *codec) |
1262 | { | 1270 | { |
1263 | struct ad198x_spec *spec; | 1271 | struct ad198x_spec *spec; |
1264 | int err, board_config; | 1272 | int err, board_config; |
1265 | 1273 | ||
1274 | board_config = snd_hda_check_board_config(codec, AD1986A_MODELS, | ||
1275 | ad1986a_models, | ||
1276 | ad1986a_cfg_tbl); | ||
1277 | if (board_config < 0) { | ||
1278 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
1279 | codec->chip_name); | ||
1280 | board_config = AD1986A_AUTO; | ||
1281 | } | ||
1282 | |||
1283 | if (board_config == AD1986A_AUTO) | ||
1284 | return ad1986a_parse_auto_config(codec); | ||
1285 | |||
1266 | err = alloc_ad_spec(codec); | 1286 | err = alloc_ad_spec(codec); |
1267 | if (err < 0) | 1287 | if (err < 0) |
1268 | return err; | 1288 | return err; |
@@ -1291,14 +1311,11 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1291 | spec->loopback.amplist = ad1986a_loopbacks; | 1311 | spec->loopback.amplist = ad1986a_loopbacks; |
1292 | #endif | 1312 | #endif |
1293 | spec->vmaster_nid = 0x1b; | 1313 | spec->vmaster_nid = 0x1b; |
1294 | spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */ | 1314 | codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */ |
1295 | 1315 | ||
1296 | codec->patch_ops = ad198x_patch_ops; | 1316 | codec->patch_ops = ad198x_patch_ops; |
1297 | 1317 | ||
1298 | /* override some parameters */ | 1318 | /* override some parameters */ |
1299 | board_config = snd_hda_check_board_config(codec, AD1986A_MODELS, | ||
1300 | ad1986a_models, | ||
1301 | ad1986a_cfg_tbl); | ||
1302 | switch (board_config) { | 1319 | switch (board_config) { |
1303 | case AD1986A_3STACK: | 1320 | case AD1986A_3STACK: |
1304 | spec->num_mixers = 2; | 1321 | spec->num_mixers = 2; |
@@ -1409,11 +1426,15 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1409 | 1426 | ||
1410 | return 0; | 1427 | return 0; |
1411 | } | 1428 | } |
1429 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
1430 | #define patch_ad1986a ad1986a_parse_auto_config | ||
1431 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1412 | 1432 | ||
1413 | /* | 1433 | /* |
1414 | * AD1983 specific | 1434 | * AD1983 specific |
1415 | */ | 1435 | */ |
1416 | 1436 | ||
1437 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1417 | #define AD1983_SPDIF_OUT 0x02 | 1438 | #define AD1983_SPDIF_OUT 0x02 |
1418 | #define AD1983_DAC 0x03 | 1439 | #define AD1983_DAC 0x03 |
1419 | #define AD1983_ADC 0x04 | 1440 | #define AD1983_ADC 0x04 |
@@ -1554,11 +1575,137 @@ static const struct hda_amp_list ad1983_loopbacks[] = { | |||
1554 | }; | 1575 | }; |
1555 | #endif | 1576 | #endif |
1556 | 1577 | ||
1578 | /* models */ | ||
1579 | enum { | ||
1580 | AD1983_AUTO, | ||
1581 | AD1983_BASIC, | ||
1582 | AD1983_MODELS | ||
1583 | }; | ||
1584 | |||
1585 | static const char * const ad1983_models[AD1983_MODELS] = { | ||
1586 | [AD1983_AUTO] = "auto", | ||
1587 | [AD1983_BASIC] = "basic", | ||
1588 | }; | ||
1589 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1590 | |||
1591 | |||
1592 | /* | ||
1593 | * SPDIF mux control for AD1983 auto-parser | ||
1594 | */ | ||
1595 | static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol, | ||
1596 | struct snd_ctl_elem_info *uinfo) | ||
1597 | { | ||
1598 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1599 | struct ad198x_spec *spec = codec->spec; | ||
1600 | static const char * const texts2[] = { "PCM", "ADC" }; | ||
1601 | static const char * const texts3[] = { "PCM", "ADC1", "ADC2" }; | ||
1602 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | ||
1603 | int num_conns = snd_hda_get_num_conns(codec, dig_out); | ||
1604 | |||
1605 | if (num_conns == 2) | ||
1606 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2); | ||
1607 | else if (num_conns == 3) | ||
1608 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | ||
1609 | else | ||
1610 | return -EINVAL; | ||
1611 | } | ||
1612 | |||
1613 | static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol, | ||
1614 | struct snd_ctl_elem_value *ucontrol) | ||
1615 | { | ||
1616 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1617 | struct ad198x_spec *spec = codec->spec; | ||
1618 | |||
1619 | ucontrol->value.enumerated.item[0] = spec->cur_smux; | ||
1620 | return 0; | ||
1621 | } | ||
1622 | |||
1623 | static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, | ||
1624 | struct snd_ctl_elem_value *ucontrol) | ||
1625 | { | ||
1626 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1627 | struct ad198x_spec *spec = codec->spec; | ||
1628 | unsigned int val = ucontrol->value.enumerated.item[0]; | ||
1629 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | ||
1630 | int num_conns = snd_hda_get_num_conns(codec, dig_out); | ||
1631 | |||
1632 | if (val >= num_conns) | ||
1633 | return -EINVAL; | ||
1634 | if (spec->cur_smux == val) | ||
1635 | return 0; | ||
1636 | spec->cur_smux = val; | ||
1637 | snd_hda_codec_write_cache(codec, dig_out, 0, | ||
1638 | AC_VERB_SET_CONNECT_SEL, val); | ||
1639 | return 1; | ||
1640 | } | ||
1641 | |||
1642 | static struct snd_kcontrol_new ad1983_auto_smux_mixer = { | ||
1643 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1644 | .name = "IEC958 Playback Source", | ||
1645 | .info = ad1983_auto_smux_enum_info, | ||
1646 | .get = ad1983_auto_smux_enum_get, | ||
1647 | .put = ad1983_auto_smux_enum_put, | ||
1648 | }; | ||
1649 | |||
1650 | static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) | ||
1651 | { | ||
1652 | struct ad198x_spec *spec = codec->spec; | ||
1653 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | ||
1654 | int num_conns; | ||
1655 | |||
1656 | if (!dig_out) | ||
1657 | return 0; | ||
1658 | num_conns = snd_hda_get_num_conns(codec, dig_out); | ||
1659 | if (num_conns != 2 && num_conns != 3) | ||
1660 | return 0; | ||
1661 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer)) | ||
1662 | return -ENOMEM; | ||
1663 | return 0; | ||
1664 | } | ||
1665 | |||
1666 | static int ad1983_parse_auto_config(struct hda_codec *codec) | ||
1667 | { | ||
1668 | struct ad198x_spec *spec; | ||
1669 | int err; | ||
1670 | |||
1671 | err = alloc_ad_spec(codec); | ||
1672 | if (err < 0) | ||
1673 | return err; | ||
1674 | spec = codec->spec; | ||
1675 | |||
1676 | spec->beep_dev_nid = 0x10; | ||
1677 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | ||
1678 | err = ad198x_parse_auto_config(codec); | ||
1679 | if (err < 0) | ||
1680 | goto error; | ||
1681 | err = ad1983_add_spdif_mux_ctl(codec); | ||
1682 | if (err < 0) | ||
1683 | goto error; | ||
1684 | return 0; | ||
1685 | |||
1686 | error: | ||
1687 | ad198x_free(codec); | ||
1688 | return err; | ||
1689 | } | ||
1690 | |||
1691 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1557 | static int patch_ad1983(struct hda_codec *codec) | 1692 | static int patch_ad1983(struct hda_codec *codec) |
1558 | { | 1693 | { |
1559 | struct ad198x_spec *spec; | 1694 | struct ad198x_spec *spec; |
1695 | int board_config; | ||
1560 | int err; | 1696 | int err; |
1561 | 1697 | ||
1698 | board_config = snd_hda_check_board_config(codec, AD1983_MODELS, | ||
1699 | ad1983_models, NULL); | ||
1700 | if (board_config < 0) { | ||
1701 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
1702 | codec->chip_name); | ||
1703 | board_config = AD1983_AUTO; | ||
1704 | } | ||
1705 | |||
1706 | if (board_config == AD1983_AUTO) | ||
1707 | return ad1983_parse_auto_config(codec); | ||
1708 | |||
1562 | err = alloc_ad_spec(codec); | 1709 | err = alloc_ad_spec(codec); |
1563 | if (err < 0) | 1710 | if (err < 0) |
1564 | return err; | 1711 | return err; |
@@ -1596,12 +1743,16 @@ static int patch_ad1983(struct hda_codec *codec) | |||
1596 | 1743 | ||
1597 | return 0; | 1744 | return 0; |
1598 | } | 1745 | } |
1746 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
1747 | #define patch_ad1983 ad1983_parse_auto_config | ||
1748 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1599 | 1749 | ||
1600 | 1750 | ||
1601 | /* | 1751 | /* |
1602 | * AD1981 HD specific | 1752 | * AD1981 HD specific |
1603 | */ | 1753 | */ |
1604 | 1754 | ||
1755 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1605 | #define AD1981_SPDIF_OUT 0x02 | 1756 | #define AD1981_SPDIF_OUT 0x02 |
1606 | #define AD1981_DAC 0x03 | 1757 | #define AD1981_DAC 0x03 |
1607 | #define AD1981_ADC 0x04 | 1758 | #define AD1981_ADC 0x04 |
@@ -1932,6 +2083,7 @@ static const struct hda_input_mux ad1981_thinkpad_capture_source = { | |||
1932 | 2083 | ||
1933 | /* models */ | 2084 | /* models */ |
1934 | enum { | 2085 | enum { |
2086 | AD1981_AUTO, | ||
1935 | AD1981_BASIC, | 2087 | AD1981_BASIC, |
1936 | AD1981_HP, | 2088 | AD1981_HP, |
1937 | AD1981_THINKPAD, | 2089 | AD1981_THINKPAD, |
@@ -1940,6 +2092,7 @@ enum { | |||
1940 | }; | 2092 | }; |
1941 | 2093 | ||
1942 | static const char * const ad1981_models[AD1981_MODELS] = { | 2094 | static const char * const ad1981_models[AD1981_MODELS] = { |
2095 | [AD1981_AUTO] = "auto", | ||
1943 | [AD1981_HP] = "hp", | 2096 | [AD1981_HP] = "hp", |
1944 | [AD1981_THINKPAD] = "thinkpad", | 2097 | [AD1981_THINKPAD] = "thinkpad", |
1945 | [AD1981_BASIC] = "basic", | 2098 | [AD1981_BASIC] = "basic", |
@@ -1958,12 +2111,122 @@ static const struct snd_pci_quirk ad1981_cfg_tbl[] = { | |||
1958 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), | 2111 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), |
1959 | {} | 2112 | {} |
1960 | }; | 2113 | }; |
2114 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2115 | |||
2116 | |||
2117 | /* follow EAPD via vmaster hook */ | ||
2118 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) | ||
2119 | { | ||
2120 | struct hda_codec *codec = private_data; | ||
2121 | struct ad198x_spec *spec = codec->spec; | ||
2122 | snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, | ||
2123 | AC_VERB_SET_EAPD_BTLENABLE, | ||
2124 | enabled ? 0x02 : 0x00); | ||
2125 | } | ||
2126 | |||
2127 | static void ad1981_fixup_hp_eapd(struct hda_codec *codec, | ||
2128 | const struct hda_fixup *fix, int action) | ||
2129 | { | ||
2130 | struct ad198x_spec *spec = codec->spec; | ||
2131 | |||
2132 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2133 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | ||
2134 | spec->eapd_nid = 0x05; | ||
2135 | } | ||
2136 | } | ||
2137 | |||
2138 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | ||
2139 | * damage by overloading | ||
2140 | */ | ||
2141 | static void ad1981_fixup_amp_override(struct hda_codec *codec, | ||
2142 | const struct hda_fixup *fix, int action) | ||
2143 | { | ||
2144 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2145 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
2146 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2147 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2148 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2149 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
2150 | } | ||
2151 | |||
2152 | enum { | ||
2153 | AD1981_FIXUP_AMP_OVERRIDE, | ||
2154 | AD1981_FIXUP_HP_EAPD, | ||
2155 | }; | ||
2156 | |||
2157 | static const struct hda_fixup ad1981_fixups[] = { | ||
2158 | [AD1981_FIXUP_AMP_OVERRIDE] = { | ||
2159 | .type = HDA_FIXUP_FUNC, | ||
2160 | .v.func = ad1981_fixup_amp_override, | ||
2161 | }, | ||
2162 | [AD1981_FIXUP_HP_EAPD] = { | ||
2163 | .type = HDA_FIXUP_FUNC, | ||
2164 | .v.func = ad1981_fixup_hp_eapd, | ||
2165 | .chained = true, | ||
2166 | .chain_id = AD1981_FIXUP_AMP_OVERRIDE, | ||
2167 | }, | ||
2168 | }; | ||
2169 | |||
2170 | static const struct snd_pci_quirk ad1981_fixup_tbl[] = { | ||
2171 | SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | ||
2172 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD), | ||
2173 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | ||
2174 | /* HP nx6320 (reversed SSID, H/W bug) */ | ||
2175 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD), | ||
2176 | {} | ||
2177 | }; | ||
2178 | |||
2179 | static int ad1981_parse_auto_config(struct hda_codec *codec) | ||
2180 | { | ||
2181 | struct ad198x_spec *spec; | ||
2182 | int err; | ||
1961 | 2183 | ||
2184 | err = alloc_ad_spec(codec); | ||
2185 | if (err < 0) | ||
2186 | return -ENOMEM; | ||
2187 | spec = codec->spec; | ||
2188 | |||
2189 | spec->gen.mixer_nid = 0x0e; | ||
2190 | spec->beep_dev_nid = 0x10; | ||
2191 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); | ||
2192 | |||
2193 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); | ||
2194 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
2195 | |||
2196 | err = ad198x_parse_auto_config(codec); | ||
2197 | if (err < 0) | ||
2198 | goto error; | ||
2199 | err = ad1983_add_spdif_mux_ctl(codec); | ||
2200 | if (err < 0) | ||
2201 | goto error; | ||
2202 | |||
2203 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
2204 | |||
2205 | return 0; | ||
2206 | |||
2207 | error: | ||
2208 | ad198x_free(codec); | ||
2209 | return err; | ||
2210 | } | ||
2211 | |||
2212 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1962 | static int patch_ad1981(struct hda_codec *codec) | 2213 | static int patch_ad1981(struct hda_codec *codec) |
1963 | { | 2214 | { |
1964 | struct ad198x_spec *spec; | 2215 | struct ad198x_spec *spec; |
1965 | int err, board_config; | 2216 | int err, board_config; |
1966 | 2217 | ||
2218 | board_config = snd_hda_check_board_config(codec, AD1981_MODELS, | ||
2219 | ad1981_models, | ||
2220 | ad1981_cfg_tbl); | ||
2221 | if (board_config < 0) { | ||
2222 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
2223 | codec->chip_name); | ||
2224 | board_config = AD1981_AUTO; | ||
2225 | } | ||
2226 | |||
2227 | if (board_config == AD1981_AUTO) | ||
2228 | return ad1981_parse_auto_config(codec); | ||
2229 | |||
1967 | err = alloc_ad_spec(codec); | 2230 | err = alloc_ad_spec(codec); |
1968 | if (err < 0) | 2231 | if (err < 0) |
1969 | return -ENOMEM; | 2232 | return -ENOMEM; |
@@ -1997,9 +2260,6 @@ static int patch_ad1981(struct hda_codec *codec) | |||
1997 | codec->patch_ops = ad198x_patch_ops; | 2260 | codec->patch_ops = ad198x_patch_ops; |
1998 | 2261 | ||
1999 | /* override some parameters */ | 2262 | /* override some parameters */ |
2000 | board_config = snd_hda_check_board_config(codec, AD1981_MODELS, | ||
2001 | ad1981_models, | ||
2002 | ad1981_cfg_tbl); | ||
2003 | switch (board_config) { | 2263 | switch (board_config) { |
2004 | case AD1981_HP: | 2264 | case AD1981_HP: |
2005 | spec->mixers[0] = ad1981_hp_mixers; | 2265 | spec->mixers[0] = ad1981_hp_mixers; |
@@ -2049,6 +2309,9 @@ static int patch_ad1981(struct hda_codec *codec) | |||
2049 | 2309 | ||
2050 | return 0; | 2310 | return 0; |
2051 | } | 2311 | } |
2312 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
2313 | #define patch_ad1981 ad1981_parse_auto_config | ||
2314 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2052 | 2315 | ||
2053 | 2316 | ||
2054 | /* | 2317 | /* |
@@ -2137,15 +2400,16 @@ static int patch_ad1981(struct hda_codec *codec) | |||
2137 | */ | 2400 | */ |
2138 | 2401 | ||
2139 | 2402 | ||
2403 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
2140 | /* models */ | 2404 | /* models */ |
2141 | enum { | 2405 | enum { |
2406 | AD1988_AUTO, | ||
2142 | AD1988_6STACK, | 2407 | AD1988_6STACK, |
2143 | AD1988_6STACK_DIG, | 2408 | AD1988_6STACK_DIG, |
2144 | AD1988_3STACK, | 2409 | AD1988_3STACK, |
2145 | AD1988_3STACK_DIG, | 2410 | AD1988_3STACK_DIG, |
2146 | AD1988_LAPTOP, | 2411 | AD1988_LAPTOP, |
2147 | AD1988_LAPTOP_DIG, | 2412 | AD1988_LAPTOP_DIG, |
2148 | AD1988_AUTO, | ||
2149 | AD1988_MODEL_LAST, | 2413 | AD1988_MODEL_LAST, |
2150 | }; | 2414 | }; |
2151 | 2415 | ||
@@ -2250,17 +2514,6 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
2250 | return err; | 2514 | return err; |
2251 | } | 2515 | } |
2252 | 2516 | ||
2253 | static const struct snd_kcontrol_new ad1988_hp_mixers[] = { | ||
2254 | { | ||
2255 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2256 | .name = "Independent HP", | ||
2257 | .info = ad1988_independent_hp_info, | ||
2258 | .get = ad1988_independent_hp_get, | ||
2259 | .put = ad1988_independent_hp_put, | ||
2260 | }, | ||
2261 | { } /* end */ | ||
2262 | }; | ||
2263 | |||
2264 | /* 6-stack mode */ | 2517 | /* 6-stack mode */ |
2265 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | 2518 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { |
2266 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2519 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
@@ -2823,421 +3076,185 @@ static const struct hda_amp_list ad1988_loopbacks[] = { | |||
2823 | { } /* end */ | 3076 | { } /* end */ |
2824 | }; | 3077 | }; |
2825 | #endif | 3078 | #endif |
3079 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2826 | 3080 | ||
2827 | /* | 3081 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, |
2828 | * Automatic parse of I/O pins from the BIOS configuration | 3082 | struct snd_ctl_elem_info *uinfo) |
2829 | */ | ||
2830 | |||
2831 | enum { | ||
2832 | AD_CTL_WIDGET_VOL, | ||
2833 | AD_CTL_WIDGET_MUTE, | ||
2834 | AD_CTL_BIND_MUTE, | ||
2835 | }; | ||
2836 | static const struct snd_kcontrol_new ad1988_control_templates[] = { | ||
2837 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
2838 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
2839 | HDA_BIND_MUTE(NULL, 0, 0, 0), | ||
2840 | }; | ||
2841 | |||
2842 | /* add dynamic controls */ | ||
2843 | static int add_control(struct ad198x_spec *spec, int type, const char *name, | ||
2844 | unsigned long val) | ||
2845 | { | ||
2846 | struct snd_kcontrol_new *knew; | ||
2847 | |||
2848 | knew = snd_array_new(&spec->kctls); | ||
2849 | if (!knew) | ||
2850 | return -ENOMEM; | ||
2851 | *knew = ad1988_control_templates[type]; | ||
2852 | knew->name = kstrdup(name, GFP_KERNEL); | ||
2853 | if (! knew->name) | ||
2854 | return -ENOMEM; | ||
2855 | if (get_amp_nid_(val)) | ||
2856 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
2857 | knew->private_value = val; | ||
2858 | return 0; | ||
2859 | } | ||
2860 | |||
2861 | #define AD1988_PIN_CD_NID 0x18 | ||
2862 | #define AD1988_PIN_BEEP_NID 0x10 | ||
2863 | |||
2864 | static const hda_nid_t ad1988_mixer_nids[8] = { | ||
2865 | /* A B C D E F G H */ | ||
2866 | 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 | ||
2867 | }; | ||
2868 | |||
2869 | static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) | ||
2870 | { | ||
2871 | static const hda_nid_t idx_to_dac[8] = { | ||
2872 | /* A B C D E F G H */ | ||
2873 | 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a | ||
2874 | }; | ||
2875 | static const hda_nid_t idx_to_dac_rev2[8] = { | ||
2876 | /* A B C D E F G H */ | ||
2877 | 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 | ||
2878 | }; | ||
2879 | if (is_rev2(codec)) | ||
2880 | return idx_to_dac_rev2[idx]; | ||
2881 | else | ||
2882 | return idx_to_dac[idx]; | ||
2883 | } | ||
2884 | |||
2885 | static const hda_nid_t ad1988_boost_nids[8] = { | ||
2886 | 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 | ||
2887 | }; | ||
2888 | |||
2889 | static int ad1988_pin_idx(hda_nid_t nid) | ||
2890 | { | ||
2891 | static const hda_nid_t ad1988_io_pins[8] = { | ||
2892 | 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 | ||
2893 | }; | ||
2894 | int i; | ||
2895 | for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++) | ||
2896 | if (ad1988_io_pins[i] == nid) | ||
2897 | return i; | ||
2898 | return 0; /* should be -1 */ | ||
2899 | } | ||
2900 | |||
2901 | static int ad1988_pin_to_loopback_idx(hda_nid_t nid) | ||
2902 | { | 3083 | { |
2903 | static const int loopback_idx[8] = { | 3084 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2904 | 2, 0, 1, 3, 4, 5, 1, 4 | 3085 | static const char * const texts[] = { |
2905 | }; | 3086 | "PCM", "ADC1", "ADC2", "ADC3", |
2906 | switch (nid) { | ||
2907 | case AD1988_PIN_CD_NID: | ||
2908 | return 6; | ||
2909 | default: | ||
2910 | return loopback_idx[ad1988_pin_idx(nid)]; | ||
2911 | } | ||
2912 | } | ||
2913 | |||
2914 | static int ad1988_pin_to_adc_idx(hda_nid_t nid) | ||
2915 | { | ||
2916 | static const int adc_idx[8] = { | ||
2917 | 0, 1, 2, 8, 4, 3, 6, 7 | ||
2918 | }; | 3087 | }; |
2919 | switch (nid) { | 3088 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
2920 | case AD1988_PIN_CD_NID: | 3089 | if (num_conns > 4) |
2921 | return 5; | 3090 | num_conns = 4; |
2922 | default: | 3091 | return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts); |
2923 | return adc_idx[ad1988_pin_idx(nid)]; | ||
2924 | } | ||
2925 | } | 3092 | } |
2926 | 3093 | ||
2927 | /* fill in the dac_nids table from the parsed pin configuration */ | 3094 | static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol, |
2928 | static int ad1988_auto_fill_dac_nids(struct hda_codec *codec, | 3095 | struct snd_ctl_elem_value *ucontrol) |
2929 | const struct auto_pin_cfg *cfg) | ||
2930 | { | 3096 | { |
3097 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2931 | struct ad198x_spec *spec = codec->spec; | 3098 | struct ad198x_spec *spec = codec->spec; |
2932 | int i, idx; | ||
2933 | 3099 | ||
2934 | spec->multiout.dac_nids = spec->private_dac_nids; | 3100 | ucontrol->value.enumerated.item[0] = spec->cur_smux; |
2935 | |||
2936 | /* check the pins hardwired to audio widget */ | ||
2937 | for (i = 0; i < cfg->line_outs; i++) { | ||
2938 | idx = ad1988_pin_idx(cfg->line_out_pins[i]); | ||
2939 | spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx); | ||
2940 | } | ||
2941 | spec->multiout.num_dacs = cfg->line_outs; | ||
2942 | return 0; | 3101 | return 0; |
2943 | } | 3102 | } |
2944 | 3103 | ||
2945 | /* add playback controls from the parsed DAC table */ | 3104 | static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, |
2946 | static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec, | 3105 | struct snd_ctl_elem_value *ucontrol) |
2947 | const struct auto_pin_cfg *cfg) | ||
2948 | { | ||
2949 | char name[32]; | ||
2950 | static const char * const chname[4] = { | ||
2951 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
2952 | }; | ||
2953 | hda_nid_t nid; | ||
2954 | int i, err; | ||
2955 | |||
2956 | for (i = 0; i < cfg->line_outs; i++) { | ||
2957 | hda_nid_t dac = spec->multiout.dac_nids[i]; | ||
2958 | if (! dac) | ||
2959 | continue; | ||
2960 | nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])]; | ||
2961 | if (i == 2) { | ||
2962 | /* Center/LFE */ | ||
2963 | err = add_control(spec, AD_CTL_WIDGET_VOL, | ||
2964 | "Center Playback Volume", | ||
2965 | HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT)); | ||
2966 | if (err < 0) | ||
2967 | return err; | ||
2968 | err = add_control(spec, AD_CTL_WIDGET_VOL, | ||
2969 | "LFE Playback Volume", | ||
2970 | HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT)); | ||
2971 | if (err < 0) | ||
2972 | return err; | ||
2973 | err = add_control(spec, AD_CTL_BIND_MUTE, | ||
2974 | "Center Playback Switch", | ||
2975 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT)); | ||
2976 | if (err < 0) | ||
2977 | return err; | ||
2978 | err = add_control(spec, AD_CTL_BIND_MUTE, | ||
2979 | "LFE Playback Switch", | ||
2980 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT)); | ||
2981 | if (err < 0) | ||
2982 | return err; | ||
2983 | } else { | ||
2984 | sprintf(name, "%s Playback Volume", chname[i]); | ||
2985 | err = add_control(spec, AD_CTL_WIDGET_VOL, name, | ||
2986 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT)); | ||
2987 | if (err < 0) | ||
2988 | return err; | ||
2989 | sprintf(name, "%s Playback Switch", chname[i]); | ||
2990 | err = add_control(spec, AD_CTL_BIND_MUTE, name, | ||
2991 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); | ||
2992 | if (err < 0) | ||
2993 | return err; | ||
2994 | } | ||
2995 | } | ||
2996 | return 0; | ||
2997 | } | ||
2998 | |||
2999 | /* add playback controls for speaker and HP outputs */ | ||
3000 | static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | ||
3001 | const char *pfx) | ||
3002 | { | 3106 | { |
3107 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3003 | struct ad198x_spec *spec = codec->spec; | 3108 | struct ad198x_spec *spec = codec->spec; |
3004 | hda_nid_t nid; | 3109 | unsigned int val = ucontrol->value.enumerated.item[0]; |
3005 | int i, idx, err; | 3110 | struct nid_path *path; |
3006 | char name[32]; | 3111 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
3007 | 3112 | ||
3008 | if (! pin) | 3113 | if (val >= num_conns) |
3114 | return -EINVAL; | ||
3115 | if (spec->cur_smux == val) | ||
3009 | return 0; | 3116 | return 0; |
3010 | 3117 | ||
3011 | idx = ad1988_pin_idx(pin); | 3118 | mutex_lock(&codec->control_mutex); |
3012 | nid = ad1988_idx_to_dac(codec, idx); | 3119 | codec->cached_write = 1; |
3013 | /* check whether the corresponding DAC was already taken */ | 3120 | path = snd_hda_get_path_from_idx(codec, |
3014 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 3121 | spec->smux_paths[spec->cur_smux]); |
3015 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 3122 | if (path) |
3016 | hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin)); | 3123 | snd_hda_activate_path(codec, path, false, true); |
3017 | if (dac == nid) | 3124 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]); |
3018 | break; | 3125 | if (path) |
3019 | } | 3126 | snd_hda_activate_path(codec, path, true, true); |
3020 | if (i >= spec->autocfg.line_outs) { | 3127 | spec->cur_smux = val; |
3021 | /* specify the DAC as the extra output */ | 3128 | codec->cached_write = 0; |
3022 | if (!spec->multiout.hp_nid) | 3129 | mutex_unlock(&codec->control_mutex); |
3023 | spec->multiout.hp_nid = nid; | 3130 | snd_hda_codec_flush_cache(codec); /* flush the updates */ |
3024 | else | 3131 | return 1; |
3025 | spec->multiout.extra_out_nid[0] = nid; | ||
3026 | /* control HP volume/switch on the output mixer amp */ | ||
3027 | sprintf(name, "%s Playback Volume", pfx); | ||
3028 | err = add_control(spec, AD_CTL_WIDGET_VOL, name, | ||
3029 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
3030 | if (err < 0) | ||
3031 | return err; | ||
3032 | } | ||
3033 | nid = ad1988_mixer_nids[idx]; | ||
3034 | sprintf(name, "%s Playback Switch", pfx); | ||
3035 | if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, | ||
3036 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) | ||
3037 | return err; | ||
3038 | return 0; | ||
3039 | } | 3132 | } |
3040 | 3133 | ||
3041 | /* create input playback/capture controls for the given pin */ | 3134 | static struct snd_kcontrol_new ad1988_auto_smux_mixer = { |
3042 | static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin, | 3135 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
3043 | const char *ctlname, int ctlidx, int boost) | 3136 | .name = "IEC958 Playback Source", |
3137 | .info = ad1988_auto_smux_enum_info, | ||
3138 | .get = ad1988_auto_smux_enum_get, | ||
3139 | .put = ad1988_auto_smux_enum_put, | ||
3140 | }; | ||
3141 | |||
3142 | static int ad1988_auto_init(struct hda_codec *codec) | ||
3044 | { | 3143 | { |
3045 | char name[32]; | 3144 | struct ad198x_spec *spec = codec->spec; |
3046 | int err, idx; | 3145 | int i, err; |
3047 | 3146 | ||
3048 | sprintf(name, "%s Playback Volume", ctlname); | 3147 | err = snd_hda_gen_init(codec); |
3049 | idx = ad1988_pin_to_loopback_idx(pin); | 3148 | if (err < 0) |
3050 | if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, | ||
3051 | HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) | ||
3052 | return err; | ||
3053 | sprintf(name, "%s Playback Switch", ctlname); | ||
3054 | if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name, | ||
3055 | HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) | ||
3056 | return err; | 3149 | return err; |
3057 | if (boost) { | 3150 | if (!spec->gen.autocfg.dig_outs) |
3058 | hda_nid_t bnid; | 3151 | return 0; |
3059 | idx = ad1988_pin_idx(pin); | ||
3060 | bnid = ad1988_boost_nids[idx]; | ||
3061 | if (bnid) { | ||
3062 | sprintf(name, "%s Boost Volume", ctlname); | ||
3063 | return add_control(spec, AD_CTL_WIDGET_VOL, name, | ||
3064 | HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); | ||
3065 | 3152 | ||
3066 | } | 3153 | for (i = 0; i < 4; i++) { |
3154 | struct nid_path *path; | ||
3155 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]); | ||
3156 | if (path) | ||
3157 | snd_hda_activate_path(codec, path, path->active, false); | ||
3067 | } | 3158 | } |
3159 | |||
3068 | return 0; | 3160 | return 0; |
3069 | } | 3161 | } |
3070 | 3162 | ||
3071 | /* create playback/capture controls for input pins */ | 3163 | static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec) |
3072 | static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec, | ||
3073 | const struct auto_pin_cfg *cfg) | ||
3074 | { | 3164 | { |
3075 | struct ad198x_spec *spec = codec->spec; | 3165 | struct ad198x_spec *spec = codec->spec; |
3076 | struct hda_input_mux *imux = &spec->private_imux; | 3166 | int i, num_conns; |
3077 | int i, err, type, type_idx; | 3167 | /* we create four static faked paths, since AD codecs have odd |
3078 | 3168 | * widget connections regarding the SPDIF out source | |
3079 | for (i = 0; i < cfg->num_inputs; i++) { | 3169 | */ |
3080 | const char *label; | 3170 | static struct nid_path fake_paths[4] = { |
3081 | type = cfg->inputs[i].type; | 3171 | { |
3082 | label = hda_get_autocfg_input_label(codec, cfg, i); | 3172 | .depth = 3, |
3083 | snd_hda_add_imux_item(imux, label, | 3173 | .path = { 0x02, 0x1d, 0x1b }, |
3084 | ad1988_pin_to_adc_idx(cfg->inputs[i].pin), | 3174 | .idx = { 0, 0, 0 }, |
3085 | &type_idx); | 3175 | .multi = { 0, 0, 0 }, |
3086 | err = new_analog_input(spec, cfg->inputs[i].pin, | 3176 | }, |
3087 | label, type_idx, | 3177 | { |
3088 | type == AUTO_PIN_MIC); | 3178 | .depth = 4, |
3089 | if (err < 0) | 3179 | .path = { 0x08, 0x0b, 0x1d, 0x1b }, |
3090 | return err; | 3180 | .idx = { 0, 0, 1, 0 }, |
3091 | } | 3181 | .multi = { 0, 1, 0, 0 }, |
3092 | snd_hda_add_imux_item(imux, "Mix", 9, NULL); | 3182 | }, |
3183 | { | ||
3184 | .depth = 4, | ||
3185 | .path = { 0x09, 0x0b, 0x1d, 0x1b }, | ||
3186 | .idx = { 0, 1, 1, 0 }, | ||
3187 | .multi = { 0, 1, 0, 0 }, | ||
3188 | }, | ||
3189 | { | ||
3190 | .depth = 4, | ||
3191 | .path = { 0x0f, 0x0b, 0x1d, 0x1b }, | ||
3192 | .idx = { 0, 2, 1, 0 }, | ||
3193 | .multi = { 0, 1, 0, 0 }, | ||
3194 | }, | ||
3195 | }; | ||
3093 | 3196 | ||
3094 | if ((err = add_control(spec, AD_CTL_WIDGET_VOL, | 3197 | /* SPDIF source mux appears to be present only on AD1988A */ |
3095 | "Analog Mix Playback Volume", | 3198 | if (!spec->gen.autocfg.dig_outs || |
3096 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) | 3199 | get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX) |
3097 | return err; | 3200 | return 0; |
3098 | if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, | ||
3099 | "Analog Mix Playback Switch", | ||
3100 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) | ||
3101 | return err; | ||
3102 | 3201 | ||
3103 | return 0; | 3202 | num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
3104 | } | 3203 | if (num_conns != 3 && num_conns != 4) |
3204 | return 0; | ||
3105 | 3205 | ||
3106 | static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec, | 3206 | for (i = 0; i < num_conns; i++) { |
3107 | hda_nid_t nid, int pin_type, | 3207 | struct nid_path *path = snd_array_new(&spec->gen.paths); |
3108 | int dac_idx) | 3208 | if (!path) |
3109 | { | 3209 | return -ENOMEM; |
3110 | /* set as output */ | 3210 | *path = fake_paths[i]; |
3111 | snd_hda_set_pin_ctl(codec, nid, pin_type); | 3211 | if (!i) |
3112 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 3212 | path->active = 1; |
3113 | switch (nid) { | 3213 | spec->smux_paths[i] = snd_hda_get_path_idx(codec, path); |
3114 | case 0x11: /* port-A - DAC 03 */ | ||
3115 | snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00); | ||
3116 | break; | ||
3117 | case 0x14: /* port-B - DAC 06 */ | ||
3118 | snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); | ||
3119 | break; | ||
3120 | case 0x15: /* port-C - DAC 05 */ | ||
3121 | snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00); | ||
3122 | break; | ||
3123 | case 0x17: /* port-E - DAC 0a */ | ||
3124 | snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01); | ||
3125 | break; | ||
3126 | case 0x13: /* mono - DAC 04 */ | ||
3127 | snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01); | ||
3128 | break; | ||
3129 | } | 3214 | } |
3130 | } | ||
3131 | 3215 | ||
3132 | static void ad1988_auto_init_multi_out(struct hda_codec *codec) | 3216 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer)) |
3133 | { | 3217 | return -ENOMEM; |
3134 | struct ad198x_spec *spec = codec->spec; | ||
3135 | int i; | ||
3136 | 3218 | ||
3137 | for (i = 0; i < spec->autocfg.line_outs; i++) { | 3219 | codec->patch_ops.init = ad1988_auto_init; |
3138 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
3139 | ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | ||
3140 | } | ||
3141 | } | ||
3142 | 3220 | ||
3143 | static void ad1988_auto_init_extra_out(struct hda_codec *codec) | 3221 | return 0; |
3144 | { | ||
3145 | struct ad198x_spec *spec = codec->spec; | ||
3146 | hda_nid_t pin; | ||
3147 | |||
3148 | pin = spec->autocfg.speaker_pins[0]; | ||
3149 | if (pin) /* connect to front */ | ||
3150 | ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | ||
3151 | pin = spec->autocfg.hp_pins[0]; | ||
3152 | if (pin) /* connect to front */ | ||
3153 | ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
3154 | } | 3222 | } |
3155 | 3223 | ||
3156 | static void ad1988_auto_init_analog_input(struct hda_codec *codec) | 3224 | /* |
3157 | { | 3225 | */ |
3158 | struct ad198x_spec *spec = codec->spec; | ||
3159 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3160 | int i, idx; | ||
3161 | |||
3162 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3163 | hda_nid_t nid = cfg->inputs[i].pin; | ||
3164 | int type = cfg->inputs[i].type; | ||
3165 | int val; | ||
3166 | switch (nid) { | ||
3167 | case 0x15: /* port-C */ | ||
3168 | snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); | ||
3169 | break; | ||
3170 | case 0x17: /* port-E */ | ||
3171 | snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0); | ||
3172 | break; | ||
3173 | } | ||
3174 | val = PIN_IN; | ||
3175 | if (type == AUTO_PIN_MIC) | ||
3176 | val |= snd_hda_get_default_vref(codec, nid); | ||
3177 | snd_hda_set_pin_ctl(codec, nid, val); | ||
3178 | if (nid != AD1988_PIN_CD_NID) | ||
3179 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3180 | AMP_OUT_MUTE); | ||
3181 | idx = ad1988_pin_idx(nid); | ||
3182 | if (ad1988_boost_nids[idx]) | ||
3183 | snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0, | ||
3184 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
3185 | AMP_OUT_ZERO); | ||
3186 | } | ||
3187 | } | ||
3188 | 3226 | ||
3189 | /* parse the BIOS configuration and set up the alc_spec */ | ||
3190 | /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ | ||
3191 | static int ad1988_parse_auto_config(struct hda_codec *codec) | 3227 | static int ad1988_parse_auto_config(struct hda_codec *codec) |
3192 | { | 3228 | { |
3193 | struct ad198x_spec *spec = codec->spec; | 3229 | struct ad198x_spec *spec; |
3194 | int err; | 3230 | int err; |
3195 | 3231 | ||
3196 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) | 3232 | err = alloc_ad_spec(codec); |
3197 | return err; | 3233 | if (err < 0) |
3198 | if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | ||
3199 | return err; | ||
3200 | if (! spec->autocfg.line_outs) | ||
3201 | return 0; /* can't find valid BIOS pin config */ | ||
3202 | if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | ||
3203 | (err = ad1988_auto_create_extra_out(codec, | ||
3204 | spec->autocfg.speaker_pins[0], | ||
3205 | "Speaker")) < 0 || | ||
3206 | (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], | ||
3207 | "Headphone")) < 0 || | ||
3208 | (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) | ||
3209 | return err; | 3234 | return err; |
3235 | spec = codec->spec; | ||
3210 | 3236 | ||
3211 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3237 | spec->gen.mixer_nid = 0x20; |
3212 | 3238 | spec->gen.mixer_merge_nid = 0x21; | |
3213 | if (spec->autocfg.dig_outs) | 3239 | spec->beep_dev_nid = 0x10; |
3214 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | 3240 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
3215 | if (spec->autocfg.dig_in_pin) | 3241 | err = ad198x_parse_auto_config(codec); |
3216 | spec->dig_in_nid = AD1988_SPDIF_IN; | 3242 | if (err < 0) |
3217 | 3243 | goto error; | |
3218 | if (spec->kctls.list) | 3244 | err = ad1988_add_spdif_mux_ctl(codec); |
3219 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | 3245 | if (err < 0) |
3220 | 3246 | goto error; | |
3221 | spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; | ||
3222 | |||
3223 | spec->input_mux = &spec->private_imux; | ||
3224 | |||
3225 | return 1; | ||
3226 | } | ||
3227 | |||
3228 | /* init callback for auto-configuration model -- overriding the default init */ | ||
3229 | static int ad1988_auto_init(struct hda_codec *codec) | ||
3230 | { | ||
3231 | ad198x_init(codec); | ||
3232 | ad1988_auto_init_multi_out(codec); | ||
3233 | ad1988_auto_init_extra_out(codec); | ||
3234 | ad1988_auto_init_analog_input(codec); | ||
3235 | return 0; | 3247 | return 0; |
3248 | |||
3249 | error: | ||
3250 | ad198x_free(codec); | ||
3251 | return err; | ||
3236 | } | 3252 | } |
3237 | 3253 | ||
3238 | /* | 3254 | /* |
3239 | */ | 3255 | */ |
3240 | 3256 | ||
3257 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
3241 | static const char * const ad1988_models[AD1988_MODEL_LAST] = { | 3258 | static const char * const ad1988_models[AD1988_MODEL_LAST] = { |
3242 | [AD1988_6STACK] = "6stack", | 3259 | [AD1988_6STACK] = "6stack", |
3243 | [AD1988_6STACK_DIG] = "6stack-dig", | 3260 | [AD1988_6STACK_DIG] = "6stack-dig", |
@@ -3262,14 +3279,6 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3262 | struct ad198x_spec *spec; | 3279 | struct ad198x_spec *spec; |
3263 | int err, board_config; | 3280 | int err, board_config; |
3264 | 3281 | ||
3265 | err = alloc_ad_spec(codec); | ||
3266 | if (err < 0) | ||
3267 | return err; | ||
3268 | spec = codec->spec; | ||
3269 | |||
3270 | if (is_rev2(codec)) | ||
3271 | snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); | ||
3272 | |||
3273 | board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, | 3282 | board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, |
3274 | ad1988_models, ad1988_cfg_tbl); | 3283 | ad1988_models, ad1988_cfg_tbl); |
3275 | if (board_config < 0) { | 3284 | if (board_config < 0) { |
@@ -3278,17 +3287,16 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3278 | board_config = AD1988_AUTO; | 3287 | board_config = AD1988_AUTO; |
3279 | } | 3288 | } |
3280 | 3289 | ||
3281 | if (board_config == AD1988_AUTO) { | 3290 | if (board_config == AD1988_AUTO) |
3282 | /* automatic parse from the BIOS config */ | 3291 | return ad1988_parse_auto_config(codec); |
3283 | err = ad1988_parse_auto_config(codec); | 3292 | |
3284 | if (err < 0) { | 3293 | err = alloc_ad_spec(codec); |
3285 | ad198x_free(codec); | 3294 | if (err < 0) |
3286 | return err; | 3295 | return err; |
3287 | } else if (! err) { | 3296 | spec = codec->spec; |
3288 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n"); | 3297 | |
3289 | board_config = AD1988_6STACK; | 3298 | if (is_rev2(codec)) |
3290 | } | 3299 | snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); |
3291 | } | ||
3292 | 3300 | ||
3293 | err = snd_hda_attach_beep_device(codec, 0x10); | 3301 | err = snd_hda_attach_beep_device(codec, 0x10); |
3294 | if (err < 0) { | 3302 | if (err < 0) { |
@@ -3352,7 +3360,7 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3352 | spec->input_mux = &ad1988_laptop_capture_source; | 3360 | spec->input_mux = &ad1988_laptop_capture_source; |
3353 | spec->num_mixers = 1; | 3361 | spec->num_mixers = 1; |
3354 | spec->mixers[0] = ad1988_laptop_mixers; | 3362 | spec->mixers[0] = ad1988_laptop_mixers; |
3355 | spec->inv_eapd = 1; /* inverted EAPD */ | 3363 | codec->inv_eapd = 1; /* inverted EAPD */ |
3356 | spec->num_init_verbs = 1; | 3364 | spec->num_init_verbs = 1; |
3357 | spec->init_verbs[0] = ad1988_laptop_init_verbs; | 3365 | spec->init_verbs[0] = ad1988_laptop_init_verbs; |
3358 | if (board_config == AD1988_LAPTOP_DIG) | 3366 | if (board_config == AD1988_LAPTOP_DIG) |
@@ -3360,15 +3368,6 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3360 | break; | 3368 | break; |
3361 | } | 3369 | } |
3362 | 3370 | ||
3363 | if (spec->autocfg.hp_pins[0]) { | ||
3364 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; | ||
3365 | spec->slave_vols = ad1988_6stack_fp_slave_pfxs; | ||
3366 | spec->slave_sws = ad1988_6stack_fp_slave_pfxs; | ||
3367 | spec->alt_dac_nid = ad1988_alt_dac_nid; | ||
3368 | spec->stream_analog_alt_playback = | ||
3369 | &ad198x_pcm_analog_alt_playback; | ||
3370 | } | ||
3371 | |||
3372 | spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); | 3371 | spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); |
3373 | spec->adc_nids = ad1988_adc_nids; | 3372 | spec->adc_nids = ad1988_adc_nids; |
3374 | spec->capsrc_nids = ad1988_capsrc_nids; | 3373 | spec->capsrc_nids = ad1988_capsrc_nids; |
@@ -3396,9 +3395,6 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3396 | 3395 | ||
3397 | codec->patch_ops = ad198x_patch_ops; | 3396 | codec->patch_ops = ad198x_patch_ops; |
3398 | switch (board_config) { | 3397 | switch (board_config) { |
3399 | case AD1988_AUTO: | ||
3400 | codec->patch_ops.init = ad1988_auto_init; | ||
3401 | break; | ||
3402 | case AD1988_LAPTOP: | 3398 | case AD1988_LAPTOP: |
3403 | case AD1988_LAPTOP_DIG: | 3399 | case AD1988_LAPTOP_DIG: |
3404 | codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; | 3400 | codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; |
@@ -3414,6 +3410,9 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3414 | 3410 | ||
3415 | return 0; | 3411 | return 0; |
3416 | } | 3412 | } |
3413 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
3414 | #define patch_ad1988 ad1988_parse_auto_config | ||
3415 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
3417 | 3416 | ||
3418 | 3417 | ||
3419 | /* | 3418 | /* |
@@ -3434,6 +3433,7 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3434 | * but no build-up framework is given, so far. | 3433 | * but no build-up framework is given, so far. |
3435 | */ | 3434 | */ |
3436 | 3435 | ||
3436 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
3437 | static const hda_nid_t ad1884_dac_nids[1] = { | 3437 | static const hda_nid_t ad1884_dac_nids[1] = { |
3438 | 0x04, | 3438 | 0x04, |
3439 | }; | 3439 | }; |
@@ -3576,7 +3576,107 @@ static const char * const ad1884_slave_vols[] = { | |||
3576 | NULL | 3576 | NULL |
3577 | }; | 3577 | }; |
3578 | 3578 | ||
3579 | static int patch_ad1884(struct hda_codec *codec) | 3579 | enum { |
3580 | AD1884_AUTO, | ||
3581 | AD1884_BASIC, | ||
3582 | AD1884_MODELS | ||
3583 | }; | ||
3584 | |||
3585 | static const char * const ad1884_models[AD1884_MODELS] = { | ||
3586 | [AD1884_AUTO] = "auto", | ||
3587 | [AD1884_BASIC] = "basic", | ||
3588 | }; | ||
3589 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
3590 | |||
3591 | |||
3592 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | ||
3593 | * damage by overloading | ||
3594 | */ | ||
3595 | static void ad1884_fixup_amp_override(struct hda_codec *codec, | ||
3596 | const struct hda_fixup *fix, int action) | ||
3597 | { | ||
3598 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
3599 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, | ||
3600 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
3601 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
3602 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
3603 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
3604 | } | ||
3605 | |||
3606 | static void ad1884_fixup_hp_eapd(struct hda_codec *codec, | ||
3607 | const struct hda_fixup *fix, int action) | ||
3608 | { | ||
3609 | struct ad198x_spec *spec = codec->spec; | ||
3610 | |||
3611 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3612 | if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
3613 | spec->eapd_nid = spec->gen.autocfg.line_out_pins[0]; | ||
3614 | else | ||
3615 | spec->eapd_nid = spec->gen.autocfg.speaker_pins[0]; | ||
3616 | if (spec->eapd_nid) | ||
3617 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | ||
3618 | } | ||
3619 | } | ||
3620 | |||
3621 | enum { | ||
3622 | AD1884_FIXUP_AMP_OVERRIDE, | ||
3623 | AD1884_FIXUP_HP_EAPD, | ||
3624 | }; | ||
3625 | |||
3626 | static const struct hda_fixup ad1884_fixups[] = { | ||
3627 | [AD1884_FIXUP_AMP_OVERRIDE] = { | ||
3628 | .type = HDA_FIXUP_FUNC, | ||
3629 | .v.func = ad1884_fixup_amp_override, | ||
3630 | }, | ||
3631 | [AD1884_FIXUP_HP_EAPD] = { | ||
3632 | .type = HDA_FIXUP_FUNC, | ||
3633 | .v.func = ad1884_fixup_hp_eapd, | ||
3634 | .chained = true, | ||
3635 | .chain_id = AD1884_FIXUP_AMP_OVERRIDE, | ||
3636 | }, | ||
3637 | }; | ||
3638 | |||
3639 | static const struct snd_pci_quirk ad1884_fixup_tbl[] = { | ||
3640 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), | ||
3641 | {} | ||
3642 | }; | ||
3643 | |||
3644 | |||
3645 | static int ad1884_parse_auto_config(struct hda_codec *codec) | ||
3646 | { | ||
3647 | struct ad198x_spec *spec; | ||
3648 | int err; | ||
3649 | |||
3650 | err = alloc_ad_spec(codec); | ||
3651 | if (err < 0) | ||
3652 | return err; | ||
3653 | spec = codec->spec; | ||
3654 | |||
3655 | spec->gen.mixer_nid = 0x20; | ||
3656 | spec->beep_dev_nid = 0x10; | ||
3657 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | ||
3658 | |||
3659 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); | ||
3660 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
3661 | |||
3662 | err = ad198x_parse_auto_config(codec); | ||
3663 | if (err < 0) | ||
3664 | goto error; | ||
3665 | err = ad1983_add_spdif_mux_ctl(codec); | ||
3666 | if (err < 0) | ||
3667 | goto error; | ||
3668 | |||
3669 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
3670 | |||
3671 | return 0; | ||
3672 | |||
3673 | error: | ||
3674 | ad198x_free(codec); | ||
3675 | return err; | ||
3676 | } | ||
3677 | |||
3678 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
3679 | static int patch_ad1884_basic(struct hda_codec *codec) | ||
3580 | { | 3680 | { |
3581 | struct ad198x_spec *spec; | 3681 | struct ad198x_spec *spec; |
3582 | int err; | 3682 | int err; |
@@ -3623,6 +3723,29 @@ static int patch_ad1884(struct hda_codec *codec) | |||
3623 | return 0; | 3723 | return 0; |
3624 | } | 3724 | } |
3625 | 3725 | ||
3726 | static int patch_ad1884(struct hda_codec *codec) | ||
3727 | { | ||
3728 | int board_config; | ||
3729 | |||
3730 | board_config = snd_hda_check_board_config(codec, AD1884_MODELS, | ||
3731 | ad1884_models, NULL); | ||
3732 | if (board_config < 0) { | ||
3733 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
3734 | codec->chip_name); | ||
3735 | board_config = AD1884_AUTO; | ||
3736 | } | ||
3737 | |||
3738 | if (board_config == AD1884_AUTO) | ||
3739 | return ad1884_parse_auto_config(codec); | ||
3740 | else | ||
3741 | return patch_ad1884_basic(codec); | ||
3742 | } | ||
3743 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
3744 | #define patch_ad1884 ad1884_parse_auto_config | ||
3745 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
3746 | |||
3747 | |||
3748 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
3626 | /* | 3749 | /* |
3627 | * Lenovo Thinkpad T61/X61 | 3750 | * Lenovo Thinkpad T61/X61 |
3628 | */ | 3751 | */ |
@@ -3795,6 +3918,7 @@ static int ad1984_build_pcms(struct hda_codec *codec) | |||
3795 | 3918 | ||
3796 | /* models */ | 3919 | /* models */ |
3797 | enum { | 3920 | enum { |
3921 | AD1984_AUTO, | ||
3798 | AD1984_BASIC, | 3922 | AD1984_BASIC, |
3799 | AD1984_THINKPAD, | 3923 | AD1984_THINKPAD, |
3800 | AD1984_DELL_DESKTOP, | 3924 | AD1984_DELL_DESKTOP, |
@@ -3802,6 +3926,7 @@ enum { | |||
3802 | }; | 3926 | }; |
3803 | 3927 | ||
3804 | static const char * const ad1984_models[AD1984_MODELS] = { | 3928 | static const char * const ad1984_models[AD1984_MODELS] = { |
3929 | [AD1984_AUTO] = "auto", | ||
3805 | [AD1984_BASIC] = "basic", | 3930 | [AD1984_BASIC] = "basic", |
3806 | [AD1984_THINKPAD] = "thinkpad", | 3931 | [AD1984_THINKPAD] = "thinkpad", |
3807 | [AD1984_DELL_DESKTOP] = "dell_desktop", | 3932 | [AD1984_DELL_DESKTOP] = "dell_desktop", |
@@ -3820,12 +3945,22 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3820 | struct ad198x_spec *spec; | 3945 | struct ad198x_spec *spec; |
3821 | int board_config, err; | 3946 | int board_config, err; |
3822 | 3947 | ||
3823 | err = patch_ad1884(codec); | 3948 | board_config = snd_hda_check_board_config(codec, AD1984_MODELS, |
3949 | ad1984_models, ad1984_cfg_tbl); | ||
3950 | if (board_config < 0) { | ||
3951 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
3952 | codec->chip_name); | ||
3953 | board_config = AD1984_AUTO; | ||
3954 | } | ||
3955 | |||
3956 | if (board_config == AD1984_AUTO) | ||
3957 | return ad1884_parse_auto_config(codec); | ||
3958 | |||
3959 | err = patch_ad1884_basic(codec); | ||
3824 | if (err < 0) | 3960 | if (err < 0) |
3825 | return err; | 3961 | return err; |
3826 | spec = codec->spec; | 3962 | spec = codec->spec; |
3827 | board_config = snd_hda_check_board_config(codec, AD1984_MODELS, | 3963 | |
3828 | ad1984_models, ad1984_cfg_tbl); | ||
3829 | switch (board_config) { | 3964 | switch (board_config) { |
3830 | case AD1984_BASIC: | 3965 | case AD1984_BASIC: |
3831 | /* additional digital mics */ | 3966 | /* additional digital mics */ |
@@ -3852,6 +3987,9 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3852 | } | 3987 | } |
3853 | return 0; | 3988 | return 0; |
3854 | } | 3989 | } |
3990 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
3991 | #define patch_ad1984 ad1884_parse_auto_config | ||
3992 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
3855 | 3993 | ||
3856 | 3994 | ||
3857 | /* | 3995 | /* |
@@ -3872,6 +4010,7 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3872 | * We share the single DAC for both HP and line-outs (see AD1884/1984). | 4010 | * We share the single DAC for both HP and line-outs (see AD1884/1984). |
3873 | */ | 4011 | */ |
3874 | 4012 | ||
4013 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
3875 | static const hda_nid_t ad1884a_dac_nids[1] = { | 4014 | static const hda_nid_t ad1884a_dac_nids[1] = { |
3876 | 0x03, | 4015 | 0x03, |
3877 | }; | 4016 | }; |
@@ -4542,6 +4681,7 @@ static int ad1984a_touchsmart_init(struct hda_codec *codec) | |||
4542 | */ | 4681 | */ |
4543 | 4682 | ||
4544 | enum { | 4683 | enum { |
4684 | AD1884A_AUTO, | ||
4545 | AD1884A_DESKTOP, | 4685 | AD1884A_DESKTOP, |
4546 | AD1884A_LAPTOP, | 4686 | AD1884A_LAPTOP, |
4547 | AD1884A_MOBILE, | 4687 | AD1884A_MOBILE, |
@@ -4552,6 +4692,7 @@ enum { | |||
4552 | }; | 4692 | }; |
4553 | 4693 | ||
4554 | static const char * const ad1884a_models[AD1884A_MODELS] = { | 4694 | static const char * const ad1884a_models[AD1884A_MODELS] = { |
4695 | [AD1884A_AUTO] = "auto", | ||
4555 | [AD1884A_DESKTOP] = "desktop", | 4696 | [AD1884A_DESKTOP] = "desktop", |
4556 | [AD1884A_LAPTOP] = "laptop", | 4697 | [AD1884A_LAPTOP] = "laptop", |
4557 | [AD1884A_MOBILE] = "mobile", | 4698 | [AD1884A_MOBILE] = "mobile", |
@@ -4580,6 +4721,18 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4580 | struct ad198x_spec *spec; | 4721 | struct ad198x_spec *spec; |
4581 | int err, board_config; | 4722 | int err, board_config; |
4582 | 4723 | ||
4724 | board_config = snd_hda_check_board_config(codec, AD1884A_MODELS, | ||
4725 | ad1884a_models, | ||
4726 | ad1884a_cfg_tbl); | ||
4727 | if (board_config < 0) { | ||
4728 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4729 | codec->chip_name); | ||
4730 | board_config = AD1884A_AUTO; | ||
4731 | } | ||
4732 | |||
4733 | if (board_config == AD1884A_AUTO) | ||
4734 | return ad1884_parse_auto_config(codec); | ||
4735 | |||
4583 | err = alloc_ad_spec(codec); | 4736 | err = alloc_ad_spec(codec); |
4584 | if (err < 0) | 4737 | if (err < 0) |
4585 | return err; | 4738 | return err; |
@@ -4611,9 +4764,6 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4611 | codec->patch_ops = ad198x_patch_ops; | 4764 | codec->patch_ops = ad198x_patch_ops; |
4612 | 4765 | ||
4613 | /* override some parameters */ | 4766 | /* override some parameters */ |
4614 | board_config = snd_hda_check_board_config(codec, AD1884A_MODELS, | ||
4615 | ad1884a_models, | ||
4616 | ad1884a_cfg_tbl); | ||
4617 | switch (board_config) { | 4767 | switch (board_config) { |
4618 | case AD1884A_LAPTOP: | 4768 | case AD1884A_LAPTOP: |
4619 | spec->mixers[0] = ad1884a_laptop_mixers; | 4769 | spec->mixers[0] = ad1884a_laptop_mixers; |
@@ -4684,6 +4834,9 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4684 | 4834 | ||
4685 | return 0; | 4835 | return 0; |
4686 | } | 4836 | } |
4837 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
4838 | #define patch_ad1884a ad1884_parse_auto_config | ||
4839 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
4687 | 4840 | ||
4688 | 4841 | ||
4689 | /* | 4842 | /* |
@@ -4698,6 +4851,7 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4698 | * port-G - rear clfe-out (6stack) | 4851 | * port-G - rear clfe-out (6stack) |
4699 | */ | 4852 | */ |
4700 | 4853 | ||
4854 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
4701 | static const hda_nid_t ad1882_dac_nids[3] = { | 4855 | static const hda_nid_t ad1882_dac_nids[3] = { |
4702 | 0x04, 0x03, 0x05 | 4856 | 0x04, 0x03, 0x05 |
4703 | }; | 4857 | }; |
@@ -4974,6 +5128,7 @@ static const struct hda_amp_list ad1882_loopbacks[] = { | |||
4974 | 5128 | ||
4975 | /* models */ | 5129 | /* models */ |
4976 | enum { | 5130 | enum { |
5131 | AD1882_AUTO, | ||
4977 | AD1882_3STACK, | 5132 | AD1882_3STACK, |
4978 | AD1882_6STACK, | 5133 | AD1882_6STACK, |
4979 | AD1882_3STACK_AUTOMUTE, | 5134 | AD1882_3STACK_AUTOMUTE, |
@@ -4981,17 +5136,57 @@ enum { | |||
4981 | }; | 5136 | }; |
4982 | 5137 | ||
4983 | static const char * const ad1882_models[AD1986A_MODELS] = { | 5138 | static const char * const ad1882_models[AD1986A_MODELS] = { |
5139 | [AD1882_AUTO] = "auto", | ||
4984 | [AD1882_3STACK] = "3stack", | 5140 | [AD1882_3STACK] = "3stack", |
4985 | [AD1882_6STACK] = "6stack", | 5141 | [AD1882_6STACK] = "6stack", |
4986 | [AD1882_3STACK_AUTOMUTE] = "3stack-automute", | 5142 | [AD1882_3STACK_AUTOMUTE] = "3stack-automute", |
4987 | }; | 5143 | }; |
5144 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
5145 | |||
5146 | static int ad1882_parse_auto_config(struct hda_codec *codec) | ||
5147 | { | ||
5148 | struct ad198x_spec *spec; | ||
5149 | int err; | ||
4988 | 5150 | ||
5151 | err = alloc_ad_spec(codec); | ||
5152 | if (err < 0) | ||
5153 | return err; | ||
5154 | spec = codec->spec; | ||
4989 | 5155 | ||
5156 | spec->gen.mixer_nid = 0x20; | ||
5157 | spec->gen.mixer_merge_nid = 0x21; | ||
5158 | spec->beep_dev_nid = 0x10; | ||
5159 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | ||
5160 | err = ad198x_parse_auto_config(codec); | ||
5161 | if (err < 0) | ||
5162 | goto error; | ||
5163 | err = ad1988_add_spdif_mux_ctl(codec); | ||
5164 | if (err < 0) | ||
5165 | goto error; | ||
5166 | return 0; | ||
5167 | |||
5168 | error: | ||
5169 | ad198x_free(codec); | ||
5170 | return err; | ||
5171 | } | ||
5172 | |||
5173 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
4990 | static int patch_ad1882(struct hda_codec *codec) | 5174 | static int patch_ad1882(struct hda_codec *codec) |
4991 | { | 5175 | { |
4992 | struct ad198x_spec *spec; | 5176 | struct ad198x_spec *spec; |
4993 | int err, board_config; | 5177 | int err, board_config; |
4994 | 5178 | ||
5179 | board_config = snd_hda_check_board_config(codec, AD1882_MODELS, | ||
5180 | ad1882_models, NULL); | ||
5181 | if (board_config < 0) { | ||
5182 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5183 | codec->chip_name); | ||
5184 | board_config = AD1882_AUTO; | ||
5185 | } | ||
5186 | |||
5187 | if (board_config == AD1882_AUTO) | ||
5188 | return ad1882_parse_auto_config(codec); | ||
5189 | |||
4995 | err = alloc_ad_spec(codec); | 5190 | err = alloc_ad_spec(codec); |
4996 | if (err < 0) | 5191 | if (err < 0) |
4997 | return err; | 5192 | return err; |
@@ -5032,8 +5227,6 @@ static int patch_ad1882(struct hda_codec *codec) | |||
5032 | codec->patch_ops = ad198x_patch_ops; | 5227 | codec->patch_ops = ad198x_patch_ops; |
5033 | 5228 | ||
5034 | /* override some parameters */ | 5229 | /* override some parameters */ |
5035 | board_config = snd_hda_check_board_config(codec, AD1882_MODELS, | ||
5036 | ad1882_models, NULL); | ||
5037 | switch (board_config) { | 5230 | switch (board_config) { |
5038 | default: | 5231 | default: |
5039 | case AD1882_3STACK: | 5232 | case AD1882_3STACK: |
@@ -5063,6 +5256,9 @@ static int patch_ad1882(struct hda_codec *codec) | |||
5063 | 5256 | ||
5064 | return 0; | 5257 | return 0; |
5065 | } | 5258 | } |
5259 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
5260 | #define patch_ad1882 ad1882_parse_auto_config | ||
5261 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
5066 | 5262 | ||
5067 | 5263 | ||
5068 | /* | 5264 | /* |
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 19ae14f739cb..30b3a4bc06ee 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -19,7 +19,6 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
24 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -27,502 +26,46 @@ | |||
27 | #include "hda_codec.h" | 26 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 27 | #include "hda_local.h" |
29 | #include "hda_auto_parser.h" | 28 | #include "hda_auto_parser.h" |
29 | #include "hda_jack.h" | ||
30 | #include "hda_generic.h" | ||
30 | 31 | ||
31 | /* | ||
32 | */ | ||
33 | |||
34 | struct ca0110_spec { | ||
35 | struct auto_pin_cfg autocfg; | ||
36 | struct hda_multi_out multiout; | ||
37 | hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; | ||
38 | hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; | ||
39 | hda_nid_t hp_dac; | ||
40 | hda_nid_t input_pins[AUTO_PIN_LAST]; | ||
41 | hda_nid_t adcs[AUTO_PIN_LAST]; | ||
42 | hda_nid_t dig_out; | ||
43 | hda_nid_t dig_in; | ||
44 | unsigned int num_inputs; | ||
45 | char input_labels[AUTO_PIN_LAST][32]; | ||
46 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * PCM callbacks | ||
51 | */ | ||
52 | static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
53 | struct hda_codec *codec, | ||
54 | struct snd_pcm_substream *substream) | ||
55 | { | ||
56 | struct ca0110_spec *spec = codec->spec; | ||
57 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
58 | hinfo); | ||
59 | } | ||
60 | |||
61 | static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
62 | struct hda_codec *codec, | ||
63 | unsigned int stream_tag, | ||
64 | unsigned int format, | ||
65 | struct snd_pcm_substream *substream) | ||
66 | { | ||
67 | struct ca0110_spec *spec = codec->spec; | ||
68 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
69 | stream_tag, format, substream); | ||
70 | } | ||
71 | |||
72 | static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
73 | struct hda_codec *codec, | ||
74 | struct snd_pcm_substream *substream) | ||
75 | { | ||
76 | struct ca0110_spec *spec = codec->spec; | ||
77 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * Digital out | ||
82 | */ | ||
83 | static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
84 | struct hda_codec *codec, | ||
85 | struct snd_pcm_substream *substream) | ||
86 | { | ||
87 | struct ca0110_spec *spec = codec->spec; | ||
88 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
89 | } | ||
90 | |||
91 | static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
92 | struct hda_codec *codec, | ||
93 | struct snd_pcm_substream *substream) | ||
94 | { | ||
95 | struct ca0110_spec *spec = codec->spec; | ||
96 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
97 | } | ||
98 | |||
99 | static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
100 | struct hda_codec *codec, | ||
101 | unsigned int stream_tag, | ||
102 | unsigned int format, | ||
103 | struct snd_pcm_substream *substream) | ||
104 | { | ||
105 | struct ca0110_spec *spec = codec->spec; | ||
106 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
107 | format, substream); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Analog capture | ||
112 | */ | ||
113 | static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
114 | struct hda_codec *codec, | ||
115 | unsigned int stream_tag, | ||
116 | unsigned int format, | ||
117 | struct snd_pcm_substream *substream) | ||
118 | { | ||
119 | struct ca0110_spec *spec = codec->spec; | ||
120 | |||
121 | snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], | ||
122 | stream_tag, 0, format); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
127 | struct hda_codec *codec, | ||
128 | struct snd_pcm_substream *substream) | ||
129 | { | ||
130 | struct ca0110_spec *spec = codec->spec; | ||
131 | |||
132 | snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | */ | ||
138 | |||
139 | static const char * const dirstr[2] = { "Playback", "Capture" }; | ||
140 | |||
141 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
142 | int chan, int dir) | ||
143 | { | ||
144 | char namestr[44]; | ||
145 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
146 | struct snd_kcontrol_new knew = | ||
147 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | ||
148 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | ||
149 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | ||
150 | } | ||
151 | |||
152 | static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | ||
153 | int chan, int dir) | ||
154 | { | ||
155 | char namestr[44]; | ||
156 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | ||
157 | struct snd_kcontrol_new knew = | ||
158 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | ||
159 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | ||
160 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | ||
161 | } | ||
162 | |||
163 | #define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) | ||
164 | #define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0) | ||
165 | #define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1) | ||
166 | #define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1) | ||
167 | #define add_mono_switch(codec, nid, pfx, chan) \ | ||
168 | _add_switch(codec, nid, pfx, chan, 0) | ||
169 | #define add_mono_volume(codec, nid, pfx, chan) \ | ||
170 | _add_volume(codec, nid, pfx, chan, 0) | ||
171 | |||
172 | static int ca0110_build_controls(struct hda_codec *codec) | ||
173 | { | ||
174 | struct ca0110_spec *spec = codec->spec; | ||
175 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
176 | static const char * const prefix[AUTO_CFG_MAX_OUTS] = { | ||
177 | "Front", "Surround", NULL, "Side", "Multi" | ||
178 | }; | ||
179 | hda_nid_t mutenid; | ||
180 | int i, err; | ||
181 | |||
182 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
183 | if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP) | ||
184 | mutenid = spec->out_pins[i]; | ||
185 | else | ||
186 | mutenid = spec->multiout.dac_nids[i]; | ||
187 | if (!prefix[i]) { | ||
188 | err = add_mono_switch(codec, mutenid, | ||
189 | "Center", 1); | ||
190 | if (err < 0) | ||
191 | return err; | ||
192 | err = add_mono_switch(codec, mutenid, | ||
193 | "LFE", 1); | ||
194 | if (err < 0) | ||
195 | return err; | ||
196 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
197 | "Center", 1); | ||
198 | if (err < 0) | ||
199 | return err; | ||
200 | err = add_mono_volume(codec, spec->multiout.dac_nids[i], | ||
201 | "LFE", 1); | ||
202 | if (err < 0) | ||
203 | return err; | ||
204 | } else { | ||
205 | err = add_out_switch(codec, mutenid, | ||
206 | prefix[i]); | ||
207 | if (err < 0) | ||
208 | return err; | ||
209 | err = add_out_volume(codec, spec->multiout.dac_nids[i], | ||
210 | prefix[i]); | ||
211 | if (err < 0) | ||
212 | return err; | ||
213 | } | ||
214 | } | ||
215 | if (cfg->hp_outs) { | ||
216 | if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP) | ||
217 | mutenid = cfg->hp_pins[0]; | ||
218 | else | ||
219 | mutenid = spec->multiout.dac_nids[i]; | ||
220 | |||
221 | err = add_out_switch(codec, mutenid, "Headphone"); | ||
222 | if (err < 0) | ||
223 | return err; | ||
224 | if (spec->hp_dac) { | ||
225 | err = add_out_volume(codec, spec->hp_dac, "Headphone"); | ||
226 | if (err < 0) | ||
227 | return err; | ||
228 | } | ||
229 | } | ||
230 | for (i = 0; i < spec->num_inputs; i++) { | ||
231 | const char *label = spec->input_labels[i]; | ||
232 | if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP) | ||
233 | mutenid = spec->input_pins[i]; | ||
234 | else | ||
235 | mutenid = spec->adcs[i]; | ||
236 | err = add_in_switch(codec, mutenid, label); | ||
237 | if (err < 0) | ||
238 | return err; | ||
239 | err = add_in_volume(codec, spec->adcs[i], label); | ||
240 | if (err < 0) | ||
241 | return err; | ||
242 | } | ||
243 | |||
244 | if (spec->dig_out) { | ||
245 | err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out, | ||
246 | spec->dig_out); | ||
247 | if (err < 0) | ||
248 | return err; | ||
249 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | ||
250 | if (err < 0) | ||
251 | return err; | ||
252 | spec->multiout.share_spdif = 1; | ||
253 | } | ||
254 | if (spec->dig_in) { | ||
255 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | ||
256 | if (err < 0) | ||
257 | return err; | ||
258 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
259 | } | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | */ | ||
265 | static const struct hda_pcm_stream ca0110_pcm_analog_playback = { | ||
266 | .substreams = 1, | ||
267 | .channels_min = 2, | ||
268 | .channels_max = 8, | ||
269 | .ops = { | ||
270 | .open = ca0110_playback_pcm_open, | ||
271 | .prepare = ca0110_playback_pcm_prepare, | ||
272 | .cleanup = ca0110_playback_pcm_cleanup | ||
273 | }, | ||
274 | }; | ||
275 | |||
276 | static const struct hda_pcm_stream ca0110_pcm_analog_capture = { | ||
277 | .substreams = 1, | ||
278 | .channels_min = 2, | ||
279 | .channels_max = 2, | ||
280 | .ops = { | ||
281 | .prepare = ca0110_capture_pcm_prepare, | ||
282 | .cleanup = ca0110_capture_pcm_cleanup | ||
283 | }, | ||
284 | }; | ||
285 | |||
286 | static const struct hda_pcm_stream ca0110_pcm_digital_playback = { | ||
287 | .substreams = 1, | ||
288 | .channels_min = 2, | ||
289 | .channels_max = 2, | ||
290 | .ops = { | ||
291 | .open = ca0110_dig_playback_pcm_open, | ||
292 | .close = ca0110_dig_playback_pcm_close, | ||
293 | .prepare = ca0110_dig_playback_pcm_prepare | ||
294 | }, | ||
295 | }; | ||
296 | |||
297 | static const struct hda_pcm_stream ca0110_pcm_digital_capture = { | ||
298 | .substreams = 1, | ||
299 | .channels_min = 2, | ||
300 | .channels_max = 2, | ||
301 | }; | ||
302 | |||
303 | static int ca0110_build_pcms(struct hda_codec *codec) | ||
304 | { | ||
305 | struct ca0110_spec *spec = codec->spec; | ||
306 | struct hda_pcm *info = spec->pcm_rec; | ||
307 | |||
308 | codec->pcm_info = info; | ||
309 | codec->num_pcms = 0; | ||
310 | |||
311 | info->name = "CA0110 Analog"; | ||
312 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; | ||
313 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; | ||
314 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
315 | spec->multiout.max_channels; | ||
316 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; | ||
317 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; | ||
318 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; | ||
319 | codec->num_pcms++; | ||
320 | |||
321 | if (!spec->dig_out && !spec->dig_in) | ||
322 | return 0; | ||
323 | |||
324 | info++; | ||
325 | info->name = "CA0110 Digital"; | ||
326 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
327 | if (spec->dig_out) { | ||
328 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
329 | ca0110_pcm_digital_playback; | ||
330 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out; | ||
331 | } | ||
332 | if (spec->dig_in) { | ||
333 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
334 | ca0110_pcm_digital_capture; | ||
335 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | ||
336 | } | ||
337 | codec->num_pcms++; | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | ||
343 | { | ||
344 | if (pin) { | ||
345 | snd_hda_set_pin_ctl(codec, pin, PIN_HP); | ||
346 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
347 | snd_hda_codec_write(codec, pin, 0, | ||
348 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
349 | AMP_OUT_UNMUTE); | ||
350 | } | ||
351 | if (dac) | ||
352 | snd_hda_codec_write(codec, dac, 0, | ||
353 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | ||
354 | } | ||
355 | |||
356 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | ||
357 | { | ||
358 | if (pin) { | ||
359 | snd_hda_set_pin_ctl(codec, pin, PIN_IN | | ||
360 | snd_hda_get_default_vref(codec, pin)); | ||
361 | if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) | ||
362 | snd_hda_codec_write(codec, pin, 0, | ||
363 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
364 | AMP_IN_UNMUTE(0)); | ||
365 | } | ||
366 | if (adc) | ||
367 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
368 | AMP_IN_UNMUTE(0)); | ||
369 | } | ||
370 | |||
371 | static int ca0110_init(struct hda_codec *codec) | ||
372 | { | ||
373 | struct ca0110_spec *spec = codec->spec; | ||
374 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
375 | int i; | ||
376 | |||
377 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
378 | init_output(codec, spec->out_pins[i], | ||
379 | spec->multiout.dac_nids[i]); | ||
380 | init_output(codec, cfg->hp_pins[0], spec->hp_dac); | ||
381 | init_output(codec, cfg->dig_out_pins[0], spec->dig_out); | ||
382 | |||
383 | for (i = 0; i < spec->num_inputs; i++) | ||
384 | init_input(codec, spec->input_pins[i], spec->adcs[i]); | ||
385 | init_input(codec, cfg->dig_in_pin, spec->dig_in); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static void ca0110_free(struct hda_codec *codec) | ||
390 | { | ||
391 | kfree(codec->spec); | ||
392 | } | ||
393 | 32 | ||
394 | static const struct hda_codec_ops ca0110_patch_ops = { | 33 | static const struct hda_codec_ops ca0110_patch_ops = { |
395 | .build_controls = ca0110_build_controls, | 34 | .build_controls = snd_hda_gen_build_controls, |
396 | .build_pcms = ca0110_build_pcms, | 35 | .build_pcms = snd_hda_gen_build_pcms, |
397 | .init = ca0110_init, | 36 | .init = snd_hda_gen_init, |
398 | .free = ca0110_free, | 37 | .free = snd_hda_gen_free, |
38 | .unsol_event = snd_hda_jack_unsol_event, | ||
399 | }; | 39 | }; |
400 | 40 | ||
401 | |||
402 | static void parse_line_outs(struct hda_codec *codec) | ||
403 | { | ||
404 | struct ca0110_spec *spec = codec->spec; | ||
405 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
406 | int i, n; | ||
407 | unsigned int def_conf; | ||
408 | hda_nid_t nid; | ||
409 | |||
410 | n = 0; | ||
411 | for (i = 0; i < cfg->line_outs; i++) { | ||
412 | nid = cfg->line_out_pins[i]; | ||
413 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
414 | if (!def_conf) | ||
415 | continue; /* invalid pin */ | ||
416 | if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) | ||
417 | continue; | ||
418 | spec->out_pins[n++] = nid; | ||
419 | } | ||
420 | spec->multiout.dac_nids = spec->dacs; | ||
421 | spec->multiout.num_dacs = n; | ||
422 | spec->multiout.max_channels = n * 2; | ||
423 | } | ||
424 | |||
425 | static void parse_hp_out(struct hda_codec *codec) | ||
426 | { | ||
427 | struct ca0110_spec *spec = codec->spec; | ||
428 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
429 | int i; | ||
430 | unsigned int def_conf; | ||
431 | hda_nid_t nid, dac; | ||
432 | |||
433 | if (!cfg->hp_outs) | ||
434 | return; | ||
435 | nid = cfg->hp_pins[0]; | ||
436 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
437 | if (!def_conf) { | ||
438 | cfg->hp_outs = 0; | ||
439 | return; | ||
440 | } | ||
441 | if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) | ||
442 | return; | ||
443 | |||
444 | for (i = 0; i < cfg->line_outs; i++) | ||
445 | if (dac == spec->dacs[i]) | ||
446 | break; | ||
447 | if (i >= cfg->line_outs) { | ||
448 | spec->hp_dac = dac; | ||
449 | spec->multiout.hp_nid = dac; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | static void parse_input(struct hda_codec *codec) | ||
454 | { | ||
455 | struct ca0110_spec *spec = codec->spec; | ||
456 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
457 | hda_nid_t nid, pin; | ||
458 | int n, i, j; | ||
459 | |||
460 | n = 0; | ||
461 | nid = codec->start_nid; | ||
462 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
463 | unsigned int wcaps = get_wcaps(codec, nid); | ||
464 | unsigned int type = get_wcaps_type(wcaps); | ||
465 | if (type != AC_WID_AUD_IN) | ||
466 | continue; | ||
467 | if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) | ||
468 | continue; | ||
469 | if (pin == cfg->dig_in_pin) { | ||
470 | spec->dig_in = nid; | ||
471 | continue; | ||
472 | } | ||
473 | for (j = 0; j < cfg->num_inputs; j++) | ||
474 | if (cfg->inputs[j].pin == pin) | ||
475 | break; | ||
476 | if (j >= cfg->num_inputs) | ||
477 | continue; | ||
478 | spec->input_pins[n] = pin; | ||
479 | snd_hda_get_pin_label(codec, pin, cfg, | ||
480 | spec->input_labels[n], | ||
481 | sizeof(spec->input_labels[n]), NULL); | ||
482 | spec->adcs[n] = nid; | ||
483 | n++; | ||
484 | } | ||
485 | spec->num_inputs = n; | ||
486 | } | ||
487 | |||
488 | static void parse_digital(struct hda_codec *codec) | ||
489 | { | ||
490 | struct ca0110_spec *spec = codec->spec; | ||
491 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
492 | |||
493 | if (cfg->dig_outs && | ||
494 | snd_hda_get_connections(codec, cfg->dig_out_pins[0], | ||
495 | &spec->dig_out, 1) == 1) | ||
496 | spec->multiout.dig_out_nid = spec->dig_out; | ||
497 | } | ||
498 | |||
499 | static int ca0110_parse_auto_config(struct hda_codec *codec) | 41 | static int ca0110_parse_auto_config(struct hda_codec *codec) |
500 | { | 42 | { |
501 | struct ca0110_spec *spec = codec->spec; | 43 | struct hda_gen_spec *spec = codec->spec; |
502 | int err; | 44 | int err; |
503 | 45 | ||
504 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | 46 | err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0); |
47 | if (err < 0) | ||
48 | return err; | ||
49 | err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg); | ||
505 | if (err < 0) | 50 | if (err < 0) |
506 | return err; | 51 | return err; |
507 | 52 | ||
508 | parse_line_outs(codec); | ||
509 | parse_hp_out(codec); | ||
510 | parse_digital(codec); | ||
511 | parse_input(codec); | ||
512 | return 0; | 53 | return 0; |
513 | } | 54 | } |
514 | 55 | ||
515 | 56 | ||
516 | static int patch_ca0110(struct hda_codec *codec) | 57 | static int patch_ca0110(struct hda_codec *codec) |
517 | { | 58 | { |
518 | struct ca0110_spec *spec; | 59 | struct hda_gen_spec *spec; |
519 | int err; | 60 | int err; |
520 | 61 | ||
521 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 62 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
522 | if (!spec) | 63 | if (!spec) |
523 | return -ENOMEM; | 64 | return -ENOMEM; |
65 | snd_hda_gen_spec_init(spec); | ||
524 | codec->spec = spec; | 66 | codec->spec = spec; |
525 | 67 | ||
68 | spec->multi_cap_vol = 1; | ||
526 | codec->bus->needs_damn_long_delay = 1; | 69 | codec->bus->needs_damn_long_delay = 1; |
527 | 70 | ||
528 | err = ca0110_parse_auto_config(codec); | 71 | err = ca0110_parse_auto_config(codec); |
@@ -534,8 +77,7 @@ static int patch_ca0110(struct hda_codec *codec) | |||
534 | return 0; | 77 | return 0; |
535 | 78 | ||
536 | error: | 79 | error: |
537 | kfree(codec->spec); | 80 | snd_hda_gen_free(codec); |
538 | codec->spec = NULL; | ||
539 | return err; | 81 | return err; |
540 | } | 82 | } |
541 | 83 | ||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index a2537b2f8724..72ebb8a36b13 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -19,16 +19,16 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
24 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
26 | #include <sound/core.h> | 25 | #include <sound/core.h> |
26 | #include <sound/tlv.h> | ||
27 | #include "hda_codec.h" | 27 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | #include "hda_auto_parser.h" | 29 | #include "hda_auto_parser.h" |
30 | #include "hda_jack.h" | 30 | #include "hda_jack.h" |
31 | #include <sound/tlv.h> | 31 | #include "hda_generic.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | */ | 34 | */ |
@@ -36,45 +36,17 @@ | |||
36 | struct cs_spec { | 36 | struct cs_spec { |
37 | struct hda_gen_spec gen; | 37 | struct hda_gen_spec gen; |
38 | 38 | ||
39 | struct auto_pin_cfg autocfg; | ||
40 | struct hda_multi_out multiout; | ||
41 | struct snd_kcontrol *vmaster_sw; | ||
42 | struct snd_kcontrol *vmaster_vol; | ||
43 | |||
44 | hda_nid_t dac_nid[AUTO_CFG_MAX_OUTS]; | ||
45 | hda_nid_t slave_dig_outs[2]; | ||
46 | |||
47 | unsigned int input_idx[AUTO_PIN_LAST]; | ||
48 | unsigned int capsrc_idx[AUTO_PIN_LAST]; | ||
49 | hda_nid_t adc_nid[AUTO_PIN_LAST]; | ||
50 | unsigned int adc_idx[AUTO_PIN_LAST]; | ||
51 | unsigned int num_inputs; | ||
52 | unsigned int cur_input; | ||
53 | unsigned int automic_idx; | ||
54 | hda_nid_t cur_adc; | ||
55 | unsigned int cur_adc_stream_tag; | ||
56 | unsigned int cur_adc_format; | ||
57 | hda_nid_t dig_in; | ||
58 | |||
59 | const struct hda_bind_ctls *capture_bind[2]; | ||
60 | |||
61 | unsigned int gpio_mask; | 39 | unsigned int gpio_mask; |
62 | unsigned int gpio_dir; | 40 | unsigned int gpio_dir; |
63 | unsigned int gpio_data; | 41 | unsigned int gpio_data; |
64 | unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ | 42 | unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ |
65 | unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ | 43 | unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ |
66 | 44 | ||
67 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
68 | |||
69 | unsigned int hp_detect:1; | ||
70 | unsigned int mic_detect:1; | ||
71 | unsigned int speaker_2_1:1; | ||
72 | /* CS421x */ | 45 | /* CS421x */ |
73 | unsigned int spdif_detect:1; | 46 | unsigned int spdif_detect:1; |
47 | unsigned int spdif_present:1; | ||
74 | unsigned int sense_b:1; | 48 | unsigned int sense_b:1; |
75 | hda_nid_t vendor_nid; | 49 | hda_nid_t vendor_nid; |
76 | struct hda_input_mux input_mux; | ||
77 | unsigned int last_input; | ||
78 | }; | 50 | }; |
79 | 51 | ||
80 | /* available models with CS420x */ | 52 | /* available models with CS420x */ |
@@ -180,915 +152,43 @@ static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, | |||
180 | AC_VERB_SET_PROC_COEF, coef); | 152 | AC_VERB_SET_PROC_COEF, coef); |
181 | } | 153 | } |
182 | 154 | ||
183 | |||
184 | #define HP_EVENT 1 | ||
185 | #define MIC_EVENT 2 | ||
186 | |||
187 | /* | ||
188 | * PCM callbacks | ||
189 | */ | ||
190 | static int cs_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
191 | struct hda_codec *codec, | ||
192 | struct snd_pcm_substream *substream) | ||
193 | { | ||
194 | struct cs_spec *spec = codec->spec; | ||
195 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
196 | hinfo); | ||
197 | } | ||
198 | |||
199 | static int cs_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
200 | struct hda_codec *codec, | ||
201 | unsigned int stream_tag, | ||
202 | unsigned int format, | ||
203 | struct snd_pcm_substream *substream) | ||
204 | { | ||
205 | struct cs_spec *spec = codec->spec; | ||
206 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
207 | stream_tag, format, substream); | ||
208 | } | ||
209 | |||
210 | static int cs_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
211 | struct hda_codec *codec, | ||
212 | struct snd_pcm_substream *substream) | ||
213 | { | ||
214 | struct cs_spec *spec = codec->spec; | ||
215 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Digital out | ||
220 | */ | ||
221 | static int cs_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
222 | struct hda_codec *codec, | ||
223 | struct snd_pcm_substream *substream) | ||
224 | { | ||
225 | struct cs_spec *spec = codec->spec; | ||
226 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
227 | } | ||
228 | |||
229 | static int cs_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
230 | struct hda_codec *codec, | ||
231 | struct snd_pcm_substream *substream) | ||
232 | { | ||
233 | struct cs_spec *spec = codec->spec; | ||
234 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
235 | } | ||
236 | |||
237 | static int cs_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
238 | struct hda_codec *codec, | ||
239 | unsigned int stream_tag, | ||
240 | unsigned int format, | ||
241 | struct snd_pcm_substream *substream) | ||
242 | { | ||
243 | struct cs_spec *spec = codec->spec; | ||
244 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
245 | format, substream); | ||
246 | } | ||
247 | |||
248 | static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
249 | struct hda_codec *codec, | ||
250 | struct snd_pcm_substream *substream) | ||
251 | { | ||
252 | struct cs_spec *spec = codec->spec; | ||
253 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
254 | } | ||
255 | |||
256 | static void cs_update_input_select(struct hda_codec *codec) | ||
257 | { | ||
258 | struct cs_spec *spec = codec->spec; | ||
259 | if (spec->cur_adc) | ||
260 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
261 | AC_VERB_SET_CONNECT_SEL, | ||
262 | spec->adc_idx[spec->cur_input]); | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Analog capture | ||
267 | */ | ||
268 | static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
269 | struct hda_codec *codec, | ||
270 | unsigned int stream_tag, | ||
271 | unsigned int format, | ||
272 | struct snd_pcm_substream *substream) | ||
273 | { | ||
274 | struct cs_spec *spec = codec->spec; | ||
275 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | ||
276 | spec->cur_adc_stream_tag = stream_tag; | ||
277 | spec->cur_adc_format = format; | ||
278 | cs_update_input_select(codec); | ||
279 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
284 | struct hda_codec *codec, | ||
285 | struct snd_pcm_substream *substream) | ||
286 | { | ||
287 | struct cs_spec *spec = codec->spec; | ||
288 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
289 | spec->cur_adc = 0; | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | */ | ||
295 | static const struct hda_pcm_stream cs_pcm_analog_playback = { | ||
296 | .substreams = 1, | ||
297 | .channels_min = 2, | ||
298 | .channels_max = 2, | ||
299 | .ops = { | ||
300 | .open = cs_playback_pcm_open, | ||
301 | .prepare = cs_playback_pcm_prepare, | ||
302 | .cleanup = cs_playback_pcm_cleanup | ||
303 | }, | ||
304 | }; | ||
305 | |||
306 | static const struct hda_pcm_stream cs_pcm_analog_capture = { | ||
307 | .substreams = 1, | ||
308 | .channels_min = 2, | ||
309 | .channels_max = 2, | ||
310 | .ops = { | ||
311 | .prepare = cs_capture_pcm_prepare, | ||
312 | .cleanup = cs_capture_pcm_cleanup | ||
313 | }, | ||
314 | }; | ||
315 | |||
316 | static const struct hda_pcm_stream cs_pcm_digital_playback = { | ||
317 | .substreams = 1, | ||
318 | .channels_min = 2, | ||
319 | .channels_max = 2, | ||
320 | .ops = { | ||
321 | .open = cs_dig_playback_pcm_open, | ||
322 | .close = cs_dig_playback_pcm_close, | ||
323 | .prepare = cs_dig_playback_pcm_prepare, | ||
324 | .cleanup = cs_dig_playback_pcm_cleanup | ||
325 | }, | ||
326 | }; | ||
327 | |||
328 | static const struct hda_pcm_stream cs_pcm_digital_capture = { | ||
329 | .substreams = 1, | ||
330 | .channels_min = 2, | ||
331 | .channels_max = 2, | ||
332 | }; | ||
333 | |||
334 | static int cs_build_pcms(struct hda_codec *codec) | ||
335 | { | ||
336 | struct cs_spec *spec = codec->spec; | ||
337 | struct hda_pcm *info = spec->pcm_rec; | ||
338 | |||
339 | codec->pcm_info = info; | ||
340 | codec->num_pcms = 0; | ||
341 | |||
342 | info->name = "Cirrus Analog"; | ||
343 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cs_pcm_analog_playback; | ||
344 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0]; | ||
345 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
346 | spec->multiout.max_channels; | ||
347 | if (spec->speaker_2_1) | ||
348 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
349 | snd_pcm_2_1_chmaps; | ||
350 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; | ||
351 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
352 | spec->adc_nid[spec->cur_input]; | ||
353 | codec->num_pcms++; | ||
354 | |||
355 | if (!spec->multiout.dig_out_nid && !spec->dig_in) | ||
356 | return 0; | ||
357 | |||
358 | info++; | ||
359 | info->name = "Cirrus Digital"; | ||
360 | info->pcm_type = spec->autocfg.dig_out_type[0]; | ||
361 | if (!info->pcm_type) | ||
362 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
363 | if (spec->multiout.dig_out_nid) { | ||
364 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
365 | cs_pcm_digital_playback; | ||
366 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
367 | spec->multiout.dig_out_nid; | ||
368 | } | ||
369 | if (spec->dig_in) { | ||
370 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
371 | cs_pcm_digital_capture; | ||
372 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; | ||
373 | } | ||
374 | codec->num_pcms++; | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * parse codec topology | ||
381 | */ | ||
382 | |||
383 | static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin) | ||
384 | { | ||
385 | hda_nid_t dac; | ||
386 | if (!pin) | ||
387 | return 0; | ||
388 | if (snd_hda_get_connections(codec, pin, &dac, 1) != 1) | ||
389 | return 0; | ||
390 | return dac; | ||
391 | } | ||
392 | |||
393 | static int is_ext_mic(struct hda_codec *codec, unsigned int idx) | ||
394 | { | ||
395 | struct cs_spec *spec = codec->spec; | ||
396 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
397 | hda_nid_t pin = cfg->inputs[idx].pin; | ||
398 | unsigned int val; | ||
399 | if (!is_jack_detectable(codec, pin)) | ||
400 | return 0; | ||
401 | val = snd_hda_codec_get_pincfg(codec, pin); | ||
402 | return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); | ||
403 | } | ||
404 | |||
405 | static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, | ||
406 | unsigned int *idxp) | ||
407 | { | ||
408 | int i, idx; | ||
409 | hda_nid_t nid; | ||
410 | |||
411 | nid = codec->start_nid; | ||
412 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
413 | unsigned int type; | ||
414 | type = get_wcaps_type(get_wcaps(codec, nid)); | ||
415 | if (type != AC_WID_AUD_IN) | ||
416 | continue; | ||
417 | idx = snd_hda_get_conn_index(codec, nid, pin, false); | ||
418 | if (idx >= 0) { | ||
419 | *idxp = idx; | ||
420 | return nid; | ||
421 | } | ||
422 | } | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int is_active_pin(struct hda_codec *codec, hda_nid_t nid) | ||
427 | { | ||
428 | unsigned int val; | ||
429 | val = snd_hda_codec_get_pincfg(codec, nid); | ||
430 | return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); | ||
431 | } | ||
432 | |||
433 | static int parse_output(struct hda_codec *codec) | ||
434 | { | ||
435 | struct cs_spec *spec = codec->spec; | ||
436 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
437 | int i, extra_nids; | ||
438 | hda_nid_t dac; | ||
439 | |||
440 | for (i = 0; i < cfg->line_outs; i++) { | ||
441 | dac = get_dac(codec, cfg->line_out_pins[i]); | ||
442 | if (!dac) | ||
443 | break; | ||
444 | spec->dac_nid[i] = dac; | ||
445 | } | ||
446 | spec->multiout.num_dacs = i; | ||
447 | spec->multiout.dac_nids = spec->dac_nid; | ||
448 | spec->multiout.max_channels = i * 2; | ||
449 | |||
450 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && i == 2) | ||
451 | spec->speaker_2_1 = 1; /* assume 2.1 speakers */ | ||
452 | |||
453 | /* add HP and speakers */ | ||
454 | extra_nids = 0; | ||
455 | for (i = 0; i < cfg->hp_outs; i++) { | ||
456 | dac = get_dac(codec, cfg->hp_pins[i]); | ||
457 | if (!dac) | ||
458 | break; | ||
459 | if (!i) | ||
460 | spec->multiout.hp_nid = dac; | ||
461 | else | ||
462 | spec->multiout.extra_out_nid[extra_nids++] = dac; | ||
463 | } | ||
464 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
465 | dac = get_dac(codec, cfg->speaker_pins[i]); | ||
466 | if (!dac) | ||
467 | break; | ||
468 | spec->multiout.extra_out_nid[extra_nids++] = dac; | ||
469 | } | ||
470 | |||
471 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
472 | cfg->speaker_outs = cfg->line_outs; | ||
473 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
474 | sizeof(cfg->speaker_pins)); | ||
475 | cfg->line_outs = 0; | ||
476 | memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int parse_input(struct hda_codec *codec) | ||
483 | { | ||
484 | struct cs_spec *spec = codec->spec; | ||
485 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
486 | int i; | ||
487 | |||
488 | for (i = 0; i < cfg->num_inputs; i++) { | ||
489 | hda_nid_t pin = cfg->inputs[i].pin; | ||
490 | spec->input_idx[spec->num_inputs] = i; | ||
491 | spec->capsrc_idx[i] = spec->num_inputs++; | ||
492 | spec->cur_input = i; | ||
493 | spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]); | ||
494 | } | ||
495 | if (!spec->num_inputs) | ||
496 | return 0; | ||
497 | |||
498 | /* check whether the automatic mic switch is available */ | ||
499 | if (spec->num_inputs == 2 && | ||
500 | cfg->inputs[0].type == AUTO_PIN_MIC && | ||
501 | cfg->inputs[1].type == AUTO_PIN_MIC) { | ||
502 | if (is_ext_mic(codec, cfg->inputs[0].pin)) { | ||
503 | if (!is_ext_mic(codec, cfg->inputs[1].pin)) { | ||
504 | spec->mic_detect = 1; | ||
505 | spec->automic_idx = 0; | ||
506 | } | ||
507 | } else { | ||
508 | if (is_ext_mic(codec, cfg->inputs[1].pin)) { | ||
509 | spec->mic_detect = 1; | ||
510 | spec->automic_idx = 1; | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | |||
518 | static int parse_digital_output(struct hda_codec *codec) | ||
519 | { | ||
520 | struct cs_spec *spec = codec->spec; | ||
521 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
522 | hda_nid_t nid; | ||
523 | |||
524 | if (!cfg->dig_outs) | ||
525 | return 0; | ||
526 | if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1) | ||
527 | return 0; | ||
528 | spec->multiout.dig_out_nid = nid; | ||
529 | spec->multiout.share_spdif = 1; | ||
530 | if (cfg->dig_outs > 1 && | ||
531 | snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) { | ||
532 | spec->slave_dig_outs[0] = nid; | ||
533 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
534 | } | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int parse_digital_input(struct hda_codec *codec) | ||
539 | { | ||
540 | struct cs_spec *spec = codec->spec; | ||
541 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
542 | int idx; | ||
543 | |||
544 | if (cfg->dig_in_pin) | ||
545 | spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx); | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * create mixer controls | ||
551 | */ | ||
552 | |||
553 | static const char * const dir_sfx[2] = { "Playback", "Capture" }; | ||
554 | |||
555 | static int add_mute(struct hda_codec *codec, const char *name, int index, | ||
556 | unsigned int pval, int dir, struct snd_kcontrol **kctlp) | ||
557 | { | ||
558 | char tmp[44]; | ||
559 | struct snd_kcontrol_new knew = | ||
560 | HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT); | ||
561 | knew.private_value = pval; | ||
562 | snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); | ||
563 | *kctlp = snd_ctl_new1(&knew, codec); | ||
564 | (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; | ||
565 | return snd_hda_ctl_add(codec, 0, *kctlp); | ||
566 | } | ||
567 | |||
568 | static int add_volume(struct hda_codec *codec, const char *name, | ||
569 | int index, unsigned int pval, int dir, | ||
570 | struct snd_kcontrol **kctlp) | ||
571 | { | ||
572 | char tmp[44]; | ||
573 | struct snd_kcontrol_new knew = | ||
574 | HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); | ||
575 | knew.private_value = pval; | ||
576 | snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); | ||
577 | *kctlp = snd_ctl_new1(&knew, codec); | ||
578 | (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG; | ||
579 | return snd_hda_ctl_add(codec, 0, *kctlp); | ||
580 | } | ||
581 | |||
582 | static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) | ||
583 | { | ||
584 | unsigned int caps; | ||
585 | |||
586 | /* set the upper-limit for mixer amp to 0dB */ | ||
587 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); | ||
588 | caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT); | ||
589 | caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f) | ||
590 | << AC_AMPCAP_NUM_STEPS_SHIFT; | ||
591 | snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps); | ||
592 | } | ||
593 | |||
594 | static int add_vmaster(struct hda_codec *codec, hda_nid_t dac) | ||
595 | { | ||
596 | struct cs_spec *spec = codec->spec; | ||
597 | unsigned int tlv[4]; | ||
598 | int err; | ||
599 | |||
600 | spec->vmaster_sw = | ||
601 | snd_ctl_make_virtual_master("Master Playback Switch", NULL); | ||
602 | err = snd_hda_ctl_add(codec, dac, spec->vmaster_sw); | ||
603 | if (err < 0) | ||
604 | return err; | ||
605 | |||
606 | snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv); | ||
607 | spec->vmaster_vol = | ||
608 | snd_ctl_make_virtual_master("Master Playback Volume", tlv); | ||
609 | err = snd_hda_ctl_add(codec, dac, spec->vmaster_vol); | ||
610 | if (err < 0) | ||
611 | return err; | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | ||
616 | int num_ctls, int type) | ||
617 | { | ||
618 | struct cs_spec *spec = codec->spec; | ||
619 | const char *name; | ||
620 | int err, index; | ||
621 | struct snd_kcontrol *kctl; | ||
622 | static const char * const speakers[] = { | ||
623 | "Front Speaker", "Surround Speaker", "Bass Speaker" | ||
624 | }; | ||
625 | static const char * const line_outs[] = { | ||
626 | "Front Line Out", "Surround Line Out", "Bass Line Out" | ||
627 | }; | ||
628 | |||
629 | fix_volume_caps(codec, dac); | ||
630 | if (!spec->vmaster_sw) { | ||
631 | err = add_vmaster(codec, dac); | ||
632 | if (err < 0) | ||
633 | return err; | ||
634 | } | ||
635 | |||
636 | index = 0; | ||
637 | switch (type) { | ||
638 | case AUTO_PIN_HP_OUT: | ||
639 | name = "Headphone"; | ||
640 | index = idx; | ||
641 | break; | ||
642 | case AUTO_PIN_SPEAKER_OUT: | ||
643 | if (spec->speaker_2_1) | ||
644 | name = idx ? "Bass Speaker" : "Speaker"; | ||
645 | else if (num_ctls > 1) | ||
646 | name = speakers[idx]; | ||
647 | else | ||
648 | name = "Speaker"; | ||
649 | break; | ||
650 | default: | ||
651 | if (num_ctls > 1) | ||
652 | name = line_outs[idx]; | ||
653 | else | ||
654 | name = "Line Out"; | ||
655 | break; | ||
656 | } | ||
657 | |||
658 | err = add_mute(codec, name, index, | ||
659 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | ||
660 | if (err < 0) | ||
661 | return err; | ||
662 | err = snd_ctl_add_slave(spec->vmaster_sw, kctl); | ||
663 | if (err < 0) | ||
664 | return err; | ||
665 | |||
666 | err = add_volume(codec, name, index, | ||
667 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | ||
668 | if (err < 0) | ||
669 | return err; | ||
670 | err = snd_ctl_add_slave(spec->vmaster_vol, kctl); | ||
671 | if (err < 0) | ||
672 | return err; | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int build_output(struct hda_codec *codec) | ||
678 | { | ||
679 | struct cs_spec *spec = codec->spec; | ||
680 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
681 | int i, err; | ||
682 | |||
683 | for (i = 0; i < cfg->line_outs; i++) { | ||
684 | err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]), | ||
685 | i, cfg->line_outs, cfg->line_out_type); | ||
686 | if (err < 0) | ||
687 | return err; | ||
688 | } | ||
689 | for (i = 0; i < cfg->hp_outs; i++) { | ||
690 | err = add_output(codec, get_dac(codec, cfg->hp_pins[i]), | ||
691 | i, cfg->hp_outs, AUTO_PIN_HP_OUT); | ||
692 | if (err < 0) | ||
693 | return err; | ||
694 | } | ||
695 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
696 | err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]), | ||
697 | i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT); | ||
698 | if (err < 0) | ||
699 | return err; | ||
700 | } | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | /* | ||
705 | */ | ||
706 | |||
707 | static const struct snd_kcontrol_new cs_capture_ctls[] = { | ||
708 | HDA_BIND_SW("Capture Switch", 0), | ||
709 | HDA_BIND_VOL("Capture Volume", 0), | ||
710 | }; | ||
711 | |||
712 | static int change_cur_input(struct hda_codec *codec, unsigned int idx, | ||
713 | int force) | ||
714 | { | ||
715 | struct cs_spec *spec = codec->spec; | ||
716 | |||
717 | if (spec->cur_input == idx && !force) | ||
718 | return 0; | ||
719 | if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) { | ||
720 | /* stream is running, let's swap the current ADC */ | ||
721 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
722 | spec->cur_adc = spec->adc_nid[idx]; | ||
723 | snd_hda_codec_setup_stream(codec, spec->cur_adc, | ||
724 | spec->cur_adc_stream_tag, 0, | ||
725 | spec->cur_adc_format); | ||
726 | } | ||
727 | spec->cur_input = idx; | ||
728 | cs_update_input_select(codec); | ||
729 | return 1; | ||
730 | } | ||
731 | |||
732 | static int cs_capture_source_info(struct snd_kcontrol *kcontrol, | ||
733 | struct snd_ctl_elem_info *uinfo) | ||
734 | { | ||
735 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
736 | struct cs_spec *spec = codec->spec; | ||
737 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
738 | unsigned int idx; | ||
739 | |||
740 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
741 | uinfo->count = 1; | ||
742 | uinfo->value.enumerated.items = spec->num_inputs; | ||
743 | if (uinfo->value.enumerated.item >= spec->num_inputs) | ||
744 | uinfo->value.enumerated.item = spec->num_inputs - 1; | ||
745 | idx = spec->input_idx[uinfo->value.enumerated.item]; | ||
746 | snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg, | ||
747 | uinfo->value.enumerated.name, | ||
748 | sizeof(uinfo->value.enumerated.name), NULL); | ||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static int cs_capture_source_get(struct snd_kcontrol *kcontrol, | ||
753 | struct snd_ctl_elem_value *ucontrol) | ||
754 | { | ||
755 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
756 | struct cs_spec *spec = codec->spec; | ||
757 | ucontrol->value.enumerated.item[0] = spec->capsrc_idx[spec->cur_input]; | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | static int cs_capture_source_put(struct snd_kcontrol *kcontrol, | ||
762 | struct snd_ctl_elem_value *ucontrol) | ||
763 | { | ||
764 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
765 | struct cs_spec *spec = codec->spec; | ||
766 | unsigned int idx = ucontrol->value.enumerated.item[0]; | ||
767 | |||
768 | if (idx >= spec->num_inputs) | ||
769 | return -EINVAL; | ||
770 | idx = spec->input_idx[idx]; | ||
771 | return change_cur_input(codec, idx, 0); | ||
772 | } | ||
773 | |||
774 | static const struct snd_kcontrol_new cs_capture_source = { | ||
775 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
776 | .name = "Capture Source", | ||
777 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
778 | .info = cs_capture_source_info, | ||
779 | .get = cs_capture_source_get, | ||
780 | .put = cs_capture_source_put, | ||
781 | }; | ||
782 | |||
783 | static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, | ||
784 | struct hda_ctl_ops *ops) | ||
785 | { | ||
786 | struct cs_spec *spec = codec->spec; | ||
787 | struct hda_bind_ctls *bind; | ||
788 | int i, n; | ||
789 | |||
790 | bind = kzalloc(sizeof(*bind) + sizeof(long) * (spec->num_inputs + 1), | ||
791 | GFP_KERNEL); | ||
792 | if (!bind) | ||
793 | return NULL; | ||
794 | bind->ops = ops; | ||
795 | n = 0; | ||
796 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
797 | if (!spec->adc_nid[i]) | ||
798 | continue; | ||
799 | bind->values[n++] = | ||
800 | HDA_COMPOSE_AMP_VAL(spec->adc_nid[i], 3, | ||
801 | spec->adc_idx[i], HDA_INPUT); | ||
802 | } | ||
803 | return bind; | ||
804 | } | ||
805 | |||
806 | /* add a (input-boost) volume control to the given input pin */ | ||
807 | static int add_input_volume_control(struct hda_codec *codec, | ||
808 | struct auto_pin_cfg *cfg, | ||
809 | int item) | ||
810 | { | ||
811 | hda_nid_t pin = cfg->inputs[item].pin; | ||
812 | u32 caps; | ||
813 | const char *label; | ||
814 | struct snd_kcontrol *kctl; | ||
815 | |||
816 | if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP)) | ||
817 | return 0; | ||
818 | caps = query_amp_caps(codec, pin, HDA_INPUT); | ||
819 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
820 | if (caps <= 1) | ||
821 | return 0; | ||
822 | label = hda_get_autocfg_input_label(codec, cfg, item); | ||
823 | return add_volume(codec, label, 0, | ||
824 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl); | ||
825 | } | ||
826 | |||
827 | static int build_input(struct hda_codec *codec) | ||
828 | { | ||
829 | struct cs_spec *spec = codec->spec; | ||
830 | int i, err; | ||
831 | |||
832 | if (!spec->num_inputs) | ||
833 | return 0; | ||
834 | |||
835 | /* make bind-capture */ | ||
836 | spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); | ||
837 | spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); | ||
838 | for (i = 0; i < 2; i++) { | ||
839 | struct snd_kcontrol *kctl; | ||
840 | int n; | ||
841 | if (!spec->capture_bind[i]) | ||
842 | return -ENOMEM; | ||
843 | kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); | ||
844 | if (!kctl) | ||
845 | return -ENOMEM; | ||
846 | kctl->private_value = (long)spec->capture_bind[i]; | ||
847 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
848 | if (err < 0) | ||
849 | return err; | ||
850 | for (n = 0; n < AUTO_PIN_LAST; n++) { | ||
851 | if (!spec->adc_nid[n]) | ||
852 | continue; | ||
853 | err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]); | ||
854 | if (err < 0) | ||
855 | return err; | ||
856 | } | ||
857 | } | ||
858 | |||
859 | if (spec->num_inputs > 1 && !spec->mic_detect) { | ||
860 | err = snd_hda_ctl_add(codec, 0, | ||
861 | snd_ctl_new1(&cs_capture_source, codec)); | ||
862 | if (err < 0) | ||
863 | return err; | ||
864 | } | ||
865 | |||
866 | for (i = 0; i < spec->num_inputs; i++) { | ||
867 | err = add_input_volume_control(codec, &spec->autocfg, i); | ||
868 | if (err < 0) | ||
869 | return err; | ||
870 | } | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | */ | ||
877 | |||
878 | static int build_digital_output(struct hda_codec *codec) | ||
879 | { | ||
880 | struct cs_spec *spec = codec->spec; | ||
881 | int err; | ||
882 | |||
883 | if (!spec->multiout.dig_out_nid) | ||
884 | return 0; | ||
885 | |||
886 | err = snd_hda_create_dig_out_ctls(codec, spec->multiout.dig_out_nid, | ||
887 | spec->multiout.dig_out_nid, | ||
888 | spec->pcm_rec[1].pcm_type); | ||
889 | if (err < 0) | ||
890 | return err; | ||
891 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); | ||
892 | if (err < 0) | ||
893 | return err; | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static int build_digital_input(struct hda_codec *codec) | ||
898 | { | ||
899 | struct cs_spec *spec = codec->spec; | ||
900 | if (spec->dig_in) | ||
901 | return snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | ||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | /* | 155 | /* |
906 | * auto-mute and auto-mic switching | 156 | * auto-mute and auto-mic switching |
907 | * CS421x auto-output redirecting | 157 | * CS421x auto-output redirecting |
908 | * HP/SPK/SPDIF | 158 | * HP/SPK/SPDIF |
909 | */ | 159 | */ |
910 | 160 | ||
911 | static void cs_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) | 161 | static void cs_automute(struct hda_codec *codec) |
912 | { | 162 | { |
913 | struct cs_spec *spec = codec->spec; | 163 | struct cs_spec *spec = codec->spec; |
914 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
915 | unsigned int hp_present; | ||
916 | unsigned int spdif_present; | ||
917 | hda_nid_t nid; | ||
918 | int i; | ||
919 | |||
920 | spdif_present = 0; | ||
921 | if (cfg->dig_outs) { | ||
922 | nid = cfg->dig_out_pins[0]; | ||
923 | if (is_jack_detectable(codec, nid)) { | ||
924 | /* | ||
925 | TODO: SPDIF output redirect when SENSE_B is enabled. | ||
926 | Shared (SENSE_A) jack (e.g HP/mini-TOSLINK) | ||
927 | assumed. | ||
928 | */ | ||
929 | if (snd_hda_jack_detect(codec, nid) | ||
930 | /* && spec->sense_b */) | ||
931 | spdif_present = 1; | ||
932 | } | ||
933 | } | ||
934 | 164 | ||
935 | hp_present = 0; | 165 | /* mute HPs if spdif jack (SENSE_B) is present */ |
936 | for (i = 0; i < cfg->hp_outs; i++) { | 166 | spec->gen.master_mute = !!(spec->spdif_present && spec->sense_b); |
937 | nid = cfg->hp_pins[i]; | ||
938 | if (!is_jack_detectable(codec, nid)) | ||
939 | continue; | ||
940 | hp_present = snd_hda_jack_detect(codec, nid); | ||
941 | if (hp_present) | ||
942 | break; | ||
943 | } | ||
944 | 167 | ||
945 | /* mute speakers if spdif or hp jack is plugged in */ | 168 | snd_hda_gen_update_outputs(codec); |
946 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
947 | int pin_ctl = hp_present ? 0 : PIN_OUT; | ||
948 | /* detect on spdif is specific to CS4210 */ | ||
949 | if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID)) | ||
950 | pin_ctl = 0; | ||
951 | 169 | ||
952 | nid = cfg->speaker_pins[i]; | ||
953 | snd_hda_set_pin_ctl(codec, nid, pin_ctl); | ||
954 | } | ||
955 | if (spec->gpio_eapd_hp) { | 170 | if (spec->gpio_eapd_hp) { |
956 | unsigned int gpio = hp_present ? | 171 | unsigned int gpio = spec->gen.hp_jack_present ? |
957 | spec->gpio_eapd_hp : spec->gpio_eapd_speaker; | 172 | spec->gpio_eapd_hp : spec->gpio_eapd_speaker; |
958 | snd_hda_codec_write(codec, 0x01, 0, | 173 | snd_hda_codec_write(codec, 0x01, 0, |
959 | AC_VERB_SET_GPIO_DATA, gpio); | 174 | AC_VERB_SET_GPIO_DATA, gpio); |
960 | } | 175 | } |
961 | |||
962 | /* specific to CS4210 */ | ||
963 | if (spec->vendor_nid == CS4210_VENDOR_NID) { | ||
964 | /* mute HPs if spdif jack (SENSE_B) is present */ | ||
965 | for (i = 0; i < cfg->hp_outs; i++) { | ||
966 | nid = cfg->hp_pins[i]; | ||
967 | snd_hda_set_pin_ctl(codec, nid, | ||
968 | (spdif_present && spec->sense_b) ? 0 : PIN_HP); | ||
969 | } | ||
970 | |||
971 | /* SPDIF TX on/off */ | ||
972 | if (cfg->dig_outs) { | ||
973 | nid = cfg->dig_out_pins[0]; | ||
974 | snd_hda_set_pin_ctl(codec, nid, | ||
975 | spdif_present ? PIN_OUT : 0); | ||
976 | |||
977 | } | ||
978 | /* Update board GPIOs if neccessary ... */ | ||
979 | } | ||
980 | } | 176 | } |
981 | 177 | ||
982 | /* | 178 | static bool is_active_pin(struct hda_codec *codec, hda_nid_t nid) |
983 | * Auto-input redirect for CS421x | ||
984 | * Switch max 3 inputs of a single ADC (nid 3) | ||
985 | */ | ||
986 | |||
987 | static void cs_automic(struct hda_codec *codec, struct hda_jack_tbl *tbl) | ||
988 | { | 179 | { |
989 | struct cs_spec *spec = codec->spec; | 180 | unsigned int val; |
990 | struct auto_pin_cfg *cfg = &spec->autocfg; | 181 | val = snd_hda_codec_get_pincfg(codec, nid); |
991 | hda_nid_t nid; | 182 | return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); |
992 | unsigned int present; | ||
993 | |||
994 | nid = cfg->inputs[spec->automic_idx].pin; | ||
995 | present = snd_hda_jack_detect(codec, nid); | ||
996 | |||
997 | /* specific to CS421x, single ADC */ | ||
998 | if (spec->vendor_nid == CS420X_VENDOR_NID) { | ||
999 | if (present) | ||
1000 | change_cur_input(codec, spec->automic_idx, 0); | ||
1001 | else | ||
1002 | change_cur_input(codec, !spec->automic_idx, 0); | ||
1003 | } else { | ||
1004 | if (present) { | ||
1005 | if (spec->cur_input != spec->automic_idx) { | ||
1006 | spec->last_input = spec->cur_input; | ||
1007 | spec->cur_input = spec->automic_idx; | ||
1008 | } | ||
1009 | } else { | ||
1010 | spec->cur_input = spec->last_input; | ||
1011 | } | ||
1012 | cs_update_input_select(codec); | ||
1013 | } | ||
1014 | } | ||
1015 | |||
1016 | /* | ||
1017 | */ | ||
1018 | |||
1019 | static void init_output(struct hda_codec *codec) | ||
1020 | { | ||
1021 | struct cs_spec *spec = codec->spec; | ||
1022 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1023 | int i; | ||
1024 | |||
1025 | /* mute first */ | ||
1026 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
1027 | snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0, | ||
1028 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
1029 | if (spec->multiout.hp_nid) | ||
1030 | snd_hda_codec_write(codec, spec->multiout.hp_nid, 0, | ||
1031 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
1032 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) { | ||
1033 | if (!spec->multiout.extra_out_nid[i]) | ||
1034 | break; | ||
1035 | snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0, | ||
1036 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
1037 | } | ||
1038 | |||
1039 | /* set appropriate pin controls */ | ||
1040 | for (i = 0; i < cfg->line_outs; i++) | ||
1041 | snd_hda_set_pin_ctl(codec, cfg->line_out_pins[i], PIN_OUT); | ||
1042 | /* HP */ | ||
1043 | for (i = 0; i < cfg->hp_outs; i++) { | ||
1044 | hda_nid_t nid = cfg->hp_pins[i]; | ||
1045 | snd_hda_set_pin_ctl(codec, nid, PIN_HP); | ||
1046 | if (!cfg->speaker_outs) | ||
1047 | continue; | ||
1048 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | ||
1049 | snd_hda_jack_detect_enable_callback(codec, nid, HP_EVENT, cs_automute); | ||
1050 | spec->hp_detect = 1; | ||
1051 | } | ||
1052 | } | ||
1053 | |||
1054 | /* Speaker */ | ||
1055 | for (i = 0; i < cfg->speaker_outs; i++) | ||
1056 | snd_hda_set_pin_ctl(codec, cfg->speaker_pins[i], PIN_OUT); | ||
1057 | |||
1058 | /* SPDIF is enabled on presence detect for CS421x */ | ||
1059 | if (spec->hp_detect || spec->spdif_detect) | ||
1060 | cs_automute(codec, NULL); | ||
1061 | } | 183 | } |
1062 | 184 | ||
1063 | static void init_input(struct hda_codec *codec) | 185 | static void init_input_coef(struct hda_codec *codec) |
1064 | { | 186 | { |
1065 | struct cs_spec *spec = codec->spec; | 187 | struct cs_spec *spec = codec->spec; |
1066 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1067 | unsigned int coef; | 188 | unsigned int coef; |
1068 | int i; | ||
1069 | 189 | ||
1070 | for (i = 0; i < cfg->num_inputs; i++) { | ||
1071 | unsigned int ctl; | ||
1072 | hda_nid_t pin = cfg->inputs[i].pin; | ||
1073 | if (!spec->adc_nid[i]) | ||
1074 | continue; | ||
1075 | /* set appropriate pin control and mute first */ | ||
1076 | ctl = PIN_IN; | ||
1077 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | ||
1078 | ctl |= snd_hda_get_default_vref(codec, pin); | ||
1079 | snd_hda_set_pin_ctl(codec, pin, ctl); | ||
1080 | snd_hda_codec_write(codec, spec->adc_nid[i], 0, | ||
1081 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1082 | AMP_IN_MUTE(spec->adc_idx[i])); | ||
1083 | if (spec->mic_detect && spec->automic_idx == i) | ||
1084 | snd_hda_jack_detect_enable_callback(codec, pin, MIC_EVENT, cs_automic); | ||
1085 | } | ||
1086 | /* CS420x has multiple ADC, CS421x has single ADC */ | 190 | /* CS420x has multiple ADC, CS421x has single ADC */ |
1087 | if (spec->vendor_nid == CS420X_VENDOR_NID) { | 191 | if (spec->vendor_nid == CS420X_VENDOR_NID) { |
1088 | change_cur_input(codec, spec->cur_input, 1); | ||
1089 | if (spec->mic_detect) | ||
1090 | cs_automic(codec, NULL); | ||
1091 | |||
1092 | coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); | 192 | coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); |
1093 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | 193 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) |
1094 | coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ | 194 | coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ |
@@ -1099,13 +199,6 @@ static void init_input(struct hda_codec *codec) | |||
1099 | */ | 199 | */ |
1100 | 200 | ||
1101 | cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); | 201 | cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); |
1102 | } else { | ||
1103 | if (spec->mic_detect) | ||
1104 | cs_automic(codec, NULL); | ||
1105 | else { | ||
1106 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | ||
1107 | cs_update_input_select(codec); | ||
1108 | } | ||
1109 | } | 202 | } |
1110 | } | 203 | } |
1111 | 204 | ||
@@ -1178,7 +271,7 @@ static const struct hda_verb cs_errata_init_verbs[] = { | |||
1178 | }; | 271 | }; |
1179 | 272 | ||
1180 | /* SPDIF setup */ | 273 | /* SPDIF setup */ |
1181 | static void init_digital(struct hda_codec *codec) | 274 | static void init_digital_coef(struct hda_codec *codec) |
1182 | { | 275 | { |
1183 | unsigned int coef; | 276 | unsigned int coef; |
1184 | 277 | ||
@@ -1201,7 +294,7 @@ static int cs_init(struct hda_codec *codec) | |||
1201 | 294 | ||
1202 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 295 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
1203 | 296 | ||
1204 | snd_hda_gen_apply_verbs(codec); | 297 | snd_hda_gen_init(codec); |
1205 | 298 | ||
1206 | if (spec->gpio_mask) { | 299 | if (spec->gpio_mask) { |
1207 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, | 300 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, |
@@ -1212,53 +305,17 @@ static int cs_init(struct hda_codec *codec) | |||
1212 | spec->gpio_data); | 305 | spec->gpio_data); |
1213 | } | 306 | } |
1214 | 307 | ||
1215 | init_output(codec); | 308 | init_input_coef(codec); |
1216 | init_input(codec); | 309 | init_digital_coef(codec); |
1217 | init_digital(codec); | ||
1218 | |||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | static int cs_build_controls(struct hda_codec *codec) | ||
1223 | { | ||
1224 | struct cs_spec *spec = codec->spec; | ||
1225 | int err; | ||
1226 | |||
1227 | err = build_output(codec); | ||
1228 | if (err < 0) | ||
1229 | return err; | ||
1230 | err = build_input(codec); | ||
1231 | if (err < 0) | ||
1232 | return err; | ||
1233 | err = build_digital_output(codec); | ||
1234 | if (err < 0) | ||
1235 | return err; | ||
1236 | err = build_digital_input(codec); | ||
1237 | if (err < 0) | ||
1238 | return err; | ||
1239 | err = cs_init(codec); | ||
1240 | if (err < 0) | ||
1241 | return err; | ||
1242 | |||
1243 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1244 | if (err < 0) | ||
1245 | return err; | ||
1246 | 310 | ||
1247 | return 0; | 311 | return 0; |
1248 | } | 312 | } |
1249 | 313 | ||
1250 | static void cs_free(struct hda_codec *codec) | 314 | #define cs_free snd_hda_gen_free |
1251 | { | ||
1252 | struct cs_spec *spec = codec->spec; | ||
1253 | kfree(spec->capture_bind[0]); | ||
1254 | kfree(spec->capture_bind[1]); | ||
1255 | snd_hda_gen_free(&spec->gen); | ||
1256 | kfree(codec->spec); | ||
1257 | } | ||
1258 | 315 | ||
1259 | static const struct hda_codec_ops cs_patch_ops = { | 316 | static const struct hda_codec_ops cs_patch_ops = { |
1260 | .build_controls = cs_build_controls, | 317 | .build_controls = snd_hda_gen_build_controls, |
1261 | .build_pcms = cs_build_pcms, | 318 | .build_pcms = snd_hda_gen_build_pcms, |
1262 | .init = cs_init, | 319 | .init = cs_init, |
1263 | .free = cs_free, | 320 | .free = cs_free, |
1264 | .unsol_event = snd_hda_jack_unsol_event, | 321 | .unsol_event = snd_hda_jack_unsol_event, |
@@ -1269,22 +326,14 @@ static int cs_parse_auto_config(struct hda_codec *codec) | |||
1269 | struct cs_spec *spec = codec->spec; | 326 | struct cs_spec *spec = codec->spec; |
1270 | int err; | 327 | int err; |
1271 | 328 | ||
1272 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | 329 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); |
1273 | if (err < 0) | 330 | if (err < 0) |
1274 | return err; | 331 | return err; |
1275 | 332 | ||
1276 | err = parse_output(codec); | 333 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
1277 | if (err < 0) | ||
1278 | return err; | ||
1279 | err = parse_input(codec); | ||
1280 | if (err < 0) | ||
1281 | return err; | ||
1282 | err = parse_digital_output(codec); | ||
1283 | if (err < 0) | ||
1284 | return err; | ||
1285 | err = parse_digital_input(codec); | ||
1286 | if (err < 0) | 334 | if (err < 0) |
1287 | return err; | 335 | return err; |
336 | |||
1288 | return 0; | 337 | return 0; |
1289 | } | 338 | } |
1290 | 339 | ||
@@ -1434,18 +483,28 @@ static const struct hda_fixup cs420x_fixups[] = { | |||
1434 | }, | 483 | }, |
1435 | }; | 484 | }; |
1436 | 485 | ||
1437 | static int patch_cs420x(struct hda_codec *codec) | 486 | static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) |
1438 | { | 487 | { |
1439 | struct cs_spec *spec; | 488 | struct cs_spec *spec; |
1440 | int err; | ||
1441 | 489 | ||
1442 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 490 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1443 | if (!spec) | 491 | if (!spec) |
1444 | return -ENOMEM; | 492 | return NULL; |
1445 | codec->spec = spec; | 493 | codec->spec = spec; |
1446 | snd_hda_gen_init(&spec->gen); | 494 | spec->vendor_nid = vendor_nid; |
495 | snd_hda_gen_spec_init(&spec->gen); | ||
496 | |||
497 | return spec; | ||
498 | } | ||
499 | |||
500 | static int patch_cs420x(struct hda_codec *codec) | ||
501 | { | ||
502 | struct cs_spec *spec; | ||
503 | int err; | ||
1447 | 504 | ||
1448 | spec->vendor_nid = CS420X_VENDOR_NID; | 505 | spec = cs_alloc_spec(codec, CS420X_VENDOR_NID); |
506 | if (!spec) | ||
507 | return -ENOMEM; | ||
1449 | 508 | ||
1450 | snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl, | 509 | snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl, |
1451 | cs420x_fixups); | 510 | cs420x_fixups); |
@@ -1463,7 +522,6 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1463 | 522 | ||
1464 | error: | 523 | error: |
1465 | cs_free(codec); | 524 | cs_free(codec); |
1466 | codec->spec = NULL; | ||
1467 | return err; | 525 | return err; |
1468 | } | 526 | } |
1469 | 527 | ||
@@ -1622,7 +680,7 @@ static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol, | |||
1622 | } | 680 | } |
1623 | } | 681 | } |
1624 | 682 | ||
1625 | static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = { | 683 | static const struct snd_kcontrol_new cs421x_speaker_boost_ctl = { |
1626 | 684 | ||
1627 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 685 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1628 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 686 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
@@ -1667,20 +725,44 @@ static void cs4210_pinmux_init(struct hda_codec *codec) | |||
1667 | } | 725 | } |
1668 | } | 726 | } |
1669 | 727 | ||
1670 | static void init_cs421x_digital(struct hda_codec *codec) | 728 | static void cs4210_spdif_automute(struct hda_codec *codec, |
729 | struct hda_jack_tbl *tbl) | ||
1671 | { | 730 | { |
1672 | struct cs_spec *spec = codec->spec; | 731 | struct cs_spec *spec = codec->spec; |
1673 | struct auto_pin_cfg *cfg = &spec->autocfg; | 732 | bool spdif_present = false; |
1674 | int i; | 733 | hda_nid_t spdif_pin = spec->gen.autocfg.dig_out_pins[0]; |
734 | |||
735 | /* detect on spdif is specific to CS4210 */ | ||
736 | if (!spec->spdif_detect || | ||
737 | spec->vendor_nid != CS4210_VENDOR_NID) | ||
738 | return; | ||
1675 | 739 | ||
740 | spdif_present = snd_hda_jack_detect(codec, spdif_pin); | ||
741 | if (spdif_present == spec->spdif_present) | ||
742 | return; | ||
743 | |||
744 | spec->spdif_present = spdif_present; | ||
745 | /* SPDIF TX on/off */ | ||
746 | if (spdif_present) | ||
747 | snd_hda_set_pin_ctl(codec, spdif_pin, | ||
748 | spdif_present ? PIN_OUT : 0); | ||
749 | |||
750 | cs_automute(codec); | ||
751 | } | ||
752 | |||
753 | static void parse_cs421x_digital(struct hda_codec *codec) | ||
754 | { | ||
755 | struct cs_spec *spec = codec->spec; | ||
756 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
757 | int i; | ||
1676 | 758 | ||
1677 | for (i = 0; i < cfg->dig_outs; i++) { | 759 | for (i = 0; i < cfg->dig_outs; i++) { |
1678 | hda_nid_t nid = cfg->dig_out_pins[i]; | 760 | hda_nid_t nid = cfg->dig_out_pins[i]; |
1679 | if (!cfg->speaker_outs) | ||
1680 | continue; | ||
1681 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 761 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { |
1682 | snd_hda_jack_detect_enable_callback(codec, nid, SPDIF_EVENT, cs_automute); | ||
1683 | spec->spdif_detect = 1; | 762 | spec->spdif_detect = 1; |
763 | snd_hda_jack_detect_enable_callback(codec, nid, | ||
764 | SPDIF_EVENT, | ||
765 | cs4210_spdif_automute); | ||
1684 | } | 766 | } |
1685 | } | 767 | } |
1686 | } | 768 | } |
@@ -1695,6 +777,8 @@ static int cs421x_init(struct hda_codec *codec) | |||
1695 | cs4210_pinmux_init(codec); | 777 | cs4210_pinmux_init(codec); |
1696 | } | 778 | } |
1697 | 779 | ||
780 | snd_hda_gen_init(codec); | ||
781 | |||
1698 | if (spec->gpio_mask) { | 782 | if (spec->gpio_mask) { |
1699 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, | 783 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, |
1700 | spec->gpio_mask); | 784 | spec->gpio_mask); |
@@ -1704,233 +788,61 @@ static int cs421x_init(struct hda_codec *codec) | |||
1704 | spec->gpio_data); | 788 | spec->gpio_data); |
1705 | } | 789 | } |
1706 | 790 | ||
1707 | init_output(codec); | 791 | init_input_coef(codec); |
1708 | init_input(codec); | ||
1709 | init_cs421x_digital(codec); | ||
1710 | 792 | ||
1711 | return 0; | 793 | cs4210_spdif_automute(codec, NULL); |
1712 | } | ||
1713 | 794 | ||
1714 | /* | ||
1715 | * CS4210 Input MUX (1 ADC) | ||
1716 | */ | ||
1717 | static int cs421x_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
1718 | struct snd_ctl_elem_info *uinfo) | ||
1719 | { | ||
1720 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1721 | struct cs_spec *spec = codec->spec; | ||
1722 | |||
1723 | return snd_hda_input_mux_info(&spec->input_mux, uinfo); | ||
1724 | } | ||
1725 | |||
1726 | static int cs421x_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
1727 | struct snd_ctl_elem_value *ucontrol) | ||
1728 | { | ||
1729 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1730 | struct cs_spec *spec = codec->spec; | ||
1731 | |||
1732 | ucontrol->value.enumerated.item[0] = spec->cur_input; | ||
1733 | return 0; | 795 | return 0; |
1734 | } | 796 | } |
1735 | 797 | ||
1736 | static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, | 798 | static int cs421x_build_controls(struct hda_codec *codec) |
1737 | struct snd_ctl_elem_value *ucontrol) | ||
1738 | { | ||
1739 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1740 | struct cs_spec *spec = codec->spec; | ||
1741 | |||
1742 | return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol, | ||
1743 | spec->adc_nid[0], &spec->cur_input); | ||
1744 | |||
1745 | } | ||
1746 | |||
1747 | static const struct snd_kcontrol_new cs421x_capture_source = { | ||
1748 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1749 | .name = "Capture Source", | ||
1750 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
1751 | .info = cs421x_mux_enum_info, | ||
1752 | .get = cs421x_mux_enum_get, | ||
1753 | .put = cs421x_mux_enum_put, | ||
1754 | }; | ||
1755 | |||
1756 | static int cs421x_add_input_volume_control(struct hda_codec *codec, int item) | ||
1757 | { | ||
1758 | struct cs_spec *spec = codec->spec; | ||
1759 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1760 | const struct hda_input_mux *imux = &spec->input_mux; | ||
1761 | hda_nid_t pin = cfg->inputs[item].pin; | ||
1762 | struct snd_kcontrol *kctl; | ||
1763 | u32 caps; | ||
1764 | |||
1765 | if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP)) | ||
1766 | return 0; | ||
1767 | |||
1768 | caps = query_amp_caps(codec, pin, HDA_INPUT); | ||
1769 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
1770 | if (caps <= 1) | ||
1771 | return 0; | ||
1772 | |||
1773 | return add_volume(codec, imux->items[item].label, 0, | ||
1774 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl); | ||
1775 | } | ||
1776 | |||
1777 | /* add a (input-boost) volume control to the given input pin */ | ||
1778 | static int build_cs421x_input(struct hda_codec *codec) | ||
1779 | { | ||
1780 | struct cs_spec *spec = codec->spec; | ||
1781 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1782 | struct hda_input_mux *imux = &spec->input_mux; | ||
1783 | int i, err, type_idx; | ||
1784 | const char *label; | ||
1785 | |||
1786 | if (!spec->num_inputs) | ||
1787 | return 0; | ||
1788 | |||
1789 | /* make bind-capture */ | ||
1790 | spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); | ||
1791 | spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); | ||
1792 | for (i = 0; i < 2; i++) { | ||
1793 | struct snd_kcontrol *kctl; | ||
1794 | int n; | ||
1795 | if (!spec->capture_bind[i]) | ||
1796 | return -ENOMEM; | ||
1797 | kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); | ||
1798 | if (!kctl) | ||
1799 | return -ENOMEM; | ||
1800 | kctl->private_value = (long)spec->capture_bind[i]; | ||
1801 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
1802 | if (err < 0) | ||
1803 | return err; | ||
1804 | for (n = 0; n < AUTO_PIN_LAST; n++) { | ||
1805 | if (!spec->adc_nid[n]) | ||
1806 | continue; | ||
1807 | err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]); | ||
1808 | if (err < 0) | ||
1809 | return err; | ||
1810 | } | ||
1811 | } | ||
1812 | |||
1813 | /* Add Input MUX Items + Capture Volume/Switch */ | ||
1814 | for (i = 0; i < spec->num_inputs; i++) { | ||
1815 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
1816 | snd_hda_add_imux_item(imux, label, spec->adc_idx[i], &type_idx); | ||
1817 | |||
1818 | err = cs421x_add_input_volume_control(codec, i); | ||
1819 | if (err < 0) | ||
1820 | return err; | ||
1821 | } | ||
1822 | |||
1823 | /* | ||
1824 | Add 'Capture Source' Switch if | ||
1825 | * 2 inputs and no mic detec | ||
1826 | * 3 inputs | ||
1827 | */ | ||
1828 | if ((spec->num_inputs == 2 && !spec->mic_detect) || | ||
1829 | (spec->num_inputs == 3)) { | ||
1830 | |||
1831 | err = snd_hda_ctl_add(codec, spec->adc_nid[0], | ||
1832 | snd_ctl_new1(&cs421x_capture_source, codec)); | ||
1833 | if (err < 0) | ||
1834 | return err; | ||
1835 | } | ||
1836 | |||
1837 | return 0; | ||
1838 | } | ||
1839 | |||
1840 | /* Single DAC (Mute/Gain) */ | ||
1841 | static int build_cs421x_output(struct hda_codec *codec) | ||
1842 | { | 799 | { |
1843 | hda_nid_t dac = CS4210_DAC_NID; | ||
1844 | struct cs_spec *spec = codec->spec; | 800 | struct cs_spec *spec = codec->spec; |
1845 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1846 | struct snd_kcontrol *kctl; | ||
1847 | int err; | 801 | int err; |
1848 | char *name = "Master"; | ||
1849 | |||
1850 | fix_volume_caps(codec, dac); | ||
1851 | 802 | ||
1852 | err = add_mute(codec, name, 0, | 803 | err = snd_hda_gen_build_controls(codec); |
1853 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | ||
1854 | if (err < 0) | 804 | if (err < 0) |
1855 | return err; | 805 | return err; |
1856 | 806 | ||
1857 | err = add_volume(codec, name, 0, | 807 | if (spec->gen.autocfg.speaker_outs && |
1858 | HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); | 808 | spec->vendor_nid == CS4210_VENDOR_NID) { |
1859 | if (err < 0) | ||
1860 | return err; | ||
1861 | |||
1862 | if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) { | ||
1863 | err = snd_hda_ctl_add(codec, 0, | 809 | err = snd_hda_ctl_add(codec, 0, |
1864 | snd_ctl_new1(&cs421x_speaker_bost_ctl, codec)); | 810 | snd_ctl_new1(&cs421x_speaker_boost_ctl, codec)); |
1865 | if (err < 0) | 811 | if (err < 0) |
1866 | return err; | 812 | return err; |
1867 | } | 813 | } |
1868 | return err; | ||
1869 | } | ||
1870 | |||
1871 | static int cs421x_build_controls(struct hda_codec *codec) | ||
1872 | { | ||
1873 | struct cs_spec *spec = codec->spec; | ||
1874 | int err; | ||
1875 | |||
1876 | err = build_cs421x_output(codec); | ||
1877 | if (err < 0) | ||
1878 | return err; | ||
1879 | err = build_cs421x_input(codec); | ||
1880 | if (err < 0) | ||
1881 | return err; | ||
1882 | err = build_digital_output(codec); | ||
1883 | if (err < 0) | ||
1884 | return err; | ||
1885 | err = cs421x_init(codec); | ||
1886 | if (err < 0) | ||
1887 | return err; | ||
1888 | |||
1889 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1890 | if (err < 0) | ||
1891 | return err; | ||
1892 | |||
1893 | return 0; | 814 | return 0; |
1894 | } | 815 | } |
1895 | 816 | ||
1896 | static int parse_cs421x_input(struct hda_codec *codec) | 817 | static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) |
1897 | { | 818 | { |
1898 | struct cs_spec *spec = codec->spec; | 819 | unsigned int caps; |
1899 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1900 | int i; | ||
1901 | |||
1902 | for (i = 0; i < cfg->num_inputs; i++) { | ||
1903 | hda_nid_t pin = cfg->inputs[i].pin; | ||
1904 | spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]); | ||
1905 | spec->cur_input = spec->last_input = i; | ||
1906 | spec->num_inputs++; | ||
1907 | 820 | ||
1908 | /* check whether the automatic mic switch is available */ | 821 | /* set the upper-limit for mixer amp to 0dB */ |
1909 | if (is_ext_mic(codec, i) && cfg->num_inputs >= 2) { | 822 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); |
1910 | spec->mic_detect = 1; | 823 | caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT); |
1911 | spec->automic_idx = i; | 824 | caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f) |
1912 | } | 825 | << AC_AMPCAP_NUM_STEPS_SHIFT; |
1913 | } | 826 | snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps); |
1914 | return 0; | ||
1915 | } | 827 | } |
1916 | 828 | ||
1917 | static int cs421x_parse_auto_config(struct hda_codec *codec) | 829 | static int cs421x_parse_auto_config(struct hda_codec *codec) |
1918 | { | 830 | { |
1919 | struct cs_spec *spec = codec->spec; | 831 | struct cs_spec *spec = codec->spec; |
832 | hda_nid_t dac = CS4210_DAC_NID; | ||
1920 | int err; | 833 | int err; |
1921 | 834 | ||
1922 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | 835 | fix_volume_caps(codec, dac); |
1923 | if (err < 0) | 836 | |
1924 | return err; | 837 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); |
1925 | err = parse_output(codec); | ||
1926 | if (err < 0) | ||
1927 | return err; | ||
1928 | err = parse_cs421x_input(codec); | ||
1929 | if (err < 0) | 838 | if (err < 0) |
1930 | return err; | 839 | return err; |
1931 | err = parse_digital_output(codec); | 840 | |
841 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); | ||
1932 | if (err < 0) | 842 | if (err < 0) |
1933 | return err; | 843 | return err; |
844 | |||
845 | parse_cs421x_digital(codec); | ||
1934 | return 0; | 846 | return 0; |
1935 | } | 847 | } |
1936 | 848 | ||
@@ -1963,7 +875,7 @@ static int cs421x_suspend(struct hda_codec *codec) | |||
1963 | 875 | ||
1964 | static const struct hda_codec_ops cs421x_patch_ops = { | 876 | static const struct hda_codec_ops cs421x_patch_ops = { |
1965 | .build_controls = cs421x_build_controls, | 877 | .build_controls = cs421x_build_controls, |
1966 | .build_pcms = cs_build_pcms, | 878 | .build_pcms = snd_hda_gen_build_pcms, |
1967 | .init = cs421x_init, | 879 | .init = cs421x_init, |
1968 | .free = cs_free, | 880 | .free = cs_free, |
1969 | .unsol_event = snd_hda_jack_unsol_event, | 881 | .unsol_event = snd_hda_jack_unsol_event, |
@@ -1977,13 +889,9 @@ static int patch_cs4210(struct hda_codec *codec) | |||
1977 | struct cs_spec *spec; | 889 | struct cs_spec *spec; |
1978 | int err; | 890 | int err; |
1979 | 891 | ||
1980 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 892 | spec = cs_alloc_spec(codec, CS4210_VENDOR_NID); |
1981 | if (!spec) | 893 | if (!spec) |
1982 | return -ENOMEM; | 894 | return -ENOMEM; |
1983 | codec->spec = spec; | ||
1984 | snd_hda_gen_init(&spec->gen); | ||
1985 | |||
1986 | spec->vendor_nid = CS4210_VENDOR_NID; | ||
1987 | 895 | ||
1988 | snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl, | 896 | snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl, |
1989 | cs421x_fixups); | 897 | cs421x_fixups); |
@@ -2008,7 +916,6 @@ static int patch_cs4210(struct hda_codec *codec) | |||
2008 | 916 | ||
2009 | error: | 917 | error: |
2010 | cs_free(codec); | 918 | cs_free(codec); |
2011 | codec->spec = NULL; | ||
2012 | return err; | 919 | return err; |
2013 | } | 920 | } |
2014 | 921 | ||
@@ -2017,13 +924,9 @@ static int patch_cs4213(struct hda_codec *codec) | |||
2017 | struct cs_spec *spec; | 924 | struct cs_spec *spec; |
2018 | int err; | 925 | int err; |
2019 | 926 | ||
2020 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 927 | spec = cs_alloc_spec(codec, CS4213_VENDOR_NID); |
2021 | if (!spec) | 928 | if (!spec) |
2022 | return -ENOMEM; | 929 | return -ENOMEM; |
2023 | codec->spec = spec; | ||
2024 | snd_hda_gen_init(&spec->gen); | ||
2025 | |||
2026 | spec->vendor_nid = CS4213_VENDOR_NID; | ||
2027 | 930 | ||
2028 | err = cs421x_parse_auto_config(codec); | 931 | err = cs421x_parse_auto_config(codec); |
2029 | if (err < 0) | 932 | if (err < 0) |
@@ -2034,7 +937,6 @@ static int patch_cs4213(struct hda_codec *codec) | |||
2034 | 937 | ||
2035 | error: | 938 | error: |
2036 | cs_free(codec); | 939 | cs_free(codec); |
2037 | codec->spec = NULL; | ||
2038 | return err; | 940 | return err; |
2039 | } | 941 | } |
2040 | 942 | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index c8fdaaefe702..9c6ce73b03c5 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -22,7 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
@@ -30,6 +29,9 @@ | |||
30 | #include "hda_codec.h" | 29 | #include "hda_codec.h" |
31 | #include "hda_local.h" | 30 | #include "hda_local.h" |
32 | #include "hda_auto_parser.h" | 31 | #include "hda_auto_parser.h" |
32 | #include "hda_jack.h" | ||
33 | #include "hda_generic.h" | ||
34 | |||
33 | #define NUM_PINS 11 | 35 | #define NUM_PINS 11 |
34 | 36 | ||
35 | 37 | ||
@@ -45,6 +47,10 @@ enum { | |||
45 | }; | 47 | }; |
46 | 48 | ||
47 | struct cmi_spec { | 49 | struct cmi_spec { |
50 | struct hda_gen_spec gen; | ||
51 | |||
52 | /* below are only for static models */ | ||
53 | |||
48 | int board_config; | 54 | int board_config; |
49 | unsigned int no_line_in: 1; /* no line-in (5-jack) */ | 55 | unsigned int no_line_in: 1; /* no line-in (5-jack) */ |
50 | unsigned int front_panel: 1; /* has front-panel 2-jack */ | 56 | unsigned int front_panel: 1; /* has front-panel 2-jack */ |
@@ -356,77 +362,6 @@ static int cmi9880_build_controls(struct hda_codec *codec) | |||
356 | return 0; | 362 | return 0; |
357 | } | 363 | } |
358 | 364 | ||
359 | /* fill in the multi_dac_nids table, which will decide | ||
360 | which audio widget to use for each channel */ | ||
361 | static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | ||
362 | { | ||
363 | struct cmi_spec *spec = codec->spec; | ||
364 | hda_nid_t nid; | ||
365 | int assigned[4]; | ||
366 | int i, j; | ||
367 | |||
368 | /* clear the table, only one c-media dac assumed here */ | ||
369 | memset(spec->dac_nids, 0, sizeof(spec->dac_nids)); | ||
370 | memset(assigned, 0, sizeof(assigned)); | ||
371 | /* check the pins we found */ | ||
372 | for (i = 0; i < cfg->line_outs; i++) { | ||
373 | nid = cfg->line_out_pins[i]; | ||
374 | /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */ | ||
375 | if (nid >= 0x0b && nid <= 0x0e) { | ||
376 | spec->dac_nids[i] = (nid - 0x0b) + 0x03; | ||
377 | assigned[nid - 0x0b] = 1; | ||
378 | } | ||
379 | } | ||
380 | /* left pin can be connect to any audio widget */ | ||
381 | for (i = 0; i < cfg->line_outs; i++) { | ||
382 | nid = cfg->line_out_pins[i]; | ||
383 | if (nid <= 0x0e) | ||
384 | continue; | ||
385 | /* search for an empty channel */ | ||
386 | for (j = 0; j < cfg->line_outs; j++) { | ||
387 | if (! assigned[j]) { | ||
388 | spec->dac_nids[i] = j + 0x03; | ||
389 | assigned[j] = 1; | ||
390 | break; | ||
391 | } | ||
392 | } | ||
393 | } | ||
394 | spec->num_dacs = cfg->line_outs; | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | /* create multi_init table, which is used for multichannel initialization */ | ||
399 | static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | ||
400 | { | ||
401 | struct cmi_spec *spec = codec->spec; | ||
402 | hda_nid_t nid; | ||
403 | int i, j, k; | ||
404 | |||
405 | /* clear the table, only one c-media dac assumed here */ | ||
406 | memset(spec->multi_init, 0, sizeof(spec->multi_init)); | ||
407 | for (j = 0, i = 0; i < cfg->line_outs; i++) { | ||
408 | nid = cfg->line_out_pins[i]; | ||
409 | /* set as output */ | ||
410 | spec->multi_init[j].nid = nid; | ||
411 | spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL; | ||
412 | spec->multi_init[j].param = PIN_OUT; | ||
413 | j++; | ||
414 | if (nid > 0x0e) { | ||
415 | /* set connection */ | ||
416 | spec->multi_init[j].nid = nid; | ||
417 | spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; | ||
418 | spec->multi_init[j].param = 0; | ||
419 | /* find the index in connect list */ | ||
420 | k = snd_hda_get_conn_index(codec, nid, | ||
421 | spec->dac_nids[i], 0); | ||
422 | if (k >= 0) | ||
423 | spec->multi_init[j].param = k; | ||
424 | j++; | ||
425 | } | ||
426 | } | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int cmi9880_init(struct hda_codec *codec) | 365 | static int cmi9880_init(struct hda_codec *codec) |
431 | { | 366 | { |
432 | struct cmi_spec *spec = codec->spec; | 367 | struct cmi_spec *spec = codec->spec; |
@@ -632,6 +567,36 @@ static const struct hda_codec_ops cmi9880_patch_ops = { | |||
632 | .free = cmi9880_free, | 567 | .free = cmi9880_free, |
633 | }; | 568 | }; |
634 | 569 | ||
570 | /* | ||
571 | * stuff for auto-parser | ||
572 | */ | ||
573 | static const struct hda_codec_ops cmi_auto_patch_ops = { | ||
574 | .build_controls = snd_hda_gen_build_controls, | ||
575 | .build_pcms = snd_hda_gen_build_pcms, | ||
576 | .init = snd_hda_gen_init, | ||
577 | .free = snd_hda_gen_free, | ||
578 | .unsol_event = snd_hda_jack_unsol_event, | ||
579 | }; | ||
580 | |||
581 | static int cmi_parse_auto_config(struct hda_codec *codec) | ||
582 | { | ||
583 | struct cmi_spec *spec = codec->spec; | ||
584 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
585 | int err; | ||
586 | |||
587 | snd_hda_gen_spec_init(&spec->gen); | ||
588 | |||
589 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); | ||
590 | if (err < 0) | ||
591 | return err; | ||
592 | err = snd_hda_gen_parse_auto_config(codec, cfg); | ||
593 | if (err < 0) | ||
594 | return err; | ||
595 | |||
596 | codec->patch_ops = cmi_auto_patch_ops; | ||
597 | return 0; | ||
598 | } | ||
599 | |||
635 | static int patch_cmi9880(struct hda_codec *codec) | 600 | static int patch_cmi9880(struct hda_codec *codec) |
636 | { | 601 | { |
637 | struct cmi_spec *spec; | 602 | struct cmi_spec *spec; |
@@ -650,6 +615,15 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
650 | spec->board_config = CMI_AUTO; /* try everything */ | 615 | spec->board_config = CMI_AUTO; /* try everything */ |
651 | } | 616 | } |
652 | 617 | ||
618 | if (spec->board_config == CMI_AUTO) { | ||
619 | int err = cmi_parse_auto_config(codec); | ||
620 | if (err < 0) { | ||
621 | snd_hda_gen_free(codec); | ||
622 | return err; | ||
623 | } | ||
624 | return 0; | ||
625 | } | ||
626 | |||
653 | /* copy default DAC NIDs */ | 627 | /* copy default DAC NIDs */ |
654 | memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); | 628 | memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); |
655 | spec->num_dacs = 4; | 629 | spec->num_dacs = 4; |
@@ -678,59 +652,13 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
678 | } | 652 | } |
679 | break; | 653 | break; |
680 | case CMI_ALLOUT: | 654 | case CMI_ALLOUT: |
655 | default: | ||
681 | spec->front_panel = 1; | 656 | spec->front_panel = 1; |
682 | spec->multiout.max_channels = 8; | 657 | spec->multiout.max_channels = 8; |
683 | spec->no_line_in = 1; | 658 | spec->no_line_in = 1; |
684 | spec->input_mux = &cmi9880_no_line_mux; | 659 | spec->input_mux = &cmi9880_no_line_mux; |
685 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; | 660 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; |
686 | break; | 661 | break; |
687 | case CMI_AUTO: | ||
688 | { | ||
689 | unsigned int port_e, port_f, port_g, port_h; | ||
690 | unsigned int port_spdifi, port_spdifo; | ||
691 | struct auto_pin_cfg cfg; | ||
692 | |||
693 | /* collect pin default configuration */ | ||
694 | port_e = snd_hda_codec_get_pincfg(codec, 0x0f); | ||
695 | port_f = snd_hda_codec_get_pincfg(codec, 0x10); | ||
696 | spec->front_panel = 1; | ||
697 | if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE || | ||
698 | get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) { | ||
699 | port_g = snd_hda_codec_get_pincfg(codec, 0x1f); | ||
700 | port_h = snd_hda_codec_get_pincfg(codec, 0x20); | ||
701 | spec->channel_modes = cmi9880_channel_modes; | ||
702 | /* no front panel */ | ||
703 | if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE || | ||
704 | get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) { | ||
705 | /* no optional rear panel */ | ||
706 | spec->board_config = CMI_MINIMAL; | ||
707 | spec->front_panel = 0; | ||
708 | spec->num_channel_modes = 2; | ||
709 | } else { | ||
710 | spec->board_config = CMI_MIN_FP; | ||
711 | spec->num_channel_modes = 3; | ||
712 | } | ||
713 | spec->input_mux = &cmi9880_basic_mux; | ||
714 | spec->multiout.max_channels = cmi9880_channel_modes[0].channels; | ||
715 | } else { | ||
716 | spec->input_mux = &cmi9880_basic_mux; | ||
717 | port_spdifi = snd_hda_codec_get_pincfg(codec, 0x13); | ||
718 | port_spdifo = snd_hda_codec_get_pincfg(codec, 0x12); | ||
719 | if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE) | ||
720 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; | ||
721 | if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE) | ||
722 | spec->dig_in_nid = CMI_DIG_IN_NID; | ||
723 | spec->multiout.max_channels = 8; | ||
724 | } | ||
725 | snd_hda_parse_pin_def_config(codec, &cfg, NULL); | ||
726 | if (cfg.line_outs) { | ||
727 | spec->multiout.max_channels = cfg.line_outs * 2; | ||
728 | cmi9880_fill_multi_dac_nids(codec, &cfg); | ||
729 | cmi9880_fill_multi_init(codec, &cfg); | ||
730 | } else | ||
731 | snd_printd("patch_cmedia: cannot detect association in defcfg\n"); | ||
732 | break; | ||
733 | } | ||
734 | } | 662 | } |
735 | 663 | ||
736 | spec->multiout.num_dacs = spec->num_dacs; | 664 | spec->multiout.num_dacs = spec->num_dacs; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 009b77a693cf..7d941ef54172 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include "hda_auto_parser.h" | 33 | #include "hda_auto_parser.h" |
34 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
35 | #include "hda_jack.h" | 35 | #include "hda_jack.h" |
36 | #include "hda_generic.h" | ||
37 | |||
38 | #define ENABLE_CXT_STATIC_QUIRKS | ||
36 | 39 | ||
37 | #define CXT_PIN_DIR_IN 0x00 | 40 | #define CXT_PIN_DIR_IN 0x00 |
38 | #define CXT_PIN_DIR_OUT 0x01 | 41 | #define CXT_PIN_DIR_OUT 0x01 |
@@ -53,27 +56,19 @@ | |||
53 | #define AUTO_MIC_PORTB (1 << 1) | 56 | #define AUTO_MIC_PORTB (1 << 1) |
54 | #define AUTO_MIC_PORTC (1 << 2) | 57 | #define AUTO_MIC_PORTC (1 << 2) |
55 | 58 | ||
56 | struct pin_dac_pair { | ||
57 | hda_nid_t pin; | ||
58 | hda_nid_t dac; | ||
59 | int type; | ||
60 | }; | ||
61 | |||
62 | struct imux_info { | ||
63 | hda_nid_t pin; /* input pin NID */ | ||
64 | hda_nid_t adc; /* connected ADC NID */ | ||
65 | hda_nid_t boost; /* optional boost volume NID */ | ||
66 | int index; /* corresponding to autocfg.input */ | ||
67 | }; | ||
68 | |||
69 | struct conexant_spec { | 59 | struct conexant_spec { |
70 | struct hda_gen_spec gen; | 60 | struct hda_gen_spec gen; |
71 | 61 | ||
62 | unsigned int beep_amp; | ||
63 | |||
64 | /* extra EAPD pins */ | ||
65 | unsigned int num_eapds; | ||
66 | hda_nid_t eapds[4]; | ||
67 | |||
68 | #ifdef ENABLE_CXT_STATIC_QUIRKS | ||
72 | const struct snd_kcontrol_new *mixers[5]; | 69 | const struct snd_kcontrol_new *mixers[5]; |
73 | int num_mixers; | 70 | int num_mixers; |
74 | hda_nid_t vmaster_nid; | 71 | hda_nid_t vmaster_nid; |
75 | struct hda_vmaster_mute_hook vmaster_mute; | ||
76 | bool vmaster_mute_led; | ||
77 | 72 | ||
78 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 73 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
79 | * don't forget NULL | 74 | * don't forget NULL |
@@ -90,11 +85,6 @@ struct conexant_spec { | |||
90 | unsigned int hp_present; | 85 | unsigned int hp_present; |
91 | unsigned int line_present; | 86 | unsigned int line_present; |
92 | unsigned int auto_mic; | 87 | unsigned int auto_mic; |
93 | int auto_mic_ext; /* imux_pins[] index for ext mic */ | ||
94 | int auto_mic_dock; /* imux_pins[] index for dock mic */ | ||
95 | int auto_mic_int; /* imux_pins[] index for int mic */ | ||
96 | unsigned int need_dac_fix; | ||
97 | hda_nid_t slave_dig_outs[2]; | ||
98 | 88 | ||
99 | /* capture */ | 89 | /* capture */ |
100 | unsigned int num_adc_nids; | 90 | unsigned int num_adc_nids; |
@@ -122,30 +112,13 @@ struct conexant_spec { | |||
122 | 112 | ||
123 | unsigned int spdif_route; | 113 | unsigned int spdif_route; |
124 | 114 | ||
125 | /* dynamic controls, init_verbs and input_mux */ | ||
126 | struct auto_pin_cfg autocfg; | ||
127 | struct hda_input_mux private_imux; | ||
128 | struct imux_info imux_info[HDA_MAX_NUM_INPUTS]; | ||
129 | hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS]; | ||
130 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | ||
131 | struct pin_dac_pair dac_info[8]; | ||
132 | int dac_info_filled; | ||
133 | |||
134 | unsigned int port_d_mode; | 115 | unsigned int port_d_mode; |
135 | unsigned int auto_mute:1; /* used in auto-parser */ | ||
136 | unsigned int detect_line:1; /* Line-out detection enabled */ | ||
137 | unsigned int automute_lines:1; /* automute line-out as well */ | ||
138 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | ||
139 | unsigned int dell_automute:1; | 116 | unsigned int dell_automute:1; |
140 | unsigned int dell_vostro:1; | 117 | unsigned int dell_vostro:1; |
141 | unsigned int ideapad:1; | 118 | unsigned int ideapad:1; |
142 | unsigned int thinkpad:1; | 119 | unsigned int thinkpad:1; |
143 | unsigned int hp_laptop:1; | 120 | unsigned int hp_laptop:1; |
144 | unsigned int asus:1; | 121 | unsigned int asus:1; |
145 | unsigned int pin_eapd_ctrls:1; | ||
146 | unsigned int fixup_stereo_dmic:1; | ||
147 | |||
148 | unsigned int adc_switching:1; | ||
149 | 122 | ||
150 | unsigned int ext_mic_present; | 123 | unsigned int ext_mic_present; |
151 | unsigned int recording; | 124 | unsigned int recording; |
@@ -161,14 +134,48 @@ struct conexant_spec { | |||
161 | unsigned int dc_enable; | 134 | unsigned int dc_enable; |
162 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ | 135 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ |
163 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ | 136 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ |
137 | #endif /* ENABLE_CXT_STATIC_QUIRKS */ | ||
138 | }; | ||
164 | 139 | ||
165 | unsigned int beep_amp; | ||
166 | 140 | ||
167 | /* extra EAPD pins */ | 141 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
168 | unsigned int num_eapds; | 142 | #define set_beep_amp(spec, nid, idx, dir) \ |
169 | hda_nid_t eapds[4]; | 143 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) |
144 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
145 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
146 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
147 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
148 | { } /* end */ | ||
170 | }; | 149 | }; |
171 | 150 | ||
151 | /* create beep controls if needed */ | ||
152 | static int add_beep_ctls(struct hda_codec *codec) | ||
153 | { | ||
154 | struct conexant_spec *spec = codec->spec; | ||
155 | int err; | ||
156 | |||
157 | if (spec->beep_amp) { | ||
158 | const struct snd_kcontrol_new *knew; | ||
159 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
160 | struct snd_kcontrol *kctl; | ||
161 | kctl = snd_ctl_new1(knew, codec); | ||
162 | if (!kctl) | ||
163 | return -ENOMEM; | ||
164 | kctl->private_value = spec->beep_amp; | ||
165 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
166 | if (err < 0) | ||
167 | return err; | ||
168 | } | ||
169 | } | ||
170 | return 0; | ||
171 | } | ||
172 | #else | ||
173 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
174 | #define add_beep_ctls(codec) 0 | ||
175 | #endif | ||
176 | |||
177 | |||
178 | #ifdef ENABLE_CXT_STATIC_QUIRKS | ||
172 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 179 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
173 | struct hda_codec *codec, | 180 | struct hda_codec *codec, |
174 | struct snd_pcm_substream *substream) | 181 | struct snd_pcm_substream *substream) |
@@ -337,8 +344,6 @@ static const struct hda_pcm_stream cx5051_pcm_analog_capture = { | |||
337 | }, | 344 | }, |
338 | }; | 345 | }; |
339 | 346 | ||
340 | static bool is_2_1_speaker(struct conexant_spec *spec); | ||
341 | |||
342 | static int conexant_build_pcms(struct hda_codec *codec) | 347 | static int conexant_build_pcms(struct hda_codec *codec) |
343 | { | 348 | { |
344 | struct conexant_spec *spec = codec->spec; | 349 | struct conexant_spec *spec = codec->spec; |
@@ -353,9 +358,6 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
353 | spec->multiout.max_channels; | 358 | spec->multiout.max_channels; |
354 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | 359 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = |
355 | spec->multiout.dac_nids[0]; | 360 | spec->multiout.dac_nids[0]; |
356 | if (is_2_1_speaker(spec)) | ||
357 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
358 | snd_pcm_2_1_chmaps; | ||
359 | if (spec->capture_stream) | 361 | if (spec->capture_stream) |
360 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; | 362 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; |
361 | else { | 363 | else { |
@@ -386,8 +388,6 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
386 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 388 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
387 | spec->dig_in_nid; | 389 | spec->dig_in_nid; |
388 | } | 390 | } |
389 | if (spec->slave_dig_outs[0]) | ||
390 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
391 | } | 391 | } |
392 | 392 | ||
393 | return 0; | 393 | return 0; |
@@ -435,7 +435,7 @@ static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg, | |||
435 | /* partial workaround for "azx_get_response timeout" */ | 435 | /* partial workaround for "azx_get_response timeout" */ |
436 | if (power_state == AC_PWRST_D0) | 436 | if (power_state == AC_PWRST_D0) |
437 | msleep(10); | 437 | msleep(10); |
438 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | 438 | snd_hda_codec_set_power_to_all(codec, fg, power_state); |
439 | } | 439 | } |
440 | 440 | ||
441 | static int conexant_init(struct hda_codec *codec) | 441 | static int conexant_init(struct hda_codec *codec) |
@@ -451,7 +451,6 @@ static int conexant_init(struct hda_codec *codec) | |||
451 | static void conexant_free(struct hda_codec *codec) | 451 | static void conexant_free(struct hda_codec *codec) |
452 | { | 452 | { |
453 | struct conexant_spec *spec = codec->spec; | 453 | struct conexant_spec *spec = codec->spec; |
454 | snd_hda_gen_free(&spec->gen); | ||
455 | snd_hda_detach_beep_device(codec); | 454 | snd_hda_detach_beep_device(codec); |
456 | kfree(spec); | 455 | kfree(spec); |
457 | } | 456 | } |
@@ -467,15 +466,6 @@ static const struct snd_kcontrol_new cxt_capture_mixers[] = { | |||
467 | {} | 466 | {} |
468 | }; | 467 | }; |
469 | 468 | ||
470 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
471 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
472 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
473 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
474 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
475 | { } /* end */ | ||
476 | }; | ||
477 | #endif | ||
478 | |||
479 | static const char * const slave_pfxs[] = { | 469 | static const char * const slave_pfxs[] = { |
480 | "Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE", | 470 | "Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE", |
481 | NULL | 471 | NULL |
@@ -524,10 +514,9 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
524 | } | 514 | } |
525 | if (spec->vmaster_nid && | 515 | if (spec->vmaster_nid && |
526 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 516 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
527 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", | 517 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
528 | NULL, slave_pfxs, | 518 | NULL, slave_pfxs, |
529 | "Playback Switch", true, | 519 | "Playback Switch"); |
530 | &spec->vmaster_mute.sw_kctl); | ||
531 | if (err < 0) | 520 | if (err < 0) |
532 | return err; | 521 | return err; |
533 | } | 522 | } |
@@ -538,22 +527,9 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
538 | return err; | 527 | return err; |
539 | } | 528 | } |
540 | 529 | ||
541 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 530 | err = add_beep_ctls(codec); |
542 | /* create beep controls if needed */ | 531 | if (err < 0) |
543 | if (spec->beep_amp) { | 532 | return err; |
544 | const struct snd_kcontrol_new *knew; | ||
545 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
546 | struct snd_kcontrol *kctl; | ||
547 | kctl = snd_ctl_new1(knew, codec); | ||
548 | if (!kctl) | ||
549 | return -ENOMEM; | ||
550 | kctl->private_value = spec->beep_amp; | ||
551 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
552 | if (err < 0) | ||
553 | return err; | ||
554 | } | ||
555 | } | ||
556 | #endif | ||
557 | 533 | ||
558 | return 0; | 534 | return 0; |
559 | } | 535 | } |
@@ -566,13 +542,6 @@ static const struct hda_codec_ops conexant_patch_ops = { | |||
566 | .set_power_state = conexant_set_power, | 542 | .set_power_state = conexant_set_power, |
567 | }; | 543 | }; |
568 | 544 | ||
569 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
570 | #define set_beep_amp(spec, nid, idx, dir) \ | ||
571 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) | ||
572 | #else | ||
573 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
574 | #endif | ||
575 | |||
576 | static int patch_conexant_auto(struct hda_codec *codec); | 545 | static int patch_conexant_auto(struct hda_codec *codec); |
577 | /* | 546 | /* |
578 | * EAPD control | 547 | * EAPD control |
@@ -656,8 +625,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
656 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 625 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
657 | spec->num_channel_mode, | 626 | spec->num_channel_mode, |
658 | &spec->multiout.max_channels); | 627 | &spec->multiout.max_channels); |
659 | if (err >= 0 && spec->need_dac_fix) | ||
660 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
661 | return err; | 628 | return err; |
662 | } | 629 | } |
663 | 630 | ||
@@ -2496,10 +2463,6 @@ static void conexant_check_dig_outs(struct hda_codec *codec, | |||
2496 | continue; | 2463 | continue; |
2497 | if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) | 2464 | if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) |
2498 | continue; | 2465 | continue; |
2499 | if (spec->slave_dig_outs[0]) | ||
2500 | nid_loc++; | ||
2501 | else | ||
2502 | nid_loc = spec->slave_dig_outs; | ||
2503 | } | 2466 | } |
2504 | } | 2467 | } |
2505 | 2468 | ||
@@ -3141,626 +3104,12 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3141 | return 0; | 3104 | return 0; |
3142 | } | 3105 | } |
3143 | 3106 | ||
3144 | /* | 3107 | #endif /* ENABLE_CXT_STATIC_QUIRKS */ |
3145 | * Automatic parser for CX20641 & co | ||
3146 | */ | ||
3147 | 3108 | ||
3148 | static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
3149 | struct hda_codec *codec, | ||
3150 | unsigned int stream_tag, | ||
3151 | unsigned int format, | ||
3152 | struct snd_pcm_substream *substream) | ||
3153 | { | ||
3154 | struct conexant_spec *spec = codec->spec; | ||
3155 | hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc; | ||
3156 | if (spec->adc_switching) { | ||
3157 | spec->cur_adc = adc; | ||
3158 | spec->cur_adc_stream_tag = stream_tag; | ||
3159 | spec->cur_adc_format = format; | ||
3160 | } | ||
3161 | snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format); | ||
3162 | return 0; | ||
3163 | } | ||
3164 | |||
3165 | static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3166 | struct hda_codec *codec, | ||
3167 | struct snd_pcm_substream *substream) | ||
3168 | { | ||
3169 | struct conexant_spec *spec = codec->spec; | ||
3170 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
3171 | spec->cur_adc = 0; | ||
3172 | return 0; | ||
3173 | } | ||
3174 | |||
3175 | static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { | ||
3176 | .substreams = 1, | ||
3177 | .channels_min = 2, | ||
3178 | .channels_max = 2, | ||
3179 | .nid = 0, /* fill later */ | ||
3180 | .ops = { | ||
3181 | .prepare = cx_auto_capture_pcm_prepare, | ||
3182 | .cleanup = cx_auto_capture_pcm_cleanup | ||
3183 | }, | ||
3184 | }; | ||
3185 | |||
3186 | static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; | ||
3187 | |||
3188 | #define get_connection_index(codec, mux, nid)\ | ||
3189 | snd_hda_get_conn_index(codec, mux, nid, 0) | ||
3190 | |||
3191 | /* get an unassigned DAC from the given list. | ||
3192 | * Return the nid if found and reduce the DAC list, or return zero if | ||
3193 | * not found | ||
3194 | */ | ||
3195 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, | ||
3196 | hda_nid_t *dacs, int *num_dacs) | ||
3197 | { | ||
3198 | int i, nums = *num_dacs; | ||
3199 | hda_nid_t ret = 0; | ||
3200 | |||
3201 | for (i = 0; i < nums; i++) { | ||
3202 | if (get_connection_index(codec, pin, dacs[i]) >= 0) { | ||
3203 | ret = dacs[i]; | ||
3204 | break; | ||
3205 | } | ||
3206 | } | ||
3207 | if (!ret) | ||
3208 | return 0; | ||
3209 | if (--nums > 0) | ||
3210 | memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t)); | ||
3211 | *num_dacs = nums; | ||
3212 | return ret; | ||
3213 | } | ||
3214 | |||
3215 | #define MAX_AUTO_DACS 5 | ||
3216 | |||
3217 | #define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */ | ||
3218 | |||
3219 | /* fill analog DAC list from the widget tree */ | ||
3220 | static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) | ||
3221 | { | ||
3222 | hda_nid_t nid, end_nid; | ||
3223 | int nums = 0; | ||
3224 | |||
3225 | end_nid = codec->start_nid + codec->num_nodes; | ||
3226 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
3227 | unsigned int wcaps = get_wcaps(codec, nid); | ||
3228 | unsigned int type = get_wcaps_type(wcaps); | ||
3229 | if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) { | ||
3230 | dacs[nums++] = nid; | ||
3231 | if (nums >= MAX_AUTO_DACS) | ||
3232 | break; | ||
3233 | } | ||
3234 | } | ||
3235 | return nums; | ||
3236 | } | ||
3237 | |||
3238 | /* fill pin_dac_pair list from the pin and dac list */ | ||
3239 | static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, | ||
3240 | int num_pins, hda_nid_t *dacs, int *rest, | ||
3241 | struct pin_dac_pair *filled, int nums, | ||
3242 | int type) | ||
3243 | { | ||
3244 | int i, start = nums; | ||
3245 | |||
3246 | for (i = 0; i < num_pins; i++, nums++) { | ||
3247 | filled[nums].pin = pins[i]; | ||
3248 | filled[nums].type = type; | ||
3249 | filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); | ||
3250 | if (filled[nums].dac) | ||
3251 | continue; | ||
3252 | if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) { | ||
3253 | filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG; | ||
3254 | continue; | ||
3255 | } | ||
3256 | if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) { | ||
3257 | filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG; | ||
3258 | continue; | ||
3259 | } | ||
3260 | snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]); | ||
3261 | } | ||
3262 | return nums; | ||
3263 | } | ||
3264 | |||
3265 | /* parse analog output paths */ | ||
3266 | static void cx_auto_parse_output(struct hda_codec *codec) | ||
3267 | { | ||
3268 | struct conexant_spec *spec = codec->spec; | ||
3269 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3270 | hda_nid_t dacs[MAX_AUTO_DACS]; | ||
3271 | int i, j, nums, rest; | ||
3272 | |||
3273 | rest = fill_cx_auto_dacs(codec, dacs); | ||
3274 | /* parse all analog output pins */ | ||
3275 | nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, | ||
3276 | dacs, &rest, spec->dac_info, 0, | ||
3277 | AUTO_PIN_LINE_OUT); | ||
3278 | nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, | ||
3279 | dacs, &rest, spec->dac_info, nums, | ||
3280 | AUTO_PIN_HP_OUT); | ||
3281 | nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, | ||
3282 | dacs, &rest, spec->dac_info, nums, | ||
3283 | AUTO_PIN_SPEAKER_OUT); | ||
3284 | spec->dac_info_filled = nums; | ||
3285 | /* fill multiout struct */ | ||
3286 | for (i = 0; i < nums; i++) { | ||
3287 | hda_nid_t dac = spec->dac_info[i].dac; | ||
3288 | if (!dac || (dac & DAC_SLAVE_FLAG)) | ||
3289 | continue; | ||
3290 | switch (spec->dac_info[i].type) { | ||
3291 | case AUTO_PIN_LINE_OUT: | ||
3292 | spec->private_dac_nids[spec->multiout.num_dacs] = dac; | ||
3293 | spec->multiout.num_dacs++; | ||
3294 | break; | ||
3295 | case AUTO_PIN_HP_OUT: | ||
3296 | case AUTO_PIN_SPEAKER_OUT: | ||
3297 | if (!spec->multiout.hp_nid) { | ||
3298 | spec->multiout.hp_nid = dac; | ||
3299 | break; | ||
3300 | } | ||
3301 | for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++) | ||
3302 | if (!spec->multiout.extra_out_nid[j]) { | ||
3303 | spec->multiout.extra_out_nid[j] = dac; | ||
3304 | break; | ||
3305 | } | ||
3306 | break; | ||
3307 | } | ||
3308 | } | ||
3309 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
3310 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
3311 | |||
3312 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3313 | if (is_jack_detectable(codec, cfg->hp_pins[i])) { | ||
3314 | spec->auto_mute = 1; | ||
3315 | break; | ||
3316 | } | ||
3317 | } | ||
3318 | if (spec->auto_mute && | ||
3319 | cfg->line_out_pins[0] && | ||
3320 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT && | ||
3321 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | ||
3322 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | ||
3323 | for (i = 0; i < cfg->line_outs; i++) { | ||
3324 | if (is_jack_detectable(codec, cfg->line_out_pins[i])) { | ||
3325 | spec->detect_line = 1; | ||
3326 | break; | ||
3327 | } | ||
3328 | } | ||
3329 | spec->automute_lines = spec->detect_line; | ||
3330 | } | ||
3331 | |||
3332 | spec->vmaster_nid = spec->private_dac_nids[0]; | ||
3333 | } | ||
3334 | |||
3335 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | ||
3336 | hda_nid_t *pins, bool on); | ||
3337 | |||
3338 | static void do_automute(struct hda_codec *codec, int num_pins, | ||
3339 | hda_nid_t *pins, bool on) | ||
3340 | { | ||
3341 | struct conexant_spec *spec = codec->spec; | ||
3342 | int i; | ||
3343 | for (i = 0; i < num_pins; i++) | ||
3344 | snd_hda_set_pin_ctl(codec, pins[i], on ? PIN_OUT : 0); | ||
3345 | if (spec->pin_eapd_ctrls) | ||
3346 | cx_auto_turn_eapd(codec, num_pins, pins, on); | ||
3347 | } | ||
3348 | |||
3349 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | ||
3350 | { | ||
3351 | int i, present = 0; | ||
3352 | |||
3353 | for (i = 0; i < num_pins; i++) { | ||
3354 | hda_nid_t nid = pins[i]; | ||
3355 | if (!nid || !is_jack_detectable(codec, nid)) | ||
3356 | break; | ||
3357 | present |= snd_hda_jack_detect(codec, nid); | ||
3358 | } | ||
3359 | return present; | ||
3360 | } | ||
3361 | |||
3362 | /* auto-mute/unmute speaker and line outs according to headphone jack */ | ||
3363 | static void cx_auto_update_speakers(struct hda_codec *codec) | ||
3364 | { | ||
3365 | struct conexant_spec *spec = codec->spec; | ||
3366 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3367 | int on = 1; | ||
3368 | |||
3369 | /* turn on HP EAPD when HP jacks are present */ | ||
3370 | if (spec->pin_eapd_ctrls) { | ||
3371 | if (spec->auto_mute) | ||
3372 | on = spec->hp_present; | ||
3373 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); | ||
3374 | } | ||
3375 | |||
3376 | /* mute speakers in auto-mode if HP or LO jacks are plugged */ | ||
3377 | if (spec->auto_mute) | ||
3378 | on = !(spec->hp_present || | ||
3379 | (spec->detect_line && spec->line_present)); | ||
3380 | do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on); | ||
3381 | |||
3382 | /* toggle line-out mutes if needed, too */ | ||
3383 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
3384 | if (cfg->line_out_pins[0] == cfg->hp_pins[0] || | ||
3385 | cfg->line_out_pins[0] == cfg->speaker_pins[0]) | ||
3386 | return; | ||
3387 | if (spec->auto_mute) { | ||
3388 | /* mute LO in auto-mode when HP jack is present */ | ||
3389 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || | ||
3390 | spec->automute_lines) | ||
3391 | on = !spec->hp_present; | ||
3392 | else | ||
3393 | on = 1; | ||
3394 | } | ||
3395 | do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); | ||
3396 | } | ||
3397 | |||
3398 | static void cx_auto_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3399 | { | ||
3400 | struct conexant_spec *spec = codec->spec; | ||
3401 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3402 | |||
3403 | if (!spec->auto_mute) | ||
3404 | return; | ||
3405 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins); | ||
3406 | cx_auto_update_speakers(codec); | ||
3407 | } | ||
3408 | |||
3409 | static void cx_auto_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3410 | { | ||
3411 | struct conexant_spec *spec = codec->spec; | ||
3412 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3413 | |||
3414 | if (!spec->auto_mute || !spec->detect_line) | ||
3415 | return; | ||
3416 | spec->line_present = detect_jacks(codec, cfg->line_outs, | ||
3417 | cfg->line_out_pins); | ||
3418 | cx_auto_update_speakers(codec); | ||
3419 | } | ||
3420 | |||
3421 | static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, | ||
3422 | struct snd_ctl_elem_info *uinfo) | ||
3423 | { | ||
3424 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3425 | struct conexant_spec *spec = codec->spec; | ||
3426 | static const char * const texts3[] = { | ||
3427 | "Disabled", "Speaker Only", "Line Out+Speaker" | ||
3428 | }; | ||
3429 | |||
3430 | if (spec->automute_hp_lo) | ||
3431 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | ||
3432 | return snd_hda_enum_bool_helper_info(kcontrol, uinfo); | ||
3433 | } | ||
3434 | |||
3435 | static int cx_automute_mode_get(struct snd_kcontrol *kcontrol, | ||
3436 | struct snd_ctl_elem_value *ucontrol) | ||
3437 | { | ||
3438 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3439 | struct conexant_spec *spec = codec->spec; | ||
3440 | unsigned int val; | ||
3441 | if (!spec->auto_mute) | ||
3442 | val = 0; | ||
3443 | else if (!spec->automute_lines) | ||
3444 | val = 1; | ||
3445 | else | ||
3446 | val = 2; | ||
3447 | ucontrol->value.enumerated.item[0] = val; | ||
3448 | return 0; | ||
3449 | } | ||
3450 | |||
3451 | static int cx_automute_mode_put(struct snd_kcontrol *kcontrol, | ||
3452 | struct snd_ctl_elem_value *ucontrol) | ||
3453 | { | ||
3454 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3455 | struct conexant_spec *spec = codec->spec; | ||
3456 | |||
3457 | switch (ucontrol->value.enumerated.item[0]) { | ||
3458 | case 0: | ||
3459 | if (!spec->auto_mute) | ||
3460 | return 0; | ||
3461 | spec->auto_mute = 0; | ||
3462 | break; | ||
3463 | case 1: | ||
3464 | if (spec->auto_mute && !spec->automute_lines) | ||
3465 | return 0; | ||
3466 | spec->auto_mute = 1; | ||
3467 | spec->automute_lines = 0; | ||
3468 | break; | ||
3469 | case 2: | ||
3470 | if (!spec->automute_hp_lo) | ||
3471 | return -EINVAL; | ||
3472 | if (spec->auto_mute && spec->automute_lines) | ||
3473 | return 0; | ||
3474 | spec->auto_mute = 1; | ||
3475 | spec->automute_lines = 1; | ||
3476 | break; | ||
3477 | default: | ||
3478 | return -EINVAL; | ||
3479 | } | ||
3480 | cx_auto_update_speakers(codec); | ||
3481 | return 1; | ||
3482 | } | ||
3483 | |||
3484 | static const struct snd_kcontrol_new cx_automute_mode_enum[] = { | ||
3485 | { | ||
3486 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3487 | .name = "Auto-Mute Mode", | ||
3488 | .info = cx_automute_mode_info, | ||
3489 | .get = cx_automute_mode_get, | ||
3490 | .put = cx_automute_mode_put, | ||
3491 | }, | ||
3492 | { } | ||
3493 | }; | ||
3494 | |||
3495 | static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
3496 | struct snd_ctl_elem_info *uinfo) | ||
3497 | { | ||
3498 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3499 | struct conexant_spec *spec = codec->spec; | ||
3500 | |||
3501 | return snd_hda_input_mux_info(&spec->private_imux, uinfo); | ||
3502 | } | ||
3503 | |||
3504 | static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
3505 | struct snd_ctl_elem_value *ucontrol) | ||
3506 | { | ||
3507 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3508 | struct conexant_spec *spec = codec->spec; | ||
3509 | |||
3510 | ucontrol->value.enumerated.item[0] = spec->cur_mux[0]; | ||
3511 | return 0; | ||
3512 | } | ||
3513 | |||
3514 | /* look for the route the given pin from mux and return the index; | ||
3515 | * if do_select is set, actually select the route. | ||
3516 | */ | ||
3517 | static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3518 | hda_nid_t pin, hda_nid_t *srcp, | ||
3519 | bool do_select, int depth) | ||
3520 | { | ||
3521 | struct conexant_spec *spec = codec->spec; | ||
3522 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3523 | int startidx, i, nums; | ||
3524 | |||
3525 | switch (get_wcaps_type(get_wcaps(codec, mux))) { | ||
3526 | case AC_WID_AUD_IN: | ||
3527 | case AC_WID_AUD_SEL: | ||
3528 | case AC_WID_AUD_MIX: | ||
3529 | break; | ||
3530 | default: | ||
3531 | return -1; | ||
3532 | } | ||
3533 | |||
3534 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3535 | for (i = 0; i < nums; i++) | ||
3536 | if (conn[i] == pin) { | ||
3537 | if (do_select) | ||
3538 | snd_hda_codec_write(codec, mux, 0, | ||
3539 | AC_VERB_SET_CONNECT_SEL, i); | ||
3540 | if (srcp) | ||
3541 | *srcp = mux; | ||
3542 | return i; | ||
3543 | } | ||
3544 | depth++; | ||
3545 | if (depth == 2) | ||
3546 | return -1; | ||
3547 | |||
3548 | /* Try to rotate around connections to avoid one boost controlling | ||
3549 | another input path as well */ | ||
3550 | startidx = 0; | ||
3551 | for (i = 0; i < spec->private_imux.num_items; i++) | ||
3552 | if (spec->imux_info[i].pin == pin) { | ||
3553 | startidx = i; | ||
3554 | break; | ||
3555 | } | ||
3556 | |||
3557 | for (i = 0; i < nums; i++) { | ||
3558 | int j = (i + startidx) % nums; | ||
3559 | int ret = __select_input_connection(codec, conn[j], pin, srcp, | ||
3560 | do_select, depth); | ||
3561 | if (ret >= 0) { | ||
3562 | if (do_select) | ||
3563 | snd_hda_codec_write(codec, mux, 0, | ||
3564 | AC_VERB_SET_CONNECT_SEL, j); | ||
3565 | return j; | ||
3566 | } | ||
3567 | } | ||
3568 | return -1; | ||
3569 | } | ||
3570 | |||
3571 | static void select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3572 | hda_nid_t pin) | ||
3573 | { | ||
3574 | __select_input_connection(codec, mux, pin, NULL, true, 0); | ||
3575 | } | ||
3576 | |||
3577 | static int get_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3578 | hda_nid_t pin) | ||
3579 | { | ||
3580 | return __select_input_connection(codec, mux, pin, NULL, false, 0); | ||
3581 | } | ||
3582 | |||
3583 | static int cx_auto_mux_enum_update(struct hda_codec *codec, | ||
3584 | const struct hda_input_mux *imux, | ||
3585 | unsigned int idx) | ||
3586 | { | ||
3587 | struct conexant_spec *spec = codec->spec; | ||
3588 | hda_nid_t adc; | ||
3589 | int changed = 1; | ||
3590 | |||
3591 | if (!imux->num_items) | ||
3592 | return 0; | ||
3593 | if (idx >= imux->num_items) | ||
3594 | idx = imux->num_items - 1; | ||
3595 | if (spec->cur_mux[0] == idx) | ||
3596 | changed = 0; | ||
3597 | adc = spec->imux_info[idx].adc; | ||
3598 | select_input_connection(codec, spec->imux_info[idx].adc, | ||
3599 | spec->imux_info[idx].pin); | ||
3600 | if (spec->cur_adc && spec->cur_adc != adc) { | ||
3601 | /* stream is running, let's swap the current ADC */ | ||
3602 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
3603 | spec->cur_adc = adc; | ||
3604 | snd_hda_codec_setup_stream(codec, adc, | ||
3605 | spec->cur_adc_stream_tag, 0, | ||
3606 | spec->cur_adc_format); | ||
3607 | } | ||
3608 | spec->cur_mux[0] = idx; | ||
3609 | return changed; | ||
3610 | } | ||
3611 | 3109 | ||
3612 | static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, | 3110 | /* |
3613 | struct snd_ctl_elem_value *ucontrol) | 3111 | * Automatic parser for CX20641 & co |
3614 | { | ||
3615 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3616 | struct conexant_spec *spec = codec->spec; | ||
3617 | |||
3618 | return cx_auto_mux_enum_update(codec, &spec->private_imux, | ||
3619 | ucontrol->value.enumerated.item[0]); | ||
3620 | } | ||
3621 | |||
3622 | static const struct snd_kcontrol_new cx_auto_capture_mixers[] = { | ||
3623 | { | ||
3624 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3625 | .name = "Capture Source", | ||
3626 | .info = cx_auto_mux_enum_info, | ||
3627 | .get = cx_auto_mux_enum_get, | ||
3628 | .put = cx_auto_mux_enum_put | ||
3629 | }, | ||
3630 | {} | ||
3631 | }; | ||
3632 | |||
3633 | static bool select_automic(struct hda_codec *codec, int idx, bool detect) | ||
3634 | { | ||
3635 | struct conexant_spec *spec = codec->spec; | ||
3636 | if (idx < 0) | ||
3637 | return false; | ||
3638 | if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin)) | ||
3639 | return false; | ||
3640 | cx_auto_mux_enum_update(codec, &spec->private_imux, idx); | ||
3641 | return true; | ||
3642 | } | ||
3643 | |||
3644 | /* automatic switch internal and external mic */ | ||
3645 | static void cx_auto_automic(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3646 | { | ||
3647 | struct conexant_spec *spec = codec->spec; | ||
3648 | |||
3649 | if (!spec->auto_mic) | ||
3650 | return; | ||
3651 | if (!select_automic(codec, spec->auto_mic_ext, true)) | ||
3652 | if (!select_automic(codec, spec->auto_mic_dock, true)) | ||
3653 | select_automic(codec, spec->auto_mic_int, false); | ||
3654 | } | ||
3655 | |||
3656 | /* check whether the pin config is suitable for auto-mic switching; | ||
3657 | * auto-mic is enabled only when one int-mic and one ext- and/or | ||
3658 | * one dock-mic exist | ||
3659 | */ | 3112 | */ |
3660 | static void cx_auto_check_auto_mic(struct hda_codec *codec) | ||
3661 | { | ||
3662 | struct conexant_spec *spec = codec->spec; | ||
3663 | int pset[INPUT_PIN_ATTR_NORMAL + 1]; | ||
3664 | int i; | ||
3665 | |||
3666 | for (i = 0; i < ARRAY_SIZE(pset); i++) | ||
3667 | pset[i] = -1; | ||
3668 | for (i = 0; i < spec->private_imux.num_items; i++) { | ||
3669 | hda_nid_t pin = spec->imux_info[i].pin; | ||
3670 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
3671 | int type, attr; | ||
3672 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
3673 | if (attr == INPUT_PIN_ATTR_UNUSED) | ||
3674 | return; /* invalid entry */ | ||
3675 | if (attr > INPUT_PIN_ATTR_NORMAL) | ||
3676 | attr = INPUT_PIN_ATTR_NORMAL; | ||
3677 | if (attr != INPUT_PIN_ATTR_INT && | ||
3678 | !is_jack_detectable(codec, pin)) | ||
3679 | return; /* non-detectable pin */ | ||
3680 | type = get_defcfg_device(def_conf); | ||
3681 | if (type != AC_JACK_MIC_IN && | ||
3682 | (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN)) | ||
3683 | return; /* no valid input type */ | ||
3684 | if (pset[attr] >= 0) | ||
3685 | return; /* already occupied */ | ||
3686 | pset[attr] = i; | ||
3687 | } | ||
3688 | if (pset[INPUT_PIN_ATTR_INT] < 0 || | ||
3689 | (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK])) | ||
3690 | return; /* no input to switch*/ | ||
3691 | spec->auto_mic = 1; | ||
3692 | spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL]; | ||
3693 | spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK]; | ||
3694 | spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT]; | ||
3695 | } | ||
3696 | |||
3697 | static void cx_auto_parse_input(struct hda_codec *codec) | ||
3698 | { | ||
3699 | struct conexant_spec *spec = codec->spec; | ||
3700 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3701 | struct hda_input_mux *imux; | ||
3702 | int i, j; | ||
3703 | |||
3704 | imux = &spec->private_imux; | ||
3705 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3706 | for (j = 0; j < spec->num_adc_nids; j++) { | ||
3707 | hda_nid_t adc = spec->adc_nids[j]; | ||
3708 | int idx = get_input_connection(codec, adc, | ||
3709 | cfg->inputs[i].pin); | ||
3710 | if (idx >= 0) { | ||
3711 | const char *label; | ||
3712 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
3713 | spec->imux_info[imux->num_items].index = i; | ||
3714 | spec->imux_info[imux->num_items].boost = 0; | ||
3715 | spec->imux_info[imux->num_items].adc = adc; | ||
3716 | spec->imux_info[imux->num_items].pin = | ||
3717 | cfg->inputs[i].pin; | ||
3718 | snd_hda_add_imux_item(imux, label, idx, NULL); | ||
3719 | break; | ||
3720 | } | ||
3721 | } | ||
3722 | } | ||
3723 | if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) | ||
3724 | cx_auto_check_auto_mic(codec); | ||
3725 | if (imux->num_items > 1) { | ||
3726 | for (i = 1; i < imux->num_items; i++) { | ||
3727 | if (spec->imux_info[i].adc != spec->imux_info[0].adc) { | ||
3728 | spec->adc_switching = 1; | ||
3729 | break; | ||
3730 | } | ||
3731 | } | ||
3732 | } | ||
3733 | } | ||
3734 | |||
3735 | /* get digital-input audio widget corresponding to the given pin */ | ||
3736 | static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin) | ||
3737 | { | ||
3738 | hda_nid_t nid, end_nid; | ||
3739 | |||
3740 | end_nid = codec->start_nid + codec->num_nodes; | ||
3741 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
3742 | unsigned int wcaps = get_wcaps(codec, nid); | ||
3743 | unsigned int type = get_wcaps_type(wcaps); | ||
3744 | if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) { | ||
3745 | if (get_connection_index(codec, nid, pin) >= 0) | ||
3746 | return nid; | ||
3747 | } | ||
3748 | } | ||
3749 | return 0; | ||
3750 | } | ||
3751 | |||
3752 | static void cx_auto_parse_digital(struct hda_codec *codec) | ||
3753 | { | ||
3754 | struct conexant_spec *spec = codec->spec; | ||
3755 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3756 | hda_nid_t nid; | ||
3757 | |||
3758 | if (cfg->dig_outs && | ||
3759 | snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1) | ||
3760 | spec->multiout.dig_out_nid = nid; | ||
3761 | if (cfg->dig_in_pin) | ||
3762 | spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin); | ||
3763 | } | ||
3764 | 3113 | ||
3765 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 3114 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
3766 | static void cx_auto_parse_beep(struct hda_codec *codec) | 3115 | static void cx_auto_parse_beep(struct hda_codec *codec) |
@@ -3802,24 +3151,8 @@ static void cx_auto_parse_eapd(struct hda_codec *codec) | |||
3802 | * OTOH, if only one or two EAPDs are found, it's an old chip, | 3151 | * OTOH, if only one or two EAPDs are found, it's an old chip, |
3803 | * thus it might control over all pins. | 3152 | * thus it might control over all pins. |
3804 | */ | 3153 | */ |
3805 | spec->pin_eapd_ctrls = spec->num_eapds > 2; | 3154 | if (spec->num_eapds > 2) |
3806 | } | 3155 | spec->gen.own_eapd_ctl = 1; |
3807 | |||
3808 | static int cx_auto_parse_auto_config(struct hda_codec *codec) | ||
3809 | { | ||
3810 | struct conexant_spec *spec = codec->spec; | ||
3811 | int err; | ||
3812 | |||
3813 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
3814 | if (err < 0) | ||
3815 | return err; | ||
3816 | |||
3817 | cx_auto_parse_output(codec); | ||
3818 | cx_auto_parse_input(codec); | ||
3819 | cx_auto_parse_digital(codec); | ||
3820 | cx_auto_parse_beep(codec); | ||
3821 | cx_auto_parse_eapd(codec); | ||
3822 | return 0; | ||
3823 | } | 3156 | } |
3824 | 3157 | ||
3825 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | 3158 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, |
@@ -3834,565 +3167,39 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | |||
3834 | } | 3167 | } |
3835 | } | 3168 | } |
3836 | 3169 | ||
3837 | static void select_connection(struct hda_codec *codec, hda_nid_t pin, | ||
3838 | hda_nid_t src) | ||
3839 | { | ||
3840 | int idx = get_connection_index(codec, pin, src); | ||
3841 | if (idx >= 0) | ||
3842 | snd_hda_codec_write(codec, pin, 0, | ||
3843 | AC_VERB_SET_CONNECT_SEL, idx); | ||
3844 | } | ||
3845 | |||
3846 | static void mute_outputs(struct hda_codec *codec, int num_nids, | ||
3847 | const hda_nid_t *nids) | ||
3848 | { | ||
3849 | int i, val; | ||
3850 | |||
3851 | for (i = 0; i < num_nids; i++) { | ||
3852 | hda_nid_t nid = nids[i]; | ||
3853 | if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | ||
3854 | continue; | ||
3855 | if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) | ||
3856 | val = AMP_OUT_MUTE; | ||
3857 | else | ||
3858 | val = AMP_OUT_ZERO; | ||
3859 | snd_hda_codec_write(codec, nid, 0, | ||
3860 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
3861 | } | ||
3862 | } | ||
3863 | |||
3864 | static void enable_unsol_pins(struct hda_codec *codec, int num_pins, | ||
3865 | hda_nid_t *pins, unsigned int action, | ||
3866 | hda_jack_callback cb) | ||
3867 | { | ||
3868 | int i; | ||
3869 | for (i = 0; i < num_pins; i++) | ||
3870 | snd_hda_jack_detect_enable_callback(codec, pins[i], action, cb); | ||
3871 | } | ||
3872 | |||
3873 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
3874 | { | ||
3875 | int i; | ||
3876 | for (i = 0; i < nums; i++) | ||
3877 | if (list[i] == nid) | ||
3878 | return true; | ||
3879 | return false; | ||
3880 | } | ||
3881 | |||
3882 | /* is the given NID found in any of autocfg items? */ | ||
3883 | static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid) | ||
3884 | { | ||
3885 | int i; | ||
3886 | |||
3887 | if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) || | ||
3888 | found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) || | ||
3889 | found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) || | ||
3890 | found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs)) | ||
3891 | return true; | ||
3892 | for (i = 0; i < cfg->num_inputs; i++) | ||
3893 | if (cfg->inputs[i].pin == nid) | ||
3894 | return true; | ||
3895 | if (cfg->dig_in_pin == nid) | ||
3896 | return true; | ||
3897 | return false; | ||
3898 | } | ||
3899 | |||
3900 | /* clear unsol-event tags on unused pins; Conexant codecs seem to leave | ||
3901 | * invalid unsol tags by some reason | ||
3902 | */ | ||
3903 | static void clear_unsol_on_unused_pins(struct hda_codec *codec) | ||
3904 | { | ||
3905 | struct conexant_spec *spec = codec->spec; | ||
3906 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3907 | int i; | ||
3908 | |||
3909 | for (i = 0; i < codec->init_pins.used; i++) { | ||
3910 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
3911 | if (!found_in_autocfg(cfg, pin->nid)) | ||
3912 | snd_hda_codec_write(codec, pin->nid, 0, | ||
3913 | AC_VERB_SET_UNSOLICITED_ENABLE, 0); | ||
3914 | } | ||
3915 | } | ||
3916 | |||
3917 | /* turn on/off EAPD according to Master switch */ | 3170 | /* turn on/off EAPD according to Master switch */ |
3918 | static void cx_auto_vmaster_hook(void *private_data, int enabled) | 3171 | static void cx_auto_vmaster_hook(void *private_data, int enabled) |
3919 | { | 3172 | { |
3920 | struct hda_codec *codec = private_data; | 3173 | struct hda_codec *codec = private_data; |
3921 | struct conexant_spec *spec = codec->spec; | 3174 | struct conexant_spec *spec = codec->spec; |
3922 | 3175 | ||
3923 | if (enabled && spec->pin_eapd_ctrls) { | ||
3924 | cx_auto_update_speakers(codec); | ||
3925 | return; | ||
3926 | } | ||
3927 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); | 3176 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); |
3928 | } | 3177 | } |
3929 | 3178 | ||
3930 | static void cx_auto_init_output(struct hda_codec *codec) | ||
3931 | { | ||
3932 | struct conexant_spec *spec = codec->spec; | ||
3933 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3934 | hda_nid_t nid; | ||
3935 | int i; | ||
3936 | |||
3937 | mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); | ||
3938 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3939 | unsigned int val = PIN_OUT; | ||
3940 | if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & | ||
3941 | AC_PINCAP_HP_DRV) | ||
3942 | val |= AC_PINCTL_HP_EN; | ||
3943 | snd_hda_set_pin_ctl(codec, cfg->hp_pins[i], val); | ||
3944 | } | ||
3945 | mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); | ||
3946 | mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); | ||
3947 | mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); | ||
3948 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
3949 | nid = spec->dac_info[i].dac; | ||
3950 | if (!nid) | ||
3951 | nid = spec->multiout.dac_nids[0]; | ||
3952 | else if (nid & DAC_SLAVE_FLAG) | ||
3953 | nid &= ~DAC_SLAVE_FLAG; | ||
3954 | select_connection(codec, spec->dac_info[i].pin, nid); | ||
3955 | } | ||
3956 | if (spec->auto_mute) { | ||
3957 | enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, | ||
3958 | CONEXANT_HP_EVENT, cx_auto_hp_automute); | ||
3959 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, | ||
3960 | cfg->hp_pins); | ||
3961 | if (spec->detect_line) { | ||
3962 | enable_unsol_pins(codec, cfg->line_outs, | ||
3963 | cfg->line_out_pins, | ||
3964 | CONEXANT_LINE_EVENT, | ||
3965 | cx_auto_line_automute); | ||
3966 | spec->line_present = | ||
3967 | detect_jacks(codec, cfg->line_outs, | ||
3968 | cfg->line_out_pins); | ||
3969 | } | ||
3970 | } | ||
3971 | cx_auto_update_speakers(codec); | ||
3972 | /* turn on all EAPDs if no individual EAPD control is available */ | ||
3973 | if (!spec->pin_eapd_ctrls) | ||
3974 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); | ||
3975 | clear_unsol_on_unused_pins(codec); | ||
3976 | } | ||
3977 | |||
3978 | static void cx_auto_init_input(struct hda_codec *codec) | ||
3979 | { | ||
3980 | struct conexant_spec *spec = codec->spec; | ||
3981 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3982 | int i, val; | ||
3983 | |||
3984 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
3985 | hda_nid_t nid = spec->adc_nids[i]; | ||
3986 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | ||
3987 | continue; | ||
3988 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) | ||
3989 | val = AMP_IN_MUTE(0); | ||
3990 | else | ||
3991 | val = AMP_IN_UNMUTE(0); | ||
3992 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3993 | val); | ||
3994 | } | ||
3995 | |||
3996 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3997 | hda_nid_t pin = cfg->inputs[i].pin; | ||
3998 | unsigned int type = PIN_IN; | ||
3999 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | ||
4000 | type |= snd_hda_get_default_vref(codec, pin); | ||
4001 | snd_hda_set_pin_ctl(codec, pin, type); | ||
4002 | } | ||
4003 | |||
4004 | if (spec->auto_mic) { | ||
4005 | if (spec->auto_mic_ext >= 0) { | ||
4006 | snd_hda_jack_detect_enable_callback(codec, | ||
4007 | cfg->inputs[spec->auto_mic_ext].pin, | ||
4008 | CONEXANT_MIC_EVENT, cx_auto_automic); | ||
4009 | } | ||
4010 | if (spec->auto_mic_dock >= 0) { | ||
4011 | snd_hda_jack_detect_enable_callback(codec, | ||
4012 | cfg->inputs[spec->auto_mic_dock].pin, | ||
4013 | CONEXANT_MIC_EVENT, cx_auto_automic); | ||
4014 | } | ||
4015 | cx_auto_automic(codec, NULL); | ||
4016 | } else { | ||
4017 | select_input_connection(codec, spec->imux_info[0].adc, | ||
4018 | spec->imux_info[0].pin); | ||
4019 | } | ||
4020 | } | ||
4021 | |||
4022 | static void cx_auto_init_digital(struct hda_codec *codec) | ||
4023 | { | ||
4024 | struct conexant_spec *spec = codec->spec; | ||
4025 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4026 | |||
4027 | if (spec->multiout.dig_out_nid) | ||
4028 | snd_hda_set_pin_ctl(codec, cfg->dig_out_pins[0], PIN_OUT); | ||
4029 | if (spec->dig_in_nid) | ||
4030 | snd_hda_set_pin_ctl(codec, cfg->dig_in_pin, PIN_IN); | ||
4031 | } | ||
4032 | |||
4033 | static int cx_auto_init(struct hda_codec *codec) | ||
4034 | { | ||
4035 | struct conexant_spec *spec = codec->spec; | ||
4036 | snd_hda_gen_apply_verbs(codec); | ||
4037 | cx_auto_init_output(codec); | ||
4038 | cx_auto_init_input(codec); | ||
4039 | cx_auto_init_digital(codec); | ||
4040 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
4041 | return 0; | ||
4042 | } | ||
4043 | |||
4044 | static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | ||
4045 | const char *dir, int cidx, | ||
4046 | hda_nid_t nid, int hda_dir, int amp_idx, int chs) | ||
4047 | { | ||
4048 | static char name[44]; | ||
4049 | static struct snd_kcontrol_new knew[] = { | ||
4050 | HDA_CODEC_VOLUME(name, 0, 0, 0), | ||
4051 | HDA_CODEC_MUTE(name, 0, 0, 0), | ||
4052 | }; | ||
4053 | static const char * const sfx[2] = { "Volume", "Switch" }; | ||
4054 | int i, err; | ||
4055 | |||
4056 | for (i = 0; i < 2; i++) { | ||
4057 | struct snd_kcontrol *kctl; | ||
4058 | knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, chs, amp_idx, | ||
4059 | hda_dir); | ||
4060 | knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; | ||
4061 | knew[i].index = cidx; | ||
4062 | snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); | ||
4063 | kctl = snd_ctl_new1(&knew[i], codec); | ||
4064 | if (!kctl) | ||
4065 | return -ENOMEM; | ||
4066 | err = snd_hda_ctl_add(codec, nid, kctl); | ||
4067 | if (err < 0) | ||
4068 | return err; | ||
4069 | if (!(query_amp_caps(codec, nid, hda_dir) & | ||
4070 | (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))) | ||
4071 | break; | ||
4072 | } | ||
4073 | return 0; | ||
4074 | } | ||
4075 | |||
4076 | #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ | ||
4077 | cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0, 3) | ||
4078 | |||
4079 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ | ||
4080 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) | ||
4081 | |||
4082 | static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, | ||
4083 | hda_nid_t pin, const char *name, int idx) | ||
4084 | { | ||
4085 | unsigned int caps; | ||
4086 | if (dac && !(dac & DAC_SLAVE_FLAG)) { | ||
4087 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); | ||
4088 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4089 | return cx_auto_add_pb_volume(codec, dac, name, idx); | ||
4090 | } | ||
4091 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | ||
4092 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4093 | return cx_auto_add_pb_volume(codec, pin, name, idx); | ||
4094 | return 0; | ||
4095 | } | ||
4096 | |||
4097 | static bool is_2_1_speaker(struct conexant_spec *spec) | ||
4098 | { | ||
4099 | int i, type, num_spk = 0; | ||
4100 | |||
4101 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
4102 | type = spec->dac_info[i].type; | ||
4103 | if (type == AUTO_PIN_LINE_OUT) | ||
4104 | type = spec->autocfg.line_out_type; | ||
4105 | if (type == AUTO_PIN_SPEAKER_OUT) | ||
4106 | num_spk++; | ||
4107 | } | ||
4108 | return (num_spk == 2 && spec->autocfg.line_out_type != AUTO_PIN_LINE_OUT); | ||
4109 | } | ||
4110 | |||
4111 | static int cx_auto_build_output_controls(struct hda_codec *codec) | ||
4112 | { | ||
4113 | struct conexant_spec *spec = codec->spec; | ||
4114 | int i, err; | ||
4115 | int num_line = 0, num_hp = 0, num_spk = 0; | ||
4116 | bool speaker_2_1; | ||
4117 | static const char * const texts[3] = { "Front", "Surround", "CLFE" }; | ||
4118 | |||
4119 | if (spec->dac_info_filled == 1) | ||
4120 | return try_add_pb_volume(codec, spec->dac_info[0].dac, | ||
4121 | spec->dac_info[0].pin, | ||
4122 | "Master", 0); | ||
4123 | |||
4124 | speaker_2_1 = is_2_1_speaker(spec); | ||
4125 | |||
4126 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
4127 | const char *label; | ||
4128 | int idx, type; | ||
4129 | hda_nid_t dac = spec->dac_info[i].dac; | ||
4130 | type = spec->dac_info[i].type; | ||
4131 | if (type == AUTO_PIN_LINE_OUT) | ||
4132 | type = spec->autocfg.line_out_type; | ||
4133 | switch (type) { | ||
4134 | case AUTO_PIN_LINE_OUT: | ||
4135 | default: | ||
4136 | label = texts[num_line++]; | ||
4137 | idx = 0; | ||
4138 | break; | ||
4139 | case AUTO_PIN_HP_OUT: | ||
4140 | label = "Headphone"; | ||
4141 | idx = num_hp++; | ||
4142 | break; | ||
4143 | case AUTO_PIN_SPEAKER_OUT: | ||
4144 | if (speaker_2_1) { | ||
4145 | label = num_spk++ ? "Bass Speaker" : "Speaker"; | ||
4146 | idx = 0; | ||
4147 | } else { | ||
4148 | label = "Speaker"; | ||
4149 | idx = num_spk++; | ||
4150 | } | ||
4151 | break; | ||
4152 | } | ||
4153 | err = try_add_pb_volume(codec, dac, | ||
4154 | spec->dac_info[i].pin, | ||
4155 | label, idx); | ||
4156 | if (err < 0) | ||
4157 | return err; | ||
4158 | } | ||
4159 | |||
4160 | if (spec->auto_mute) { | ||
4161 | err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum); | ||
4162 | if (err < 0) | ||
4163 | return err; | ||
4164 | } | ||
4165 | |||
4166 | return 0; | ||
4167 | } | ||
4168 | |||
4169 | /* Returns zero if this is a normal stereo channel, and non-zero if it should | ||
4170 | be split in two independent channels. | ||
4171 | dest_label must be at least 44 characters. */ | ||
4172 | static int cx_auto_get_rightch_label(struct hda_codec *codec, const char *label, | ||
4173 | char *dest_label, int nid) | ||
4174 | { | ||
4175 | struct conexant_spec *spec = codec->spec; | ||
4176 | int i; | ||
4177 | |||
4178 | if (!spec->fixup_stereo_dmic) | ||
4179 | return 0; | ||
4180 | |||
4181 | for (i = 0; i < AUTO_CFG_MAX_INS; i++) { | ||
4182 | int def_conf; | ||
4183 | if (spec->autocfg.inputs[i].pin != nid) | ||
4184 | continue; | ||
4185 | |||
4186 | if (spec->autocfg.inputs[i].type != AUTO_PIN_MIC) | ||
4187 | return 0; | ||
4188 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
4189 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) | ||
4190 | return 0; | ||
4191 | |||
4192 | /* Finally found the inverted internal mic! */ | ||
4193 | snprintf(dest_label, 44, "Inverted %s", label); | ||
4194 | return 1; | ||
4195 | } | ||
4196 | return 0; | ||
4197 | } | ||
4198 | |||
4199 | static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, | ||
4200 | const char *label, const char *pfx, | ||
4201 | int cidx) | ||
4202 | { | ||
4203 | struct conexant_spec *spec = codec->spec; | ||
4204 | int i; | ||
4205 | |||
4206 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4207 | char rightch_label[44]; | ||
4208 | hda_nid_t adc_nid = spec->adc_nids[i]; | ||
4209 | int idx = get_input_connection(codec, adc_nid, nid); | ||
4210 | if (idx < 0) | ||
4211 | continue; | ||
4212 | if (codec->single_adc_amp) | ||
4213 | idx = 0; | ||
4214 | |||
4215 | if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) { | ||
4216 | /* Make two independent kcontrols for left and right */ | ||
4217 | int err = cx_auto_add_volume_idx(codec, label, pfx, | ||
4218 | cidx, adc_nid, HDA_INPUT, idx, 1); | ||
4219 | if (err < 0) | ||
4220 | return err; | ||
4221 | return cx_auto_add_volume_idx(codec, rightch_label, pfx, | ||
4222 | cidx, adc_nid, HDA_INPUT, idx, 2); | ||
4223 | } | ||
4224 | return cx_auto_add_volume_idx(codec, label, pfx, | ||
4225 | cidx, adc_nid, HDA_INPUT, idx, 3); | ||
4226 | } | ||
4227 | return 0; | ||
4228 | } | ||
4229 | |||
4230 | static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx, | ||
4231 | const char *label, int cidx) | ||
4232 | { | ||
4233 | struct conexant_spec *spec = codec->spec; | ||
4234 | hda_nid_t mux, nid; | ||
4235 | int i, con; | ||
4236 | |||
4237 | nid = spec->imux_info[idx].pin; | ||
4238 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | ||
4239 | char rightch_label[44]; | ||
4240 | if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) { | ||
4241 | int err = cx_auto_add_volume_idx(codec, label, " Boost", | ||
4242 | cidx, nid, HDA_INPUT, 0, 1); | ||
4243 | if (err < 0) | ||
4244 | return err; | ||
4245 | return cx_auto_add_volume_idx(codec, rightch_label, " Boost", | ||
4246 | cidx, nid, HDA_INPUT, 0, 2); | ||
4247 | } | ||
4248 | return cx_auto_add_volume(codec, label, " Boost", cidx, | ||
4249 | nid, HDA_INPUT); | ||
4250 | } | ||
4251 | con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, | ||
4252 | &mux, false, 0); | ||
4253 | if (con < 0) | ||
4254 | return 0; | ||
4255 | for (i = 0; i < idx; i++) { | ||
4256 | if (spec->imux_info[i].boost == mux) | ||
4257 | return 0; /* already present */ | ||
4258 | } | ||
4259 | |||
4260 | if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) { | ||
4261 | spec->imux_info[idx].boost = mux; | ||
4262 | return cx_auto_add_volume(codec, label, " Boost", cidx, | ||
4263 | mux, HDA_OUTPUT); | ||
4264 | } | ||
4265 | return 0; | ||
4266 | } | ||
4267 | |||
4268 | static int cx_auto_build_input_controls(struct hda_codec *codec) | ||
4269 | { | ||
4270 | struct conexant_spec *spec = codec->spec; | ||
4271 | struct hda_input_mux *imux = &spec->private_imux; | ||
4272 | const char *prev_label; | ||
4273 | int input_conn[HDA_MAX_NUM_INPUTS]; | ||
4274 | int i, j, err, cidx; | ||
4275 | int multi_connection; | ||
4276 | |||
4277 | if (!imux->num_items) | ||
4278 | return 0; | ||
4279 | |||
4280 | multi_connection = 0; | ||
4281 | for (i = 0; i < imux->num_items; i++) { | ||
4282 | cidx = get_input_connection(codec, spec->imux_info[i].adc, | ||
4283 | spec->imux_info[i].pin); | ||
4284 | if (cidx < 0) | ||
4285 | continue; | ||
4286 | input_conn[i] = spec->imux_info[i].adc; | ||
4287 | if (!codec->single_adc_amp) | ||
4288 | input_conn[i] |= cidx << 8; | ||
4289 | if (i > 0 && input_conn[i] != input_conn[0]) | ||
4290 | multi_connection = 1; | ||
4291 | } | ||
4292 | |||
4293 | prev_label = NULL; | ||
4294 | cidx = 0; | ||
4295 | for (i = 0; i < imux->num_items; i++) { | ||
4296 | hda_nid_t nid = spec->imux_info[i].pin; | ||
4297 | const char *label; | ||
4298 | |||
4299 | label = hda_get_autocfg_input_label(codec, &spec->autocfg, | ||
4300 | spec->imux_info[i].index); | ||
4301 | if (label == prev_label) | ||
4302 | cidx++; | ||
4303 | else | ||
4304 | cidx = 0; | ||
4305 | prev_label = label; | ||
4306 | |||
4307 | err = cx_auto_add_boost_volume(codec, i, label, cidx); | ||
4308 | if (err < 0) | ||
4309 | return err; | ||
4310 | |||
4311 | if (!multi_connection) { | ||
4312 | if (i > 0) | ||
4313 | continue; | ||
4314 | err = cx_auto_add_capture_volume(codec, nid, | ||
4315 | "Capture", "", cidx); | ||
4316 | } else { | ||
4317 | bool dup_found = false; | ||
4318 | for (j = 0; j < i; j++) { | ||
4319 | if (input_conn[j] == input_conn[i]) { | ||
4320 | dup_found = true; | ||
4321 | break; | ||
4322 | } | ||
4323 | } | ||
4324 | if (dup_found) | ||
4325 | continue; | ||
4326 | err = cx_auto_add_capture_volume(codec, nid, | ||
4327 | label, " Capture", cidx); | ||
4328 | } | ||
4329 | if (err < 0) | ||
4330 | return err; | ||
4331 | } | ||
4332 | |||
4333 | if (spec->private_imux.num_items > 1 && !spec->auto_mic) { | ||
4334 | err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers); | ||
4335 | if (err < 0) | ||
4336 | return err; | ||
4337 | } | ||
4338 | |||
4339 | return 0; | ||
4340 | } | ||
4341 | |||
4342 | static int cx_auto_build_controls(struct hda_codec *codec) | 3179 | static int cx_auto_build_controls(struct hda_codec *codec) |
4343 | { | 3180 | { |
4344 | struct conexant_spec *spec = codec->spec; | ||
4345 | int err; | 3181 | int err; |
4346 | 3182 | ||
4347 | err = cx_auto_build_output_controls(codec); | 3183 | err = snd_hda_gen_build_controls(codec); |
4348 | if (err < 0) | 3184 | if (err < 0) |
4349 | return err; | 3185 | return err; |
4350 | err = cx_auto_build_input_controls(codec); | 3186 | |
4351 | if (err < 0) | 3187 | err = add_beep_ctls(codec); |
4352 | return err; | ||
4353 | err = conexant_build_controls(codec); | ||
4354 | if (err < 0) | ||
4355 | return err; | ||
4356 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
4357 | if (err < 0) | 3188 | if (err < 0) |
4358 | return err; | 3189 | return err; |
4359 | if (spec->vmaster_mute.sw_kctl) { | ||
4360 | spec->vmaster_mute.hook = cx_auto_vmaster_hook; | ||
4361 | err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, | ||
4362 | spec->vmaster_mute_led); | ||
4363 | if (err < 0) | ||
4364 | return err; | ||
4365 | } | ||
4366 | return 0; | ||
4367 | } | ||
4368 | 3190 | ||
4369 | static int cx_auto_search_adcs(struct hda_codec *codec) | ||
4370 | { | ||
4371 | struct conexant_spec *spec = codec->spec; | ||
4372 | hda_nid_t nid, end_nid; | ||
4373 | |||
4374 | end_nid = codec->start_nid + codec->num_nodes; | ||
4375 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
4376 | unsigned int caps = get_wcaps(codec, nid); | ||
4377 | if (get_wcaps_type(caps) != AC_WID_AUD_IN) | ||
4378 | continue; | ||
4379 | if (caps & AC_WCAP_DIGITAL) | ||
4380 | continue; | ||
4381 | if (snd_BUG_ON(spec->num_adc_nids >= | ||
4382 | ARRAY_SIZE(spec->private_adc_nids))) | ||
4383 | break; | ||
4384 | spec->private_adc_nids[spec->num_adc_nids++] = nid; | ||
4385 | } | ||
4386 | spec->adc_nids = spec->private_adc_nids; | ||
4387 | return 0; | 3191 | return 0; |
4388 | } | 3192 | } |
4389 | 3193 | ||
4390 | static const struct hda_codec_ops cx_auto_patch_ops = { | 3194 | static const struct hda_codec_ops cx_auto_patch_ops = { |
4391 | .build_controls = cx_auto_build_controls, | 3195 | .build_controls = cx_auto_build_controls, |
4392 | .build_pcms = conexant_build_pcms, | 3196 | .build_pcms = snd_hda_gen_build_pcms, |
4393 | .init = cx_auto_init, | 3197 | .init = snd_hda_gen_init, |
4394 | .free = conexant_free, | 3198 | .free = snd_hda_gen_free, |
4395 | .unsol_event = snd_hda_jack_unsol_event, | 3199 | .unsol_event = snd_hda_jack_unsol_event, |
3200 | #ifdef CONFIG_PM | ||
3201 | .check_power_status = snd_hda_gen_check_power_status, | ||
3202 | #endif | ||
4396 | }; | 3203 | }; |
4397 | 3204 | ||
4398 | /* | 3205 | /* |
@@ -4411,7 +3218,7 @@ static void cxt_fixup_stereo_dmic(struct hda_codec *codec, | |||
4411 | const struct hda_fixup *fix, int action) | 3218 | const struct hda_fixup *fix, int action) |
4412 | { | 3219 | { |
4413 | struct conexant_spec *spec = codec->spec; | 3220 | struct conexant_spec *spec = codec->spec; |
4414 | spec->fixup_stereo_dmic = 1; | 3221 | spec->gen.inv_dmic_split = 1; |
4415 | } | 3222 | } |
4416 | 3223 | ||
4417 | static void cxt5066_increase_mic_boost(struct hda_codec *codec, | 3224 | static void cxt5066_increase_mic_boost(struct hda_codec *codec, |
@@ -4532,13 +3339,22 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4532 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3339 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4533 | if (!spec) | 3340 | if (!spec) |
4534 | return -ENOMEM; | 3341 | return -ENOMEM; |
3342 | snd_hda_gen_spec_init(&spec->gen); | ||
4535 | codec->spec = spec; | 3343 | codec->spec = spec; |
4536 | snd_hda_gen_init(&spec->gen); | 3344 | |
3345 | cx_auto_parse_beep(codec); | ||
3346 | cx_auto_parse_eapd(codec); | ||
3347 | if (spec->gen.own_eapd_ctl) | ||
3348 | spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook; | ||
4537 | 3349 | ||
4538 | switch (codec->vendor_id) { | 3350 | switch (codec->vendor_id) { |
4539 | case 0x14f15045: | 3351 | case 0x14f15045: |
4540 | codec->single_adc_amp = 1; | 3352 | codec->single_adc_amp = 1; |
4541 | break; | 3353 | break; |
3354 | case 0x14f15047: | ||
3355 | codec->pin_amp_workaround = 1; | ||
3356 | spec->gen.mixer_nid = 0x19; | ||
3357 | break; | ||
4542 | case 0x14f15051: | 3358 | case 0x14f15051: |
4543 | add_cx5051_fake_mutes(codec); | 3359 | add_cx5051_fake_mutes(codec); |
4544 | codec->pin_amp_workaround = 1; | 3360 | codec->pin_amp_workaround = 1; |
@@ -4550,8 +3366,6 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4550 | break; | 3366 | break; |
4551 | } | 3367 | } |
4552 | 3368 | ||
4553 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
4554 | |||
4555 | /* Show mute-led control only on HP laptops | 3369 | /* Show mute-led control only on HP laptops |
4556 | * This is a sort of white-list: on HP laptops, EAPD corresponds | 3370 | * This is a sort of white-list: on HP laptops, EAPD corresponds |
4557 | * only to the mute-LED without actualy amp function. Meanwhile, | 3371 | * only to the mute-LED without actualy amp function. Meanwhile, |
@@ -4560,20 +3374,20 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4560 | */ | 3374 | */ |
4561 | switch (codec->subsystem_id >> 16) { | 3375 | switch (codec->subsystem_id >> 16) { |
4562 | case 0x103c: | 3376 | case 0x103c: |
4563 | spec->vmaster_mute_led = 1; | 3377 | spec->gen.vmaster_mute_enum = 1; |
4564 | break; | 3378 | break; |
4565 | } | 3379 | } |
4566 | 3380 | ||
4567 | err = cx_auto_search_adcs(codec); | 3381 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
3382 | |||
3383 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); | ||
4568 | if (err < 0) | 3384 | if (err < 0) |
4569 | return err; | 3385 | goto error; |
4570 | err = cx_auto_parse_auto_config(codec); | 3386 | |
4571 | if (err < 0) { | 3387 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
4572 | kfree(codec->spec); | 3388 | if (err < 0) |
4573 | codec->spec = NULL; | 3389 | goto error; |
4574 | return err; | 3390 | |
4575 | } | ||
4576 | spec->capture_stream = &cx_auto_pcm_analog_capture; | ||
4577 | codec->patch_ops = cx_auto_patch_ops; | 3391 | codec->patch_ops = cx_auto_patch_ops; |
4578 | if (spec->beep_amp) | 3392 | if (spec->beep_amp) |
4579 | snd_hda_attach_beep_device(codec, spec->beep_amp); | 3393 | snd_hda_attach_beep_device(codec, spec->beep_amp); |
@@ -4590,8 +3404,19 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4590 | } | 3404 | } |
4591 | 3405 | ||
4592 | return 0; | 3406 | return 0; |
3407 | |||
3408 | error: | ||
3409 | snd_hda_gen_free(codec); | ||
3410 | return err; | ||
4593 | } | 3411 | } |
4594 | 3412 | ||
3413 | #ifndef ENABLE_CXT_STATIC_QUIRKS | ||
3414 | #define patch_cxt5045 patch_conexant_auto | ||
3415 | #define patch_cxt5047 patch_conexant_auto | ||
3416 | #define patch_cxt5051 patch_conexant_auto | ||
3417 | #define patch_cxt5066 patch_conexant_auto | ||
3418 | #endif | ||
3419 | |||
4595 | /* | 3420 | /* |
4596 | */ | 3421 | */ |
4597 | 3422 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e85959f72047..85236da79046 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1103,8 +1103,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
1103 | if (!static_hdmi_pcm && eld->eld_valid) { | 1103 | if (!static_hdmi_pcm && eld->eld_valid) { |
1104 | snd_hdmi_eld_update_pcm_info(eld, hinfo); | 1104 | snd_hdmi_eld_update_pcm_info(eld, hinfo); |
1105 | if (hinfo->channels_min > hinfo->channels_max || | 1105 | if (hinfo->channels_min > hinfo->channels_max || |
1106 | !hinfo->rates || !hinfo->formats) | 1106 | !hinfo->rates || !hinfo->formats) { |
1107 | per_cvt->assigned = 0; | ||
1108 | hinfo->nid = 0; | ||
1109 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | ||
1107 | return -ENODEV; | 1110 | return -ENODEV; |
1111 | } | ||
1108 | } | 1112 | } |
1109 | 1113 | ||
1110 | /* Store the updated parameters */ | 1114 | /* Store the updated parameters */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5faaad219a7f..de512c52fa96 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/dmi.h> | ||
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <sound/core.h> | 32 | #include <sound/core.h> |
32 | #include <sound/jack.h> | 33 | #include <sound/jack.h> |
@@ -35,12 +36,10 @@ | |||
35 | #include "hda_auto_parser.h" | 36 | #include "hda_auto_parser.h" |
36 | #include "hda_beep.h" | 37 | #include "hda_beep.h" |
37 | #include "hda_jack.h" | 38 | #include "hda_jack.h" |
39 | #include "hda_generic.h" | ||
38 | 40 | ||
39 | /* unsol event tags */ | 41 | /* unsol event tags */ |
40 | #define ALC_FRONT_EVENT 0x01 | 42 | #define ALC_DCVOL_EVENT 0x08 |
41 | #define ALC_DCVOL_EVENT 0x02 | ||
42 | #define ALC_HP_EVENT 0x04 | ||
43 | #define ALC_MIC_EVENT 0x08 | ||
44 | 43 | ||
45 | /* for GPIO Poll */ | 44 | /* for GPIO Poll */ |
46 | #define GPIO_MASK 0x03 | 45 | #define GPIO_MASK 0x03 |
@@ -67,355 +66,42 @@ struct alc_customize_define { | |||
67 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ | 66 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ |
68 | }; | 67 | }; |
69 | 68 | ||
70 | struct alc_multi_io { | ||
71 | hda_nid_t pin; /* multi-io widget pin NID */ | ||
72 | hda_nid_t dac; /* DAC to be connected */ | ||
73 | unsigned int ctl_in; /* cached input-pin control value */ | ||
74 | }; | ||
75 | |||
76 | enum { | ||
77 | ALC_AUTOMUTE_PIN, /* change the pin control */ | ||
78 | ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */ | ||
79 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ | ||
80 | }; | ||
81 | |||
82 | #define MAX_VOL_NIDS 0x40 | ||
83 | |||
84 | /* make compatible with old code */ | ||
85 | #define alc_apply_pincfgs snd_hda_apply_pincfgs | ||
86 | #define alc_apply_fixup snd_hda_apply_fixup | ||
87 | #define alc_pick_fixup snd_hda_pick_fixup | ||
88 | #define alc_fixup hda_fixup | ||
89 | #define alc_pincfg hda_pintbl | ||
90 | #define alc_model_fixup hda_model_fixup | ||
91 | |||
92 | #define ALC_FIXUP_PINS HDA_FIXUP_PINS | ||
93 | #define ALC_FIXUP_VERBS HDA_FIXUP_VERBS | ||
94 | #define ALC_FIXUP_FUNC HDA_FIXUP_FUNC | ||
95 | |||
96 | #define ALC_FIXUP_ACT_PRE_PROBE HDA_FIXUP_ACT_PRE_PROBE | ||
97 | #define ALC_FIXUP_ACT_PROBE HDA_FIXUP_ACT_PROBE | ||
98 | #define ALC_FIXUP_ACT_INIT HDA_FIXUP_ACT_INIT | ||
99 | #define ALC_FIXUP_ACT_BUILD HDA_FIXUP_ACT_BUILD | ||
100 | |||
101 | |||
102 | struct alc_spec { | 69 | struct alc_spec { |
103 | struct hda_gen_spec gen; | 70 | struct hda_gen_spec gen; /* must be at head */ |
104 | 71 | ||
105 | /* codec parameterization */ | 72 | /* codec parameterization */ |
106 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 73 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
107 | unsigned int num_mixers; | 74 | unsigned int num_mixers; |
108 | const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ | ||
109 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 75 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
110 | 76 | ||
111 | char stream_name_analog[32]; /* analog PCM stream */ | ||
112 | const struct hda_pcm_stream *stream_analog_playback; | ||
113 | const struct hda_pcm_stream *stream_analog_capture; | ||
114 | const struct hda_pcm_stream *stream_analog_alt_playback; | ||
115 | const struct hda_pcm_stream *stream_analog_alt_capture; | ||
116 | |||
117 | char stream_name_digital[32]; /* digital PCM stream */ | ||
118 | const struct hda_pcm_stream *stream_digital_playback; | ||
119 | const struct hda_pcm_stream *stream_digital_capture; | ||
120 | |||
121 | /* playback */ | ||
122 | struct hda_multi_out multiout; /* playback set-up | ||
123 | * max_channels, dacs must be set | ||
124 | * dig_out_nid and hp_nid are optional | ||
125 | */ | ||
126 | hda_nid_t alt_dac_nid; | ||
127 | hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ | ||
128 | int dig_out_type; | ||
129 | |||
130 | /* capture */ | ||
131 | unsigned int num_adc_nids; | ||
132 | const hda_nid_t *adc_nids; | ||
133 | const hda_nid_t *capsrc_nids; | ||
134 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | ||
135 | hda_nid_t mixer_nid; /* analog-mixer NID */ | ||
136 | DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1); | ||
137 | DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1); | ||
138 | |||
139 | /* capture setup for dynamic dual-adc switch */ | ||
140 | hda_nid_t cur_adc; | ||
141 | unsigned int cur_adc_stream_tag; | ||
142 | unsigned int cur_adc_format; | ||
143 | |||
144 | /* capture source */ | ||
145 | unsigned int num_mux_defs; | ||
146 | const struct hda_input_mux *input_mux; | ||
147 | unsigned int cur_mux[3]; | ||
148 | hda_nid_t ext_mic_pin; | ||
149 | hda_nid_t dock_mic_pin; | ||
150 | hda_nid_t int_mic_pin; | ||
151 | |||
152 | /* channel model */ | ||
153 | const struct hda_channel_mode *channel_mode; | ||
154 | int num_channel_mode; | ||
155 | int need_dac_fix; | ||
156 | int const_channel_count; /* min. channel count (for speakers) */ | ||
157 | int ext_channel_count; /* current channel count for multi-io */ | ||
158 | |||
159 | /* PCM information */ | ||
160 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ | ||
161 | |||
162 | /* dynamic controls, init_verbs and input_mux */ | ||
163 | struct auto_pin_cfg autocfg; | ||
164 | struct alc_customize_define cdefine; | 77 | struct alc_customize_define cdefine; |
165 | struct snd_array kctls; | 78 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ |
166 | struct hda_input_mux private_imux[3]; | 79 | |
167 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 80 | /* inverted dmic fix */ |
168 | hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; | 81 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ |
169 | hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; | 82 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ |
170 | hda_nid_t imux_pins[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 */ | ||
173 | hda_nid_t inv_dmic_pin; | 83 | hda_nid_t inv_dmic_pin; |
174 | 84 | ||
85 | /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ | ||
86 | int mute_led_polarity; | ||
87 | hda_nid_t mute_led_nid; | ||
88 | |||
175 | /* hooks */ | 89 | /* hooks */ |
176 | void (*init_hook)(struct hda_codec *codec); | 90 | void (*init_hook)(struct hda_codec *codec); |
177 | #ifdef CONFIG_PM | 91 | #ifdef CONFIG_PM |
178 | void (*power_hook)(struct hda_codec *codec); | 92 | void (*power_hook)(struct hda_codec *codec); |
179 | #endif | 93 | #endif |
180 | void (*shutup)(struct hda_codec *codec); | 94 | void (*shutup)(struct hda_codec *codec); |
181 | void (*automute_hook)(struct hda_codec *codec); | ||
182 | |||
183 | /* for pin sensing */ | ||
184 | unsigned int hp_jack_present:1; | ||
185 | unsigned int line_jack_present:1; | ||
186 | unsigned int master_mute:1; | ||
187 | unsigned int auto_mic:1; | ||
188 | unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ | ||
189 | unsigned int automute_speaker:1; /* automute speaker outputs */ | ||
190 | unsigned int automute_lo:1; /* automute LO outputs */ | ||
191 | unsigned int detect_hp:1; /* Headphone detection enabled */ | ||
192 | unsigned int detect_lo:1; /* Line-out detection enabled */ | ||
193 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | ||
194 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | ||
195 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
196 | |||
197 | /* other flags */ | ||
198 | unsigned int no_analog :1; /* digital I/O only */ | ||
199 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ | ||
200 | unsigned int single_input_src:1; | ||
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() */ | ||
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? */ | ||
206 | unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ | ||
207 | |||
208 | /* auto-mute control */ | ||
209 | int automute_mode; | ||
210 | hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; | ||
211 | 95 | ||
212 | int init_amp; | 96 | int init_amp; |
213 | int codec_variant; /* flag for other variants */ | 97 | int codec_variant; /* flag for other variants */ |
214 | 98 | ||
215 | /* for virtual master */ | ||
216 | hda_nid_t vmaster_nid; | ||
217 | struct hda_vmaster_mute_hook vmaster_mute; | ||
218 | #ifdef CONFIG_PM | ||
219 | struct hda_loopback_check loopback; | ||
220 | int num_loopbacks; | ||
221 | struct hda_amp_list loopback_list[8]; | ||
222 | #endif | ||
223 | |||
224 | /* for PLL fix */ | 99 | /* for PLL fix */ |
225 | hda_nid_t pll_nid; | 100 | hda_nid_t pll_nid; |
226 | unsigned int pll_coef_idx, pll_coef_bit; | 101 | unsigned int pll_coef_idx, pll_coef_bit; |
227 | unsigned int coef0; | 102 | unsigned int coef0; |
228 | |||
229 | /* multi-io */ | ||
230 | int multi_ios; | ||
231 | struct alc_multi_io multi_io[4]; | ||
232 | |||
233 | /* bind volumes */ | ||
234 | struct snd_array bind_ctls; | ||
235 | }; | 103 | }; |
236 | 104 | ||
237 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, | ||
238 | int dir, unsigned int bits) | ||
239 | { | ||
240 | if (!nid) | ||
241 | return false; | ||
242 | if (get_wcaps(codec, nid) & (1 << (dir + 1))) | ||
243 | if (query_amp_caps(codec, nid, dir) & bits) | ||
244 | return true; | ||
245 | return false; | ||
246 | } | ||
247 | |||
248 | #define nid_has_mute(codec, nid, dir) \ | ||
249 | check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) | ||
250 | #define nid_has_volume(codec, nid, dir) \ | ||
251 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) | ||
252 | |||
253 | /* | ||
254 | * input MUX handling | ||
255 | */ | ||
256 | static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
257 | struct snd_ctl_elem_info *uinfo) | ||
258 | { | ||
259 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
260 | struct alc_spec *spec = codec->spec; | ||
261 | unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); | ||
262 | if (mux_idx >= spec->num_mux_defs) | ||
263 | mux_idx = 0; | ||
264 | if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) | ||
265 | mux_idx = 0; | ||
266 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); | ||
267 | } | ||
268 | |||
269 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
270 | struct snd_ctl_elem_value *ucontrol) | ||
271 | { | ||
272 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
273 | struct alc_spec *spec = codec->spec; | ||
274 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
275 | |||
276 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | ||
281 | { | ||
282 | struct alc_spec *spec = codec->spec; | ||
283 | hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]]; | ||
284 | |||
285 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
286 | /* stream is running, let's swap the current ADC */ | ||
287 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
288 | spec->cur_adc = new_adc; | ||
289 | snd_hda_codec_setup_stream(codec, new_adc, | ||
290 | spec->cur_adc_stream_tag, 0, | ||
291 | spec->cur_adc_format); | ||
292 | return true; | ||
293 | } | ||
294 | return false; | ||
295 | } | ||
296 | |||
297 | static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | ||
298 | { | ||
299 | return spec->capsrc_nids ? | ||
300 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; | ||
301 | } | ||
302 | |||
303 | static void call_update_outputs(struct hda_codec *codec); | ||
304 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); | ||
305 | |||
306 | /* for shared I/O, change the pin-control accordingly */ | ||
307 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | ||
308 | { | ||
309 | struct alc_spec *spec = codec->spec; | ||
310 | unsigned int val; | ||
311 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
312 | /* NOTE: this assumes that there are only two inputs, the | ||
313 | * first is the real internal mic and the second is HP/mic jack. | ||
314 | */ | ||
315 | |||
316 | val = snd_hda_get_default_vref(codec, pin); | ||
317 | |||
318 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | ||
319 | instead, as suggested by Realtek */ | ||
320 | if (val == AC_PINCTL_VREF_HIZ) { | ||
321 | const hda_nid_t vref_pin = 0x18; | ||
322 | /* Sanity check pin 0x18 */ | ||
323 | if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN && | ||
324 | get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) { | ||
325 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | ||
326 | if (vref_val != AC_PINCTL_VREF_HIZ) | ||
327 | snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0)); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | val = set_as_mic ? val | PIN_IN : PIN_HP; | ||
332 | snd_hda_set_pin_ctl(codec, pin, val); | ||
333 | |||
334 | spec->automute_speaker = !set_as_mic; | ||
335 | call_update_outputs(codec); | ||
336 | } | ||
337 | |||
338 | /* select the given imux item; either unmute exclusively or select the route */ | ||
339 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | ||
340 | unsigned int idx, bool force) | ||
341 | { | ||
342 | struct alc_spec *spec = codec->spec; | ||
343 | const struct hda_input_mux *imux; | ||
344 | unsigned int mux_idx; | ||
345 | int i, type, num_conns; | ||
346 | hda_nid_t nid; | ||
347 | |||
348 | if (!spec->input_mux) | ||
349 | return 0; | ||
350 | |||
351 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | ||
352 | imux = &spec->input_mux[mux_idx]; | ||
353 | if (!imux->num_items && mux_idx > 0) | ||
354 | imux = &spec->input_mux[0]; | ||
355 | if (!imux->num_items) | ||
356 | return 0; | ||
357 | |||
358 | if (idx >= imux->num_items) | ||
359 | idx = imux->num_items - 1; | ||
360 | if (spec->cur_mux[adc_idx] == idx && !force) | ||
361 | return 0; | ||
362 | spec->cur_mux[adc_idx] = idx; | ||
363 | |||
364 | if (spec->shared_mic_hp) | ||
365 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); | ||
366 | |||
367 | if (spec->dyn_adc_switch) { | ||
368 | alc_dyn_adc_pcm_resetup(codec, idx); | ||
369 | adc_idx = spec->dyn_adc_idx[idx]; | ||
370 | } | ||
371 | |||
372 | nid = get_capsrc(spec, adc_idx); | ||
373 | |||
374 | /* no selection? */ | ||
375 | num_conns = snd_hda_get_num_conns(codec, nid); | ||
376 | if (num_conns <= 1) | ||
377 | return 1; | ||
378 | |||
379 | type = get_wcaps_type(get_wcaps(codec, nid)); | ||
380 | if (type == AC_WID_AUD_MIX) { | ||
381 | /* Matrix-mixer style (e.g. ALC882) */ | ||
382 | int active = imux->items[idx].index; | ||
383 | for (i = 0; i < num_conns; i++) { | ||
384 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; | ||
385 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, | ||
386 | HDA_AMP_MUTE, v); | ||
387 | } | ||
388 | } else { | ||
389 | /* MUX style (e.g. ALC880) */ | ||
390 | snd_hda_codec_write_cache(codec, nid, 0, | ||
391 | AC_VERB_SET_CONNECT_SEL, | ||
392 | imux->items[idx].index); | ||
393 | } | ||
394 | alc_inv_dmic_sync(codec, true); | ||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
399 | struct snd_ctl_elem_value *ucontrol) | ||
400 | { | ||
401 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
402 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
403 | return alc_mux_select(codec, adc_idx, | ||
404 | ucontrol->value.enumerated.item[0], false); | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * set up the input pin config (depending on the given auto-pin type) | ||
409 | */ | ||
410 | static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | ||
411 | int auto_pin_type) | ||
412 | { | ||
413 | unsigned int val = PIN_IN; | ||
414 | if (auto_pin_type == AUTO_PIN_MIC) | ||
415 | val |= snd_hda_get_default_vref(codec, nid); | ||
416 | snd_hda_set_pin_ctl(codec, nid, val); | ||
417 | } | ||
418 | |||
419 | /* | 105 | /* |
420 | * Append the given mixer and verb elements for the later use | 106 | * Append the given mixer and verb elements for the later use |
421 | * The mixer array is referred in build_controls(), and init_verbs are | 107 | * The mixer array is referred in build_controls(), and init_verbs are |
@@ -485,171 +171,6 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
485 | alc_fix_pll(codec); | 171 | alc_fix_pll(codec); |
486 | } | 172 | } |
487 | 173 | ||
488 | /* | ||
489 | * Jack detections for HP auto-mute and mic-switch | ||
490 | */ | ||
491 | |||
492 | /* check each pin in the given array; returns true if any of them is plugged */ | ||
493 | static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | ||
494 | { | ||
495 | int i, present = 0; | ||
496 | |||
497 | for (i = 0; i < num_pins; i++) { | ||
498 | hda_nid_t nid = pins[i]; | ||
499 | if (!nid) | ||
500 | break; | ||
501 | present |= snd_hda_jack_detect(codec, nid); | ||
502 | } | ||
503 | return present; | ||
504 | } | ||
505 | |||
506 | /* standard HP/line-out auto-mute helper */ | ||
507 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | ||
508 | bool mute, bool hp_out) | ||
509 | { | ||
510 | struct alc_spec *spec = codec->spec; | ||
511 | unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; | ||
512 | unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); | ||
513 | int i; | ||
514 | |||
515 | for (i = 0; i < num_pins; i++) { | ||
516 | hda_nid_t nid = pins[i]; | ||
517 | unsigned int val; | ||
518 | if (!nid) | ||
519 | break; | ||
520 | switch (spec->automute_mode) { | ||
521 | case ALC_AUTOMUTE_PIN: | ||
522 | /* don't reset VREF value in case it's controlling | ||
523 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
524 | */ | ||
525 | if (spec->keep_vref_in_automute) { | ||
526 | val = snd_hda_codec_read(codec, nid, 0, | ||
527 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
528 | val &= ~PIN_HP; | ||
529 | } else | ||
530 | val = 0; | ||
531 | val |= pin_bits; | ||
532 | snd_hda_set_pin_ctl(codec, nid, val); | ||
533 | break; | ||
534 | case ALC_AUTOMUTE_AMP: | ||
535 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
536 | HDA_AMP_MUTE, mute_bits); | ||
537 | break; | ||
538 | case ALC_AUTOMUTE_MIXER: | ||
539 | nid = spec->automute_mixer_nid[i]; | ||
540 | if (!nid) | ||
541 | break; | ||
542 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, | ||
543 | HDA_AMP_MUTE, mute_bits); | ||
544 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, | ||
545 | HDA_AMP_MUTE, mute_bits); | ||
546 | break; | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | |||
551 | /* Toggle outputs muting */ | ||
552 | static void update_outputs(struct hda_codec *codec) | ||
553 | { | ||
554 | struct alc_spec *spec = codec->spec; | ||
555 | int on; | ||
556 | |||
557 | /* Control HP pins/amps depending on master_mute state; | ||
558 | * in general, HP pins/amps control should be enabled in all cases, | ||
559 | * but currently set only for master_mute, just to be safe | ||
560 | */ | ||
561 | if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ | ||
562 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
563 | spec->autocfg.hp_pins, spec->master_mute, true); | ||
564 | |||
565 | if (!spec->automute_speaker) | ||
566 | on = 0; | ||
567 | else | ||
568 | on = spec->hp_jack_present | spec->line_jack_present; | ||
569 | on |= spec->master_mute; | ||
570 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | ||
571 | spec->autocfg.speaker_pins, on, false); | ||
572 | |||
573 | /* toggle line-out mutes if needed, too */ | ||
574 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
575 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || | ||
576 | spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) | ||
577 | return; | ||
578 | if (!spec->automute_lo) | ||
579 | on = 0; | ||
580 | else | ||
581 | on = spec->hp_jack_present; | ||
582 | on |= spec->master_mute; | ||
583 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
584 | spec->autocfg.line_out_pins, on, false); | ||
585 | } | ||
586 | |||
587 | static void call_update_outputs(struct hda_codec *codec) | ||
588 | { | ||
589 | struct alc_spec *spec = codec->spec; | ||
590 | if (spec->automute_hook) | ||
591 | spec->automute_hook(codec); | ||
592 | else | ||
593 | update_outputs(codec); | ||
594 | } | ||
595 | |||
596 | /* standard HP-automute helper */ | ||
597 | static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
598 | { | ||
599 | struct alc_spec *spec = codec->spec; | ||
600 | |||
601 | spec->hp_jack_present = | ||
602 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
603 | spec->autocfg.hp_pins); | ||
604 | if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo)) | ||
605 | return; | ||
606 | call_update_outputs(codec); | ||
607 | } | ||
608 | |||
609 | /* standard line-out-automute helper */ | ||
610 | static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
611 | { | ||
612 | struct alc_spec *spec = codec->spec; | ||
613 | |||
614 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
615 | return; | ||
616 | /* check LO jack only when it's different from HP */ | ||
617 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) | ||
618 | return; | ||
619 | |||
620 | spec->line_jack_present = | ||
621 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
622 | spec->autocfg.line_out_pins); | ||
623 | if (!spec->automute_speaker || !spec->detect_lo) | ||
624 | return; | ||
625 | call_update_outputs(codec); | ||
626 | } | ||
627 | |||
628 | #define get_connection_index(codec, mux, nid) \ | ||
629 | snd_hda_get_conn_index(codec, mux, nid, 0) | ||
630 | |||
631 | /* standard mic auto-switch helper */ | ||
632 | static void alc_mic_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
633 | { | ||
634 | struct alc_spec *spec = codec->spec; | ||
635 | hda_nid_t *pins = spec->imux_pins; | ||
636 | |||
637 | if (!spec->auto_mic || !spec->auto_mic_valid_imux) | ||
638 | return; | ||
639 | if (snd_BUG_ON(!spec->adc_nids)) | ||
640 | return; | ||
641 | if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0)) | ||
642 | return; | ||
643 | |||
644 | if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx])) | ||
645 | alc_mux_select(codec, 0, spec->ext_mic_idx, false); | ||
646 | else if (spec->dock_mic_idx >= 0 && | ||
647 | snd_hda_jack_detect(codec, pins[spec->dock_mic_idx])) | ||
648 | alc_mux_select(codec, 0, spec->dock_mic_idx, false); | ||
649 | else | ||
650 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | ||
651 | } | ||
652 | |||
653 | /* update the master volume per volume-knob's unsol event */ | 174 | /* update the master volume per volume-knob's unsol event */ |
654 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) | 175 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) |
655 | { | 176 | { |
@@ -679,14 +200,6 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | |||
679 | snd_hda_jack_unsol_event(codec, res >> 2); | 200 | snd_hda_jack_unsol_event(codec, res >> 2); |
680 | } | 201 | } |
681 | 202 | ||
682 | /* call init functions of standard auto-mute helpers */ | ||
683 | static void alc_inithook(struct hda_codec *codec) | ||
684 | { | ||
685 | alc_hp_automute(codec, NULL); | ||
686 | alc_line_automute(codec, NULL); | ||
687 | alc_mic_automute(codec, NULL); | ||
688 | } | ||
689 | |||
690 | /* additional initialization for ALC888 variants */ | 203 | /* additional initialization for ALC888 variants */ |
691 | static void alc888_coef_init(struct hda_codec *codec) | 204 | static void alc888_coef_init(struct hda_codec *codec) |
692 | { | 205 | { |
@@ -807,366 +320,6 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
807 | } | 320 | } |
808 | } | 321 | } |
809 | 322 | ||
810 | /* | ||
811 | * Auto-Mute mode mixer enum support | ||
812 | */ | ||
813 | static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, | ||
814 | struct snd_ctl_elem_info *uinfo) | ||
815 | { | ||
816 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
817 | struct alc_spec *spec = codec->spec; | ||
818 | static const char * const texts3[] = { | ||
819 | "Disabled", "Speaker Only", "Line Out+Speaker" | ||
820 | }; | ||
821 | |||
822 | if (spec->automute_speaker_possible && spec->automute_lo_possible) | ||
823 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | ||
824 | return snd_hda_enum_bool_helper_info(kcontrol, uinfo); | ||
825 | } | ||
826 | |||
827 | static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, | ||
828 | struct snd_ctl_elem_value *ucontrol) | ||
829 | { | ||
830 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
831 | struct alc_spec *spec = codec->spec; | ||
832 | unsigned int val = 0; | ||
833 | if (spec->automute_speaker) | ||
834 | val++; | ||
835 | if (spec->automute_lo) | ||
836 | val++; | ||
837 | |||
838 | ucontrol->value.enumerated.item[0] = val; | ||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, | ||
843 | struct snd_ctl_elem_value *ucontrol) | ||
844 | { | ||
845 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
846 | struct alc_spec *spec = codec->spec; | ||
847 | |||
848 | switch (ucontrol->value.enumerated.item[0]) { | ||
849 | case 0: | ||
850 | if (!spec->automute_speaker && !spec->automute_lo) | ||
851 | return 0; | ||
852 | spec->automute_speaker = 0; | ||
853 | spec->automute_lo = 0; | ||
854 | break; | ||
855 | case 1: | ||
856 | if (spec->automute_speaker_possible) { | ||
857 | if (!spec->automute_lo && spec->automute_speaker) | ||
858 | return 0; | ||
859 | spec->automute_speaker = 1; | ||
860 | spec->automute_lo = 0; | ||
861 | } else if (spec->automute_lo_possible) { | ||
862 | if (spec->automute_lo) | ||
863 | return 0; | ||
864 | spec->automute_lo = 1; | ||
865 | } else | ||
866 | return -EINVAL; | ||
867 | break; | ||
868 | case 2: | ||
869 | if (!spec->automute_lo_possible || !spec->automute_speaker_possible) | ||
870 | return -EINVAL; | ||
871 | if (spec->automute_speaker && spec->automute_lo) | ||
872 | return 0; | ||
873 | spec->automute_speaker = 1; | ||
874 | spec->automute_lo = 1; | ||
875 | break; | ||
876 | default: | ||
877 | return -EINVAL; | ||
878 | } | ||
879 | call_update_outputs(codec); | ||
880 | return 1; | ||
881 | } | ||
882 | |||
883 | static const struct snd_kcontrol_new alc_automute_mode_enum = { | ||
884 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
885 | .name = "Auto-Mute Mode", | ||
886 | .info = alc_automute_mode_info, | ||
887 | .get = alc_automute_mode_get, | ||
888 | .put = alc_automute_mode_put, | ||
889 | }; | ||
890 | |||
891 | static struct snd_kcontrol_new * | ||
892 | alc_kcontrol_new(struct alc_spec *spec, const char *name, | ||
893 | const struct snd_kcontrol_new *temp) | ||
894 | { | ||
895 | struct snd_kcontrol_new *knew = snd_array_new(&spec->kctls); | ||
896 | if (!knew) | ||
897 | return NULL; | ||
898 | *knew = *temp; | ||
899 | knew->name = kstrdup(name, GFP_KERNEL); | ||
900 | if (!knew->name) | ||
901 | return NULL; | ||
902 | return knew; | ||
903 | } | ||
904 | |||
905 | static int alc_add_automute_mode_enum(struct hda_codec *codec) | ||
906 | { | ||
907 | struct alc_spec *spec = codec->spec; | ||
908 | |||
909 | if (!alc_kcontrol_new(spec, "Auto-Mute Mode", &alc_automute_mode_enum)) | ||
910 | return -ENOMEM; | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Check the availability of HP/line-out auto-mute; | ||
916 | * Set up appropriately if really supported | ||
917 | */ | ||
918 | static int alc_init_automute(struct hda_codec *codec) | ||
919 | { | ||
920 | struct alc_spec *spec = codec->spec; | ||
921 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
922 | int present = 0; | ||
923 | int i, err; | ||
924 | |||
925 | if (cfg->hp_pins[0]) | ||
926 | present++; | ||
927 | if (cfg->line_out_pins[0]) | ||
928 | present++; | ||
929 | if (cfg->speaker_pins[0]) | ||
930 | present++; | ||
931 | if (present < 2) /* need two different output types */ | ||
932 | return 0; | ||
933 | |||
934 | if (!cfg->speaker_pins[0] && | ||
935 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
936 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
937 | sizeof(cfg->speaker_pins)); | ||
938 | cfg->speaker_outs = cfg->line_outs; | ||
939 | } | ||
940 | |||
941 | if (!cfg->hp_pins[0] && | ||
942 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
943 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
944 | sizeof(cfg->hp_pins)); | ||
945 | cfg->hp_outs = cfg->line_outs; | ||
946 | } | ||
947 | |||
948 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
949 | |||
950 | for (i = 0; i < cfg->hp_outs; i++) { | ||
951 | hda_nid_t nid = cfg->hp_pins[i]; | ||
952 | if (!is_jack_detectable(codec, nid)) | ||
953 | continue; | ||
954 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | ||
955 | nid); | ||
956 | snd_hda_jack_detect_enable_callback(codec, nid, ALC_HP_EVENT, | ||
957 | alc_hp_automute); | ||
958 | spec->detect_hp = 1; | ||
959 | } | ||
960 | |||
961 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) { | ||
962 | if (cfg->speaker_outs) | ||
963 | for (i = 0; i < cfg->line_outs; i++) { | ||
964 | hda_nid_t nid = cfg->line_out_pins[i]; | ||
965 | if (!is_jack_detectable(codec, nid)) | ||
966 | continue; | ||
967 | snd_printdd("realtek: Enable Line-Out " | ||
968 | "auto-muting on NID 0x%x\n", nid); | ||
969 | snd_hda_jack_detect_enable_callback(codec, nid, ALC_FRONT_EVENT, | ||
970 | alc_line_automute); | ||
971 | spec->detect_lo = 1; | ||
972 | } | ||
973 | spec->automute_lo_possible = spec->detect_hp; | ||
974 | } | ||
975 | |||
976 | spec->automute_speaker_possible = cfg->speaker_outs && | ||
977 | (spec->detect_hp || spec->detect_lo); | ||
978 | |||
979 | spec->automute_lo = spec->automute_lo_possible; | ||
980 | spec->automute_speaker = spec->automute_speaker_possible; | ||
981 | |||
982 | if (spec->automute_speaker_possible || spec->automute_lo_possible) { | ||
983 | /* create a control for automute mode */ | ||
984 | err = alc_add_automute_mode_enum(codec); | ||
985 | if (err < 0) | ||
986 | return err; | ||
987 | } | ||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | /* return the position of NID in the list, or -1 if not found */ | ||
992 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
993 | { | ||
994 | int i; | ||
995 | for (i = 0; i < nums; i++) | ||
996 | if (list[i] == nid) | ||
997 | return i; | ||
998 | return -1; | ||
999 | } | ||
1000 | |||
1001 | /* check whether dynamic ADC-switching is available */ | ||
1002 | static bool alc_check_dyn_adc_switch(struct hda_codec *codec) | ||
1003 | { | ||
1004 | struct alc_spec *spec = codec->spec; | ||
1005 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
1006 | int i, n, idx; | ||
1007 | hda_nid_t cap, pin; | ||
1008 | |||
1009 | if (imux != spec->input_mux) /* no dynamic imux? */ | ||
1010 | return false; | ||
1011 | |||
1012 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
1013 | cap = spec->private_capsrc_nids[n]; | ||
1014 | for (i = 0; i < imux->num_items; i++) { | ||
1015 | pin = spec->imux_pins[i]; | ||
1016 | if (!pin) | ||
1017 | return false; | ||
1018 | if (get_connection_index(codec, cap, pin) < 0) | ||
1019 | break; | ||
1020 | } | ||
1021 | if (i >= imux->num_items) | ||
1022 | return true; /* no ADC-switch is needed */ | ||
1023 | } | ||
1024 | |||
1025 | for (i = 0; i < imux->num_items; i++) { | ||
1026 | pin = spec->imux_pins[i]; | ||
1027 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
1028 | cap = spec->private_capsrc_nids[n]; | ||
1029 | idx = get_connection_index(codec, cap, pin); | ||
1030 | if (idx >= 0) { | ||
1031 | imux->items[i].index = idx; | ||
1032 | spec->dyn_adc_idx[i] = n; | ||
1033 | break; | ||
1034 | } | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | snd_printdd("realtek: enabling ADC switching\n"); | ||
1039 | spec->dyn_adc_switch = 1; | ||
1040 | return true; | ||
1041 | } | ||
1042 | |||
1043 | /* check whether all auto-mic pins are valid; setup indices if OK */ | ||
1044 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) | ||
1045 | { | ||
1046 | struct alc_spec *spec = codec->spec; | ||
1047 | const struct hda_input_mux *imux; | ||
1048 | |||
1049 | if (!spec->auto_mic) | ||
1050 | return false; | ||
1051 | if (spec->auto_mic_valid_imux) | ||
1052 | return true; /* already checked */ | ||
1053 | |||
1054 | /* fill up imux indices */ | ||
1055 | if (!alc_check_dyn_adc_switch(codec)) { | ||
1056 | spec->auto_mic = 0; | ||
1057 | return false; | ||
1058 | } | ||
1059 | |||
1060 | imux = spec->input_mux; | ||
1061 | spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin, | ||
1062 | spec->imux_pins, imux->num_items); | ||
1063 | spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin, | ||
1064 | spec->imux_pins, imux->num_items); | ||
1065 | spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin, | ||
1066 | spec->imux_pins, imux->num_items); | ||
1067 | if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) { | ||
1068 | spec->auto_mic = 0; | ||
1069 | return false; /* no corresponding imux */ | ||
1070 | } | ||
1071 | |||
1072 | snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin, | ||
1073 | ALC_MIC_EVENT, alc_mic_automute); | ||
1074 | if (spec->dock_mic_pin) | ||
1075 | snd_hda_jack_detect_enable_callback(codec, spec->dock_mic_pin, | ||
1076 | ALC_MIC_EVENT, | ||
1077 | alc_mic_automute); | ||
1078 | |||
1079 | spec->auto_mic_valid_imux = 1; | ||
1080 | spec->auto_mic = 1; | ||
1081 | return true; | ||
1082 | } | ||
1083 | |||
1084 | /* | ||
1085 | * Check the availability of auto-mic switch; | ||
1086 | * Set up if really supported | ||
1087 | */ | ||
1088 | static int alc_init_auto_mic(struct hda_codec *codec) | ||
1089 | { | ||
1090 | struct alc_spec *spec = codec->spec; | ||
1091 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1092 | hda_nid_t fixed, ext, dock; | ||
1093 | int i; | ||
1094 | |||
1095 | if (spec->shared_mic_hp) | ||
1096 | return 0; /* no auto-mic for the shared I/O */ | ||
1097 | |||
1098 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; | ||
1099 | |||
1100 | fixed = ext = dock = 0; | ||
1101 | for (i = 0; i < cfg->num_inputs; i++) { | ||
1102 | hda_nid_t nid = cfg->inputs[i].pin; | ||
1103 | unsigned int defcfg; | ||
1104 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
1105 | switch (snd_hda_get_input_pin_attr(defcfg)) { | ||
1106 | case INPUT_PIN_ATTR_INT: | ||
1107 | if (fixed) | ||
1108 | return 0; /* already occupied */ | ||
1109 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
1110 | return 0; /* invalid type */ | ||
1111 | fixed = nid; | ||
1112 | break; | ||
1113 | case INPUT_PIN_ATTR_UNUSED: | ||
1114 | return 0; /* invalid entry */ | ||
1115 | case INPUT_PIN_ATTR_DOCK: | ||
1116 | if (dock) | ||
1117 | return 0; /* already occupied */ | ||
1118 | if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) | ||
1119 | return 0; /* invalid type */ | ||
1120 | dock = nid; | ||
1121 | break; | ||
1122 | default: | ||
1123 | if (ext) | ||
1124 | return 0; /* already occupied */ | ||
1125 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
1126 | return 0; /* invalid type */ | ||
1127 | ext = nid; | ||
1128 | break; | ||
1129 | } | ||
1130 | } | ||
1131 | if (!ext && dock) { | ||
1132 | ext = dock; | ||
1133 | dock = 0; | ||
1134 | } | ||
1135 | if (!ext || !fixed) | ||
1136 | return 0; | ||
1137 | if (!is_jack_detectable(codec, ext)) | ||
1138 | return 0; /* no unsol support */ | ||
1139 | if (dock && !is_jack_detectable(codec, dock)) | ||
1140 | return 0; /* no unsol support */ | ||
1141 | |||
1142 | /* check imux indices */ | ||
1143 | spec->ext_mic_pin = ext; | ||
1144 | spec->int_mic_pin = fixed; | ||
1145 | spec->dock_mic_pin = dock; | ||
1146 | |||
1147 | spec->auto_mic = 1; | ||
1148 | if (!alc_auto_mic_check_imux(codec)) | ||
1149 | return 0; | ||
1150 | |||
1151 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | ||
1152 | ext, fixed, dock); | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | /* check the availabilities of auto-mute and auto-mic switches */ | ||
1158 | static int alc_auto_check_switches(struct hda_codec *codec) | ||
1159 | { | ||
1160 | int err; | ||
1161 | |||
1162 | err = alc_init_automute(codec); | ||
1163 | if (err < 0) | ||
1164 | return err; | ||
1165 | err = alc_init_auto_mic(codec); | ||
1166 | if (err < 0) | ||
1167 | return err; | ||
1168 | return 0; | ||
1169 | } | ||
1170 | 323 | ||
1171 | /* | 324 | /* |
1172 | * Realtek SSID verification | 325 | * Realtek SSID verification |
@@ -1252,6 +405,15 @@ do_sku: | |||
1252 | return 0; | 405 | return 0; |
1253 | } | 406 | } |
1254 | 407 | ||
408 | /* return the position of NID in the list, or -1 if not found */ | ||
409 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
410 | { | ||
411 | int i; | ||
412 | for (i = 0; i < nums; i++) | ||
413 | if (list[i] == nid) | ||
414 | return i; | ||
415 | return -1; | ||
416 | } | ||
1255 | /* return true if the given NID is found in the list */ | 417 | /* return true if the given NID is found in the list */ |
1256 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 418 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
1257 | { | 419 | { |
@@ -1354,9 +516,9 @@ do_sku: | |||
1354 | * 15 : 1 --> enable the function "Mute internal speaker | 516 | * 15 : 1 --> enable the function "Mute internal speaker |
1355 | * when the external headphone out jack is plugged" | 517 | * when the external headphone out jack is plugged" |
1356 | */ | 518 | */ |
1357 | if (!spec->autocfg.hp_pins[0] && | 519 | if (!spec->gen.autocfg.hp_pins[0] && |
1358 | !(spec->autocfg.line_out_pins[0] && | 520 | !(spec->gen.autocfg.line_out_pins[0] && |
1359 | spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) { | 521 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { |
1360 | hda_nid_t nid; | 522 | hda_nid_t nid; |
1361 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 523 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
1362 | if (tmp == 0) | 524 | if (tmp == 0) |
@@ -1369,10 +531,10 @@ do_sku: | |||
1369 | nid = porti; | 531 | nid = porti; |
1370 | else | 532 | else |
1371 | return 1; | 533 | return 1; |
1372 | if (found_in_nid_list(nid, spec->autocfg.line_out_pins, | 534 | if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, |
1373 | spec->autocfg.line_outs)) | 535 | spec->gen.autocfg.line_outs)) |
1374 | return 1; | 536 | return 1; |
1375 | spec->autocfg.hp_pins[0] = nid; | 537 | spec->gen.autocfg.hp_pins[0] = nid; |
1376 | } | 538 | } |
1377 | return 1; | 539 | return 1; |
1378 | } | 540 | } |
@@ -1422,252 +584,54 @@ static unsigned int alc_get_coef0(struct hda_codec *codec) | |||
1422 | } | 584 | } |
1423 | 585 | ||
1424 | /* | 586 | /* |
1425 | * Digital I/O handling | ||
1426 | */ | ||
1427 | |||
1428 | /* set right pin controls for digital I/O */ | ||
1429 | static void alc_auto_init_digital(struct hda_codec *codec) | ||
1430 | { | ||
1431 | struct alc_spec *spec = codec->spec; | ||
1432 | int i; | ||
1433 | hda_nid_t pin, dac; | ||
1434 | |||
1435 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1436 | pin = spec->autocfg.dig_out_pins[i]; | ||
1437 | if (!pin) | ||
1438 | continue; | ||
1439 | snd_hda_set_pin_ctl(codec, pin, PIN_OUT); | ||
1440 | if (!i) | ||
1441 | dac = spec->multiout.dig_out_nid; | ||
1442 | else | ||
1443 | dac = spec->slave_dig_outs[i - 1]; | ||
1444 | if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP)) | ||
1445 | continue; | ||
1446 | snd_hda_codec_write(codec, dac, 0, | ||
1447 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1448 | AMP_OUT_UNMUTE); | ||
1449 | } | ||
1450 | pin = spec->autocfg.dig_in_pin; | ||
1451 | if (pin) | ||
1452 | snd_hda_set_pin_ctl(codec, pin, PIN_IN); | ||
1453 | } | ||
1454 | |||
1455 | /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ | ||
1456 | static void alc_auto_parse_digital(struct hda_codec *codec) | ||
1457 | { | ||
1458 | struct alc_spec *spec = codec->spec; | ||
1459 | int i, err, nums; | ||
1460 | hda_nid_t dig_nid; | ||
1461 | |||
1462 | /* support multiple SPDIFs; the secondary is set up as a slave */ | ||
1463 | nums = 0; | ||
1464 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1465 | hda_nid_t conn[4]; | ||
1466 | err = snd_hda_get_connections(codec, | ||
1467 | spec->autocfg.dig_out_pins[i], | ||
1468 | conn, ARRAY_SIZE(conn)); | ||
1469 | if (err <= 0) | ||
1470 | continue; | ||
1471 | dig_nid = conn[0]; /* assume the first element is audio-out */ | ||
1472 | if (!nums) { | ||
1473 | spec->multiout.dig_out_nid = dig_nid; | ||
1474 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
1475 | } else { | ||
1476 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
1477 | if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
1478 | break; | ||
1479 | spec->slave_dig_outs[nums - 1] = dig_nid; | ||
1480 | } | ||
1481 | nums++; | ||
1482 | } | ||
1483 | |||
1484 | if (spec->autocfg.dig_in_pin) { | ||
1485 | dig_nid = codec->start_nid; | ||
1486 | for (i = 0; i < codec->num_nodes; i++, dig_nid++) { | ||
1487 | unsigned int wcaps = get_wcaps(codec, dig_nid); | ||
1488 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) | ||
1489 | continue; | ||
1490 | if (!(wcaps & AC_WCAP_DIGITAL)) | ||
1491 | continue; | ||
1492 | if (!(wcaps & AC_WCAP_CONN_LIST)) | ||
1493 | continue; | ||
1494 | err = get_connection_index(codec, dig_nid, | ||
1495 | spec->autocfg.dig_in_pin); | ||
1496 | if (err >= 0) { | ||
1497 | spec->dig_in_nid = dig_nid; | ||
1498 | break; | ||
1499 | } | ||
1500 | } | ||
1501 | } | ||
1502 | } | ||
1503 | |||
1504 | /* | ||
1505 | * capture mixer elements | ||
1506 | */ | 587 | */ |
1507 | static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, | ||
1508 | struct snd_ctl_elem_info *uinfo) | ||
1509 | { | ||
1510 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1511 | struct alc_spec *spec = codec->spec; | ||
1512 | unsigned long val; | ||
1513 | int err; | ||
1514 | 588 | ||
1515 | mutex_lock(&codec->control_mutex); | 589 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) |
1516 | if (spec->vol_in_capsrc) | ||
1517 | val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); | ||
1518 | else | ||
1519 | val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); | ||
1520 | kcontrol->private_value = val; | ||
1521 | err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); | ||
1522 | mutex_unlock(&codec->control_mutex); | ||
1523 | return err; | ||
1524 | } | ||
1525 | |||
1526 | static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
1527 | unsigned int size, unsigned int __user *tlv) | ||
1528 | { | 590 | { |
1529 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 591 | struct hda_gen_spec *spec = codec->spec; |
1530 | struct alc_spec *spec = codec->spec; | 592 | if (spec->dyn_adc_switch) |
1531 | unsigned long val; | 593 | adc_idx = spec->dyn_adc_idx[imux_idx]; |
1532 | int err; | 594 | return spec->adc_nids[adc_idx]; |
1533 | |||
1534 | mutex_lock(&codec->control_mutex); | ||
1535 | if (spec->vol_in_capsrc) | ||
1536 | val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); | ||
1537 | else | ||
1538 | val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); | ||
1539 | kcontrol->private_value = val; | ||
1540 | err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); | ||
1541 | mutex_unlock(&codec->control_mutex); | ||
1542 | return err; | ||
1543 | } | 595 | } |
1544 | 596 | ||
1545 | typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | 597 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) |
1546 | struct snd_ctl_elem_value *ucontrol); | ||
1547 | |||
1548 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | ||
1549 | struct snd_ctl_elem_value *ucontrol, | ||
1550 | getput_call_t func, bool is_put) | ||
1551 | { | 598 | { |
1552 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1553 | struct alc_spec *spec = codec->spec; | 599 | struct alc_spec *spec = codec->spec; |
1554 | int i, err = 0; | 600 | struct hda_input_mux *imux = &spec->gen.input_mux; |
1555 | 601 | struct nid_path *path; | |
1556 | mutex_lock(&codec->control_mutex); | 602 | hda_nid_t nid; |
1557 | if (is_put && spec->dyn_adc_switch) { | 603 | int i, dir, parm; |
1558 | for (i = 0; i < spec->num_adc_nids; i++) { | 604 | unsigned int val; |
1559 | kcontrol->private_value = | ||
1560 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
1561 | 3, 0, HDA_INPUT); | ||
1562 | err = func(kcontrol, ucontrol); | ||
1563 | if (err < 0) | ||
1564 | goto error; | ||
1565 | } | ||
1566 | } else { | ||
1567 | i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
1568 | if (spec->vol_in_capsrc) | ||
1569 | kcontrol->private_value = | ||
1570 | HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i], | ||
1571 | 3, 0, HDA_OUTPUT); | ||
1572 | else | ||
1573 | kcontrol->private_value = | ||
1574 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
1575 | 3, 0, HDA_INPUT); | ||
1576 | err = func(kcontrol, ucontrol); | ||
1577 | } | ||
1578 | if (err >= 0 && is_put) | ||
1579 | alc_inv_dmic_sync(codec, false); | ||
1580 | error: | ||
1581 | mutex_unlock(&codec->control_mutex); | ||
1582 | return err; | ||
1583 | } | ||
1584 | |||
1585 | static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, | ||
1586 | struct snd_ctl_elem_value *ucontrol) | ||
1587 | { | ||
1588 | return alc_cap_getput_caller(kcontrol, ucontrol, | ||
1589 | snd_hda_mixer_amp_volume_get, false); | ||
1590 | } | ||
1591 | |||
1592 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, | ||
1593 | struct snd_ctl_elem_value *ucontrol) | ||
1594 | { | ||
1595 | return alc_cap_getput_caller(kcontrol, ucontrol, | ||
1596 | snd_hda_mixer_amp_volume_put, true); | ||
1597 | } | ||
1598 | |||
1599 | /* capture mixer elements */ | ||
1600 | #define alc_cap_sw_info snd_ctl_boolean_stereo_info | ||
1601 | |||
1602 | static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, | ||
1603 | struct snd_ctl_elem_value *ucontrol) | ||
1604 | { | ||
1605 | return alc_cap_getput_caller(kcontrol, ucontrol, | ||
1606 | snd_hda_mixer_amp_switch_get, false); | ||
1607 | } | ||
1608 | |||
1609 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | ||
1610 | struct snd_ctl_elem_value *ucontrol) | ||
1611 | { | ||
1612 | return alc_cap_getput_caller(kcontrol, ucontrol, | ||
1613 | snd_hda_mixer_amp_switch_put, true); | ||
1614 | } | ||
1615 | 605 | ||
1616 | #define _DEFINE_CAPMIX(num) \ | 606 | for (i = 0; i < imux->num_items; i++) { |
1617 | { \ | 607 | if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) |
1618 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 608 | break; |
1619 | .name = "Capture Switch", \ | ||
1620 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
1621 | .count = num, \ | ||
1622 | .info = alc_cap_sw_info, \ | ||
1623 | .get = alc_cap_sw_get, \ | ||
1624 | .put = alc_cap_sw_put, \ | ||
1625 | }, \ | ||
1626 | { \ | ||
1627 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1628 | .name = "Capture Volume", \ | ||
1629 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
1630 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
1631 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ | ||
1632 | .count = num, \ | ||
1633 | .info = alc_cap_vol_info, \ | ||
1634 | .get = alc_cap_vol_get, \ | ||
1635 | .put = alc_cap_vol_put, \ | ||
1636 | .tlv = { .c = alc_cap_vol_tlv }, \ | ||
1637 | } | 609 | } |
610 | if (i >= imux->num_items) | ||
611 | return; | ||
1638 | 612 | ||
1639 | #define _DEFINE_CAPSRC(num) \ | 613 | path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, |
1640 | { \ | 614 | get_adc_nid(codec, adc_idx, i)); |
1641 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 615 | val = path->ctls[NID_PATH_MUTE_CTL]; |
1642 | /* .name = "Capture Source", */ \ | 616 | if (!val) |
1643 | .name = "Input Source", \ | 617 | return; |
1644 | .count = num, \ | 618 | nid = get_amp_nid_(val); |
1645 | .info = alc_mux_enum_info, \ | 619 | dir = get_amp_direction_(val); |
1646 | .get = alc_mux_enum_get, \ | 620 | parm = AC_AMP_SET_RIGHT | |
1647 | .put = alc_mux_enum_put, \ | 621 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); |
1648 | } | ||
1649 | 622 | ||
1650 | #define DEFINE_CAPMIX(num) \ | 623 | /* flush all cached amps at first */ |
1651 | static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | 624 | snd_hda_codec_flush_cache(codec); |
1652 | _DEFINE_CAPMIX(num), \ | ||
1653 | _DEFINE_CAPSRC(num), \ | ||
1654 | { } /* end */ \ | ||
1655 | } | ||
1656 | 625 | ||
1657 | #define DEFINE_CAPMIX_NOSRC(num) \ | 626 | /* we care only right channel */ |
1658 | static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ | 627 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); |
1659 | _DEFINE_CAPMIX(num), \ | 628 | if (val & 0x80) /* if already muted, we don't need to touch */ |
1660 | { } /* end */ \ | 629 | return; |
630 | val |= 0x80; | ||
631 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
632 | parm | val); | ||
1661 | } | 633 | } |
1662 | 634 | ||
1663 | /* up to three ADCs */ | ||
1664 | DEFINE_CAPMIX(1); | ||
1665 | DEFINE_CAPMIX(2); | ||
1666 | DEFINE_CAPMIX(3); | ||
1667 | DEFINE_CAPMIX_NOSRC(1); | ||
1668 | DEFINE_CAPMIX_NOSRC(2); | ||
1669 | DEFINE_CAPMIX_NOSRC(3); | ||
1670 | |||
1671 | /* | 635 | /* |
1672 | * Inverted digital-mic handling | 636 | * Inverted digital-mic handling |
1673 | * | 637 | * |
@@ -1686,43 +650,31 @@ DEFINE_CAPMIX_NOSRC(3); | |||
1686 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | 650 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) |
1687 | { | 651 | { |
1688 | struct alc_spec *spec = codec->spec; | 652 | struct alc_spec *spec = codec->spec; |
1689 | int i; | 653 | int src, nums; |
1690 | 654 | ||
1691 | if (!spec->inv_dmic_fixup) | 655 | if (!spec->inv_dmic_fixup) |
1692 | return; | 656 | return; |
1693 | if (!spec->inv_dmic_muted && !force) | 657 | if (!spec->inv_dmic_muted && !force) |
1694 | return; | 658 | return; |
1695 | for (i = 0; i < spec->num_adc_nids; i++) { | 659 | nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; |
1696 | int src = spec->dyn_adc_switch ? 0 : i; | 660 | for (src = 0; src < nums; src++) { |
1697 | bool dmic_fixup = false; | 661 | bool dmic_fixup = false; |
1698 | hda_nid_t nid; | ||
1699 | int parm, dir, v; | ||
1700 | 662 | ||
1701 | if (spec->inv_dmic_muted && | 663 | if (spec->inv_dmic_muted && |
1702 | spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) | 664 | spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) |
1703 | dmic_fixup = true; | 665 | dmic_fixup = true; |
1704 | if (!dmic_fixup && !force) | 666 | if (!dmic_fixup && !force) |
1705 | continue; | 667 | continue; |
1706 | if (spec->vol_in_capsrc) { | 668 | alc_inv_dmic_sync_adc(codec, src); |
1707 | nid = spec->capsrc_nids[i]; | ||
1708 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT; | ||
1709 | dir = HDA_OUTPUT; | ||
1710 | } else { | ||
1711 | nid = spec->adc_nids[i]; | ||
1712 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT; | ||
1713 | dir = HDA_INPUT; | ||
1714 | } | ||
1715 | /* we care only right channel */ | ||
1716 | v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | ||
1717 | if (v & 0x80) /* if already muted, we don't need to touch */ | ||
1718 | continue; | ||
1719 | if (dmic_fixup) /* add mute for d-mic */ | ||
1720 | v |= 0x80; | ||
1721 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1722 | parm | v); | ||
1723 | } | 669 | } |
1724 | } | 670 | } |
1725 | 671 | ||
672 | static void alc_inv_dmic_hook(struct hda_codec *codec, | ||
673 | struct snd_ctl_elem_value *ucontrol) | ||
674 | { | ||
675 | alc_inv_dmic_sync(codec, false); | ||
676 | } | ||
677 | |||
1726 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, | 678 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, |
1727 | struct snd_ctl_elem_value *ucontrol) | 679 | struct snd_ctl_elem_value *ucontrol) |
1728 | { | 680 | { |
@@ -1749,6 +701,7 @@ static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, | |||
1749 | 701 | ||
1750 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { | 702 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { |
1751 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 703 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
704 | .name = "Inverted Internal Mic Capture Switch", | ||
1752 | .info = snd_ctl_boolean_mono_info, | 705 | .info = snd_ctl_boolean_mono_info, |
1753 | .get = alc_inv_dmic_sw_get, | 706 | .get = alc_inv_dmic_sw_get, |
1754 | .put = alc_inv_dmic_sw_put, | 707 | .put = alc_inv_dmic_sw_put, |
@@ -1758,51 +711,23 @@ static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) | |||
1758 | { | 711 | { |
1759 | struct alc_spec *spec = codec->spec; | 712 | struct alc_spec *spec = codec->spec; |
1760 | 713 | ||
1761 | if (!alc_kcontrol_new(spec, "Inverted Internal Mic Capture Switch", | 714 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) |
1762 | &alc_inv_dmic_sw)) | ||
1763 | return -ENOMEM; | 715 | return -ENOMEM; |
1764 | spec->inv_dmic_fixup = 1; | 716 | spec->inv_dmic_fixup = 1; |
1765 | spec->inv_dmic_muted = 0; | 717 | spec->inv_dmic_muted = 0; |
1766 | spec->inv_dmic_pin = nid; | 718 | spec->inv_dmic_pin = nid; |
719 | spec->gen.cap_sync_hook = alc_inv_dmic_hook; | ||
1767 | return 0; | 720 | return 0; |
1768 | } | 721 | } |
1769 | 722 | ||
1770 | /* typically the digital mic is put at node 0x12 */ | 723 | /* typically the digital mic is put at node 0x12 */ |
1771 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, | 724 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, |
1772 | const struct alc_fixup *fix, int action) | 725 | const struct hda_fixup *fix, int action) |
1773 | { | 726 | { |
1774 | if (action == ALC_FIXUP_ACT_PROBE) | 727 | if (action == HDA_FIXUP_ACT_PROBE) |
1775 | alc_add_inv_dmic_mixer(codec, 0x12); | 728 | alc_add_inv_dmic_mixer(codec, 0x12); |
1776 | } | 729 | } |
1777 | 730 | ||
1778 | /* | ||
1779 | * virtual master controls | ||
1780 | */ | ||
1781 | |||
1782 | /* | ||
1783 | * slave controls for virtual master | ||
1784 | */ | ||
1785 | static const char * const alc_slave_pfxs[] = { | ||
1786 | "Front", "Surround", "Center", "LFE", "Side", | ||
1787 | "Headphone", "Speaker", "Mono", "Line Out", | ||
1788 | "CLFE", "Bass Speaker", "PCM", | ||
1789 | NULL, | ||
1790 | }; | ||
1791 | |||
1792 | /* | ||
1793 | * build control elements | ||
1794 | */ | ||
1795 | |||
1796 | #define NID_MAPPING (-1) | ||
1797 | |||
1798 | #define SUBDEV_SPEAKER_ (0 << 6) | ||
1799 | #define SUBDEV_HP_ (1 << 6) | ||
1800 | #define SUBDEV_LINE_ (2 << 6) | ||
1801 | #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) | ||
1802 | #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) | ||
1803 | #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) | ||
1804 | |||
1805 | static void alc_free_kctls(struct hda_codec *codec); | ||
1806 | 731 | ||
1807 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 732 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
1808 | /* additional beep mixers; the actual parameters are overwritten at build */ | 733 | /* additional beep mixers; the actual parameters are overwritten at build */ |
@@ -1813,45 +738,20 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1813 | }; | 738 | }; |
1814 | #endif | 739 | #endif |
1815 | 740 | ||
1816 | static int __alc_build_controls(struct hda_codec *codec) | 741 | static int alc_build_controls(struct hda_codec *codec) |
1817 | { | 742 | { |
1818 | struct alc_spec *spec = codec->spec; | 743 | struct alc_spec *spec = codec->spec; |
1819 | struct snd_kcontrol *kctl = NULL; | 744 | int i, err; |
1820 | const struct snd_kcontrol_new *knew; | 745 | |
1821 | int i, j, err; | 746 | err = snd_hda_gen_build_controls(codec); |
1822 | unsigned int u; | 747 | if (err < 0) |
1823 | hda_nid_t nid; | 748 | return err; |
1824 | 749 | ||
1825 | for (i = 0; i < spec->num_mixers; i++) { | 750 | for (i = 0; i < spec->num_mixers; i++) { |
1826 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 751 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
1827 | if (err < 0) | 752 | if (err < 0) |
1828 | return err; | 753 | return err; |
1829 | } | 754 | } |
1830 | if (spec->cap_mixer) { | ||
1831 | err = snd_hda_add_new_ctls(codec, spec->cap_mixer); | ||
1832 | if (err < 0) | ||
1833 | return err; | ||
1834 | } | ||
1835 | if (spec->multiout.dig_out_nid) { | ||
1836 | err = snd_hda_create_dig_out_ctls(codec, | ||
1837 | spec->multiout.dig_out_nid, | ||
1838 | spec->multiout.dig_out_nid, | ||
1839 | spec->pcm_rec[1].pcm_type); | ||
1840 | if (err < 0) | ||
1841 | return err; | ||
1842 | if (!spec->no_analog) { | ||
1843 | err = snd_hda_create_spdif_share_sw(codec, | ||
1844 | &spec->multiout); | ||
1845 | if (err < 0) | ||
1846 | return err; | ||
1847 | spec->multiout.share_spdif = 1; | ||
1848 | } | ||
1849 | } | ||
1850 | if (spec->dig_in_nid) { | ||
1851 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
1852 | if (err < 0) | ||
1853 | return err; | ||
1854 | } | ||
1855 | 755 | ||
1856 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 756 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
1857 | /* create beep controls if needed */ | 757 | /* create beep controls if needed */ |
@@ -1870,130 +770,7 @@ static int __alc_build_controls(struct hda_codec *codec) | |||
1870 | } | 770 | } |
1871 | #endif | 771 | #endif |
1872 | 772 | ||
1873 | /* if we have no master control, let's create it */ | 773 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); |
1874 | if (!spec->no_analog && | ||
1875 | !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | ||
1876 | unsigned int vmaster_tlv[4]; | ||
1877 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | ||
1878 | HDA_OUTPUT, vmaster_tlv); | ||
1879 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | ||
1880 | vmaster_tlv, alc_slave_pfxs, | ||
1881 | "Playback Volume"); | ||
1882 | if (err < 0) | ||
1883 | return err; | ||
1884 | } | ||
1885 | if (!spec->no_analog && | ||
1886 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | ||
1887 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", | ||
1888 | NULL, alc_slave_pfxs, | ||
1889 | "Playback Switch", | ||
1890 | true, &spec->vmaster_mute.sw_kctl); | ||
1891 | if (err < 0) | ||
1892 | return err; | ||
1893 | } | ||
1894 | |||
1895 | /* assign Capture Source enums to NID */ | ||
1896 | if (spec->capsrc_nids || spec->adc_nids) { | ||
1897 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
1898 | if (!kctl) | ||
1899 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
1900 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1901 | err = snd_hda_add_nid(codec, kctl, i, | ||
1902 | get_capsrc(spec, i)); | ||
1903 | if (err < 0) | ||
1904 | return err; | ||
1905 | } | ||
1906 | } | ||
1907 | if (spec->cap_mixer && spec->adc_nids) { | ||
1908 | const char *kname = kctl ? kctl->id.name : NULL; | ||
1909 | for (knew = spec->cap_mixer; knew->name; knew++) { | ||
1910 | if (kname && strcmp(knew->name, kname) == 0) | ||
1911 | continue; | ||
1912 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1913 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1914 | err = snd_hda_add_nid(codec, kctl, i, | ||
1915 | spec->adc_nids[i]); | ||
1916 | if (err < 0) | ||
1917 | return err; | ||
1918 | } | ||
1919 | } | ||
1920 | } | ||
1921 | |||
1922 | /* other nid->control mapping */ | ||
1923 | for (i = 0; i < spec->num_mixers; i++) { | ||
1924 | for (knew = spec->mixers[i]; knew->name; knew++) { | ||
1925 | if (knew->iface != NID_MAPPING) | ||
1926 | continue; | ||
1927 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1928 | if (kctl == NULL) | ||
1929 | continue; | ||
1930 | u = knew->subdevice; | ||
1931 | for (j = 0; j < 4; j++, u >>= 8) { | ||
1932 | nid = u & 0x3f; | ||
1933 | if (nid == 0) | ||
1934 | continue; | ||
1935 | switch (u & 0xc0) { | ||
1936 | case SUBDEV_SPEAKER_: | ||
1937 | nid = spec->autocfg.speaker_pins[nid]; | ||
1938 | break; | ||
1939 | case SUBDEV_LINE_: | ||
1940 | nid = spec->autocfg.line_out_pins[nid]; | ||
1941 | break; | ||
1942 | case SUBDEV_HP_: | ||
1943 | nid = spec->autocfg.hp_pins[nid]; | ||
1944 | break; | ||
1945 | default: | ||
1946 | continue; | ||
1947 | } | ||
1948 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
1949 | if (err < 0) | ||
1950 | return err; | ||
1951 | } | ||
1952 | u = knew->private_value; | ||
1953 | for (j = 0; j < 4; j++, u >>= 8) { | ||
1954 | nid = u & 0xff; | ||
1955 | if (nid == 0) | ||
1956 | continue; | ||
1957 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
1958 | if (err < 0) | ||
1959 | return err; | ||
1960 | } | ||
1961 | } | ||
1962 | } | ||
1963 | |||
1964 | alc_free_kctls(codec); /* no longer needed */ | ||
1965 | |||
1966 | return 0; | ||
1967 | } | ||
1968 | |||
1969 | static int alc_build_jacks(struct hda_codec *codec) | ||
1970 | { | ||
1971 | struct alc_spec *spec = codec->spec; | ||
1972 | |||
1973 | if (spec->shared_mic_hp) { | ||
1974 | int err; | ||
1975 | int nid = spec->autocfg.inputs[1].pin; | ||
1976 | err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); | ||
1977 | if (err < 0) | ||
1978 | return err; | ||
1979 | err = snd_hda_jack_detect_enable(codec, nid, 0); | ||
1980 | if (err < 0) | ||
1981 | return err; | ||
1982 | } | ||
1983 | |||
1984 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1985 | } | ||
1986 | |||
1987 | static int alc_build_controls(struct hda_codec *codec) | ||
1988 | { | ||
1989 | int err = __alc_build_controls(codec); | ||
1990 | if (err < 0) | ||
1991 | return err; | ||
1992 | |||
1993 | err = alc_build_jacks(codec); | ||
1994 | if (err < 0) | ||
1995 | return err; | ||
1996 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); | ||
1997 | return 0; | 774 | return 0; |
1998 | } | 775 | } |
1999 | 776 | ||
@@ -2002,9 +779,6 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2002 | * Common callbacks | 779 | * Common callbacks |
2003 | */ | 780 | */ |
2004 | 781 | ||
2005 | static void alc_init_special_input_src(struct hda_codec *codec); | ||
2006 | static void alc_auto_init_std(struct hda_codec *codec); | ||
2007 | |||
2008 | static int alc_init(struct hda_codec *codec) | 782 | static int alc_init(struct hda_codec *codec) |
2009 | { | 783 | { |
2010 | struct alc_spec *spec = codec->spec; | 784 | struct alc_spec *spec = codec->spec; |
@@ -2015,347 +789,9 @@ static int alc_init(struct hda_codec *codec) | |||
2015 | alc_fix_pll(codec); | 789 | alc_fix_pll(codec); |
2016 | alc_auto_init_amp(codec, spec->init_amp); | 790 | alc_auto_init_amp(codec, spec->init_amp); |
2017 | 791 | ||
2018 | snd_hda_gen_apply_verbs(codec); | 792 | snd_hda_gen_init(codec); |
2019 | alc_init_special_input_src(codec); | ||
2020 | alc_auto_init_std(codec); | ||
2021 | 793 | ||
2022 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); | 794 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); |
2023 | |||
2024 | hda_call_check_power_status(codec, 0x01); | ||
2025 | return 0; | ||
2026 | } | ||
2027 | |||
2028 | #ifdef CONFIG_PM | ||
2029 | static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) | ||
2030 | { | ||
2031 | struct alc_spec *spec = codec->spec; | ||
2032 | return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); | ||
2033 | } | ||
2034 | #endif | ||
2035 | |||
2036 | /* | ||
2037 | * Analog playback callbacks | ||
2038 | */ | ||
2039 | static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
2040 | struct hda_codec *codec, | ||
2041 | struct snd_pcm_substream *substream) | ||
2042 | { | ||
2043 | struct alc_spec *spec = codec->spec; | ||
2044 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
2045 | hinfo); | ||
2046 | } | ||
2047 | |||
2048 | static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2049 | struct hda_codec *codec, | ||
2050 | unsigned int stream_tag, | ||
2051 | unsigned int format, | ||
2052 | struct snd_pcm_substream *substream) | ||
2053 | { | ||
2054 | struct alc_spec *spec = codec->spec; | ||
2055 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
2056 | stream_tag, format, substream); | ||
2057 | } | ||
2058 | |||
2059 | static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2060 | struct hda_codec *codec, | ||
2061 | struct snd_pcm_substream *substream) | ||
2062 | { | ||
2063 | struct alc_spec *spec = codec->spec; | ||
2064 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
2065 | } | ||
2066 | |||
2067 | /* | ||
2068 | * Digital out | ||
2069 | */ | ||
2070 | static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
2071 | struct hda_codec *codec, | ||
2072 | struct snd_pcm_substream *substream) | ||
2073 | { | ||
2074 | struct alc_spec *spec = codec->spec; | ||
2075 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
2076 | } | ||
2077 | |||
2078 | static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2079 | struct hda_codec *codec, | ||
2080 | unsigned int stream_tag, | ||
2081 | unsigned int format, | ||
2082 | struct snd_pcm_substream *substream) | ||
2083 | { | ||
2084 | struct alc_spec *spec = codec->spec; | ||
2085 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
2086 | stream_tag, format, substream); | ||
2087 | } | ||
2088 | |||
2089 | static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2090 | struct hda_codec *codec, | ||
2091 | struct snd_pcm_substream *substream) | ||
2092 | { | ||
2093 | struct alc_spec *spec = codec->spec; | ||
2094 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
2095 | } | ||
2096 | |||
2097 | static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
2098 | struct hda_codec *codec, | ||
2099 | struct snd_pcm_substream *substream) | ||
2100 | { | ||
2101 | struct alc_spec *spec = codec->spec; | ||
2102 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
2103 | } | ||
2104 | |||
2105 | /* | ||
2106 | * Analog capture | ||
2107 | */ | ||
2108 | static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2109 | struct hda_codec *codec, | ||
2110 | unsigned int stream_tag, | ||
2111 | unsigned int format, | ||
2112 | struct snd_pcm_substream *substream) | ||
2113 | { | ||
2114 | struct alc_spec *spec = codec->spec; | ||
2115 | |||
2116 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], | ||
2117 | stream_tag, 0, format); | ||
2118 | return 0; | ||
2119 | } | ||
2120 | |||
2121 | static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2122 | struct hda_codec *codec, | ||
2123 | struct snd_pcm_substream *substream) | ||
2124 | { | ||
2125 | struct alc_spec *spec = codec->spec; | ||
2126 | |||
2127 | snd_hda_codec_cleanup_stream(codec, | ||
2128 | spec->adc_nids[substream->number + 1]); | ||
2129 | return 0; | ||
2130 | } | ||
2131 | |||
2132 | /* analog capture with dynamic dual-adc changes */ | ||
2133 | static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2134 | struct hda_codec *codec, | ||
2135 | unsigned int stream_tag, | ||
2136 | unsigned int format, | ||
2137 | struct snd_pcm_substream *substream) | ||
2138 | { | ||
2139 | struct alc_spec *spec = codec->spec; | ||
2140 | spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]]; | ||
2141 | spec->cur_adc_stream_tag = stream_tag; | ||
2142 | spec->cur_adc_format = format; | ||
2143 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
2144 | return 0; | ||
2145 | } | ||
2146 | |||
2147 | static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2148 | struct hda_codec *codec, | ||
2149 | struct snd_pcm_substream *substream) | ||
2150 | { | ||
2151 | struct alc_spec *spec = codec->spec; | ||
2152 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
2153 | spec->cur_adc = 0; | ||
2154 | return 0; | ||
2155 | } | ||
2156 | |||
2157 | static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = { | ||
2158 | .substreams = 1, | ||
2159 | .channels_min = 2, | ||
2160 | .channels_max = 2, | ||
2161 | .nid = 0, /* fill later */ | ||
2162 | .ops = { | ||
2163 | .prepare = dyn_adc_capture_pcm_prepare, | ||
2164 | .cleanup = dyn_adc_capture_pcm_cleanup | ||
2165 | }, | ||
2166 | }; | ||
2167 | |||
2168 | /* | ||
2169 | */ | ||
2170 | static const struct hda_pcm_stream alc_pcm_analog_playback = { | ||
2171 | .substreams = 1, | ||
2172 | .channels_min = 2, | ||
2173 | .channels_max = 8, | ||
2174 | /* NID is set in alc_build_pcms */ | ||
2175 | .ops = { | ||
2176 | .open = alc_playback_pcm_open, | ||
2177 | .prepare = alc_playback_pcm_prepare, | ||
2178 | .cleanup = alc_playback_pcm_cleanup | ||
2179 | }, | ||
2180 | }; | ||
2181 | |||
2182 | static const struct hda_pcm_stream alc_pcm_analog_capture = { | ||
2183 | .substreams = 1, | ||
2184 | .channels_min = 2, | ||
2185 | .channels_max = 2, | ||
2186 | /* NID is set in alc_build_pcms */ | ||
2187 | }; | ||
2188 | |||
2189 | static const struct hda_pcm_stream alc_pcm_analog_alt_playback = { | ||
2190 | .substreams = 1, | ||
2191 | .channels_min = 2, | ||
2192 | .channels_max = 2, | ||
2193 | /* NID is set in alc_build_pcms */ | ||
2194 | }; | ||
2195 | |||
2196 | static const struct hda_pcm_stream alc_pcm_analog_alt_capture = { | ||
2197 | .substreams = 2, /* can be overridden */ | ||
2198 | .channels_min = 2, | ||
2199 | .channels_max = 2, | ||
2200 | /* NID is set in alc_build_pcms */ | ||
2201 | .ops = { | ||
2202 | .prepare = alc_alt_capture_pcm_prepare, | ||
2203 | .cleanup = alc_alt_capture_pcm_cleanup | ||
2204 | }, | ||
2205 | }; | ||
2206 | |||
2207 | static const struct hda_pcm_stream alc_pcm_digital_playback = { | ||
2208 | .substreams = 1, | ||
2209 | .channels_min = 2, | ||
2210 | .channels_max = 2, | ||
2211 | /* NID is set in alc_build_pcms */ | ||
2212 | .ops = { | ||
2213 | .open = alc_dig_playback_pcm_open, | ||
2214 | .close = alc_dig_playback_pcm_close, | ||
2215 | .prepare = alc_dig_playback_pcm_prepare, | ||
2216 | .cleanup = alc_dig_playback_pcm_cleanup | ||
2217 | }, | ||
2218 | }; | ||
2219 | |||
2220 | static const struct hda_pcm_stream alc_pcm_digital_capture = { | ||
2221 | .substreams = 1, | ||
2222 | .channels_min = 2, | ||
2223 | .channels_max = 2, | ||
2224 | /* NID is set in alc_build_pcms */ | ||
2225 | }; | ||
2226 | |||
2227 | /* Used by alc_build_pcms to flag that a PCM has no playback stream */ | ||
2228 | static const struct hda_pcm_stream alc_pcm_null_stream = { | ||
2229 | .substreams = 0, | ||
2230 | .channels_min = 0, | ||
2231 | .channels_max = 0, | ||
2232 | }; | ||
2233 | |||
2234 | static int alc_build_pcms(struct hda_codec *codec) | ||
2235 | { | ||
2236 | struct alc_spec *spec = codec->spec; | ||
2237 | struct hda_pcm *info = spec->pcm_rec; | ||
2238 | const struct hda_pcm_stream *p; | ||
2239 | bool have_multi_adcs; | ||
2240 | int i; | ||
2241 | |||
2242 | codec->num_pcms = 1; | ||
2243 | codec->pcm_info = info; | ||
2244 | |||
2245 | if (spec->no_analog) | ||
2246 | goto skip_analog; | ||
2247 | |||
2248 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), | ||
2249 | "%s Analog", codec->chip_name); | ||
2250 | info->name = spec->stream_name_analog; | ||
2251 | |||
2252 | if (spec->multiout.num_dacs > 0) { | ||
2253 | p = spec->stream_analog_playback; | ||
2254 | if (!p) | ||
2255 | p = &alc_pcm_analog_playback; | ||
2256 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
2257 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; | ||
2258 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
2259 | spec->multiout.max_channels; | ||
2260 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
2261 | spec->autocfg.line_outs == 2) | ||
2262 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
2263 | snd_pcm_2_1_chmaps; | ||
2264 | } | ||
2265 | if (spec->adc_nids) { | ||
2266 | p = spec->stream_analog_capture; | ||
2267 | if (!p) { | ||
2268 | if (spec->dyn_adc_switch) | ||
2269 | p = &dyn_adc_pcm_analog_capture; | ||
2270 | else | ||
2271 | p = &alc_pcm_analog_capture; | ||
2272 | } | ||
2273 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
2274 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
2275 | } | ||
2276 | |||
2277 | if (spec->channel_mode) { | ||
2278 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; | ||
2279 | for (i = 0; i < spec->num_channel_mode; i++) { | ||
2280 | if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { | ||
2281 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; | ||
2282 | } | ||
2283 | } | ||
2284 | } | ||
2285 | |||
2286 | skip_analog: | ||
2287 | /* SPDIF for stream index #1 */ | ||
2288 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | ||
2289 | snprintf(spec->stream_name_digital, | ||
2290 | sizeof(spec->stream_name_digital), | ||
2291 | "%s Digital", codec->chip_name); | ||
2292 | codec->num_pcms = 2; | ||
2293 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | ||
2294 | info = spec->pcm_rec + 1; | ||
2295 | info->name = spec->stream_name_digital; | ||
2296 | if (spec->dig_out_type) | ||
2297 | info->pcm_type = spec->dig_out_type; | ||
2298 | else | ||
2299 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
2300 | if (spec->multiout.dig_out_nid) { | ||
2301 | p = spec->stream_digital_playback; | ||
2302 | if (!p) | ||
2303 | p = &alc_pcm_digital_playback; | ||
2304 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
2305 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | ||
2306 | } | ||
2307 | if (spec->dig_in_nid) { | ||
2308 | p = spec->stream_digital_capture; | ||
2309 | if (!p) | ||
2310 | p = &alc_pcm_digital_capture; | ||
2311 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
2312 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
2313 | } | ||
2314 | /* FIXME: do we need this for all Realtek codec models? */ | ||
2315 | codec->spdif_status_reset = 1; | ||
2316 | } | ||
2317 | |||
2318 | if (spec->no_analog) | ||
2319 | return 0; | ||
2320 | |||
2321 | /* If the use of more than one ADC is requested for the current | ||
2322 | * model, configure a second analog capture-only PCM. | ||
2323 | */ | ||
2324 | have_multi_adcs = (spec->num_adc_nids > 1) && | ||
2325 | !spec->dyn_adc_switch && !spec->auto_mic && | ||
2326 | (!spec->input_mux || spec->input_mux->num_items > 1); | ||
2327 | /* Additional Analaog capture for index #2 */ | ||
2328 | if (spec->alt_dac_nid || have_multi_adcs) { | ||
2329 | codec->num_pcms = 3; | ||
2330 | info = spec->pcm_rec + 2; | ||
2331 | info->name = spec->stream_name_analog; | ||
2332 | if (spec->alt_dac_nid) { | ||
2333 | p = spec->stream_analog_alt_playback; | ||
2334 | if (!p) | ||
2335 | p = &alc_pcm_analog_alt_playback; | ||
2336 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; | ||
2337 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
2338 | spec->alt_dac_nid; | ||
2339 | } else { | ||
2340 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
2341 | alc_pcm_null_stream; | ||
2342 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; | ||
2343 | } | ||
2344 | if (have_multi_adcs) { | ||
2345 | p = spec->stream_analog_alt_capture; | ||
2346 | if (!p) | ||
2347 | p = &alc_pcm_analog_alt_capture; | ||
2348 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | ||
2349 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
2350 | spec->adc_nids[1]; | ||
2351 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
2352 | spec->num_adc_nids - 1; | ||
2353 | } else { | ||
2354 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
2355 | alc_pcm_null_stream; | ||
2356 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; | ||
2357 | } | ||
2358 | } | ||
2359 | 795 | ||
2360 | return 0; | 796 | return 0; |
2361 | } | 797 | } |
@@ -2369,31 +805,6 @@ static inline void alc_shutup(struct hda_codec *codec) | |||
2369 | snd_hda_shutup_pins(codec); | 805 | snd_hda_shutup_pins(codec); |
2370 | } | 806 | } |
2371 | 807 | ||
2372 | static void alc_free_kctls(struct hda_codec *codec) | ||
2373 | { | ||
2374 | struct alc_spec *spec = codec->spec; | ||
2375 | |||
2376 | if (spec->kctls.list) { | ||
2377 | struct snd_kcontrol_new *kctl = spec->kctls.list; | ||
2378 | int i; | ||
2379 | for (i = 0; i < spec->kctls.used; i++) | ||
2380 | kfree(kctl[i].name); | ||
2381 | } | ||
2382 | snd_array_free(&spec->kctls); | ||
2383 | } | ||
2384 | |||
2385 | static void alc_free_bind_ctls(struct hda_codec *codec) | ||
2386 | { | ||
2387 | struct alc_spec *spec = codec->spec; | ||
2388 | if (spec->bind_ctls.list) { | ||
2389 | struct hda_bind_ctls **ctl = spec->bind_ctls.list; | ||
2390 | int i; | ||
2391 | for (i = 0; i < spec->bind_ctls.used; i++) | ||
2392 | kfree(ctl[i]); | ||
2393 | } | ||
2394 | snd_array_free(&spec->bind_ctls); | ||
2395 | } | ||
2396 | |||
2397 | static void alc_free(struct hda_codec *codec) | 808 | static void alc_free(struct hda_codec *codec) |
2398 | { | 809 | { |
2399 | struct alc_spec *spec = codec->spec; | 810 | struct alc_spec *spec = codec->spec; |
@@ -2401,11 +812,9 @@ static void alc_free(struct hda_codec *codec) | |||
2401 | if (!spec) | 812 | if (!spec) |
2402 | return; | 813 | return; |
2403 | 814 | ||
2404 | alc_free_kctls(codec); | 815 | snd_hda_gen_spec_free(&spec->gen); |
2405 | alc_free_bind_ctls(codec); | ||
2406 | snd_hda_gen_free(&spec->gen); | ||
2407 | kfree(spec); | ||
2408 | snd_hda_detach_beep_device(codec); | 816 | snd_hda_detach_beep_device(codec); |
817 | kfree(spec); | ||
2409 | } | 818 | } |
2410 | 819 | ||
2411 | #ifdef CONFIG_PM | 820 | #ifdef CONFIG_PM |
@@ -2441,16 +850,14 @@ static int alc_resume(struct hda_codec *codec) | |||
2441 | */ | 850 | */ |
2442 | static const struct hda_codec_ops alc_patch_ops = { | 851 | static const struct hda_codec_ops alc_patch_ops = { |
2443 | .build_controls = alc_build_controls, | 852 | .build_controls = alc_build_controls, |
2444 | .build_pcms = alc_build_pcms, | 853 | .build_pcms = snd_hda_gen_build_pcms, |
2445 | .init = alc_init, | 854 | .init = alc_init, |
2446 | .free = alc_free, | 855 | .free = alc_free, |
2447 | .unsol_event = snd_hda_jack_unsol_event, | 856 | .unsol_event = snd_hda_jack_unsol_event, |
2448 | #ifdef CONFIG_PM | 857 | #ifdef CONFIG_PM |
2449 | .resume = alc_resume, | 858 | .resume = alc_resume, |
2450 | #endif | ||
2451 | #ifdef CONFIG_PM | ||
2452 | .suspend = alc_suspend, | 859 | .suspend = alc_suspend, |
2453 | .check_power_status = alc_check_power_status, | 860 | .check_power_status = snd_hda_gen_check_power_status, |
2454 | #endif | 861 | #endif |
2455 | .reboot_notify = alc_shutup, | 862 | .reboot_notify = alc_shutup, |
2456 | }; | 863 | }; |
@@ -2510,1727 +917,6 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) | |||
2510 | return 0; | 917 | return 0; |
2511 | } | 918 | } |
2512 | 919 | ||
2513 | /* | ||
2514 | * Automatic parse of I/O pins from the BIOS configuration | ||
2515 | */ | ||
2516 | |||
2517 | enum { | ||
2518 | ALC_CTL_WIDGET_VOL, | ||
2519 | ALC_CTL_WIDGET_MUTE, | ||
2520 | ALC_CTL_BIND_MUTE, | ||
2521 | ALC_CTL_BIND_VOL, | ||
2522 | ALC_CTL_BIND_SW, | ||
2523 | }; | ||
2524 | static const struct snd_kcontrol_new alc_control_templates[] = { | ||
2525 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
2526 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
2527 | HDA_BIND_MUTE(NULL, 0, 0, 0), | ||
2528 | HDA_BIND_VOL(NULL, 0), | ||
2529 | HDA_BIND_SW(NULL, 0), | ||
2530 | }; | ||
2531 | |||
2532 | /* add dynamic controls */ | ||
2533 | static int add_control(struct alc_spec *spec, int type, const char *name, | ||
2534 | int cidx, unsigned long val) | ||
2535 | { | ||
2536 | struct snd_kcontrol_new *knew; | ||
2537 | |||
2538 | knew = alc_kcontrol_new(spec, name, &alc_control_templates[type]); | ||
2539 | if (!knew) | ||
2540 | return -ENOMEM; | ||
2541 | knew->index = cidx; | ||
2542 | if (get_amp_nid_(val)) | ||
2543 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
2544 | knew->private_value = val; | ||
2545 | return 0; | ||
2546 | } | ||
2547 | |||
2548 | static int add_control_with_pfx(struct alc_spec *spec, int type, | ||
2549 | const char *pfx, const char *dir, | ||
2550 | const char *sfx, int cidx, unsigned long val) | ||
2551 | { | ||
2552 | char name[32]; | ||
2553 | snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); | ||
2554 | return add_control(spec, type, name, cidx, val); | ||
2555 | } | ||
2556 | |||
2557 | #define add_pb_vol_ctrl(spec, type, pfx, val) \ | ||
2558 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) | ||
2559 | #define add_pb_sw_ctrl(spec, type, pfx, val) \ | ||
2560 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) | ||
2561 | #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ | ||
2562 | add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) | ||
2563 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ | ||
2564 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) | ||
2565 | |||
2566 | static const char * const channel_name[4] = { | ||
2567 | "Front", "Surround", "CLFE", "Side" | ||
2568 | }; | ||
2569 | |||
2570 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | ||
2571 | bool can_be_master, int *index) | ||
2572 | { | ||
2573 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2574 | |||
2575 | *index = 0; | ||
2576 | if (cfg->line_outs == 1 && !spec->multi_ios && | ||
2577 | !cfg->hp_outs && !cfg->speaker_outs && can_be_master) | ||
2578 | return "Master"; | ||
2579 | |||
2580 | switch (cfg->line_out_type) { | ||
2581 | case AUTO_PIN_SPEAKER_OUT: | ||
2582 | if (cfg->line_outs == 1) | ||
2583 | return "Speaker"; | ||
2584 | if (cfg->line_outs == 2) | ||
2585 | return ch ? "Bass Speaker" : "Speaker"; | ||
2586 | break; | ||
2587 | case AUTO_PIN_HP_OUT: | ||
2588 | /* for multi-io case, only the primary out */ | ||
2589 | if (ch && spec->multi_ios) | ||
2590 | break; | ||
2591 | *index = ch; | ||
2592 | return "Headphone"; | ||
2593 | default: | ||
2594 | if (cfg->line_outs == 1 && !spec->multi_ios) | ||
2595 | return "PCM"; | ||
2596 | break; | ||
2597 | } | ||
2598 | if (ch >= ARRAY_SIZE(channel_name)) { | ||
2599 | snd_BUG(); | ||
2600 | return "PCM"; | ||
2601 | } | ||
2602 | |||
2603 | return channel_name[ch]; | ||
2604 | } | ||
2605 | |||
2606 | #ifdef CONFIG_PM | ||
2607 | /* add the powersave loopback-list entry */ | ||
2608 | static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx) | ||
2609 | { | ||
2610 | struct hda_amp_list *list; | ||
2611 | |||
2612 | if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1) | ||
2613 | return; | ||
2614 | list = spec->loopback_list + spec->num_loopbacks; | ||
2615 | list->nid = mix; | ||
2616 | list->dir = HDA_INPUT; | ||
2617 | list->idx = idx; | ||
2618 | spec->num_loopbacks++; | ||
2619 | spec->loopback.amplist = spec->loopback_list; | ||
2620 | } | ||
2621 | #else | ||
2622 | #define add_loopback_list(spec, mix, idx) /* NOP */ | ||
2623 | #endif | ||
2624 | |||
2625 | /* create input playback/capture controls for the given pin */ | ||
2626 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | ||
2627 | const char *ctlname, int ctlidx, | ||
2628 | int idx, hda_nid_t mix_nid) | ||
2629 | { | ||
2630 | int err; | ||
2631 | |||
2632 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, | ||
2633 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | ||
2634 | if (err < 0) | ||
2635 | return err; | ||
2636 | err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, | ||
2637 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | ||
2638 | if (err < 0) | ||
2639 | return err; | ||
2640 | add_loopback_list(spec, mix_nid, idx); | ||
2641 | return 0; | ||
2642 | } | ||
2643 | |||
2644 | static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) | ||
2645 | { | ||
2646 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | ||
2647 | return (pincap & AC_PINCAP_IN) != 0; | ||
2648 | } | ||
2649 | |||
2650 | /* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */ | ||
2651 | static int alc_auto_fill_adc_caps(struct hda_codec *codec) | ||
2652 | { | ||
2653 | struct alc_spec *spec = codec->spec; | ||
2654 | hda_nid_t nid; | ||
2655 | hda_nid_t *adc_nids = spec->private_adc_nids; | ||
2656 | hda_nid_t *cap_nids = spec->private_capsrc_nids; | ||
2657 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); | ||
2658 | int i, nums = 0; | ||
2659 | |||
2660 | nid = codec->start_nid; | ||
2661 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
2662 | hda_nid_t src; | ||
2663 | unsigned int caps = get_wcaps(codec, nid); | ||
2664 | int type = get_wcaps_type(caps); | ||
2665 | |||
2666 | if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL)) | ||
2667 | continue; | ||
2668 | adc_nids[nums] = nid; | ||
2669 | cap_nids[nums] = nid; | ||
2670 | src = nid; | ||
2671 | for (;;) { | ||
2672 | int n; | ||
2673 | type = get_wcaps_type(get_wcaps(codec, src)); | ||
2674 | if (type == AC_WID_PIN) | ||
2675 | break; | ||
2676 | if (type == AC_WID_AUD_SEL) { | ||
2677 | cap_nids[nums] = src; | ||
2678 | break; | ||
2679 | } | ||
2680 | n = snd_hda_get_num_conns(codec, src); | ||
2681 | if (n > 1) { | ||
2682 | cap_nids[nums] = src; | ||
2683 | break; | ||
2684 | } else if (n != 1) | ||
2685 | break; | ||
2686 | if (snd_hda_get_connections(codec, src, &src, 1) != 1) | ||
2687 | break; | ||
2688 | } | ||
2689 | if (++nums >= max_nums) | ||
2690 | break; | ||
2691 | } | ||
2692 | spec->adc_nids = spec->private_adc_nids; | ||
2693 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
2694 | spec->num_adc_nids = nums; | ||
2695 | return nums; | ||
2696 | } | ||
2697 | |||
2698 | /* create playback/capture controls for input pins */ | ||
2699 | static int alc_auto_create_input_ctls(struct hda_codec *codec) | ||
2700 | { | ||
2701 | struct alc_spec *spec = codec->spec; | ||
2702 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2703 | hda_nid_t mixer = spec->mixer_nid; | ||
2704 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
2705 | int num_adcs; | ||
2706 | int i, c, err, idx, type_idx = 0; | ||
2707 | const char *prev_label = NULL; | ||
2708 | |||
2709 | num_adcs = alc_auto_fill_adc_caps(codec); | ||
2710 | if (num_adcs < 0) | ||
2711 | return 0; | ||
2712 | |||
2713 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2714 | hda_nid_t pin; | ||
2715 | const char *label; | ||
2716 | |||
2717 | pin = cfg->inputs[i].pin; | ||
2718 | if (!alc_is_input_pin(codec, pin)) | ||
2719 | continue; | ||
2720 | |||
2721 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
2722 | if (spec->shared_mic_hp && !strcmp(label, "Misc")) | ||
2723 | label = "Headphone Mic"; | ||
2724 | if (prev_label && !strcmp(label, prev_label)) | ||
2725 | type_idx++; | ||
2726 | else | ||
2727 | type_idx = 0; | ||
2728 | prev_label = label; | ||
2729 | |||
2730 | if (mixer) { | ||
2731 | idx = get_connection_index(codec, mixer, pin); | ||
2732 | if (idx >= 0) { | ||
2733 | err = new_analog_input(spec, pin, | ||
2734 | label, type_idx, | ||
2735 | idx, mixer); | ||
2736 | if (err < 0) | ||
2737 | return err; | ||
2738 | } | ||
2739 | } | ||
2740 | |||
2741 | for (c = 0; c < num_adcs; c++) { | ||
2742 | hda_nid_t cap = get_capsrc(spec, c); | ||
2743 | idx = get_connection_index(codec, cap, pin); | ||
2744 | if (idx >= 0) { | ||
2745 | spec->imux_pins[imux->num_items] = pin; | ||
2746 | snd_hda_add_imux_item(imux, label, idx, NULL); | ||
2747 | break; | ||
2748 | } | ||
2749 | } | ||
2750 | } | ||
2751 | |||
2752 | spec->num_mux_defs = 1; | ||
2753 | spec->input_mux = imux; | ||
2754 | |||
2755 | return 0; | ||
2756 | } | ||
2757 | |||
2758 | /* create a shared input with the headphone out */ | ||
2759 | static int alc_auto_create_shared_input(struct hda_codec *codec) | ||
2760 | { | ||
2761 | struct alc_spec *spec = codec->spec; | ||
2762 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2763 | unsigned int defcfg; | ||
2764 | hda_nid_t nid; | ||
2765 | |||
2766 | /* only one internal input pin? */ | ||
2767 | if (cfg->num_inputs != 1) | ||
2768 | return 0; | ||
2769 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); | ||
2770 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | ||
2771 | return 0; | ||
2772 | |||
2773 | if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
2774 | nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ | ||
2775 | else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) | ||
2776 | nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ | ||
2777 | else | ||
2778 | return 0; /* both not available */ | ||
2779 | |||
2780 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) | ||
2781 | return 0; /* no input */ | ||
2782 | |||
2783 | cfg->inputs[1].pin = nid; | ||
2784 | cfg->inputs[1].type = AUTO_PIN_MIC; | ||
2785 | cfg->num_inputs = 2; | ||
2786 | spec->shared_mic_hp = 1; | ||
2787 | snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid); | ||
2788 | return 0; | ||
2789 | } | ||
2790 | |||
2791 | static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, | ||
2792 | unsigned int pin_type) | ||
2793 | { | ||
2794 | snd_hda_set_pin_ctl(codec, nid, pin_type); | ||
2795 | /* unmute pin */ | ||
2796 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
2797 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
2798 | AMP_OUT_UNMUTE); | ||
2799 | } | ||
2800 | |||
2801 | static int get_pin_type(int line_out_type) | ||
2802 | { | ||
2803 | if (line_out_type == AUTO_PIN_HP_OUT) | ||
2804 | return PIN_HP; | ||
2805 | else | ||
2806 | return PIN_OUT; | ||
2807 | } | ||
2808 | |||
2809 | static void alc_auto_init_analog_input(struct hda_codec *codec) | ||
2810 | { | ||
2811 | struct alc_spec *spec = codec->spec; | ||
2812 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2813 | int i; | ||
2814 | |||
2815 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2816 | hda_nid_t nid = cfg->inputs[i].pin; | ||
2817 | if (alc_is_input_pin(codec, nid)) { | ||
2818 | alc_set_input_pin(codec, nid, cfg->inputs[i].type); | ||
2819 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | ||
2820 | snd_hda_codec_write(codec, nid, 0, | ||
2821 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2822 | AMP_OUT_MUTE); | ||
2823 | } | ||
2824 | } | ||
2825 | |||
2826 | /* mute all loopback inputs */ | ||
2827 | if (spec->mixer_nid) { | ||
2828 | int nums = snd_hda_get_num_conns(codec, spec->mixer_nid); | ||
2829 | for (i = 0; i < nums; i++) | ||
2830 | snd_hda_codec_write(codec, spec->mixer_nid, 0, | ||
2831 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
2832 | AMP_IN_MUTE(i)); | ||
2833 | } | ||
2834 | } | ||
2835 | |||
2836 | /* convert from MIX nid to DAC */ | ||
2837 | static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) | ||
2838 | { | ||
2839 | hda_nid_t list[5]; | ||
2840 | int i, num; | ||
2841 | |||
2842 | if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT) | ||
2843 | return nid; | ||
2844 | num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); | ||
2845 | for (i = 0; i < num; i++) { | ||
2846 | if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) | ||
2847 | return list[i]; | ||
2848 | } | ||
2849 | return 0; | ||
2850 | } | ||
2851 | |||
2852 | /* go down to the selector widget before the mixer */ | ||
2853 | static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) | ||
2854 | { | ||
2855 | hda_nid_t srcs[5]; | ||
2856 | int num = snd_hda_get_connections(codec, pin, srcs, | ||
2857 | ARRAY_SIZE(srcs)); | ||
2858 | if (num != 1 || | ||
2859 | get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) | ||
2860 | return pin; | ||
2861 | return srcs[0]; | ||
2862 | } | ||
2863 | |||
2864 | /* get MIX nid connected to the given pin targeted to DAC */ | ||
2865 | static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, | ||
2866 | hda_nid_t dac) | ||
2867 | { | ||
2868 | hda_nid_t mix[5]; | ||
2869 | int i, num; | ||
2870 | |||
2871 | pin = alc_go_down_to_selector(codec, pin); | ||
2872 | num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); | ||
2873 | for (i = 0; i < num; i++) { | ||
2874 | if (alc_auto_mix_to_dac(codec, mix[i]) == dac) | ||
2875 | return mix[i]; | ||
2876 | } | ||
2877 | return 0; | ||
2878 | } | ||
2879 | |||
2880 | /* select the connection from pin to DAC if needed */ | ||
2881 | static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, | ||
2882 | hda_nid_t dac) | ||
2883 | { | ||
2884 | hda_nid_t mix[5]; | ||
2885 | int i, num; | ||
2886 | |||
2887 | pin = alc_go_down_to_selector(codec, pin); | ||
2888 | num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); | ||
2889 | if (num < 2) | ||
2890 | return 0; | ||
2891 | for (i = 0; i < num; i++) { | ||
2892 | if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { | ||
2893 | snd_hda_codec_update_cache(codec, pin, 0, | ||
2894 | AC_VERB_SET_CONNECT_SEL, i); | ||
2895 | return 0; | ||
2896 | } | ||
2897 | } | ||
2898 | return 0; | ||
2899 | } | ||
2900 | |||
2901 | static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) | ||
2902 | { | ||
2903 | struct alc_spec *spec = codec->spec; | ||
2904 | int i; | ||
2905 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | ||
2906 | ARRAY_SIZE(spec->private_dac_nids)) || | ||
2907 | found_in_nid_list(nid, spec->multiout.hp_out_nid, | ||
2908 | ARRAY_SIZE(spec->multiout.hp_out_nid)) || | ||
2909 | found_in_nid_list(nid, spec->multiout.extra_out_nid, | ||
2910 | ARRAY_SIZE(spec->multiout.extra_out_nid))) | ||
2911 | return true; | ||
2912 | for (i = 0; i < spec->multi_ios; i++) { | ||
2913 | if (spec->multi_io[i].dac == nid) | ||
2914 | return true; | ||
2915 | } | ||
2916 | return false; | ||
2917 | } | ||
2918 | |||
2919 | /* look for an empty DAC slot */ | ||
2920 | static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | ||
2921 | { | ||
2922 | hda_nid_t srcs[5]; | ||
2923 | int i, num; | ||
2924 | |||
2925 | pin = alc_go_down_to_selector(codec, pin); | ||
2926 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); | ||
2927 | for (i = 0; i < num; i++) { | ||
2928 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); | ||
2929 | if (!nid) | ||
2930 | continue; | ||
2931 | if (!alc_is_dac_already_used(codec, nid)) | ||
2932 | return nid; | ||
2933 | } | ||
2934 | return 0; | ||
2935 | } | ||
2936 | |||
2937 | /* check whether the DAC is reachable from the pin */ | ||
2938 | static bool alc_auto_is_dac_reachable(struct hda_codec *codec, | ||
2939 | hda_nid_t pin, hda_nid_t dac) | ||
2940 | { | ||
2941 | hda_nid_t srcs[5]; | ||
2942 | int i, num; | ||
2943 | |||
2944 | if (!pin || !dac) | ||
2945 | return false; | ||
2946 | pin = alc_go_down_to_selector(codec, pin); | ||
2947 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); | ||
2948 | for (i = 0; i < num; i++) { | ||
2949 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); | ||
2950 | if (nid == dac) | ||
2951 | return true; | ||
2952 | } | ||
2953 | return false; | ||
2954 | } | ||
2955 | |||
2956 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | ||
2957 | { | ||
2958 | struct alc_spec *spec = codec->spec; | ||
2959 | hda_nid_t sel = alc_go_down_to_selector(codec, pin); | ||
2960 | hda_nid_t nid, nid_found, srcs[5]; | ||
2961 | int i, num = snd_hda_get_connections(codec, sel, srcs, | ||
2962 | ARRAY_SIZE(srcs)); | ||
2963 | if (num == 1) | ||
2964 | return alc_auto_look_for_dac(codec, pin); | ||
2965 | nid_found = 0; | ||
2966 | for (i = 0; i < num; i++) { | ||
2967 | if (srcs[i] == spec->mixer_nid) | ||
2968 | continue; | ||
2969 | nid = alc_auto_mix_to_dac(codec, srcs[i]); | ||
2970 | if (nid && !alc_is_dac_already_used(codec, nid)) { | ||
2971 | if (nid_found) | ||
2972 | return 0; | ||
2973 | nid_found = nid; | ||
2974 | } | ||
2975 | } | ||
2976 | return nid_found; | ||
2977 | } | ||
2978 | |||
2979 | /* mark up volume and mute control NIDs: used during badness parsing and | ||
2980 | * at creating actual controls | ||
2981 | */ | ||
2982 | static inline unsigned int get_ctl_pos(unsigned int data) | ||
2983 | { | ||
2984 | hda_nid_t nid = get_amp_nid_(data); | ||
2985 | unsigned int dir; | ||
2986 | if (snd_BUG_ON(nid >= MAX_VOL_NIDS)) | ||
2987 | return 0; | ||
2988 | dir = get_amp_direction_(data); | ||
2989 | return (nid << 1) | dir; | ||
2990 | } | ||
2991 | |||
2992 | #define is_ctl_used(bits, data) \ | ||
2993 | test_bit(get_ctl_pos(data), bits) | ||
2994 | #define mark_ctl_usage(bits, data) \ | ||
2995 | set_bit(get_ctl_pos(data), bits) | ||
2996 | |||
2997 | static void clear_vol_marks(struct hda_codec *codec) | ||
2998 | { | ||
2999 | struct alc_spec *spec = codec->spec; | ||
3000 | memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls)); | ||
3001 | memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls)); | ||
3002 | } | ||
3003 | |||
3004 | /* badness definition */ | ||
3005 | enum { | ||
3006 | /* No primary DAC is found for the main output */ | ||
3007 | BAD_NO_PRIMARY_DAC = 0x10000, | ||
3008 | /* No DAC is found for the extra output */ | ||
3009 | BAD_NO_DAC = 0x4000, | ||
3010 | /* No possible multi-ios */ | ||
3011 | BAD_MULTI_IO = 0x103, | ||
3012 | /* No individual DAC for extra output */ | ||
3013 | BAD_NO_EXTRA_DAC = 0x102, | ||
3014 | /* No individual DAC for extra surrounds */ | ||
3015 | BAD_NO_EXTRA_SURR_DAC = 0x101, | ||
3016 | /* Primary DAC shared with main surrounds */ | ||
3017 | BAD_SHARED_SURROUND = 0x100, | ||
3018 | /* Primary DAC shared with main CLFE */ | ||
3019 | BAD_SHARED_CLFE = 0x10, | ||
3020 | /* Primary DAC shared with extra surrounds */ | ||
3021 | BAD_SHARED_EXTRA_SURROUND = 0x10, | ||
3022 | /* Volume widget is shared */ | ||
3023 | BAD_SHARED_VOL = 0x10, | ||
3024 | }; | ||
3025 | |||
3026 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, | ||
3027 | hda_nid_t pin, hda_nid_t dac); | ||
3028 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | ||
3029 | hda_nid_t pin, hda_nid_t dac); | ||
3030 | |||
3031 | static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin, | ||
3032 | hda_nid_t dac) | ||
3033 | { | ||
3034 | struct alc_spec *spec = codec->spec; | ||
3035 | hda_nid_t nid; | ||
3036 | unsigned int val; | ||
3037 | int badness = 0; | ||
3038 | |||
3039 | nid = alc_look_for_out_vol_nid(codec, pin, dac); | ||
3040 | if (nid) { | ||
3041 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3042 | if (is_ctl_used(spec->vol_ctls, nid)) | ||
3043 | badness += BAD_SHARED_VOL; | ||
3044 | else | ||
3045 | mark_ctl_usage(spec->vol_ctls, val); | ||
3046 | } else | ||
3047 | badness += BAD_SHARED_VOL; | ||
3048 | nid = alc_look_for_out_mute_nid(codec, pin, dac); | ||
3049 | if (nid) { | ||
3050 | unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid)); | ||
3051 | if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) | ||
3052 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3053 | else | ||
3054 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT); | ||
3055 | if (is_ctl_used(spec->sw_ctls, val)) | ||
3056 | badness += BAD_SHARED_VOL; | ||
3057 | else | ||
3058 | mark_ctl_usage(spec->sw_ctls, val); | ||
3059 | } else | ||
3060 | badness += BAD_SHARED_VOL; | ||
3061 | return badness; | ||
3062 | } | ||
3063 | |||
3064 | struct badness_table { | ||
3065 | int no_primary_dac; /* no primary DAC */ | ||
3066 | int no_dac; /* no secondary DACs */ | ||
3067 | int shared_primary; /* primary DAC is shared with main output */ | ||
3068 | int shared_surr; /* secondary DAC shared with main or primary */ | ||
3069 | int shared_clfe; /* third DAC shared with main or primary */ | ||
3070 | int shared_surr_main; /* secondary DAC sahred with main/DAC0 */ | ||
3071 | }; | ||
3072 | |||
3073 | static struct badness_table main_out_badness = { | ||
3074 | .no_primary_dac = BAD_NO_PRIMARY_DAC, | ||
3075 | .no_dac = BAD_NO_DAC, | ||
3076 | .shared_primary = BAD_NO_PRIMARY_DAC, | ||
3077 | .shared_surr = BAD_SHARED_SURROUND, | ||
3078 | .shared_clfe = BAD_SHARED_CLFE, | ||
3079 | .shared_surr_main = BAD_SHARED_SURROUND, | ||
3080 | }; | ||
3081 | |||
3082 | static struct badness_table extra_out_badness = { | ||
3083 | .no_primary_dac = BAD_NO_DAC, | ||
3084 | .no_dac = BAD_NO_DAC, | ||
3085 | .shared_primary = BAD_NO_EXTRA_DAC, | ||
3086 | .shared_surr = BAD_SHARED_EXTRA_SURROUND, | ||
3087 | .shared_clfe = BAD_SHARED_EXTRA_SURROUND, | ||
3088 | .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, | ||
3089 | }; | ||
3090 | |||
3091 | /* try to assign DACs to pins and return the resultant badness */ | ||
3092 | static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs, | ||
3093 | const hda_nid_t *pins, hda_nid_t *dacs, | ||
3094 | const struct badness_table *bad) | ||
3095 | { | ||
3096 | struct alc_spec *spec = codec->spec; | ||
3097 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3098 | int i, j; | ||
3099 | int badness = 0; | ||
3100 | hda_nid_t dac; | ||
3101 | |||
3102 | if (!num_outs) | ||
3103 | return 0; | ||
3104 | |||
3105 | for (i = 0; i < num_outs; i++) { | ||
3106 | hda_nid_t pin = pins[i]; | ||
3107 | if (!dacs[i]) | ||
3108 | dacs[i] = alc_auto_look_for_dac(codec, pin); | ||
3109 | if (!dacs[i] && !i) { | ||
3110 | for (j = 1; j < num_outs; j++) { | ||
3111 | if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) { | ||
3112 | dacs[0] = dacs[j]; | ||
3113 | dacs[j] = 0; | ||
3114 | break; | ||
3115 | } | ||
3116 | } | ||
3117 | } | ||
3118 | dac = dacs[i]; | ||
3119 | if (!dac) { | ||
3120 | if (alc_auto_is_dac_reachable(codec, pin, dacs[0])) | ||
3121 | dac = dacs[0]; | ||
3122 | else if (cfg->line_outs > i && | ||
3123 | alc_auto_is_dac_reachable(codec, pin, | ||
3124 | spec->private_dac_nids[i])) | ||
3125 | dac = spec->private_dac_nids[i]; | ||
3126 | if (dac) { | ||
3127 | if (!i) | ||
3128 | badness += bad->shared_primary; | ||
3129 | else if (i == 1) | ||
3130 | badness += bad->shared_surr; | ||
3131 | else | ||
3132 | badness += bad->shared_clfe; | ||
3133 | } else if (alc_auto_is_dac_reachable(codec, pin, | ||
3134 | spec->private_dac_nids[0])) { | ||
3135 | dac = spec->private_dac_nids[0]; | ||
3136 | badness += bad->shared_surr_main; | ||
3137 | } else if (!i) | ||
3138 | badness += bad->no_primary_dac; | ||
3139 | else | ||
3140 | badness += bad->no_dac; | ||
3141 | } | ||
3142 | if (dac) | ||
3143 | badness += eval_shared_vol_badness(codec, pin, dac); | ||
3144 | } | ||
3145 | |||
3146 | return badness; | ||
3147 | } | ||
3148 | |||
3149 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | ||
3150 | hda_nid_t reference_pin, | ||
3151 | bool hardwired, int offset); | ||
3152 | |||
3153 | static bool alc_map_singles(struct hda_codec *codec, int outs, | ||
3154 | const hda_nid_t *pins, hda_nid_t *dacs) | ||
3155 | { | ||
3156 | int i; | ||
3157 | bool found = false; | ||
3158 | for (i = 0; i < outs; i++) { | ||
3159 | if (dacs[i]) | ||
3160 | continue; | ||
3161 | dacs[i] = get_dac_if_single(codec, pins[i]); | ||
3162 | if (dacs[i]) | ||
3163 | found = true; | ||
3164 | } | ||
3165 | return found; | ||
3166 | } | ||
3167 | |||
3168 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
3169 | static int fill_and_eval_dacs(struct hda_codec *codec, | ||
3170 | bool fill_hardwired, | ||
3171 | bool fill_mio_first) | ||
3172 | { | ||
3173 | struct alc_spec *spec = codec->spec; | ||
3174 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3175 | int i, err, badness; | ||
3176 | |||
3177 | /* set num_dacs once to full for alc_auto_look_for_dac() */ | ||
3178 | spec->multiout.num_dacs = cfg->line_outs; | ||
3179 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
3180 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | ||
3181 | memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid)); | ||
3182 | memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid)); | ||
3183 | spec->multi_ios = 0; | ||
3184 | clear_vol_marks(codec); | ||
3185 | badness = 0; | ||
3186 | |||
3187 | /* fill hard-wired DACs first */ | ||
3188 | if (fill_hardwired) { | ||
3189 | bool mapped; | ||
3190 | do { | ||
3191 | mapped = alc_map_singles(codec, cfg->line_outs, | ||
3192 | cfg->line_out_pins, | ||
3193 | spec->private_dac_nids); | ||
3194 | mapped |= alc_map_singles(codec, cfg->hp_outs, | ||
3195 | cfg->hp_pins, | ||
3196 | spec->multiout.hp_out_nid); | ||
3197 | mapped |= alc_map_singles(codec, cfg->speaker_outs, | ||
3198 | cfg->speaker_pins, | ||
3199 | spec->multiout.extra_out_nid); | ||
3200 | if (fill_mio_first && cfg->line_outs == 1 && | ||
3201 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3202 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0); | ||
3203 | if (!err) | ||
3204 | mapped = true; | ||
3205 | } | ||
3206 | } while (mapped); | ||
3207 | } | ||
3208 | |||
3209 | badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins, | ||
3210 | spec->private_dac_nids, | ||
3211 | &main_out_badness); | ||
3212 | |||
3213 | /* re-count num_dacs and squash invalid entries */ | ||
3214 | spec->multiout.num_dacs = 0; | ||
3215 | for (i = 0; i < cfg->line_outs; i++) { | ||
3216 | if (spec->private_dac_nids[i]) | ||
3217 | spec->multiout.num_dacs++; | ||
3218 | else { | ||
3219 | memmove(spec->private_dac_nids + i, | ||
3220 | spec->private_dac_nids + i + 1, | ||
3221 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | ||
3222 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
3223 | } | ||
3224 | } | ||
3225 | |||
3226 | if (fill_mio_first && | ||
3227 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3228 | /* try to fill multi-io first */ | ||
3229 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); | ||
3230 | if (err < 0) | ||
3231 | return err; | ||
3232 | /* we don't count badness at this stage yet */ | ||
3233 | } | ||
3234 | |||
3235 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { | ||
3236 | err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins, | ||
3237 | spec->multiout.hp_out_nid, | ||
3238 | &extra_out_badness); | ||
3239 | if (err < 0) | ||
3240 | return err; | ||
3241 | badness += err; | ||
3242 | } | ||
3243 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3244 | err = alc_auto_fill_dacs(codec, cfg->speaker_outs, | ||
3245 | cfg->speaker_pins, | ||
3246 | spec->multiout.extra_out_nid, | ||
3247 | &extra_out_badness); | ||
3248 | if (err < 0) | ||
3249 | return err; | ||
3250 | badness += err; | ||
3251 | } | ||
3252 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3253 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); | ||
3254 | if (err < 0) | ||
3255 | return err; | ||
3256 | badness += err; | ||
3257 | } | ||
3258 | if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
3259 | /* try multi-ios with HP + inputs */ | ||
3260 | int offset = 0; | ||
3261 | if (cfg->line_outs >= 3) | ||
3262 | offset = 1; | ||
3263 | err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false, | ||
3264 | offset); | ||
3265 | if (err < 0) | ||
3266 | return err; | ||
3267 | badness += err; | ||
3268 | } | ||
3269 | |||
3270 | if (spec->multi_ios == 2) { | ||
3271 | for (i = 0; i < 2; i++) | ||
3272 | spec->private_dac_nids[spec->multiout.num_dacs++] = | ||
3273 | spec->multi_io[i].dac; | ||
3274 | spec->ext_channel_count = 2; | ||
3275 | } else if (spec->multi_ios) { | ||
3276 | spec->multi_ios = 0; | ||
3277 | badness += BAD_MULTI_IO; | ||
3278 | } | ||
3279 | |||
3280 | return badness; | ||
3281 | } | ||
3282 | |||
3283 | #define DEBUG_BADNESS | ||
3284 | |||
3285 | #ifdef DEBUG_BADNESS | ||
3286 | #define debug_badness snd_printdd | ||
3287 | #else | ||
3288 | #define debug_badness(...) | ||
3289 | #endif | ||
3290 | |||
3291 | static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg) | ||
3292 | { | ||
3293 | debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3294 | cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
3295 | cfg->line_out_pins[2], cfg->line_out_pins[2], | ||
3296 | spec->multiout.dac_nids[0], | ||
3297 | spec->multiout.dac_nids[1], | ||
3298 | spec->multiout.dac_nids[2], | ||
3299 | spec->multiout.dac_nids[3]); | ||
3300 | if (spec->multi_ios > 0) | ||
3301 | debug_badness("multi_ios(%d) = %x/%x : %x/%x\n", | ||
3302 | spec->multi_ios, | ||
3303 | spec->multi_io[0].pin, spec->multi_io[1].pin, | ||
3304 | spec->multi_io[0].dac, spec->multi_io[1].dac); | ||
3305 | debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3306 | cfg->hp_pins[0], cfg->hp_pins[1], | ||
3307 | cfg->hp_pins[2], cfg->hp_pins[2], | ||
3308 | spec->multiout.hp_out_nid[0], | ||
3309 | spec->multiout.hp_out_nid[1], | ||
3310 | spec->multiout.hp_out_nid[2], | ||
3311 | spec->multiout.hp_out_nid[3]); | ||
3312 | debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3313 | cfg->speaker_pins[0], cfg->speaker_pins[1], | ||
3314 | cfg->speaker_pins[2], cfg->speaker_pins[3], | ||
3315 | spec->multiout.extra_out_nid[0], | ||
3316 | spec->multiout.extra_out_nid[1], | ||
3317 | spec->multiout.extra_out_nid[2], | ||
3318 | spec->multiout.extra_out_nid[3]); | ||
3319 | } | ||
3320 | |||
3321 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | ||
3322 | { | ||
3323 | struct alc_spec *spec = codec->spec; | ||
3324 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3325 | struct auto_pin_cfg *best_cfg; | ||
3326 | int best_badness = INT_MAX; | ||
3327 | int badness; | ||
3328 | bool fill_hardwired = true, fill_mio_first = true; | ||
3329 | bool best_wired = true, best_mio = true; | ||
3330 | bool hp_spk_swapped = false; | ||
3331 | |||
3332 | best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL); | ||
3333 | if (!best_cfg) | ||
3334 | return -ENOMEM; | ||
3335 | *best_cfg = *cfg; | ||
3336 | |||
3337 | for (;;) { | ||
3338 | badness = fill_and_eval_dacs(codec, fill_hardwired, | ||
3339 | fill_mio_first); | ||
3340 | if (badness < 0) { | ||
3341 | kfree(best_cfg); | ||
3342 | return badness; | ||
3343 | } | ||
3344 | debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", | ||
3345 | cfg->line_out_type, fill_hardwired, fill_mio_first, | ||
3346 | badness); | ||
3347 | debug_show_configs(spec, cfg); | ||
3348 | if (badness < best_badness) { | ||
3349 | best_badness = badness; | ||
3350 | *best_cfg = *cfg; | ||
3351 | best_wired = fill_hardwired; | ||
3352 | best_mio = fill_mio_first; | ||
3353 | } | ||
3354 | if (!badness) | ||
3355 | break; | ||
3356 | fill_mio_first = !fill_mio_first; | ||
3357 | if (!fill_mio_first) | ||
3358 | continue; | ||
3359 | fill_hardwired = !fill_hardwired; | ||
3360 | if (!fill_hardwired) | ||
3361 | continue; | ||
3362 | if (hp_spk_swapped) | ||
3363 | break; | ||
3364 | hp_spk_swapped = true; | ||
3365 | if (cfg->speaker_outs > 0 && | ||
3366 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3367 | cfg->hp_outs = cfg->line_outs; | ||
3368 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3369 | sizeof(cfg->hp_pins)); | ||
3370 | cfg->line_outs = cfg->speaker_outs; | ||
3371 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
3372 | sizeof(cfg->speaker_pins)); | ||
3373 | cfg->speaker_outs = 0; | ||
3374 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
3375 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
3376 | fill_hardwired = true; | ||
3377 | continue; | ||
3378 | } | ||
3379 | if (cfg->hp_outs > 0 && | ||
3380 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
3381 | cfg->speaker_outs = cfg->line_outs; | ||
3382 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
3383 | sizeof(cfg->speaker_pins)); | ||
3384 | cfg->line_outs = cfg->hp_outs; | ||
3385 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
3386 | sizeof(cfg->hp_pins)); | ||
3387 | cfg->hp_outs = 0; | ||
3388 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
3389 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
3390 | fill_hardwired = true; | ||
3391 | continue; | ||
3392 | } | ||
3393 | break; | ||
3394 | } | ||
3395 | |||
3396 | if (badness) { | ||
3397 | *cfg = *best_cfg; | ||
3398 | fill_and_eval_dacs(codec, best_wired, best_mio); | ||
3399 | } | ||
3400 | debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n", | ||
3401 | cfg->line_out_type, best_wired, best_mio); | ||
3402 | debug_show_configs(spec, cfg); | ||
3403 | |||
3404 | if (cfg->line_out_pins[0]) | ||
3405 | spec->vmaster_nid = | ||
3406 | alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], | ||
3407 | spec->multiout.dac_nids[0]); | ||
3408 | |||
3409 | /* clear the bitmap flags for creating controls */ | ||
3410 | clear_vol_marks(codec); | ||
3411 | kfree(best_cfg); | ||
3412 | return 0; | ||
3413 | } | ||
3414 | |||
3415 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, | ||
3416 | const char *pfx, int cidx, | ||
3417 | hda_nid_t nid, unsigned int chs) | ||
3418 | { | ||
3419 | struct alc_spec *spec = codec->spec; | ||
3420 | unsigned int val; | ||
3421 | if (!nid) | ||
3422 | return 0; | ||
3423 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); | ||
3424 | if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */ | ||
3425 | return 0; | ||
3426 | mark_ctl_usage(spec->vol_ctls, val); | ||
3427 | return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, | ||
3428 | val); | ||
3429 | } | ||
3430 | |||
3431 | static int alc_auto_add_stereo_vol(struct hda_codec *codec, | ||
3432 | const char *pfx, int cidx, | ||
3433 | hda_nid_t nid) | ||
3434 | { | ||
3435 | int chs = 1; | ||
3436 | if (get_wcaps(codec, nid) & AC_WCAP_STEREO) | ||
3437 | chs = 3; | ||
3438 | return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs); | ||
3439 | } | ||
3440 | |||
3441 | /* create a mute-switch for the given mixer widget; | ||
3442 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute | ||
3443 | */ | ||
3444 | static int alc_auto_add_sw_ctl(struct hda_codec *codec, | ||
3445 | const char *pfx, int cidx, | ||
3446 | hda_nid_t nid, unsigned int chs) | ||
3447 | { | ||
3448 | struct alc_spec *spec = codec->spec; | ||
3449 | int wid_type; | ||
3450 | int type; | ||
3451 | unsigned long val; | ||
3452 | if (!nid) | ||
3453 | return 0; | ||
3454 | wid_type = get_wcaps_type(get_wcaps(codec, nid)); | ||
3455 | if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) { | ||
3456 | type = ALC_CTL_WIDGET_MUTE; | ||
3457 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); | ||
3458 | } else if (snd_hda_get_num_conns(codec, nid) == 1) { | ||
3459 | type = ALC_CTL_WIDGET_MUTE; | ||
3460 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT); | ||
3461 | } else { | ||
3462 | type = ALC_CTL_BIND_MUTE; | ||
3463 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); | ||
3464 | } | ||
3465 | if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */ | ||
3466 | return 0; | ||
3467 | mark_ctl_usage(spec->sw_ctls, val); | ||
3468 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); | ||
3469 | } | ||
3470 | |||
3471 | static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx, | ||
3472 | int cidx, hda_nid_t nid) | ||
3473 | { | ||
3474 | int chs = 1; | ||
3475 | if (get_wcaps(codec, nid) & AC_WCAP_STEREO) | ||
3476 | chs = 3; | ||
3477 | return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs); | ||
3478 | } | ||
3479 | |||
3480 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, | ||
3481 | hda_nid_t pin, hda_nid_t dac) | ||
3482 | { | ||
3483 | hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); | ||
3484 | if (nid_has_mute(codec, pin, HDA_OUTPUT)) | ||
3485 | return pin; | ||
3486 | else if (mix && nid_has_mute(codec, mix, HDA_INPUT)) | ||
3487 | return mix; | ||
3488 | else if (nid_has_mute(codec, dac, HDA_OUTPUT)) | ||
3489 | return dac; | ||
3490 | return 0; | ||
3491 | } | ||
3492 | |||
3493 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | ||
3494 | hda_nid_t pin, hda_nid_t dac) | ||
3495 | { | ||
3496 | hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); | ||
3497 | if (nid_has_volume(codec, dac, HDA_OUTPUT)) | ||
3498 | return dac; | ||
3499 | else if (nid_has_volume(codec, mix, HDA_OUTPUT)) | ||
3500 | return mix; | ||
3501 | else if (nid_has_volume(codec, pin, HDA_OUTPUT)) | ||
3502 | return pin; | ||
3503 | return 0; | ||
3504 | } | ||
3505 | |||
3506 | /* add playback controls from the parsed DAC table */ | ||
3507 | static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
3508 | const struct auto_pin_cfg *cfg) | ||
3509 | { | ||
3510 | struct alc_spec *spec = codec->spec; | ||
3511 | int i, err, noutputs; | ||
3512 | |||
3513 | noutputs = cfg->line_outs; | ||
3514 | if (spec->multi_ios > 0 && cfg->line_outs < 3) | ||
3515 | noutputs += spec->multi_ios; | ||
3516 | |||
3517 | for (i = 0; i < noutputs; i++) { | ||
3518 | const char *name; | ||
3519 | int index; | ||
3520 | hda_nid_t dac, pin; | ||
3521 | hda_nid_t sw, vol; | ||
3522 | |||
3523 | dac = spec->multiout.dac_nids[i]; | ||
3524 | if (!dac) | ||
3525 | continue; | ||
3526 | if (i >= cfg->line_outs) { | ||
3527 | pin = spec->multi_io[i - 1].pin; | ||
3528 | index = 0; | ||
3529 | name = channel_name[i]; | ||
3530 | } else { | ||
3531 | pin = cfg->line_out_pins[i]; | ||
3532 | name = alc_get_line_out_pfx(spec, i, true, &index); | ||
3533 | } | ||
3534 | |||
3535 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | ||
3536 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | ||
3537 | if (!name || !strcmp(name, "CLFE")) { | ||
3538 | /* Center/LFE */ | ||
3539 | err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); | ||
3540 | if (err < 0) | ||
3541 | return err; | ||
3542 | err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2); | ||
3543 | if (err < 0) | ||
3544 | return err; | ||
3545 | err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1); | ||
3546 | if (err < 0) | ||
3547 | return err; | ||
3548 | err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2); | ||
3549 | if (err < 0) | ||
3550 | return err; | ||
3551 | } else { | ||
3552 | err = alc_auto_add_stereo_vol(codec, name, index, vol); | ||
3553 | if (err < 0) | ||
3554 | return err; | ||
3555 | err = alc_auto_add_stereo_sw(codec, name, index, sw); | ||
3556 | if (err < 0) | ||
3557 | return err; | ||
3558 | } | ||
3559 | } | ||
3560 | return 0; | ||
3561 | } | ||
3562 | |||
3563 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | ||
3564 | hda_nid_t dac, const char *pfx, | ||
3565 | int cidx) | ||
3566 | { | ||
3567 | struct alc_spec *spec = codec->spec; | ||
3568 | hda_nid_t sw, vol; | ||
3569 | int err; | ||
3570 | |||
3571 | if (!dac) { | ||
3572 | unsigned int val; | ||
3573 | /* the corresponding DAC is already occupied */ | ||
3574 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) | ||
3575 | return 0; /* no way */ | ||
3576 | /* create a switch only */ | ||
3577 | val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT); | ||
3578 | if (is_ctl_used(spec->sw_ctls, val)) | ||
3579 | return 0; /* already created */ | ||
3580 | mark_ctl_usage(spec->sw_ctls, val); | ||
3581 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); | ||
3582 | } | ||
3583 | |||
3584 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | ||
3585 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | ||
3586 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); | ||
3587 | if (err < 0) | ||
3588 | return err; | ||
3589 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); | ||
3590 | if (err < 0) | ||
3591 | return err; | ||
3592 | return 0; | ||
3593 | } | ||
3594 | |||
3595 | static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec, | ||
3596 | unsigned int nums, | ||
3597 | struct hda_ctl_ops *ops) | ||
3598 | { | ||
3599 | struct alc_spec *spec = codec->spec; | ||
3600 | struct hda_bind_ctls **ctlp, *ctl; | ||
3601 | ctlp = snd_array_new(&spec->bind_ctls); | ||
3602 | if (!ctlp) | ||
3603 | return NULL; | ||
3604 | ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL); | ||
3605 | *ctlp = ctl; | ||
3606 | if (ctl) | ||
3607 | ctl->ops = ops; | ||
3608 | return ctl; | ||
3609 | } | ||
3610 | |||
3611 | /* add playback controls for speaker and HP outputs */ | ||
3612 | static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | ||
3613 | const hda_nid_t *pins, | ||
3614 | const hda_nid_t *dacs, | ||
3615 | const char *pfx) | ||
3616 | { | ||
3617 | struct alc_spec *spec = codec->spec; | ||
3618 | struct hda_bind_ctls *ctl; | ||
3619 | char name[32]; | ||
3620 | int i, n, err; | ||
3621 | |||
3622 | if (!num_pins || !pins[0]) | ||
3623 | return 0; | ||
3624 | |||
3625 | if (num_pins == 1) { | ||
3626 | hda_nid_t dac = *dacs; | ||
3627 | if (!dac) | ||
3628 | dac = spec->multiout.dac_nids[0]; | ||
3629 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); | ||
3630 | } | ||
3631 | |||
3632 | for (i = 0; i < num_pins; i++) { | ||
3633 | hda_nid_t dac; | ||
3634 | if (dacs[num_pins - 1]) | ||
3635 | dac = dacs[i]; /* with individual volumes */ | ||
3636 | else | ||
3637 | dac = 0; | ||
3638 | if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) { | ||
3639 | err = alc_auto_create_extra_out(codec, pins[i], dac, | ||
3640 | "Bass Speaker", 0); | ||
3641 | } else if (num_pins >= 3) { | ||
3642 | snprintf(name, sizeof(name), "%s %s", | ||
3643 | pfx, channel_name[i]); | ||
3644 | err = alc_auto_create_extra_out(codec, pins[i], dac, | ||
3645 | name, 0); | ||
3646 | } else { | ||
3647 | err = alc_auto_create_extra_out(codec, pins[i], dac, | ||
3648 | pfx, i); | ||
3649 | } | ||
3650 | if (err < 0) | ||
3651 | return err; | ||
3652 | } | ||
3653 | if (dacs[num_pins - 1]) | ||
3654 | return 0; | ||
3655 | |||
3656 | /* Let's create a bind-controls for volumes */ | ||
3657 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); | ||
3658 | if (!ctl) | ||
3659 | return -ENOMEM; | ||
3660 | n = 0; | ||
3661 | for (i = 0; i < num_pins; i++) { | ||
3662 | hda_nid_t vol; | ||
3663 | if (!pins[i] || !dacs[i]) | ||
3664 | continue; | ||
3665 | vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]); | ||
3666 | if (vol) | ||
3667 | ctl->values[n++] = | ||
3668 | HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT); | ||
3669 | } | ||
3670 | if (n) { | ||
3671 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | ||
3672 | err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl); | ||
3673 | if (err < 0) | ||
3674 | return err; | ||
3675 | } | ||
3676 | return 0; | ||
3677 | } | ||
3678 | |||
3679 | static int alc_auto_create_hp_out(struct hda_codec *codec) | ||
3680 | { | ||
3681 | struct alc_spec *spec = codec->spec; | ||
3682 | return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs, | ||
3683 | spec->autocfg.hp_pins, | ||
3684 | spec->multiout.hp_out_nid, | ||
3685 | "Headphone"); | ||
3686 | } | ||
3687 | |||
3688 | static int alc_auto_create_speaker_out(struct hda_codec *codec) | ||
3689 | { | ||
3690 | struct alc_spec *spec = codec->spec; | ||
3691 | return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs, | ||
3692 | spec->autocfg.speaker_pins, | ||
3693 | spec->multiout.extra_out_nid, | ||
3694 | "Speaker"); | ||
3695 | } | ||
3696 | |||
3697 | static void alc_auto_set_output_and_unmute(struct hda_codec *codec, | ||
3698 | hda_nid_t pin, int pin_type, | ||
3699 | hda_nid_t dac) | ||
3700 | { | ||
3701 | int i, num; | ||
3702 | hda_nid_t nid, mix = 0; | ||
3703 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; | ||
3704 | |||
3705 | alc_set_pin_output(codec, pin, pin_type); | ||
3706 | nid = alc_go_down_to_selector(codec, pin); | ||
3707 | num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); | ||
3708 | for (i = 0; i < num; i++) { | ||
3709 | if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) | ||
3710 | continue; | ||
3711 | mix = srcs[i]; | ||
3712 | break; | ||
3713 | } | ||
3714 | if (!mix) | ||
3715 | return; | ||
3716 | |||
3717 | /* need the manual connection? */ | ||
3718 | if (num > 1) | ||
3719 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); | ||
3720 | /* unmute mixer widget inputs */ | ||
3721 | if (nid_has_mute(codec, mix, HDA_INPUT)) { | ||
3722 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3723 | AMP_IN_UNMUTE(0)); | ||
3724 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3725 | AMP_IN_UNMUTE(1)); | ||
3726 | } | ||
3727 | /* initialize volume */ | ||
3728 | nid = alc_look_for_out_vol_nid(codec, pin, dac); | ||
3729 | if (nid) | ||
3730 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3731 | AMP_OUT_ZERO); | ||
3732 | |||
3733 | /* unmute DAC if it's not assigned to a mixer */ | ||
3734 | nid = alc_look_for_out_mute_nid(codec, pin, dac); | ||
3735 | if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT)) | ||
3736 | snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3737 | AMP_OUT_ZERO); | ||
3738 | } | ||
3739 | |||
3740 | static void alc_auto_init_multi_out(struct hda_codec *codec) | ||
3741 | { | ||
3742 | struct alc_spec *spec = codec->spec; | ||
3743 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
3744 | int i; | ||
3745 | |||
3746 | for (i = 0; i <= HDA_SIDE; i++) { | ||
3747 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
3748 | if (nid) | ||
3749 | alc_auto_set_output_and_unmute(codec, nid, pin_type, | ||
3750 | spec->multiout.dac_nids[i]); | ||
3751 | } | ||
3752 | } | ||
3753 | |||
3754 | static void alc_auto_init_extra_out(struct hda_codec *codec) | ||
3755 | { | ||
3756 | struct alc_spec *spec = codec->spec; | ||
3757 | int i; | ||
3758 | hda_nid_t pin, dac; | ||
3759 | |||
3760 | for (i = 0; i < spec->autocfg.hp_outs; i++) { | ||
3761 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
3762 | break; | ||
3763 | pin = spec->autocfg.hp_pins[i]; | ||
3764 | if (!pin) | ||
3765 | break; | ||
3766 | dac = spec->multiout.hp_out_nid[i]; | ||
3767 | if (!dac) { | ||
3768 | if (i > 0 && spec->multiout.hp_out_nid[0]) | ||
3769 | dac = spec->multiout.hp_out_nid[0]; | ||
3770 | else | ||
3771 | dac = spec->multiout.dac_nids[0]; | ||
3772 | } | ||
3773 | alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | ||
3774 | } | ||
3775 | for (i = 0; i < spec->autocfg.speaker_outs; i++) { | ||
3776 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
3777 | break; | ||
3778 | pin = spec->autocfg.speaker_pins[i]; | ||
3779 | if (!pin) | ||
3780 | break; | ||
3781 | dac = spec->multiout.extra_out_nid[i]; | ||
3782 | if (!dac) { | ||
3783 | if (i > 0 && spec->multiout.extra_out_nid[0]) | ||
3784 | dac = spec->multiout.extra_out_nid[0]; | ||
3785 | else | ||
3786 | dac = spec->multiout.dac_nids[0]; | ||
3787 | } | ||
3788 | alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); | ||
3789 | } | ||
3790 | } | ||
3791 | |||
3792 | /* check whether the given pin can be a multi-io pin */ | ||
3793 | static bool can_be_multiio_pin(struct hda_codec *codec, | ||
3794 | unsigned int location, hda_nid_t nid) | ||
3795 | { | ||
3796 | unsigned int defcfg, caps; | ||
3797 | |||
3798 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3799 | if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) | ||
3800 | return false; | ||
3801 | if (location && get_defcfg_location(defcfg) != location) | ||
3802 | return false; | ||
3803 | caps = snd_hda_query_pin_caps(codec, nid); | ||
3804 | if (!(caps & AC_PINCAP_OUT)) | ||
3805 | return false; | ||
3806 | return true; | ||
3807 | } | ||
3808 | |||
3809 | /* | ||
3810 | * multi-io helper | ||
3811 | * | ||
3812 | * When hardwired is set, try to fill ony hardwired pins, and returns | ||
3813 | * zero if any pins are filled, non-zero if nothing found. | ||
3814 | * When hardwired is off, try to fill possible input pins, and returns | ||
3815 | * the badness value. | ||
3816 | */ | ||
3817 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | ||
3818 | hda_nid_t reference_pin, | ||
3819 | bool hardwired, int offset) | ||
3820 | { | ||
3821 | struct alc_spec *spec = codec->spec; | ||
3822 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3823 | int type, i, j, dacs, num_pins, old_pins; | ||
3824 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); | ||
3825 | unsigned int location = get_defcfg_location(defcfg); | ||
3826 | int badness = 0; | ||
3827 | |||
3828 | old_pins = spec->multi_ios; | ||
3829 | if (old_pins >= 2) | ||
3830 | goto end_fill; | ||
3831 | |||
3832 | num_pins = 0; | ||
3833 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
3834 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3835 | if (cfg->inputs[i].type != type) | ||
3836 | continue; | ||
3837 | if (can_be_multiio_pin(codec, location, | ||
3838 | cfg->inputs[i].pin)) | ||
3839 | num_pins++; | ||
3840 | } | ||
3841 | } | ||
3842 | if (num_pins < 2) | ||
3843 | goto end_fill; | ||
3844 | |||
3845 | dacs = spec->multiout.num_dacs; | ||
3846 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
3847 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3848 | hda_nid_t nid = cfg->inputs[i].pin; | ||
3849 | hda_nid_t dac = 0; | ||
3850 | |||
3851 | if (cfg->inputs[i].type != type) | ||
3852 | continue; | ||
3853 | if (!can_be_multiio_pin(codec, location, nid)) | ||
3854 | continue; | ||
3855 | for (j = 0; j < spec->multi_ios; j++) { | ||
3856 | if (nid == spec->multi_io[j].pin) | ||
3857 | break; | ||
3858 | } | ||
3859 | if (j < spec->multi_ios) | ||
3860 | continue; | ||
3861 | |||
3862 | if (offset && offset + spec->multi_ios < dacs) { | ||
3863 | dac = spec->private_dac_nids[offset + spec->multi_ios]; | ||
3864 | if (!alc_auto_is_dac_reachable(codec, nid, dac)) | ||
3865 | dac = 0; | ||
3866 | } | ||
3867 | if (hardwired) | ||
3868 | dac = get_dac_if_single(codec, nid); | ||
3869 | else if (!dac) | ||
3870 | dac = alc_auto_look_for_dac(codec, nid); | ||
3871 | if (!dac) { | ||
3872 | badness++; | ||
3873 | continue; | ||
3874 | } | ||
3875 | spec->multi_io[spec->multi_ios].pin = nid; | ||
3876 | spec->multi_io[spec->multi_ios].dac = dac; | ||
3877 | spec->multi_ios++; | ||
3878 | if (spec->multi_ios >= 2) | ||
3879 | break; | ||
3880 | } | ||
3881 | } | ||
3882 | end_fill: | ||
3883 | if (badness) | ||
3884 | badness = BAD_MULTI_IO; | ||
3885 | if (old_pins == spec->multi_ios) { | ||
3886 | if (hardwired) | ||
3887 | return 1; /* nothing found */ | ||
3888 | else | ||
3889 | return badness; /* no badness if nothing found */ | ||
3890 | } | ||
3891 | if (!hardwired && spec->multi_ios < 2) { | ||
3892 | spec->multi_ios = old_pins; | ||
3893 | return badness; | ||
3894 | } | ||
3895 | |||
3896 | return 0; | ||
3897 | } | ||
3898 | |||
3899 | static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
3900 | struct snd_ctl_elem_info *uinfo) | ||
3901 | { | ||
3902 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3903 | struct alc_spec *spec = codec->spec; | ||
3904 | |||
3905 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3906 | uinfo->count = 1; | ||
3907 | uinfo->value.enumerated.items = spec->multi_ios + 1; | ||
3908 | if (uinfo->value.enumerated.item > spec->multi_ios) | ||
3909 | uinfo->value.enumerated.item = spec->multi_ios; | ||
3910 | sprintf(uinfo->value.enumerated.name, "%dch", | ||
3911 | (uinfo->value.enumerated.item + 1) * 2); | ||
3912 | return 0; | ||
3913 | } | ||
3914 | |||
3915 | static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
3916 | struct snd_ctl_elem_value *ucontrol) | ||
3917 | { | ||
3918 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3919 | struct alc_spec *spec = codec->spec; | ||
3920 | ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; | ||
3921 | return 0; | ||
3922 | } | ||
3923 | |||
3924 | static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) | ||
3925 | { | ||
3926 | struct alc_spec *spec = codec->spec; | ||
3927 | hda_nid_t nid = spec->multi_io[idx].pin; | ||
3928 | |||
3929 | if (!spec->multi_io[idx].ctl_in) | ||
3930 | spec->multi_io[idx].ctl_in = | ||
3931 | snd_hda_codec_read(codec, nid, 0, | ||
3932 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
3933 | if (output) { | ||
3934 | snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT); | ||
3935 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | ||
3936 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
3937 | HDA_AMP_MUTE, 0); | ||
3938 | alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); | ||
3939 | } else { | ||
3940 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | ||
3941 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
3942 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
3943 | snd_hda_set_pin_ctl_cache(codec, nid, | ||
3944 | spec->multi_io[idx].ctl_in); | ||
3945 | } | ||
3946 | return 0; | ||
3947 | } | ||
3948 | |||
3949 | static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
3950 | struct snd_ctl_elem_value *ucontrol) | ||
3951 | { | ||
3952 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3953 | struct alc_spec *spec = codec->spec; | ||
3954 | int i, ch; | ||
3955 | |||
3956 | ch = ucontrol->value.enumerated.item[0]; | ||
3957 | if (ch < 0 || ch > spec->multi_ios) | ||
3958 | return -EINVAL; | ||
3959 | if (ch == (spec->ext_channel_count - 1) / 2) | ||
3960 | return 0; | ||
3961 | spec->ext_channel_count = (ch + 1) * 2; | ||
3962 | for (i = 0; i < spec->multi_ios; i++) | ||
3963 | alc_set_multi_io(codec, i, i < ch); | ||
3964 | spec->multiout.max_channels = max(spec->ext_channel_count, | ||
3965 | spec->const_channel_count); | ||
3966 | if (spec->need_dac_fix) | ||
3967 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
3968 | return 1; | ||
3969 | } | ||
3970 | |||
3971 | static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { | ||
3972 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3973 | .name = "Channel Mode", | ||
3974 | .info = alc_auto_ch_mode_info, | ||
3975 | .get = alc_auto_ch_mode_get, | ||
3976 | .put = alc_auto_ch_mode_put, | ||
3977 | }; | ||
3978 | |||
3979 | static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) | ||
3980 | { | ||
3981 | struct alc_spec *spec = codec->spec; | ||
3982 | |||
3983 | if (spec->multi_ios > 0) { | ||
3984 | if (!alc_kcontrol_new(spec, "Channel Mode", | ||
3985 | &alc_auto_channel_mode_enum)) | ||
3986 | return -ENOMEM; | ||
3987 | } | ||
3988 | return 0; | ||
3989 | } | ||
3990 | |||
3991 | /* filter out invalid adc_nids (and capsrc_nids) that don't give all | ||
3992 | * active input pins | ||
3993 | */ | ||
3994 | static void alc_remove_invalid_adc_nids(struct hda_codec *codec) | ||
3995 | { | ||
3996 | struct alc_spec *spec = codec->spec; | ||
3997 | const struct hda_input_mux *imux; | ||
3998 | hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | ||
3999 | hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | ||
4000 | int i, n, nums; | ||
4001 | |||
4002 | imux = spec->input_mux; | ||
4003 | if (!imux) | ||
4004 | return; | ||
4005 | if (spec->dyn_adc_switch) | ||
4006 | return; | ||
4007 | |||
4008 | again: | ||
4009 | nums = 0; | ||
4010 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
4011 | hda_nid_t cap = spec->private_capsrc_nids[n]; | ||
4012 | int num_conns = snd_hda_get_num_conns(codec, cap); | ||
4013 | for (i = 0; i < imux->num_items; i++) { | ||
4014 | hda_nid_t pin = spec->imux_pins[i]; | ||
4015 | if (pin) { | ||
4016 | if (get_connection_index(codec, cap, pin) < 0) | ||
4017 | break; | ||
4018 | } else if (num_conns <= imux->items[i].index) | ||
4019 | break; | ||
4020 | } | ||
4021 | if (i >= imux->num_items) { | ||
4022 | adc_nids[nums] = spec->private_adc_nids[n]; | ||
4023 | capsrc_nids[nums++] = cap; | ||
4024 | } | ||
4025 | } | ||
4026 | if (!nums) { | ||
4027 | /* check whether ADC-switch is possible */ | ||
4028 | if (!alc_check_dyn_adc_switch(codec)) { | ||
4029 | if (spec->shared_mic_hp) { | ||
4030 | spec->shared_mic_hp = 0; | ||
4031 | spec->private_imux[0].num_items = 1; | ||
4032 | goto again; | ||
4033 | } | ||
4034 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | ||
4035 | " using fallback 0x%x\n", | ||
4036 | codec->chip_name, spec->private_adc_nids[0]); | ||
4037 | spec->num_adc_nids = 1; | ||
4038 | spec->auto_mic = 0; | ||
4039 | return; | ||
4040 | } | ||
4041 | } else if (nums != spec->num_adc_nids) { | ||
4042 | memcpy(spec->private_adc_nids, adc_nids, | ||
4043 | nums * sizeof(hda_nid_t)); | ||
4044 | memcpy(spec->private_capsrc_nids, capsrc_nids, | ||
4045 | nums * sizeof(hda_nid_t)); | ||
4046 | spec->num_adc_nids = nums; | ||
4047 | } | ||
4048 | |||
4049 | if (spec->auto_mic) | ||
4050 | alc_auto_mic_check_imux(codec); /* check auto-mic setups */ | ||
4051 | else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp) | ||
4052 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | ||
4053 | } | ||
4054 | |||
4055 | /* | ||
4056 | * initialize ADC paths | ||
4057 | */ | ||
4058 | static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) | ||
4059 | { | ||
4060 | struct alc_spec *spec = codec->spec; | ||
4061 | hda_nid_t nid; | ||
4062 | |||
4063 | nid = spec->adc_nids[adc_idx]; | ||
4064 | /* mute ADC */ | ||
4065 | if (nid_has_mute(codec, nid, HDA_INPUT)) { | ||
4066 | snd_hda_codec_write(codec, nid, 0, | ||
4067 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4068 | AMP_IN_MUTE(0)); | ||
4069 | return; | ||
4070 | } | ||
4071 | if (!spec->capsrc_nids) | ||
4072 | return; | ||
4073 | nid = spec->capsrc_nids[adc_idx]; | ||
4074 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
4075 | snd_hda_codec_write(codec, nid, 0, | ||
4076 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4077 | AMP_OUT_MUTE); | ||
4078 | } | ||
4079 | |||
4080 | static void alc_auto_init_input_src(struct hda_codec *codec) | ||
4081 | { | ||
4082 | struct alc_spec *spec = codec->spec; | ||
4083 | int c, nums; | ||
4084 | |||
4085 | for (c = 0; c < spec->num_adc_nids; c++) | ||
4086 | alc_auto_init_adc(codec, c); | ||
4087 | if (spec->dyn_adc_switch) | ||
4088 | nums = 1; | ||
4089 | else | ||
4090 | nums = spec->num_adc_nids; | ||
4091 | for (c = 0; c < nums; c++) | ||
4092 | alc_mux_select(codec, c, spec->cur_mux[c], true); | ||
4093 | } | ||
4094 | |||
4095 | /* add mic boosts if needed */ | ||
4096 | static int alc_auto_add_mic_boost(struct hda_codec *codec) | ||
4097 | { | ||
4098 | struct alc_spec *spec = codec->spec; | ||
4099 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4100 | int i, err; | ||
4101 | int type_idx = 0; | ||
4102 | hda_nid_t nid; | ||
4103 | const char *prev_label = NULL; | ||
4104 | |||
4105 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4106 | if (cfg->inputs[i].type > AUTO_PIN_MIC) | ||
4107 | break; | ||
4108 | nid = cfg->inputs[i].pin; | ||
4109 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | ||
4110 | const char *label; | ||
4111 | char boost_label[32]; | ||
4112 | |||
4113 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
4114 | if (spec->shared_mic_hp && !strcmp(label, "Misc")) | ||
4115 | label = "Headphone Mic"; | ||
4116 | if (prev_label && !strcmp(label, prev_label)) | ||
4117 | type_idx++; | ||
4118 | else | ||
4119 | type_idx = 0; | ||
4120 | prev_label = label; | ||
4121 | |||
4122 | snprintf(boost_label, sizeof(boost_label), | ||
4123 | "%s Boost Volume", label); | ||
4124 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
4125 | boost_label, type_idx, | ||
4126 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
4127 | if (err < 0) | ||
4128 | return err; | ||
4129 | } | ||
4130 | } | ||
4131 | return 0; | ||
4132 | } | ||
4133 | |||
4134 | /* select or unmute the given capsrc route */ | ||
4135 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | ||
4136 | int idx) | ||
4137 | { | ||
4138 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
4139 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
4140 | HDA_AMP_MUTE, 0); | ||
4141 | } else if (snd_hda_get_num_conns(codec, cap) > 1) { | ||
4142 | snd_hda_codec_write_cache(codec, cap, 0, | ||
4143 | AC_VERB_SET_CONNECT_SEL, idx); | ||
4144 | } | ||
4145 | } | ||
4146 | |||
4147 | /* set the default connection to that pin */ | ||
4148 | static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | ||
4149 | { | ||
4150 | struct alc_spec *spec = codec->spec; | ||
4151 | int i; | ||
4152 | |||
4153 | if (!pin) | ||
4154 | return 0; | ||
4155 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4156 | hda_nid_t cap = get_capsrc(spec, i); | ||
4157 | int idx; | ||
4158 | |||
4159 | idx = get_connection_index(codec, cap, pin); | ||
4160 | if (idx < 0) | ||
4161 | continue; | ||
4162 | select_or_unmute_capsrc(codec, cap, idx); | ||
4163 | return i; /* return the found index */ | ||
4164 | } | ||
4165 | return -1; /* not found */ | ||
4166 | } | ||
4167 | |||
4168 | /* initialize some special cases for input sources */ | ||
4169 | static void alc_init_special_input_src(struct hda_codec *codec) | ||
4170 | { | ||
4171 | struct alc_spec *spec = codec->spec; | ||
4172 | int i; | ||
4173 | |||
4174 | for (i = 0; i < spec->autocfg.num_inputs; i++) | ||
4175 | init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); | ||
4176 | } | ||
4177 | |||
4178 | /* assign appropriate capture mixers */ | ||
4179 | static void set_capture_mixer(struct hda_codec *codec) | ||
4180 | { | ||
4181 | struct alc_spec *spec = codec->spec; | ||
4182 | static const struct snd_kcontrol_new *caps[2][3] = { | ||
4183 | { alc_capture_mixer_nosrc1, | ||
4184 | alc_capture_mixer_nosrc2, | ||
4185 | alc_capture_mixer_nosrc3 }, | ||
4186 | { alc_capture_mixer1, | ||
4187 | alc_capture_mixer2, | ||
4188 | alc_capture_mixer3 }, | ||
4189 | }; | ||
4190 | |||
4191 | /* check whether either of ADC or MUX has a volume control */ | ||
4192 | if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) { | ||
4193 | if (!spec->capsrc_nids) | ||
4194 | return; /* no volume */ | ||
4195 | if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT)) | ||
4196 | return; /* no volume in capsrc, too */ | ||
4197 | spec->vol_in_capsrc = 1; | ||
4198 | } | ||
4199 | |||
4200 | if (spec->num_adc_nids > 0) { | ||
4201 | int mux = 0; | ||
4202 | int num_adcs = 0; | ||
4203 | |||
4204 | if (spec->input_mux && spec->input_mux->num_items > 1) | ||
4205 | mux = 1; | ||
4206 | if (spec->auto_mic) { | ||
4207 | num_adcs = 1; | ||
4208 | mux = 0; | ||
4209 | } else if (spec->dyn_adc_switch) | ||
4210 | num_adcs = 1; | ||
4211 | if (!num_adcs) { | ||
4212 | if (spec->num_adc_nids > 3) | ||
4213 | spec->num_adc_nids = 3; | ||
4214 | else if (!spec->num_adc_nids) | ||
4215 | return; | ||
4216 | num_adcs = spec->num_adc_nids; | ||
4217 | } | ||
4218 | spec->cap_mixer = caps[mux][num_adcs - 1]; | ||
4219 | } | ||
4220 | } | ||
4221 | |||
4222 | /* | ||
4223 | * standard auto-parser initializations | ||
4224 | */ | ||
4225 | static void alc_auto_init_std(struct hda_codec *codec) | ||
4226 | { | ||
4227 | alc_auto_init_multi_out(codec); | ||
4228 | alc_auto_init_extra_out(codec); | ||
4229 | alc_auto_init_analog_input(codec); | ||
4230 | alc_auto_init_input_src(codec); | ||
4231 | alc_auto_init_digital(codec); | ||
4232 | alc_inithook(codec); | ||
4233 | } | ||
4234 | 920 | ||
4235 | /* | 921 | /* |
4236 | * Digital-beep handlers | 922 | * Digital-beep handlers |
@@ -4273,93 +959,20 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
4273 | const hda_nid_t *ssid_nids) | 959 | const hda_nid_t *ssid_nids) |
4274 | { | 960 | { |
4275 | struct alc_spec *spec = codec->spec; | 961 | struct alc_spec *spec = codec->spec; |
4276 | struct auto_pin_cfg *cfg = &spec->autocfg; | 962 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
4277 | int err; | 963 | int err; |
4278 | 964 | ||
4279 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, | 965 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, |
4280 | spec->parse_flags); | 966 | spec->parse_flags); |
4281 | if (err < 0) | 967 | if (err < 0) |
4282 | return err; | 968 | return err; |
4283 | if (!cfg->line_outs) { | ||
4284 | if (cfg->dig_outs || cfg->dig_in_pin) { | ||
4285 | spec->multiout.max_channels = 2; | ||
4286 | spec->no_analog = 1; | ||
4287 | goto dig_only; | ||
4288 | } | ||
4289 | return 0; /* can't find valid BIOS pin config */ | ||
4290 | } | ||
4291 | |||
4292 | if (!spec->no_primary_hp && | ||
4293 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
4294 | cfg->line_outs <= cfg->hp_outs) { | ||
4295 | /* use HP as primary out */ | ||
4296 | cfg->speaker_outs = cfg->line_outs; | ||
4297 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
4298 | sizeof(cfg->speaker_pins)); | ||
4299 | cfg->line_outs = cfg->hp_outs; | ||
4300 | memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); | ||
4301 | cfg->hp_outs = 0; | ||
4302 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
4303 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
4304 | } | ||
4305 | |||
4306 | err = alc_auto_fill_dac_nids(codec); | ||
4307 | if (err < 0) | ||
4308 | return err; | ||
4309 | err = alc_auto_add_multi_channel_mode(codec); | ||
4310 | if (err < 0) | ||
4311 | return err; | ||
4312 | err = alc_auto_create_multi_out_ctls(codec, cfg); | ||
4313 | if (err < 0) | ||
4314 | return err; | ||
4315 | err = alc_auto_create_hp_out(codec); | ||
4316 | if (err < 0) | ||
4317 | return err; | ||
4318 | err = alc_auto_create_speaker_out(codec); | ||
4319 | if (err < 0) | ||
4320 | return err; | ||
4321 | err = alc_auto_create_shared_input(codec); | ||
4322 | if (err < 0) | ||
4323 | return err; | ||
4324 | err = alc_auto_create_input_ctls(codec); | ||
4325 | if (err < 0) | ||
4326 | return err; | ||
4327 | |||
4328 | /* check the multiple speaker pins */ | ||
4329 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
4330 | spec->const_channel_count = cfg->line_outs * 2; | ||
4331 | else | ||
4332 | spec->const_channel_count = cfg->speaker_outs * 2; | ||
4333 | |||
4334 | if (spec->multi_ios > 0) | ||
4335 | spec->multiout.max_channels = max(spec->ext_channel_count, | ||
4336 | spec->const_channel_count); | ||
4337 | else | ||
4338 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
4339 | |||
4340 | dig_only: | ||
4341 | alc_auto_parse_digital(codec); | ||
4342 | |||
4343 | if (!spec->no_analog) | ||
4344 | alc_remove_invalid_adc_nids(codec); | ||
4345 | 969 | ||
4346 | if (ssid_nids) | 970 | if (ssid_nids) |
4347 | alc_ssid_check(codec, ssid_nids); | 971 | alc_ssid_check(codec, ssid_nids); |
4348 | 972 | ||
4349 | if (!spec->no_analog) { | 973 | err = snd_hda_gen_parse_auto_config(codec, cfg); |
4350 | err = alc_auto_check_switches(codec); | 974 | if (err < 0) |
4351 | if (err < 0) | 975 | return err; |
4352 | return err; | ||
4353 | err = alc_auto_add_mic_boost(codec); | ||
4354 | if (err < 0) | ||
4355 | return err; | ||
4356 | } | ||
4357 | |||
4358 | if (spec->kctls.list) | ||
4359 | add_mixer(spec, spec->kctls.list); | ||
4360 | |||
4361 | if (!spec->no_analog && !spec->cap_mixer) | ||
4362 | set_capture_mixer(codec); | ||
4363 | 976 | ||
4364 | return 1; | 977 | return 1; |
4365 | } | 978 | } |
@@ -4373,11 +986,12 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) | |||
4373 | if (!spec) | 986 | if (!spec) |
4374 | return -ENOMEM; | 987 | return -ENOMEM; |
4375 | codec->spec = spec; | 988 | codec->spec = spec; |
989 | snd_hda_gen_spec_init(&spec->gen); | ||
990 | spec->gen.mixer_nid = mixer_nid; | ||
991 | spec->gen.own_eapd_ctl = 1; | ||
4376 | codec->single_adc_amp = 1; | 992 | codec->single_adc_amp = 1; |
4377 | spec->mixer_nid = mixer_nid; | 993 | /* FIXME: do we need this for all Realtek codec models? */ |
4378 | snd_hda_gen_init(&spec->gen); | 994 | codec->spdif_status_reset = 1; |
4379 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | ||
4380 | snd_array_init(&spec->bind_ctls, sizeof(struct hda_bind_ctls *), 8); | ||
4381 | 995 | ||
4382 | err = alc_codec_rename_from_preset(codec); | 996 | err = alc_codec_rename_from_preset(codec); |
4383 | if (err < 0) { | 997 | if (err < 0) { |
@@ -4420,27 +1034,28 @@ enum { | |||
4420 | ALC880_FIXUP_6ST_BASE, | 1034 | ALC880_FIXUP_6ST_BASE, |
4421 | ALC880_FIXUP_6ST, | 1035 | ALC880_FIXUP_6ST, |
4422 | ALC880_FIXUP_6ST_DIG, | 1036 | ALC880_FIXUP_6ST_DIG, |
1037 | ALC880_FIXUP_6ST_AUTOMUTE, | ||
4423 | }; | 1038 | }; |
4424 | 1039 | ||
4425 | /* enable the volume-knob widget support on NID 0x21 */ | 1040 | /* enable the volume-knob widget support on NID 0x21 */ |
4426 | static void alc880_fixup_vol_knob(struct hda_codec *codec, | 1041 | static void alc880_fixup_vol_knob(struct hda_codec *codec, |
4427 | const struct alc_fixup *fix, int action) | 1042 | const struct hda_fixup *fix, int action) |
4428 | { | 1043 | { |
4429 | if (action == ALC_FIXUP_ACT_PROBE) | 1044 | if (action == HDA_FIXUP_ACT_PROBE) |
4430 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); | 1045 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); |
4431 | } | 1046 | } |
4432 | 1047 | ||
4433 | static const struct alc_fixup alc880_fixups[] = { | 1048 | static const struct hda_fixup alc880_fixups[] = { |
4434 | [ALC880_FIXUP_GPIO1] = { | 1049 | [ALC880_FIXUP_GPIO1] = { |
4435 | .type = ALC_FIXUP_VERBS, | 1050 | .type = HDA_FIXUP_VERBS, |
4436 | .v.verbs = alc_gpio1_init_verbs, | 1051 | .v.verbs = alc_gpio1_init_verbs, |
4437 | }, | 1052 | }, |
4438 | [ALC880_FIXUP_GPIO2] = { | 1053 | [ALC880_FIXUP_GPIO2] = { |
4439 | .type = ALC_FIXUP_VERBS, | 1054 | .type = HDA_FIXUP_VERBS, |
4440 | .v.verbs = alc_gpio2_init_verbs, | 1055 | .v.verbs = alc_gpio2_init_verbs, |
4441 | }, | 1056 | }, |
4442 | [ALC880_FIXUP_MEDION_RIM] = { | 1057 | [ALC880_FIXUP_MEDION_RIM] = { |
4443 | .type = ALC_FIXUP_VERBS, | 1058 | .type = HDA_FIXUP_VERBS, |
4444 | .v.verbs = (const struct hda_verb[]) { | 1059 | .v.verbs = (const struct hda_verb[]) { |
4445 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1060 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
4446 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 1061 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
@@ -4450,8 +1065,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4450 | .chain_id = ALC880_FIXUP_GPIO2, | 1065 | .chain_id = ALC880_FIXUP_GPIO2, |
4451 | }, | 1066 | }, |
4452 | [ALC880_FIXUP_LG] = { | 1067 | [ALC880_FIXUP_LG] = { |
4453 | .type = ALC_FIXUP_PINS, | 1068 | .type = HDA_FIXUP_PINS, |
4454 | .v.pins = (const struct alc_pincfg[]) { | 1069 | .v.pins = (const struct hda_pintbl[]) { |
4455 | /* disable bogus unused pins */ | 1070 | /* disable bogus unused pins */ |
4456 | { 0x16, 0x411111f0 }, | 1071 | { 0x16, 0x411111f0 }, |
4457 | { 0x18, 0x411111f0 }, | 1072 | { 0x18, 0x411111f0 }, |
@@ -4460,8 +1075,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4460 | } | 1075 | } |
4461 | }, | 1076 | }, |
4462 | [ALC880_FIXUP_W810] = { | 1077 | [ALC880_FIXUP_W810] = { |
4463 | .type = ALC_FIXUP_PINS, | 1078 | .type = HDA_FIXUP_PINS, |
4464 | .v.pins = (const struct alc_pincfg[]) { | 1079 | .v.pins = (const struct hda_pintbl[]) { |
4465 | /* disable bogus unused pins */ | 1080 | /* disable bogus unused pins */ |
4466 | { 0x17, 0x411111f0 }, | 1081 | { 0x17, 0x411111f0 }, |
4467 | { } | 1082 | { } |
@@ -4470,7 +1085,7 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4470 | .chain_id = ALC880_FIXUP_GPIO2, | 1085 | .chain_id = ALC880_FIXUP_GPIO2, |
4471 | }, | 1086 | }, |
4472 | [ALC880_FIXUP_EAPD_COEF] = { | 1087 | [ALC880_FIXUP_EAPD_COEF] = { |
4473 | .type = ALC_FIXUP_VERBS, | 1088 | .type = HDA_FIXUP_VERBS, |
4474 | .v.verbs = (const struct hda_verb[]) { | 1089 | .v.verbs = (const struct hda_verb[]) { |
4475 | /* change to EAPD mode */ | 1090 | /* change to EAPD mode */ |
4476 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1091 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
@@ -4479,7 +1094,7 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4479 | }, | 1094 | }, |
4480 | }, | 1095 | }, |
4481 | [ALC880_FIXUP_TCL_S700] = { | 1096 | [ALC880_FIXUP_TCL_S700] = { |
4482 | .type = ALC_FIXUP_VERBS, | 1097 | .type = HDA_FIXUP_VERBS, |
4483 | .v.verbs = (const struct hda_verb[]) { | 1098 | .v.verbs = (const struct hda_verb[]) { |
4484 | /* change to EAPD mode */ | 1099 | /* change to EAPD mode */ |
4485 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1100 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
@@ -4490,13 +1105,13 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4490 | .chain_id = ALC880_FIXUP_GPIO2, | 1105 | .chain_id = ALC880_FIXUP_GPIO2, |
4491 | }, | 1106 | }, |
4492 | [ALC880_FIXUP_VOL_KNOB] = { | 1107 | [ALC880_FIXUP_VOL_KNOB] = { |
4493 | .type = ALC_FIXUP_FUNC, | 1108 | .type = HDA_FIXUP_FUNC, |
4494 | .v.func = alc880_fixup_vol_knob, | 1109 | .v.func = alc880_fixup_vol_knob, |
4495 | }, | 1110 | }, |
4496 | [ALC880_FIXUP_FUJITSU] = { | 1111 | [ALC880_FIXUP_FUJITSU] = { |
4497 | /* override all pins as BIOS on old Amilo is broken */ | 1112 | /* override all pins as BIOS on old Amilo is broken */ |
4498 | .type = ALC_FIXUP_PINS, | 1113 | .type = HDA_FIXUP_PINS, |
4499 | .v.pins = (const struct alc_pincfg[]) { | 1114 | .v.pins = (const struct hda_pintbl[]) { |
4500 | { 0x14, 0x0121411f }, /* HP */ | 1115 | { 0x14, 0x0121411f }, /* HP */ |
4501 | { 0x15, 0x99030120 }, /* speaker */ | 1116 | { 0x15, 0x99030120 }, /* speaker */ |
4502 | { 0x16, 0x99030130 }, /* bass speaker */ | 1117 | { 0x16, 0x99030130 }, /* bass speaker */ |
@@ -4515,8 +1130,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4515 | }, | 1130 | }, |
4516 | [ALC880_FIXUP_F1734] = { | 1131 | [ALC880_FIXUP_F1734] = { |
4517 | /* almost compatible with FUJITSU, but no bass and SPDIF */ | 1132 | /* almost compatible with FUJITSU, but no bass and SPDIF */ |
4518 | .type = ALC_FIXUP_PINS, | 1133 | .type = HDA_FIXUP_PINS, |
4519 | .v.pins = (const struct alc_pincfg[]) { | 1134 | .v.pins = (const struct hda_pintbl[]) { |
4520 | { 0x14, 0x0121411f }, /* HP */ | 1135 | { 0x14, 0x0121411f }, /* HP */ |
4521 | { 0x15, 0x99030120 }, /* speaker */ | 1136 | { 0x15, 0x99030120 }, /* speaker */ |
4522 | { 0x16, 0x411111f0 }, /* N/A */ | 1137 | { 0x16, 0x411111f0 }, /* N/A */ |
@@ -4535,8 +1150,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4535 | }, | 1150 | }, |
4536 | [ALC880_FIXUP_UNIWILL] = { | 1151 | [ALC880_FIXUP_UNIWILL] = { |
4537 | /* need to fix HP and speaker pins to be parsed correctly */ | 1152 | /* need to fix HP and speaker pins to be parsed correctly */ |
4538 | .type = ALC_FIXUP_PINS, | 1153 | .type = HDA_FIXUP_PINS, |
4539 | .v.pins = (const struct alc_pincfg[]) { | 1154 | .v.pins = (const struct hda_pintbl[]) { |
4540 | { 0x14, 0x0121411f }, /* HP */ | 1155 | { 0x14, 0x0121411f }, /* HP */ |
4541 | { 0x15, 0x99030120 }, /* speaker */ | 1156 | { 0x15, 0x99030120 }, /* speaker */ |
4542 | { 0x16, 0x99030130 }, /* bass speaker */ | 1157 | { 0x16, 0x99030130 }, /* bass speaker */ |
@@ -4544,8 +1159,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4544 | }, | 1159 | }, |
4545 | }, | 1160 | }, |
4546 | [ALC880_FIXUP_UNIWILL_DIG] = { | 1161 | [ALC880_FIXUP_UNIWILL_DIG] = { |
4547 | .type = ALC_FIXUP_PINS, | 1162 | .type = HDA_FIXUP_PINS, |
4548 | .v.pins = (const struct alc_pincfg[]) { | 1163 | .v.pins = (const struct hda_pintbl[]) { |
4549 | /* disable bogus unused pins */ | 1164 | /* disable bogus unused pins */ |
4550 | { 0x17, 0x411111f0 }, | 1165 | { 0x17, 0x411111f0 }, |
4551 | { 0x19, 0x411111f0 }, | 1166 | { 0x19, 0x411111f0 }, |
@@ -4555,8 +1170,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4555 | } | 1170 | } |
4556 | }, | 1171 | }, |
4557 | [ALC880_FIXUP_Z71V] = { | 1172 | [ALC880_FIXUP_Z71V] = { |
4558 | .type = ALC_FIXUP_PINS, | 1173 | .type = HDA_FIXUP_PINS, |
4559 | .v.pins = (const struct alc_pincfg[]) { | 1174 | .v.pins = (const struct hda_pintbl[]) { |
4560 | /* set up the whole pins as BIOS is utterly broken */ | 1175 | /* set up the whole pins as BIOS is utterly broken */ |
4561 | { 0x14, 0x99030120 }, /* speaker */ | 1176 | { 0x14, 0x99030120 }, /* speaker */ |
4562 | { 0x15, 0x0121411f }, /* HP */ | 1177 | { 0x15, 0x0121411f }, /* HP */ |
@@ -4573,8 +1188,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4573 | } | 1188 | } |
4574 | }, | 1189 | }, |
4575 | [ALC880_FIXUP_3ST_BASE] = { | 1190 | [ALC880_FIXUP_3ST_BASE] = { |
4576 | .type = ALC_FIXUP_PINS, | 1191 | .type = HDA_FIXUP_PINS, |
4577 | .v.pins = (const struct alc_pincfg[]) { | 1192 | .v.pins = (const struct hda_pintbl[]) { |
4578 | { 0x14, 0x01014010 }, /* line-out */ | 1193 | { 0x14, 0x01014010 }, /* line-out */ |
4579 | { 0x15, 0x411111f0 }, /* N/A */ | 1194 | { 0x15, 0x411111f0 }, /* N/A */ |
4580 | { 0x16, 0x411111f0 }, /* N/A */ | 1195 | { 0x16, 0x411111f0 }, /* N/A */ |
@@ -4591,8 +1206,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4591 | } | 1206 | } |
4592 | }, | 1207 | }, |
4593 | [ALC880_FIXUP_3ST] = { | 1208 | [ALC880_FIXUP_3ST] = { |
4594 | .type = ALC_FIXUP_PINS, | 1209 | .type = HDA_FIXUP_PINS, |
4595 | .v.pins = (const struct alc_pincfg[]) { | 1210 | .v.pins = (const struct hda_pintbl[]) { |
4596 | { 0x1e, 0x411111f0 }, /* N/A */ | 1211 | { 0x1e, 0x411111f0 }, /* N/A */ |
4597 | { } | 1212 | { } |
4598 | }, | 1213 | }, |
@@ -4600,8 +1215,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4600 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1215 | .chain_id = ALC880_FIXUP_3ST_BASE, |
4601 | }, | 1216 | }, |
4602 | [ALC880_FIXUP_3ST_DIG] = { | 1217 | [ALC880_FIXUP_3ST_DIG] = { |
4603 | .type = ALC_FIXUP_PINS, | 1218 | .type = HDA_FIXUP_PINS, |
4604 | .v.pins = (const struct alc_pincfg[]) { | 1219 | .v.pins = (const struct hda_pintbl[]) { |
4605 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1220 | { 0x1e, 0x0144111e }, /* SPDIF */ |
4606 | { } | 1221 | { } |
4607 | }, | 1222 | }, |
@@ -4609,8 +1224,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4609 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1224 | .chain_id = ALC880_FIXUP_3ST_BASE, |
4610 | }, | 1225 | }, |
4611 | [ALC880_FIXUP_5ST_BASE] = { | 1226 | [ALC880_FIXUP_5ST_BASE] = { |
4612 | .type = ALC_FIXUP_PINS, | 1227 | .type = HDA_FIXUP_PINS, |
4613 | .v.pins = (const struct alc_pincfg[]) { | 1228 | .v.pins = (const struct hda_pintbl[]) { |
4614 | { 0x14, 0x01014010 }, /* front */ | 1229 | { 0x14, 0x01014010 }, /* front */ |
4615 | { 0x15, 0x411111f0 }, /* N/A */ | 1230 | { 0x15, 0x411111f0 }, /* N/A */ |
4616 | { 0x16, 0x01011411 }, /* CLFE */ | 1231 | { 0x16, 0x01011411 }, /* CLFE */ |
@@ -4627,8 +1242,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4627 | } | 1242 | } |
4628 | }, | 1243 | }, |
4629 | [ALC880_FIXUP_5ST] = { | 1244 | [ALC880_FIXUP_5ST] = { |
4630 | .type = ALC_FIXUP_PINS, | 1245 | .type = HDA_FIXUP_PINS, |
4631 | .v.pins = (const struct alc_pincfg[]) { | 1246 | .v.pins = (const struct hda_pintbl[]) { |
4632 | { 0x1e, 0x411111f0 }, /* N/A */ | 1247 | { 0x1e, 0x411111f0 }, /* N/A */ |
4633 | { } | 1248 | { } |
4634 | }, | 1249 | }, |
@@ -4636,8 +1251,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4636 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1251 | .chain_id = ALC880_FIXUP_5ST_BASE, |
4637 | }, | 1252 | }, |
4638 | [ALC880_FIXUP_5ST_DIG] = { | 1253 | [ALC880_FIXUP_5ST_DIG] = { |
4639 | .type = ALC_FIXUP_PINS, | 1254 | .type = HDA_FIXUP_PINS, |
4640 | .v.pins = (const struct alc_pincfg[]) { | 1255 | .v.pins = (const struct hda_pintbl[]) { |
4641 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1256 | { 0x1e, 0x0144111e }, /* SPDIF */ |
4642 | { } | 1257 | { } |
4643 | }, | 1258 | }, |
@@ -4645,8 +1260,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4645 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1260 | .chain_id = ALC880_FIXUP_5ST_BASE, |
4646 | }, | 1261 | }, |
4647 | [ALC880_FIXUP_6ST_BASE] = { | 1262 | [ALC880_FIXUP_6ST_BASE] = { |
4648 | .type = ALC_FIXUP_PINS, | 1263 | .type = HDA_FIXUP_PINS, |
4649 | .v.pins = (const struct alc_pincfg[]) { | 1264 | .v.pins = (const struct hda_pintbl[]) { |
4650 | { 0x14, 0x01014010 }, /* front */ | 1265 | { 0x14, 0x01014010 }, /* front */ |
4651 | { 0x15, 0x01016412 }, /* surr */ | 1266 | { 0x15, 0x01016412 }, /* surr */ |
4652 | { 0x16, 0x01011411 }, /* CLFE */ | 1267 | { 0x16, 0x01011411 }, /* CLFE */ |
@@ -4663,8 +1278,8 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4663 | } | 1278 | } |
4664 | }, | 1279 | }, |
4665 | [ALC880_FIXUP_6ST] = { | 1280 | [ALC880_FIXUP_6ST] = { |
4666 | .type = ALC_FIXUP_PINS, | 1281 | .type = HDA_FIXUP_PINS, |
4667 | .v.pins = (const struct alc_pincfg[]) { | 1282 | .v.pins = (const struct hda_pintbl[]) { |
4668 | { 0x1e, 0x411111f0 }, /* N/A */ | 1283 | { 0x1e, 0x411111f0 }, /* N/A */ |
4669 | { } | 1284 | { } |
4670 | }, | 1285 | }, |
@@ -4672,14 +1287,23 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4672 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1287 | .chain_id = ALC880_FIXUP_6ST_BASE, |
4673 | }, | 1288 | }, |
4674 | [ALC880_FIXUP_6ST_DIG] = { | 1289 | [ALC880_FIXUP_6ST_DIG] = { |
4675 | .type = ALC_FIXUP_PINS, | 1290 | .type = HDA_FIXUP_PINS, |
4676 | .v.pins = (const struct alc_pincfg[]) { | 1291 | .v.pins = (const struct hda_pintbl[]) { |
4677 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1292 | { 0x1e, 0x0144111e }, /* SPDIF */ |
4678 | { } | 1293 | { } |
4679 | }, | 1294 | }, |
4680 | .chained = true, | 1295 | .chained = true, |
4681 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1296 | .chain_id = ALC880_FIXUP_6ST_BASE, |
4682 | }, | 1297 | }, |
1298 | [ALC880_FIXUP_6ST_AUTOMUTE] = { | ||
1299 | .type = HDA_FIXUP_PINS, | ||
1300 | .v.pins = (const struct hda_pintbl[]) { | ||
1301 | { 0x1b, 0x0121401f }, /* HP with jack detect */ | ||
1302 | { } | ||
1303 | }, | ||
1304 | .chained_before = true, | ||
1305 | .chain_id = ALC880_FIXUP_6ST_BASE, | ||
1306 | }, | ||
4683 | }; | 1307 | }; |
4684 | 1308 | ||
4685 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 1309 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
@@ -4694,7 +1318,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = { | |||
4694 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), | 1318 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), |
4695 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | 1319 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
4696 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 1320 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |
4697 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST), | 1321 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), |
4698 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), | 1322 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), |
4699 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), | 1323 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), |
4700 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), | 1324 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), |
@@ -4750,13 +1374,14 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = { | |||
4750 | {} | 1374 | {} |
4751 | }; | 1375 | }; |
4752 | 1376 | ||
4753 | static const struct alc_model_fixup alc880_fixup_models[] = { | 1377 | static const struct hda_model_fixup alc880_fixup_models[] = { |
4754 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, | 1378 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, |
4755 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, | 1379 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, |
4756 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, | 1380 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, |
4757 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, | 1381 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, |
4758 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, | 1382 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, |
4759 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, | 1383 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, |
1384 | {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, | ||
4760 | {} | 1385 | {} |
4761 | }; | 1386 | }; |
4762 | 1387 | ||
@@ -4774,18 +1399,18 @@ static int patch_alc880(struct hda_codec *codec) | |||
4774 | return err; | 1399 | return err; |
4775 | 1400 | ||
4776 | spec = codec->spec; | 1401 | spec = codec->spec; |
4777 | spec->need_dac_fix = 1; | 1402 | spec->gen.need_dac_fix = 1; |
4778 | 1403 | ||
4779 | alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, | 1404 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, |
4780 | alc880_fixups); | 1405 | alc880_fixups); |
4781 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 1406 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4782 | 1407 | ||
4783 | /* automatic parse from the BIOS config */ | 1408 | /* automatic parse from the BIOS config */ |
4784 | err = alc880_parse_auto_config(codec); | 1409 | err = alc880_parse_auto_config(codec); |
4785 | if (err < 0) | 1410 | if (err < 0) |
4786 | goto error; | 1411 | goto error; |
4787 | 1412 | ||
4788 | if (!spec->no_analog) { | 1413 | if (!spec->gen.no_analog) { |
4789 | err = snd_hda_attach_beep_device(codec, 0x1); | 1414 | err = snd_hda_attach_beep_device(codec, 0x1); |
4790 | if (err < 0) | 1415 | if (err < 0) |
4791 | goto error; | 1416 | goto error; |
@@ -4796,7 +1421,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4796 | codec->patch_ops.unsol_event = alc880_unsol_event; | 1421 | codec->patch_ops.unsol_event = alc880_unsol_event; |
4797 | 1422 | ||
4798 | 1423 | ||
4799 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 1424 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4800 | 1425 | ||
4801 | return 0; | 1426 | return 0; |
4802 | 1427 | ||
@@ -4828,38 +1453,39 @@ enum { | |||
4828 | ALC260_FIXUP_REPLACER, | 1453 | ALC260_FIXUP_REPLACER, |
4829 | ALC260_FIXUP_HP_B1900, | 1454 | ALC260_FIXUP_HP_B1900, |
4830 | ALC260_FIXUP_KN1, | 1455 | ALC260_FIXUP_KN1, |
1456 | ALC260_FIXUP_FSC_S7020, | ||
4831 | }; | 1457 | }; |
4832 | 1458 | ||
4833 | static void alc260_gpio1_automute(struct hda_codec *codec) | 1459 | static void alc260_gpio1_automute(struct hda_codec *codec) |
4834 | { | 1460 | { |
4835 | struct alc_spec *spec = codec->spec; | 1461 | struct alc_spec *spec = codec->spec; |
4836 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 1462 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
4837 | spec->hp_jack_present); | 1463 | spec->gen.hp_jack_present); |
4838 | } | 1464 | } |
4839 | 1465 | ||
4840 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | 1466 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, |
4841 | const struct alc_fixup *fix, int action) | 1467 | const struct hda_fixup *fix, int action) |
4842 | { | 1468 | { |
4843 | struct alc_spec *spec = codec->spec; | 1469 | struct alc_spec *spec = codec->spec; |
4844 | if (action == ALC_FIXUP_ACT_PROBE) { | 1470 | if (action == HDA_FIXUP_ACT_PROBE) { |
4845 | /* although the machine has only one output pin, we need to | 1471 | /* although the machine has only one output pin, we need to |
4846 | * toggle GPIO1 according to the jack state | 1472 | * toggle GPIO1 according to the jack state |
4847 | */ | 1473 | */ |
4848 | spec->automute_hook = alc260_gpio1_automute; | 1474 | spec->gen.automute_hook = alc260_gpio1_automute; |
4849 | spec->detect_hp = 1; | 1475 | spec->gen.detect_hp = 1; |
4850 | spec->automute_speaker = 1; | 1476 | spec->gen.automute_speaker = 1; |
4851 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | 1477 | spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ |
4852 | snd_hda_jack_detect_enable_callback(codec, 0x0f, ALC_HP_EVENT, | 1478 | snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, |
4853 | alc_hp_automute); | 1479 | snd_hda_gen_hp_automute); |
4854 | snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); | 1480 | snd_hda_add_verbs(codec, alc_gpio1_init_verbs); |
4855 | } | 1481 | } |
4856 | } | 1482 | } |
4857 | 1483 | ||
4858 | static void alc260_fixup_kn1(struct hda_codec *codec, | 1484 | static void alc260_fixup_kn1(struct hda_codec *codec, |
4859 | const struct alc_fixup *fix, int action) | 1485 | const struct hda_fixup *fix, int action) |
4860 | { | 1486 | { |
4861 | struct alc_spec *spec = codec->spec; | 1487 | struct alc_spec *spec = codec->spec; |
4862 | static const struct alc_pincfg pincfgs[] = { | 1488 | static const struct hda_pintbl pincfgs[] = { |
4863 | { 0x0f, 0x02214000 }, /* HP/speaker */ | 1489 | { 0x0f, 0x02214000 }, /* HP/speaker */ |
4864 | { 0x12, 0x90a60160 }, /* int mic */ | 1490 | { 0x12, 0x90a60160 }, /* int mic */ |
4865 | { 0x13, 0x02a19000 }, /* ext mic */ | 1491 | { 0x13, 0x02a19000 }, /* ext mic */ |
@@ -4876,32 +1502,41 @@ static void alc260_fixup_kn1(struct hda_codec *codec, | |||
4876 | }; | 1502 | }; |
4877 | 1503 | ||
4878 | switch (action) { | 1504 | switch (action) { |
4879 | case ALC_FIXUP_ACT_PRE_PROBE: | 1505 | case HDA_FIXUP_ACT_PRE_PROBE: |
4880 | alc_apply_pincfgs(codec, pincfgs); | 1506 | snd_hda_apply_pincfgs(codec, pincfgs); |
4881 | break; | 1507 | break; |
4882 | case ALC_FIXUP_ACT_PROBE: | 1508 | case HDA_FIXUP_ACT_PROBE: |
4883 | spec->init_amp = ALC_INIT_NONE; | 1509 | spec->init_amp = ALC_INIT_NONE; |
4884 | break; | 1510 | break; |
4885 | } | 1511 | } |
4886 | } | 1512 | } |
4887 | 1513 | ||
4888 | static const struct alc_fixup alc260_fixups[] = { | 1514 | static void alc260_fixup_fsc_s7020(struct hda_codec *codec, |
1515 | const struct hda_fixup *fix, int action) | ||
1516 | { | ||
1517 | struct alc_spec *spec = codec->spec; | ||
1518 | |||
1519 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
1520 | spec->gen.add_out_jack_modes = 1; | ||
1521 | } | ||
1522 | |||
1523 | static const struct hda_fixup alc260_fixups[] = { | ||
4889 | [ALC260_FIXUP_HP_DC5750] = { | 1524 | [ALC260_FIXUP_HP_DC5750] = { |
4890 | .type = ALC_FIXUP_PINS, | 1525 | .type = HDA_FIXUP_PINS, |
4891 | .v.pins = (const struct alc_pincfg[]) { | 1526 | .v.pins = (const struct hda_pintbl[]) { |
4892 | { 0x11, 0x90130110 }, /* speaker */ | 1527 | { 0x11, 0x90130110 }, /* speaker */ |
4893 | { } | 1528 | { } |
4894 | } | 1529 | } |
4895 | }, | 1530 | }, |
4896 | [ALC260_FIXUP_HP_PIN_0F] = { | 1531 | [ALC260_FIXUP_HP_PIN_0F] = { |
4897 | .type = ALC_FIXUP_PINS, | 1532 | .type = HDA_FIXUP_PINS, |
4898 | .v.pins = (const struct alc_pincfg[]) { | 1533 | .v.pins = (const struct hda_pintbl[]) { |
4899 | { 0x0f, 0x01214000 }, /* HP */ | 1534 | { 0x0f, 0x01214000 }, /* HP */ |
4900 | { } | 1535 | { } |
4901 | } | 1536 | } |
4902 | }, | 1537 | }, |
4903 | [ALC260_FIXUP_COEF] = { | 1538 | [ALC260_FIXUP_COEF] = { |
4904 | .type = ALC_FIXUP_VERBS, | 1539 | .type = HDA_FIXUP_VERBS, |
4905 | .v.verbs = (const struct hda_verb[]) { | 1540 | .v.verbs = (const struct hda_verb[]) { |
4906 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1541 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
4907 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, | 1542 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, |
@@ -4911,17 +1546,17 @@ static const struct alc_fixup alc260_fixups[] = { | |||
4911 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1546 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
4912 | }, | 1547 | }, |
4913 | [ALC260_FIXUP_GPIO1] = { | 1548 | [ALC260_FIXUP_GPIO1] = { |
4914 | .type = ALC_FIXUP_VERBS, | 1549 | .type = HDA_FIXUP_VERBS, |
4915 | .v.verbs = alc_gpio1_init_verbs, | 1550 | .v.verbs = alc_gpio1_init_verbs, |
4916 | }, | 1551 | }, |
4917 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | 1552 | [ALC260_FIXUP_GPIO1_TOGGLE] = { |
4918 | .type = ALC_FIXUP_FUNC, | 1553 | .type = HDA_FIXUP_FUNC, |
4919 | .v.func = alc260_fixup_gpio1_toggle, | 1554 | .v.func = alc260_fixup_gpio1_toggle, |
4920 | .chained = true, | 1555 | .chained = true, |
4921 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1556 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
4922 | }, | 1557 | }, |
4923 | [ALC260_FIXUP_REPLACER] = { | 1558 | [ALC260_FIXUP_REPLACER] = { |
4924 | .type = ALC_FIXUP_VERBS, | 1559 | .type = HDA_FIXUP_VERBS, |
4925 | .v.verbs = (const struct hda_verb[]) { | 1560 | .v.verbs = (const struct hda_verb[]) { |
4926 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1561 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
4927 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 1562 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
@@ -4931,15 +1566,19 @@ static const struct alc_fixup alc260_fixups[] = { | |||
4931 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | 1566 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, |
4932 | }, | 1567 | }, |
4933 | [ALC260_FIXUP_HP_B1900] = { | 1568 | [ALC260_FIXUP_HP_B1900] = { |
4934 | .type = ALC_FIXUP_FUNC, | 1569 | .type = HDA_FIXUP_FUNC, |
4935 | .v.func = alc260_fixup_gpio1_toggle, | 1570 | .v.func = alc260_fixup_gpio1_toggle, |
4936 | .chained = true, | 1571 | .chained = true, |
4937 | .chain_id = ALC260_FIXUP_COEF, | 1572 | .chain_id = ALC260_FIXUP_COEF, |
4938 | }, | 1573 | }, |
4939 | [ALC260_FIXUP_KN1] = { | 1574 | [ALC260_FIXUP_KN1] = { |
4940 | .type = ALC_FIXUP_FUNC, | 1575 | .type = HDA_FIXUP_FUNC, |
4941 | .v.func = alc260_fixup_kn1, | 1576 | .v.func = alc260_fixup_kn1, |
4942 | }, | 1577 | }, |
1578 | [ALC260_FIXUP_FSC_S7020] = { | ||
1579 | .type = HDA_FIXUP_FUNC, | ||
1580 | .v.func = alc260_fixup_fsc_s7020, | ||
1581 | }, | ||
4943 | }; | 1582 | }; |
4944 | 1583 | ||
4945 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 1584 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
@@ -4948,6 +1587,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { | |||
4948 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | 1587 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), |
4949 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | 1588 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), |
4950 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | 1589 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), |
1590 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), | ||
4951 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | 1591 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), |
4952 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), | 1592 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), |
4953 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | 1593 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), |
@@ -4967,16 +1607,21 @@ static int patch_alc260(struct hda_codec *codec) | |||
4967 | return err; | 1607 | return err; |
4968 | 1608 | ||
4969 | spec = codec->spec; | 1609 | spec = codec->spec; |
1610 | /* as quite a few machines require HP amp for speaker outputs, | ||
1611 | * it's easier to enable it unconditionally; even if it's unneeded, | ||
1612 | * it's almost harmless. | ||
1613 | */ | ||
1614 | spec->gen.prefer_hp_amp = 1; | ||
4970 | 1615 | ||
4971 | alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); | 1616 | snd_hda_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); |
4972 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 1617 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4973 | 1618 | ||
4974 | /* automatic parse from the BIOS config */ | 1619 | /* automatic parse from the BIOS config */ |
4975 | err = alc260_parse_auto_config(codec); | 1620 | err = alc260_parse_auto_config(codec); |
4976 | if (err < 0) | 1621 | if (err < 0) |
4977 | goto error; | 1622 | goto error; |
4978 | 1623 | ||
4979 | if (!spec->no_analog) { | 1624 | if (!spec->gen.no_analog) { |
4980 | err = snd_hda_attach_beep_device(codec, 0x1); | 1625 | err = snd_hda_attach_beep_device(codec, 0x1); |
4981 | if (err < 0) | 1626 | if (err < 0) |
4982 | goto error; | 1627 | goto error; |
@@ -4986,7 +1631,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
4986 | codec->patch_ops = alc_patch_ops; | 1631 | codec->patch_ops = alc_patch_ops; |
4987 | spec->shutup = alc_eapd_shutup; | 1632 | spec->shutup = alc_eapd_shutup; |
4988 | 1633 | ||
4989 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 1634 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4990 | 1635 | ||
4991 | return 0; | 1636 | return 0; |
4992 | 1637 | ||
@@ -5040,9 +1685,9 @@ enum { | |||
5040 | }; | 1685 | }; |
5041 | 1686 | ||
5042 | static void alc889_fixup_coef(struct hda_codec *codec, | 1687 | static void alc889_fixup_coef(struct hda_codec *codec, |
5043 | const struct alc_fixup *fix, int action) | 1688 | const struct hda_fixup *fix, int action) |
5044 | { | 1689 | { |
5045 | if (action != ALC_FIXUP_ACT_INIT) | 1690 | if (action != HDA_FIXUP_ACT_INIT) |
5046 | return; | 1691 | return; |
5047 | alc889_coef_init(codec); | 1692 | alc889_coef_init(codec); |
5048 | } | 1693 | } |
@@ -5082,9 +1727,9 @@ static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | |||
5082 | 1727 | ||
5083 | /* set up GPIO at initialization */ | 1728 | /* set up GPIO at initialization */ |
5084 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | 1729 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, |
5085 | const struct alc_fixup *fix, int action) | 1730 | const struct hda_fixup *fix, int action) |
5086 | { | 1731 | { |
5087 | if (action != ALC_FIXUP_ACT_INIT) | 1732 | if (action != HDA_FIXUP_ACT_INIT) |
5088 | return; | 1733 | return; |
5089 | alc882_gpio_mute(codec, 0, 0); | 1734 | alc882_gpio_mute(codec, 0, 0); |
5090 | alc882_gpio_mute(codec, 1, 0); | 1735 | alc882_gpio_mute(codec, 1, 0); |
@@ -5095,9 +1740,9 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | |||
5095 | * work correctly (bko#42740) | 1740 | * work correctly (bko#42740) |
5096 | */ | 1741 | */ |
5097 | static void alc889_fixup_dac_route(struct hda_codec *codec, | 1742 | static void alc889_fixup_dac_route(struct hda_codec *codec, |
5098 | const struct alc_fixup *fix, int action) | 1743 | const struct hda_fixup *fix, int action) |
5099 | { | 1744 | { |
5100 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | 1745 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5101 | /* fake the connections during parsing the tree */ | 1746 | /* fake the connections during parsing the tree */ |
5102 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | 1747 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; |
5103 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | 1748 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; |
@@ -5105,7 +1750,7 @@ static void alc889_fixup_dac_route(struct hda_codec *codec, | |||
5105 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | 1750 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); |
5106 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | 1751 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); |
5107 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | 1752 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); |
5108 | } else if (action == ALC_FIXUP_ACT_PROBE) { | 1753 | } else if (action == HDA_FIXUP_ACT_PROBE) { |
5109 | /* restore the connections */ | 1754 | /* restore the connections */ |
5110 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | 1755 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; |
5111 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | 1756 | snd_hda_override_conn_list(codec, 0x14, 5, conn); |
@@ -5117,62 +1762,60 @@ static void alc889_fixup_dac_route(struct hda_codec *codec, | |||
5117 | 1762 | ||
5118 | /* Set VREF on HP pin */ | 1763 | /* Set VREF on HP pin */ |
5119 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, | 1764 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, |
5120 | const struct alc_fixup *fix, int action) | 1765 | const struct hda_fixup *fix, int action) |
5121 | { | 1766 | { |
5122 | struct alc_spec *spec = codec->spec; | 1767 | struct alc_spec *spec = codec->spec; |
5123 | static hda_nid_t nids[2] = { 0x14, 0x15 }; | 1768 | static hda_nid_t nids[2] = { 0x14, 0x15 }; |
5124 | int i; | 1769 | int i; |
5125 | 1770 | ||
5126 | if (action != ALC_FIXUP_ACT_INIT) | 1771 | if (action != HDA_FIXUP_ACT_INIT) |
5127 | return; | 1772 | return; |
5128 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | 1773 | for (i = 0; i < ARRAY_SIZE(nids); i++) { |
5129 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); | 1774 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); |
5130 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) | 1775 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) |
5131 | continue; | 1776 | continue; |
5132 | val = snd_hda_codec_read(codec, nids[i], 0, | 1777 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
5133 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5134 | val |= AC_PINCTL_VREF_80; | 1778 | val |= AC_PINCTL_VREF_80; |
5135 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1779 | snd_hda_set_pin_ctl(codec, nids[i], val); |
5136 | spec->keep_vref_in_automute = 1; | 1780 | spec->gen.keep_vref_in_automute = 1; |
5137 | break; | 1781 | break; |
5138 | } | 1782 | } |
5139 | } | 1783 | } |
5140 | 1784 | ||
5141 | /* Set VREF on speaker pins on imac91 */ | 1785 | /* Set VREF on speaker pins on imac91 */ |
5142 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, | 1786 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, |
5143 | const struct alc_fixup *fix, int action) | 1787 | const struct hda_fixup *fix, int action) |
5144 | { | 1788 | { |
5145 | struct alc_spec *spec = codec->spec; | 1789 | struct alc_spec *spec = codec->spec; |
5146 | static hda_nid_t nids[2] = { 0x18, 0x1a }; | 1790 | static hda_nid_t nids[2] = { 0x18, 0x1a }; |
5147 | int i; | 1791 | int i; |
5148 | 1792 | ||
5149 | if (action != ALC_FIXUP_ACT_INIT) | 1793 | if (action != HDA_FIXUP_ACT_INIT) |
5150 | return; | 1794 | return; |
5151 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | 1795 | for (i = 0; i < ARRAY_SIZE(nids); i++) { |
5152 | unsigned int val; | 1796 | unsigned int val; |
5153 | val = snd_hda_codec_read(codec, nids[i], 0, | 1797 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
5154 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5155 | val |= AC_PINCTL_VREF_50; | 1798 | val |= AC_PINCTL_VREF_50; |
5156 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1799 | snd_hda_set_pin_ctl(codec, nids[i], val); |
5157 | } | 1800 | } |
5158 | spec->keep_vref_in_automute = 1; | 1801 | spec->gen.keep_vref_in_automute = 1; |
5159 | } | 1802 | } |
5160 | 1803 | ||
5161 | /* Don't take HP output as primary | 1804 | /* Don't take HP output as primary |
5162 | * strangely, the speaker output doesn't work on VAIO Z through DAC 0x05 | 1805 | * strangely, the speaker output doesn't work on VAIO Z through DAC 0x05 |
5163 | */ | 1806 | */ |
5164 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | 1807 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, |
5165 | const struct alc_fixup *fix, int action) | 1808 | const struct hda_fixup *fix, int action) |
5166 | { | 1809 | { |
5167 | struct alc_spec *spec = codec->spec; | 1810 | struct alc_spec *spec = codec->spec; |
5168 | if (action == ALC_FIXUP_ACT_PRE_PROBE) | 1811 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
5169 | spec->no_primary_hp = 1; | 1812 | spec->gen.no_primary_hp = 1; |
5170 | } | 1813 | } |
5171 | 1814 | ||
5172 | static const struct alc_fixup alc882_fixups[] = { | 1815 | static const struct hda_fixup alc882_fixups[] = { |
5173 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 1816 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
5174 | .type = ALC_FIXUP_PINS, | 1817 | .type = HDA_FIXUP_PINS, |
5175 | .v.pins = (const struct alc_pincfg[]) { | 1818 | .v.pins = (const struct hda_pintbl[]) { |
5176 | { 0x15, 0x01080104 }, /* side */ | 1819 | { 0x15, 0x01080104 }, /* side */ |
5177 | { 0x16, 0x01011012 }, /* rear */ | 1820 | { 0x16, 0x01011012 }, /* rear */ |
5178 | { 0x17, 0x01016011 }, /* clfe */ | 1821 | { 0x17, 0x01016011 }, /* clfe */ |
@@ -5180,47 +1823,47 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5180 | } | 1823 | } |
5181 | }, | 1824 | }, |
5182 | [ALC882_FIXUP_LENOVO_Y530] = { | 1825 | [ALC882_FIXUP_LENOVO_Y530] = { |
5183 | .type = ALC_FIXUP_PINS, | 1826 | .type = HDA_FIXUP_PINS, |
5184 | .v.pins = (const struct alc_pincfg[]) { | 1827 | .v.pins = (const struct hda_pintbl[]) { |
5185 | { 0x15, 0x99130112 }, /* rear int speakers */ | 1828 | { 0x15, 0x99130112 }, /* rear int speakers */ |
5186 | { 0x16, 0x99130111 }, /* subwoofer */ | 1829 | { 0x16, 0x99130111 }, /* subwoofer */ |
5187 | { } | 1830 | { } |
5188 | } | 1831 | } |
5189 | }, | 1832 | }, |
5190 | [ALC882_FIXUP_PB_M5210] = { | 1833 | [ALC882_FIXUP_PB_M5210] = { |
5191 | .type = ALC_FIXUP_VERBS, | 1834 | .type = HDA_FIXUP_PINCTLS, |
5192 | .v.verbs = (const struct hda_verb[]) { | 1835 | .v.pins = (const struct hda_pintbl[]) { |
5193 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | 1836 | { 0x19, PIN_VREF50 }, |
5194 | {} | 1837 | {} |
5195 | } | 1838 | } |
5196 | }, | 1839 | }, |
5197 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { | 1840 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { |
5198 | .type = ALC_FIXUP_FUNC, | 1841 | .type = HDA_FIXUP_FUNC, |
5199 | .v.func = alc_fixup_sku_ignore, | 1842 | .v.func = alc_fixup_sku_ignore, |
5200 | }, | 1843 | }, |
5201 | [ALC882_FIXUP_ASUS_W90V] = { | 1844 | [ALC882_FIXUP_ASUS_W90V] = { |
5202 | .type = ALC_FIXUP_PINS, | 1845 | .type = HDA_FIXUP_PINS, |
5203 | .v.pins = (const struct alc_pincfg[]) { | 1846 | .v.pins = (const struct hda_pintbl[]) { |
5204 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | 1847 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ |
5205 | { } | 1848 | { } |
5206 | } | 1849 | } |
5207 | }, | 1850 | }, |
5208 | [ALC889_FIXUP_CD] = { | 1851 | [ALC889_FIXUP_CD] = { |
5209 | .type = ALC_FIXUP_PINS, | 1852 | .type = HDA_FIXUP_PINS, |
5210 | .v.pins = (const struct alc_pincfg[]) { | 1853 | .v.pins = (const struct hda_pintbl[]) { |
5211 | { 0x1c, 0x993301f0 }, /* CD */ | 1854 | { 0x1c, 0x993301f0 }, /* CD */ |
5212 | { } | 1855 | { } |
5213 | } | 1856 | } |
5214 | }, | 1857 | }, |
5215 | [ALC889_FIXUP_VAIO_TT] = { | 1858 | [ALC889_FIXUP_VAIO_TT] = { |
5216 | .type = ALC_FIXUP_PINS, | 1859 | .type = HDA_FIXUP_PINS, |
5217 | .v.pins = (const struct alc_pincfg[]) { | 1860 | .v.pins = (const struct hda_pintbl[]) { |
5218 | { 0x17, 0x90170111 }, /* hidden surround speaker */ | 1861 | { 0x17, 0x90170111 }, /* hidden surround speaker */ |
5219 | { } | 1862 | { } |
5220 | } | 1863 | } |
5221 | }, | 1864 | }, |
5222 | [ALC888_FIXUP_EEE1601] = { | 1865 | [ALC888_FIXUP_EEE1601] = { |
5223 | .type = ALC_FIXUP_VERBS, | 1866 | .type = HDA_FIXUP_VERBS, |
5224 | .v.verbs = (const struct hda_verb[]) { | 1867 | .v.verbs = (const struct hda_verb[]) { |
5225 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 1868 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
5226 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, | 1869 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, |
@@ -5228,7 +1871,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5228 | } | 1871 | } |
5229 | }, | 1872 | }, |
5230 | [ALC882_FIXUP_EAPD] = { | 1873 | [ALC882_FIXUP_EAPD] = { |
5231 | .type = ALC_FIXUP_VERBS, | 1874 | .type = HDA_FIXUP_VERBS, |
5232 | .v.verbs = (const struct hda_verb[]) { | 1875 | .v.verbs = (const struct hda_verb[]) { |
5233 | /* change to EAPD mode */ | 1876 | /* change to EAPD mode */ |
5234 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1877 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
@@ -5237,7 +1880,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5237 | } | 1880 | } |
5238 | }, | 1881 | }, |
5239 | [ALC883_FIXUP_EAPD] = { | 1882 | [ALC883_FIXUP_EAPD] = { |
5240 | .type = ALC_FIXUP_VERBS, | 1883 | .type = HDA_FIXUP_VERBS, |
5241 | .v.verbs = (const struct hda_verb[]) { | 1884 | .v.verbs = (const struct hda_verb[]) { |
5242 | /* change to EAPD mode */ | 1885 | /* change to EAPD mode */ |
5243 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1886 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
@@ -5246,7 +1889,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5246 | } | 1889 | } |
5247 | }, | 1890 | }, |
5248 | [ALC883_FIXUP_ACER_EAPD] = { | 1891 | [ALC883_FIXUP_ACER_EAPD] = { |
5249 | .type = ALC_FIXUP_VERBS, | 1892 | .type = HDA_FIXUP_VERBS, |
5250 | .v.verbs = (const struct hda_verb[]) { | 1893 | .v.verbs = (const struct hda_verb[]) { |
5251 | /* eanable EAPD on Acer laptops */ | 1894 | /* eanable EAPD on Acer laptops */ |
5252 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1895 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
@@ -5255,30 +1898,30 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5255 | } | 1898 | } |
5256 | }, | 1899 | }, |
5257 | [ALC882_FIXUP_GPIO1] = { | 1900 | [ALC882_FIXUP_GPIO1] = { |
5258 | .type = ALC_FIXUP_VERBS, | 1901 | .type = HDA_FIXUP_VERBS, |
5259 | .v.verbs = alc_gpio1_init_verbs, | 1902 | .v.verbs = alc_gpio1_init_verbs, |
5260 | }, | 1903 | }, |
5261 | [ALC882_FIXUP_GPIO2] = { | 1904 | [ALC882_FIXUP_GPIO2] = { |
5262 | .type = ALC_FIXUP_VERBS, | 1905 | .type = HDA_FIXUP_VERBS, |
5263 | .v.verbs = alc_gpio2_init_verbs, | 1906 | .v.verbs = alc_gpio2_init_verbs, |
5264 | }, | 1907 | }, |
5265 | [ALC882_FIXUP_GPIO3] = { | 1908 | [ALC882_FIXUP_GPIO3] = { |
5266 | .type = ALC_FIXUP_VERBS, | 1909 | .type = HDA_FIXUP_VERBS, |
5267 | .v.verbs = alc_gpio3_init_verbs, | 1910 | .v.verbs = alc_gpio3_init_verbs, |
5268 | }, | 1911 | }, |
5269 | [ALC882_FIXUP_ASUS_W2JC] = { | 1912 | [ALC882_FIXUP_ASUS_W2JC] = { |
5270 | .type = ALC_FIXUP_VERBS, | 1913 | .type = HDA_FIXUP_VERBS, |
5271 | .v.verbs = alc_gpio1_init_verbs, | 1914 | .v.verbs = alc_gpio1_init_verbs, |
5272 | .chained = true, | 1915 | .chained = true, |
5273 | .chain_id = ALC882_FIXUP_EAPD, | 1916 | .chain_id = ALC882_FIXUP_EAPD, |
5274 | }, | 1917 | }, |
5275 | [ALC889_FIXUP_COEF] = { | 1918 | [ALC889_FIXUP_COEF] = { |
5276 | .type = ALC_FIXUP_FUNC, | 1919 | .type = HDA_FIXUP_FUNC, |
5277 | .v.func = alc889_fixup_coef, | 1920 | .v.func = alc889_fixup_coef, |
5278 | }, | 1921 | }, |
5279 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { | 1922 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { |
5280 | .type = ALC_FIXUP_PINS, | 1923 | .type = HDA_FIXUP_PINS, |
5281 | .v.pins = (const struct alc_pincfg[]) { | 1924 | .v.pins = (const struct hda_pintbl[]) { |
5282 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 1925 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
5283 | { 0x17, 0x99130112 }, /* surround speaker */ | 1926 | { 0x17, 0x99130112 }, /* surround speaker */ |
5284 | { } | 1927 | { } |
@@ -5287,8 +1930,8 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5287 | .chain_id = ALC882_FIXUP_GPIO1, | 1930 | .chain_id = ALC882_FIXUP_GPIO1, |
5288 | }, | 1931 | }, |
5289 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { | 1932 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { |
5290 | .type = ALC_FIXUP_PINS, | 1933 | .type = HDA_FIXUP_PINS, |
5291 | .v.pins = (const struct alc_pincfg[]) { | 1934 | .v.pins = (const struct hda_pintbl[]) { |
5292 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 1935 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
5293 | { 0x1b, 0x99130112 }, /* surround speaker */ | 1936 | { 0x1b, 0x99130112 }, /* surround speaker */ |
5294 | { } | 1937 | { } |
@@ -5298,7 +1941,7 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5298 | }, | 1941 | }, |
5299 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { | 1942 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { |
5300 | /* additional init verbs for Acer Aspire 8930G */ | 1943 | /* additional init verbs for Acer Aspire 8930G */ |
5301 | .type = ALC_FIXUP_VERBS, | 1944 | .type = HDA_FIXUP_VERBS, |
5302 | .v.verbs = (const struct hda_verb[]) { | 1945 | .v.verbs = (const struct hda_verb[]) { |
5303 | /* Enable all DACs */ | 1946 | /* Enable all DACs */ |
5304 | /* DAC DISABLE/MUTE 1? */ | 1947 | /* DAC DISABLE/MUTE 1? */ |
@@ -5332,31 +1975,31 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5332 | .chain_id = ALC882_FIXUP_GPIO1, | 1975 | .chain_id = ALC882_FIXUP_GPIO1, |
5333 | }, | 1976 | }, |
5334 | [ALC885_FIXUP_MACPRO_GPIO] = { | 1977 | [ALC885_FIXUP_MACPRO_GPIO] = { |
5335 | .type = ALC_FIXUP_FUNC, | 1978 | .type = HDA_FIXUP_FUNC, |
5336 | .v.func = alc885_fixup_macpro_gpio, | 1979 | .v.func = alc885_fixup_macpro_gpio, |
5337 | }, | 1980 | }, |
5338 | [ALC889_FIXUP_DAC_ROUTE] = { | 1981 | [ALC889_FIXUP_DAC_ROUTE] = { |
5339 | .type = ALC_FIXUP_FUNC, | 1982 | .type = HDA_FIXUP_FUNC, |
5340 | .v.func = alc889_fixup_dac_route, | 1983 | .v.func = alc889_fixup_dac_route, |
5341 | }, | 1984 | }, |
5342 | [ALC889_FIXUP_MBP_VREF] = { | 1985 | [ALC889_FIXUP_MBP_VREF] = { |
5343 | .type = ALC_FIXUP_FUNC, | 1986 | .type = HDA_FIXUP_FUNC, |
5344 | .v.func = alc889_fixup_mbp_vref, | 1987 | .v.func = alc889_fixup_mbp_vref, |
5345 | .chained = true, | 1988 | .chained = true, |
5346 | .chain_id = ALC882_FIXUP_GPIO1, | 1989 | .chain_id = ALC882_FIXUP_GPIO1, |
5347 | }, | 1990 | }, |
5348 | [ALC889_FIXUP_IMAC91_VREF] = { | 1991 | [ALC889_FIXUP_IMAC91_VREF] = { |
5349 | .type = ALC_FIXUP_FUNC, | 1992 | .type = HDA_FIXUP_FUNC, |
5350 | .v.func = alc889_fixup_imac91_vref, | 1993 | .v.func = alc889_fixup_imac91_vref, |
5351 | .chained = true, | 1994 | .chained = true, |
5352 | .chain_id = ALC882_FIXUP_GPIO1, | 1995 | .chain_id = ALC882_FIXUP_GPIO1, |
5353 | }, | 1996 | }, |
5354 | [ALC882_FIXUP_INV_DMIC] = { | 1997 | [ALC882_FIXUP_INV_DMIC] = { |
5355 | .type = ALC_FIXUP_FUNC, | 1998 | .type = HDA_FIXUP_FUNC, |
5356 | .v.func = alc_fixup_inv_dmic_0x12, | 1999 | .v.func = alc_fixup_inv_dmic_0x12, |
5357 | }, | 2000 | }, |
5358 | [ALC882_FIXUP_NO_PRIMARY_HP] = { | 2001 | [ALC882_FIXUP_NO_PRIMARY_HP] = { |
5359 | .type = ALC_FIXUP_FUNC, | 2002 | .type = HDA_FIXUP_FUNC, |
5360 | .v.func = alc882_fixup_no_primary_hp, | 2003 | .v.func = alc882_fixup_no_primary_hp, |
5361 | }, | 2004 | }, |
5362 | }; | 2005 | }; |
@@ -5431,7 +2074,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
5431 | {} | 2074 | {} |
5432 | }; | 2075 | }; |
5433 | 2076 | ||
5434 | static const struct alc_model_fixup alc882_fixup_models[] = { | 2077 | static const struct hda_model_fixup alc882_fixup_models[] = { |
5435 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 2078 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
5436 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 2079 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
5437 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 2080 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
@@ -5474,9 +2117,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
5474 | break; | 2117 | break; |
5475 | } | 2118 | } |
5476 | 2119 | ||
5477 | alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, | 2120 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, |
5478 | alc882_fixups); | 2121 | alc882_fixups); |
5479 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 2122 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5480 | 2123 | ||
5481 | alc_auto_parse_customize_define(codec); | 2124 | alc_auto_parse_customize_define(codec); |
5482 | 2125 | ||
@@ -5485,7 +2128,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
5485 | if (err < 0) | 2128 | if (err < 0) |
5486 | goto error; | 2129 | goto error; |
5487 | 2130 | ||
5488 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 2131 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { |
5489 | err = snd_hda_attach_beep_device(codec, 0x1); | 2132 | err = snd_hda_attach_beep_device(codec, 0x1); |
5490 | if (err < 0) | 2133 | if (err < 0) |
5491 | goto error; | 2134 | goto error; |
@@ -5494,7 +2137,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
5494 | 2137 | ||
5495 | codec->patch_ops = alc_patch_ops; | 2138 | codec->patch_ops = alc_patch_ops; |
5496 | 2139 | ||
5497 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 2140 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5498 | 2141 | ||
5499 | return 0; | 2142 | return 0; |
5500 | 2143 | ||
@@ -5519,6 +2162,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
5519 | */ | 2162 | */ |
5520 | enum { | 2163 | enum { |
5521 | ALC262_FIXUP_FSC_H270, | 2164 | ALC262_FIXUP_FSC_H270, |
2165 | ALC262_FIXUP_FSC_S7110, | ||
5522 | ALC262_FIXUP_HP_Z200, | 2166 | ALC262_FIXUP_HP_Z200, |
5523 | ALC262_FIXUP_TYAN, | 2167 | ALC262_FIXUP_TYAN, |
5524 | ALC262_FIXUP_LENOVO_3000, | 2168 | ALC262_FIXUP_LENOVO_3000, |
@@ -5527,41 +2171,50 @@ enum { | |||
5527 | ALC262_FIXUP_INV_DMIC, | 2171 | ALC262_FIXUP_INV_DMIC, |
5528 | }; | 2172 | }; |
5529 | 2173 | ||
5530 | static const struct alc_fixup alc262_fixups[] = { | 2174 | static const struct hda_fixup alc262_fixups[] = { |
5531 | [ALC262_FIXUP_FSC_H270] = { | 2175 | [ALC262_FIXUP_FSC_H270] = { |
5532 | .type = ALC_FIXUP_PINS, | 2176 | .type = HDA_FIXUP_PINS, |
5533 | .v.pins = (const struct alc_pincfg[]) { | 2177 | .v.pins = (const struct hda_pintbl[]) { |
5534 | { 0x14, 0x99130110 }, /* speaker */ | 2178 | { 0x14, 0x99130110 }, /* speaker */ |
5535 | { 0x15, 0x0221142f }, /* front HP */ | 2179 | { 0x15, 0x0221142f }, /* front HP */ |
5536 | { 0x1b, 0x0121141f }, /* rear HP */ | 2180 | { 0x1b, 0x0121141f }, /* rear HP */ |
5537 | { } | 2181 | { } |
5538 | } | 2182 | } |
5539 | }, | 2183 | }, |
2184 | [ALC262_FIXUP_FSC_S7110] = { | ||
2185 | .type = HDA_FIXUP_PINS, | ||
2186 | .v.pins = (const struct hda_pintbl[]) { | ||
2187 | { 0x15, 0x90170110 }, /* speaker */ | ||
2188 | { } | ||
2189 | }, | ||
2190 | .chained = true, | ||
2191 | .chain_id = ALC262_FIXUP_BENQ, | ||
2192 | }, | ||
5540 | [ALC262_FIXUP_HP_Z200] = { | 2193 | [ALC262_FIXUP_HP_Z200] = { |
5541 | .type = ALC_FIXUP_PINS, | 2194 | .type = HDA_FIXUP_PINS, |
5542 | .v.pins = (const struct alc_pincfg[]) { | 2195 | .v.pins = (const struct hda_pintbl[]) { |
5543 | { 0x16, 0x99130120 }, /* internal speaker */ | 2196 | { 0x16, 0x99130120 }, /* internal speaker */ |
5544 | { } | 2197 | { } |
5545 | } | 2198 | } |
5546 | }, | 2199 | }, |
5547 | [ALC262_FIXUP_TYAN] = { | 2200 | [ALC262_FIXUP_TYAN] = { |
5548 | .type = ALC_FIXUP_PINS, | 2201 | .type = HDA_FIXUP_PINS, |
5549 | .v.pins = (const struct alc_pincfg[]) { | 2202 | .v.pins = (const struct hda_pintbl[]) { |
5550 | { 0x14, 0x1993e1f0 }, /* int AUX */ | 2203 | { 0x14, 0x1993e1f0 }, /* int AUX */ |
5551 | { } | 2204 | { } |
5552 | } | 2205 | } |
5553 | }, | 2206 | }, |
5554 | [ALC262_FIXUP_LENOVO_3000] = { | 2207 | [ALC262_FIXUP_LENOVO_3000] = { |
5555 | .type = ALC_FIXUP_VERBS, | 2208 | .type = HDA_FIXUP_PINCTLS, |
5556 | .v.verbs = (const struct hda_verb[]) { | 2209 | .v.pins = (const struct hda_pintbl[]) { |
5557 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | 2210 | { 0x19, PIN_VREF50 }, |
5558 | {} | 2211 | {} |
5559 | }, | 2212 | }, |
5560 | .chained = true, | 2213 | .chained = true, |
5561 | .chain_id = ALC262_FIXUP_BENQ, | 2214 | .chain_id = ALC262_FIXUP_BENQ, |
5562 | }, | 2215 | }, |
5563 | [ALC262_FIXUP_BENQ] = { | 2216 | [ALC262_FIXUP_BENQ] = { |
5564 | .type = ALC_FIXUP_VERBS, | 2217 | .type = HDA_FIXUP_VERBS, |
5565 | .v.verbs = (const struct hda_verb[]) { | 2218 | .v.verbs = (const struct hda_verb[]) { |
5566 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2219 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
5567 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2220 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
@@ -5569,7 +2222,7 @@ static const struct alc_fixup alc262_fixups[] = { | |||
5569 | } | 2222 | } |
5570 | }, | 2223 | }, |
5571 | [ALC262_FIXUP_BENQ_T31] = { | 2224 | [ALC262_FIXUP_BENQ_T31] = { |
5572 | .type = ALC_FIXUP_VERBS, | 2225 | .type = HDA_FIXUP_VERBS, |
5573 | .v.verbs = (const struct hda_verb[]) { | 2226 | .v.verbs = (const struct hda_verb[]) { |
5574 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2227 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
5575 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2228 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
@@ -5577,14 +2230,14 @@ static const struct alc_fixup alc262_fixups[] = { | |||
5577 | } | 2230 | } |
5578 | }, | 2231 | }, |
5579 | [ALC262_FIXUP_INV_DMIC] = { | 2232 | [ALC262_FIXUP_INV_DMIC] = { |
5580 | .type = ALC_FIXUP_FUNC, | 2233 | .type = HDA_FIXUP_FUNC, |
5581 | .v.func = alc_fixup_inv_dmic_0x12, | 2234 | .v.func = alc_fixup_inv_dmic_0x12, |
5582 | }, | 2235 | }, |
5583 | }; | 2236 | }; |
5584 | 2237 | ||
5585 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 2238 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
5586 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), | 2239 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
5587 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), | 2240 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), |
5588 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 2241 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
5589 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 2242 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
5590 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 2243 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
@@ -5594,7 +2247,7 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
5594 | {} | 2247 | {} |
5595 | }; | 2248 | }; |
5596 | 2249 | ||
5597 | static const struct alc_model_fixup alc262_fixup_models[] = { | 2250 | static const struct hda_model_fixup alc262_fixup_models[] = { |
5598 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2251 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
5599 | {} | 2252 | {} |
5600 | }; | 2253 | }; |
@@ -5611,6 +2264,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
5611 | return err; | 2264 | return err; |
5612 | 2265 | ||
5613 | spec = codec->spec; | 2266 | spec = codec->spec; |
2267 | spec->gen.shared_mic_vref_pin = 0x18; | ||
5614 | 2268 | ||
5615 | #if 0 | 2269 | #if 0 |
5616 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is | 2270 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
@@ -5626,9 +2280,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
5626 | #endif | 2280 | #endif |
5627 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2281 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
5628 | 2282 | ||
5629 | alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, | 2283 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
5630 | alc262_fixups); | 2284 | alc262_fixups); |
5631 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 2285 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5632 | 2286 | ||
5633 | alc_auto_parse_customize_define(codec); | 2287 | alc_auto_parse_customize_define(codec); |
5634 | 2288 | ||
@@ -5637,7 +2291,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
5637 | if (err < 0) | 2291 | if (err < 0) |
5638 | goto error; | 2292 | goto error; |
5639 | 2293 | ||
5640 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 2294 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { |
5641 | err = snd_hda_attach_beep_device(codec, 0x1); | 2295 | err = snd_hda_attach_beep_device(codec, 0x1); |
5642 | if (err < 0) | 2296 | if (err < 0) |
5643 | goto error; | 2297 | goto error; |
@@ -5647,7 +2301,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
5647 | codec->patch_ops = alc_patch_ops; | 2301 | codec->patch_ops = alc_patch_ops; |
5648 | spec->shutup = alc_eapd_shutup; | 2302 | spec->shutup = alc_eapd_shutup; |
5649 | 2303 | ||
5650 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 2304 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5651 | 2305 | ||
5652 | return 0; | 2306 | return 0; |
5653 | 2307 | ||
@@ -5688,13 +2342,13 @@ enum { | |||
5688 | ALC268_FIXUP_HP_EAPD, | 2342 | ALC268_FIXUP_HP_EAPD, |
5689 | }; | 2343 | }; |
5690 | 2344 | ||
5691 | static const struct alc_fixup alc268_fixups[] = { | 2345 | static const struct hda_fixup alc268_fixups[] = { |
5692 | [ALC268_FIXUP_INV_DMIC] = { | 2346 | [ALC268_FIXUP_INV_DMIC] = { |
5693 | .type = ALC_FIXUP_FUNC, | 2347 | .type = HDA_FIXUP_FUNC, |
5694 | .v.func = alc_fixup_inv_dmic_0x12, | 2348 | .v.func = alc_fixup_inv_dmic_0x12, |
5695 | }, | 2349 | }, |
5696 | [ALC268_FIXUP_HP_EAPD] = { | 2350 | [ALC268_FIXUP_HP_EAPD] = { |
5697 | .type = ALC_FIXUP_VERBS, | 2351 | .type = HDA_FIXUP_VERBS, |
5698 | .v.verbs = (const struct hda_verb[]) { | 2352 | .v.verbs = (const struct hda_verb[]) { |
5699 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 2353 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
5700 | {} | 2354 | {} |
@@ -5702,7 +2356,7 @@ static const struct alc_fixup alc268_fixups[] = { | |||
5702 | }, | 2356 | }, |
5703 | }; | 2357 | }; |
5704 | 2358 | ||
5705 | static const struct alc_model_fixup alc268_fixup_models[] = { | 2359 | static const struct hda_model_fixup alc268_fixup_models[] = { |
5706 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2360 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
5707 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, | 2361 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, |
5708 | {} | 2362 | {} |
@@ -5726,9 +2380,10 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
5726 | struct alc_spec *spec = codec->spec; | 2380 | struct alc_spec *spec = codec->spec; |
5727 | int err = alc_parse_auto_config(codec, NULL, alc268_ssids); | 2381 | int err = alc_parse_auto_config(codec, NULL, alc268_ssids); |
5728 | if (err > 0) { | 2382 | if (err > 0) { |
5729 | if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) { | 2383 | if (!spec->gen.no_analog && |
2384 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { | ||
5730 | add_mixer(spec, alc268_beep_mixer); | 2385 | add_mixer(spec, alc268_beep_mixer); |
5731 | snd_hda_gen_add_verbs(&spec->gen, alc268_beep_init_verbs); | 2386 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); |
5732 | } | 2387 | } |
5733 | } | 2388 | } |
5734 | return err; | 2389 | return err; |
@@ -5748,8 +2403,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
5748 | 2403 | ||
5749 | spec = codec->spec; | 2404 | spec = codec->spec; |
5750 | 2405 | ||
5751 | alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); | 2406 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); |
5752 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 2407 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5753 | 2408 | ||
5754 | /* automatic parse from the BIOS config */ | 2409 | /* automatic parse from the BIOS config */ |
5755 | err = alc268_parse_auto_config(codec); | 2410 | err = alc268_parse_auto_config(codec); |
@@ -5780,7 +2435,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
5780 | codec->patch_ops = alc_patch_ops; | 2435 | codec->patch_ops = alc_patch_ops; |
5781 | spec->shutup = alc_eapd_shutup; | 2436 | spec->shutup = alc_eapd_shutup; |
5782 | 2437 | ||
5783 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 2438 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5784 | 2439 | ||
5785 | return 0; | 2440 | return 0; |
5786 | 2441 | ||
@@ -5792,6 +2447,35 @@ static int patch_alc268(struct hda_codec *codec) | |||
5792 | /* | 2447 | /* |
5793 | * ALC269 | 2448 | * ALC269 |
5794 | */ | 2449 | */ |
2450 | |||
2451 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
2452 | struct hda_codec *codec, | ||
2453 | struct snd_pcm_substream *substream) | ||
2454 | { | ||
2455 | struct hda_gen_spec *spec = codec->spec; | ||
2456 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
2457 | hinfo); | ||
2458 | } | ||
2459 | |||
2460 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2461 | struct hda_codec *codec, | ||
2462 | unsigned int stream_tag, | ||
2463 | unsigned int format, | ||
2464 | struct snd_pcm_substream *substream) | ||
2465 | { | ||
2466 | struct hda_gen_spec *spec = codec->spec; | ||
2467 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | ||
2468 | stream_tag, format, substream); | ||
2469 | } | ||
2470 | |||
2471 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2472 | struct hda_codec *codec, | ||
2473 | struct snd_pcm_substream *substream) | ||
2474 | { | ||
2475 | struct hda_gen_spec *spec = codec->spec; | ||
2476 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
2477 | } | ||
2478 | |||
5795 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 2479 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
5796 | .substreams = 1, | 2480 | .substreams = 1, |
5797 | .channels_min = 2, | 2481 | .channels_min = 2, |
@@ -5799,9 +2483,9 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | |||
5799 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2483 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
5800 | /* NID is set in alc_build_pcms */ | 2484 | /* NID is set in alc_build_pcms */ |
5801 | .ops = { | 2485 | .ops = { |
5802 | .open = alc_playback_pcm_open, | 2486 | .open = playback_pcm_open, |
5803 | .prepare = alc_playback_pcm_prepare, | 2487 | .prepare = playback_pcm_prepare, |
5804 | .cleanup = alc_playback_pcm_cleanup | 2488 | .cleanup = playback_pcm_cleanup |
5805 | }, | 2489 | }, |
5806 | }; | 2490 | }; |
5807 | 2491 | ||
@@ -5909,27 +2593,27 @@ static int alc269_resume(struct hda_codec *codec) | |||
5909 | #endif /* CONFIG_PM */ | 2593 | #endif /* CONFIG_PM */ |
5910 | 2594 | ||
5911 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, | 2595 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, |
5912 | const struct alc_fixup *fix, int action) | 2596 | const struct hda_fixup *fix, int action) |
5913 | { | 2597 | { |
5914 | struct alc_spec *spec = codec->spec; | 2598 | struct alc_spec *spec = codec->spec; |
5915 | 2599 | ||
5916 | if (action == ALC_FIXUP_ACT_PRE_PROBE) | 2600 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
5917 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 2601 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
5918 | } | 2602 | } |
5919 | 2603 | ||
5920 | static void alc269_fixup_hweq(struct hda_codec *codec, | 2604 | static void alc269_fixup_hweq(struct hda_codec *codec, |
5921 | const struct alc_fixup *fix, int action) | 2605 | const struct hda_fixup *fix, int action) |
5922 | { | 2606 | { |
5923 | int coef; | 2607 | int coef; |
5924 | 2608 | ||
5925 | if (action != ALC_FIXUP_ACT_INIT) | 2609 | if (action != HDA_FIXUP_ACT_INIT) |
5926 | return; | 2610 | return; |
5927 | coef = alc_read_coef_idx(codec, 0x1e); | 2611 | coef = alc_read_coef_idx(codec, 0x1e); |
5928 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); | 2612 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); |
5929 | } | 2613 | } |
5930 | 2614 | ||
5931 | static void alc271_fixup_dmic(struct hda_codec *codec, | 2615 | static void alc271_fixup_dmic(struct hda_codec *codec, |
5932 | const struct alc_fixup *fix, int action) | 2616 | const struct hda_fixup *fix, int action) |
5933 | { | 2617 | { |
5934 | static const struct hda_verb verbs[] = { | 2618 | static const struct hda_verb verbs[] = { |
5935 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | 2619 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, |
@@ -5946,26 +2630,26 @@ static void alc271_fixup_dmic(struct hda_codec *codec, | |||
5946 | } | 2630 | } |
5947 | 2631 | ||
5948 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, | 2632 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, |
5949 | const struct alc_fixup *fix, int action) | 2633 | const struct hda_fixup *fix, int action) |
5950 | { | 2634 | { |
5951 | struct alc_spec *spec = codec->spec; | 2635 | struct alc_spec *spec = codec->spec; |
5952 | 2636 | ||
5953 | if (action != ALC_FIXUP_ACT_PROBE) | 2637 | if (action != HDA_FIXUP_ACT_PROBE) |
5954 | return; | 2638 | return; |
5955 | 2639 | ||
5956 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 2640 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
5957 | * fix the sample rate of analog I/O to 44.1kHz | 2641 | * fix the sample rate of analog I/O to 44.1kHz |
5958 | */ | 2642 | */ |
5959 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; | 2643 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; |
5960 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; | 2644 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; |
5961 | } | 2645 | } |
5962 | 2646 | ||
5963 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | 2647 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, |
5964 | const struct alc_fixup *fix, int action) | 2648 | const struct hda_fixup *fix, int action) |
5965 | { | 2649 | { |
5966 | int coef; | 2650 | int coef; |
5967 | 2651 | ||
5968 | if (action != ALC_FIXUP_ACT_INIT) | 2652 | if (action != HDA_FIXUP_ACT_INIT) |
5969 | return; | 2653 | return; |
5970 | /* The digital-mic unit sends PDM (differential signal) instead of | 2654 | /* The digital-mic unit sends PDM (differential signal) instead of |
5971 | * the standard PCM, thus you can't record a valid mono stream as is. | 2655 | * the standard PCM, thus you can't record a valid mono stream as is. |
@@ -5978,7 +2662,7 @@ static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | |||
5978 | 2662 | ||
5979 | static void alc269_quanta_automute(struct hda_codec *codec) | 2663 | static void alc269_quanta_automute(struct hda_codec *codec) |
5980 | { | 2664 | { |
5981 | update_outputs(codec); | 2665 | snd_hda_gen_update_outputs(codec); |
5982 | 2666 | ||
5983 | snd_hda_codec_write(codec, 0x20, 0, | 2667 | snd_hda_codec_write(codec, 0x20, 0, |
5984 | AC_VERB_SET_COEF_INDEX, 0x0c); | 2668 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -5992,70 +2676,79 @@ static void alc269_quanta_automute(struct hda_codec *codec) | |||
5992 | } | 2676 | } |
5993 | 2677 | ||
5994 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, | 2678 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, |
5995 | const struct alc_fixup *fix, int action) | 2679 | const struct hda_fixup *fix, int action) |
5996 | { | 2680 | { |
5997 | struct alc_spec *spec = codec->spec; | 2681 | struct alc_spec *spec = codec->spec; |
5998 | if (action != ALC_FIXUP_ACT_PROBE) | 2682 | if (action != HDA_FIXUP_ACT_PROBE) |
5999 | return; | 2683 | return; |
6000 | spec->automute_hook = alc269_quanta_automute; | 2684 | spec->gen.automute_hook = alc269_quanta_automute; |
6001 | } | 2685 | } |
6002 | 2686 | ||
6003 | /* update mute-LED according to the speaker mute state via mic1 VREF pin */ | 2687 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
6004 | static void alc269_fixup_mic1_mute_hook(void *private_data, int enabled) | 2688 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
6005 | { | 2689 | { |
6006 | struct hda_codec *codec = private_data; | 2690 | struct hda_codec *codec = private_data; |
6007 | unsigned int pinval = AC_PINCTL_IN_EN + (enabled ? | 2691 | struct alc_spec *spec = codec->spec; |
6008 | AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); | 2692 | unsigned int pinval; |
6009 | snd_hda_set_pin_ctl_cache(codec, 0x18, pinval); | 2693 | |
2694 | if (spec->mute_led_polarity) | ||
2695 | enabled = !enabled; | ||
2696 | pinval = AC_PINCTL_IN_EN | | ||
2697 | (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); | ||
2698 | if (spec->mute_led_nid) | ||
2699 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); | ||
6010 | } | 2700 | } |
6011 | 2701 | ||
6012 | static void alc269_fixup_mic1_mute(struct hda_codec *codec, | 2702 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, |
6013 | const struct alc_fixup *fix, int action) | 2703 | const struct hda_fixup *fix, int action) |
6014 | { | 2704 | { |
6015 | struct alc_spec *spec = codec->spec; | 2705 | struct alc_spec *spec = codec->spec; |
6016 | switch (action) { | 2706 | const struct dmi_device *dev = NULL; |
6017 | case ALC_FIXUP_ACT_BUILD: | 2707 | |
6018 | spec->vmaster_mute.hook = alc269_fixup_mic1_mute_hook; | 2708 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
6019 | snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); | 2709 | return; |
6020 | /* fallthru */ | 2710 | |
6021 | case ALC_FIXUP_ACT_INIT: | 2711 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { |
6022 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | 2712 | int pol, pin; |
2713 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) | ||
2714 | continue; | ||
2715 | if (pin < 0x0a || pin >= 0x10) | ||
2716 | break; | ||
2717 | spec->mute_led_polarity = pol; | ||
2718 | spec->mute_led_nid = pin - 0x0a + 0x18; | ||
2719 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | ||
2720 | spec->gen.vmaster_mute_enum = 1; | ||
2721 | snd_printd("Detected mute LED for %x:%d\n", spec->mute_led_nid, | ||
2722 | spec->mute_led_polarity); | ||
6023 | break; | 2723 | break; |
6024 | } | 2724 | } |
6025 | } | 2725 | } |
6026 | 2726 | ||
6027 | /* update mute-LED according to the speaker mute state via mic2 VREF pin */ | 2727 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, |
6028 | static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled) | 2728 | const struct hda_fixup *fix, int action) |
6029 | { | ||
6030 | struct hda_codec *codec = private_data; | ||
6031 | unsigned int pinval = enabled ? 0x20 : 0x24; | ||
6032 | snd_hda_set_pin_ctl_cache(codec, 0x19, pinval); | ||
6033 | } | ||
6034 | |||
6035 | static void alc269_fixup_mic2_mute(struct hda_codec *codec, | ||
6036 | const struct alc_fixup *fix, int action) | ||
6037 | { | 2729 | { |
6038 | struct alc_spec *spec = codec->spec; | 2730 | struct alc_spec *spec = codec->spec; |
6039 | switch (action) { | 2731 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
6040 | case ALC_FIXUP_ACT_BUILD: | 2732 | spec->mute_led_polarity = 0; |
6041 | spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook; | 2733 | spec->mute_led_nid = 0x19; |
6042 | snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); | 2734 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
6043 | /* fallthru */ | 2735 | spec->gen.vmaster_mute_enum = 1; |
6044 | case ALC_FIXUP_ACT_INIT: | ||
6045 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
6046 | break; | ||
6047 | } | 2736 | } |
6048 | } | 2737 | } |
6049 | 2738 | ||
6050 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 2739 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
6051 | const struct alc_fixup *fix, | 2740 | const struct hda_fixup *fix, |
6052 | int action) | 2741 | int action) |
6053 | { | 2742 | { |
6054 | struct alc_spec *spec = codec->spec; | 2743 | struct alc_spec *spec = codec->spec; |
6055 | 2744 | ||
6056 | if (action == ALC_FIXUP_ACT_PROBE) | 2745 | if (action == HDA_FIXUP_ACT_PROBE) { |
6057 | snd_hda_jack_set_gating_jack(codec, spec->ext_mic_pin, | 2746 | if (snd_BUG_ON(!spec->gen.am_entry[1].pin || |
6058 | spec->autocfg.hp_pins[0]); | 2747 | !spec->gen.autocfg.hp_pins[0])) |
2748 | return; | ||
2749 | snd_hda_jack_set_gating_jack(codec, spec->gen.am_entry[1].pin, | ||
2750 | spec->gen.autocfg.hp_pins[0]); | ||
2751 | } | ||
6059 | } | 2752 | } |
6060 | 2753 | ||
6061 | enum { | 2754 | enum { |
@@ -6075,8 +2768,8 @@ enum { | |||
6075 | ALC269_FIXUP_DMIC, | 2768 | ALC269_FIXUP_DMIC, |
6076 | ALC269VB_FIXUP_AMIC, | 2769 | ALC269VB_FIXUP_AMIC, |
6077 | ALC269VB_FIXUP_DMIC, | 2770 | ALC269VB_FIXUP_DMIC, |
6078 | ALC269_FIXUP_MIC1_MUTE_LED, | 2771 | ALC269_FIXUP_HP_MUTE_LED, |
6079 | ALC269_FIXUP_MIC2_MUTE_LED, | 2772 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
6080 | ALC269_FIXUP_INV_DMIC, | 2773 | ALC269_FIXUP_INV_DMIC, |
6081 | ALC269_FIXUP_LENOVO_DOCK, | 2774 | ALC269_FIXUP_LENOVO_DOCK, |
6082 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 2775 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
@@ -6084,16 +2777,16 @@ enum { | |||
6084 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 2777 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
6085 | }; | 2778 | }; |
6086 | 2779 | ||
6087 | static const struct alc_fixup alc269_fixups[] = { | 2780 | static const struct hda_fixup alc269_fixups[] = { |
6088 | [ALC269_FIXUP_SONY_VAIO] = { | 2781 | [ALC269_FIXUP_SONY_VAIO] = { |
6089 | .type = ALC_FIXUP_VERBS, | 2782 | .type = HDA_FIXUP_PINCTLS, |
6090 | .v.verbs = (const struct hda_verb[]) { | 2783 | .v.pins = (const struct hda_pintbl[]) { |
6091 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, | 2784 | {0x19, PIN_VREFGRD}, |
6092 | {} | 2785 | {} |
6093 | } | 2786 | } |
6094 | }, | 2787 | }, |
6095 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { | 2788 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { |
6096 | .type = ALC_FIXUP_VERBS, | 2789 | .type = HDA_FIXUP_VERBS, |
6097 | .v.verbs = (const struct hda_verb[]) { | 2790 | .v.verbs = (const struct hda_verb[]) { |
6098 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, | 2791 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, |
6099 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, | 2792 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, |
@@ -6104,7 +2797,7 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6104 | .chain_id = ALC269_FIXUP_SONY_VAIO | 2797 | .chain_id = ALC269_FIXUP_SONY_VAIO |
6105 | }, | 2798 | }, |
6106 | [ALC269_FIXUP_DELL_M101Z] = { | 2799 | [ALC269_FIXUP_DELL_M101Z] = { |
6107 | .type = ALC_FIXUP_VERBS, | 2800 | .type = HDA_FIXUP_VERBS, |
6108 | .v.verbs = (const struct hda_verb[]) { | 2801 | .v.verbs = (const struct hda_verb[]) { |
6109 | /* Enables internal speaker */ | 2802 | /* Enables internal speaker */ |
6110 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, | 2803 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, |
@@ -6113,50 +2806,50 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6113 | } | 2806 | } |
6114 | }, | 2807 | }, |
6115 | [ALC269_FIXUP_SKU_IGNORE] = { | 2808 | [ALC269_FIXUP_SKU_IGNORE] = { |
6116 | .type = ALC_FIXUP_FUNC, | 2809 | .type = HDA_FIXUP_FUNC, |
6117 | .v.func = alc_fixup_sku_ignore, | 2810 | .v.func = alc_fixup_sku_ignore, |
6118 | }, | 2811 | }, |
6119 | [ALC269_FIXUP_ASUS_G73JW] = { | 2812 | [ALC269_FIXUP_ASUS_G73JW] = { |
6120 | .type = ALC_FIXUP_PINS, | 2813 | .type = HDA_FIXUP_PINS, |
6121 | .v.pins = (const struct alc_pincfg[]) { | 2814 | .v.pins = (const struct hda_pintbl[]) { |
6122 | { 0x17, 0x99130111 }, /* subwoofer */ | 2815 | { 0x17, 0x99130111 }, /* subwoofer */ |
6123 | { } | 2816 | { } |
6124 | } | 2817 | } |
6125 | }, | 2818 | }, |
6126 | [ALC269_FIXUP_LENOVO_EAPD] = { | 2819 | [ALC269_FIXUP_LENOVO_EAPD] = { |
6127 | .type = ALC_FIXUP_VERBS, | 2820 | .type = HDA_FIXUP_VERBS, |
6128 | .v.verbs = (const struct hda_verb[]) { | 2821 | .v.verbs = (const struct hda_verb[]) { |
6129 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 2822 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
6130 | {} | 2823 | {} |
6131 | } | 2824 | } |
6132 | }, | 2825 | }, |
6133 | [ALC275_FIXUP_SONY_HWEQ] = { | 2826 | [ALC275_FIXUP_SONY_HWEQ] = { |
6134 | .type = ALC_FIXUP_FUNC, | 2827 | .type = HDA_FIXUP_FUNC, |
6135 | .v.func = alc269_fixup_hweq, | 2828 | .v.func = alc269_fixup_hweq, |
6136 | .chained = true, | 2829 | .chained = true, |
6137 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 2830 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
6138 | }, | 2831 | }, |
6139 | [ALC271_FIXUP_DMIC] = { | 2832 | [ALC271_FIXUP_DMIC] = { |
6140 | .type = ALC_FIXUP_FUNC, | 2833 | .type = HDA_FIXUP_FUNC, |
6141 | .v.func = alc271_fixup_dmic, | 2834 | .v.func = alc271_fixup_dmic, |
6142 | }, | 2835 | }, |
6143 | [ALC269_FIXUP_PCM_44K] = { | 2836 | [ALC269_FIXUP_PCM_44K] = { |
6144 | .type = ALC_FIXUP_FUNC, | 2837 | .type = HDA_FIXUP_FUNC, |
6145 | .v.func = alc269_fixup_pcm_44k, | 2838 | .v.func = alc269_fixup_pcm_44k, |
6146 | .chained = true, | 2839 | .chained = true, |
6147 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 2840 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
6148 | }, | 2841 | }, |
6149 | [ALC269_FIXUP_STEREO_DMIC] = { | 2842 | [ALC269_FIXUP_STEREO_DMIC] = { |
6150 | .type = ALC_FIXUP_FUNC, | 2843 | .type = HDA_FIXUP_FUNC, |
6151 | .v.func = alc269_fixup_stereo_dmic, | 2844 | .v.func = alc269_fixup_stereo_dmic, |
6152 | }, | 2845 | }, |
6153 | [ALC269_FIXUP_QUANTA_MUTE] = { | 2846 | [ALC269_FIXUP_QUANTA_MUTE] = { |
6154 | .type = ALC_FIXUP_FUNC, | 2847 | .type = HDA_FIXUP_FUNC, |
6155 | .v.func = alc269_fixup_quanta_mute, | 2848 | .v.func = alc269_fixup_quanta_mute, |
6156 | }, | 2849 | }, |
6157 | [ALC269_FIXUP_LIFEBOOK] = { | 2850 | [ALC269_FIXUP_LIFEBOOK] = { |
6158 | .type = ALC_FIXUP_PINS, | 2851 | .type = HDA_FIXUP_PINS, |
6159 | .v.pins = (const struct alc_pincfg[]) { | 2852 | .v.pins = (const struct hda_pintbl[]) { |
6160 | { 0x1a, 0x2101103f }, /* dock line-out */ | 2853 | { 0x1a, 0x2101103f }, /* dock line-out */ |
6161 | { 0x1b, 0x23a11040 }, /* dock mic-in */ | 2854 | { 0x1b, 0x23a11040 }, /* dock mic-in */ |
6162 | { } | 2855 | { } |
@@ -6165,8 +2858,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6165 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 2858 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
6166 | }, | 2859 | }, |
6167 | [ALC269_FIXUP_AMIC] = { | 2860 | [ALC269_FIXUP_AMIC] = { |
6168 | .type = ALC_FIXUP_PINS, | 2861 | .type = HDA_FIXUP_PINS, |
6169 | .v.pins = (const struct alc_pincfg[]) { | 2862 | .v.pins = (const struct hda_pintbl[]) { |
6170 | { 0x14, 0x99130110 }, /* speaker */ | 2863 | { 0x14, 0x99130110 }, /* speaker */ |
6171 | { 0x15, 0x0121401f }, /* HP out */ | 2864 | { 0x15, 0x0121401f }, /* HP out */ |
6172 | { 0x18, 0x01a19c20 }, /* mic */ | 2865 | { 0x18, 0x01a19c20 }, /* mic */ |
@@ -6175,8 +2868,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6175 | }, | 2868 | }, |
6176 | }, | 2869 | }, |
6177 | [ALC269_FIXUP_DMIC] = { | 2870 | [ALC269_FIXUP_DMIC] = { |
6178 | .type = ALC_FIXUP_PINS, | 2871 | .type = HDA_FIXUP_PINS, |
6179 | .v.pins = (const struct alc_pincfg[]) { | 2872 | .v.pins = (const struct hda_pintbl[]) { |
6180 | { 0x12, 0x99a3092f }, /* int-mic */ | 2873 | { 0x12, 0x99a3092f }, /* int-mic */ |
6181 | { 0x14, 0x99130110 }, /* speaker */ | 2874 | { 0x14, 0x99130110 }, /* speaker */ |
6182 | { 0x15, 0x0121401f }, /* HP out */ | 2875 | { 0x15, 0x0121401f }, /* HP out */ |
@@ -6185,8 +2878,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6185 | }, | 2878 | }, |
6186 | }, | 2879 | }, |
6187 | [ALC269VB_FIXUP_AMIC] = { | 2880 | [ALC269VB_FIXUP_AMIC] = { |
6188 | .type = ALC_FIXUP_PINS, | 2881 | .type = HDA_FIXUP_PINS, |
6189 | .v.pins = (const struct alc_pincfg[]) { | 2882 | .v.pins = (const struct hda_pintbl[]) { |
6190 | { 0x14, 0x99130110 }, /* speaker */ | 2883 | { 0x14, 0x99130110 }, /* speaker */ |
6191 | { 0x18, 0x01a19c20 }, /* mic */ | 2884 | { 0x18, 0x01a19c20 }, /* mic */ |
6192 | { 0x19, 0x99a3092f }, /* int-mic */ | 2885 | { 0x19, 0x99a3092f }, /* int-mic */ |
@@ -6195,8 +2888,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6195 | }, | 2888 | }, |
6196 | }, | 2889 | }, |
6197 | [ALC269VB_FIXUP_DMIC] = { | 2890 | [ALC269VB_FIXUP_DMIC] = { |
6198 | .type = ALC_FIXUP_PINS, | 2891 | .type = HDA_FIXUP_PINS, |
6199 | .v.pins = (const struct alc_pincfg[]) { | 2892 | .v.pins = (const struct hda_pintbl[]) { |
6200 | { 0x12, 0x99a3092f }, /* int-mic */ | 2893 | { 0x12, 0x99a3092f }, /* int-mic */ |
6201 | { 0x14, 0x99130110 }, /* speaker */ | 2894 | { 0x14, 0x99130110 }, /* speaker */ |
6202 | { 0x18, 0x01a19c20 }, /* mic */ | 2895 | { 0x18, 0x01a19c20 }, /* mic */ |
@@ -6204,21 +2897,21 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6204 | { } | 2897 | { } |
6205 | }, | 2898 | }, |
6206 | }, | 2899 | }, |
6207 | [ALC269_FIXUP_MIC1_MUTE_LED] = { | 2900 | [ALC269_FIXUP_HP_MUTE_LED] = { |
6208 | .type = ALC_FIXUP_FUNC, | 2901 | .type = HDA_FIXUP_FUNC, |
6209 | .v.func = alc269_fixup_mic1_mute, | 2902 | .v.func = alc269_fixup_hp_mute_led, |
6210 | }, | 2903 | }, |
6211 | [ALC269_FIXUP_MIC2_MUTE_LED] = { | 2904 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { |
6212 | .type = ALC_FIXUP_FUNC, | 2905 | .type = HDA_FIXUP_FUNC, |
6213 | .v.func = alc269_fixup_mic2_mute, | 2906 | .v.func = alc269_fixup_hp_mute_led_mic2, |
6214 | }, | 2907 | }, |
6215 | [ALC269_FIXUP_INV_DMIC] = { | 2908 | [ALC269_FIXUP_INV_DMIC] = { |
6216 | .type = ALC_FIXUP_FUNC, | 2909 | .type = HDA_FIXUP_FUNC, |
6217 | .v.func = alc_fixup_inv_dmic_0x12, | 2910 | .v.func = alc_fixup_inv_dmic_0x12, |
6218 | }, | 2911 | }, |
6219 | [ALC269_FIXUP_LENOVO_DOCK] = { | 2912 | [ALC269_FIXUP_LENOVO_DOCK] = { |
6220 | .type = ALC_FIXUP_PINS, | 2913 | .type = HDA_FIXUP_PINS, |
6221 | .v.pins = (const struct alc_pincfg[]) { | 2914 | .v.pins = (const struct hda_pintbl[]) { |
6222 | { 0x19, 0x23a11040 }, /* dock mic */ | 2915 | { 0x19, 0x23a11040 }, /* dock mic */ |
6223 | { 0x1b, 0x2121103f }, /* dock headphone */ | 2916 | { 0x1b, 0x2121103f }, /* dock headphone */ |
6224 | { } | 2917 | { } |
@@ -6227,12 +2920,12 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6227 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT | 2920 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT |
6228 | }, | 2921 | }, |
6229 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { | 2922 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { |
6230 | .type = ALC_FIXUP_FUNC, | 2923 | .type = HDA_FIXUP_FUNC, |
6231 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 2924 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
6232 | }, | 2925 | }, |
6233 | [ALC271_FIXUP_AMIC_MIC2] = { | 2926 | [ALC271_FIXUP_AMIC_MIC2] = { |
6234 | .type = ALC_FIXUP_PINS, | 2927 | .type = HDA_FIXUP_PINS, |
6235 | .v.pins = (const struct alc_pincfg[]) { | 2928 | .v.pins = (const struct hda_pintbl[]) { |
6236 | { 0x14, 0x99130110 }, /* speaker */ | 2929 | { 0x14, 0x99130110 }, /* speaker */ |
6237 | { 0x19, 0x01a19c20 }, /* mic */ | 2930 | { 0x19, 0x01a19c20 }, /* mic */ |
6238 | { 0x1b, 0x99a7012f }, /* int-mic */ | 2931 | { 0x1b, 0x99a7012f }, /* int-mic */ |
@@ -6241,7 +2934,7 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6241 | }, | 2934 | }, |
6242 | }, | 2935 | }, |
6243 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { | 2936 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { |
6244 | .type = ALC_FIXUP_FUNC, | 2937 | .type = HDA_FIXUP_FUNC, |
6245 | .v.func = alc271_hp_gate_mic_jack, | 2938 | .v.func = alc271_hp_gate_mic_jack, |
6246 | .chained = true, | 2939 | .chained = true, |
6247 | .chain_id = ALC271_FIXUP_AMIC_MIC2, | 2940 | .chain_id = ALC271_FIXUP_AMIC_MIC2, |
@@ -6251,9 +2944,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6251 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 2944 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
6252 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 2945 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
6253 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 2946 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
6254 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), | 2947 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
6255 | SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED), | 2948 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
6256 | SND_PCI_QUIRK(0x103c, 0x1977, "HP Pavilion 14", ALC269_FIXUP_MIC1_MUTE_LED), | ||
6257 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), | 2949 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), |
6258 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), | 2950 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), |
6259 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 2951 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
@@ -6336,7 +3028,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6336 | {} | 3028 | {} |
6337 | }; | 3029 | }; |
6338 | 3030 | ||
6339 | static const struct alc_model_fixup alc269_fixup_models[] = { | 3031 | static const struct hda_model_fixup alc269_fixup_models[] = { |
6340 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 3032 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
6341 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 3033 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
6342 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | 3034 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, |
@@ -6403,10 +3095,11 @@ static int patch_alc269(struct hda_codec *codec) | |||
6403 | return err; | 3095 | return err; |
6404 | 3096 | ||
6405 | spec = codec->spec; | 3097 | spec = codec->spec; |
3098 | spec->gen.shared_mic_vref_pin = 0x18; | ||
6406 | 3099 | ||
6407 | alc_pick_fixup(codec, alc269_fixup_models, | 3100 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
6408 | alc269_fixup_tbl, alc269_fixups); | 3101 | alc269_fixup_tbl, alc269_fixups); |
6409 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 3102 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6410 | 3103 | ||
6411 | alc_auto_parse_customize_define(codec); | 3104 | alc_auto_parse_customize_define(codec); |
6412 | 3105 | ||
@@ -6457,7 +3150,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
6457 | if (err < 0) | 3150 | if (err < 0) |
6458 | goto error; | 3151 | goto error; |
6459 | 3152 | ||
6460 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 3153 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { |
6461 | err = snd_hda_attach_beep_device(codec, 0x1); | 3154 | err = snd_hda_attach_beep_device(codec, 0x1); |
6462 | if (err < 0) | 3155 | if (err < 0) |
6463 | goto error; | 3156 | goto error; |
@@ -6470,7 +3163,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
6470 | #endif | 3163 | #endif |
6471 | spec->shutup = alc269_shutup; | 3164 | spec->shutup = alc269_shutup; |
6472 | 3165 | ||
6473 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 3166 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
6474 | 3167 | ||
6475 | return 0; | 3168 | return 0; |
6476 | 3169 | ||
@@ -6500,49 +3193,48 @@ enum { | |||
6500 | 3193 | ||
6501 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | 3194 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ |
6502 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | 3195 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, |
6503 | const struct alc_fixup *fix, int action) | 3196 | const struct hda_fixup *fix, int action) |
6504 | { | 3197 | { |
6505 | struct alc_spec *spec = codec->spec; | 3198 | struct alc_spec *spec = codec->spec; |
6506 | unsigned int val; | 3199 | unsigned int val; |
6507 | 3200 | ||
6508 | if (action != ALC_FIXUP_ACT_INIT) | 3201 | if (action != HDA_FIXUP_ACT_INIT) |
6509 | return; | 3202 | return; |
6510 | val = snd_hda_codec_read(codec, 0x0f, 0, | 3203 | val = snd_hda_codec_get_pin_target(codec, 0x0f); |
6511 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
6512 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | 3204 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) |
6513 | val |= AC_PINCTL_IN_EN; | 3205 | val |= AC_PINCTL_IN_EN; |
6514 | val |= AC_PINCTL_VREF_50; | 3206 | val |= AC_PINCTL_VREF_50; |
6515 | snd_hda_set_pin_ctl(codec, 0x0f, val); | 3207 | snd_hda_set_pin_ctl(codec, 0x0f, val); |
6516 | spec->keep_vref_in_automute = 1; | 3208 | spec->gen.keep_vref_in_automute = 1; |
6517 | } | 3209 | } |
6518 | 3210 | ||
6519 | /* suppress the jack-detection */ | 3211 | /* suppress the jack-detection */ |
6520 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | 3212 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, |
6521 | const struct alc_fixup *fix, int action) | 3213 | const struct hda_fixup *fix, int action) |
6522 | { | 3214 | { |
6523 | if (action == ALC_FIXUP_ACT_PRE_PROBE) | 3215 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
6524 | codec->no_jack_detect = 1; | 3216 | codec->no_jack_detect = 1; |
6525 | } | 3217 | } |
6526 | 3218 | ||
6527 | static const struct alc_fixup alc861_fixups[] = { | 3219 | static const struct hda_fixup alc861_fixups[] = { |
6528 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { | 3220 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
6529 | .type = ALC_FIXUP_PINS, | 3221 | .type = HDA_FIXUP_PINS, |
6530 | .v.pins = (const struct alc_pincfg[]) { | 3222 | .v.pins = (const struct hda_pintbl[]) { |
6531 | { 0x0b, 0x0221101f }, /* HP */ | 3223 | { 0x0b, 0x0221101f }, /* HP */ |
6532 | { 0x0f, 0x90170310 }, /* speaker */ | 3224 | { 0x0f, 0x90170310 }, /* speaker */ |
6533 | { } | 3225 | { } |
6534 | } | 3226 | } |
6535 | }, | 3227 | }, |
6536 | [ALC861_FIXUP_AMP_VREF_0F] = { | 3228 | [ALC861_FIXUP_AMP_VREF_0F] = { |
6537 | .type = ALC_FIXUP_FUNC, | 3229 | .type = HDA_FIXUP_FUNC, |
6538 | .v.func = alc861_fixup_asus_amp_vref_0f, | 3230 | .v.func = alc861_fixup_asus_amp_vref_0f, |
6539 | }, | 3231 | }, |
6540 | [ALC861_FIXUP_NO_JACK_DETECT] = { | 3232 | [ALC861_FIXUP_NO_JACK_DETECT] = { |
6541 | .type = ALC_FIXUP_FUNC, | 3233 | .type = HDA_FIXUP_FUNC, |
6542 | .v.func = alc_fixup_no_jack_detect, | 3234 | .v.func = alc_fixup_no_jack_detect, |
6543 | }, | 3235 | }, |
6544 | [ALC861_FIXUP_ASUS_A6RP] = { | 3236 | [ALC861_FIXUP_ASUS_A6RP] = { |
6545 | .type = ALC_FIXUP_FUNC, | 3237 | .type = HDA_FIXUP_FUNC, |
6546 | .v.func = alc861_fixup_asus_amp_vref_0f, | 3238 | .v.func = alc861_fixup_asus_amp_vref_0f, |
6547 | .chained = true, | 3239 | .chained = true, |
6548 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | 3240 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, |
@@ -6572,15 +3264,15 @@ static int patch_alc861(struct hda_codec *codec) | |||
6572 | 3264 | ||
6573 | spec = codec->spec; | 3265 | spec = codec->spec; |
6574 | 3266 | ||
6575 | alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | 3267 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
6576 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 3268 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6577 | 3269 | ||
6578 | /* automatic parse from the BIOS config */ | 3270 | /* automatic parse from the BIOS config */ |
6579 | err = alc861_parse_auto_config(codec); | 3271 | err = alc861_parse_auto_config(codec); |
6580 | if (err < 0) | 3272 | if (err < 0) |
6581 | goto error; | 3273 | goto error; |
6582 | 3274 | ||
6583 | if (!spec->no_analog) { | 3275 | if (!spec->gen.no_analog) { |
6584 | err = snd_hda_attach_beep_device(codec, 0x23); | 3276 | err = snd_hda_attach_beep_device(codec, 0x23); |
6585 | if (err < 0) | 3277 | if (err < 0) |
6586 | goto error; | 3278 | goto error; |
@@ -6592,7 +3284,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
6592 | spec->power_hook = alc_power_eapd; | 3284 | spec->power_hook = alc_power_eapd; |
6593 | #endif | 3285 | #endif |
6594 | 3286 | ||
6595 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 3287 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
6596 | 3288 | ||
6597 | return 0; | 3289 | return 0; |
6598 | 3290 | ||
@@ -6622,17 +3314,17 @@ enum { | |||
6622 | 3314 | ||
6623 | /* exclude VREF80 */ | 3315 | /* exclude VREF80 */ |
6624 | static void alc861vd_fixup_dallas(struct hda_codec *codec, | 3316 | static void alc861vd_fixup_dallas(struct hda_codec *codec, |
6625 | const struct alc_fixup *fix, int action) | 3317 | const struct hda_fixup *fix, int action) |
6626 | { | 3318 | { |
6627 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | 3319 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
6628 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); | 3320 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); |
6629 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); | 3321 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); |
6630 | } | 3322 | } |
6631 | } | 3323 | } |
6632 | 3324 | ||
6633 | static const struct alc_fixup alc861vd_fixups[] = { | 3325 | static const struct hda_fixup alc861vd_fixups[] = { |
6634 | [ALC660VD_FIX_ASUS_GPIO1] = { | 3326 | [ALC660VD_FIX_ASUS_GPIO1] = { |
6635 | .type = ALC_FIXUP_VERBS, | 3327 | .type = HDA_FIXUP_VERBS, |
6636 | .v.verbs = (const struct hda_verb[]) { | 3328 | .v.verbs = (const struct hda_verb[]) { |
6637 | /* reset GPIO1 */ | 3329 | /* reset GPIO1 */ |
6638 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 3330 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
@@ -6642,7 +3334,7 @@ static const struct alc_fixup alc861vd_fixups[] = { | |||
6642 | } | 3334 | } |
6643 | }, | 3335 | }, |
6644 | [ALC861VD_FIX_DALLAS] = { | 3336 | [ALC861VD_FIX_DALLAS] = { |
6645 | .type = ALC_FIXUP_FUNC, | 3337 | .type = HDA_FIXUP_FUNC, |
6646 | .v.func = alc861vd_fixup_dallas, | 3338 | .v.func = alc861vd_fixup_dallas, |
6647 | }, | 3339 | }, |
6648 | }; | 3340 | }; |
@@ -6667,15 +3359,15 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
6667 | 3359 | ||
6668 | spec = codec->spec; | 3360 | spec = codec->spec; |
6669 | 3361 | ||
6670 | alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | 3362 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
6671 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 3363 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6672 | 3364 | ||
6673 | /* automatic parse from the BIOS config */ | 3365 | /* automatic parse from the BIOS config */ |
6674 | err = alc861vd_parse_auto_config(codec); | 3366 | err = alc861vd_parse_auto_config(codec); |
6675 | if (err < 0) | 3367 | if (err < 0) |
6676 | goto error; | 3368 | goto error; |
6677 | 3369 | ||
6678 | if (!spec->no_analog) { | 3370 | if (!spec->gen.no_analog) { |
6679 | err = snd_hda_attach_beep_device(codec, 0x23); | 3371 | err = snd_hda_attach_beep_device(codec, 0x23); |
6680 | if (err < 0) | 3372 | if (err < 0) |
6681 | goto error; | 3373 | goto error; |
@@ -6686,7 +3378,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
6686 | 3378 | ||
6687 | spec->shutup = alc_eapd_shutup; | 3379 | spec->shutup = alc_eapd_shutup; |
6688 | 3380 | ||
6689 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 3381 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
6690 | 3382 | ||
6691 | return 0; | 3383 | return 0; |
6692 | 3384 | ||
@@ -6727,9 +3419,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
6727 | } | 3419 | } |
6728 | 3420 | ||
6729 | static void alc272_fixup_mario(struct hda_codec *codec, | 3421 | static void alc272_fixup_mario(struct hda_codec *codec, |
6730 | const struct alc_fixup *fix, int action) | 3422 | const struct hda_fixup *fix, int action) |
6731 | { | 3423 | { |
6732 | if (action != ALC_FIXUP_ACT_PROBE) | 3424 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
6733 | return; | 3425 | return; |
6734 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, | 3426 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, |
6735 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | | 3427 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | |
@@ -6760,39 +3452,39 @@ enum { | |||
6760 | ALC662_FIXUP_INV_DMIC, | 3452 | ALC662_FIXUP_INV_DMIC, |
6761 | }; | 3453 | }; |
6762 | 3454 | ||
6763 | static const struct alc_fixup alc662_fixups[] = { | 3455 | static const struct hda_fixup alc662_fixups[] = { |
6764 | [ALC662_FIXUP_ASPIRE] = { | 3456 | [ALC662_FIXUP_ASPIRE] = { |
6765 | .type = ALC_FIXUP_PINS, | 3457 | .type = HDA_FIXUP_PINS, |
6766 | .v.pins = (const struct alc_pincfg[]) { | 3458 | .v.pins = (const struct hda_pintbl[]) { |
6767 | { 0x15, 0x99130112 }, /* subwoofer */ | 3459 | { 0x15, 0x99130112 }, /* subwoofer */ |
6768 | { } | 3460 | { } |
6769 | } | 3461 | } |
6770 | }, | 3462 | }, |
6771 | [ALC662_FIXUP_IDEAPAD] = { | 3463 | [ALC662_FIXUP_IDEAPAD] = { |
6772 | .type = ALC_FIXUP_PINS, | 3464 | .type = HDA_FIXUP_PINS, |
6773 | .v.pins = (const struct alc_pincfg[]) { | 3465 | .v.pins = (const struct hda_pintbl[]) { |
6774 | { 0x17, 0x99130112 }, /* subwoofer */ | 3466 | { 0x17, 0x99130112 }, /* subwoofer */ |
6775 | { } | 3467 | { } |
6776 | } | 3468 | } |
6777 | }, | 3469 | }, |
6778 | [ALC272_FIXUP_MARIO] = { | 3470 | [ALC272_FIXUP_MARIO] = { |
6779 | .type = ALC_FIXUP_FUNC, | 3471 | .type = HDA_FIXUP_FUNC, |
6780 | .v.func = alc272_fixup_mario, | 3472 | .v.func = alc272_fixup_mario, |
6781 | }, | 3473 | }, |
6782 | [ALC662_FIXUP_CZC_P10T] = { | 3474 | [ALC662_FIXUP_CZC_P10T] = { |
6783 | .type = ALC_FIXUP_VERBS, | 3475 | .type = HDA_FIXUP_VERBS, |
6784 | .v.verbs = (const struct hda_verb[]) { | 3476 | .v.verbs = (const struct hda_verb[]) { |
6785 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 3477 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
6786 | {} | 3478 | {} |
6787 | } | 3479 | } |
6788 | }, | 3480 | }, |
6789 | [ALC662_FIXUP_SKU_IGNORE] = { | 3481 | [ALC662_FIXUP_SKU_IGNORE] = { |
6790 | .type = ALC_FIXUP_FUNC, | 3482 | .type = HDA_FIXUP_FUNC, |
6791 | .v.func = alc_fixup_sku_ignore, | 3483 | .v.func = alc_fixup_sku_ignore, |
6792 | }, | 3484 | }, |
6793 | [ALC662_FIXUP_HP_RP5800] = { | 3485 | [ALC662_FIXUP_HP_RP5800] = { |
6794 | .type = ALC_FIXUP_PINS, | 3486 | .type = HDA_FIXUP_PINS, |
6795 | .v.pins = (const struct alc_pincfg[]) { | 3487 | .v.pins = (const struct hda_pintbl[]) { |
6796 | { 0x14, 0x0221201f }, /* HP out */ | 3488 | { 0x14, 0x0221201f }, /* HP out */ |
6797 | { } | 3489 | { } |
6798 | }, | 3490 | }, |
@@ -6800,8 +3492,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6800 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3492 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6801 | }, | 3493 | }, |
6802 | [ALC662_FIXUP_ASUS_MODE1] = { | 3494 | [ALC662_FIXUP_ASUS_MODE1] = { |
6803 | .type = ALC_FIXUP_PINS, | 3495 | .type = HDA_FIXUP_PINS, |
6804 | .v.pins = (const struct alc_pincfg[]) { | 3496 | .v.pins = (const struct hda_pintbl[]) { |
6805 | { 0x14, 0x99130110 }, /* speaker */ | 3497 | { 0x14, 0x99130110 }, /* speaker */ |
6806 | { 0x18, 0x01a19c20 }, /* mic */ | 3498 | { 0x18, 0x01a19c20 }, /* mic */ |
6807 | { 0x19, 0x99a3092f }, /* int-mic */ | 3499 | { 0x19, 0x99a3092f }, /* int-mic */ |
@@ -6812,8 +3504,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6812 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3504 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6813 | }, | 3505 | }, |
6814 | [ALC662_FIXUP_ASUS_MODE2] = { | 3506 | [ALC662_FIXUP_ASUS_MODE2] = { |
6815 | .type = ALC_FIXUP_PINS, | 3507 | .type = HDA_FIXUP_PINS, |
6816 | .v.pins = (const struct alc_pincfg[]) { | 3508 | .v.pins = (const struct hda_pintbl[]) { |
6817 | { 0x14, 0x99130110 }, /* speaker */ | 3509 | { 0x14, 0x99130110 }, /* speaker */ |
6818 | { 0x18, 0x01a19820 }, /* mic */ | 3510 | { 0x18, 0x01a19820 }, /* mic */ |
6819 | { 0x19, 0x99a3092f }, /* int-mic */ | 3511 | { 0x19, 0x99a3092f }, /* int-mic */ |
@@ -6824,8 +3516,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6824 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3516 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6825 | }, | 3517 | }, |
6826 | [ALC662_FIXUP_ASUS_MODE3] = { | 3518 | [ALC662_FIXUP_ASUS_MODE3] = { |
6827 | .type = ALC_FIXUP_PINS, | 3519 | .type = HDA_FIXUP_PINS, |
6828 | .v.pins = (const struct alc_pincfg[]) { | 3520 | .v.pins = (const struct hda_pintbl[]) { |
6829 | { 0x14, 0x99130110 }, /* speaker */ | 3521 | { 0x14, 0x99130110 }, /* speaker */ |
6830 | { 0x15, 0x0121441f }, /* HP */ | 3522 | { 0x15, 0x0121441f }, /* HP */ |
6831 | { 0x18, 0x01a19840 }, /* mic */ | 3523 | { 0x18, 0x01a19840 }, /* mic */ |
@@ -6837,8 +3529,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6837 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3529 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6838 | }, | 3530 | }, |
6839 | [ALC662_FIXUP_ASUS_MODE4] = { | 3531 | [ALC662_FIXUP_ASUS_MODE4] = { |
6840 | .type = ALC_FIXUP_PINS, | 3532 | .type = HDA_FIXUP_PINS, |
6841 | .v.pins = (const struct alc_pincfg[]) { | 3533 | .v.pins = (const struct hda_pintbl[]) { |
6842 | { 0x14, 0x99130110 }, /* speaker */ | 3534 | { 0x14, 0x99130110 }, /* speaker */ |
6843 | { 0x16, 0x99130111 }, /* speaker */ | 3535 | { 0x16, 0x99130111 }, /* speaker */ |
6844 | { 0x18, 0x01a19840 }, /* mic */ | 3536 | { 0x18, 0x01a19840 }, /* mic */ |
@@ -6850,8 +3542,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6850 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3542 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6851 | }, | 3543 | }, |
6852 | [ALC662_FIXUP_ASUS_MODE5] = { | 3544 | [ALC662_FIXUP_ASUS_MODE5] = { |
6853 | .type = ALC_FIXUP_PINS, | 3545 | .type = HDA_FIXUP_PINS, |
6854 | .v.pins = (const struct alc_pincfg[]) { | 3546 | .v.pins = (const struct hda_pintbl[]) { |
6855 | { 0x14, 0x99130110 }, /* speaker */ | 3547 | { 0x14, 0x99130110 }, /* speaker */ |
6856 | { 0x15, 0x0121441f }, /* HP */ | 3548 | { 0x15, 0x0121441f }, /* HP */ |
6857 | { 0x16, 0x99130111 }, /* speaker */ | 3549 | { 0x16, 0x99130111 }, /* speaker */ |
@@ -6863,8 +3555,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6863 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3555 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6864 | }, | 3556 | }, |
6865 | [ALC662_FIXUP_ASUS_MODE6] = { | 3557 | [ALC662_FIXUP_ASUS_MODE6] = { |
6866 | .type = ALC_FIXUP_PINS, | 3558 | .type = HDA_FIXUP_PINS, |
6867 | .v.pins = (const struct alc_pincfg[]) { | 3559 | .v.pins = (const struct hda_pintbl[]) { |
6868 | { 0x14, 0x99130110 }, /* speaker */ | 3560 | { 0x14, 0x99130110 }, /* speaker */ |
6869 | { 0x15, 0x01211420 }, /* HP2 */ | 3561 | { 0x15, 0x01211420 }, /* HP2 */ |
6870 | { 0x18, 0x01a19840 }, /* mic */ | 3562 | { 0x18, 0x01a19840 }, /* mic */ |
@@ -6876,8 +3568,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6876 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3568 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6877 | }, | 3569 | }, |
6878 | [ALC662_FIXUP_ASUS_MODE7] = { | 3570 | [ALC662_FIXUP_ASUS_MODE7] = { |
6879 | .type = ALC_FIXUP_PINS, | 3571 | .type = HDA_FIXUP_PINS, |
6880 | .v.pins = (const struct alc_pincfg[]) { | 3572 | .v.pins = (const struct hda_pintbl[]) { |
6881 | { 0x14, 0x99130110 }, /* speaker */ | 3573 | { 0x14, 0x99130110 }, /* speaker */ |
6882 | { 0x17, 0x99130111 }, /* speaker */ | 3574 | { 0x17, 0x99130111 }, /* speaker */ |
6883 | { 0x18, 0x01a19840 }, /* mic */ | 3575 | { 0x18, 0x01a19840 }, /* mic */ |
@@ -6890,8 +3582,8 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6890 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3582 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6891 | }, | 3583 | }, |
6892 | [ALC662_FIXUP_ASUS_MODE8] = { | 3584 | [ALC662_FIXUP_ASUS_MODE8] = { |
6893 | .type = ALC_FIXUP_PINS, | 3585 | .type = HDA_FIXUP_PINS, |
6894 | .v.pins = (const struct alc_pincfg[]) { | 3586 | .v.pins = (const struct hda_pintbl[]) { |
6895 | { 0x14, 0x99130110 }, /* speaker */ | 3587 | { 0x14, 0x99130110 }, /* speaker */ |
6896 | { 0x12, 0x99a30970 }, /* int-mic */ | 3588 | { 0x12, 0x99a30970 }, /* int-mic */ |
6897 | { 0x15, 0x01214020 }, /* HP */ | 3589 | { 0x15, 0x01214020 }, /* HP */ |
@@ -6904,18 +3596,18 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6904 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 3596 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6905 | }, | 3597 | }, |
6906 | [ALC662_FIXUP_NO_JACK_DETECT] = { | 3598 | [ALC662_FIXUP_NO_JACK_DETECT] = { |
6907 | .type = ALC_FIXUP_FUNC, | 3599 | .type = HDA_FIXUP_FUNC, |
6908 | .v.func = alc_fixup_no_jack_detect, | 3600 | .v.func = alc_fixup_no_jack_detect, |
6909 | }, | 3601 | }, |
6910 | [ALC662_FIXUP_ZOTAC_Z68] = { | 3602 | [ALC662_FIXUP_ZOTAC_Z68] = { |
6911 | .type = ALC_FIXUP_PINS, | 3603 | .type = HDA_FIXUP_PINS, |
6912 | .v.pins = (const struct alc_pincfg[]) { | 3604 | .v.pins = (const struct hda_pintbl[]) { |
6913 | { 0x1b, 0x02214020 }, /* Front HP */ | 3605 | { 0x1b, 0x02214020 }, /* Front HP */ |
6914 | { } | 3606 | { } |
6915 | } | 3607 | } |
6916 | }, | 3608 | }, |
6917 | [ALC662_FIXUP_INV_DMIC] = { | 3609 | [ALC662_FIXUP_INV_DMIC] = { |
6918 | .type = ALC_FIXUP_FUNC, | 3610 | .type = HDA_FIXUP_FUNC, |
6919 | .v.func = alc_fixup_inv_dmic_0x12, | 3611 | .v.func = alc_fixup_inv_dmic_0x12, |
6920 | }, | 3612 | }, |
6921 | }; | 3613 | }; |
@@ -6995,7 +3687,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
6995 | {} | 3687 | {} |
6996 | }; | 3688 | }; |
6997 | 3689 | ||
6998 | static const struct alc_model_fixup alc662_fixup_models[] = { | 3690 | static const struct hda_model_fixup alc662_fixup_models[] = { |
6999 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | 3691 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
7000 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, | 3692 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, |
7001 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, | 3693 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, |
@@ -7056,9 +3748,9 @@ static int patch_alc662(struct hda_codec *codec) | |||
7056 | spec->init_hook = alc662_fill_coef; | 3748 | spec->init_hook = alc662_fill_coef; |
7057 | alc662_fill_coef(codec); | 3749 | alc662_fill_coef(codec); |
7058 | 3750 | ||
7059 | alc_pick_fixup(codec, alc662_fixup_models, | 3751 | snd_hda_pick_fixup(codec, alc662_fixup_models, |
7060 | alc662_fixup_tbl, alc662_fixups); | 3752 | alc662_fixup_tbl, alc662_fixups); |
7061 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 3753 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
7062 | 3754 | ||
7063 | alc_auto_parse_customize_define(codec); | 3755 | alc_auto_parse_customize_define(codec); |
7064 | 3756 | ||
@@ -7074,7 +3766,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
7074 | if (err < 0) | 3766 | if (err < 0) |
7075 | goto error; | 3767 | goto error; |
7076 | 3768 | ||
7077 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 3769 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { |
7078 | err = snd_hda_attach_beep_device(codec, 0x1); | 3770 | err = snd_hda_attach_beep_device(codec, 0x1); |
7079 | if (err < 0) | 3771 | if (err < 0) |
7080 | goto error; | 3772 | goto error; |
@@ -7096,7 +3788,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
7096 | codec->patch_ops = alc_patch_ops; | 3788 | codec->patch_ops = alc_patch_ops; |
7097 | spec->shutup = alc_eapd_shutup; | 3789 | spec->shutup = alc_eapd_shutup; |
7098 | 3790 | ||
7099 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 3791 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
7100 | 3792 | ||
7101 | return 0; | 3793 | return 0; |
7102 | 3794 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a86547ca17c8..617ac1f542fb 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <sound/core.h> | 33 | #include <sound/core.h> |
34 | #include <sound/asoundef.h> | ||
35 | #include <sound/jack.h> | 34 | #include <sound/jack.h> |
36 | #include <sound/tlv.h> | 35 | #include <sound/tlv.h> |
37 | #include "hda_codec.h" | 36 | #include "hda_codec.h" |
@@ -39,18 +38,14 @@ | |||
39 | #include "hda_auto_parser.h" | 38 | #include "hda_auto_parser.h" |
40 | #include "hda_beep.h" | 39 | #include "hda_beep.h" |
41 | #include "hda_jack.h" | 40 | #include "hda_jack.h" |
41 | #include "hda_generic.h" | ||
42 | 42 | ||
43 | enum { | 43 | enum { |
44 | STAC_VREF_EVENT = 1, | 44 | STAC_VREF_EVENT = 8, |
45 | STAC_INSERT_EVENT, | ||
46 | STAC_PWR_EVENT, | 45 | STAC_PWR_EVENT, |
47 | STAC_HP_EVENT, | ||
48 | STAC_LO_EVENT, | ||
49 | STAC_MIC_EVENT, | ||
50 | }; | 46 | }; |
51 | 47 | ||
52 | enum { | 48 | enum { |
53 | STAC_AUTO, | ||
54 | STAC_REF, | 49 | STAC_REF, |
55 | STAC_9200_OQO, | 50 | STAC_9200_OQO, |
56 | STAC_9200_DELL_D21, | 51 | STAC_9200_DELL_D21, |
@@ -66,11 +61,11 @@ enum { | |||
66 | STAC_9200_M4, | 61 | STAC_9200_M4, |
67 | STAC_9200_M4_2, | 62 | STAC_9200_M4_2, |
68 | STAC_9200_PANASONIC, | 63 | STAC_9200_PANASONIC, |
64 | STAC_9200_EAPD_INIT, | ||
69 | STAC_9200_MODELS | 65 | STAC_9200_MODELS |
70 | }; | 66 | }; |
71 | 67 | ||
72 | enum { | 68 | enum { |
73 | STAC_9205_AUTO, | ||
74 | STAC_9205_REF, | 69 | STAC_9205_REF, |
75 | STAC_9205_DELL_M42, | 70 | STAC_9205_DELL_M42, |
76 | STAC_9205_DELL_M43, | 71 | STAC_9205_DELL_M43, |
@@ -80,7 +75,6 @@ enum { | |||
80 | }; | 75 | }; |
81 | 76 | ||
82 | enum { | 77 | enum { |
83 | STAC_92HD73XX_AUTO, | ||
84 | STAC_92HD73XX_NO_JD, /* no jack-detection */ | 78 | STAC_92HD73XX_NO_JD, /* no jack-detection */ |
85 | STAC_92HD73XX_REF, | 79 | STAC_92HD73XX_REF, |
86 | STAC_92HD73XX_INTEL, | 80 | STAC_92HD73XX_INTEL, |
@@ -93,7 +87,6 @@ enum { | |||
93 | }; | 87 | }; |
94 | 88 | ||
95 | enum { | 89 | enum { |
96 | STAC_92HD83XXX_AUTO, | ||
97 | STAC_92HD83XXX_REF, | 90 | STAC_92HD83XXX_REF, |
98 | STAC_92HD83XXX_PWR_REF, | 91 | STAC_92HD83XXX_PWR_REF, |
99 | STAC_DELL_S14, | 92 | STAC_DELL_S14, |
@@ -105,11 +98,12 @@ enum { | |||
105 | STAC_92HD83XXX_HP_INV_LED, | 98 | STAC_92HD83XXX_HP_INV_LED, |
106 | STAC_92HD83XXX_HP_MIC_LED, | 99 | STAC_92HD83XXX_HP_MIC_LED, |
107 | STAC_92HD83XXX_HEADSET_JACK, | 100 | STAC_92HD83XXX_HEADSET_JACK, |
101 | STAC_92HD83XXX_HP, | ||
102 | STAC_HP_ENVY_BASS, | ||
108 | STAC_92HD83XXX_MODELS | 103 | STAC_92HD83XXX_MODELS |
109 | }; | 104 | }; |
110 | 105 | ||
111 | enum { | 106 | enum { |
112 | STAC_92HD71BXX_AUTO, | ||
113 | STAC_92HD71BXX_REF, | 107 | STAC_92HD71BXX_REF, |
114 | STAC_DELL_M4_1, | 108 | STAC_DELL_M4_1, |
115 | STAC_DELL_M4_2, | 109 | STAC_DELL_M4_2, |
@@ -118,12 +112,13 @@ enum { | |||
118 | STAC_HP_DV4, | 112 | STAC_HP_DV4, |
119 | STAC_HP_DV5, | 113 | STAC_HP_DV5, |
120 | STAC_HP_HDX, | 114 | STAC_HP_HDX, |
121 | STAC_HP_DV4_1222NR, | 115 | STAC_92HD71BXX_HP, |
116 | STAC_92HD71BXX_NO_DMIC, | ||
117 | STAC_92HD71BXX_NO_SMUX, | ||
122 | STAC_92HD71BXX_MODELS | 118 | STAC_92HD71BXX_MODELS |
123 | }; | 119 | }; |
124 | 120 | ||
125 | enum { | 121 | enum { |
126 | STAC_925x_AUTO, | ||
127 | STAC_925x_REF, | 122 | STAC_925x_REF, |
128 | STAC_M1, | 123 | STAC_M1, |
129 | STAC_M1_2, | 124 | STAC_M1_2, |
@@ -136,7 +131,6 @@ enum { | |||
136 | }; | 131 | }; |
137 | 132 | ||
138 | enum { | 133 | enum { |
139 | STAC_922X_AUTO, | ||
140 | STAC_D945_REF, | 134 | STAC_D945_REF, |
141 | STAC_D945GTP3, | 135 | STAC_D945GTP3, |
142 | STAC_D945GTP5, | 136 | STAC_D945GTP5, |
@@ -145,67 +139,45 @@ enum { | |||
145 | STAC_INTEL_MAC_V3, | 139 | STAC_INTEL_MAC_V3, |
146 | STAC_INTEL_MAC_V4, | 140 | STAC_INTEL_MAC_V4, |
147 | STAC_INTEL_MAC_V5, | 141 | STAC_INTEL_MAC_V5, |
148 | STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter | 142 | STAC_INTEL_MAC_AUTO, |
149 | * is given, one of the above models will be | ||
150 | * chosen according to the subsystem id. */ | ||
151 | /* for backward compatibility */ | ||
152 | STAC_MACMINI, | ||
153 | STAC_MACBOOK, | ||
154 | STAC_MACBOOK_PRO_V1, | ||
155 | STAC_MACBOOK_PRO_V2, | ||
156 | STAC_IMAC_INTEL, | ||
157 | STAC_IMAC_INTEL_20, | ||
158 | STAC_ECS_202, | 143 | STAC_ECS_202, |
159 | STAC_922X_DELL_D81, | 144 | STAC_922X_DELL_D81, |
160 | STAC_922X_DELL_D82, | 145 | STAC_922X_DELL_D82, |
161 | STAC_922X_DELL_M81, | 146 | STAC_922X_DELL_M81, |
162 | STAC_922X_DELL_M82, | 147 | STAC_922X_DELL_M82, |
148 | STAC_922X_INTEL_MAC_GPIO, | ||
163 | STAC_922X_MODELS | 149 | STAC_922X_MODELS |
164 | }; | 150 | }; |
165 | 151 | ||
166 | enum { | 152 | enum { |
167 | STAC_927X_AUTO, | ||
168 | STAC_D965_REF_NO_JD, /* no jack-detection */ | 153 | STAC_D965_REF_NO_JD, /* no jack-detection */ |
169 | STAC_D965_REF, | 154 | STAC_D965_REF, |
170 | STAC_D965_3ST, | 155 | STAC_D965_3ST, |
171 | STAC_D965_5ST, | 156 | STAC_D965_5ST, |
172 | STAC_D965_5ST_NO_FP, | 157 | STAC_D965_5ST_NO_FP, |
158 | STAC_D965_VERBS, | ||
173 | STAC_DELL_3ST, | 159 | STAC_DELL_3ST, |
174 | STAC_DELL_BIOS, | 160 | STAC_DELL_BIOS, |
161 | STAC_DELL_BIOS_SPDIF, | ||
162 | STAC_927X_DELL_DMIC, | ||
175 | STAC_927X_VOLKNOB, | 163 | STAC_927X_VOLKNOB, |
176 | STAC_927X_MODELS | 164 | STAC_927X_MODELS |
177 | }; | 165 | }; |
178 | 166 | ||
179 | enum { | 167 | enum { |
180 | STAC_9872_AUTO, | ||
181 | STAC_9872_VAIO, | 168 | STAC_9872_VAIO, |
182 | STAC_9872_MODELS | 169 | STAC_9872_MODELS |
183 | }; | 170 | }; |
184 | 171 | ||
185 | struct sigmatel_mic_route { | ||
186 | hda_nid_t pin; | ||
187 | signed char mux_idx; | ||
188 | signed char dmux_idx; | ||
189 | }; | ||
190 | |||
191 | #define MAX_PINS_NUM 16 | ||
192 | #define MAX_ADCS_NUM 4 | ||
193 | #define MAX_DMICS_NUM 4 | ||
194 | |||
195 | struct sigmatel_spec { | 172 | struct sigmatel_spec { |
196 | struct snd_kcontrol_new *mixers[4]; | 173 | struct hda_gen_spec gen; |
197 | unsigned int num_mixers; | ||
198 | 174 | ||
199 | int board_config; | ||
200 | unsigned int eapd_switch: 1; | 175 | unsigned int eapd_switch: 1; |
201 | unsigned int surr_switch: 1; | ||
202 | unsigned int alt_switch: 1; | ||
203 | unsigned int hp_detect: 1; | ||
204 | unsigned int spdif_mute: 1; | ||
205 | unsigned int check_volume_offset:1; | ||
206 | unsigned int auto_mic:1; | ||
207 | unsigned int linear_tone_beep:1; | 176 | unsigned int linear_tone_beep:1; |
208 | unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */ | 177 | unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */ |
178 | unsigned int volknob_init:1; /* special volume-knob initialization */ | ||
179 | unsigned int powerdown_adcs:1; | ||
180 | unsigned int have_spdif_mux:1; | ||
209 | 181 | ||
210 | /* gpio lines */ | 182 | /* gpio lines */ |
211 | unsigned int eapd_mask; | 183 | unsigned int eapd_mask; |
@@ -217,6 +189,7 @@ struct sigmatel_spec { | |||
217 | unsigned int gpio_led_polarity; | 189 | unsigned int gpio_led_polarity; |
218 | unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ | 190 | unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ |
219 | unsigned int vref_led; | 191 | unsigned int vref_led; |
192 | int default_polarity; | ||
220 | 193 | ||
221 | unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ | 194 | unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */ |
222 | bool mic_mute_led_on; /* current mic mute state */ | 195 | bool mic_mute_led_on; /* current mic mute state */ |
@@ -226,6 +199,7 @@ struct sigmatel_spec { | |||
226 | 199 | ||
227 | /* analog loopback */ | 200 | /* analog loopback */ |
228 | const struct snd_kcontrol_new *aloopback_ctl; | 201 | const struct snd_kcontrol_new *aloopback_ctl; |
202 | unsigned int aloopback; | ||
229 | unsigned char aloopback_mask; | 203 | unsigned char aloopback_mask; |
230 | unsigned char aloopback_shift; | 204 | unsigned char aloopback_shift; |
231 | 205 | ||
@@ -233,647 +207,778 @@ struct sigmatel_spec { | |||
233 | unsigned int power_map_bits; | 207 | unsigned int power_map_bits; |
234 | unsigned int num_pwrs; | 208 | unsigned int num_pwrs; |
235 | const hda_nid_t *pwr_nids; | 209 | const hda_nid_t *pwr_nids; |
236 | const hda_nid_t *dac_list; | 210 | unsigned int active_adcs; |
237 | |||
238 | /* playback */ | ||
239 | struct hda_input_mux *mono_mux; | ||
240 | unsigned int cur_mmux; | ||
241 | struct hda_multi_out multiout; | ||
242 | hda_nid_t dac_nids[5]; | ||
243 | hda_nid_t hp_dacs[5]; | ||
244 | hda_nid_t speaker_dacs[5]; | ||
245 | |||
246 | int volume_offset; | ||
247 | |||
248 | /* capture */ | ||
249 | const hda_nid_t *adc_nids; | ||
250 | unsigned int num_adcs; | ||
251 | const hda_nid_t *mux_nids; | ||
252 | unsigned int num_muxes; | ||
253 | const hda_nid_t *dmic_nids; | ||
254 | unsigned int num_dmics; | ||
255 | const hda_nid_t *dmux_nids; | ||
256 | unsigned int num_dmuxes; | ||
257 | const hda_nid_t *smux_nids; | ||
258 | unsigned int num_smuxes; | ||
259 | unsigned int num_analog_muxes; | ||
260 | |||
261 | const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ | ||
262 | const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ | ||
263 | unsigned int num_caps; /* number of capture volume/switch elements */ | ||
264 | |||
265 | struct sigmatel_mic_route ext_mic; | ||
266 | struct sigmatel_mic_route int_mic; | ||
267 | struct sigmatel_mic_route dock_mic; | ||
268 | 211 | ||
269 | const char * const *spdif_labels; | 212 | /* beep widgets */ |
270 | |||
271 | hda_nid_t dig_in_nid; | ||
272 | hda_nid_t mono_nid; | ||
273 | hda_nid_t anabeep_nid; | 213 | hda_nid_t anabeep_nid; |
274 | hda_nid_t digbeep_nid; | 214 | hda_nid_t digbeep_nid; |
275 | 215 | ||
276 | /* pin widgets */ | 216 | /* SPDIF-out mux */ |
277 | const hda_nid_t *pin_nids; | 217 | const char * const *spdif_labels; |
278 | unsigned int num_pins; | 218 | struct hda_input_mux spdif_mux; |
279 | |||
280 | /* codec specific stuff */ | ||
281 | const struct hda_verb *init; | ||
282 | const struct snd_kcontrol_new *mixer; | ||
283 | |||
284 | /* capture source */ | ||
285 | struct hda_input_mux *dinput_mux; | ||
286 | unsigned int cur_dmux[2]; | ||
287 | struct hda_input_mux *input_mux; | ||
288 | unsigned int cur_mux[3]; | ||
289 | struct hda_input_mux *sinput_mux; | ||
290 | unsigned int cur_smux[2]; | 219 | unsigned int cur_smux[2]; |
291 | unsigned int cur_amux; | ||
292 | hda_nid_t *amp_nids; | ||
293 | unsigned int powerdown_adcs; | ||
294 | |||
295 | /* i/o switches */ | ||
296 | unsigned int io_switch[2]; | ||
297 | unsigned int clfe_swap; | ||
298 | hda_nid_t line_switch; /* shared line-in for input and output */ | ||
299 | hda_nid_t mic_switch; /* shared mic-in for input and output */ | ||
300 | hda_nid_t hp_switch; /* NID of HP as line-out */ | ||
301 | unsigned int aloopback; | ||
302 | |||
303 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
304 | |||
305 | /* dynamic controls and input_mux */ | ||
306 | struct auto_pin_cfg autocfg; | ||
307 | struct snd_array kctls; | ||
308 | struct hda_input_mux private_dimux; | ||
309 | struct hda_input_mux private_imux; | ||
310 | struct hda_input_mux private_smux; | ||
311 | struct hda_input_mux private_mono_mux; | ||
312 | |||
313 | /* auto spec */ | ||
314 | unsigned auto_pin_cnt; | ||
315 | hda_nid_t auto_pin_nids[MAX_PINS_NUM]; | ||
316 | unsigned auto_adc_cnt; | ||
317 | hda_nid_t auto_adc_nids[MAX_ADCS_NUM]; | ||
318 | hda_nid_t auto_mux_nids[MAX_ADCS_NUM]; | ||
319 | hda_nid_t auto_dmux_nids[MAX_ADCS_NUM]; | ||
320 | unsigned long auto_capvols[MAX_ADCS_NUM]; | ||
321 | unsigned auto_dmic_cnt; | ||
322 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; | ||
323 | |||
324 | struct hda_vmaster_mute_hook vmaster_mute; | ||
325 | }; | 220 | }; |
326 | 221 | ||
327 | #define AC_VERB_IDT_SET_POWER_MAP 0x7ec | 222 | #define AC_VERB_IDT_SET_POWER_MAP 0x7ec |
328 | #define AC_VERB_IDT_GET_POWER_MAP 0xfec | 223 | #define AC_VERB_IDT_GET_POWER_MAP 0xfec |
329 | 224 | ||
330 | static const hda_nid_t stac9200_adc_nids[1] = { | ||
331 | 0x03, | ||
332 | }; | ||
333 | |||
334 | static const hda_nid_t stac9200_mux_nids[1] = { | ||
335 | 0x0c, | ||
336 | }; | ||
337 | |||
338 | static const hda_nid_t stac9200_dac_nids[1] = { | ||
339 | 0x02, | ||
340 | }; | ||
341 | |||
342 | static const hda_nid_t stac92hd73xx_pwr_nids[8] = { | 225 | static const hda_nid_t stac92hd73xx_pwr_nids[8] = { |
343 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, | 226 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, |
344 | 0x0f, 0x10, 0x11 | 227 | 0x0f, 0x10, 0x11 |
345 | }; | 228 | }; |
346 | 229 | ||
347 | static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = { | 230 | static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { |
348 | 0x26, 0, | 231 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, |
349 | }; | 232 | 0x0f, 0x10 |
350 | |||
351 | static const hda_nid_t stac92hd73xx_adc_nids[2] = { | ||
352 | 0x1a, 0x1b | ||
353 | }; | ||
354 | |||
355 | #define STAC92HD73XX_NUM_DMICS 2 | ||
356 | static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { | ||
357 | 0x13, 0x14, 0 | ||
358 | }; | ||
359 | |||
360 | #define STAC92HD73_DAC_COUNT 5 | ||
361 | |||
362 | static const hda_nid_t stac92hd73xx_mux_nids[2] = { | ||
363 | 0x20, 0x21, | ||
364 | }; | 233 | }; |
365 | 234 | ||
366 | static const hda_nid_t stac92hd73xx_dmux_nids[2] = { | 235 | static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
367 | 0x20, 0x21, | 236 | 0x0a, 0x0d, 0x0f |
368 | }; | 237 | }; |
369 | 238 | ||
370 | static const hda_nid_t stac92hd73xx_smux_nids[2] = { | ||
371 | 0x22, 0x23, | ||
372 | }; | ||
373 | 239 | ||
374 | #define STAC92HD73XX_NUM_CAPS 2 | 240 | /* |
375 | static const unsigned long stac92hd73xx_capvols[] = { | 241 | * PCM hooks |
376 | HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), | 242 | */ |
377 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | 243 | static void stac_playback_pcm_hook(struct hda_pcm_stream *hinfo, |
378 | }; | 244 | struct hda_codec *codec, |
379 | #define stac92hd73xx_capsws stac92hd73xx_capvols | 245 | struct snd_pcm_substream *substream, |
246 | int action) | ||
247 | { | ||
248 | struct sigmatel_spec *spec = codec->spec; | ||
249 | if (action == HDA_GEN_PCM_ACT_OPEN && spec->stream_delay) | ||
250 | msleep(spec->stream_delay); | ||
251 | } | ||
380 | 252 | ||
381 | #define STAC92HD83_DAC_COUNT 3 | 253 | static void stac_capture_pcm_hook(struct hda_pcm_stream *hinfo, |
254 | struct hda_codec *codec, | ||
255 | struct snd_pcm_substream *substream, | ||
256 | int action) | ||
257 | { | ||
258 | struct sigmatel_spec *spec = codec->spec; | ||
259 | int i, idx = 0; | ||
382 | 260 | ||
383 | static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { | 261 | if (!spec->powerdown_adcs) |
384 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, | 262 | return; |
385 | 0x0f, 0x10 | ||
386 | }; | ||
387 | 263 | ||
388 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | 264 | for (i = 0; i < spec->gen.num_all_adcs; i++) { |
389 | 0x1e, 0, | 265 | if (spec->gen.all_adcs[i] == hinfo->nid) { |
390 | }; | 266 | idx = i; |
267 | break; | ||
268 | } | ||
269 | } | ||
391 | 270 | ||
392 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { | 271 | switch (action) { |
393 | 0x11, 0x20, | 272 | case HDA_GEN_PCM_ACT_OPEN: |
394 | }; | 273 | msleep(40); |
274 | snd_hda_codec_write(codec, hinfo->nid, 0, | ||
275 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
276 | spec->active_adcs |= (1 << idx); | ||
277 | break; | ||
278 | case HDA_GEN_PCM_ACT_CLOSE: | ||
279 | snd_hda_codec_write(codec, hinfo->nid, 0, | ||
280 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
281 | spec->active_adcs &= ~(1 << idx); | ||
282 | break; | ||
283 | } | ||
284 | } | ||
395 | 285 | ||
396 | static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 286 | /* |
397 | 0x0a, 0x0d, 0x0f | 287 | * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a |
398 | }; | 288 | * funky external mute control using GPIO pins. |
289 | */ | ||
399 | 290 | ||
400 | static const hda_nid_t stac92hd71bxx_adc_nids[2] = { | 291 | static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, |
401 | 0x12, 0x13, | 292 | unsigned int dir_mask, unsigned int data) |
402 | }; | 293 | { |
294 | unsigned int gpiostate, gpiomask, gpiodir; | ||
403 | 295 | ||
404 | static const hda_nid_t stac92hd71bxx_mux_nids[2] = { | 296 | snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data); |
405 | 0x1a, 0x1b | ||
406 | }; | ||
407 | 297 | ||
408 | static const hda_nid_t stac92hd71bxx_dmux_nids[2] = { | 298 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, |
409 | 0x1c, 0x1d, | 299 | AC_VERB_GET_GPIO_DATA, 0); |
410 | }; | 300 | gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); |
411 | 301 | ||
412 | static const hda_nid_t stac92hd71bxx_smux_nids[2] = { | 302 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, |
413 | 0x24, 0x25, | 303 | AC_VERB_GET_GPIO_MASK, 0); |
414 | }; | 304 | gpiomask |= mask; |
415 | 305 | ||
416 | #define STAC92HD71BXX_NUM_DMICS 2 | 306 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, |
417 | static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { | 307 | AC_VERB_GET_GPIO_DIRECTION, 0); |
418 | 0x18, 0x19, 0 | 308 | gpiodir |= dir_mask; |
419 | }; | ||
420 | 309 | ||
421 | static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = { | 310 | /* Configure GPIOx as CMOS */ |
422 | 0x18, 0 | 311 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0); |
423 | }; | ||
424 | 312 | ||
425 | static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | 313 | snd_hda_codec_write(codec, codec->afg, 0, |
426 | 0x22, 0 | 314 | AC_VERB_SET_GPIO_MASK, gpiomask); |
427 | }; | 315 | snd_hda_codec_read(codec, codec->afg, 0, |
316 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */ | ||
428 | 317 | ||
429 | #define STAC92HD71BXX_NUM_CAPS 2 | 318 | msleep(1); |
430 | static const unsigned long stac92hd71bxx_capvols[] = { | ||
431 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
432 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
433 | }; | ||
434 | #define stac92hd71bxx_capsws stac92hd71bxx_capvols | ||
435 | 319 | ||
436 | static const hda_nid_t stac925x_adc_nids[1] = { | 320 | snd_hda_codec_read(codec, codec->afg, 0, |
437 | 0x03, | 321 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ |
438 | }; | 322 | } |
439 | 323 | ||
440 | static const hda_nid_t stac925x_mux_nids[1] = { | 324 | /* hook for controlling mic-mute LED GPIO */ |
441 | 0x0f, | 325 | static void stac_capture_led_hook(struct hda_codec *codec, |
442 | }; | 326 | struct snd_ctl_elem_value *ucontrol) |
327 | { | ||
328 | struct sigmatel_spec *spec = codec->spec; | ||
329 | bool mute; | ||
443 | 330 | ||
444 | static const hda_nid_t stac925x_dac_nids[1] = { | 331 | if (!ucontrol) |
445 | 0x02, | 332 | return; |
446 | }; | ||
447 | 333 | ||
448 | #define STAC925X_NUM_DMICS 1 | 334 | mute = !(ucontrol->value.integer.value[0] || |
449 | static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { | 335 | ucontrol->value.integer.value[1]); |
450 | 0x15, 0 | 336 | if (spec->mic_mute_led_on != mute) { |
451 | }; | 337 | spec->mic_mute_led_on = mute; |
338 | if (mute) | ||
339 | spec->gpio_data |= spec->mic_mute_led_gpio; | ||
340 | else | ||
341 | spec->gpio_data &= ~spec->mic_mute_led_gpio; | ||
342 | stac_gpio_set(codec, spec->gpio_mask, | ||
343 | spec->gpio_dir, spec->gpio_data); | ||
344 | } | ||
345 | } | ||
452 | 346 | ||
453 | static const hda_nid_t stac925x_dmux_nids[1] = { | 347 | static int stac_vrefout_set(struct hda_codec *codec, |
454 | 0x14, | 348 | hda_nid_t nid, unsigned int new_vref) |
455 | }; | 349 | { |
350 | int error, pinctl; | ||
456 | 351 | ||
457 | static const unsigned long stac925x_capvols[] = { | 352 | snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref); |
458 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | 353 | pinctl = snd_hda_codec_read(codec, nid, 0, |
459 | }; | 354 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
460 | static const unsigned long stac925x_capsws[] = { | ||
461 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
462 | }; | ||
463 | 355 | ||
464 | static const hda_nid_t stac922x_adc_nids[2] = { | 356 | if (pinctl < 0) |
465 | 0x06, 0x07, | 357 | return pinctl; |
466 | }; | ||
467 | 358 | ||
468 | static const hda_nid_t stac922x_mux_nids[2] = { | 359 | pinctl &= 0xff; |
469 | 0x12, 0x13, | 360 | pinctl &= ~AC_PINCTL_VREFEN; |
470 | }; | 361 | pinctl |= (new_vref & AC_PINCTL_VREFEN); |
471 | 362 | ||
472 | #define STAC922X_NUM_CAPS 2 | 363 | error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl); |
473 | static const unsigned long stac922x_capvols[] = { | 364 | if (error < 0) |
474 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), | 365 | return error; |
475 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | ||
476 | }; | ||
477 | #define stac922x_capsws stac922x_capvols | ||
478 | 366 | ||
479 | static const hda_nid_t stac927x_slave_dig_outs[2] = { | 367 | return 1; |
480 | 0x1f, 0, | 368 | } |
481 | }; | ||
482 | 369 | ||
483 | static const hda_nid_t stac927x_adc_nids[3] = { | 370 | /* update mute-LED accoring to the master switch */ |
484 | 0x07, 0x08, 0x09 | 371 | static void stac_update_led_status(struct hda_codec *codec, int enabled) |
485 | }; | 372 | { |
373 | struct sigmatel_spec *spec = codec->spec; | ||
374 | int muted = !enabled; | ||
486 | 375 | ||
487 | static const hda_nid_t stac927x_mux_nids[3] = { | 376 | if (!spec->gpio_led) |
488 | 0x15, 0x16, 0x17 | 377 | return; |
489 | }; | ||
490 | 378 | ||
491 | static const hda_nid_t stac927x_smux_nids[1] = { | 379 | /* LED state is inverted on these systems */ |
492 | 0x21, | 380 | if (spec->gpio_led_polarity) |
493 | }; | 381 | muted = !muted; |
494 | 382 | ||
495 | static const hda_nid_t stac927x_dac_nids[6] = { | 383 | if (!spec->vref_mute_led_nid) { |
496 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 | 384 | if (muted) |
497 | }; | 385 | spec->gpio_data |= spec->gpio_led; |
386 | else | ||
387 | spec->gpio_data &= ~spec->gpio_led; | ||
388 | stac_gpio_set(codec, spec->gpio_mask, | ||
389 | spec->gpio_dir, spec->gpio_data); | ||
390 | } else { | ||
391 | spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD; | ||
392 | stac_vrefout_set(codec, spec->vref_mute_led_nid, | ||
393 | spec->vref_led); | ||
394 | } | ||
395 | } | ||
498 | 396 | ||
499 | static const hda_nid_t stac927x_dmux_nids[1] = { | 397 | /* vmaster hook to update mute LED */ |
500 | 0x1b, | 398 | static void stac_vmaster_hook(void *private_data, int val) |
501 | }; | 399 | { |
400 | stac_update_led_status(private_data, val); | ||
401 | } | ||
502 | 402 | ||
503 | #define STAC927X_NUM_DMICS 2 | 403 | /* automute hook to handle GPIO mute and EAPD updates */ |
504 | static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { | 404 | static void stac_update_outputs(struct hda_codec *codec) |
505 | 0x13, 0x14, 0 | 405 | { |
506 | }; | 406 | struct sigmatel_spec *spec = codec->spec; |
507 | 407 | ||
508 | #define STAC927X_NUM_CAPS 3 | 408 | if (spec->gpio_mute) |
509 | static const unsigned long stac927x_capvols[] = { | 409 | spec->gen.master_mute = |
510 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | 410 | !(snd_hda_codec_read(codec, codec->afg, 0, |
511 | HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), | 411 | AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute); |
512 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), | ||
513 | }; | ||
514 | static const unsigned long stac927x_capsws[] = { | ||
515 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
516 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | ||
517 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | ||
518 | }; | ||
519 | 412 | ||
520 | static const char * const stac927x_spdif_labels[5] = { | 413 | snd_hda_gen_update_outputs(codec); |
521 | "Digital Playback", "ADAT", "Analog Mux 1", | ||
522 | "Analog Mux 2", "Analog Mux 3" | ||
523 | }; | ||
524 | 414 | ||
525 | static const hda_nid_t stac9205_adc_nids[2] = { | 415 | if (spec->eapd_mask && spec->eapd_switch) { |
526 | 0x12, 0x13 | 416 | unsigned int val = spec->gpio_data; |
527 | }; | 417 | if (spec->gen.speaker_muted) |
418 | val &= ~spec->eapd_mask; | ||
419 | else | ||
420 | val |= spec->eapd_mask; | ||
421 | if (spec->gpio_data != val) | ||
422 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, | ||
423 | val); | ||
424 | } | ||
425 | } | ||
528 | 426 | ||
529 | static const hda_nid_t stac9205_mux_nids[2] = { | 427 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
530 | 0x19, 0x1a | 428 | bool enable, bool do_write) |
531 | }; | 429 | { |
430 | struct sigmatel_spec *spec = codec->spec; | ||
431 | unsigned int idx, val; | ||
532 | 432 | ||
533 | static const hda_nid_t stac9205_dmux_nids[1] = { | 433 | for (idx = 0; idx < spec->num_pwrs; idx++) { |
534 | 0x1d, | 434 | if (spec->pwr_nids[idx] == nid) |
535 | }; | 435 | break; |
436 | } | ||
437 | if (idx >= spec->num_pwrs) | ||
438 | return; | ||
536 | 439 | ||
537 | static const hda_nid_t stac9205_smux_nids[1] = { | 440 | idx = 1 << idx; |
538 | 0x21, | ||
539 | }; | ||
540 | 441 | ||
541 | #define STAC9205_NUM_DMICS 2 | 442 | val = spec->power_map_bits; |
542 | static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | 443 | if (enable) |
543 | 0x17, 0x18, 0 | 444 | val &= ~idx; |
544 | }; | 445 | else |
446 | val |= idx; | ||
545 | 447 | ||
546 | #define STAC9205_NUM_CAPS 2 | 448 | /* power down unused output ports */ |
547 | static const unsigned long stac9205_capvols[] = { | 449 | if (val != spec->power_map_bits) { |
548 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), | 450 | spec->power_map_bits = val; |
549 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), | 451 | if (do_write) |
550 | }; | 452 | snd_hda_codec_write(codec, codec->afg, 0, |
551 | static const unsigned long stac9205_capsws[] = { | 453 | AC_VERB_IDT_SET_POWER_MAP, val); |
552 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | 454 | } |
553 | HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), | 455 | } |
554 | }; | ||
555 | 456 | ||
556 | static const hda_nid_t stac9200_pin_nids[8] = { | 457 | /* update power bit per jack plug/unplug */ |
557 | 0x08, 0x09, 0x0d, 0x0e, | 458 | static void jack_update_power(struct hda_codec *codec, |
558 | 0x0f, 0x10, 0x11, 0x12, | 459 | struct hda_jack_tbl *jack) |
559 | }; | 460 | { |
461 | struct sigmatel_spec *spec = codec->spec; | ||
462 | int i; | ||
560 | 463 | ||
561 | static const hda_nid_t stac925x_pin_nids[8] = { | 464 | if (!spec->num_pwrs) |
562 | 0x07, 0x08, 0x0a, 0x0b, | 465 | return; |
563 | 0x0c, 0x0d, 0x10, 0x11, | ||
564 | }; | ||
565 | 466 | ||
566 | static const hda_nid_t stac922x_pin_nids[10] = { | 467 | if (jack && jack->nid) { |
567 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 468 | stac_toggle_power_map(codec, jack->nid, |
568 | 0x0f, 0x10, 0x11, 0x15, 0x1b, | 469 | snd_hda_jack_detect(codec, jack->nid), |
569 | }; | 470 | true); |
471 | return; | ||
472 | } | ||
570 | 473 | ||
571 | static const hda_nid_t stac92hd73xx_pin_nids[13] = { | 474 | /* update all jacks */ |
572 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 475 | for (i = 0; i < spec->num_pwrs; i++) { |
573 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 476 | hda_nid_t nid = spec->pwr_nids[i]; |
574 | 0x14, 0x22, 0x23 | 477 | jack = snd_hda_jack_tbl_get(codec, nid); |
575 | }; | 478 | if (!jack || !jack->action) |
479 | continue; | ||
480 | if (jack->action == STAC_PWR_EVENT || | ||
481 | jack->action <= HDA_GEN_LAST_EVENT) | ||
482 | stac_toggle_power_map(codec, nid, | ||
483 | snd_hda_jack_detect(codec, nid), | ||
484 | false); | ||
485 | } | ||
576 | 486 | ||
577 | #define STAC92HD71BXX_NUM_PINS 13 | 487 | snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP, |
578 | static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | 488 | spec->power_map_bits); |
579 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | 489 | } |
580 | 0x00, 0x14, 0x18, 0x19, 0x1e, | ||
581 | 0x1f, 0x20, 0x27 | ||
582 | }; | ||
583 | static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { | ||
584 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | ||
585 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | ||
586 | 0x1f, 0x20, 0x27 | ||
587 | }; | ||
588 | 490 | ||
589 | static const hda_nid_t stac927x_pin_nids[14] = { | 491 | static void stac_hp_automute(struct hda_codec *codec, |
590 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 492 | struct hda_jack_tbl *jack) |
591 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 493 | { |
592 | 0x14, 0x21, 0x22, 0x23, | 494 | snd_hda_gen_hp_automute(codec, jack); |
593 | }; | 495 | jack_update_power(codec, jack); |
496 | } | ||
594 | 497 | ||
595 | static const hda_nid_t stac9205_pin_nids[12] = { | 498 | static void stac_line_automute(struct hda_codec *codec, |
596 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 499 | struct hda_jack_tbl *jack) |
597 | 0x0f, 0x14, 0x16, 0x17, 0x18, | 500 | { |
598 | 0x21, 0x22, | 501 | snd_hda_gen_line_automute(codec, jack); |
599 | }; | 502 | jack_update_power(codec, jack); |
503 | } | ||
600 | 504 | ||
601 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, | 505 | static void stac_mic_autoswitch(struct hda_codec *codec, |
602 | struct snd_ctl_elem_info *uinfo) | 506 | struct hda_jack_tbl *jack) |
603 | { | 507 | { |
604 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 508 | snd_hda_gen_mic_autoswitch(codec, jack); |
605 | struct sigmatel_spec *spec = codec->spec; | 509 | jack_update_power(codec, jack); |
606 | return snd_hda_input_mux_info(spec->dinput_mux, uinfo); | ||
607 | } | 510 | } |
608 | 511 | ||
609 | static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol, | 512 | static void stac_vref_event(struct hda_codec *codec, struct hda_jack_tbl *event) |
610 | struct snd_ctl_elem_value *ucontrol) | ||
611 | { | 513 | { |
612 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 514 | unsigned int data; |
613 | struct sigmatel_spec *spec = codec->spec; | ||
614 | unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
615 | 515 | ||
616 | ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx]; | 516 | data = snd_hda_codec_read(codec, codec->afg, 0, |
617 | return 0; | 517 | AC_VERB_GET_GPIO_DATA, 0); |
518 | /* toggle VREF state based on GPIOx status */ | ||
519 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, | ||
520 | !!(data & (1 << event->private_data))); | ||
618 | } | 521 | } |
619 | 522 | ||
620 | static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, | 523 | /* initialize the power map and enable the power event to jacks that |
621 | struct snd_ctl_elem_value *ucontrol) | 524 | * haven't been assigned to automute |
525 | */ | ||
526 | static void stac_init_power_map(struct hda_codec *codec) | ||
622 | { | 527 | { |
623 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
624 | struct sigmatel_spec *spec = codec->spec; | 528 | struct sigmatel_spec *spec = codec->spec; |
625 | unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 529 | int i; |
626 | 530 | ||
627 | return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol, | 531 | for (i = 0; i < spec->num_pwrs; i++) { |
628 | spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); | 532 | hda_nid_t nid = spec->pwr_nids[i]; |
533 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
534 | def_conf = get_defcfg_connect(def_conf); | ||
535 | if (snd_hda_jack_tbl_get(codec, nid)) | ||
536 | continue; | ||
537 | if (def_conf == AC_JACK_PORT_COMPLEX && | ||
538 | !(spec->vref_mute_led_nid == nid || | ||
539 | is_jack_detectable(codec, nid))) { | ||
540 | snd_hda_jack_detect_enable_callback(codec, nid, | ||
541 | STAC_PWR_EVENT, | ||
542 | jack_update_power); | ||
543 | } else { | ||
544 | if (def_conf == AC_JACK_PORT_NONE) | ||
545 | stac_toggle_power_map(codec, nid, false, false); | ||
546 | else | ||
547 | stac_toggle_power_map(codec, nid, true, false); | ||
548 | } | ||
549 | } | ||
629 | } | 550 | } |
630 | 551 | ||
631 | static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, | 552 | /* |
632 | struct snd_ctl_elem_info *uinfo) | 553 | */ |
554 | |||
555 | static inline bool get_int_hint(struct hda_codec *codec, const char *key, | ||
556 | int *valp) | ||
633 | { | 557 | { |
634 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 558 | return !snd_hda_get_int_hint(codec, key, valp); |
635 | struct sigmatel_spec *spec = codec->spec; | ||
636 | return snd_hda_input_mux_info(spec->sinput_mux, uinfo); | ||
637 | } | 559 | } |
638 | 560 | ||
639 | static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, | 561 | /* override some hints from the hwdep entry */ |
640 | struct snd_ctl_elem_value *ucontrol) | 562 | static void stac_store_hints(struct hda_codec *codec) |
641 | { | 563 | { |
642 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
643 | struct sigmatel_spec *spec = codec->spec; | 564 | struct sigmatel_spec *spec = codec->spec; |
644 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 565 | int val; |
645 | 566 | ||
646 | ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; | 567 | if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { |
647 | return 0; | 568 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = |
569 | spec->gpio_mask; | ||
570 | } | ||
571 | if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) | ||
572 | spec->gpio_mask &= spec->gpio_mask; | ||
573 | if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) | ||
574 | spec->gpio_dir &= spec->gpio_mask; | ||
575 | if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) | ||
576 | spec->eapd_mask &= spec->gpio_mask; | ||
577 | if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) | ||
578 | spec->gpio_mute &= spec->gpio_mask; | ||
579 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | ||
580 | if (val >= 0) | ||
581 | spec->eapd_switch = val; | ||
648 | } | 582 | } |
649 | 583 | ||
650 | static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | 584 | /* |
651 | struct snd_ctl_elem_value *ucontrol) | 585 | * loopback controls |
586 | */ | ||
587 | |||
588 | #define stac_aloopback_info snd_ctl_boolean_mono_info | ||
589 | |||
590 | static int stac_aloopback_get(struct snd_kcontrol *kcontrol, | ||
591 | struct snd_ctl_elem_value *ucontrol) | ||
652 | { | 592 | { |
653 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 593 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
594 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
654 | struct sigmatel_spec *spec = codec->spec; | 595 | struct sigmatel_spec *spec = codec->spec; |
655 | struct hda_input_mux *smux = &spec->private_smux; | ||
656 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
657 | int err, val; | ||
658 | hda_nid_t nid; | ||
659 | |||
660 | err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, | ||
661 | spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); | ||
662 | if (err < 0) | ||
663 | return err; | ||
664 | 596 | ||
665 | if (spec->spdif_mute) { | 597 | ucontrol->value.integer.value[0] = !!(spec->aloopback & |
666 | if (smux_idx == 0) | 598 | (spec->aloopback_mask << idx)); |
667 | nid = spec->multiout.dig_out_nid; | ||
668 | else | ||
669 | nid = codec->slave_dig_outs[smux_idx - 1]; | ||
670 | if (spec->cur_smux[smux_idx] == smux->num_items - 1) | ||
671 | val = HDA_AMP_MUTE; | ||
672 | else | ||
673 | val = 0; | ||
674 | /* un/mute SPDIF out */ | ||
675 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
676 | HDA_AMP_MUTE, val); | ||
677 | } | ||
678 | return 0; | 599 | return 0; |
679 | } | 600 | } |
680 | 601 | ||
681 | static int stac_vrefout_set(struct hda_codec *codec, | 602 | static int stac_aloopback_put(struct snd_kcontrol *kcontrol, |
682 | hda_nid_t nid, unsigned int new_vref) | 603 | struct snd_ctl_elem_value *ucontrol) |
683 | { | 604 | { |
684 | int error, pinctl; | 605 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
606 | struct sigmatel_spec *spec = codec->spec; | ||
607 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
608 | unsigned int dac_mode; | ||
609 | unsigned int val, idx_val; | ||
685 | 610 | ||
686 | snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref); | 611 | idx_val = spec->aloopback_mask << idx; |
687 | pinctl = snd_hda_codec_read(codec, nid, 0, | 612 | if (ucontrol->value.integer.value[0]) |
688 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 613 | val = spec->aloopback | idx_val; |
614 | else | ||
615 | val = spec->aloopback & ~idx_val; | ||
616 | if (spec->aloopback == val) | ||
617 | return 0; | ||
689 | 618 | ||
690 | if (pinctl < 0) | 619 | spec->aloopback = val; |
691 | return pinctl; | ||
692 | 620 | ||
693 | pinctl &= 0xff; | 621 | /* Only return the bits defined by the shift value of the |
694 | pinctl &= ~AC_PINCTL_VREFEN; | 622 | * first two bytes of the mask |
695 | pinctl |= (new_vref & AC_PINCTL_VREFEN); | 623 | */ |
624 | dac_mode = snd_hda_codec_read(codec, codec->afg, 0, | ||
625 | kcontrol->private_value & 0xFFFF, 0x0); | ||
626 | dac_mode >>= spec->aloopback_shift; | ||
696 | 627 | ||
697 | error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl); | 628 | if (spec->aloopback & idx_val) { |
698 | if (error < 0) | 629 | snd_hda_power_up(codec); |
699 | return error; | 630 | dac_mode |= idx_val; |
631 | } else { | ||
632 | snd_hda_power_down(codec); | ||
633 | dac_mode &= ~idx_val; | ||
634 | } | ||
635 | |||
636 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
637 | kcontrol->private_value >> 16, dac_mode); | ||
700 | 638 | ||
701 | return 1; | 639 | return 1; |
702 | } | 640 | } |
703 | 641 | ||
704 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, | 642 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ |
705 | hda_nid_t nid, unsigned int new_vref) | 643 | { \ |
644 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
645 | .name = "Analog Loopback", \ | ||
646 | .count = cnt, \ | ||
647 | .info = stac_aloopback_info, \ | ||
648 | .get = stac_aloopback_get, \ | ||
649 | .put = stac_aloopback_put, \ | ||
650 | .private_value = verb_read | (verb_write << 16), \ | ||
651 | } | ||
652 | |||
653 | /* | ||
654 | * Mute LED handling on HP laptops | ||
655 | */ | ||
656 | |||
657 | /* check whether it's a HP laptop with a docking port */ | ||
658 | static bool hp_bnb2011_with_dock(struct hda_codec *codec) | ||
706 | { | 659 | { |
707 | int error; | 660 | if (codec->vendor_id != 0x111d7605 && |
708 | unsigned int pincfg; | 661 | codec->vendor_id != 0x111d76d1) |
709 | pincfg = snd_hda_codec_read(codec, nid, 0, | 662 | return false; |
710 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
711 | 663 | ||
712 | pincfg &= 0xff; | 664 | switch (codec->subsystem_id) { |
713 | pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | 665 | case 0x103c1618: |
714 | pincfg |= new_vref; | 666 | case 0x103c1619: |
667 | case 0x103c161a: | ||
668 | case 0x103c161b: | ||
669 | case 0x103c161c: | ||
670 | case 0x103c161d: | ||
671 | case 0x103c161e: | ||
672 | case 0x103c161f: | ||
715 | 673 | ||
716 | if (new_vref == AC_PINCTL_VREF_HIZ) | 674 | case 0x103c162a: |
717 | pincfg |= AC_PINCTL_OUT_EN; | 675 | case 0x103c162b: |
718 | else | ||
719 | pincfg |= AC_PINCTL_IN_EN; | ||
720 | 676 | ||
721 | error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg); | 677 | case 0x103c1630: |
722 | if (error < 0) | 678 | case 0x103c1631: |
723 | return error; | 679 | |
724 | else | 680 | case 0x103c1633: |
725 | return 1; | 681 | case 0x103c1634: |
682 | case 0x103c1635: | ||
683 | |||
684 | case 0x103c3587: | ||
685 | case 0x103c3588: | ||
686 | case 0x103c3589: | ||
687 | case 0x103c358a: | ||
688 | |||
689 | case 0x103c3667: | ||
690 | case 0x103c3668: | ||
691 | case 0x103c3669: | ||
692 | |||
693 | return true; | ||
694 | } | ||
695 | return false; | ||
726 | } | 696 | } |
727 | 697 | ||
728 | static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid) | 698 | static bool hp_blike_system(u32 subsystem_id) |
729 | { | 699 | { |
730 | unsigned int vref; | 700 | switch (subsystem_id) { |
731 | vref = snd_hda_codec_read(codec, nid, 0, | 701 | case 0x103c1520: |
732 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 702 | case 0x103c1521: |
733 | vref &= AC_PINCTL_VREFEN; | 703 | case 0x103c1523: |
734 | return vref; | 704 | case 0x103c1524: |
705 | case 0x103c1525: | ||
706 | case 0x103c1722: | ||
707 | case 0x103c1723: | ||
708 | case 0x103c1724: | ||
709 | case 0x103c1725: | ||
710 | case 0x103c1726: | ||
711 | case 0x103c1727: | ||
712 | case 0x103c1728: | ||
713 | case 0x103c1729: | ||
714 | case 0x103c172a: | ||
715 | case 0x103c172b: | ||
716 | case 0x103c307e: | ||
717 | case 0x103c307f: | ||
718 | case 0x103c3080: | ||
719 | case 0x103c3081: | ||
720 | case 0x103c7007: | ||
721 | case 0x103c7008: | ||
722 | return true; | ||
723 | } | ||
724 | return false; | ||
735 | } | 725 | } |
736 | 726 | ||
737 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 727 | static void set_hp_led_gpio(struct hda_codec *codec) |
738 | { | 728 | { |
739 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
740 | struct sigmatel_spec *spec = codec->spec; | 729 | struct sigmatel_spec *spec = codec->spec; |
741 | return snd_hda_input_mux_info(spec->input_mux, uinfo); | 730 | unsigned int gpio; |
731 | |||
732 | if (spec->gpio_led) | ||
733 | return; | ||
734 | |||
735 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); | ||
736 | gpio &= AC_GPIO_IO_COUNT; | ||
737 | if (gpio > 3) | ||
738 | spec->gpio_led = 0x08; /* GPIO 3 */ | ||
739 | else | ||
740 | spec->gpio_led = 0x01; /* GPIO 0 */ | ||
742 | } | 741 | } |
743 | 742 | ||
744 | static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 743 | /* |
744 | * This method searches for the mute LED GPIO configuration | ||
745 | * provided as OEM string in SMBIOS. The format of that string | ||
746 | * is HP_Mute_LED_P_G or HP_Mute_LED_P | ||
747 | * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) | ||
748 | * that corresponds to the NOT muted state of the master volume | ||
749 | * and G is the index of the GPIO to use as the mute LED control (0..9) | ||
750 | * If _G portion is missing it is assigned based on the codec ID | ||
751 | * | ||
752 | * So, HP B-series like systems may have HP_Mute_LED_0 (current models) | ||
753 | * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings | ||
754 | * | ||
755 | * | ||
756 | * The dv-series laptops don't seem to have the HP_Mute_LED* strings in | ||
757 | * SMBIOS - at least the ones I have seen do not have them - which include | ||
758 | * my own system (HP Pavilion dv6-1110ax) and my cousin's | ||
759 | * HP Pavilion dv9500t CTO. | ||
760 | * Need more information on whether it is true across the entire series. | ||
761 | * -- kunal | ||
762 | */ | ||
763 | static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | ||
745 | { | 764 | { |
746 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
747 | struct sigmatel_spec *spec = codec->spec; | 765 | struct sigmatel_spec *spec = codec->spec; |
748 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 766 | const struct dmi_device *dev = NULL; |
749 | 767 | ||
750 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; | 768 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { |
769 | get_int_hint(codec, "gpio_led_polarity", | ||
770 | &spec->gpio_led_polarity); | ||
771 | return 1; | ||
772 | } | ||
773 | |||
774 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | ||
775 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", | ||
776 | &spec->gpio_led_polarity, | ||
777 | &spec->gpio_led) == 2) { | ||
778 | unsigned int max_gpio; | ||
779 | max_gpio = snd_hda_param_read(codec, codec->afg, | ||
780 | AC_PAR_GPIO_CAP); | ||
781 | max_gpio &= AC_GPIO_IO_COUNT; | ||
782 | if (spec->gpio_led < max_gpio) | ||
783 | spec->gpio_led = 1 << spec->gpio_led; | ||
784 | else | ||
785 | spec->vref_mute_led_nid = spec->gpio_led; | ||
786 | return 1; | ||
787 | } | ||
788 | if (sscanf(dev->name, "HP_Mute_LED_%d", | ||
789 | &spec->gpio_led_polarity) == 1) { | ||
790 | set_hp_led_gpio(codec); | ||
791 | return 1; | ||
792 | } | ||
793 | /* BIOS bug: unfilled OEM string */ | ||
794 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { | ||
795 | set_hp_led_gpio(codec); | ||
796 | if (default_polarity >= 0) | ||
797 | spec->gpio_led_polarity = default_polarity; | ||
798 | else | ||
799 | spec->gpio_led_polarity = 1; | ||
800 | return 1; | ||
801 | } | ||
802 | } | ||
803 | |||
804 | /* | ||
805 | * Fallback case - if we don't find the DMI strings, | ||
806 | * we statically set the GPIO - if not a B-series system | ||
807 | * and default polarity is provided | ||
808 | */ | ||
809 | if (!hp_blike_system(codec->subsystem_id) && | ||
810 | (default_polarity == 0 || default_polarity == 1)) { | ||
811 | set_hp_led_gpio(codec); | ||
812 | spec->gpio_led_polarity = default_polarity; | ||
813 | return 1; | ||
814 | } | ||
751 | return 0; | 815 | return 0; |
752 | } | 816 | } |
753 | 817 | ||
754 | static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 818 | /* |
819 | * PC beep controls | ||
820 | */ | ||
821 | |||
822 | /* create PC beep volume controls */ | ||
823 | static int stac_auto_create_beep_ctls(struct hda_codec *codec, | ||
824 | hda_nid_t nid) | ||
755 | { | 825 | { |
756 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
757 | struct sigmatel_spec *spec = codec->spec; | 826 | struct sigmatel_spec *spec = codec->spec; |
758 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 827 | u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
759 | const struct hda_input_mux *imux = spec->input_mux; | 828 | struct snd_kcontrol_new *knew; |
760 | unsigned int idx, prev_idx, didx; | 829 | static struct snd_kcontrol_new abeep_mute_ctl = |
761 | 830 | HDA_CODEC_MUTE(NULL, 0, 0, 0); | |
762 | idx = ucontrol->value.enumerated.item[0]; | 831 | static struct snd_kcontrol_new dbeep_mute_ctl = |
763 | if (idx >= imux->num_items) | 832 | HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0); |
764 | idx = imux->num_items - 1; | 833 | static struct snd_kcontrol_new beep_vol_ctl = |
765 | prev_idx = spec->cur_mux[adc_idx]; | 834 | HDA_CODEC_VOLUME(NULL, 0, 0, 0); |
766 | if (prev_idx == idx) | 835 | |
767 | return 0; | 836 | /* check for mute support for the the amp */ |
768 | if (idx < spec->num_analog_muxes) { | 837 | if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { |
769 | snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, | 838 | const struct snd_kcontrol_new *temp; |
770 | AC_VERB_SET_CONNECT_SEL, | 839 | if (spec->anabeep_nid == nid) |
771 | imux->items[idx].index); | 840 | temp = &abeep_mute_ctl; |
772 | if (prev_idx >= spec->num_analog_muxes && | 841 | else |
773 | spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) { | 842 | temp = &dbeep_mute_ctl; |
774 | imux = spec->dinput_mux; | 843 | knew = snd_hda_gen_add_kctl(&spec->gen, |
775 | /* 0 = analog */ | 844 | "Beep Playback Switch", temp); |
776 | snd_hda_codec_write_cache(codec, | 845 | if (!knew) |
777 | spec->dmux_nids[adc_idx], 0, | 846 | return -ENOMEM; |
778 | AC_VERB_SET_CONNECT_SEL, | 847 | knew->private_value = |
779 | imux->items[0].index); | 848 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT); |
780 | } | ||
781 | } else { | ||
782 | imux = spec->dinput_mux; | ||
783 | /* first dimux item is hardcoded to select analog imux, | ||
784 | * so lets skip it | ||
785 | */ | ||
786 | didx = idx - spec->num_analog_muxes + 1; | ||
787 | snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, | ||
788 | AC_VERB_SET_CONNECT_SEL, | ||
789 | imux->items[didx].index); | ||
790 | } | 849 | } |
791 | spec->cur_mux[adc_idx] = idx; | 850 | |
792 | return 1; | 851 | /* check to see if there is volume support for the amp */ |
852 | if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
853 | knew = snd_hda_gen_add_kctl(&spec->gen, | ||
854 | "Beep Playback Volume", | ||
855 | &beep_vol_ctl); | ||
856 | if (!knew) | ||
857 | return -ENOMEM; | ||
858 | knew->private_value = | ||
859 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT); | ||
860 | } | ||
861 | return 0; | ||
793 | } | 862 | } |
794 | 863 | ||
795 | static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, | 864 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
796 | struct snd_ctl_elem_info *uinfo) | 865 | #define stac_dig_beep_switch_info snd_ctl_boolean_mono_info |
866 | |||
867 | static int stac_dig_beep_switch_get(struct snd_kcontrol *kcontrol, | ||
868 | struct snd_ctl_elem_value *ucontrol) | ||
797 | { | 869 | { |
798 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 870 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
799 | struct sigmatel_spec *spec = codec->spec; | 871 | ucontrol->value.integer.value[0] = codec->beep->enabled; |
800 | return snd_hda_input_mux_info(spec->mono_mux, uinfo); | 872 | return 0; |
801 | } | 873 | } |
802 | 874 | ||
803 | static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol, | 875 | static int stac_dig_beep_switch_put(struct snd_kcontrol *kcontrol, |
804 | struct snd_ctl_elem_value *ucontrol) | 876 | struct snd_ctl_elem_value *ucontrol) |
805 | { | 877 | { |
806 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 878 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
879 | return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); | ||
880 | } | ||
881 | |||
882 | static const struct snd_kcontrol_new stac_dig_beep_ctrl = { | ||
883 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
884 | .name = "Beep Playback Switch", | ||
885 | .info = stac_dig_beep_switch_info, | ||
886 | .get = stac_dig_beep_switch_get, | ||
887 | .put = stac_dig_beep_switch_put, | ||
888 | }; | ||
889 | |||
890 | static int stac_beep_switch_ctl(struct hda_codec *codec) | ||
891 | { | ||
807 | struct sigmatel_spec *spec = codec->spec; | 892 | struct sigmatel_spec *spec = codec->spec; |
808 | 893 | ||
809 | ucontrol->value.enumerated.item[0] = spec->cur_mmux; | 894 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_dig_beep_ctrl)) |
895 | return -ENOMEM; | ||
810 | return 0; | 896 | return 0; |
811 | } | 897 | } |
898 | #endif | ||
899 | |||
900 | /* | ||
901 | * SPDIF-out mux controls | ||
902 | */ | ||
812 | 903 | ||
813 | static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, | 904 | static int stac_smux_enum_info(struct snd_kcontrol *kcontrol, |
814 | struct snd_ctl_elem_value *ucontrol) | 905 | struct snd_ctl_elem_info *uinfo) |
815 | { | 906 | { |
816 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 907 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
817 | struct sigmatel_spec *spec = codec->spec; | 908 | struct sigmatel_spec *spec = codec->spec; |
818 | 909 | return snd_hda_input_mux_info(&spec->spdif_mux, uinfo); | |
819 | return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol, | ||
820 | spec->mono_nid, &spec->cur_mmux); | ||
821 | } | 910 | } |
822 | 911 | ||
823 | #define stac92xx_aloopback_info snd_ctl_boolean_mono_info | 912 | static int stac_smux_enum_get(struct snd_kcontrol *kcontrol, |
824 | 913 | struct snd_ctl_elem_value *ucontrol) | |
825 | static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, | ||
826 | struct snd_ctl_elem_value *ucontrol) | ||
827 | { | 914 | { |
828 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 915 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
829 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
830 | struct sigmatel_spec *spec = codec->spec; | 916 | struct sigmatel_spec *spec = codec->spec; |
917 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
831 | 918 | ||
832 | ucontrol->value.integer.value[0] = !!(spec->aloopback & | 919 | ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; |
833 | (spec->aloopback_mask << idx)); | ||
834 | return 0; | 920 | return 0; |
835 | } | 921 | } |
836 | 922 | ||
837 | static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, | 923 | static int stac_smux_enum_put(struct snd_kcontrol *kcontrol, |
838 | struct snd_ctl_elem_value *ucontrol) | 924 | struct snd_ctl_elem_value *ucontrol) |
839 | { | 925 | { |
840 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 926 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
841 | struct sigmatel_spec *spec = codec->spec; | 927 | struct sigmatel_spec *spec = codec->spec; |
842 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 928 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
843 | unsigned int dac_mode; | ||
844 | unsigned int val, idx_val; | ||
845 | 929 | ||
846 | idx_val = spec->aloopback_mask << idx; | 930 | return snd_hda_input_mux_put(codec, &spec->spdif_mux, ucontrol, |
847 | if (ucontrol->value.integer.value[0]) | 931 | spec->gen.autocfg.dig_out_pins[smux_idx], |
848 | val = spec->aloopback | idx_val; | 932 | &spec->cur_smux[smux_idx]); |
849 | else | 933 | } |
850 | val = spec->aloopback & ~idx_val; | ||
851 | if (spec->aloopback == val) | ||
852 | return 0; | ||
853 | 934 | ||
854 | spec->aloopback = val; | 935 | static struct snd_kcontrol_new stac_smux_mixer = { |
936 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
937 | .name = "IEC958 Playback Source", | ||
938 | /* count set later */ | ||
939 | .info = stac_smux_enum_info, | ||
940 | .get = stac_smux_enum_get, | ||
941 | .put = stac_smux_enum_put, | ||
942 | }; | ||
855 | 943 | ||
856 | /* Only return the bits defined by the shift value of the | 944 | static const char * const stac_spdif_labels[] = { |
857 | * first two bytes of the mask | 945 | "Digital Playback", "Analog Mux 1", "Analog Mux 2", NULL |
858 | */ | 946 | }; |
859 | dac_mode = snd_hda_codec_read(codec, codec->afg, 0, | ||
860 | kcontrol->private_value & 0xFFFF, 0x0); | ||
861 | dac_mode >>= spec->aloopback_shift; | ||
862 | 947 | ||
863 | if (spec->aloopback & idx_val) { | 948 | static int stac_create_spdif_mux_ctls(struct hda_codec *codec) |
864 | snd_hda_power_up(codec); | 949 | { |
865 | dac_mode |= idx_val; | 950 | struct sigmatel_spec *spec = codec->spec; |
866 | } else { | 951 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
867 | snd_hda_power_down(codec); | 952 | const char * const *labels = spec->spdif_labels; |
868 | dac_mode &= ~idx_val; | 953 | struct snd_kcontrol_new *kctl; |
954 | int i, num_cons; | ||
955 | |||
956 | if (cfg->dig_outs < 1) | ||
957 | return 0; | ||
958 | |||
959 | num_cons = snd_hda_get_num_conns(codec, cfg->dig_out_pins[0]); | ||
960 | if (num_cons <= 1) | ||
961 | return 0; | ||
962 | |||
963 | if (!labels) | ||
964 | labels = stac_spdif_labels; | ||
965 | for (i = 0; i < num_cons; i++) { | ||
966 | if (snd_BUG_ON(!labels[i])) | ||
967 | return -EINVAL; | ||
968 | snd_hda_add_imux_item(&spec->spdif_mux, labels[i], i, NULL); | ||
869 | } | 969 | } |
870 | 970 | ||
871 | snd_hda_codec_write_cache(codec, codec->afg, 0, | 971 | kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer); |
872 | kcontrol->private_value >> 16, dac_mode); | 972 | if (!kctl) |
973 | return -ENOMEM; | ||
974 | kctl->count = cfg->dig_outs; | ||
873 | 975 | ||
874 | return 1; | 976 | return 0; |
875 | } | 977 | } |
876 | 978 | ||
979 | /* | ||
980 | */ | ||
981 | |||
877 | static const struct hda_verb stac9200_core_init[] = { | 982 | static const struct hda_verb stac9200_core_init[] = { |
878 | /* set dac0mux for dac converter */ | 983 | /* set dac0mux for dac converter */ |
879 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 984 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -936,17 +1041,15 @@ static const struct hda_verb stac925x_core_init[] = { | |||
936 | }; | 1041 | }; |
937 | 1042 | ||
938 | static const struct hda_verb stac922x_core_init[] = { | 1043 | static const struct hda_verb stac922x_core_init[] = { |
939 | /* set master volume and direct control */ | 1044 | /* set master volume and direct control */ |
940 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 1045 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
941 | {} | 1046 | {} |
942 | }; | 1047 | }; |
943 | 1048 | ||
944 | static const struct hda_verb d965_core_init[] = { | 1049 | static const struct hda_verb d965_core_init[] = { |
945 | /* set master volume and direct control */ | ||
946 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
947 | /* unmute node 0x1b */ | 1050 | /* unmute node 0x1b */ |
948 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 1051 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
949 | /* select node 0x03 as DAC */ | 1052 | /* select node 0x03 as DAC */ |
950 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, | 1053 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, |
951 | {} | 1054 | {} |
952 | }; | 1055 | }; |
@@ -962,7 +1065,7 @@ static const struct hda_verb dell_3st_core_init[] = { | |||
962 | }; | 1065 | }; |
963 | 1066 | ||
964 | static const struct hda_verb stac927x_core_init[] = { | 1067 | static const struct hda_verb stac927x_core_init[] = { |
965 | /* set master volume and direct control */ | 1068 | /* set master volume and direct control */ |
966 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 1069 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
967 | /* enable analog pc beep path */ | 1070 | /* enable analog pc beep path */ |
968 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | 1071 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, |
@@ -978,261 +1081,103 @@ static const struct hda_verb stac927x_volknob_core_init[] = { | |||
978 | }; | 1081 | }; |
979 | 1082 | ||
980 | static const struct hda_verb stac9205_core_init[] = { | 1083 | static const struct hda_verb stac9205_core_init[] = { |
981 | /* set master volume and direct control */ | 1084 | /* set master volume and direct control */ |
982 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 1085 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
983 | /* enable analog pc beep path */ | 1086 | /* enable analog pc beep path */ |
984 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | 1087 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, |
985 | {} | 1088 | {} |
986 | }; | 1089 | }; |
987 | 1090 | ||
988 | #define STAC_MONO_MUX \ | 1091 | static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback = |
989 | { \ | 1092 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3); |
990 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
991 | .name = "Mono Mux", \ | ||
992 | .count = 1, \ | ||
993 | .info = stac92xx_mono_mux_enum_info, \ | ||
994 | .get = stac92xx_mono_mux_enum_get, \ | ||
995 | .put = stac92xx_mono_mux_enum_put, \ | ||
996 | } | ||
997 | 1093 | ||
998 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ | 1094 | static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback = |
999 | { \ | 1095 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4); |
1000 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1001 | .name = "Analog Loopback", \ | ||
1002 | .count = cnt, \ | ||
1003 | .info = stac92xx_aloopback_info, \ | ||
1004 | .get = stac92xx_aloopback_get, \ | ||
1005 | .put = stac92xx_aloopback_put, \ | ||
1006 | .private_value = verb_read | (verb_write << 16), \ | ||
1007 | } | ||
1008 | 1096 | ||
1009 | #define DC_BIAS(xname, idx, nid) \ | 1097 | static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback = |
1010 | { \ | 1098 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5); |
1011 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1012 | .name = xname, \ | ||
1013 | .index = idx, \ | ||
1014 | .info = stac92xx_dc_bias_info, \ | ||
1015 | .get = stac92xx_dc_bias_get, \ | ||
1016 | .put = stac92xx_dc_bias_put, \ | ||
1017 | .private_value = nid, \ | ||
1018 | } | ||
1019 | 1099 | ||
1020 | static const struct snd_kcontrol_new stac9200_mixer[] = { | 1100 | static const struct snd_kcontrol_new stac92hd71bxx_loopback = |
1021 | HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT), | 1101 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2); |
1022 | HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT), | ||
1023 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | ||
1024 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | ||
1025 | { } /* end */ | ||
1026 | }; | ||
1027 | 1102 | ||
1028 | static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { | 1103 | static const struct snd_kcontrol_new stac9205_loopback = |
1029 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | 1104 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1); |
1030 | {} | ||
1031 | }; | ||
1032 | 1105 | ||
1033 | static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { | 1106 | static const struct snd_kcontrol_new stac927x_loopback = |
1034 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), | 1107 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1); |
1035 | {} | ||
1036 | }; | ||
1037 | 1108 | ||
1038 | static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | 1109 | static const struct hda_pintbl ref9200_pin_configs[] = { |
1039 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | 1110 | { 0x08, 0x01c47010 }, |
1111 | { 0x09, 0x01447010 }, | ||
1112 | { 0x0d, 0x0221401f }, | ||
1113 | { 0x0e, 0x01114010 }, | ||
1114 | { 0x0f, 0x02a19020 }, | ||
1115 | { 0x10, 0x01a19021 }, | ||
1116 | { 0x11, 0x90100140 }, | ||
1117 | { 0x12, 0x01813122 }, | ||
1040 | {} | 1118 | {} |
1041 | }; | 1119 | }; |
1042 | 1120 | ||
1043 | 1121 | static const struct hda_pintbl gateway9200_m4_pin_configs[] = { | |
1044 | static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | 1122 | { 0x08, 0x400000fe }, |
1045 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) | 1123 | { 0x09, 0x404500f4 }, |
1046 | }; | 1124 | { 0x0d, 0x400100f0 }, |
1047 | 1125 | { 0x0e, 0x90110010 }, | |
1048 | static const struct snd_kcontrol_new stac925x_mixer[] = { | 1126 | { 0x0f, 0x400100f1 }, |
1049 | HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT), | 1127 | { 0x10, 0x02a1902e }, |
1050 | HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1128 | { 0x11, 0x500000f2 }, |
1051 | { } /* end */ | 1129 | { 0x12, 0x500000f3 }, |
1052 | }; | ||
1053 | |||
1054 | static const struct snd_kcontrol_new stac9205_loopback[] = { | ||
1055 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | ||
1056 | {} | 1130 | {} |
1057 | }; | 1131 | }; |
1058 | 1132 | ||
1059 | static const struct snd_kcontrol_new stac927x_loopback[] = { | 1133 | static const struct hda_pintbl gateway9200_m4_2_pin_configs[] = { |
1060 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1134 | { 0x08, 0x400000fe }, |
1135 | { 0x09, 0x404500f4 }, | ||
1136 | { 0x0d, 0x400100f0 }, | ||
1137 | { 0x0e, 0x90110010 }, | ||
1138 | { 0x0f, 0x400100f1 }, | ||
1139 | { 0x10, 0x02a1902e }, | ||
1140 | { 0x11, 0x500000f2 }, | ||
1141 | { 0x12, 0x500000f3 }, | ||
1061 | {} | 1142 | {} |
1062 | }; | 1143 | }; |
1063 | 1144 | ||
1064 | static struct snd_kcontrol_new stac_dmux_mixer = { | ||
1065 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1066 | .name = "Digital Input Source", | ||
1067 | /* count set later */ | ||
1068 | .info = stac92xx_dmux_enum_info, | ||
1069 | .get = stac92xx_dmux_enum_get, | ||
1070 | .put = stac92xx_dmux_enum_put, | ||
1071 | }; | ||
1072 | |||
1073 | static struct snd_kcontrol_new stac_smux_mixer = { | ||
1074 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1075 | .name = "IEC958 Playback Source", | ||
1076 | /* count set later */ | ||
1077 | .info = stac92xx_smux_enum_info, | ||
1078 | .get = stac92xx_smux_enum_get, | ||
1079 | .put = stac92xx_smux_enum_put, | ||
1080 | }; | ||
1081 | |||
1082 | static const char * const slave_pfxs[] = { | ||
1083 | "Front", "Surround", "Center", "LFE", "Side", | ||
1084 | "Headphone", "Speaker", "Bass Speaker", "IEC958", "PCM", | ||
1085 | NULL | ||
1086 | }; | ||
1087 | |||
1088 | static void stac92xx_update_led_status(struct hda_codec *codec, int enabled); | ||
1089 | |||
1090 | static void stac92xx_vmaster_hook(void *private_data, int val) | ||
1091 | { | ||
1092 | stac92xx_update_led_status(private_data, val); | ||
1093 | } | ||
1094 | |||
1095 | static void stac92xx_free_kctls(struct hda_codec *codec); | ||
1096 | |||
1097 | static int stac92xx_build_controls(struct hda_codec *codec) | ||
1098 | { | ||
1099 | struct sigmatel_spec *spec = codec->spec; | ||
1100 | unsigned int vmaster_tlv[4]; | ||
1101 | int err; | ||
1102 | int i; | ||
1103 | |||
1104 | if (spec->mixer) { | ||
1105 | err = snd_hda_add_new_ctls(codec, spec->mixer); | ||
1106 | if (err < 0) | ||
1107 | return err; | ||
1108 | } | ||
1109 | |||
1110 | for (i = 0; i < spec->num_mixers; i++) { | ||
1111 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | ||
1112 | if (err < 0) | ||
1113 | return err; | ||
1114 | } | ||
1115 | if (!spec->auto_mic && spec->num_dmuxes > 0 && | ||
1116 | snd_hda_get_bool_hint(codec, "separate_dmux") == 1) { | ||
1117 | stac_dmux_mixer.count = spec->num_dmuxes; | ||
1118 | err = snd_hda_ctl_add(codec, 0, | ||
1119 | snd_ctl_new1(&stac_dmux_mixer, codec)); | ||
1120 | if (err < 0) | ||
1121 | return err; | ||
1122 | } | ||
1123 | if (spec->num_smuxes > 0) { | ||
1124 | int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); | ||
1125 | struct hda_input_mux *smux = &spec->private_smux; | ||
1126 | /* check for mute support on SPDIF out */ | ||
1127 | if (wcaps & AC_WCAP_OUT_AMP) { | ||
1128 | snd_hda_add_imux_item(smux, "Off", 0, NULL); | ||
1129 | spec->spdif_mute = 1; | ||
1130 | } | ||
1131 | stac_smux_mixer.count = spec->num_smuxes; | ||
1132 | err = snd_hda_ctl_add(codec, 0, | ||
1133 | snd_ctl_new1(&stac_smux_mixer, codec)); | ||
1134 | if (err < 0) | ||
1135 | return err; | ||
1136 | } | ||
1137 | |||
1138 | if (spec->multiout.dig_out_nid) { | ||
1139 | err = snd_hda_create_dig_out_ctls(codec, | ||
1140 | spec->multiout.dig_out_nid, | ||
1141 | spec->multiout.dig_out_nid, | ||
1142 | spec->autocfg.dig_out_type[0]); | ||
1143 | if (err < 0) | ||
1144 | return err; | ||
1145 | err = snd_hda_create_spdif_share_sw(codec, | ||
1146 | &spec->multiout); | ||
1147 | if (err < 0) | ||
1148 | return err; | ||
1149 | spec->multiout.share_spdif = 1; | ||
1150 | } | ||
1151 | if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { | ||
1152 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
1153 | if (err < 0) | ||
1154 | return err; | ||
1155 | } | ||
1156 | |||
1157 | /* if we have no master control, let's create it */ | ||
1158 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | ||
1159 | HDA_OUTPUT, vmaster_tlv); | ||
1160 | /* correct volume offset */ | ||
1161 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | ||
1162 | /* minimum value is actually mute */ | ||
1163 | vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; | ||
1164 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | ||
1165 | vmaster_tlv, slave_pfxs, | ||
1166 | "Playback Volume"); | ||
1167 | if (err < 0) | ||
1168 | return err; | ||
1169 | |||
1170 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", | ||
1171 | NULL, slave_pfxs, | ||
1172 | "Playback Switch", true, | ||
1173 | &spec->vmaster_mute.sw_kctl); | ||
1174 | if (err < 0) | ||
1175 | return err; | ||
1176 | |||
1177 | if (spec->gpio_led) { | ||
1178 | spec->vmaster_mute.hook = stac92xx_vmaster_hook; | ||
1179 | err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); | ||
1180 | if (err < 0) | ||
1181 | return err; | ||
1182 | } | ||
1183 | |||
1184 | if (spec->aloopback_ctl && | ||
1185 | snd_hda_get_bool_hint(codec, "loopback") == 1) { | ||
1186 | err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl); | ||
1187 | if (err < 0) | ||
1188 | return err; | ||
1189 | } | ||
1190 | |||
1191 | stac92xx_free_kctls(codec); /* no longer needed */ | ||
1192 | |||
1193 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1194 | if (err < 0) | ||
1195 | return err; | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static const unsigned int ref9200_pin_configs[8] = { | ||
1201 | 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, | ||
1202 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | ||
1203 | }; | ||
1204 | |||
1205 | static const unsigned int gateway9200_m4_pin_configs[8] = { | ||
1206 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | ||
1207 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | ||
1208 | }; | ||
1209 | static const unsigned int gateway9200_m4_2_pin_configs[8] = { | ||
1210 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | ||
1211 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | ||
1212 | }; | ||
1213 | |||
1214 | /* | 1145 | /* |
1215 | STAC 9200 pin configs for | 1146 | STAC 9200 pin configs for |
1216 | 102801A8 | 1147 | 102801A8 |
1217 | 102801DE | 1148 | 102801DE |
1218 | 102801E8 | 1149 | 102801E8 |
1219 | */ | 1150 | */ |
1220 | static const unsigned int dell9200_d21_pin_configs[8] = { | 1151 | static const struct hda_pintbl dell9200_d21_pin_configs[] = { |
1221 | 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, | 1152 | { 0x08, 0x400001f0 }, |
1222 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | 1153 | { 0x09, 0x400001f1 }, |
1154 | { 0x0d, 0x02214030 }, | ||
1155 | { 0x0e, 0x01014010 }, | ||
1156 | { 0x0f, 0x02a19020 }, | ||
1157 | { 0x10, 0x01a19021 }, | ||
1158 | { 0x11, 0x90100140 }, | ||
1159 | { 0x12, 0x01813122 }, | ||
1160 | {} | ||
1223 | }; | 1161 | }; |
1224 | 1162 | ||
1225 | /* | 1163 | /* |
1226 | STAC 9200 pin configs for | 1164 | STAC 9200 pin configs for |
1227 | 102801C0 | 1165 | 102801C0 |
1228 | 102801C1 | 1166 | 102801C1 |
1229 | */ | 1167 | */ |
1230 | static const unsigned int dell9200_d22_pin_configs[8] = { | 1168 | static const struct hda_pintbl dell9200_d22_pin_configs[] = { |
1231 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, | 1169 | { 0x08, 0x400001f0 }, |
1232 | 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, | 1170 | { 0x09, 0x400001f1 }, |
1171 | { 0x0d, 0x0221401f }, | ||
1172 | { 0x0e, 0x01014010 }, | ||
1173 | { 0x0f, 0x01813020 }, | ||
1174 | { 0x10, 0x02a19021 }, | ||
1175 | { 0x11, 0x90100140 }, | ||
1176 | { 0x12, 0x400001f2 }, | ||
1177 | {} | ||
1233 | }; | 1178 | }; |
1234 | 1179 | ||
1235 | /* | 1180 | /* |
1236 | STAC 9200 pin configs for | 1181 | STAC 9200 pin configs for |
1237 | 102801C4 (Dell Dimension E310) | 1182 | 102801C4 (Dell Dimension E310) |
1238 | 102801C5 | 1183 | 102801C5 |
@@ -1241,9 +1186,16 @@ static const unsigned int dell9200_d22_pin_configs[8] = { | |||
1241 | 102801DA | 1186 | 102801DA |
1242 | 102801E3 | 1187 | 102801E3 |
1243 | */ | 1188 | */ |
1244 | static const unsigned int dell9200_d23_pin_configs[8] = { | 1189 | static const struct hda_pintbl dell9200_d23_pin_configs[] = { |
1245 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, | 1190 | { 0x08, 0x400001f0 }, |
1246 | 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, | 1191 | { 0x09, 0x400001f1 }, |
1192 | { 0x0d, 0x0221401f }, | ||
1193 | { 0x0e, 0x01014010 }, | ||
1194 | { 0x0f, 0x01813020 }, | ||
1195 | { 0x10, 0x01a19021 }, | ||
1196 | { 0x11, 0x90100140 }, | ||
1197 | { 0x12, 0x400001f2 }, | ||
1198 | {} | ||
1247 | }; | 1199 | }; |
1248 | 1200 | ||
1249 | 1201 | ||
@@ -1252,9 +1204,16 @@ static const unsigned int dell9200_d23_pin_configs[8] = { | |||
1252 | 102801B5 (Dell Inspiron 630m) | 1204 | 102801B5 (Dell Inspiron 630m) |
1253 | 102801D8 (Dell Inspiron 640m) | 1205 | 102801D8 (Dell Inspiron 640m) |
1254 | */ | 1206 | */ |
1255 | static const unsigned int dell9200_m21_pin_configs[8] = { | 1207 | static const struct hda_pintbl dell9200_m21_pin_configs[] = { |
1256 | 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, | 1208 | { 0x08, 0x40c003fa }, |
1257 | 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, | 1209 | { 0x09, 0x03441340 }, |
1210 | { 0x0d, 0x0321121f }, | ||
1211 | { 0x0e, 0x90170310 }, | ||
1212 | { 0x0f, 0x408003fb }, | ||
1213 | { 0x10, 0x03a11020 }, | ||
1214 | { 0x11, 0x401003fc }, | ||
1215 | { 0x12, 0x403003fd }, | ||
1216 | {} | ||
1258 | }; | 1217 | }; |
1259 | 1218 | ||
1260 | /* | 1219 | /* |
@@ -1265,9 +1224,16 @@ static const unsigned int dell9200_m21_pin_configs[8] = { | |||
1265 | 102801D4 | 1224 | 102801D4 |
1266 | 102801D6 | 1225 | 102801D6 |
1267 | */ | 1226 | */ |
1268 | static const unsigned int dell9200_m22_pin_configs[8] = { | 1227 | static const struct hda_pintbl dell9200_m22_pin_configs[] = { |
1269 | 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, | 1228 | { 0x08, 0x40c003fa }, |
1270 | 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, | 1229 | { 0x09, 0x0144131f }, |
1230 | { 0x0d, 0x0321121f }, | ||
1231 | { 0x0e, 0x90170310 }, | ||
1232 | { 0x0f, 0x90a70321 }, | ||
1233 | { 0x10, 0x03a11020 }, | ||
1234 | { 0x11, 0x401003fb }, | ||
1235 | { 0x12, 0x40f000fc }, | ||
1236 | {} | ||
1271 | }; | 1237 | }; |
1272 | 1238 | ||
1273 | /* | 1239 | /* |
@@ -1275,9 +1241,16 @@ static const unsigned int dell9200_m22_pin_configs[8] = { | |||
1275 | 102801CE (Dell XPS M1710) | 1241 | 102801CE (Dell XPS M1710) |
1276 | 102801CF (Dell Precision M90) | 1242 | 102801CF (Dell Precision M90) |
1277 | */ | 1243 | */ |
1278 | static const unsigned int dell9200_m23_pin_configs[8] = { | 1244 | static const struct hda_pintbl dell9200_m23_pin_configs[] = { |
1279 | 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, | 1245 | { 0x08, 0x40c003fa }, |
1280 | 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, | 1246 | { 0x09, 0x01441340 }, |
1247 | { 0x0d, 0x0421421f }, | ||
1248 | { 0x0e, 0x90170310 }, | ||
1249 | { 0x0f, 0x408003fb }, | ||
1250 | { 0x10, 0x04a1102e }, | ||
1251 | { 0x11, 0x90170311 }, | ||
1252 | { 0x12, 0x403003fc }, | ||
1253 | {} | ||
1281 | }; | 1254 | }; |
1282 | 1255 | ||
1283 | /* | 1256 | /* |
@@ -1287,9 +1260,16 @@ static const unsigned int dell9200_m23_pin_configs[8] = { | |||
1287 | 102801CB (Dell Latitude 120L) | 1260 | 102801CB (Dell Latitude 120L) |
1288 | 102801D3 | 1261 | 102801D3 |
1289 | */ | 1262 | */ |
1290 | static const unsigned int dell9200_m24_pin_configs[8] = { | 1263 | static const struct hda_pintbl dell9200_m24_pin_configs[] = { |
1291 | 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, | 1264 | { 0x08, 0x40c003fa }, |
1292 | 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, | 1265 | { 0x09, 0x404003fb }, |
1266 | { 0x0d, 0x0321121f }, | ||
1267 | { 0x0e, 0x90170310 }, | ||
1268 | { 0x0f, 0x408003fc }, | ||
1269 | { 0x10, 0x03a11020 }, | ||
1270 | { 0x11, 0x401003fd }, | ||
1271 | { 0x12, 0x403003fe }, | ||
1272 | {} | ||
1293 | }; | 1273 | }; |
1294 | 1274 | ||
1295 | /* | 1275 | /* |
@@ -1298,9 +1278,16 @@ static const unsigned int dell9200_m24_pin_configs[8] = { | |||
1298 | 102801EE | 1278 | 102801EE |
1299 | 102801EF | 1279 | 102801EF |
1300 | */ | 1280 | */ |
1301 | static const unsigned int dell9200_m25_pin_configs[8] = { | 1281 | static const struct hda_pintbl dell9200_m25_pin_configs[] = { |
1302 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, | 1282 | { 0x08, 0x40c003fa }, |
1303 | 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, | 1283 | { 0x09, 0x01441340 }, |
1284 | { 0x0d, 0x0421121f }, | ||
1285 | { 0x0e, 0x90170310 }, | ||
1286 | { 0x0f, 0x408003fb }, | ||
1287 | { 0x10, 0x04a11020 }, | ||
1288 | { 0x11, 0x401003fc }, | ||
1289 | { 0x12, 0x403003fd }, | ||
1290 | {} | ||
1304 | }; | 1291 | }; |
1305 | 1292 | ||
1306 | /* | 1293 | /* |
@@ -1308,64 +1295,159 @@ static const unsigned int dell9200_m25_pin_configs[8] = { | |||
1308 | 102801F5 (Dell Inspiron 1501) | 1295 | 102801F5 (Dell Inspiron 1501) |
1309 | 102801F6 | 1296 | 102801F6 |
1310 | */ | 1297 | */ |
1311 | static const unsigned int dell9200_m26_pin_configs[8] = { | 1298 | static const struct hda_pintbl dell9200_m26_pin_configs[] = { |
1312 | 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, | 1299 | { 0x08, 0x40c003fa }, |
1313 | 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, | 1300 | { 0x09, 0x404003fb }, |
1301 | { 0x0d, 0x0421121f }, | ||
1302 | { 0x0e, 0x90170310 }, | ||
1303 | { 0x0f, 0x408003fc }, | ||
1304 | { 0x10, 0x04a11020 }, | ||
1305 | { 0x11, 0x401003fd }, | ||
1306 | { 0x12, 0x403003fe }, | ||
1307 | {} | ||
1314 | }; | 1308 | }; |
1315 | 1309 | ||
1316 | /* | 1310 | /* |
1317 | STAC 9200-32 | 1311 | STAC 9200-32 |
1318 | 102801CD (Dell Inspiron E1705/9400) | 1312 | 102801CD (Dell Inspiron E1705/9400) |
1319 | */ | 1313 | */ |
1320 | static const unsigned int dell9200_m27_pin_configs[8] = { | 1314 | static const struct hda_pintbl dell9200_m27_pin_configs[] = { |
1321 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, | 1315 | { 0x08, 0x40c003fa }, |
1322 | 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, | 1316 | { 0x09, 0x01441340 }, |
1317 | { 0x0d, 0x0421121f }, | ||
1318 | { 0x0e, 0x90170310 }, | ||
1319 | { 0x0f, 0x90170310 }, | ||
1320 | { 0x10, 0x04a11020 }, | ||
1321 | { 0x11, 0x90170310 }, | ||
1322 | { 0x12, 0x40f003fc }, | ||
1323 | {} | ||
1323 | }; | 1324 | }; |
1324 | 1325 | ||
1325 | static const unsigned int oqo9200_pin_configs[8] = { | 1326 | static const struct hda_pintbl oqo9200_pin_configs[] = { |
1326 | 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, | 1327 | { 0x08, 0x40c000f0 }, |
1327 | 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, | 1328 | { 0x09, 0x404000f1 }, |
1329 | { 0x0d, 0x0221121f }, | ||
1330 | { 0x0e, 0x02211210 }, | ||
1331 | { 0x0f, 0x90170111 }, | ||
1332 | { 0x10, 0x90a70120 }, | ||
1333 | { 0x11, 0x400000f2 }, | ||
1334 | { 0x12, 0x400000f3 }, | ||
1335 | {} | ||
1328 | }; | 1336 | }; |
1329 | 1337 | ||
1330 | 1338 | ||
1331 | static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | 1339 | static void stac9200_fixup_panasonic(struct hda_codec *codec, |
1332 | [STAC_REF] = ref9200_pin_configs, | 1340 | const struct hda_fixup *fix, int action) |
1333 | [STAC_9200_OQO] = oqo9200_pin_configs, | 1341 | { |
1334 | [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, | 1342 | struct sigmatel_spec *spec = codec->spec; |
1335 | [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, | 1343 | |
1336 | [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, | 1344 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1337 | [STAC_9200_DELL_M21] = dell9200_m21_pin_configs, | 1345 | spec->gpio_mask = spec->gpio_dir = 0x09; |
1338 | [STAC_9200_DELL_M22] = dell9200_m22_pin_configs, | 1346 | spec->gpio_data = 0x00; |
1339 | [STAC_9200_DELL_M23] = dell9200_m23_pin_configs, | 1347 | /* CF-74 has no headphone detection, and the driver should *NOT* |
1340 | [STAC_9200_DELL_M24] = dell9200_m24_pin_configs, | 1348 | * do detection and HP/speaker toggle because the hardware does it. |
1341 | [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, | 1349 | */ |
1342 | [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, | 1350 | spec->gen.suppress_auto_mute = 1; |
1343 | [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, | 1351 | } |
1344 | [STAC_9200_M4] = gateway9200_m4_pin_configs, | 1352 | } |
1345 | [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, | 1353 | |
1346 | [STAC_9200_PANASONIC] = ref9200_pin_configs, | 1354 | |
1355 | static const struct hda_fixup stac9200_fixups[] = { | ||
1356 | [STAC_REF] = { | ||
1357 | .type = HDA_FIXUP_PINS, | ||
1358 | .v.pins = ref9200_pin_configs, | ||
1359 | }, | ||
1360 | [STAC_9200_OQO] = { | ||
1361 | .type = HDA_FIXUP_PINS, | ||
1362 | .v.pins = oqo9200_pin_configs, | ||
1363 | .chained = true, | ||
1364 | .chain_id = STAC_9200_EAPD_INIT, | ||
1365 | }, | ||
1366 | [STAC_9200_DELL_D21] = { | ||
1367 | .type = HDA_FIXUP_PINS, | ||
1368 | .v.pins = dell9200_d21_pin_configs, | ||
1369 | }, | ||
1370 | [STAC_9200_DELL_D22] = { | ||
1371 | .type = HDA_FIXUP_PINS, | ||
1372 | .v.pins = dell9200_d22_pin_configs, | ||
1373 | }, | ||
1374 | [STAC_9200_DELL_D23] = { | ||
1375 | .type = HDA_FIXUP_PINS, | ||
1376 | .v.pins = dell9200_d23_pin_configs, | ||
1377 | }, | ||
1378 | [STAC_9200_DELL_M21] = { | ||
1379 | .type = HDA_FIXUP_PINS, | ||
1380 | .v.pins = dell9200_m21_pin_configs, | ||
1381 | }, | ||
1382 | [STAC_9200_DELL_M22] = { | ||
1383 | .type = HDA_FIXUP_PINS, | ||
1384 | .v.pins = dell9200_m22_pin_configs, | ||
1385 | }, | ||
1386 | [STAC_9200_DELL_M23] = { | ||
1387 | .type = HDA_FIXUP_PINS, | ||
1388 | .v.pins = dell9200_m23_pin_configs, | ||
1389 | }, | ||
1390 | [STAC_9200_DELL_M24] = { | ||
1391 | .type = HDA_FIXUP_PINS, | ||
1392 | .v.pins = dell9200_m24_pin_configs, | ||
1393 | }, | ||
1394 | [STAC_9200_DELL_M25] = { | ||
1395 | .type = HDA_FIXUP_PINS, | ||
1396 | .v.pins = dell9200_m25_pin_configs, | ||
1397 | }, | ||
1398 | [STAC_9200_DELL_M26] = { | ||
1399 | .type = HDA_FIXUP_PINS, | ||
1400 | .v.pins = dell9200_m26_pin_configs, | ||
1401 | }, | ||
1402 | [STAC_9200_DELL_M27] = { | ||
1403 | .type = HDA_FIXUP_PINS, | ||
1404 | .v.pins = dell9200_m27_pin_configs, | ||
1405 | }, | ||
1406 | [STAC_9200_M4] = { | ||
1407 | .type = HDA_FIXUP_PINS, | ||
1408 | .v.pins = gateway9200_m4_pin_configs, | ||
1409 | .chained = true, | ||
1410 | .chain_id = STAC_9200_EAPD_INIT, | ||
1411 | }, | ||
1412 | [STAC_9200_M4_2] = { | ||
1413 | .type = HDA_FIXUP_PINS, | ||
1414 | .v.pins = gateway9200_m4_2_pin_configs, | ||
1415 | .chained = true, | ||
1416 | .chain_id = STAC_9200_EAPD_INIT, | ||
1417 | }, | ||
1418 | [STAC_9200_PANASONIC] = { | ||
1419 | .type = HDA_FIXUP_FUNC, | ||
1420 | .v.func = stac9200_fixup_panasonic, | ||
1421 | }, | ||
1422 | [STAC_9200_EAPD_INIT] = { | ||
1423 | .type = HDA_FIXUP_VERBS, | ||
1424 | .v.verbs = (const struct hda_verb[]) { | ||
1425 | {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
1426 | {} | ||
1427 | }, | ||
1428 | }, | ||
1347 | }; | 1429 | }; |
1348 | 1430 | ||
1349 | static const char * const stac9200_models[STAC_9200_MODELS] = { | 1431 | static const struct hda_model_fixup stac9200_models[] = { |
1350 | [STAC_AUTO] = "auto", | 1432 | { .id = STAC_REF, .name = "ref" }, |
1351 | [STAC_REF] = "ref", | 1433 | { .id = STAC_9200_OQO, .name = "oqo" }, |
1352 | [STAC_9200_OQO] = "oqo", | 1434 | { .id = STAC_9200_DELL_D21, .name = "dell-d21" }, |
1353 | [STAC_9200_DELL_D21] = "dell-d21", | 1435 | { .id = STAC_9200_DELL_D22, .name = "dell-d22" }, |
1354 | [STAC_9200_DELL_D22] = "dell-d22", | 1436 | { .id = STAC_9200_DELL_D23, .name = "dell-d23" }, |
1355 | [STAC_9200_DELL_D23] = "dell-d23", | 1437 | { .id = STAC_9200_DELL_M21, .name = "dell-m21" }, |
1356 | [STAC_9200_DELL_M21] = "dell-m21", | 1438 | { .id = STAC_9200_DELL_M22, .name = "dell-m22" }, |
1357 | [STAC_9200_DELL_M22] = "dell-m22", | 1439 | { .id = STAC_9200_DELL_M23, .name = "dell-m23" }, |
1358 | [STAC_9200_DELL_M23] = "dell-m23", | 1440 | { .id = STAC_9200_DELL_M24, .name = "dell-m24" }, |
1359 | [STAC_9200_DELL_M24] = "dell-m24", | 1441 | { .id = STAC_9200_DELL_M25, .name = "dell-m25" }, |
1360 | [STAC_9200_DELL_M25] = "dell-m25", | 1442 | { .id = STAC_9200_DELL_M26, .name = "dell-m26" }, |
1361 | [STAC_9200_DELL_M26] = "dell-m26", | 1443 | { .id = STAC_9200_DELL_M27, .name = "dell-m27" }, |
1362 | [STAC_9200_DELL_M27] = "dell-m27", | 1444 | { .id = STAC_9200_M4, .name = "gateway-m4" }, |
1363 | [STAC_9200_M4] = "gateway-m4", | 1445 | { .id = STAC_9200_M4_2, .name = "gateway-m4-2" }, |
1364 | [STAC_9200_M4_2] = "gateway-m4-2", | 1446 | { .id = STAC_9200_PANASONIC, .name = "panasonic" }, |
1365 | [STAC_9200_PANASONIC] = "panasonic", | 1447 | {} |
1366 | }; | 1448 | }; |
1367 | 1449 | ||
1368 | static const struct snd_pci_quirk stac9200_cfg_tbl[] = { | 1450 | static const struct snd_pci_quirk stac9200_fixup_tbl[] = { |
1369 | /* SigmaTel reference board */ | 1451 | /* SigmaTel reference board */ |
1370 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1452 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1371 | "DFI LanParty", STAC_REF), | 1453 | "DFI LanParty", STAC_REF), |
@@ -1441,70 +1523,159 @@ static const struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1441 | {} /* terminator */ | 1523 | {} /* terminator */ |
1442 | }; | 1524 | }; |
1443 | 1525 | ||
1444 | static const unsigned int ref925x_pin_configs[8] = { | 1526 | static const struct hda_pintbl ref925x_pin_configs[] = { |
1445 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | 1527 | { 0x07, 0x40c003f0 }, |
1446 | 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, | 1528 | { 0x08, 0x424503f2 }, |
1529 | { 0x0a, 0x01813022 }, | ||
1530 | { 0x0b, 0x02a19021 }, | ||
1531 | { 0x0c, 0x90a70320 }, | ||
1532 | { 0x0d, 0x02214210 }, | ||
1533 | { 0x10, 0x01019020 }, | ||
1534 | { 0x11, 0x9033032e }, | ||
1535 | {} | ||
1447 | }; | 1536 | }; |
1448 | 1537 | ||
1449 | static const unsigned int stac925xM1_pin_configs[8] = { | 1538 | static const struct hda_pintbl stac925xM1_pin_configs[] = { |
1450 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1539 | { 0x07, 0x40c003f4 }, |
1451 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1540 | { 0x08, 0x424503f2 }, |
1541 | { 0x0a, 0x400000f3 }, | ||
1542 | { 0x0b, 0x02a19020 }, | ||
1543 | { 0x0c, 0x40a000f0 }, | ||
1544 | { 0x0d, 0x90100210 }, | ||
1545 | { 0x10, 0x400003f1 }, | ||
1546 | { 0x11, 0x9033032e }, | ||
1547 | {} | ||
1452 | }; | 1548 | }; |
1453 | 1549 | ||
1454 | static const unsigned int stac925xM1_2_pin_configs[8] = { | 1550 | static const struct hda_pintbl stac925xM1_2_pin_configs[] = { |
1455 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1551 | { 0x07, 0x40c003f4 }, |
1456 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1552 | { 0x08, 0x424503f2 }, |
1553 | { 0x0a, 0x400000f3 }, | ||
1554 | { 0x0b, 0x02a19020 }, | ||
1555 | { 0x0c, 0x40a000f0 }, | ||
1556 | { 0x0d, 0x90100210 }, | ||
1557 | { 0x10, 0x400003f1 }, | ||
1558 | { 0x11, 0x9033032e }, | ||
1559 | {} | ||
1457 | }; | 1560 | }; |
1458 | 1561 | ||
1459 | static const unsigned int stac925xM2_pin_configs[8] = { | 1562 | static const struct hda_pintbl stac925xM2_pin_configs[] = { |
1460 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1563 | { 0x07, 0x40c003f4 }, |
1461 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1564 | { 0x08, 0x424503f2 }, |
1565 | { 0x0a, 0x400000f3 }, | ||
1566 | { 0x0b, 0x02a19020 }, | ||
1567 | { 0x0c, 0x40a000f0 }, | ||
1568 | { 0x0d, 0x90100210 }, | ||
1569 | { 0x10, 0x400003f1 }, | ||
1570 | { 0x11, 0x9033032e }, | ||
1571 | {} | ||
1462 | }; | 1572 | }; |
1463 | 1573 | ||
1464 | static const unsigned int stac925xM2_2_pin_configs[8] = { | 1574 | static const struct hda_pintbl stac925xM2_2_pin_configs[] = { |
1465 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1575 | { 0x07, 0x40c003f4 }, |
1466 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1576 | { 0x08, 0x424503f2 }, |
1577 | { 0x0a, 0x400000f3 }, | ||
1578 | { 0x0b, 0x02a19020 }, | ||
1579 | { 0x0c, 0x40a000f0 }, | ||
1580 | { 0x0d, 0x90100210 }, | ||
1581 | { 0x10, 0x400003f1 }, | ||
1582 | { 0x11, 0x9033032e }, | ||
1583 | {} | ||
1467 | }; | 1584 | }; |
1468 | 1585 | ||
1469 | static const unsigned int stac925xM3_pin_configs[8] = { | 1586 | static const struct hda_pintbl stac925xM3_pin_configs[] = { |
1470 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1587 | { 0x07, 0x40c003f4 }, |
1471 | 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, | 1588 | { 0x08, 0x424503f2 }, |
1589 | { 0x0a, 0x400000f3 }, | ||
1590 | { 0x0b, 0x02a19020 }, | ||
1591 | { 0x0c, 0x40a000f0 }, | ||
1592 | { 0x0d, 0x90100210 }, | ||
1593 | { 0x10, 0x400003f1 }, | ||
1594 | { 0x11, 0x503303f3 }, | ||
1595 | {} | ||
1472 | }; | 1596 | }; |
1473 | 1597 | ||
1474 | static const unsigned int stac925xM5_pin_configs[8] = { | 1598 | static const struct hda_pintbl stac925xM5_pin_configs[] = { |
1475 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1599 | { 0x07, 0x40c003f4 }, |
1476 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1600 | { 0x08, 0x424503f2 }, |
1601 | { 0x0a, 0x400000f3 }, | ||
1602 | { 0x0b, 0x02a19020 }, | ||
1603 | { 0x0c, 0x40a000f0 }, | ||
1604 | { 0x0d, 0x90100210 }, | ||
1605 | { 0x10, 0x400003f1 }, | ||
1606 | { 0x11, 0x9033032e }, | ||
1607 | {} | ||
1477 | }; | 1608 | }; |
1478 | 1609 | ||
1479 | static const unsigned int stac925xM6_pin_configs[8] = { | 1610 | static const struct hda_pintbl stac925xM6_pin_configs[] = { |
1480 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1611 | { 0x07, 0x40c003f4 }, |
1481 | 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, | 1612 | { 0x08, 0x424503f2 }, |
1613 | { 0x0a, 0x400000f3 }, | ||
1614 | { 0x0b, 0x02a19020 }, | ||
1615 | { 0x0c, 0x40a000f0 }, | ||
1616 | { 0x0d, 0x90100210 }, | ||
1617 | { 0x10, 0x400003f1 }, | ||
1618 | { 0x11, 0x90330320 }, | ||
1619 | {} | ||
1482 | }; | 1620 | }; |
1483 | 1621 | ||
1484 | static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | 1622 | static const struct hda_fixup stac925x_fixups[] = { |
1485 | [STAC_REF] = ref925x_pin_configs, | 1623 | [STAC_REF] = { |
1486 | [STAC_M1] = stac925xM1_pin_configs, | 1624 | .type = HDA_FIXUP_PINS, |
1487 | [STAC_M1_2] = stac925xM1_2_pin_configs, | 1625 | .v.pins = ref925x_pin_configs, |
1488 | [STAC_M2] = stac925xM2_pin_configs, | 1626 | }, |
1489 | [STAC_M2_2] = stac925xM2_2_pin_configs, | 1627 | [STAC_M1] = { |
1490 | [STAC_M3] = stac925xM3_pin_configs, | 1628 | .type = HDA_FIXUP_PINS, |
1491 | [STAC_M5] = stac925xM5_pin_configs, | 1629 | .v.pins = stac925xM1_pin_configs, |
1492 | [STAC_M6] = stac925xM6_pin_configs, | 1630 | }, |
1631 | [STAC_M1_2] = { | ||
1632 | .type = HDA_FIXUP_PINS, | ||
1633 | .v.pins = stac925xM1_2_pin_configs, | ||
1634 | }, | ||
1635 | [STAC_M2] = { | ||
1636 | .type = HDA_FIXUP_PINS, | ||
1637 | .v.pins = stac925xM2_pin_configs, | ||
1638 | }, | ||
1639 | [STAC_M2_2] = { | ||
1640 | .type = HDA_FIXUP_PINS, | ||
1641 | .v.pins = stac925xM2_2_pin_configs, | ||
1642 | }, | ||
1643 | [STAC_M3] = { | ||
1644 | .type = HDA_FIXUP_PINS, | ||
1645 | .v.pins = stac925xM3_pin_configs, | ||
1646 | }, | ||
1647 | [STAC_M5] = { | ||
1648 | .type = HDA_FIXUP_PINS, | ||
1649 | .v.pins = stac925xM5_pin_configs, | ||
1650 | }, | ||
1651 | [STAC_M6] = { | ||
1652 | .type = HDA_FIXUP_PINS, | ||
1653 | .v.pins = stac925xM6_pin_configs, | ||
1654 | }, | ||
1493 | }; | 1655 | }; |
1494 | 1656 | ||
1495 | static const char * const stac925x_models[STAC_925x_MODELS] = { | 1657 | static const struct hda_model_fixup stac925x_models[] = { |
1496 | [STAC_925x_AUTO] = "auto", | 1658 | { .id = STAC_REF, .name = "ref" }, |
1497 | [STAC_REF] = "ref", | 1659 | { .id = STAC_M1, .name = "m1" }, |
1498 | [STAC_M1] = "m1", | 1660 | { .id = STAC_M1_2, .name = "m1-2" }, |
1499 | [STAC_M1_2] = "m1-2", | 1661 | { .id = STAC_M2, .name = "m2" }, |
1500 | [STAC_M2] = "m2", | 1662 | { .id = STAC_M2_2, .name = "m2-2" }, |
1501 | [STAC_M2_2] = "m2-2", | 1663 | { .id = STAC_M3, .name = "m3" }, |
1502 | [STAC_M3] = "m3", | 1664 | { .id = STAC_M5, .name = "m5" }, |
1503 | [STAC_M5] = "m5", | 1665 | { .id = STAC_M6, .name = "m6" }, |
1504 | [STAC_M6] = "m6", | 1666 | {} |
1505 | }; | 1667 | }; |
1506 | 1668 | ||
1507 | static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | 1669 | static const struct snd_pci_quirk stac925x_fixup_tbl[] = { |
1670 | /* SigmaTel reference board */ | ||
1671 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | ||
1672 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), | ||
1673 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), | ||
1674 | |||
1675 | /* Default table for unknown ID */ | ||
1676 | SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), | ||
1677 | |||
1678 | /* gateway machines are checked via codec ssid */ | ||
1508 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), | 1679 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), |
1509 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), | 1680 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), |
1510 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), | 1681 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), |
@@ -1518,67 +1689,202 @@ static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | |||
1518 | {} /* terminator */ | 1689 | {} /* terminator */ |
1519 | }; | 1690 | }; |
1520 | 1691 | ||
1521 | static const struct snd_pci_quirk stac925x_cfg_tbl[] = { | 1692 | static const struct hda_pintbl ref92hd73xx_pin_configs[] = { |
1522 | /* SigmaTel reference board */ | 1693 | { 0x0a, 0x02214030 }, |
1523 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | 1694 | { 0x0b, 0x02a19040 }, |
1524 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), | 1695 | { 0x0c, 0x01a19020 }, |
1525 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), | 1696 | { 0x0d, 0x02214030 }, |
1526 | 1697 | { 0x0e, 0x0181302e }, | |
1527 | /* Default table for unknown ID */ | 1698 | { 0x0f, 0x01014010 }, |
1528 | SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), | 1699 | { 0x10, 0x01014020 }, |
1529 | 1700 | { 0x11, 0x01014030 }, | |
1530 | {} /* terminator */ | 1701 | { 0x12, 0x02319040 }, |
1702 | { 0x13, 0x90a000f0 }, | ||
1703 | { 0x14, 0x90a000f0 }, | ||
1704 | { 0x22, 0x01452050 }, | ||
1705 | { 0x23, 0x01452050 }, | ||
1706 | {} | ||
1531 | }; | 1707 | }; |
1532 | 1708 | ||
1533 | static const unsigned int ref92hd73xx_pin_configs[13] = { | 1709 | static const struct hda_pintbl dell_m6_pin_configs[] = { |
1534 | 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, | 1710 | { 0x0a, 0x0321101f }, |
1535 | 0x0181302e, 0x01014010, 0x01014020, 0x01014030, | 1711 | { 0x0b, 0x4f00000f }, |
1536 | 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, | 1712 | { 0x0c, 0x4f0000f0 }, |
1537 | 0x01452050, | 1713 | { 0x0d, 0x90170110 }, |
1714 | { 0x0e, 0x03a11020 }, | ||
1715 | { 0x0f, 0x0321101f }, | ||
1716 | { 0x10, 0x4f0000f0 }, | ||
1717 | { 0x11, 0x4f0000f0 }, | ||
1718 | { 0x12, 0x4f0000f0 }, | ||
1719 | { 0x13, 0x90a60160 }, | ||
1720 | { 0x14, 0x4f0000f0 }, | ||
1721 | { 0x22, 0x4f0000f0 }, | ||
1722 | { 0x23, 0x4f0000f0 }, | ||
1723 | {} | ||
1538 | }; | 1724 | }; |
1539 | 1725 | ||
1540 | static const unsigned int dell_m6_pin_configs[13] = { | 1726 | static const struct hda_pintbl alienware_m17x_pin_configs[] = { |
1541 | 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, | 1727 | { 0x0a, 0x0321101f }, |
1542 | 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, | 1728 | { 0x0b, 0x0321101f }, |
1543 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, | 1729 | { 0x0c, 0x03a11020 }, |
1544 | 0x4f0000f0, | 1730 | { 0x0d, 0x03014020 }, |
1731 | { 0x0e, 0x90170110 }, | ||
1732 | { 0x0f, 0x4f0000f0 }, | ||
1733 | { 0x10, 0x4f0000f0 }, | ||
1734 | { 0x11, 0x4f0000f0 }, | ||
1735 | { 0x12, 0x4f0000f0 }, | ||
1736 | { 0x13, 0x90a60160 }, | ||
1737 | { 0x14, 0x4f0000f0 }, | ||
1738 | { 0x22, 0x4f0000f0 }, | ||
1739 | { 0x23, 0x904601b0 }, | ||
1740 | {} | ||
1545 | }; | 1741 | }; |
1546 | 1742 | ||
1547 | static const unsigned int alienware_m17x_pin_configs[13] = { | 1743 | static const struct hda_pintbl intel_dg45id_pin_configs[] = { |
1548 | 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, | 1744 | { 0x0a, 0x02214230 }, |
1549 | 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, | 1745 | { 0x0b, 0x02A19240 }, |
1550 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, | 1746 | { 0x0c, 0x01013214 }, |
1551 | 0x904601b0, | 1747 | { 0x0d, 0x01014210 }, |
1748 | { 0x0e, 0x01A19250 }, | ||
1749 | { 0x0f, 0x01011212 }, | ||
1750 | { 0x10, 0x01016211 }, | ||
1751 | {} | ||
1552 | }; | 1752 | }; |
1553 | 1753 | ||
1554 | static const unsigned int intel_dg45id_pin_configs[13] = { | 1754 | static void stac92hd73xx_fixup_ref(struct hda_codec *codec, |
1555 | 0x02214230, 0x02A19240, 0x01013214, 0x01014210, | 1755 | const struct hda_fixup *fix, int action) |
1556 | 0x01A19250, 0x01011212, 0x01016211 | 1756 | { |
1557 | }; | 1757 | struct sigmatel_spec *spec = codec->spec; |
1758 | |||
1759 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
1760 | return; | ||
1761 | |||
1762 | snd_hda_apply_pincfgs(codec, ref92hd73xx_pin_configs); | ||
1763 | spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0; | ||
1764 | } | ||
1765 | |||
1766 | static void stac92hd73xx_fixup_dell(struct hda_codec *codec) | ||
1767 | { | ||
1768 | struct sigmatel_spec *spec = codec->spec; | ||
1769 | |||
1770 | snd_hda_apply_pincfgs(codec, dell_m6_pin_configs); | ||
1771 | spec->eapd_switch = 0; | ||
1772 | } | ||
1773 | |||
1774 | static void stac92hd73xx_fixup_dell_eq(struct hda_codec *codec, | ||
1775 | const struct hda_fixup *fix, int action) | ||
1776 | { | ||
1777 | struct sigmatel_spec *spec = codec->spec; | ||
1558 | 1778 | ||
1559 | static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | 1779 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
1560 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, | 1780 | return; |
1561 | [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, | 1781 | |
1562 | [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, | 1782 | stac92hd73xx_fixup_dell(codec); |
1563 | [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, | 1783 | snd_hda_add_verbs(codec, dell_eq_core_init); |
1564 | [STAC_DELL_EQ] = dell_m6_pin_configs, | 1784 | spec->volknob_init = 1; |
1565 | [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, | 1785 | } |
1566 | [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, | 1786 | |
1787 | /* Analog Mics */ | ||
1788 | static void stac92hd73xx_fixup_dell_m6_amic(struct hda_codec *codec, | ||
1789 | const struct hda_fixup *fix, int action) | ||
1790 | { | ||
1791 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
1792 | return; | ||
1793 | |||
1794 | stac92hd73xx_fixup_dell(codec); | ||
1795 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | ||
1796 | } | ||
1797 | |||
1798 | /* Digital Mics */ | ||
1799 | static void stac92hd73xx_fixup_dell_m6_dmic(struct hda_codec *codec, | ||
1800 | const struct hda_fixup *fix, int action) | ||
1801 | { | ||
1802 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
1803 | return; | ||
1804 | |||
1805 | stac92hd73xx_fixup_dell(codec); | ||
1806 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | ||
1807 | } | ||
1808 | |||
1809 | /* Both */ | ||
1810 | static void stac92hd73xx_fixup_dell_m6_both(struct hda_codec *codec, | ||
1811 | const struct hda_fixup *fix, int action) | ||
1812 | { | ||
1813 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
1814 | return; | ||
1815 | |||
1816 | stac92hd73xx_fixup_dell(codec); | ||
1817 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | ||
1818 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | ||
1819 | } | ||
1820 | |||
1821 | static void stac92hd73xx_fixup_alienware_m17x(struct hda_codec *codec, | ||
1822 | const struct hda_fixup *fix, int action) | ||
1823 | { | ||
1824 | struct sigmatel_spec *spec = codec->spec; | ||
1825 | |||
1826 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
1827 | return; | ||
1828 | |||
1829 | snd_hda_apply_pincfgs(codec, alienware_m17x_pin_configs); | ||
1830 | spec->eapd_switch = 0; | ||
1831 | } | ||
1832 | |||
1833 | static void stac92hd73xx_fixup_no_jd(struct hda_codec *codec, | ||
1834 | const struct hda_fixup *fix, int action) | ||
1835 | { | ||
1836 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
1837 | codec->no_jack_detect = 1; | ||
1838 | } | ||
1839 | |||
1840 | static const struct hda_fixup stac92hd73xx_fixups[] = { | ||
1841 | [STAC_92HD73XX_REF] = { | ||
1842 | .type = HDA_FIXUP_FUNC, | ||
1843 | .v.func = stac92hd73xx_fixup_ref, | ||
1844 | }, | ||
1845 | [STAC_DELL_M6_AMIC] = { | ||
1846 | .type = HDA_FIXUP_FUNC, | ||
1847 | .v.func = stac92hd73xx_fixup_dell_m6_amic, | ||
1848 | }, | ||
1849 | [STAC_DELL_M6_DMIC] = { | ||
1850 | .type = HDA_FIXUP_FUNC, | ||
1851 | .v.func = stac92hd73xx_fixup_dell_m6_dmic, | ||
1852 | }, | ||
1853 | [STAC_DELL_M6_BOTH] = { | ||
1854 | .type = HDA_FIXUP_FUNC, | ||
1855 | .v.func = stac92hd73xx_fixup_dell_m6_both, | ||
1856 | }, | ||
1857 | [STAC_DELL_EQ] = { | ||
1858 | .type = HDA_FIXUP_FUNC, | ||
1859 | .v.func = stac92hd73xx_fixup_dell_eq, | ||
1860 | }, | ||
1861 | [STAC_ALIENWARE_M17X] = { | ||
1862 | .type = HDA_FIXUP_FUNC, | ||
1863 | .v.func = stac92hd73xx_fixup_alienware_m17x, | ||
1864 | }, | ||
1865 | [STAC_92HD73XX_INTEL] = { | ||
1866 | .type = HDA_FIXUP_PINS, | ||
1867 | .v.pins = intel_dg45id_pin_configs, | ||
1868 | }, | ||
1869 | [STAC_92HD73XX_NO_JD] = { | ||
1870 | .type = HDA_FIXUP_FUNC, | ||
1871 | .v.func = stac92hd73xx_fixup_no_jd, | ||
1872 | } | ||
1567 | }; | 1873 | }; |
1568 | 1874 | ||
1569 | static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1875 | static const struct hda_model_fixup stac92hd73xx_models[] = { |
1570 | [STAC_92HD73XX_AUTO] = "auto", | 1876 | { .id = STAC_92HD73XX_NO_JD, .name = "no-jd" }, |
1571 | [STAC_92HD73XX_NO_JD] = "no-jd", | 1877 | { .id = STAC_92HD73XX_REF, .name = "ref" }, |
1572 | [STAC_92HD73XX_REF] = "ref", | 1878 | { .id = STAC_92HD73XX_INTEL, .name = "intel" }, |
1573 | [STAC_92HD73XX_INTEL] = "intel", | 1879 | { .id = STAC_DELL_M6_AMIC, .name = "dell-m6-amic" }, |
1574 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", | 1880 | { .id = STAC_DELL_M6_DMIC, .name = "dell-m6-dmic" }, |
1575 | [STAC_DELL_M6_DMIC] = "dell-m6-dmic", | 1881 | { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, |
1576 | [STAC_DELL_M6_BOTH] = "dell-m6", | 1882 | { .id = STAC_DELL_EQ, .name = "dell-eq" }, |
1577 | [STAC_DELL_EQ] = "dell-eq", | 1883 | { .id = STAC_ALIENWARE_M17X, .name = "alienware" }, |
1578 | [STAC_ALIENWARE_M17X] = "alienware", | 1884 | {} |
1579 | }; | 1885 | }; |
1580 | 1886 | ||
1581 | static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | 1887 | static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { |
1582 | /* SigmaTel reference board */ | 1888 | /* SigmaTel reference board */ |
1583 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1889 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1584 | "DFI LanParty", STAC_92HD73XX_REF), | 1890 | "DFI LanParty", STAC_92HD73XX_REF), |
@@ -1616,10 +1922,7 @@ static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1616 | "Dell Studio XPS 1645", STAC_DELL_M6_DMIC), | 1922 | "Dell Studio XPS 1645", STAC_DELL_M6_DMIC), |
1617 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, | 1923 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, |
1618 | "Dell Studio 1558", STAC_DELL_M6_DMIC), | 1924 | "Dell Studio 1558", STAC_DELL_M6_DMIC), |
1619 | {} /* terminator */ | 1925 | /* codec SSID matching */ |
1620 | }; | ||
1621 | |||
1622 | static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | ||
1623 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, | 1926 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, |
1624 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1927 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1625 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, | 1928 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, |
@@ -1629,68 +1932,240 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | |||
1629 | {} /* terminator */ | 1932 | {} /* terminator */ |
1630 | }; | 1933 | }; |
1631 | 1934 | ||
1632 | static const unsigned int ref92hd83xxx_pin_configs[10] = { | 1935 | static const struct hda_pintbl ref92hd83xxx_pin_configs[] = { |
1633 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | 1936 | { 0x0a, 0x02214030 }, |
1634 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | 1937 | { 0x0b, 0x02211010 }, |
1635 | 0x01451160, 0x98560170, | 1938 | { 0x0c, 0x02a19020 }, |
1939 | { 0x0d, 0x02170130 }, | ||
1940 | { 0x0e, 0x01014050 }, | ||
1941 | { 0x0f, 0x01819040 }, | ||
1942 | { 0x10, 0x01014020 }, | ||
1943 | { 0x11, 0x90a3014e }, | ||
1944 | { 0x1f, 0x01451160 }, | ||
1945 | { 0x20, 0x98560170 }, | ||
1946 | {} | ||
1636 | }; | 1947 | }; |
1637 | 1948 | ||
1638 | static const unsigned int dell_s14_pin_configs[10] = { | 1949 | static const struct hda_pintbl dell_s14_pin_configs[] = { |
1639 | 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, | 1950 | { 0x0a, 0x0221403f }, |
1640 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, | 1951 | { 0x0b, 0x0221101f }, |
1641 | 0x40f000f0, 0x40f000f0, | 1952 | { 0x0c, 0x02a19020 }, |
1953 | { 0x0d, 0x90170110 }, | ||
1954 | { 0x0e, 0x40f000f0 }, | ||
1955 | { 0x0f, 0x40f000f0 }, | ||
1956 | { 0x10, 0x40f000f0 }, | ||
1957 | { 0x11, 0x90a60160 }, | ||
1958 | { 0x1f, 0x40f000f0 }, | ||
1959 | { 0x20, 0x40f000f0 }, | ||
1960 | {} | ||
1642 | }; | 1961 | }; |
1643 | 1962 | ||
1644 | static const unsigned int dell_vostro_3500_pin_configs[10] = { | 1963 | static const struct hda_pintbl dell_vostro_3500_pin_configs[] = { |
1645 | 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, | 1964 | { 0x0a, 0x02a11020 }, |
1646 | 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, | 1965 | { 0x0b, 0x0221101f }, |
1647 | 0x400000f4, 0x400000f5, | 1966 | { 0x0c, 0x400000f0 }, |
1967 | { 0x0d, 0x90170110 }, | ||
1968 | { 0x0e, 0x400000f1 }, | ||
1969 | { 0x0f, 0x400000f2 }, | ||
1970 | { 0x10, 0x400000f3 }, | ||
1971 | { 0x11, 0x90a60160 }, | ||
1972 | { 0x1f, 0x400000f4 }, | ||
1973 | { 0x20, 0x400000f5 }, | ||
1974 | {} | ||
1648 | }; | 1975 | }; |
1649 | 1976 | ||
1650 | static const unsigned int hp_dv7_4000_pin_configs[10] = { | 1977 | static const struct hda_pintbl hp_dv7_4000_pin_configs[] = { |
1651 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, | 1978 | { 0x0a, 0x03a12050 }, |
1652 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, | 1979 | { 0x0b, 0x0321201f }, |
1653 | 0x40f000f0, 0x40f000f0, | 1980 | { 0x0c, 0x40f000f0 }, |
1981 | { 0x0d, 0x90170110 }, | ||
1982 | { 0x0e, 0x40f000f0 }, | ||
1983 | { 0x0f, 0x40f000f0 }, | ||
1984 | { 0x10, 0x90170110 }, | ||
1985 | { 0x11, 0xd5a30140 }, | ||
1986 | { 0x1f, 0x40f000f0 }, | ||
1987 | { 0x20, 0x40f000f0 }, | ||
1988 | {} | ||
1654 | }; | 1989 | }; |
1655 | 1990 | ||
1656 | static const unsigned int hp_zephyr_pin_configs[10] = { | 1991 | static const struct hda_pintbl hp_zephyr_pin_configs[] = { |
1657 | 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310, | 1992 | { 0x0a, 0x01813050 }, |
1658 | 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130, | 1993 | { 0x0b, 0x0421201f }, |
1659 | 0, 0, | 1994 | { 0x0c, 0x04a1205e }, |
1995 | { 0x0d, 0x96130310 }, | ||
1996 | { 0x0e, 0x96130310 }, | ||
1997 | { 0x0f, 0x0101401f }, | ||
1998 | { 0x10, 0x1111611f }, | ||
1999 | { 0x11, 0xd5a30130 }, | ||
2000 | {} | ||
1660 | }; | 2001 | }; |
1661 | 2002 | ||
1662 | static const unsigned int hp_cNB11_intquad_pin_configs[10] = { | 2003 | static const struct hda_pintbl hp_cNB11_intquad_pin_configs[] = { |
1663 | 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, | 2004 | { 0x0a, 0x40f000f0 }, |
1664 | 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, | 2005 | { 0x0b, 0x0221101f }, |
1665 | 0x40f000f0, 0x40f000f0, | 2006 | { 0x0c, 0x02a11020 }, |
2007 | { 0x0d, 0x92170110 }, | ||
2008 | { 0x0e, 0x40f000f0 }, | ||
2009 | { 0x0f, 0x92170110 }, | ||
2010 | { 0x10, 0x40f000f0 }, | ||
2011 | { 0x11, 0xd5a30130 }, | ||
2012 | { 0x1f, 0x40f000f0 }, | ||
2013 | { 0x20, 0x40f000f0 }, | ||
2014 | {} | ||
1666 | }; | 2015 | }; |
1667 | 2016 | ||
1668 | static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | 2017 | static void stac92hd83xxx_fixup_hp(struct hda_codec *codec, |
1669 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 2018 | const struct hda_fixup *fix, int action) |
1670 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 2019 | { |
1671 | [STAC_DELL_S14] = dell_s14_pin_configs, | 2020 | struct sigmatel_spec *spec = codec->spec; |
1672 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, | 2021 | |
1673 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, | 2022 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
1674 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, | 2023 | return; |
1675 | [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs, | 2024 | |
2025 | if (hp_bnb2011_with_dock(codec)) { | ||
2026 | snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f); | ||
2027 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); | ||
2028 | } | ||
2029 | |||
2030 | if (find_mute_led_cfg(codec, spec->default_polarity)) | ||
2031 | snd_printd("mute LED gpio %d polarity %d\n", | ||
2032 | spec->gpio_led, | ||
2033 | spec->gpio_led_polarity); | ||
2034 | } | ||
2035 | |||
2036 | static void stac92hd83xxx_fixup_hp_zephyr(struct hda_codec *codec, | ||
2037 | const struct hda_fixup *fix, int action) | ||
2038 | { | ||
2039 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
2040 | return; | ||
2041 | |||
2042 | snd_hda_apply_pincfgs(codec, hp_zephyr_pin_configs); | ||
2043 | snd_hda_add_verbs(codec, stac92hd83xxx_hp_zephyr_init); | ||
2044 | } | ||
2045 | |||
2046 | static void stac92hd83xxx_fixup_hp_led(struct hda_codec *codec, | ||
2047 | const struct hda_fixup *fix, int action) | ||
2048 | { | ||
2049 | struct sigmatel_spec *spec = codec->spec; | ||
2050 | |||
2051 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2052 | spec->default_polarity = 0; | ||
2053 | } | ||
2054 | |||
2055 | static void stac92hd83xxx_fixup_hp_inv_led(struct hda_codec *codec, | ||
2056 | const struct hda_fixup *fix, int action) | ||
2057 | { | ||
2058 | struct sigmatel_spec *spec = codec->spec; | ||
2059 | |||
2060 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2061 | spec->default_polarity = 1; | ||
2062 | } | ||
2063 | |||
2064 | static void stac92hd83xxx_fixup_hp_mic_led(struct hda_codec *codec, | ||
2065 | const struct hda_fixup *fix, int action) | ||
2066 | { | ||
2067 | struct sigmatel_spec *spec = codec->spec; | ||
2068 | |||
2069 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2070 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ | ||
2071 | } | ||
2072 | |||
2073 | static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, | ||
2074 | const struct hda_fixup *fix, int action) | ||
2075 | { | ||
2076 | struct sigmatel_spec *spec = codec->spec; | ||
2077 | |||
2078 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
2079 | spec->headset_jack = 1; | ||
2080 | } | ||
2081 | |||
2082 | static const struct hda_fixup stac92hd83xxx_fixups[] = { | ||
2083 | [STAC_92HD83XXX_REF] = { | ||
2084 | .type = HDA_FIXUP_PINS, | ||
2085 | .v.pins = ref92hd83xxx_pin_configs, | ||
2086 | }, | ||
2087 | [STAC_92HD83XXX_PWR_REF] = { | ||
2088 | .type = HDA_FIXUP_PINS, | ||
2089 | .v.pins = ref92hd83xxx_pin_configs, | ||
2090 | }, | ||
2091 | [STAC_DELL_S14] = { | ||
2092 | .type = HDA_FIXUP_PINS, | ||
2093 | .v.pins = dell_s14_pin_configs, | ||
2094 | }, | ||
2095 | [STAC_DELL_VOSTRO_3500] = { | ||
2096 | .type = HDA_FIXUP_PINS, | ||
2097 | .v.pins = dell_vostro_3500_pin_configs, | ||
2098 | }, | ||
2099 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = { | ||
2100 | .type = HDA_FIXUP_PINS, | ||
2101 | .v.pins = hp_cNB11_intquad_pin_configs, | ||
2102 | .chained = true, | ||
2103 | .chain_id = STAC_92HD83XXX_HP, | ||
2104 | }, | ||
2105 | [STAC_92HD83XXX_HP] = { | ||
2106 | .type = HDA_FIXUP_FUNC, | ||
2107 | .v.func = stac92hd83xxx_fixup_hp, | ||
2108 | }, | ||
2109 | [STAC_HP_DV7_4000] = { | ||
2110 | .type = HDA_FIXUP_PINS, | ||
2111 | .v.pins = hp_dv7_4000_pin_configs, | ||
2112 | .chained = true, | ||
2113 | .chain_id = STAC_92HD83XXX_HP, | ||
2114 | }, | ||
2115 | [STAC_HP_ZEPHYR] = { | ||
2116 | .type = HDA_FIXUP_FUNC, | ||
2117 | .v.func = stac92hd83xxx_fixup_hp_zephyr, | ||
2118 | .chained = true, | ||
2119 | .chain_id = STAC_92HD83XXX_HP, | ||
2120 | }, | ||
2121 | [STAC_92HD83XXX_HP_LED] = { | ||
2122 | .type = HDA_FIXUP_FUNC, | ||
2123 | .v.func = stac92hd83xxx_fixup_hp_led, | ||
2124 | .chained = true, | ||
2125 | .chain_id = STAC_92HD83XXX_HP, | ||
2126 | }, | ||
2127 | [STAC_92HD83XXX_HP_INV_LED] = { | ||
2128 | .type = HDA_FIXUP_FUNC, | ||
2129 | .v.func = stac92hd83xxx_fixup_hp_inv_led, | ||
2130 | .chained = true, | ||
2131 | .chain_id = STAC_92HD83XXX_HP, | ||
2132 | }, | ||
2133 | [STAC_92HD83XXX_HP_MIC_LED] = { | ||
2134 | .type = HDA_FIXUP_FUNC, | ||
2135 | .v.func = stac92hd83xxx_fixup_hp_mic_led, | ||
2136 | .chained = true, | ||
2137 | .chain_id = STAC_92HD83XXX_HP, | ||
2138 | }, | ||
2139 | [STAC_92HD83XXX_HEADSET_JACK] = { | ||
2140 | .type = HDA_FIXUP_FUNC, | ||
2141 | .v.func = stac92hd83xxx_fixup_headset_jack, | ||
2142 | }, | ||
2143 | [STAC_HP_ENVY_BASS] = { | ||
2144 | .type = HDA_FIXUP_PINS, | ||
2145 | .v.pins = (const struct hda_pintbl[]) { | ||
2146 | { 0x0f, 0x90170111 }, | ||
2147 | {} | ||
2148 | }, | ||
2149 | }, | ||
1676 | }; | 2150 | }; |
1677 | 2151 | ||
1678 | static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 2152 | static const struct hda_model_fixup stac92hd83xxx_models[] = { |
1679 | [STAC_92HD83XXX_AUTO] = "auto", | 2153 | { .id = STAC_92HD83XXX_REF, .name = "ref" }, |
1680 | [STAC_92HD83XXX_REF] = "ref", | 2154 | { .id = STAC_92HD83XXX_PWR_REF, .name = "mic-ref" }, |
1681 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 2155 | { .id = STAC_DELL_S14, .name = "dell-s14" }, |
1682 | [STAC_DELL_S14] = "dell-s14", | 2156 | { .id = STAC_DELL_VOSTRO_3500, .name = "dell-vostro-3500" }, |
1683 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | 2157 | { .id = STAC_92HD83XXX_HP_cNB11_INTQUAD, .name = "hp_cNB11_intquad" }, |
1684 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 2158 | { .id = STAC_HP_DV7_4000, .name = "hp-dv7-4000" }, |
1685 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 2159 | { .id = STAC_HP_ZEPHYR, .name = "hp-zephyr" }, |
1686 | [STAC_HP_ZEPHYR] = "hp-zephyr", | 2160 | { .id = STAC_92HD83XXX_HP_LED, .name = "hp-led" }, |
1687 | [STAC_92HD83XXX_HP_LED] = "hp-led", | 2161 | { .id = STAC_92HD83XXX_HP_INV_LED, .name = "hp-inv-led" }, |
1688 | [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led", | 2162 | { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" }, |
1689 | [STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led", | 2163 | { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" }, |
1690 | [STAC_92HD83XXX_HEADSET_JACK] = "headset-jack", | 2164 | { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" }, |
2165 | {} | ||
1691 | }; | 2166 | }; |
1692 | 2167 | ||
1693 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 2168 | static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = { |
1694 | /* SigmaTel reference board */ | 2169 | /* SigmaTel reference board */ |
1695 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2170 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1696 | "DFI LanParty", STAC_92HD83XXX_REF), | 2171 | "DFI LanParty", STAC_92HD83XXX_REF), |
@@ -1730,6 +2205,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1730 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 2205 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1731 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, | 2206 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, |
1732 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 2207 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
2208 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1888, | ||
2209 | "HP Envy Spectre", STAC_HP_ENVY_BASS), | ||
1733 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, | 2210 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df, |
1734 | "HP Folio", STAC_92HD83XXX_HP_MIC_LED), | 2211 | "HP Folio", STAC_92HD83XXX_HP_MIC_LED), |
1735 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388, | 2212 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388, |
@@ -1766,76 +2243,297 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1766 | "HP Mini", STAC_92HD83XXX_HP_LED), | 2243 | "HP Mini", STAC_92HD83XXX_HP_LED), |
1767 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E, | 2244 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E, |
1768 | "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED), | 2245 | "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED), |
2246 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x148a, | ||
2247 | "HP Mini", STAC_92HD83XXX_HP_LED), | ||
2248 | SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD83XXX_HP), | ||
1769 | {} /* terminator */ | 2249 | {} /* terminator */ |
1770 | }; | 2250 | }; |
1771 | 2251 | ||
1772 | static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = { | 2252 | /* HP dv7 bass switch - GPIO5 */ |
1773 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, | 2253 | #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info |
1774 | "HP", STAC_HP_ZEPHYR), | 2254 | static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, |
1775 | {} /* terminator */ | 2255 | struct snd_ctl_elem_value *ucontrol) |
2256 | { | ||
2257 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2258 | struct sigmatel_spec *spec = codec->spec; | ||
2259 | ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); | ||
2260 | return 0; | ||
2261 | } | ||
2262 | |||
2263 | static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, | ||
2264 | struct snd_ctl_elem_value *ucontrol) | ||
2265 | { | ||
2266 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2267 | struct sigmatel_spec *spec = codec->spec; | ||
2268 | unsigned int gpio_data; | ||
2269 | |||
2270 | gpio_data = (spec->gpio_data & ~0x20) | | ||
2271 | (ucontrol->value.integer.value[0] ? 0x20 : 0); | ||
2272 | if (gpio_data == spec->gpio_data) | ||
2273 | return 0; | ||
2274 | spec->gpio_data = gpio_data; | ||
2275 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | ||
2276 | return 1; | ||
2277 | } | ||
2278 | |||
2279 | static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { | ||
2280 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2281 | .info = stac_hp_bass_gpio_info, | ||
2282 | .get = stac_hp_bass_gpio_get, | ||
2283 | .put = stac_hp_bass_gpio_put, | ||
1776 | }; | 2284 | }; |
1777 | 2285 | ||
1778 | static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 2286 | static int stac_add_hp_bass_switch(struct hda_codec *codec) |
1779 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 2287 | { |
1780 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | 2288 | struct sigmatel_spec *spec = codec->spec; |
1781 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, | 2289 | |
1782 | 0x00000000 | 2290 | if (!snd_hda_gen_add_kctl(&spec->gen, "Bass Speaker Playback Switch", |
2291 | &stac_hp_bass_sw_ctrl)) | ||
2292 | return -ENOMEM; | ||
2293 | |||
2294 | spec->gpio_mask |= 0x20; | ||
2295 | spec->gpio_dir |= 0x20; | ||
2296 | spec->gpio_data |= 0x20; | ||
2297 | return 0; | ||
2298 | } | ||
2299 | |||
2300 | static const struct hda_pintbl ref92hd71bxx_pin_configs[] = { | ||
2301 | { 0x0a, 0x02214030 }, | ||
2302 | { 0x0b, 0x02a19040 }, | ||
2303 | { 0x0c, 0x01a19020 }, | ||
2304 | { 0x0d, 0x01014010 }, | ||
2305 | { 0x0e, 0x0181302e }, | ||
2306 | { 0x0f, 0x01014010 }, | ||
2307 | { 0x14, 0x01019020 }, | ||
2308 | { 0x18, 0x90a000f0 }, | ||
2309 | { 0x19, 0x90a000f0 }, | ||
2310 | { 0x1e, 0x01452050 }, | ||
2311 | { 0x1f, 0x01452050 }, | ||
2312 | {} | ||
1783 | }; | 2313 | }; |
1784 | 2314 | ||
1785 | static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 2315 | static const struct hda_pintbl dell_m4_1_pin_configs[] = { |
1786 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 2316 | { 0x0a, 0x0421101f }, |
1787 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 2317 | { 0x0b, 0x04a11221 }, |
1788 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, | 2318 | { 0x0c, 0x40f000f0 }, |
1789 | 0x00000000 | 2319 | { 0x0d, 0x90170110 }, |
2320 | { 0x0e, 0x23a1902e }, | ||
2321 | { 0x0f, 0x23014250 }, | ||
2322 | { 0x14, 0x40f000f0 }, | ||
2323 | { 0x18, 0x90a000f0 }, | ||
2324 | { 0x19, 0x40f000f0 }, | ||
2325 | { 0x1e, 0x4f0000f0 }, | ||
2326 | { 0x1f, 0x4f0000f0 }, | ||
2327 | {} | ||
1790 | }; | 2328 | }; |
1791 | 2329 | ||
1792 | static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 2330 | static const struct hda_pintbl dell_m4_2_pin_configs[] = { |
1793 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 2331 | { 0x0a, 0x0421101f }, |
1794 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 2332 | { 0x0b, 0x04a11221 }, |
1795 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, | 2333 | { 0x0c, 0x90a70330 }, |
1796 | 0x00000000 | 2334 | { 0x0d, 0x90170110 }, |
2335 | { 0x0e, 0x23a1902e }, | ||
2336 | { 0x0f, 0x23014250 }, | ||
2337 | { 0x14, 0x40f000f0 }, | ||
2338 | { 0x18, 0x40f000f0 }, | ||
2339 | { 0x19, 0x40f000f0 }, | ||
2340 | { 0x1e, 0x044413b0 }, | ||
2341 | { 0x1f, 0x044413b0 }, | ||
2342 | {} | ||
1797 | }; | 2343 | }; |
1798 | 2344 | ||
1799 | static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 2345 | static const struct hda_pintbl dell_m4_3_pin_configs[] = { |
1800 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 2346 | { 0x0a, 0x0421101f }, |
1801 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, | 2347 | { 0x0b, 0x04a11221 }, |
1802 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, | 2348 | { 0x0c, 0x90a70330 }, |
1803 | 0x00000000 | 2349 | { 0x0d, 0x90170110 }, |
2350 | { 0x0e, 0x40f000f0 }, | ||
2351 | { 0x0f, 0x40f000f0 }, | ||
2352 | { 0x14, 0x40f000f0 }, | ||
2353 | { 0x18, 0x90a000f0 }, | ||
2354 | { 0x19, 0x40f000f0 }, | ||
2355 | { 0x1e, 0x044413b0 }, | ||
2356 | { 0x1f, 0x044413b0 }, | ||
2357 | {} | ||
1804 | }; | 2358 | }; |
1805 | 2359 | ||
1806 | static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 2360 | static void stac92hd71bxx_fixup_ref(struct hda_codec *codec, |
1807 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, | 2361 | const struct hda_fixup *fix, int action) |
1808 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, | 2362 | { |
1809 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | 2363 | struct sigmatel_spec *spec = codec->spec; |
1810 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, | 2364 | |
1811 | [STAC_HP_M4] = NULL, | 2365 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
1812 | [STAC_HP_DV4] = NULL, | 2366 | return; |
1813 | [STAC_HP_DV5] = NULL, | 2367 | |
1814 | [STAC_HP_HDX] = NULL, | 2368 | snd_hda_apply_pincfgs(codec, ref92hd71bxx_pin_configs); |
1815 | [STAC_HP_DV4_1222NR] = NULL, | 2369 | spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0; |
2370 | } | ||
2371 | |||
2372 | static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec, | ||
2373 | const struct hda_fixup *fix, int action) | ||
2374 | { | ||
2375 | struct sigmatel_spec *spec = codec->spec; | ||
2376 | struct hda_jack_tbl *jack; | ||
2377 | |||
2378 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
2379 | return; | ||
2380 | |||
2381 | /* Enable VREF power saving on GPIO1 detect */ | ||
2382 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
2383 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); | ||
2384 | snd_hda_jack_detect_enable_callback(codec, codec->afg, | ||
2385 | STAC_VREF_EVENT, | ||
2386 | stac_vref_event); | ||
2387 | jack = snd_hda_jack_tbl_get(codec, codec->afg); | ||
2388 | if (jack) | ||
2389 | jack->private_data = 0x02; | ||
2390 | |||
2391 | spec->gpio_mask |= 0x02; | ||
2392 | |||
2393 | /* enable internal microphone */ | ||
2394 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); | ||
2395 | } | ||
2396 | |||
2397 | static void stac92hd71bxx_fixup_hp_dv4(struct hda_codec *codec, | ||
2398 | const struct hda_fixup *fix, int action) | ||
2399 | { | ||
2400 | struct sigmatel_spec *spec = codec->spec; | ||
2401 | |||
2402 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
2403 | return; | ||
2404 | spec->gpio_led = 0x01; | ||
2405 | } | ||
2406 | |||
2407 | static void stac92hd71bxx_fixup_hp_dv5(struct hda_codec *codec, | ||
2408 | const struct hda_fixup *fix, int action) | ||
2409 | { | ||
2410 | unsigned int cap; | ||
2411 | |||
2412 | switch (action) { | ||
2413 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
2414 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | ||
2415 | break; | ||
2416 | |||
2417 | case HDA_FIXUP_ACT_PROBE: | ||
2418 | /* enable bass on HP dv7 */ | ||
2419 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); | ||
2420 | cap &= AC_GPIO_IO_COUNT; | ||
2421 | if (cap >= 6) | ||
2422 | stac_add_hp_bass_switch(codec); | ||
2423 | break; | ||
2424 | } | ||
2425 | } | ||
2426 | |||
2427 | static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec, | ||
2428 | const struct hda_fixup *fix, int action) | ||
2429 | { | ||
2430 | struct sigmatel_spec *spec = codec->spec; | ||
2431 | |||
2432 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
2433 | return; | ||
2434 | spec->gpio_led = 0x08; | ||
2435 | } | ||
2436 | |||
2437 | |||
2438 | static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, | ||
2439 | const struct hda_fixup *fix, int action) | ||
2440 | { | ||
2441 | struct sigmatel_spec *spec = codec->spec; | ||
2442 | |||
2443 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
2444 | return; | ||
2445 | |||
2446 | if (hp_blike_system(codec->subsystem_id)) { | ||
2447 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | ||
2448 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | ||
2449 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | ||
2450 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { | ||
2451 | /* It was changed in the BIOS to just satisfy MS DTM. | ||
2452 | * Lets turn it back into slaved HP | ||
2453 | */ | ||
2454 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | ||
2455 | | (AC_JACK_HP_OUT << | ||
2456 | AC_DEFCFG_DEVICE_SHIFT); | ||
2457 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | ||
2458 | | AC_DEFCFG_SEQUENCE))) | ||
2459 | | 0x1f; | ||
2460 | snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); | ||
2461 | } | ||
2462 | } | ||
2463 | |||
2464 | if (find_mute_led_cfg(codec, 1)) | ||
2465 | snd_printd("mute LED gpio %d polarity %d\n", | ||
2466 | spec->gpio_led, | ||
2467 | spec->gpio_led_polarity); | ||
2468 | |||
2469 | } | ||
2470 | |||
2471 | static const struct hda_fixup stac92hd71bxx_fixups[] = { | ||
2472 | [STAC_92HD71BXX_REF] = { | ||
2473 | .type = HDA_FIXUP_FUNC, | ||
2474 | .v.func = stac92hd71bxx_fixup_ref, | ||
2475 | }, | ||
2476 | [STAC_DELL_M4_1] = { | ||
2477 | .type = HDA_FIXUP_PINS, | ||
2478 | .v.pins = dell_m4_1_pin_configs, | ||
2479 | }, | ||
2480 | [STAC_DELL_M4_2] = { | ||
2481 | .type = HDA_FIXUP_PINS, | ||
2482 | .v.pins = dell_m4_2_pin_configs, | ||
2483 | }, | ||
2484 | [STAC_DELL_M4_3] = { | ||
2485 | .type = HDA_FIXUP_PINS, | ||
2486 | .v.pins = dell_m4_3_pin_configs, | ||
2487 | }, | ||
2488 | [STAC_HP_M4] = { | ||
2489 | .type = HDA_FIXUP_FUNC, | ||
2490 | .v.func = stac92hd71bxx_fixup_hp_m4, | ||
2491 | .chained = true, | ||
2492 | .chain_id = STAC_92HD71BXX_HP, | ||
2493 | }, | ||
2494 | [STAC_HP_DV4] = { | ||
2495 | .type = HDA_FIXUP_FUNC, | ||
2496 | .v.func = stac92hd71bxx_fixup_hp_dv4, | ||
2497 | .chained = true, | ||
2498 | .chain_id = STAC_HP_DV5, | ||
2499 | }, | ||
2500 | [STAC_HP_DV5] = { | ||
2501 | .type = HDA_FIXUP_FUNC, | ||
2502 | .v.func = stac92hd71bxx_fixup_hp_dv5, | ||
2503 | .chained = true, | ||
2504 | .chain_id = STAC_92HD71BXX_HP, | ||
2505 | }, | ||
2506 | [STAC_HP_HDX] = { | ||
2507 | .type = HDA_FIXUP_FUNC, | ||
2508 | .v.func = stac92hd71bxx_fixup_hp_hdx, | ||
2509 | .chained = true, | ||
2510 | .chain_id = STAC_92HD71BXX_HP, | ||
2511 | }, | ||
2512 | [STAC_92HD71BXX_HP] = { | ||
2513 | .type = HDA_FIXUP_FUNC, | ||
2514 | .v.func = stac92hd71bxx_fixup_hp, | ||
2515 | }, | ||
1816 | }; | 2516 | }; |
1817 | 2517 | ||
1818 | static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 2518 | static const struct hda_model_fixup stac92hd71bxx_models[] = { |
1819 | [STAC_92HD71BXX_AUTO] = "auto", | 2519 | { .id = STAC_92HD71BXX_REF, .name = "ref" }, |
1820 | [STAC_92HD71BXX_REF] = "ref", | 2520 | { .id = STAC_DELL_M4_1, .name = "dell-m4-1" }, |
1821 | [STAC_DELL_M4_1] = "dell-m4-1", | 2521 | { .id = STAC_DELL_M4_2, .name = "dell-m4-2" }, |
1822 | [STAC_DELL_M4_2] = "dell-m4-2", | 2522 | { .id = STAC_DELL_M4_3, .name = "dell-m4-3" }, |
1823 | [STAC_DELL_M4_3] = "dell-m4-3", | 2523 | { .id = STAC_HP_M4, .name = "hp-m4" }, |
1824 | [STAC_HP_M4] = "hp-m4", | 2524 | { .id = STAC_HP_DV4, .name = "hp-dv4" }, |
1825 | [STAC_HP_DV4] = "hp-dv4", | 2525 | { .id = STAC_HP_DV5, .name = "hp-dv5" }, |
1826 | [STAC_HP_DV5] = "hp-dv5", | 2526 | { .id = STAC_HP_HDX, .name = "hp-hdx" }, |
1827 | [STAC_HP_HDX] = "hp-hdx", | 2527 | { .id = STAC_HP_DV4, .name = "hp-dv4-1222nr" }, |
1828 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", | 2528 | {} |
1829 | }; | 2529 | }; |
1830 | 2530 | ||
1831 | static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 2531 | static const struct snd_pci_quirk stac92hd71bxx_fixup_tbl[] = { |
1832 | /* SigmaTel reference board */ | 2532 | /* SigmaTel reference board */ |
1833 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2533 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1834 | "DFI LanParty", STAC_92HD71BXX_REF), | 2534 | "DFI LanParty", STAC_92HD71BXX_REF), |
1835 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 2535 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1836 | "DFI LanParty", STAC_92HD71BXX_REF), | 2536 | "DFI LanParty", STAC_92HD71BXX_REF), |
1837 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, | ||
1838 | "HP dv4-1222nr", STAC_HP_DV4_1222NR), | ||
1839 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, | 2537 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, |
1840 | "HP", STAC_HP_DV5), | 2538 | "HP", STAC_HP_DV5), |
1841 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, | 2539 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
@@ -1858,6 +2556,7 @@ static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1858 | "HP DV6", STAC_HP_DV5), | 2556 | "HP DV6", STAC_HP_DV5), |
1859 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, | 2557 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, |
1860 | "HP", STAC_HP_DV5), | 2558 | "HP", STAC_HP_DV5), |
2559 | SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_HP, "HP", STAC_92HD71BXX_HP), | ||
1861 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 2560 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1862 | "unknown Dell", STAC_DELL_M4_1), | 2561 | "unknown Dell", STAC_DELL_M4_1), |
1863 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 2562 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -1885,10 +2584,18 @@ static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1885 | {} /* terminator */ | 2584 | {} /* terminator */ |
1886 | }; | 2585 | }; |
1887 | 2586 | ||
1888 | static const unsigned int ref922x_pin_configs[10] = { | 2587 | static const struct hda_pintbl ref922x_pin_configs[] = { |
1889 | 0x01014010, 0x01016011, 0x01012012, 0x0221401f, | 2588 | { 0x0a, 0x01014010 }, |
1890 | 0x01813122, 0x01011014, 0x01441030, 0x01c41030, | 2589 | { 0x0b, 0x01016011 }, |
1891 | 0x40000100, 0x40000100, | 2590 | { 0x0c, 0x01012012 }, |
2591 | { 0x0d, 0x0221401f }, | ||
2592 | { 0x0e, 0x01813122 }, | ||
2593 | { 0x0f, 0x01011014 }, | ||
2594 | { 0x10, 0x01441030 }, | ||
2595 | { 0x11, 0x01c41030 }, | ||
2596 | { 0x15, 0x40000100 }, | ||
2597 | { 0x1b, 0x40000100 }, | ||
2598 | {} | ||
1892 | }; | 2599 | }; |
1893 | 2600 | ||
1894 | /* | 2601 | /* |
@@ -1899,10 +2606,18 @@ static const unsigned int ref922x_pin_configs[10] = { | |||
1899 | 102801D1 | 2606 | 102801D1 |
1900 | 102801D2 | 2607 | 102801D2 |
1901 | */ | 2608 | */ |
1902 | static const unsigned int dell_922x_d81_pin_configs[10] = { | 2609 | static const struct hda_pintbl dell_922x_d81_pin_configs[] = { |
1903 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, | 2610 | { 0x0a, 0x02214030 }, |
1904 | 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, | 2611 | { 0x0b, 0x01a19021 }, |
1905 | 0x01813122, 0x400001f2, | 2612 | { 0x0c, 0x01111012 }, |
2613 | { 0x0d, 0x01114010 }, | ||
2614 | { 0x0e, 0x02a19020 }, | ||
2615 | { 0x0f, 0x01117011 }, | ||
2616 | { 0x10, 0x400001f0 }, | ||
2617 | { 0x11, 0x400001f1 }, | ||
2618 | { 0x15, 0x01813122 }, | ||
2619 | { 0x1b, 0x400001f2 }, | ||
2620 | {} | ||
1906 | }; | 2621 | }; |
1907 | 2622 | ||
1908 | /* | 2623 | /* |
@@ -1910,130 +2625,311 @@ static const unsigned int dell_922x_d81_pin_configs[10] = { | |||
1910 | 102801AC | 2625 | 102801AC |
1911 | 102801D0 | 2626 | 102801D0 |
1912 | */ | 2627 | */ |
1913 | static const unsigned int dell_922x_d82_pin_configs[10] = { | 2628 | static const struct hda_pintbl dell_922x_d82_pin_configs[] = { |
1914 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, | 2629 | { 0x0a, 0x02214030 }, |
1915 | 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, | 2630 | { 0x0b, 0x01a19021 }, |
1916 | 0x01813122, 0x400001f1, | 2631 | { 0x0c, 0x01111012 }, |
2632 | { 0x0d, 0x01114010 }, | ||
2633 | { 0x0e, 0x02a19020 }, | ||
2634 | { 0x0f, 0x01117011 }, | ||
2635 | { 0x10, 0x01451140 }, | ||
2636 | { 0x11, 0x400001f0 }, | ||
2637 | { 0x15, 0x01813122 }, | ||
2638 | { 0x1b, 0x400001f1 }, | ||
2639 | {} | ||
1917 | }; | 2640 | }; |
1918 | 2641 | ||
1919 | /* | 2642 | /* |
1920 | STAC 922X pin configs for | 2643 | STAC 922X pin configs for |
1921 | 102801BF | 2644 | 102801BF |
1922 | */ | 2645 | */ |
1923 | static const unsigned int dell_922x_m81_pin_configs[10] = { | 2646 | static const struct hda_pintbl dell_922x_m81_pin_configs[] = { |
1924 | 0x0321101f, 0x01112024, 0x01111222, 0x91174220, | 2647 | { 0x0a, 0x0321101f }, |
1925 | 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, | 2648 | { 0x0b, 0x01112024 }, |
1926 | 0x40C003f1, 0x405003f0, | 2649 | { 0x0c, 0x01111222 }, |
2650 | { 0x0d, 0x91174220 }, | ||
2651 | { 0x0e, 0x03a11050 }, | ||
2652 | { 0x0f, 0x01116221 }, | ||
2653 | { 0x10, 0x90a70330 }, | ||
2654 | { 0x11, 0x01452340 }, | ||
2655 | { 0x15, 0x40C003f1 }, | ||
2656 | { 0x1b, 0x405003f0 }, | ||
2657 | {} | ||
1927 | }; | 2658 | }; |
1928 | 2659 | ||
1929 | /* | 2660 | /* |
1930 | STAC 9221 A1 pin configs for | 2661 | STAC 9221 A1 pin configs for |
1931 | 102801D7 (Dell XPS M1210) | 2662 | 102801D7 (Dell XPS M1210) |
1932 | */ | 2663 | */ |
1933 | static const unsigned int dell_922x_m82_pin_configs[10] = { | 2664 | static const struct hda_pintbl dell_922x_m82_pin_configs[] = { |
1934 | 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, | 2665 | { 0x0a, 0x02211211 }, |
1935 | 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, | 2666 | { 0x0b, 0x408103ff }, |
1936 | 0x508003f3, 0x405003f4, | 2667 | { 0x0c, 0x02a1123e }, |
2668 | { 0x0d, 0x90100310 }, | ||
2669 | { 0x0e, 0x408003f1 }, | ||
2670 | { 0x0f, 0x0221121f }, | ||
2671 | { 0x10, 0x03451340 }, | ||
2672 | { 0x11, 0x40c003f2 }, | ||
2673 | { 0x15, 0x508003f3 }, | ||
2674 | { 0x1b, 0x405003f4 }, | ||
2675 | {} | ||
1937 | }; | 2676 | }; |
1938 | 2677 | ||
1939 | static const unsigned int d945gtp3_pin_configs[10] = { | 2678 | static const struct hda_pintbl d945gtp3_pin_configs[] = { |
1940 | 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, | 2679 | { 0x0a, 0x0221401f }, |
1941 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, | 2680 | { 0x0b, 0x01a19022 }, |
1942 | 0x02a19120, 0x40000100, | 2681 | { 0x0c, 0x01813021 }, |
2682 | { 0x0d, 0x01014010 }, | ||
2683 | { 0x0e, 0x40000100 }, | ||
2684 | { 0x0f, 0x40000100 }, | ||
2685 | { 0x10, 0x40000100 }, | ||
2686 | { 0x11, 0x40000100 }, | ||
2687 | { 0x15, 0x02a19120 }, | ||
2688 | { 0x1b, 0x40000100 }, | ||
2689 | {} | ||
1943 | }; | 2690 | }; |
1944 | 2691 | ||
1945 | static const unsigned int d945gtp5_pin_configs[10] = { | 2692 | static const struct hda_pintbl d945gtp5_pin_configs[] = { |
1946 | 0x0221401f, 0x01011012, 0x01813024, 0x01014010, | 2693 | { 0x0a, 0x0221401f }, |
1947 | 0x01a19021, 0x01016011, 0x01452130, 0x40000100, | 2694 | { 0x0b, 0x01011012 }, |
1948 | 0x02a19320, 0x40000100, | 2695 | { 0x0c, 0x01813024 }, |
2696 | { 0x0d, 0x01014010 }, | ||
2697 | { 0x0e, 0x01a19021 }, | ||
2698 | { 0x0f, 0x01016011 }, | ||
2699 | { 0x10, 0x01452130 }, | ||
2700 | { 0x11, 0x40000100 }, | ||
2701 | { 0x15, 0x02a19320 }, | ||
2702 | { 0x1b, 0x40000100 }, | ||
2703 | {} | ||
1949 | }; | 2704 | }; |
1950 | 2705 | ||
1951 | static const unsigned int intel_mac_v1_pin_configs[10] = { | 2706 | static const struct hda_pintbl intel_mac_v1_pin_configs[] = { |
1952 | 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, | 2707 | { 0x0a, 0x0121e21f }, |
1953 | 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, | 2708 | { 0x0b, 0x400000ff }, |
1954 | 0x400000fc, 0x400000fb, | 2709 | { 0x0c, 0x9017e110 }, |
2710 | { 0x0d, 0x400000fd }, | ||
2711 | { 0x0e, 0x400000fe }, | ||
2712 | { 0x0f, 0x0181e020 }, | ||
2713 | { 0x10, 0x1145e030 }, | ||
2714 | { 0x11, 0x11c5e240 }, | ||
2715 | { 0x15, 0x400000fc }, | ||
2716 | { 0x1b, 0x400000fb }, | ||
2717 | {} | ||
1955 | }; | 2718 | }; |
1956 | 2719 | ||
1957 | static const unsigned int intel_mac_v2_pin_configs[10] = { | 2720 | static const struct hda_pintbl intel_mac_v2_pin_configs[] = { |
1958 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | 2721 | { 0x0a, 0x0121e21f }, |
1959 | 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, | 2722 | { 0x0b, 0x90a7012e }, |
1960 | 0x400000fc, 0x400000fb, | 2723 | { 0x0c, 0x9017e110 }, |
2724 | { 0x0d, 0x400000fd }, | ||
2725 | { 0x0e, 0x400000fe }, | ||
2726 | { 0x0f, 0x0181e020 }, | ||
2727 | { 0x10, 0x1145e230 }, | ||
2728 | { 0x11, 0x500000fa }, | ||
2729 | { 0x15, 0x400000fc }, | ||
2730 | { 0x1b, 0x400000fb }, | ||
2731 | {} | ||
1961 | }; | 2732 | }; |
1962 | 2733 | ||
1963 | static const unsigned int intel_mac_v3_pin_configs[10] = { | 2734 | static const struct hda_pintbl intel_mac_v3_pin_configs[] = { |
1964 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | 2735 | { 0x0a, 0x0121e21f }, |
1965 | 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, | 2736 | { 0x0b, 0x90a7012e }, |
1966 | 0x400000fc, 0x400000fb, | 2737 | { 0x0c, 0x9017e110 }, |
2738 | { 0x0d, 0x400000fd }, | ||
2739 | { 0x0e, 0x400000fe }, | ||
2740 | { 0x0f, 0x0181e020 }, | ||
2741 | { 0x10, 0x1145e230 }, | ||
2742 | { 0x11, 0x11c5e240 }, | ||
2743 | { 0x15, 0x400000fc }, | ||
2744 | { 0x1b, 0x400000fb }, | ||
2745 | {} | ||
1967 | }; | 2746 | }; |
1968 | 2747 | ||
1969 | static const unsigned int intel_mac_v4_pin_configs[10] = { | 2748 | static const struct hda_pintbl intel_mac_v4_pin_configs[] = { |
1970 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, | 2749 | { 0x0a, 0x0321e21f }, |
1971 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, | 2750 | { 0x0b, 0x03a1e02e }, |
1972 | 0x400000fc, 0x400000fb, | 2751 | { 0x0c, 0x9017e110 }, |
2752 | { 0x0d, 0x9017e11f }, | ||
2753 | { 0x0e, 0x400000fe }, | ||
2754 | { 0x0f, 0x0381e020 }, | ||
2755 | { 0x10, 0x1345e230 }, | ||
2756 | { 0x11, 0x13c5e240 }, | ||
2757 | { 0x15, 0x400000fc }, | ||
2758 | { 0x1b, 0x400000fb }, | ||
2759 | {} | ||
1973 | }; | 2760 | }; |
1974 | 2761 | ||
1975 | static const unsigned int intel_mac_v5_pin_configs[10] = { | 2762 | static const struct hda_pintbl intel_mac_v5_pin_configs[] = { |
1976 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, | 2763 | { 0x0a, 0x0321e21f }, |
1977 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, | 2764 | { 0x0b, 0x03a1e02e }, |
1978 | 0x400000fc, 0x400000fb, | 2765 | { 0x0c, 0x9017e110 }, |
2766 | { 0x0d, 0x9017e11f }, | ||
2767 | { 0x0e, 0x400000fe }, | ||
2768 | { 0x0f, 0x0381e020 }, | ||
2769 | { 0x10, 0x1345e230 }, | ||
2770 | { 0x11, 0x13c5e240 }, | ||
2771 | { 0x15, 0x400000fc }, | ||
2772 | { 0x1b, 0x400000fb }, | ||
2773 | {} | ||
1979 | }; | 2774 | }; |
1980 | 2775 | ||
1981 | static const unsigned int ecs202_pin_configs[10] = { | 2776 | static const struct hda_pintbl ecs202_pin_configs[] = { |
1982 | 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, | 2777 | { 0x0a, 0x0221401f }, |
1983 | 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, | 2778 | { 0x0b, 0x02a19020 }, |
1984 | 0x9037012e, 0x40e000f2, | 2779 | { 0x0c, 0x01a19020 }, |
2780 | { 0x0d, 0x01114010 }, | ||
2781 | { 0x0e, 0x408000f0 }, | ||
2782 | { 0x0f, 0x01813022 }, | ||
2783 | { 0x10, 0x074510a0 }, | ||
2784 | { 0x11, 0x40c400f1 }, | ||
2785 | { 0x15, 0x9037012e }, | ||
2786 | { 0x1b, 0x40e000f2 }, | ||
2787 | {} | ||
1985 | }; | 2788 | }; |
1986 | 2789 | ||
1987 | static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 2790 | /* codec SSIDs for Intel Mac sharing the same PCI SSID 8384:7680 */ |
1988 | [STAC_D945_REF] = ref922x_pin_configs, | 2791 | static const struct snd_pci_quirk stac922x_intel_mac_fixup_tbl[] = { |
1989 | [STAC_D945GTP3] = d945gtp3_pin_configs, | 2792 | SND_PCI_QUIRK(0x106b, 0x0800, "Mac", STAC_INTEL_MAC_V1), |
1990 | [STAC_D945GTP5] = d945gtp5_pin_configs, | 2793 | SND_PCI_QUIRK(0x106b, 0x0600, "Mac", STAC_INTEL_MAC_V2), |
1991 | [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, | 2794 | SND_PCI_QUIRK(0x106b, 0x0700, "Mac", STAC_INTEL_MAC_V2), |
1992 | [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, | 2795 | SND_PCI_QUIRK(0x106b, 0x0e00, "Mac", STAC_INTEL_MAC_V3), |
1993 | [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, | 2796 | SND_PCI_QUIRK(0x106b, 0x0f00, "Mac", STAC_INTEL_MAC_V3), |
1994 | [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, | 2797 | SND_PCI_QUIRK(0x106b, 0x1600, "Mac", STAC_INTEL_MAC_V3), |
1995 | [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, | 2798 | SND_PCI_QUIRK(0x106b, 0x1700, "Mac", STAC_INTEL_MAC_V3), |
1996 | [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs, | 2799 | SND_PCI_QUIRK(0x106b, 0x0200, "Mac", STAC_INTEL_MAC_V3), |
1997 | /* for backward compatibility */ | 2800 | SND_PCI_QUIRK(0x106b, 0x1e00, "Mac", STAC_INTEL_MAC_V3), |
1998 | [STAC_MACMINI] = intel_mac_v3_pin_configs, | 2801 | SND_PCI_QUIRK(0x106b, 0x1a00, "Mac", STAC_INTEL_MAC_V4), |
1999 | [STAC_MACBOOK] = intel_mac_v5_pin_configs, | 2802 | SND_PCI_QUIRK(0x106b, 0x0a00, "Mac", STAC_INTEL_MAC_V5), |
2000 | [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, | 2803 | SND_PCI_QUIRK(0x106b, 0x2200, "Mac", STAC_INTEL_MAC_V5), |
2001 | [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, | 2804 | {} |
2002 | [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, | ||
2003 | [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, | ||
2004 | [STAC_ECS_202] = ecs202_pin_configs, | ||
2005 | [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, | ||
2006 | [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, | ||
2007 | [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, | ||
2008 | [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, | ||
2009 | }; | 2805 | }; |
2010 | 2806 | ||
2011 | static const char * const stac922x_models[STAC_922X_MODELS] = { | 2807 | static const struct hda_fixup stac922x_fixups[]; |
2012 | [STAC_922X_AUTO] = "auto", | 2808 | |
2013 | [STAC_D945_REF] = "ref", | 2809 | /* remap the fixup from codec SSID and apply it */ |
2014 | [STAC_D945GTP5] = "5stack", | 2810 | static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec, |
2015 | [STAC_D945GTP3] = "3stack", | 2811 | const struct hda_fixup *fix, |
2016 | [STAC_INTEL_MAC_V1] = "intel-mac-v1", | 2812 | int action) |
2017 | [STAC_INTEL_MAC_V2] = "intel-mac-v2", | 2813 | { |
2018 | [STAC_INTEL_MAC_V3] = "intel-mac-v3", | 2814 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
2019 | [STAC_INTEL_MAC_V4] = "intel-mac-v4", | 2815 | return; |
2020 | [STAC_INTEL_MAC_V5] = "intel-mac-v5", | 2816 | snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl, |
2021 | [STAC_INTEL_MAC_AUTO] = "intel-mac-auto", | 2817 | stac922x_fixups); |
2818 | if (codec->fixup_id != STAC_INTEL_MAC_AUTO) | ||
2819 | snd_hda_apply_fixup(codec, action); | ||
2820 | } | ||
2821 | |||
2822 | static void stac922x_fixup_intel_mac_gpio(struct hda_codec *codec, | ||
2823 | const struct hda_fixup *fix, | ||
2824 | int action) | ||
2825 | { | ||
2826 | struct sigmatel_spec *spec = codec->spec; | ||
2827 | |||
2828 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2829 | spec->gpio_mask = spec->gpio_dir = 0x03; | ||
2830 | spec->gpio_data = 0x03; | ||
2831 | } | ||
2832 | } | ||
2833 | |||
2834 | static const struct hda_fixup stac922x_fixups[] = { | ||
2835 | [STAC_D945_REF] = { | ||
2836 | .type = HDA_FIXUP_PINS, | ||
2837 | .v.pins = ref922x_pin_configs, | ||
2838 | }, | ||
2839 | [STAC_D945GTP3] = { | ||
2840 | .type = HDA_FIXUP_PINS, | ||
2841 | .v.pins = d945gtp3_pin_configs, | ||
2842 | }, | ||
2843 | [STAC_D945GTP5] = { | ||
2844 | .type = HDA_FIXUP_PINS, | ||
2845 | .v.pins = d945gtp5_pin_configs, | ||
2846 | }, | ||
2847 | [STAC_INTEL_MAC_AUTO] = { | ||
2848 | .type = HDA_FIXUP_FUNC, | ||
2849 | .v.func = stac922x_fixup_intel_mac_auto, | ||
2850 | }, | ||
2851 | [STAC_INTEL_MAC_V1] = { | ||
2852 | .type = HDA_FIXUP_PINS, | ||
2853 | .v.pins = intel_mac_v1_pin_configs, | ||
2854 | .chained = true, | ||
2855 | .chain_id = STAC_922X_INTEL_MAC_GPIO, | ||
2856 | }, | ||
2857 | [STAC_INTEL_MAC_V2] = { | ||
2858 | .type = HDA_FIXUP_PINS, | ||
2859 | .v.pins = intel_mac_v2_pin_configs, | ||
2860 | .chained = true, | ||
2861 | .chain_id = STAC_922X_INTEL_MAC_GPIO, | ||
2862 | }, | ||
2863 | [STAC_INTEL_MAC_V3] = { | ||
2864 | .type = HDA_FIXUP_PINS, | ||
2865 | .v.pins = intel_mac_v3_pin_configs, | ||
2866 | .chained = true, | ||
2867 | .chain_id = STAC_922X_INTEL_MAC_GPIO, | ||
2868 | }, | ||
2869 | [STAC_INTEL_MAC_V4] = { | ||
2870 | .type = HDA_FIXUP_PINS, | ||
2871 | .v.pins = intel_mac_v4_pin_configs, | ||
2872 | .chained = true, | ||
2873 | .chain_id = STAC_922X_INTEL_MAC_GPIO, | ||
2874 | }, | ||
2875 | [STAC_INTEL_MAC_V5] = { | ||
2876 | .type = HDA_FIXUP_PINS, | ||
2877 | .v.pins = intel_mac_v5_pin_configs, | ||
2878 | .chained = true, | ||
2879 | .chain_id = STAC_922X_INTEL_MAC_GPIO, | ||
2880 | }, | ||
2881 | [STAC_922X_INTEL_MAC_GPIO] = { | ||
2882 | .type = HDA_FIXUP_FUNC, | ||
2883 | .v.func = stac922x_fixup_intel_mac_gpio, | ||
2884 | }, | ||
2885 | [STAC_ECS_202] = { | ||
2886 | .type = HDA_FIXUP_PINS, | ||
2887 | .v.pins = ecs202_pin_configs, | ||
2888 | }, | ||
2889 | [STAC_922X_DELL_D81] = { | ||
2890 | .type = HDA_FIXUP_PINS, | ||
2891 | .v.pins = dell_922x_d81_pin_configs, | ||
2892 | }, | ||
2893 | [STAC_922X_DELL_D82] = { | ||
2894 | .type = HDA_FIXUP_PINS, | ||
2895 | .v.pins = dell_922x_d82_pin_configs, | ||
2896 | }, | ||
2897 | [STAC_922X_DELL_M81] = { | ||
2898 | .type = HDA_FIXUP_PINS, | ||
2899 | .v.pins = dell_922x_m81_pin_configs, | ||
2900 | }, | ||
2901 | [STAC_922X_DELL_M82] = { | ||
2902 | .type = HDA_FIXUP_PINS, | ||
2903 | .v.pins = dell_922x_m82_pin_configs, | ||
2904 | }, | ||
2905 | }; | ||
2906 | |||
2907 | static const struct hda_model_fixup stac922x_models[] = { | ||
2908 | { .id = STAC_D945_REF, .name = "ref" }, | ||
2909 | { .id = STAC_D945GTP5, .name = "5stack" }, | ||
2910 | { .id = STAC_D945GTP3, .name = "3stack" }, | ||
2911 | { .id = STAC_INTEL_MAC_V1, .name = "intel-mac-v1" }, | ||
2912 | { .id = STAC_INTEL_MAC_V2, .name = "intel-mac-v2" }, | ||
2913 | { .id = STAC_INTEL_MAC_V3, .name = "intel-mac-v3" }, | ||
2914 | { .id = STAC_INTEL_MAC_V4, .name = "intel-mac-v4" }, | ||
2915 | { .id = STAC_INTEL_MAC_V5, .name = "intel-mac-v5" }, | ||
2916 | { .id = STAC_INTEL_MAC_AUTO, .name = "intel-mac-auto" }, | ||
2917 | { .id = STAC_ECS_202, .name = "ecs202" }, | ||
2918 | { .id = STAC_922X_DELL_D81, .name = "dell-d81" }, | ||
2919 | { .id = STAC_922X_DELL_D82, .name = "dell-d82" }, | ||
2920 | { .id = STAC_922X_DELL_M81, .name = "dell-m81" }, | ||
2921 | { .id = STAC_922X_DELL_M82, .name = "dell-m82" }, | ||
2022 | /* for backward compatibility */ | 2922 | /* for backward compatibility */ |
2023 | [STAC_MACMINI] = "macmini", | 2923 | { .id = STAC_INTEL_MAC_V3, .name = "macmini" }, |
2024 | [STAC_MACBOOK] = "macbook", | 2924 | { .id = STAC_INTEL_MAC_V5, .name = "macbook" }, |
2025 | [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", | 2925 | { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro-v1" }, |
2026 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", | 2926 | { .id = STAC_INTEL_MAC_V3, .name = "macbook-pro" }, |
2027 | [STAC_IMAC_INTEL] = "imac-intel", | 2927 | { .id = STAC_INTEL_MAC_V2, .name = "imac-intel" }, |
2028 | [STAC_IMAC_INTEL_20] = "imac-intel-20", | 2928 | { .id = STAC_INTEL_MAC_V3, .name = "imac-intel-20" }, |
2029 | [STAC_ECS_202] = "ecs202", | 2929 | {} |
2030 | [STAC_922X_DELL_D81] = "dell-d81", | ||
2031 | [STAC_922X_DELL_D82] = "dell-d82", | ||
2032 | [STAC_922X_DELL_M81] = "dell-m81", | ||
2033 | [STAC_922X_DELL_M82] = "dell-m82", | ||
2034 | }; | 2930 | }; |
2035 | 2931 | ||
2036 | static const struct snd_pci_quirk stac922x_cfg_tbl[] = { | 2932 | static const struct snd_pci_quirk stac922x_fixup_tbl[] = { |
2037 | /* SigmaTel reference board */ | 2933 | /* SigmaTel reference board */ |
2038 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2934 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2039 | "DFI LanParty", STAC_D945_REF), | 2935 | "DFI LanParty", STAC_D945_REF), |
@@ -2096,9 +2992,10 @@ static const struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2096 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, | 2992 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, |
2097 | "Intel D945", STAC_D945_REF), | 2993 | "Intel D945", STAC_D945_REF), |
2098 | /* other systems */ | 2994 | /* other systems */ |
2995 | |||
2099 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ | 2996 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ |
2100 | SND_PCI_QUIRK(0x8384, 0x7680, | 2997 | SND_PCI_QUIRK(0x8384, 0x7680, "Mac", STAC_INTEL_MAC_AUTO), |
2101 | "Mac", STAC_INTEL_MAC_AUTO), | 2998 | |
2102 | /* Dell systems */ | 2999 | /* Dell systems */ |
2103 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, | 3000 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, |
2104 | "unknown Dell", STAC_922X_DELL_D81), | 3001 | "unknown Dell", STAC_922X_DELL_D81), |
@@ -2124,65 +3021,229 @@ static const struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2124 | {} /* terminator */ | 3021 | {} /* terminator */ |
2125 | }; | 3022 | }; |
2126 | 3023 | ||
2127 | static const unsigned int ref927x_pin_configs[14] = { | 3024 | static const struct hda_pintbl ref927x_pin_configs[] = { |
2128 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | 3025 | { 0x0a, 0x02214020 }, |
2129 | 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, | 3026 | { 0x0b, 0x02a19080 }, |
2130 | 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, | 3027 | { 0x0c, 0x0181304e }, |
2131 | 0x01c42190, 0x40000100, | 3028 | { 0x0d, 0x01014010 }, |
3029 | { 0x0e, 0x01a19040 }, | ||
3030 | { 0x0f, 0x01011012 }, | ||
3031 | { 0x10, 0x01016011 }, | ||
3032 | { 0x11, 0x0101201f }, | ||
3033 | { 0x12, 0x183301f0 }, | ||
3034 | { 0x13, 0x18a001f0 }, | ||
3035 | { 0x14, 0x18a001f0 }, | ||
3036 | { 0x21, 0x01442070 }, | ||
3037 | { 0x22, 0x01c42190 }, | ||
3038 | { 0x23, 0x40000100 }, | ||
3039 | {} | ||
2132 | }; | 3040 | }; |
2133 | 3041 | ||
2134 | static const unsigned int d965_3st_pin_configs[14] = { | 3042 | static const struct hda_pintbl d965_3st_pin_configs[] = { |
2135 | 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, | 3043 | { 0x0a, 0x0221401f }, |
2136 | 0x01a19021, 0x01813024, 0x40000100, 0x40000100, | 3044 | { 0x0b, 0x02a19120 }, |
2137 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, | 3045 | { 0x0c, 0x40000100 }, |
2138 | 0x40000100, 0x40000100 | 3046 | { 0x0d, 0x01014011 }, |
3047 | { 0x0e, 0x01a19021 }, | ||
3048 | { 0x0f, 0x01813024 }, | ||
3049 | { 0x10, 0x40000100 }, | ||
3050 | { 0x11, 0x40000100 }, | ||
3051 | { 0x12, 0x40000100 }, | ||
3052 | { 0x13, 0x40000100 }, | ||
3053 | { 0x14, 0x40000100 }, | ||
3054 | { 0x21, 0x40000100 }, | ||
3055 | { 0x22, 0x40000100 }, | ||
3056 | { 0x23, 0x40000100 }, | ||
3057 | {} | ||
2139 | }; | 3058 | }; |
2140 | 3059 | ||
2141 | static const unsigned int d965_5st_pin_configs[14] = { | 3060 | static const struct hda_pintbl d965_5st_pin_configs[] = { |
2142 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | 3061 | { 0x0a, 0x02214020 }, |
2143 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, | 3062 | { 0x0b, 0x02a19080 }, |
2144 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, | 3063 | { 0x0c, 0x0181304e }, |
2145 | 0x40000100, 0x40000100 | 3064 | { 0x0d, 0x01014010 }, |
3065 | { 0x0e, 0x01a19040 }, | ||
3066 | { 0x0f, 0x01011012 }, | ||
3067 | { 0x10, 0x01016011 }, | ||
3068 | { 0x11, 0x40000100 }, | ||
3069 | { 0x12, 0x40000100 }, | ||
3070 | { 0x13, 0x40000100 }, | ||
3071 | { 0x14, 0x40000100 }, | ||
3072 | { 0x21, 0x01442070 }, | ||
3073 | { 0x22, 0x40000100 }, | ||
3074 | { 0x23, 0x40000100 }, | ||
3075 | {} | ||
2146 | }; | 3076 | }; |
2147 | 3077 | ||
2148 | static const unsigned int d965_5st_no_fp_pin_configs[14] = { | 3078 | static const struct hda_pintbl d965_5st_no_fp_pin_configs[] = { |
2149 | 0x40000100, 0x40000100, 0x0181304e, 0x01014010, | 3079 | { 0x0a, 0x40000100 }, |
2150 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, | 3080 | { 0x0b, 0x40000100 }, |
2151 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, | 3081 | { 0x0c, 0x0181304e }, |
2152 | 0x40000100, 0x40000100 | 3082 | { 0x0d, 0x01014010 }, |
3083 | { 0x0e, 0x01a19040 }, | ||
3084 | { 0x0f, 0x01011012 }, | ||
3085 | { 0x10, 0x01016011 }, | ||
3086 | { 0x11, 0x40000100 }, | ||
3087 | { 0x12, 0x40000100 }, | ||
3088 | { 0x13, 0x40000100 }, | ||
3089 | { 0x14, 0x40000100 }, | ||
3090 | { 0x21, 0x01442070 }, | ||
3091 | { 0x22, 0x40000100 }, | ||
3092 | { 0x23, 0x40000100 }, | ||
3093 | {} | ||
2153 | }; | 3094 | }; |
2154 | 3095 | ||
2155 | static const unsigned int dell_3st_pin_configs[14] = { | 3096 | static const struct hda_pintbl dell_3st_pin_configs[] = { |
2156 | 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, | 3097 | { 0x0a, 0x02211230 }, |
2157 | 0x01111212, 0x01116211, 0x01813050, 0x01112214, | 3098 | { 0x0b, 0x02a11220 }, |
2158 | 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, | 3099 | { 0x0c, 0x01a19040 }, |
2159 | 0x40c003fc, 0x40000100 | 3100 | { 0x0d, 0x01114210 }, |
3101 | { 0x0e, 0x01111212 }, | ||
3102 | { 0x0f, 0x01116211 }, | ||
3103 | { 0x10, 0x01813050 }, | ||
3104 | { 0x11, 0x01112214 }, | ||
3105 | { 0x12, 0x403003fa }, | ||
3106 | { 0x13, 0x90a60040 }, | ||
3107 | { 0x14, 0x90a60040 }, | ||
3108 | { 0x21, 0x404003fb }, | ||
3109 | { 0x22, 0x40c003fc }, | ||
3110 | { 0x23, 0x40000100 }, | ||
3111 | {} | ||
2160 | }; | 3112 | }; |
2161 | 3113 | ||
2162 | static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | 3114 | static void stac927x_fixup_ref_no_jd(struct hda_codec *codec, |
2163 | [STAC_D965_REF_NO_JD] = ref927x_pin_configs, | 3115 | const struct hda_fixup *fix, int action) |
2164 | [STAC_D965_REF] = ref927x_pin_configs, | 3116 | { |
2165 | [STAC_D965_3ST] = d965_3st_pin_configs, | 3117 | /* no jack detecion for ref-no-jd model */ |
2166 | [STAC_D965_5ST] = d965_5st_pin_configs, | 3118 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
2167 | [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs, | 3119 | codec->no_jack_detect = 1; |
2168 | [STAC_DELL_3ST] = dell_3st_pin_configs, | 3120 | } |
2169 | [STAC_DELL_BIOS] = NULL, | 3121 | |
2170 | [STAC_927X_VOLKNOB] = NULL, | 3122 | static void stac927x_fixup_ref(struct hda_codec *codec, |
3123 | const struct hda_fixup *fix, int action) | ||
3124 | { | ||
3125 | struct sigmatel_spec *spec = codec->spec; | ||
3126 | |||
3127 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3128 | snd_hda_apply_pincfgs(codec, ref927x_pin_configs); | ||
3129 | spec->eapd_mask = spec->gpio_mask = 0; | ||
3130 | spec->gpio_dir = spec->gpio_data = 0; | ||
3131 | } | ||
3132 | } | ||
3133 | |||
3134 | static void stac927x_fixup_dell_dmic(struct hda_codec *codec, | ||
3135 | const struct hda_fixup *fix, int action) | ||
3136 | { | ||
3137 | struct sigmatel_spec *spec = codec->spec; | ||
3138 | |||
3139 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | ||
3140 | return; | ||
3141 | |||
3142 | if (codec->subsystem_id != 0x1028022f) { | ||
3143 | /* GPIO2 High = Enable EAPD */ | ||
3144 | spec->eapd_mask = spec->gpio_mask = 0x04; | ||
3145 | spec->gpio_dir = spec->gpio_data = 0x04; | ||
3146 | } | ||
3147 | |||
3148 | snd_hda_add_verbs(codec, dell_3st_core_init); | ||
3149 | spec->volknob_init = 1; | ||
3150 | } | ||
3151 | |||
3152 | static void stac927x_fixup_volknob(struct hda_codec *codec, | ||
3153 | const struct hda_fixup *fix, int action) | ||
3154 | { | ||
3155 | struct sigmatel_spec *spec = codec->spec; | ||
3156 | |||
3157 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3158 | snd_hda_add_verbs(codec, stac927x_volknob_core_init); | ||
3159 | spec->volknob_init = 1; | ||
3160 | } | ||
3161 | } | ||
3162 | |||
3163 | static const struct hda_fixup stac927x_fixups[] = { | ||
3164 | [STAC_D965_REF_NO_JD] = { | ||
3165 | .type = HDA_FIXUP_FUNC, | ||
3166 | .v.func = stac927x_fixup_ref_no_jd, | ||
3167 | .chained = true, | ||
3168 | .chain_id = STAC_D965_REF, | ||
3169 | }, | ||
3170 | [STAC_D965_REF] = { | ||
3171 | .type = HDA_FIXUP_FUNC, | ||
3172 | .v.func = stac927x_fixup_ref, | ||
3173 | }, | ||
3174 | [STAC_D965_3ST] = { | ||
3175 | .type = HDA_FIXUP_PINS, | ||
3176 | .v.pins = d965_3st_pin_configs, | ||
3177 | .chained = true, | ||
3178 | .chain_id = STAC_D965_VERBS, | ||
3179 | }, | ||
3180 | [STAC_D965_5ST] = { | ||
3181 | .type = HDA_FIXUP_PINS, | ||
3182 | .v.pins = d965_5st_pin_configs, | ||
3183 | .chained = true, | ||
3184 | .chain_id = STAC_D965_VERBS, | ||
3185 | }, | ||
3186 | [STAC_D965_VERBS] = { | ||
3187 | .type = HDA_FIXUP_VERBS, | ||
3188 | .v.verbs = d965_core_init, | ||
3189 | }, | ||
3190 | [STAC_D965_5ST_NO_FP] = { | ||
3191 | .type = HDA_FIXUP_PINS, | ||
3192 | .v.pins = d965_5st_no_fp_pin_configs, | ||
3193 | }, | ||
3194 | [STAC_DELL_3ST] = { | ||
3195 | .type = HDA_FIXUP_PINS, | ||
3196 | .v.pins = dell_3st_pin_configs, | ||
3197 | .chained = true, | ||
3198 | .chain_id = STAC_927X_DELL_DMIC, | ||
3199 | }, | ||
3200 | [STAC_DELL_BIOS] = { | ||
3201 | .type = HDA_FIXUP_PINS, | ||
3202 | .v.pins = (const struct hda_pintbl[]) { | ||
3203 | /* configure the analog microphone on some laptops */ | ||
3204 | { 0x0c, 0x90a79130 }, | ||
3205 | /* correct the front output jack as a hp out */ | ||
3206 | { 0x0f, 0x0227011f }, | ||
3207 | /* correct the front input jack as a mic */ | ||
3208 | { 0x0e, 0x02a79130 }, | ||
3209 | {} | ||
3210 | }, | ||
3211 | .chained = true, | ||
3212 | .chain_id = STAC_927X_DELL_DMIC, | ||
3213 | }, | ||
3214 | [STAC_DELL_BIOS_SPDIF] = { | ||
3215 | .type = HDA_FIXUP_PINS, | ||
3216 | .v.pins = (const struct hda_pintbl[]) { | ||
3217 | /* correct the device field to SPDIF out */ | ||
3218 | { 0x21, 0x01442070 }, | ||
3219 | {} | ||
3220 | }, | ||
3221 | .chained = true, | ||
3222 | .chain_id = STAC_DELL_BIOS, | ||
3223 | }, | ||
3224 | [STAC_927X_DELL_DMIC] = { | ||
3225 | .type = HDA_FIXUP_FUNC, | ||
3226 | .v.func = stac927x_fixup_dell_dmic, | ||
3227 | }, | ||
3228 | [STAC_927X_VOLKNOB] = { | ||
3229 | .type = HDA_FIXUP_FUNC, | ||
3230 | .v.func = stac927x_fixup_volknob, | ||
3231 | }, | ||
2171 | }; | 3232 | }; |
2172 | 3233 | ||
2173 | static const char * const stac927x_models[STAC_927X_MODELS] = { | 3234 | static const struct hda_model_fixup stac927x_models[] = { |
2174 | [STAC_927X_AUTO] = "auto", | 3235 | { .id = STAC_D965_REF_NO_JD, .name = "ref-no-jd" }, |
2175 | [STAC_D965_REF_NO_JD] = "ref-no-jd", | 3236 | { .id = STAC_D965_REF, .name = "ref" }, |
2176 | [STAC_D965_REF] = "ref", | 3237 | { .id = STAC_D965_3ST, .name = "3stack" }, |
2177 | [STAC_D965_3ST] = "3stack", | 3238 | { .id = STAC_D965_5ST, .name = "5stack" }, |
2178 | [STAC_D965_5ST] = "5stack", | 3239 | { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" }, |
2179 | [STAC_D965_5ST_NO_FP] = "5stack-no-fp", | 3240 | { .id = STAC_DELL_3ST, .name = "dell-3stack" }, |
2180 | [STAC_DELL_3ST] = "dell-3stack", | 3241 | { .id = STAC_DELL_BIOS, .name = "dell-bios" }, |
2181 | [STAC_DELL_BIOS] = "dell-bios", | 3242 | { .id = STAC_927X_VOLKNOB, .name = "volknob" }, |
2182 | [STAC_927X_VOLKNOB] = "volknob", | 3243 | {} |
2183 | }; | 3244 | }; |
2184 | 3245 | ||
2185 | static const struct snd_pci_quirk stac927x_cfg_tbl[] = { | 3246 | static const struct snd_pci_quirk stac927x_fixup_tbl[] = { |
2186 | /* SigmaTel reference board */ | 3247 | /* SigmaTel reference board */ |
2187 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 3248 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2188 | "DFI LanParty", STAC_D965_REF), | 3249 | "DFI LanParty", STAC_D965_REF), |
@@ -2204,12 +3265,12 @@ static const struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2204 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), | 3265 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), |
2205 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), | 3266 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), |
2206 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), | 3267 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), |
2207 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), | 3268 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS_SPDIF), |
2208 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), | 3269 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), |
2209 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), | 3270 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), |
2210 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), | 3271 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), |
2211 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), | 3272 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), |
2212 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), | 3273 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS_SPDIF), |
2213 | /* 965 based 5 stack systems */ | 3274 | /* 965 based 5 stack systems */ |
2214 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, | 3275 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, |
2215 | "Intel D965", STAC_D965_5ST), | 3276 | "Intel D965", STAC_D965_5ST), |
@@ -2220,10 +3281,20 @@ static const struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2220 | {} /* terminator */ | 3281 | {} /* terminator */ |
2221 | }; | 3282 | }; |
2222 | 3283 | ||
2223 | static const unsigned int ref9205_pin_configs[12] = { | 3284 | static const struct hda_pintbl ref9205_pin_configs[] = { |
2224 | 0x40000100, 0x40000100, 0x01016011, 0x01014010, | 3285 | { 0x0a, 0x40000100 }, |
2225 | 0x01813122, 0x01a19021, 0x01019020, 0x40000100, | 3286 | { 0x0b, 0x40000100 }, |
2226 | 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 | 3287 | { 0x0c, 0x01016011 }, |
3288 | { 0x0d, 0x01014010 }, | ||
3289 | { 0x0e, 0x01813122 }, | ||
3290 | { 0x0f, 0x01a19021 }, | ||
3291 | { 0x14, 0x01019020 }, | ||
3292 | { 0x16, 0x40000100 }, | ||
3293 | { 0x17, 0x90a000f0 }, | ||
3294 | { 0x18, 0x90a000f0 }, | ||
3295 | { 0x21, 0x01441030 }, | ||
3296 | { 0x22, 0x01c41030 }, | ||
3297 | {} | ||
2227 | }; | 3298 | }; |
2228 | 3299 | ||
2229 | /* | 3300 | /* |
@@ -2237,10 +3308,20 @@ static const unsigned int ref9205_pin_configs[12] = { | |||
2237 | 10280228 (Dell Vostro 1500) | 3308 | 10280228 (Dell Vostro 1500) |
2238 | 10280229 (Dell Vostro 1700) | 3309 | 10280229 (Dell Vostro 1700) |
2239 | */ | 3310 | */ |
2240 | static const unsigned int dell_9205_m42_pin_configs[12] = { | 3311 | static const struct hda_pintbl dell_9205_m42_pin_configs[] = { |
2241 | 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, | 3312 | { 0x0a, 0x0321101F }, |
2242 | 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, | 3313 | { 0x0b, 0x03A11020 }, |
2243 | 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, | 3314 | { 0x0c, 0x400003FA }, |
3315 | { 0x0d, 0x90170310 }, | ||
3316 | { 0x0e, 0x400003FB }, | ||
3317 | { 0x0f, 0x400003FC }, | ||
3318 | { 0x14, 0x400003FD }, | ||
3319 | { 0x16, 0x40F000F9 }, | ||
3320 | { 0x17, 0x90A60330 }, | ||
3321 | { 0x18, 0x400003FF }, | ||
3322 | { 0x21, 0x0144131F }, | ||
3323 | { 0x22, 0x40C003FE }, | ||
3324 | {} | ||
2244 | }; | 3325 | }; |
2245 | 3326 | ||
2246 | /* | 3327 | /* |
@@ -2253,36 +3334,126 @@ static const unsigned int dell_9205_m42_pin_configs[12] = { | |||
2253 | 10280200 | 3334 | 10280200 |
2254 | 10280201 | 3335 | 10280201 |
2255 | */ | 3336 | */ |
2256 | static const unsigned int dell_9205_m43_pin_configs[12] = { | 3337 | static const struct hda_pintbl dell_9205_m43_pin_configs[] = { |
2257 | 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, | 3338 | { 0x0a, 0x0321101f }, |
2258 | 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, | 3339 | { 0x0b, 0x03a11020 }, |
2259 | 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, | 3340 | { 0x0c, 0x90a70330 }, |
3341 | { 0x0d, 0x90170310 }, | ||
3342 | { 0x0e, 0x400000fe }, | ||
3343 | { 0x0f, 0x400000ff }, | ||
3344 | { 0x14, 0x400000fd }, | ||
3345 | { 0x16, 0x40f000f9 }, | ||
3346 | { 0x17, 0x400000fa }, | ||
3347 | { 0x18, 0x400000fc }, | ||
3348 | { 0x21, 0x0144131f }, | ||
3349 | { 0x22, 0x40c003f8 }, | ||
3350 | /* Enable SPDIF in/out */ | ||
3351 | { 0x1f, 0x01441030 }, | ||
3352 | { 0x20, 0x1c410030 }, | ||
3353 | {} | ||
2260 | }; | 3354 | }; |
2261 | 3355 | ||
2262 | static const unsigned int dell_9205_m44_pin_configs[12] = { | 3356 | static const struct hda_pintbl dell_9205_m44_pin_configs[] = { |
2263 | 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, | 3357 | { 0x0a, 0x0421101f }, |
2264 | 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, | 3358 | { 0x0b, 0x04a11020 }, |
2265 | 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, | 3359 | { 0x0c, 0x400003fa }, |
3360 | { 0x0d, 0x90170310 }, | ||
3361 | { 0x0e, 0x400003fb }, | ||
3362 | { 0x0f, 0x400003fc }, | ||
3363 | { 0x14, 0x400003fd }, | ||
3364 | { 0x16, 0x400003f9 }, | ||
3365 | { 0x17, 0x90a60330 }, | ||
3366 | { 0x18, 0x400003ff }, | ||
3367 | { 0x21, 0x01441340 }, | ||
3368 | { 0x22, 0x40c003fe }, | ||
3369 | {} | ||
2266 | }; | 3370 | }; |
2267 | 3371 | ||
2268 | static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | 3372 | static void stac9205_fixup_ref(struct hda_codec *codec, |
2269 | [STAC_9205_REF] = ref9205_pin_configs, | 3373 | const struct hda_fixup *fix, int action) |
2270 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, | 3374 | { |
2271 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, | 3375 | struct sigmatel_spec *spec = codec->spec; |
2272 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, | 3376 | |
2273 | [STAC_9205_EAPD] = NULL, | 3377 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3378 | snd_hda_apply_pincfgs(codec, ref9205_pin_configs); | ||
3379 | /* SPDIF-In enabled */ | ||
3380 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0; | ||
3381 | } | ||
3382 | } | ||
3383 | |||
3384 | static void stac9205_fixup_dell_m43(struct hda_codec *codec, | ||
3385 | const struct hda_fixup *fix, int action) | ||
3386 | { | ||
3387 | struct sigmatel_spec *spec = codec->spec; | ||
3388 | struct hda_jack_tbl *jack; | ||
3389 | |||
3390 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3391 | snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs); | ||
3392 | |||
3393 | /* Enable unsol response for GPIO4/Dock HP connection */ | ||
3394 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
3395 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); | ||
3396 | snd_hda_jack_detect_enable_callback(codec, codec->afg, | ||
3397 | STAC_VREF_EVENT, | ||
3398 | stac_vref_event); | ||
3399 | jack = snd_hda_jack_tbl_get(codec, codec->afg); | ||
3400 | if (jack) | ||
3401 | jack->private_data = 0x01; | ||
3402 | |||
3403 | spec->gpio_dir = 0x0b; | ||
3404 | spec->eapd_mask = 0x01; | ||
3405 | spec->gpio_mask = 0x1b; | ||
3406 | spec->gpio_mute = 0x10; | ||
3407 | /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, | ||
3408 | * GPIO3 Low = DRM | ||
3409 | */ | ||
3410 | spec->gpio_data = 0x01; | ||
3411 | } | ||
3412 | } | ||
3413 | |||
3414 | static void stac9205_fixup_eapd(struct hda_codec *codec, | ||
3415 | const struct hda_fixup *fix, int action) | ||
3416 | { | ||
3417 | struct sigmatel_spec *spec = codec->spec; | ||
3418 | |||
3419 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | ||
3420 | spec->eapd_switch = 0; | ||
3421 | } | ||
3422 | |||
3423 | static const struct hda_fixup stac9205_fixups[] = { | ||
3424 | [STAC_9205_REF] = { | ||
3425 | .type = HDA_FIXUP_FUNC, | ||
3426 | .v.func = stac9205_fixup_ref, | ||
3427 | }, | ||
3428 | [STAC_9205_DELL_M42] = { | ||
3429 | .type = HDA_FIXUP_PINS, | ||
3430 | .v.pins = dell_9205_m42_pin_configs, | ||
3431 | }, | ||
3432 | [STAC_9205_DELL_M43] = { | ||
3433 | .type = HDA_FIXUP_FUNC, | ||
3434 | .v.func = stac9205_fixup_dell_m43, | ||
3435 | }, | ||
3436 | [STAC_9205_DELL_M44] = { | ||
3437 | .type = HDA_FIXUP_PINS, | ||
3438 | .v.pins = dell_9205_m44_pin_configs, | ||
3439 | }, | ||
3440 | [STAC_9205_EAPD] = { | ||
3441 | .type = HDA_FIXUP_FUNC, | ||
3442 | .v.func = stac9205_fixup_eapd, | ||
3443 | }, | ||
3444 | {} | ||
2274 | }; | 3445 | }; |
2275 | 3446 | ||
2276 | static const char * const stac9205_models[STAC_9205_MODELS] = { | 3447 | static const struct hda_model_fixup stac9205_models[] = { |
2277 | [STAC_9205_AUTO] = "auto", | 3448 | { .id = STAC_9205_REF, .name = "ref" }, |
2278 | [STAC_9205_REF] = "ref", | 3449 | { .id = STAC_9205_DELL_M42, .name = "dell-m42" }, |
2279 | [STAC_9205_DELL_M42] = "dell-m42", | 3450 | { .id = STAC_9205_DELL_M43, .name = "dell-m43" }, |
2280 | [STAC_9205_DELL_M43] = "dell-m43", | 3451 | { .id = STAC_9205_DELL_M44, .name = "dell-m44" }, |
2281 | [STAC_9205_DELL_M44] = "dell-m44", | 3452 | { .id = STAC_9205_EAPD, .name = "eapd" }, |
2282 | [STAC_9205_EAPD] = "eapd", | 3453 | {} |
2283 | }; | 3454 | }; |
2284 | 3455 | ||
2285 | static const struct snd_pci_quirk stac9205_cfg_tbl[] = { | 3456 | static const struct snd_pci_quirk stac9205_fixup_tbl[] = { |
2286 | /* SigmaTel reference board */ | 3457 | /* SigmaTel reference board */ |
2287 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 3458 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2288 | "DFI LanParty", STAC_9205_REF), | 3459 | "DFI LanParty", STAC_9205_REF), |
@@ -2329,1640 +3500,35 @@ static const struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2329 | {} /* terminator */ | 3500 | {} /* terminator */ |
2330 | }; | 3501 | }; |
2331 | 3502 | ||
2332 | static void stac92xx_set_config_regs(struct hda_codec *codec, | 3503 | static int stac_parse_auto_config(struct hda_codec *codec) |
2333 | const unsigned int *pincfgs) | ||
2334 | { | ||
2335 | int i; | ||
2336 | struct sigmatel_spec *spec = codec->spec; | ||
2337 | |||
2338 | if (!pincfgs) | ||
2339 | return; | ||
2340 | |||
2341 | for (i = 0; i < spec->num_pins; i++) | ||
2342 | if (spec->pin_nids[i] && pincfgs[i]) | ||
2343 | snd_hda_codec_set_pincfg(codec, spec->pin_nids[i], | ||
2344 | pincfgs[i]); | ||
2345 | } | ||
2346 | |||
2347 | /* | ||
2348 | * Analog playback callbacks | ||
2349 | */ | ||
2350 | static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
2351 | struct hda_codec *codec, | ||
2352 | struct snd_pcm_substream *substream) | ||
2353 | { | ||
2354 | struct sigmatel_spec *spec = codec->spec; | ||
2355 | if (spec->stream_delay) | ||
2356 | msleep(spec->stream_delay); | ||
2357 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
2358 | hinfo); | ||
2359 | } | ||
2360 | |||
2361 | static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2362 | struct hda_codec *codec, | ||
2363 | unsigned int stream_tag, | ||
2364 | unsigned int format, | ||
2365 | struct snd_pcm_substream *substream) | ||
2366 | { | ||
2367 | struct sigmatel_spec *spec = codec->spec; | ||
2368 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream); | ||
2369 | } | ||
2370 | |||
2371 | static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2372 | struct hda_codec *codec, | ||
2373 | struct snd_pcm_substream *substream) | ||
2374 | { | ||
2375 | struct sigmatel_spec *spec = codec->spec; | ||
2376 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
2377 | } | ||
2378 | |||
2379 | /* | ||
2380 | * Digital playback callbacks | ||
2381 | */ | ||
2382 | static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
2383 | struct hda_codec *codec, | ||
2384 | struct snd_pcm_substream *substream) | ||
2385 | { | ||
2386 | struct sigmatel_spec *spec = codec->spec; | ||
2387 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
2388 | } | ||
2389 | |||
2390 | static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
2391 | struct hda_codec *codec, | ||
2392 | struct snd_pcm_substream *substream) | ||
2393 | { | ||
2394 | struct sigmatel_spec *spec = codec->spec; | ||
2395 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
2396 | } | ||
2397 | |||
2398 | static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2399 | struct hda_codec *codec, | ||
2400 | unsigned int stream_tag, | ||
2401 | unsigned int format, | ||
2402 | struct snd_pcm_substream *substream) | ||
2403 | { | ||
2404 | struct sigmatel_spec *spec = codec->spec; | ||
2405 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
2406 | stream_tag, format, substream); | ||
2407 | } | ||
2408 | |||
2409 | static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2410 | struct hda_codec *codec, | ||
2411 | struct snd_pcm_substream *substream) | ||
2412 | { | ||
2413 | struct sigmatel_spec *spec = codec->spec; | ||
2414 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
2415 | } | ||
2416 | |||
2417 | |||
2418 | /* | ||
2419 | * Analog capture callbacks | ||
2420 | */ | ||
2421 | static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
2422 | struct hda_codec *codec, | ||
2423 | unsigned int stream_tag, | ||
2424 | unsigned int format, | ||
2425 | struct snd_pcm_substream *substream) | ||
2426 | { | ||
2427 | struct sigmatel_spec *spec = codec->spec; | ||
2428 | hda_nid_t nid = spec->adc_nids[substream->number]; | ||
2429 | |||
2430 | if (spec->powerdown_adcs) { | ||
2431 | msleep(40); | ||
2432 | snd_hda_codec_write(codec, nid, 0, | ||
2433 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
2434 | } | ||
2435 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | ||
2436 | return 0; | ||
2437 | } | ||
2438 | |||
2439 | static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2440 | struct hda_codec *codec, | ||
2441 | struct snd_pcm_substream *substream) | ||
2442 | { | ||
2443 | struct sigmatel_spec *spec = codec->spec; | ||
2444 | hda_nid_t nid = spec->adc_nids[substream->number]; | ||
2445 | |||
2446 | snd_hda_codec_cleanup_stream(codec, nid); | ||
2447 | if (spec->powerdown_adcs) | ||
2448 | snd_hda_codec_write(codec, nid, 0, | ||
2449 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
2450 | return 0; | ||
2451 | } | ||
2452 | |||
2453 | static const struct hda_pcm_stream stac92xx_pcm_digital_playback = { | ||
2454 | .substreams = 1, | ||
2455 | .channels_min = 2, | ||
2456 | .channels_max = 2, | ||
2457 | /* NID is set in stac92xx_build_pcms */ | ||
2458 | .ops = { | ||
2459 | .open = stac92xx_dig_playback_pcm_open, | ||
2460 | .close = stac92xx_dig_playback_pcm_close, | ||
2461 | .prepare = stac92xx_dig_playback_pcm_prepare, | ||
2462 | .cleanup = stac92xx_dig_playback_pcm_cleanup | ||
2463 | }, | ||
2464 | }; | ||
2465 | |||
2466 | static const struct hda_pcm_stream stac92xx_pcm_digital_capture = { | ||
2467 | .substreams = 1, | ||
2468 | .channels_min = 2, | ||
2469 | .channels_max = 2, | ||
2470 | /* NID is set in stac92xx_build_pcms */ | ||
2471 | }; | ||
2472 | |||
2473 | static const struct hda_pcm_stream stac92xx_pcm_analog_playback = { | ||
2474 | .substreams = 1, | ||
2475 | .channels_min = 2, | ||
2476 | .channels_max = 8, | ||
2477 | .nid = 0x02, /* NID to query formats and rates */ | ||
2478 | .ops = { | ||
2479 | .open = stac92xx_playback_pcm_open, | ||
2480 | .prepare = stac92xx_playback_pcm_prepare, | ||
2481 | .cleanup = stac92xx_playback_pcm_cleanup | ||
2482 | }, | ||
2483 | }; | ||
2484 | |||
2485 | static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { | ||
2486 | .substreams = 1, | ||
2487 | .channels_min = 2, | ||
2488 | .channels_max = 2, | ||
2489 | .nid = 0x06, /* NID to query formats and rates */ | ||
2490 | .ops = { | ||
2491 | .open = stac92xx_playback_pcm_open, | ||
2492 | .prepare = stac92xx_playback_pcm_prepare, | ||
2493 | .cleanup = stac92xx_playback_pcm_cleanup | ||
2494 | }, | ||
2495 | }; | ||
2496 | |||
2497 | static const struct hda_pcm_stream stac92xx_pcm_analog_capture = { | ||
2498 | .channels_min = 2, | ||
2499 | .channels_max = 2, | ||
2500 | /* NID + .substreams is set in stac92xx_build_pcms */ | ||
2501 | .ops = { | ||
2502 | .prepare = stac92xx_capture_pcm_prepare, | ||
2503 | .cleanup = stac92xx_capture_pcm_cleanup | ||
2504 | }, | ||
2505 | }; | ||
2506 | |||
2507 | static int stac92xx_build_pcms(struct hda_codec *codec) | ||
2508 | { | ||
2509 | struct sigmatel_spec *spec = codec->spec; | ||
2510 | struct hda_pcm *info = spec->pcm_rec; | ||
2511 | |||
2512 | codec->num_pcms = 1; | ||
2513 | codec->pcm_info = info; | ||
2514 | |||
2515 | info->name = "STAC92xx Analog"; | ||
2516 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; | ||
2517 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
2518 | spec->multiout.dac_nids[0]; | ||
2519 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
2520 | spec->autocfg.line_outs == 2) | ||
2521 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
2522 | snd_pcm_2_1_chmaps; | ||
2523 | |||
2524 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; | ||
2525 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
2526 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; | ||
2527 | |||
2528 | if (spec->alt_switch) { | ||
2529 | codec->num_pcms++; | ||
2530 | info++; | ||
2531 | info->name = "STAC92xx Analog Alt"; | ||
2532 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback; | ||
2533 | } | ||
2534 | |||
2535 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | ||
2536 | codec->num_pcms++; | ||
2537 | info++; | ||
2538 | info->name = "STAC92xx Digital"; | ||
2539 | info->pcm_type = spec->autocfg.dig_out_type[0]; | ||
2540 | if (spec->multiout.dig_out_nid) { | ||
2541 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; | ||
2542 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | ||
2543 | } | ||
2544 | if (spec->dig_in_nid) { | ||
2545 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture; | ||
2546 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
2547 | } | ||
2548 | } | ||
2549 | |||
2550 | return 0; | ||
2551 | } | ||
2552 | |||
2553 | static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) | ||
2554 | |||
2555 | { | ||
2556 | snd_hda_set_pin_ctl_cache(codec, nid, pin_type); | ||
2557 | } | ||
2558 | |||
2559 | #define stac92xx_hp_switch_info snd_ctl_boolean_mono_info | ||
2560 | |||
2561 | static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, | ||
2562 | struct snd_ctl_elem_value *ucontrol) | ||
2563 | { | ||
2564 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2565 | struct sigmatel_spec *spec = codec->spec; | ||
2566 | |||
2567 | ucontrol->value.integer.value[0] = !!spec->hp_switch; | ||
2568 | return 0; | ||
2569 | } | ||
2570 | |||
2571 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid); | ||
2572 | |||
2573 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | ||
2574 | struct snd_ctl_elem_value *ucontrol) | ||
2575 | { | ||
2576 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2577 | struct sigmatel_spec *spec = codec->spec; | ||
2578 | int nid = kcontrol->private_value; | ||
2579 | |||
2580 | spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; | ||
2581 | |||
2582 | /* check to be sure that the ports are up to date with | ||
2583 | * switch changes | ||
2584 | */ | ||
2585 | stac_issue_unsol_event(codec, nid); | ||
2586 | |||
2587 | return 1; | ||
2588 | } | ||
2589 | |||
2590 | static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol, | ||
2591 | struct snd_ctl_elem_info *uinfo) | ||
2592 | { | ||
2593 | int i; | ||
2594 | static const char * const texts[] = { | ||
2595 | "Mic In", "Line In", "Line Out" | ||
2596 | }; | ||
2597 | |||
2598 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2599 | struct sigmatel_spec *spec = codec->spec; | ||
2600 | hda_nid_t nid = kcontrol->private_value; | ||
2601 | |||
2602 | if (nid == spec->mic_switch || nid == spec->line_switch) | ||
2603 | i = 3; | ||
2604 | else | ||
2605 | i = 2; | ||
2606 | |||
2607 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2608 | uinfo->value.enumerated.items = i; | ||
2609 | uinfo->count = 1; | ||
2610 | if (uinfo->value.enumerated.item >= i) | ||
2611 | uinfo->value.enumerated.item = i-1; | ||
2612 | strcpy(uinfo->value.enumerated.name, | ||
2613 | texts[uinfo->value.enumerated.item]); | ||
2614 | |||
2615 | return 0; | ||
2616 | } | ||
2617 | |||
2618 | static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol, | ||
2619 | struct snd_ctl_elem_value *ucontrol) | ||
2620 | { | ||
2621 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2622 | hda_nid_t nid = kcontrol->private_value; | ||
2623 | unsigned int vref = stac92xx_vref_get(codec, nid); | ||
2624 | |||
2625 | if (vref == snd_hda_get_default_vref(codec, nid)) | ||
2626 | ucontrol->value.enumerated.item[0] = 0; | ||
2627 | else if (vref == AC_PINCTL_VREF_GRD) | ||
2628 | ucontrol->value.enumerated.item[0] = 1; | ||
2629 | else if (vref == AC_PINCTL_VREF_HIZ) | ||
2630 | ucontrol->value.enumerated.item[0] = 2; | ||
2631 | |||
2632 | return 0; | ||
2633 | } | ||
2634 | |||
2635 | static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, | ||
2636 | struct snd_ctl_elem_value *ucontrol) | ||
2637 | { | ||
2638 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2639 | unsigned int new_vref = 0; | ||
2640 | int error; | ||
2641 | hda_nid_t nid = kcontrol->private_value; | ||
2642 | |||
2643 | if (ucontrol->value.enumerated.item[0] == 0) | ||
2644 | new_vref = snd_hda_get_default_vref(codec, nid); | ||
2645 | else if (ucontrol->value.enumerated.item[0] == 1) | ||
2646 | new_vref = AC_PINCTL_VREF_GRD; | ||
2647 | else if (ucontrol->value.enumerated.item[0] == 2) | ||
2648 | new_vref = AC_PINCTL_VREF_HIZ; | ||
2649 | else | ||
2650 | return 0; | ||
2651 | |||
2652 | if (new_vref != stac92xx_vref_get(codec, nid)) { | ||
2653 | error = stac92xx_vref_set(codec, nid, new_vref); | ||
2654 | return error; | ||
2655 | } | ||
2656 | |||
2657 | return 0; | ||
2658 | } | ||
2659 | |||
2660 | static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, | ||
2661 | struct snd_ctl_elem_info *uinfo) | ||
2662 | { | ||
2663 | char *texts[2]; | ||
2664 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2665 | struct sigmatel_spec *spec = codec->spec; | ||
2666 | |||
2667 | if (kcontrol->private_value == spec->line_switch) | ||
2668 | texts[0] = "Line In"; | ||
2669 | else | ||
2670 | texts[0] = "Mic In"; | ||
2671 | texts[1] = "Line Out"; | ||
2672 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2673 | uinfo->value.enumerated.items = 2; | ||
2674 | uinfo->count = 1; | ||
2675 | |||
2676 | if (uinfo->value.enumerated.item >= 2) | ||
2677 | uinfo->value.enumerated.item = 1; | ||
2678 | strcpy(uinfo->value.enumerated.name, | ||
2679 | texts[uinfo->value.enumerated.item]); | ||
2680 | |||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2685 | { | ||
2686 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2687 | struct sigmatel_spec *spec = codec->spec; | ||
2688 | hda_nid_t nid = kcontrol->private_value; | ||
2689 | int io_idx = (nid == spec->mic_switch) ? 1 : 0; | ||
2690 | |||
2691 | ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx]; | ||
2692 | return 0; | ||
2693 | } | ||
2694 | |||
2695 | static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2696 | { | ||
2697 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2698 | struct sigmatel_spec *spec = codec->spec; | ||
2699 | hda_nid_t nid = kcontrol->private_value; | ||
2700 | int io_idx = (nid == spec->mic_switch) ? 1 : 0; | ||
2701 | unsigned short val = !!ucontrol->value.enumerated.item[0]; | ||
2702 | |||
2703 | spec->io_switch[io_idx] = val; | ||
2704 | |||
2705 | if (val) | ||
2706 | stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
2707 | else { | ||
2708 | unsigned int pinctl = AC_PINCTL_IN_EN; | ||
2709 | if (io_idx) /* set VREF for mic */ | ||
2710 | pinctl |= snd_hda_get_default_vref(codec, nid); | ||
2711 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | ||
2712 | } | ||
2713 | |||
2714 | /* check the auto-mute again: we need to mute/unmute the speaker | ||
2715 | * appropriately according to the pin direction | ||
2716 | */ | ||
2717 | if (spec->hp_detect) | ||
2718 | stac_issue_unsol_event(codec, nid); | ||
2719 | |||
2720 | return 1; | ||
2721 | } | ||
2722 | |||
2723 | #define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info | ||
2724 | |||
2725 | static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol, | ||
2726 | struct snd_ctl_elem_value *ucontrol) | ||
2727 | { | ||
2728 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2729 | struct sigmatel_spec *spec = codec->spec; | ||
2730 | |||
2731 | ucontrol->value.integer.value[0] = spec->clfe_swap; | ||
2732 | return 0; | ||
2733 | } | ||
2734 | |||
2735 | static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, | ||
2736 | struct snd_ctl_elem_value *ucontrol) | ||
2737 | { | ||
2738 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2739 | struct sigmatel_spec *spec = codec->spec; | ||
2740 | hda_nid_t nid = kcontrol->private_value & 0xff; | ||
2741 | unsigned int val = !!ucontrol->value.integer.value[0]; | ||
2742 | |||
2743 | if (spec->clfe_swap == val) | ||
2744 | return 0; | ||
2745 | |||
2746 | spec->clfe_swap = val; | ||
2747 | |||
2748 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
2749 | spec->clfe_swap ? 0x4 : 0x0); | ||
2750 | |||
2751 | return 1; | ||
2752 | } | ||
2753 | |||
2754 | #define STAC_CODEC_HP_SWITCH(xname) \ | ||
2755 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2756 | .name = xname, \ | ||
2757 | .index = 0, \ | ||
2758 | .info = stac92xx_hp_switch_info, \ | ||
2759 | .get = stac92xx_hp_switch_get, \ | ||
2760 | .put = stac92xx_hp_switch_put, \ | ||
2761 | } | ||
2762 | |||
2763 | #define STAC_CODEC_IO_SWITCH(xname, xpval) \ | ||
2764 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2765 | .name = xname, \ | ||
2766 | .index = 0, \ | ||
2767 | .info = stac92xx_io_switch_info, \ | ||
2768 | .get = stac92xx_io_switch_get, \ | ||
2769 | .put = stac92xx_io_switch_put, \ | ||
2770 | .private_value = xpval, \ | ||
2771 | } | ||
2772 | |||
2773 | #define STAC_CODEC_CLFE_SWITCH(xname, xpval) \ | ||
2774 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2775 | .name = xname, \ | ||
2776 | .index = 0, \ | ||
2777 | .info = stac92xx_clfe_switch_info, \ | ||
2778 | .get = stac92xx_clfe_switch_get, \ | ||
2779 | .put = stac92xx_clfe_switch_put, \ | ||
2780 | .private_value = xpval, \ | ||
2781 | } | ||
2782 | |||
2783 | enum { | ||
2784 | STAC_CTL_WIDGET_VOL, | ||
2785 | STAC_CTL_WIDGET_MUTE, | ||
2786 | STAC_CTL_WIDGET_MUTE_BEEP, | ||
2787 | STAC_CTL_WIDGET_MONO_MUX, | ||
2788 | STAC_CTL_WIDGET_HP_SWITCH, | ||
2789 | STAC_CTL_WIDGET_IO_SWITCH, | ||
2790 | STAC_CTL_WIDGET_CLFE_SWITCH, | ||
2791 | STAC_CTL_WIDGET_DC_BIAS | ||
2792 | }; | ||
2793 | |||
2794 | static const struct snd_kcontrol_new stac92xx_control_templates[] = { | ||
2795 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
2796 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
2797 | HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), | ||
2798 | STAC_MONO_MUX, | ||
2799 | STAC_CODEC_HP_SWITCH(NULL), | ||
2800 | STAC_CODEC_IO_SWITCH(NULL, 0), | ||
2801 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | ||
2802 | DC_BIAS(NULL, 0, 0), | ||
2803 | }; | ||
2804 | |||
2805 | /* add dynamic controls */ | ||
2806 | static struct snd_kcontrol_new * | ||
2807 | stac_control_new(struct sigmatel_spec *spec, | ||
2808 | const struct snd_kcontrol_new *ktemp, | ||
2809 | const char *name, | ||
2810 | unsigned int subdev) | ||
2811 | { | ||
2812 | struct snd_kcontrol_new *knew; | ||
2813 | |||
2814 | knew = snd_array_new(&spec->kctls); | ||
2815 | if (!knew) | ||
2816 | return NULL; | ||
2817 | *knew = *ktemp; | ||
2818 | knew->name = kstrdup(name, GFP_KERNEL); | ||
2819 | if (!knew->name) { | ||
2820 | /* roolback */ | ||
2821 | memset(knew, 0, sizeof(*knew)); | ||
2822 | spec->kctls.alloced--; | ||
2823 | return NULL; | ||
2824 | } | ||
2825 | knew->subdevice = subdev; | ||
2826 | return knew; | ||
2827 | } | ||
2828 | |||
2829 | static struct snd_kcontrol_new * | ||
2830 | add_control_temp(struct sigmatel_spec *spec, | ||
2831 | const struct snd_kcontrol_new *ktemp, | ||
2832 | int idx, const char *name, | ||
2833 | unsigned long val) | ||
2834 | { | ||
2835 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, | ||
2836 | HDA_SUBDEV_AMP_FLAG); | ||
2837 | if (!knew) | ||
2838 | return NULL; | ||
2839 | knew->index = idx; | ||
2840 | knew->private_value = val; | ||
2841 | return knew; | ||
2842 | } | ||
2843 | |||
2844 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | ||
2845 | const struct snd_kcontrol_new *ktemp, | ||
2846 | int idx, const char *name, | ||
2847 | unsigned long val) | ||
2848 | { | ||
2849 | return add_control_temp(spec, ktemp, idx, name, val) ? 0 : -ENOMEM; | ||
2850 | } | ||
2851 | |||
2852 | static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec, | ||
2853 | int type, int idx, const char *name, | ||
2854 | unsigned long val) | ||
2855 | { | ||
2856 | return stac92xx_add_control_temp(spec, | ||
2857 | &stac92xx_control_templates[type], | ||
2858 | idx, name, val); | ||
2859 | } | ||
2860 | |||
2861 | |||
2862 | /* add dynamic controls */ | ||
2863 | static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | ||
2864 | const char *name, unsigned long val) | ||
2865 | { | ||
2866 | return stac92xx_add_control_idx(spec, type, 0, name, val); | ||
2867 | } | ||
2868 | |||
2869 | static const struct snd_kcontrol_new stac_input_src_temp = { | ||
2870 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2871 | .name = "Input Source", | ||
2872 | .info = stac92xx_mux_enum_info, | ||
2873 | .get = stac92xx_mux_enum_get, | ||
2874 | .put = stac92xx_mux_enum_put, | ||
2875 | }; | ||
2876 | |||
2877 | static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, | ||
2878 | hda_nid_t nid, int idx) | ||
2879 | { | ||
2880 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
2881 | int control = 0; | ||
2882 | struct sigmatel_spec *spec = codec->spec; | ||
2883 | char name[22]; | ||
2884 | |||
2885 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { | ||
2886 | if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf) | ||
2887 | != INPUT_PIN_ATTR_DOCK) | ||
2888 | return 0; | ||
2889 | if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD | ||
2890 | && nid == spec->line_switch) | ||
2891 | control = STAC_CTL_WIDGET_IO_SWITCH; | ||
2892 | else if (snd_hda_query_pin_caps(codec, nid) | ||
2893 | & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT)) | ||
2894 | control = STAC_CTL_WIDGET_DC_BIAS; | ||
2895 | else if (nid == spec->mic_switch) | ||
2896 | control = STAC_CTL_WIDGET_IO_SWITCH; | ||
2897 | } | ||
2898 | |||
2899 | if (control) { | ||
2900 | snd_hda_get_pin_label(codec, nid, &spec->autocfg, | ||
2901 | name, sizeof(name), NULL); | ||
2902 | return stac92xx_add_control(codec->spec, control, | ||
2903 | strcat(name, " Jack Mode"), nid); | ||
2904 | } | ||
2905 | |||
2906 | return 0; | ||
2907 | } | ||
2908 | |||
2909 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) | ||
2910 | { | ||
2911 | struct snd_kcontrol_new *knew; | ||
2912 | struct hda_input_mux *imux = &spec->private_imux; | ||
2913 | |||
2914 | if (spec->auto_mic) | ||
2915 | return 0; /* no need for input source */ | ||
2916 | if (!spec->num_adcs || imux->num_items <= 1) | ||
2917 | return 0; /* no need for input source control */ | ||
2918 | knew = stac_control_new(spec, &stac_input_src_temp, | ||
2919 | stac_input_src_temp.name, 0); | ||
2920 | if (!knew) | ||
2921 | return -ENOMEM; | ||
2922 | knew->count = spec->num_adcs; | ||
2923 | return 0; | ||
2924 | } | ||
2925 | |||
2926 | /* check whether the line-input can be used as line-out */ | ||
2927 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) | ||
2928 | { | 3504 | { |
2929 | struct sigmatel_spec *spec = codec->spec; | 3505 | struct sigmatel_spec *spec = codec->spec; |
2930 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2931 | hda_nid_t nid; | ||
2932 | unsigned int pincap; | ||
2933 | int i; | ||
2934 | |||
2935 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) | ||
2936 | return 0; | ||
2937 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2938 | if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) { | ||
2939 | nid = cfg->inputs[i].pin; | ||
2940 | pincap = snd_hda_query_pin_caps(codec, nid); | ||
2941 | if (pincap & AC_PINCAP_OUT) | ||
2942 | return nid; | ||
2943 | } | ||
2944 | } | ||
2945 | return 0; | ||
2946 | } | ||
2947 | |||
2948 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid); | ||
2949 | |||
2950 | /* check whether the mic-input can be used as line-out */ | ||
2951 | static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac) | ||
2952 | { | ||
2953 | struct sigmatel_spec *spec = codec->spec; | ||
2954 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2955 | unsigned int def_conf, pincap; | ||
2956 | int i; | ||
2957 | |||
2958 | *dac = 0; | ||
2959 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) | ||
2960 | return 0; | ||
2961 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2962 | hda_nid_t nid = cfg->inputs[i].pin; | ||
2963 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
2964 | continue; | ||
2965 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
2966 | /* some laptops have an internal analog microphone | ||
2967 | * which can't be used as a output */ | ||
2968 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { | ||
2969 | pincap = snd_hda_query_pin_caps(codec, nid); | ||
2970 | if (pincap & AC_PINCAP_OUT) { | ||
2971 | *dac = get_unassigned_dac(codec, nid); | ||
2972 | if (*dac) | ||
2973 | return nid; | ||
2974 | } | ||
2975 | } | ||
2976 | } | ||
2977 | return 0; | ||
2978 | } | ||
2979 | |||
2980 | static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2981 | { | ||
2982 | int i; | ||
2983 | |||
2984 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
2985 | if (spec->multiout.dac_nids[i] == nid) | ||
2986 | return 1; | ||
2987 | } | ||
2988 | |||
2989 | return 0; | ||
2990 | } | ||
2991 | |||
2992 | static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2993 | { | ||
2994 | int i; | ||
2995 | if (is_in_dac_nids(spec, nid)) | ||
2996 | return 1; | ||
2997 | for (i = 0; i < spec->autocfg.hp_outs; i++) | ||
2998 | if (spec->hp_dacs[i] == nid) | ||
2999 | return 1; | ||
3000 | for (i = 0; i < spec->autocfg.speaker_outs; i++) | ||
3001 | if (spec->speaker_dacs[i] == nid) | ||
3002 | return 1; | ||
3003 | return 0; | ||
3004 | } | ||
3005 | |||
3006 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | ||
3007 | { | ||
3008 | struct sigmatel_spec *spec = codec->spec; | ||
3009 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3010 | int j, conn_len; | ||
3011 | hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac; | ||
3012 | unsigned int wcaps, wtype; | ||
3013 | |||
3014 | conn_len = snd_hda_get_connections(codec, nid, conn, | ||
3015 | HDA_MAX_CONNECTIONS); | ||
3016 | /* 92HD88: trace back up the link of nids to find the DAC */ | ||
3017 | while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0])) | ||
3018 | != AC_WID_AUD_OUT)) { | ||
3019 | nid = conn[0]; | ||
3020 | conn_len = snd_hda_get_connections(codec, nid, conn, | ||
3021 | HDA_MAX_CONNECTIONS); | ||
3022 | } | ||
3023 | for (j = 0; j < conn_len; j++) { | ||
3024 | wcaps = get_wcaps(codec, conn[j]); | ||
3025 | wtype = get_wcaps_type(wcaps); | ||
3026 | /* we check only analog outputs */ | ||
3027 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | ||
3028 | continue; | ||
3029 | /* if this route has a free DAC, assign it */ | ||
3030 | if (!check_all_dac_nids(spec, conn[j])) { | ||
3031 | if (conn_len > 1) { | ||
3032 | /* select this DAC in the pin's input mux */ | ||
3033 | snd_hda_codec_write_cache(codec, nid, 0, | ||
3034 | AC_VERB_SET_CONNECT_SEL, j); | ||
3035 | } | ||
3036 | return conn[j]; | ||
3037 | } | ||
3038 | } | ||
3039 | |||
3040 | /* if all DACs are already assigned, connect to the primary DAC, | ||
3041 | unless we're assigning a secondary headphone */ | ||
3042 | fallback_dac = spec->multiout.dac_nids[0]; | ||
3043 | if (spec->multiout.hp_nid) { | ||
3044 | for (j = 0; j < cfg->hp_outs; j++) | ||
3045 | if (cfg->hp_pins[j] == nid) { | ||
3046 | fallback_dac = spec->multiout.hp_nid; | ||
3047 | break; | ||
3048 | } | ||
3049 | } | ||
3050 | |||
3051 | if (conn_len > 1) { | ||
3052 | for (j = 0; j < conn_len; j++) { | ||
3053 | if (conn[j] == fallback_dac) { | ||
3054 | snd_hda_codec_write_cache(codec, nid, 0, | ||
3055 | AC_VERB_SET_CONNECT_SEL, j); | ||
3056 | break; | ||
3057 | } | ||
3058 | } | ||
3059 | } | ||
3060 | return 0; | ||
3061 | } | ||
3062 | |||
3063 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid); | ||
3064 | static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid); | ||
3065 | |||
3066 | /* | ||
3067 | * Fill in the dac_nids table from the parsed pin configuration | ||
3068 | * This function only works when every pin in line_out_pins[] | ||
3069 | * contains atleast one DAC in its connection list. Some 92xx | ||
3070 | * codecs are not connected directly to a DAC, such as the 9200 | ||
3071 | * and 9202/925x. For those, dac_nids[] must be hard-coded. | ||
3072 | */ | ||
3073 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | ||
3074 | { | ||
3075 | struct sigmatel_spec *spec = codec->spec; | ||
3076 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3077 | int i; | ||
3078 | hda_nid_t nid, dac; | ||
3079 | |||
3080 | for (i = 0; i < cfg->line_outs; i++) { | ||
3081 | nid = cfg->line_out_pins[i]; | ||
3082 | dac = get_unassigned_dac(codec, nid); | ||
3083 | if (!dac) { | ||
3084 | if (spec->multiout.num_dacs > 0) { | ||
3085 | /* we have already working output pins, | ||
3086 | * so let's drop the broken ones again | ||
3087 | */ | ||
3088 | cfg->line_outs = spec->multiout.num_dacs; | ||
3089 | break; | ||
3090 | } | ||
3091 | /* error out, no available DAC found */ | ||
3092 | snd_printk(KERN_ERR | ||
3093 | "%s: No available DAC for pin 0x%x\n", | ||
3094 | __func__, nid); | ||
3095 | return -ENODEV; | ||
3096 | } | ||
3097 | add_spec_dacs(spec, dac); | ||
3098 | } | ||
3099 | |||
3100 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3101 | nid = cfg->hp_pins[i]; | ||
3102 | dac = get_unassigned_dac(codec, nid); | ||
3103 | if (dac) { | ||
3104 | if (!spec->multiout.hp_nid) | ||
3105 | spec->multiout.hp_nid = dac; | ||
3106 | else | ||
3107 | add_spec_extra_dacs(spec, dac); | ||
3108 | } | ||
3109 | spec->hp_dacs[i] = dac; | ||
3110 | } | ||
3111 | |||
3112 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
3113 | nid = cfg->speaker_pins[i]; | ||
3114 | dac = get_unassigned_dac(codec, nid); | ||
3115 | if (dac) | ||
3116 | add_spec_extra_dacs(spec, dac); | ||
3117 | spec->speaker_dacs[i] = dac; | ||
3118 | } | ||
3119 | |||
3120 | /* add line-in as output */ | ||
3121 | nid = check_line_out_switch(codec); | ||
3122 | if (nid) { | ||
3123 | dac = get_unassigned_dac(codec, nid); | ||
3124 | if (dac) { | ||
3125 | snd_printdd("STAC: Add line-in 0x%x as output %d\n", | ||
3126 | nid, cfg->line_outs); | ||
3127 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
3128 | cfg->line_outs++; | ||
3129 | spec->line_switch = nid; | ||
3130 | add_spec_dacs(spec, dac); | ||
3131 | } | ||
3132 | } | ||
3133 | /* add mic as output */ | ||
3134 | nid = check_mic_out_switch(codec, &dac); | ||
3135 | if (nid && dac) { | ||
3136 | snd_printdd("STAC: Add mic-in 0x%x as output %d\n", | ||
3137 | nid, cfg->line_outs); | ||
3138 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
3139 | cfg->line_outs++; | ||
3140 | spec->mic_switch = nid; | ||
3141 | add_spec_dacs(spec, dac); | ||
3142 | } | ||
3143 | |||
3144 | snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
3145 | spec->multiout.num_dacs, | ||
3146 | spec->multiout.dac_nids[0], | ||
3147 | spec->multiout.dac_nids[1], | ||
3148 | spec->multiout.dac_nids[2], | ||
3149 | spec->multiout.dac_nids[3], | ||
3150 | spec->multiout.dac_nids[4]); | ||
3151 | |||
3152 | return 0; | ||
3153 | } | ||
3154 | |||
3155 | /* create volume control/switch for the given prefx type */ | ||
3156 | static int create_controls_idx(struct hda_codec *codec, const char *pfx, | ||
3157 | int idx, hda_nid_t nid, int chs) | ||
3158 | { | ||
3159 | struct sigmatel_spec *spec = codec->spec; | ||
3160 | char name[32]; | ||
3161 | int err; | 3506 | int err; |
3162 | 3507 | ||
3163 | if (!spec->check_volume_offset) { | 3508 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); |
3164 | unsigned int caps, step, nums, db_scale; | ||
3165 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3166 | step = (caps & AC_AMPCAP_STEP_SIZE) >> | ||
3167 | AC_AMPCAP_STEP_SIZE_SHIFT; | ||
3168 | step = (step + 1) * 25; /* in .01dB unit */ | ||
3169 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> | ||
3170 | AC_AMPCAP_NUM_STEPS_SHIFT; | ||
3171 | db_scale = nums * step; | ||
3172 | /* if dB scale is over -64dB, and finer enough, | ||
3173 | * let's reduce it to half | ||
3174 | */ | ||
3175 | if (db_scale > 6400 && nums >= 0x1f) | ||
3176 | spec->volume_offset = nums / 2; | ||
3177 | spec->check_volume_offset = 1; | ||
3178 | } | ||
3179 | |||
3180 | sprintf(name, "%s Playback Volume", pfx); | ||
3181 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name, | ||
3182 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT, | ||
3183 | spec->volume_offset)); | ||
3184 | if (err < 0) | ||
3185 | return err; | ||
3186 | sprintf(name, "%s Playback Switch", pfx); | ||
3187 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name, | ||
3188 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
3189 | if (err < 0) | 3509 | if (err < 0) |
3190 | return err; | 3510 | return err; |
3191 | return 0; | ||
3192 | } | ||
3193 | |||
3194 | #define create_controls(codec, pfx, nid, chs) \ | ||
3195 | create_controls_idx(codec, pfx, 0, nid, chs) | ||
3196 | |||
3197 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | ||
3198 | { | ||
3199 | if (spec->multiout.num_dacs > 4) { | ||
3200 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | ||
3201 | return 1; | ||
3202 | } else { | ||
3203 | snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids); | ||
3204 | spec->dac_nids[spec->multiout.num_dacs] = nid; | ||
3205 | spec->multiout.num_dacs++; | ||
3206 | } | ||
3207 | return 0; | ||
3208 | } | ||
3209 | 3511 | ||
3210 | static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | 3512 | /* add hooks */ |
3211 | { | 3513 | spec->gen.pcm_playback_hook = stac_playback_pcm_hook; |
3212 | int i; | 3514 | spec->gen.pcm_capture_hook = stac_capture_pcm_hook; |
3213 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) { | ||
3214 | if (!spec->multiout.extra_out_nid[i]) { | ||
3215 | spec->multiout.extra_out_nid[i] = nid; | ||
3216 | return 0; | ||
3217 | } | ||
3218 | } | ||
3219 | printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid); | ||
3220 | return 1; | ||
3221 | } | ||
3222 | 3515 | ||
3223 | /* Create output controls | 3516 | spec->gen.automute_hook = stac_update_outputs; |
3224 | * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT) | 3517 | spec->gen.hp_automute_hook = stac_hp_automute; |
3225 | */ | 3518 | spec->gen.line_automute_hook = stac_line_automute; |
3226 | static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | 3519 | spec->gen.mic_autoswitch_hook = stac_mic_autoswitch; |
3227 | const hda_nid_t *pins, | ||
3228 | const hda_nid_t *dac_nids, | ||
3229 | int type) | ||
3230 | { | ||
3231 | struct sigmatel_spec *spec = codec->spec; | ||
3232 | static const char * const chname[4] = { | ||
3233 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
3234 | }; | ||
3235 | hda_nid_t nid; | ||
3236 | int i, err; | ||
3237 | unsigned int wid_caps; | ||
3238 | |||
3239 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { | ||
3240 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3241 | if (is_jack_detectable(codec, pins[i])) | ||
3242 | spec->hp_detect = 1; | ||
3243 | } | ||
3244 | nid = dac_nids[i]; | ||
3245 | if (!nid) | ||
3246 | continue; | ||
3247 | if (type != AUTO_PIN_HP_OUT && i == 2) { | ||
3248 | /* Center/LFE */ | ||
3249 | err = create_controls(codec, "Center", nid, 1); | ||
3250 | if (err < 0) | ||
3251 | return err; | ||
3252 | err = create_controls(codec, "LFE", nid, 2); | ||
3253 | if (err < 0) | ||
3254 | return err; | ||
3255 | |||
3256 | wid_caps = get_wcaps(codec, nid); | ||
3257 | |||
3258 | if (wid_caps & AC_WCAP_LR_SWAP) { | ||
3259 | err = stac92xx_add_control(spec, | ||
3260 | STAC_CTL_WIDGET_CLFE_SWITCH, | ||
3261 | "Swap Center/LFE Playback Switch", nid); | ||
3262 | 3520 | ||
3263 | if (err < 0) | 3521 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
3264 | return err; | ||
3265 | } | ||
3266 | |||
3267 | } else { | ||
3268 | const char *name; | ||
3269 | int idx; | ||
3270 | switch (type) { | ||
3271 | case AUTO_PIN_HP_OUT: | ||
3272 | name = "Headphone"; | ||
3273 | idx = i; | ||
3274 | break; | ||
3275 | case AUTO_PIN_SPEAKER_OUT: | ||
3276 | if (num_outs <= 2) { | ||
3277 | name = i ? "Bass Speaker" : "Speaker"; | ||
3278 | idx = 0; | ||
3279 | break; | ||
3280 | } | ||
3281 | /* Fall through in case of multi speaker outs */ | ||
3282 | default: | ||
3283 | name = chname[i]; | ||
3284 | idx = 0; | ||
3285 | break; | ||
3286 | } | ||
3287 | err = create_controls_idx(codec, name, idx, nid, 3); | ||
3288 | if (err < 0) | ||
3289 | return err; | ||
3290 | } | ||
3291 | } | ||
3292 | return 0; | ||
3293 | } | ||
3294 | |||
3295 | static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | ||
3296 | unsigned int dir_mask, unsigned int data); | ||
3297 | |||
3298 | /* hook for controlling mic-mute LED GPIO */ | ||
3299 | static int stac92xx_capture_sw_put_led(struct snd_kcontrol *kcontrol, | ||
3300 | struct snd_ctl_elem_value *ucontrol) | ||
3301 | { | ||
3302 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3303 | struct sigmatel_spec *spec = codec->spec; | ||
3304 | int err; | ||
3305 | bool mute; | ||
3306 | |||
3307 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
3308 | if (err <= 0) | ||
3309 | return err; | ||
3310 | mute = !(ucontrol->value.integer.value[0] && | ||
3311 | ucontrol->value.integer.value[1]); | ||
3312 | if (spec->mic_mute_led_on != mute) { | ||
3313 | spec->mic_mute_led_on = mute; | ||
3314 | if (mute) | ||
3315 | spec->gpio_data |= spec->mic_mute_led_gpio; | ||
3316 | else | ||
3317 | spec->gpio_data &= ~spec->mic_mute_led_gpio; | ||
3318 | stac_gpio_set(codec, spec->gpio_mask, | ||
3319 | spec->gpio_dir, spec->gpio_data); | ||
3320 | } | ||
3321 | return err; | ||
3322 | } | ||
3323 | |||
3324 | static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol, | ||
3325 | unsigned long sw, int idx) | ||
3326 | { | ||
3327 | struct sigmatel_spec *spec = codec->spec; | ||
3328 | struct snd_kcontrol_new *knew; | ||
3329 | int err; | ||
3330 | |||
3331 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, | ||
3332 | "Capture Volume", vol); | ||
3333 | if (err < 0) | 3522 | if (err < 0) |
3334 | return err; | 3523 | return err; |
3335 | 3524 | ||
3336 | knew = add_control_temp(spec, | 3525 | /* minimum value is actually mute */ |
3337 | &stac92xx_control_templates[STAC_CTL_WIDGET_MUTE], | 3526 | spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; |
3338 | idx, "Capture Switch", sw); | ||
3339 | if (!knew) | ||
3340 | return -ENOMEM; | ||
3341 | /* add a LED hook for some HP laptops */ | ||
3342 | if (spec->mic_mute_led_gpio) | ||
3343 | knew->put = stac92xx_capture_sw_put_led; | ||
3344 | |||
3345 | return 0; | ||
3346 | } | ||
3347 | |||
3348 | /* add playback controls from the parsed DAC table */ | ||
3349 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
3350 | const struct auto_pin_cfg *cfg) | ||
3351 | { | ||
3352 | struct sigmatel_spec *spec = codec->spec; | ||
3353 | hda_nid_t nid; | ||
3354 | int err; | ||
3355 | int idx; | ||
3356 | |||
3357 | err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, | ||
3358 | spec->multiout.dac_nids, | ||
3359 | cfg->line_out_type); | ||
3360 | if (err < 0) | ||
3361 | return err; | ||
3362 | |||
3363 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { | ||
3364 | err = stac92xx_add_control(spec, | ||
3365 | STAC_CTL_WIDGET_HP_SWITCH, | ||
3366 | "Headphone as Line Out Switch", | ||
3367 | cfg->hp_pins[cfg->hp_outs - 1]); | ||
3368 | if (err < 0) | ||
3369 | return err; | ||
3370 | } | ||
3371 | |||
3372 | for (idx = 0; idx < cfg->num_inputs; idx++) { | ||
3373 | if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN) | ||
3374 | break; | ||
3375 | nid = cfg->inputs[idx].pin; | ||
3376 | err = stac92xx_add_jack_mode_control(codec, nid, idx); | ||
3377 | if (err < 0) | ||
3378 | return err; | ||
3379 | } | ||
3380 | |||
3381 | return 0; | ||
3382 | } | ||
3383 | |||
3384 | /* add playback controls for Speaker and HP outputs */ | ||
3385 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | ||
3386 | struct auto_pin_cfg *cfg) | ||
3387 | { | ||
3388 | struct sigmatel_spec *spec = codec->spec; | ||
3389 | int err; | ||
3390 | |||
3391 | err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins, | ||
3392 | spec->hp_dacs, AUTO_PIN_HP_OUT); | ||
3393 | if (err < 0) | ||
3394 | return err; | ||
3395 | |||
3396 | err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins, | ||
3397 | spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT); | ||
3398 | if (err < 0) | ||
3399 | return err; | ||
3400 | |||
3401 | return 0; | ||
3402 | } | ||
3403 | |||
3404 | /* labels for mono mux outputs */ | ||
3405 | static const char * const stac92xx_mono_labels[4] = { | ||
3406 | "DAC0", "DAC1", "Mixer", "DAC2" | ||
3407 | }; | ||
3408 | |||
3409 | /* create mono mux for mono out on capable codecs */ | ||
3410 | static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) | ||
3411 | { | ||
3412 | struct sigmatel_spec *spec = codec->spec; | ||
3413 | struct hda_input_mux *mono_mux = &spec->private_mono_mux; | ||
3414 | int i, num_cons; | ||
3415 | hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)]; | ||
3416 | |||
3417 | num_cons = snd_hda_get_connections(codec, | ||
3418 | spec->mono_nid, | ||
3419 | con_lst, | ||
3420 | HDA_MAX_NUM_INPUTS); | ||
3421 | if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) | ||
3422 | return -EINVAL; | ||
3423 | |||
3424 | for (i = 0; i < num_cons; i++) | ||
3425 | snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i, | ||
3426 | NULL); | ||
3427 | |||
3428 | return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX, | ||
3429 | "Mono Mux", spec->mono_nid); | ||
3430 | } | ||
3431 | |||
3432 | /* create PC beep volume controls */ | ||
3433 | static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, | ||
3434 | hda_nid_t nid) | ||
3435 | { | ||
3436 | struct sigmatel_spec *spec = codec->spec; | ||
3437 | u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3438 | int err, type = STAC_CTL_WIDGET_MUTE_BEEP; | ||
3439 | |||
3440 | if (spec->anabeep_nid == nid) | ||
3441 | type = STAC_CTL_WIDGET_MUTE; | ||
3442 | |||
3443 | /* check for mute support for the the amp */ | ||
3444 | if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { | ||
3445 | err = stac92xx_add_control(spec, type, | ||
3446 | "Beep Playback Switch", | ||
3447 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | ||
3448 | if (err < 0) | ||
3449 | return err; | ||
3450 | } | ||
3451 | |||
3452 | /* check to see if there is volume support for the amp */ | ||
3453 | if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
3454 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, | ||
3455 | "Beep Playback Volume", | ||
3456 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | ||
3457 | if (err < 0) | ||
3458 | return err; | ||
3459 | } | ||
3460 | return 0; | ||
3461 | } | ||
3462 | |||
3463 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
3464 | #define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info | ||
3465 | |||
3466 | static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol, | ||
3467 | struct snd_ctl_elem_value *ucontrol) | ||
3468 | { | ||
3469 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3470 | ucontrol->value.integer.value[0] = codec->beep->enabled; | ||
3471 | return 0; | ||
3472 | } | ||
3473 | |||
3474 | static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, | ||
3475 | struct snd_ctl_elem_value *ucontrol) | ||
3476 | { | ||
3477 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3478 | return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); | ||
3479 | } | ||
3480 | |||
3481 | static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { | ||
3482 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3483 | .info = stac92xx_dig_beep_switch_info, | ||
3484 | .get = stac92xx_dig_beep_switch_get, | ||
3485 | .put = stac92xx_dig_beep_switch_put, | ||
3486 | }; | ||
3487 | |||
3488 | static int stac92xx_beep_switch_ctl(struct hda_codec *codec) | ||
3489 | { | ||
3490 | return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, | ||
3491 | 0, "Beep Playback Switch", 0); | ||
3492 | } | ||
3493 | #endif | ||
3494 | |||
3495 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | ||
3496 | { | ||
3497 | struct sigmatel_spec *spec = codec->spec; | ||
3498 | int i, j, err = 0; | ||
3499 | |||
3500 | for (i = 0; i < spec->num_muxes; i++) { | ||
3501 | hda_nid_t nid; | ||
3502 | unsigned int wcaps; | ||
3503 | unsigned long val; | ||
3504 | |||
3505 | nid = spec->mux_nids[i]; | ||
3506 | wcaps = get_wcaps(codec, nid); | ||
3507 | if (!(wcaps & AC_WCAP_OUT_AMP)) | ||
3508 | continue; | ||
3509 | |||
3510 | /* check whether already the same control was created as | ||
3511 | * normal Capture Volume. | ||
3512 | */ | ||
3513 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3514 | for (j = 0; j < spec->num_caps; j++) { | ||
3515 | if (spec->capvols[j] == val) | ||
3516 | break; | ||
3517 | } | ||
3518 | if (j < spec->num_caps) | ||
3519 | continue; | ||
3520 | |||
3521 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i, | ||
3522 | "Mux Capture Volume", val); | ||
3523 | if (err < 0) | ||
3524 | return err; | ||
3525 | } | ||
3526 | return 0; | ||
3527 | }; | ||
3528 | |||
3529 | static const char * const stac92xx_spdif_labels[3] = { | ||
3530 | "Digital Playback", "Analog Mux 1", "Analog Mux 2", | ||
3531 | }; | ||
3532 | |||
3533 | static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) | ||
3534 | { | ||
3535 | struct sigmatel_spec *spec = codec->spec; | ||
3536 | struct hda_input_mux *spdif_mux = &spec->private_smux; | ||
3537 | const char * const *labels = spec->spdif_labels; | ||
3538 | int i, num_cons; | ||
3539 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | ||
3540 | |||
3541 | num_cons = snd_hda_get_connections(codec, | ||
3542 | spec->smux_nids[0], | ||
3543 | con_lst, | ||
3544 | HDA_MAX_NUM_INPUTS); | ||
3545 | if (num_cons <= 0) | ||
3546 | return -EINVAL; | ||
3547 | |||
3548 | if (!labels) | ||
3549 | labels = stac92xx_spdif_labels; | ||
3550 | |||
3551 | for (i = 0; i < num_cons; i++) | ||
3552 | snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL); | ||
3553 | |||
3554 | return 0; | ||
3555 | } | ||
3556 | |||
3557 | /* labels for dmic mux inputs */ | ||
3558 | static const char * const stac92xx_dmic_labels[5] = { | ||
3559 | "Analog Inputs", "Digital Mic 1", "Digital Mic 2", | ||
3560 | "Digital Mic 3", "Digital Mic 4" | ||
3561 | }; | ||
3562 | |||
3563 | static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux, | ||
3564 | int idx) | ||
3565 | { | ||
3566 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3567 | int nums; | ||
3568 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3569 | if (idx >= 0 && idx < nums) | ||
3570 | return conn[idx]; | ||
3571 | return 0; | ||
3572 | } | ||
3573 | |||
3574 | /* look for NID recursively */ | ||
3575 | #define get_connection_index(codec, mux, nid) \ | ||
3576 | snd_hda_get_conn_index(codec, mux, nid, 1) | ||
3577 | |||
3578 | /* create a volume assigned to the given pin (only if supported) */ | ||
3579 | /* return 1 if the volume control is created */ | ||
3580 | static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, | ||
3581 | const char *label, int idx, int direction) | ||
3582 | { | ||
3583 | unsigned int caps, nums; | ||
3584 | char name[32]; | ||
3585 | int err; | ||
3586 | |||
3587 | if (direction == HDA_OUTPUT) | ||
3588 | caps = AC_WCAP_OUT_AMP; | ||
3589 | else | ||
3590 | caps = AC_WCAP_IN_AMP; | ||
3591 | if (!(get_wcaps(codec, nid) & caps)) | ||
3592 | return 0; | ||
3593 | caps = query_amp_caps(codec, nid, direction); | ||
3594 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
3595 | if (!nums) | ||
3596 | return 0; | ||
3597 | snprintf(name, sizeof(name), "%s Capture Volume", label); | ||
3598 | err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name, | ||
3599 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction)); | ||
3600 | if (err < 0) | ||
3601 | return err; | ||
3602 | return 1; | ||
3603 | } | ||
3604 | |||
3605 | /* create playback/capture controls for input pins on dmic capable codecs */ | ||
3606 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | ||
3607 | const struct auto_pin_cfg *cfg) | ||
3608 | { | ||
3609 | struct sigmatel_spec *spec = codec->spec; | ||
3610 | struct hda_input_mux *imux = &spec->private_imux; | ||
3611 | struct hda_input_mux *dimux = &spec->private_dimux; | ||
3612 | int err, i; | ||
3613 | unsigned int def_conf; | ||
3614 | |||
3615 | snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL); | ||
3616 | |||
3617 | for (i = 0; i < spec->num_dmics; i++) { | ||
3618 | hda_nid_t nid; | ||
3619 | int index, type_idx; | ||
3620 | char label[32]; | ||
3621 | |||
3622 | nid = spec->dmic_nids[i]; | ||
3623 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
3624 | continue; | ||
3625 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
3626 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
3627 | continue; | ||
3628 | |||
3629 | index = get_connection_index(codec, spec->dmux_nids[0], nid); | ||
3630 | if (index < 0) | ||
3631 | continue; | ||
3632 | |||
3633 | snd_hda_get_pin_label(codec, nid, &spec->autocfg, | ||
3634 | label, sizeof(label), NULL); | ||
3635 | snd_hda_add_imux_item(dimux, label, index, &type_idx); | ||
3636 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) | ||
3637 | snd_hda_add_imux_item(imux, label, index, &type_idx); | ||
3638 | |||
3639 | err = create_elem_capture_vol(codec, nid, label, type_idx, | ||
3640 | HDA_INPUT); | ||
3641 | if (err < 0) | ||
3642 | return err; | ||
3643 | if (!err) { | ||
3644 | err = create_elem_capture_vol(codec, nid, label, | ||
3645 | type_idx, HDA_OUTPUT); | ||
3646 | if (err < 0) | ||
3647 | return err; | ||
3648 | if (!err) { | ||
3649 | nid = get_connected_node(codec, | ||
3650 | spec->dmux_nids[0], index); | ||
3651 | if (nid) | ||
3652 | err = create_elem_capture_vol(codec, | ||
3653 | nid, label, | ||
3654 | type_idx, HDA_INPUT); | ||
3655 | if (err < 0) | ||
3656 | return err; | ||
3657 | } | ||
3658 | } | ||
3659 | } | ||
3660 | |||
3661 | return 0; | ||
3662 | } | ||
3663 | |||
3664 | static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | ||
3665 | hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) | ||
3666 | { | ||
3667 | unsigned int cfg; | ||
3668 | unsigned int type; | ||
3669 | |||
3670 | if (!nid) | ||
3671 | return 0; | ||
3672 | cfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3673 | type = get_defcfg_device(cfg); | ||
3674 | switch (snd_hda_get_input_pin_attr(cfg)) { | ||
3675 | case INPUT_PIN_ATTR_INT: | ||
3676 | if (*fixed) | ||
3677 | return 1; /* already occupied */ | ||
3678 | if (type != AC_JACK_MIC_IN) | ||
3679 | return 1; /* invalid type */ | ||
3680 | *fixed = nid; | ||
3681 | break; | ||
3682 | case INPUT_PIN_ATTR_UNUSED: | ||
3683 | break; | ||
3684 | case INPUT_PIN_ATTR_DOCK: | ||
3685 | if (*dock) | ||
3686 | return 1; /* already occupied */ | ||
3687 | if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN) | ||
3688 | return 1; /* invalid type */ | ||
3689 | *dock = nid; | ||
3690 | break; | ||
3691 | default: | ||
3692 | if (*ext) | ||
3693 | return 1; /* already occupied */ | ||
3694 | if (type != AC_JACK_MIC_IN) | ||
3695 | return 1; /* invalid type */ | ||
3696 | *ext = nid; | ||
3697 | break; | ||
3698 | } | ||
3699 | return 0; | ||
3700 | } | ||
3701 | |||
3702 | static int set_mic_route(struct hda_codec *codec, | ||
3703 | struct sigmatel_mic_route *mic, | ||
3704 | hda_nid_t pin) | ||
3705 | { | ||
3706 | struct sigmatel_spec *spec = codec->spec; | ||
3707 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3708 | int i; | ||
3709 | |||
3710 | mic->pin = pin; | ||
3711 | if (pin == 0) | ||
3712 | return 0; | ||
3713 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3714 | if (pin == cfg->inputs[i].pin) | ||
3715 | break; | ||
3716 | } | ||
3717 | if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) { | ||
3718 | /* analog pin */ | ||
3719 | i = get_connection_index(codec, spec->mux_nids[0], pin); | ||
3720 | if (i < 0) | ||
3721 | return -1; | ||
3722 | mic->mux_idx = i; | ||
3723 | mic->dmux_idx = -1; | ||
3724 | if (spec->dmux_nids) | ||
3725 | mic->dmux_idx = get_connection_index(codec, | ||
3726 | spec->dmux_nids[0], | ||
3727 | spec->mux_nids[0]); | ||
3728 | } else if (spec->dmux_nids) { | ||
3729 | /* digital pin */ | ||
3730 | i = get_connection_index(codec, spec->dmux_nids[0], pin); | ||
3731 | if (i < 0) | ||
3732 | return -1; | ||
3733 | mic->dmux_idx = i; | ||
3734 | mic->mux_idx = -1; | ||
3735 | if (spec->mux_nids) | ||
3736 | mic->mux_idx = get_connection_index(codec, | ||
3737 | spec->mux_nids[0], | ||
3738 | spec->dmux_nids[0]); | ||
3739 | } | ||
3740 | return 0; | ||
3741 | } | ||
3742 | |||
3743 | /* return non-zero if the device is for automatic mic switch */ | ||
3744 | static int stac_check_auto_mic(struct hda_codec *codec) | ||
3745 | { | ||
3746 | struct sigmatel_spec *spec = codec->spec; | ||
3747 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3748 | hda_nid_t fixed, ext, dock; | ||
3749 | int i; | ||
3750 | |||
3751 | fixed = ext = dock = 0; | ||
3752 | for (i = 0; i < cfg->num_inputs; i++) | ||
3753 | if (check_mic_pin(codec, cfg->inputs[i].pin, | ||
3754 | &fixed, &ext, &dock)) | ||
3755 | return 0; | ||
3756 | for (i = 0; i < spec->num_dmics; i++) | ||
3757 | if (check_mic_pin(codec, spec->dmic_nids[i], | ||
3758 | &fixed, &ext, &dock)) | ||
3759 | return 0; | ||
3760 | if (!fixed || (!ext && !dock)) | ||
3761 | return 0; /* no input to switch */ | ||
3762 | if (!is_jack_detectable(codec, ext)) | ||
3763 | return 0; /* no unsol support */ | ||
3764 | if (set_mic_route(codec, &spec->ext_mic, ext) || | ||
3765 | set_mic_route(codec, &spec->int_mic, fixed) || | ||
3766 | set_mic_route(codec, &spec->dock_mic, dock)) | ||
3767 | return 0; /* something is wrong */ | ||
3768 | return 1; | ||
3769 | } | ||
3770 | |||
3771 | /* create playback/capture controls for input pins */ | ||
3772 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | ||
3773 | { | ||
3774 | struct sigmatel_spec *spec = codec->spec; | ||
3775 | struct hda_input_mux *imux = &spec->private_imux; | ||
3776 | int i, j; | ||
3777 | const char *label; | ||
3778 | |||
3779 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3780 | hda_nid_t nid = cfg->inputs[i].pin; | ||
3781 | int index, err, type_idx; | ||
3782 | |||
3783 | index = -1; | ||
3784 | for (j = 0; j < spec->num_muxes; j++) { | ||
3785 | index = get_connection_index(codec, spec->mux_nids[j], | ||
3786 | nid); | ||
3787 | if (index >= 0) | ||
3788 | break; | ||
3789 | } | ||
3790 | if (index < 0) | ||
3791 | continue; | ||
3792 | |||
3793 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
3794 | snd_hda_add_imux_item(imux, label, index, &type_idx); | ||
3795 | |||
3796 | err = create_elem_capture_vol(codec, nid, | ||
3797 | label, type_idx, | ||
3798 | HDA_INPUT); | ||
3799 | if (err < 0) | ||
3800 | return err; | ||
3801 | } | ||
3802 | spec->num_analog_muxes = imux->num_items; | ||
3803 | |||
3804 | if (imux->num_items) { | ||
3805 | /* | ||
3806 | * Set the current input for the muxes. | ||
3807 | * The STAC9221 has two input muxes with identical source | ||
3808 | * NID lists. Hopefully this won't get confused. | ||
3809 | */ | ||
3810 | for (i = 0; i < spec->num_muxes; i++) { | ||
3811 | snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0, | ||
3812 | AC_VERB_SET_CONNECT_SEL, | ||
3813 | imux->items[0].index); | ||
3814 | } | ||
3815 | } | ||
3816 | |||
3817 | return 0; | ||
3818 | } | ||
3819 | |||
3820 | static void stac92xx_auto_init_multi_out(struct hda_codec *codec) | ||
3821 | { | ||
3822 | struct sigmatel_spec *spec = codec->spec; | ||
3823 | int i; | ||
3824 | |||
3825 | for (i = 0; i < spec->autocfg.line_outs; i++) { | ||
3826 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
3827 | stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
3828 | } | ||
3829 | } | ||
3830 | |||
3831 | static void stac92xx_auto_init_hp_out(struct hda_codec *codec) | ||
3832 | { | ||
3833 | struct sigmatel_spec *spec = codec->spec; | ||
3834 | int i; | ||
3835 | |||
3836 | for (i = 0; i < spec->autocfg.hp_outs; i++) { | ||
3837 | hda_nid_t pin; | ||
3838 | pin = spec->autocfg.hp_pins[i]; | ||
3839 | if (pin) /* connect to front */ | ||
3840 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
3841 | } | ||
3842 | for (i = 0; i < spec->autocfg.speaker_outs; i++) { | ||
3843 | hda_nid_t pin; | ||
3844 | pin = spec->autocfg.speaker_pins[i]; | ||
3845 | if (pin) /* connect to front */ | ||
3846 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN); | ||
3847 | } | ||
3848 | } | ||
3849 | |||
3850 | static int is_dual_headphones(struct hda_codec *codec) | ||
3851 | { | ||
3852 | struct sigmatel_spec *spec = codec->spec; | ||
3853 | int i, valid_hps; | ||
3854 | |||
3855 | if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT || | ||
3856 | spec->autocfg.hp_outs <= 1) | ||
3857 | return 0; | ||
3858 | valid_hps = 0; | ||
3859 | for (i = 0; i < spec->autocfg.hp_outs; i++) { | ||
3860 | hda_nid_t nid = spec->autocfg.hp_pins[i]; | ||
3861 | unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3862 | if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE) | ||
3863 | continue; | ||
3864 | valid_hps++; | ||
3865 | } | ||
3866 | return (valid_hps > 1); | ||
3867 | } | ||
3868 | |||
3869 | |||
3870 | static int stac92xx_parse_auto_config(struct hda_codec *codec) | ||
3871 | { | ||
3872 | struct sigmatel_spec *spec = codec->spec; | ||
3873 | hda_nid_t dig_out = 0, dig_in = 0; | ||
3874 | int hp_swap = 0; | ||
3875 | int i, err; | ||
3876 | |||
3877 | if ((err = snd_hda_parse_pin_def_config(codec, | ||
3878 | &spec->autocfg, | ||
3879 | spec->dmic_nids)) < 0) | ||
3880 | return err; | ||
3881 | if (! spec->autocfg.line_outs) | ||
3882 | return 0; /* can't find valid pin config */ | ||
3883 | |||
3884 | /* If we have no real line-out pin and multiple hp-outs, HPs should | ||
3885 | * be set up as multi-channel outputs. | ||
3886 | */ | ||
3887 | if (is_dual_headphones(codec)) { | ||
3888 | /* Copy hp_outs to line_outs, backup line_outs in | ||
3889 | * speaker_outs so that the following routines can handle | ||
3890 | * HP pins as primary outputs. | ||
3891 | */ | ||
3892 | snd_printdd("stac92xx: Enabling multi-HPs workaround\n"); | ||
3893 | memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, | ||
3894 | sizeof(spec->autocfg.line_out_pins)); | ||
3895 | spec->autocfg.speaker_outs = spec->autocfg.line_outs; | ||
3896 | memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, | ||
3897 | sizeof(spec->autocfg.hp_pins)); | ||
3898 | spec->autocfg.line_outs = spec->autocfg.hp_outs; | ||
3899 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; | ||
3900 | spec->autocfg.hp_outs = 0; | ||
3901 | hp_swap = 1; | ||
3902 | } | ||
3903 | if (spec->autocfg.mono_out_pin) { | ||
3904 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & | ||
3905 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | ||
3906 | u32 caps = query_amp_caps(codec, | ||
3907 | spec->autocfg.mono_out_pin, dir); | ||
3908 | hda_nid_t conn_list[1]; | ||
3909 | |||
3910 | /* get the mixer node and then the mono mux if it exists */ | ||
3911 | if (snd_hda_get_connections(codec, | ||
3912 | spec->autocfg.mono_out_pin, conn_list, 1) && | ||
3913 | snd_hda_get_connections(codec, conn_list[0], | ||
3914 | conn_list, 1) > 0) { | ||
3915 | |||
3916 | int wcaps = get_wcaps(codec, conn_list[0]); | ||
3917 | int wid_type = get_wcaps_type(wcaps); | ||
3918 | /* LR swap check, some stac925x have a mux that | ||
3919 | * changes the DACs output path instead of the | ||
3920 | * mono-mux path. | ||
3921 | */ | ||
3922 | if (wid_type == AC_WID_AUD_SEL && | ||
3923 | !(wcaps & AC_WCAP_LR_SWAP)) | ||
3924 | spec->mono_nid = conn_list[0]; | ||
3925 | } | ||
3926 | if (dir) { | ||
3927 | hda_nid_t nid = spec->autocfg.mono_out_pin; | ||
3928 | |||
3929 | /* most mono outs have a least a mute/unmute switch */ | ||
3930 | dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; | ||
3931 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | ||
3932 | "Mono Playback Switch", | ||
3933 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); | ||
3934 | if (err < 0) | ||
3935 | return err; | ||
3936 | /* check for volume support for the amp */ | ||
3937 | if ((caps & AC_AMPCAP_NUM_STEPS) | ||
3938 | >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
3939 | err = stac92xx_add_control(spec, | ||
3940 | STAC_CTL_WIDGET_VOL, | ||
3941 | "Mono Playback Volume", | ||
3942 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); | ||
3943 | if (err < 0) | ||
3944 | return err; | ||
3945 | } | ||
3946 | } | ||
3947 | |||
3948 | stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, | ||
3949 | AC_PINCTL_OUT_EN); | ||
3950 | } | ||
3951 | |||
3952 | if (!spec->multiout.num_dacs) { | ||
3953 | err = stac92xx_auto_fill_dac_nids(codec); | ||
3954 | if (err < 0) | ||
3955 | return err; | ||
3956 | err = stac92xx_auto_create_multi_out_ctls(codec, | ||
3957 | &spec->autocfg); | ||
3958 | if (err < 0) | ||
3959 | return err; | ||
3960 | } | ||
3961 | 3527 | ||
3962 | /* setup analog beep controls */ | 3528 | /* setup analog beep controls */ |
3963 | if (spec->anabeep_nid > 0) { | 3529 | if (spec->anabeep_nid > 0) { |
3964 | err = stac92xx_auto_create_beep_ctls(codec, | 3530 | err = stac_auto_create_beep_ctls(codec, |
3965 | spec->anabeep_nid); | 3531 | spec->anabeep_nid); |
3966 | if (err < 0) | 3532 | if (err < 0) |
3967 | return err; | 3533 | return err; |
3968 | } | 3534 | } |
@@ -3973,7 +3539,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec) | |||
3973 | hda_nid_t nid = spec->digbeep_nid; | 3539 | hda_nid_t nid = spec->digbeep_nid; |
3974 | unsigned int caps; | 3540 | unsigned int caps; |
3975 | 3541 | ||
3976 | err = stac92xx_auto_create_beep_ctls(codec, nid); | 3542 | err = stac_auto_create_beep_ctls(codec, nid); |
3977 | if (err < 0) | 3543 | if (err < 0) |
3978 | return err; | 3544 | return err; |
3979 | err = snd_hda_attach_beep_device(codec, nid); | 3545 | err = snd_hda_attach_beep_device(codec, nid); |
@@ -3985,7 +3551,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec) | |||
3985 | /* if no beep switch is available, make its own one */ | 3551 | /* if no beep switch is available, make its own one */ |
3986 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | 3552 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
3987 | if (!(caps & AC_AMPCAP_MUTE)) { | 3553 | if (!(caps & AC_AMPCAP_MUTE)) { |
3988 | err = stac92xx_beep_switch_ctl(codec); | 3554 | err = stac_beep_switch_ctl(codec); |
3989 | if (err < 0) | 3555 | if (err < 0) |
3990 | return err; | 3556 | return err; |
3991 | } | 3557 | } |
@@ -3993,387 +3559,33 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec) | |||
3993 | } | 3559 | } |
3994 | #endif | 3560 | #endif |
3995 | 3561 | ||
3996 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); | 3562 | if (spec->gpio_led) |
3997 | if (err < 0) | 3563 | spec->gen.vmaster_mute.hook = stac_vmaster_hook; |
3998 | return err; | ||
3999 | |||
4000 | /* All output parsing done, now restore the swapped hp pins */ | ||
4001 | if (hp_swap) { | ||
4002 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, | ||
4003 | sizeof(spec->autocfg.hp_pins)); | ||
4004 | spec->autocfg.hp_outs = spec->autocfg.line_outs; | ||
4005 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; | ||
4006 | spec->autocfg.line_outs = 0; | ||
4007 | } | ||
4008 | |||
4009 | if (stac_check_auto_mic(codec)) { | ||
4010 | spec->auto_mic = 1; | ||
4011 | /* only one capture for auto-mic */ | ||
4012 | spec->num_adcs = 1; | ||
4013 | spec->num_caps = 1; | ||
4014 | spec->num_muxes = 1; | ||
4015 | } | ||
4016 | |||
4017 | for (i = 0; i < spec->num_caps; i++) { | ||
4018 | err = stac92xx_add_capvol_ctls(codec, spec->capvols[i], | ||
4019 | spec->capsws[i], i); | ||
4020 | if (err < 0) | ||
4021 | return err; | ||
4022 | } | ||
4023 | |||
4024 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | ||
4025 | if (err < 0) | ||
4026 | return err; | ||
4027 | |||
4028 | if (spec->mono_nid > 0) { | ||
4029 | err = stac92xx_auto_create_mono_output_ctls(codec); | ||
4030 | if (err < 0) | ||
4031 | return err; | ||
4032 | } | ||
4033 | if (spec->num_dmics > 0 && !spec->dinput_mux) | ||
4034 | if ((err = stac92xx_auto_create_dmic_input_ctls(codec, | ||
4035 | &spec->autocfg)) < 0) | ||
4036 | return err; | ||
4037 | if (spec->num_muxes > 0) { | ||
4038 | err = stac92xx_auto_create_mux_input_ctls(codec); | ||
4039 | if (err < 0) | ||
4040 | return err; | ||
4041 | } | ||
4042 | if (spec->num_smuxes > 0) { | ||
4043 | err = stac92xx_auto_create_spdif_mux_ctls(codec); | ||
4044 | if (err < 0) | ||
4045 | return err; | ||
4046 | } | ||
4047 | |||
4048 | err = stac92xx_add_input_source(spec); | ||
4049 | if (err < 0) | ||
4050 | return err; | ||
4051 | |||
4052 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
4053 | if (spec->multiout.max_channels > 2) | ||
4054 | spec->surr_switch = 1; | ||
4055 | |||
4056 | /* find digital out and in converters */ | ||
4057 | for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) { | ||
4058 | unsigned int wid_caps = get_wcaps(codec, i); | ||
4059 | if (wid_caps & AC_WCAP_DIGITAL) { | ||
4060 | switch (get_wcaps_type(wid_caps)) { | ||
4061 | case AC_WID_AUD_OUT: | ||
4062 | if (!dig_out) | ||
4063 | dig_out = i; | ||
4064 | break; | ||
4065 | case AC_WID_AUD_IN: | ||
4066 | if (!dig_in) | ||
4067 | dig_in = i; | ||
4068 | break; | ||
4069 | } | ||
4070 | } | ||
4071 | } | ||
4072 | if (spec->autocfg.dig_outs) | ||
4073 | spec->multiout.dig_out_nid = dig_out; | ||
4074 | if (dig_in && spec->autocfg.dig_in_pin) | ||
4075 | spec->dig_in_nid = dig_in; | ||
4076 | |||
4077 | if (spec->kctls.list) | ||
4078 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | ||
4079 | |||
4080 | spec->input_mux = &spec->private_imux; | ||
4081 | if (!spec->dinput_mux) | ||
4082 | spec->dinput_mux = &spec->private_dimux; | ||
4083 | spec->sinput_mux = &spec->private_smux; | ||
4084 | spec->mono_mux = &spec->private_mono_mux; | ||
4085 | return 1; | ||
4086 | } | ||
4087 | |||
4088 | /* add playback controls for HP output */ | ||
4089 | static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, | ||
4090 | struct auto_pin_cfg *cfg) | ||
4091 | { | ||
4092 | struct sigmatel_spec *spec = codec->spec; | ||
4093 | hda_nid_t pin = cfg->hp_pins[0]; | ||
4094 | |||
4095 | if (! pin) | ||
4096 | return 0; | ||
4097 | |||
4098 | if (is_jack_detectable(codec, pin)) | ||
4099 | spec->hp_detect = 1; | ||
4100 | |||
4101 | return 0; | ||
4102 | } | ||
4103 | |||
4104 | /* add playback controls for LFE output */ | ||
4105 | static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | ||
4106 | struct auto_pin_cfg *cfg) | ||
4107 | { | ||
4108 | struct sigmatel_spec *spec = codec->spec; | ||
4109 | int err; | ||
4110 | hda_nid_t lfe_pin = 0x0; | ||
4111 | int i; | ||
4112 | |||
4113 | /* | ||
4114 | * search speaker outs and line outs for a mono speaker pin | ||
4115 | * with an amp. If one is found, add LFE controls | ||
4116 | * for it. | ||
4117 | */ | ||
4118 | for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { | ||
4119 | hda_nid_t pin = spec->autocfg.speaker_pins[i]; | ||
4120 | unsigned int wcaps = get_wcaps(codec, pin); | ||
4121 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | ||
4122 | if (wcaps == AC_WCAP_OUT_AMP) | ||
4123 | /* found a mono speaker with an amp, must be lfe */ | ||
4124 | lfe_pin = pin; | ||
4125 | } | ||
4126 | 3564 | ||
4127 | /* if speaker_outs is 0, then speakers may be in line_outs */ | 3565 | if (spec->aloopback_ctl && |
4128 | if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { | 3566 | snd_hda_get_bool_hint(codec, "loopback") == 1) { |
4129 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { | 3567 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl)) |
4130 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 3568 | return -ENOMEM; |
4131 | unsigned int defcfg; | ||
4132 | defcfg = snd_hda_codec_get_pincfg(codec, pin); | ||
4133 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { | ||
4134 | unsigned int wcaps = get_wcaps(codec, pin); | ||
4135 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | ||
4136 | if (wcaps == AC_WCAP_OUT_AMP) | ||
4137 | /* found a mono speaker with an amp, | ||
4138 | must be lfe */ | ||
4139 | lfe_pin = pin; | ||
4140 | } | ||
4141 | } | ||
4142 | } | 3569 | } |
4143 | 3570 | ||
4144 | if (lfe_pin) { | 3571 | if (spec->have_spdif_mux) { |
4145 | err = create_controls(codec, "LFE", lfe_pin, 1); | 3572 | err = stac_create_spdif_mux_ctls(codec); |
4146 | if (err < 0) | 3573 | if (err < 0) |
4147 | return err; | 3574 | return err; |
4148 | } | 3575 | } |
4149 | 3576 | ||
4150 | return 0; | 3577 | stac_init_power_map(codec); |
4151 | } | ||
4152 | |||
4153 | static int stac9200_parse_auto_config(struct hda_codec *codec) | ||
4154 | { | ||
4155 | struct sigmatel_spec *spec = codec->spec; | ||
4156 | int err; | ||
4157 | |||
4158 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) | ||
4159 | return err; | ||
4160 | |||
4161 | if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) | ||
4162 | return err; | ||
4163 | |||
4164 | if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) | ||
4165 | return err; | ||
4166 | |||
4167 | if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) | ||
4168 | return err; | ||
4169 | |||
4170 | if (spec->num_muxes > 0) { | ||
4171 | err = stac92xx_auto_create_mux_input_ctls(codec); | ||
4172 | if (err < 0) | ||
4173 | return err; | ||
4174 | } | ||
4175 | |||
4176 | err = stac92xx_add_input_source(spec); | ||
4177 | if (err < 0) | ||
4178 | return err; | ||
4179 | |||
4180 | if (spec->autocfg.dig_outs) | ||
4181 | spec->multiout.dig_out_nid = 0x05; | ||
4182 | if (spec->autocfg.dig_in_pin) | ||
4183 | spec->dig_in_nid = 0x04; | ||
4184 | |||
4185 | if (spec->kctls.list) | ||
4186 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | ||
4187 | |||
4188 | spec->input_mux = &spec->private_imux; | ||
4189 | spec->dinput_mux = &spec->private_dimux; | ||
4190 | |||
4191 | return 1; | ||
4192 | } | ||
4193 | |||
4194 | /* | ||
4195 | * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a | ||
4196 | * funky external mute control using GPIO pins. | ||
4197 | */ | ||
4198 | |||
4199 | static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | ||
4200 | unsigned int dir_mask, unsigned int data) | ||
4201 | { | ||
4202 | unsigned int gpiostate, gpiomask, gpiodir; | ||
4203 | |||
4204 | snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data); | ||
4205 | |||
4206 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | ||
4207 | AC_VERB_GET_GPIO_DATA, 0); | ||
4208 | gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); | ||
4209 | |||
4210 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | ||
4211 | AC_VERB_GET_GPIO_MASK, 0); | ||
4212 | gpiomask |= mask; | ||
4213 | |||
4214 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | ||
4215 | AC_VERB_GET_GPIO_DIRECTION, 0); | ||
4216 | gpiodir |= dir_mask; | ||
4217 | |||
4218 | /* Configure GPIOx as CMOS */ | ||
4219 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0); | ||
4220 | |||
4221 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4222 | AC_VERB_SET_GPIO_MASK, gpiomask); | ||
4223 | snd_hda_codec_read(codec, codec->afg, 0, | ||
4224 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */ | ||
4225 | |||
4226 | msleep(1); | ||
4227 | |||
4228 | snd_hda_codec_read(codec, codec->afg, 0, | ||
4229 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ | ||
4230 | } | ||
4231 | |||
4232 | static int stac_add_event(struct hda_codec *codec, hda_nid_t nid, | ||
4233 | unsigned char type, int data) | ||
4234 | { | ||
4235 | struct hda_jack_tbl *event; | ||
4236 | |||
4237 | event = snd_hda_jack_tbl_new(codec, nid); | ||
4238 | if (!event) | ||
4239 | return -ENOMEM; | ||
4240 | event->action = type; | ||
4241 | event->private_data = data; | ||
4242 | 3578 | ||
4243 | return 0; | 3579 | return 0; |
4244 | } | 3580 | } |
4245 | 3581 | ||
4246 | static void handle_unsol_event(struct hda_codec *codec, | ||
4247 | struct hda_jack_tbl *event); | ||
4248 | 3582 | ||
4249 | /* check if given nid is a valid pin and no other events are assigned | 3583 | static int stac_init(struct hda_codec *codec) |
4250 | * to it. If OK, assign the event, set the unsol flag, and returns 1. | ||
4251 | * Otherwise, returns zero. | ||
4252 | */ | ||
4253 | static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | ||
4254 | unsigned int type) | ||
4255 | { | ||
4256 | struct hda_jack_tbl *event; | ||
4257 | |||
4258 | if (!is_jack_detectable(codec, nid)) | ||
4259 | return 0; | ||
4260 | event = snd_hda_jack_tbl_new(codec, nid); | ||
4261 | if (!event) | ||
4262 | return -ENOMEM; | ||
4263 | if (event->action && event->action != type) | ||
4264 | return 0; | ||
4265 | event->action = type; | ||
4266 | event->callback = handle_unsol_event; | ||
4267 | snd_hda_jack_detect_enable(codec, nid, 0); | ||
4268 | return 1; | ||
4269 | } | ||
4270 | |||
4271 | static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | ||
4272 | { | ||
4273 | int i; | ||
4274 | for (i = 0; i < cfg->hp_outs; i++) | ||
4275 | if (cfg->hp_pins[i] == nid) | ||
4276 | return 1; /* nid is a HP-Out */ | ||
4277 | for (i = 0; i < cfg->line_outs; i++) | ||
4278 | if (cfg->line_out_pins[i] == nid) | ||
4279 | return 1; /* nid is a line-Out */ | ||
4280 | return 0; /* nid is not a HP-Out */ | ||
4281 | }; | ||
4282 | |||
4283 | static void stac92xx_power_down(struct hda_codec *codec) | ||
4284 | { | 3584 | { |
4285 | struct sigmatel_spec *spec = codec->spec; | 3585 | struct sigmatel_spec *spec = codec->spec; |
4286 | |||
4287 | /* power down inactive DACs */ | ||
4288 | const hda_nid_t *dac; | ||
4289 | for (dac = spec->dac_list; *dac; dac++) | ||
4290 | if (!check_all_dac_nids(spec, *dac)) | ||
4291 | snd_hda_codec_write(codec, *dac, 0, | ||
4292 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
4293 | } | ||
4294 | |||
4295 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | ||
4296 | int enable); | ||
4297 | |||
4298 | static inline int get_int_hint(struct hda_codec *codec, const char *key, | ||
4299 | int *valp) | ||
4300 | { | ||
4301 | const char *p; | ||
4302 | p = snd_hda_get_hint(codec, key); | ||
4303 | if (p) { | ||
4304 | unsigned long val; | ||
4305 | if (!strict_strtoul(p, 0, &val)) { | ||
4306 | *valp = val; | ||
4307 | return 1; | ||
4308 | } | ||
4309 | } | ||
4310 | return 0; | ||
4311 | } | ||
4312 | |||
4313 | /* override some hints from the hwdep entry */ | ||
4314 | static void stac_store_hints(struct hda_codec *codec) | ||
4315 | { | ||
4316 | struct sigmatel_spec *spec = codec->spec; | ||
4317 | int val; | ||
4318 | |||
4319 | val = snd_hda_get_bool_hint(codec, "hp_detect"); | ||
4320 | if (val >= 0) | ||
4321 | spec->hp_detect = val; | ||
4322 | if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { | ||
4323 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = | ||
4324 | spec->gpio_mask; | ||
4325 | } | ||
4326 | if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) | ||
4327 | spec->gpio_mask &= spec->gpio_mask; | ||
4328 | if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) | ||
4329 | spec->gpio_dir &= spec->gpio_mask; | ||
4330 | if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) | ||
4331 | spec->eapd_mask &= spec->gpio_mask; | ||
4332 | if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) | ||
4333 | spec->gpio_mute &= spec->gpio_mask; | ||
4334 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | ||
4335 | if (val >= 0) | ||
4336 | spec->eapd_switch = val; | ||
4337 | } | ||
4338 | |||
4339 | static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins, | ||
4340 | const hda_nid_t *pins) | ||
4341 | { | ||
4342 | while (num_pins--) | ||
4343 | stac_issue_unsol_event(codec, *pins++); | ||
4344 | } | ||
4345 | |||
4346 | /* fake event to set up pins */ | ||
4347 | static void stac_fake_hp_events(struct hda_codec *codec) | ||
4348 | { | ||
4349 | struct sigmatel_spec *spec = codec->spec; | ||
4350 | |||
4351 | if (spec->autocfg.hp_outs) | ||
4352 | stac_issue_unsol_events(codec, spec->autocfg.hp_outs, | ||
4353 | spec->autocfg.hp_pins); | ||
4354 | if (spec->autocfg.line_outs && | ||
4355 | spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0]) | ||
4356 | stac_issue_unsol_events(codec, spec->autocfg.line_outs, | ||
4357 | spec->autocfg.line_out_pins); | ||
4358 | } | ||
4359 | |||
4360 | static int stac92xx_init(struct hda_codec *codec) | ||
4361 | { | ||
4362 | struct sigmatel_spec *spec = codec->spec; | ||
4363 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4364 | unsigned int gpio; | 3586 | unsigned int gpio; |
4365 | int i; | 3587 | int i; |
4366 | 3588 | ||
4367 | if (spec->init) | ||
4368 | snd_hda_sequence_write(codec, spec->init); | ||
4369 | |||
4370 | /* power down adcs initially */ | ||
4371 | if (spec->powerdown_adcs) | ||
4372 | for (i = 0; i < spec->num_adcs; i++) | ||
4373 | snd_hda_codec_write(codec, | ||
4374 | spec->adc_nids[i], 0, | ||
4375 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
4376 | |||
4377 | /* override some hints */ | 3589 | /* override some hints */ |
4378 | stac_store_hints(codec); | 3590 | stac_store_hints(codec); |
4379 | 3591 | ||
@@ -4386,180 +3598,33 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4386 | gpio |= spec->eapd_mask; | 3598 | gpio |= spec->eapd_mask; |
4387 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); | 3599 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); |
4388 | 3600 | ||
4389 | /* set up pins */ | 3601 | snd_hda_gen_init(codec); |
4390 | if (spec->hp_detect) { | ||
4391 | /* Enable unsolicited responses on the HP widget */ | ||
4392 | for (i = 0; i < cfg->hp_outs; i++) { | ||
4393 | hda_nid_t nid = cfg->hp_pins[i]; | ||
4394 | enable_pin_detect(codec, nid, STAC_HP_EVENT); | ||
4395 | } | ||
4396 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT && | ||
4397 | cfg->speaker_outs > 0) { | ||
4398 | /* enable pin-detect for line-outs as well */ | ||
4399 | for (i = 0; i < cfg->line_outs; i++) { | ||
4400 | hda_nid_t nid = cfg->line_out_pins[i]; | ||
4401 | enable_pin_detect(codec, nid, STAC_LO_EVENT); | ||
4402 | } | ||
4403 | } | ||
4404 | |||
4405 | /* force to enable the first line-out; the others are set up | ||
4406 | * in unsol_event | ||
4407 | */ | ||
4408 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], | ||
4409 | AC_PINCTL_OUT_EN); | ||
4410 | /* fake event to set up pins */ | ||
4411 | stac_fake_hp_events(codec); | ||
4412 | } else { | ||
4413 | stac92xx_auto_init_multi_out(codec); | ||
4414 | stac92xx_auto_init_hp_out(codec); | ||
4415 | for (i = 0; i < cfg->hp_outs; i++) | ||
4416 | stac_toggle_power_map(codec, cfg->hp_pins[i], 1); | ||
4417 | } | ||
4418 | if (spec->auto_mic) { | ||
4419 | /* initialize connection to analog input */ | ||
4420 | if (spec->dmux_nids) | ||
4421 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4422 | AC_VERB_SET_CONNECT_SEL, 0); | ||
4423 | if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) | ||
4424 | stac_issue_unsol_event(codec, spec->ext_mic.pin); | ||
4425 | if (enable_pin_detect(codec, spec->dock_mic.pin, | ||
4426 | STAC_MIC_EVENT)) | ||
4427 | stac_issue_unsol_event(codec, spec->dock_mic.pin); | ||
4428 | } | ||
4429 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4430 | hda_nid_t nid = cfg->inputs[i].pin; | ||
4431 | int type = cfg->inputs[i].type; | ||
4432 | unsigned int pinctl, conf; | ||
4433 | if (type == AUTO_PIN_MIC) { | ||
4434 | /* for mic pins, force to initialize */ | ||
4435 | pinctl = snd_hda_get_default_vref(codec, nid); | ||
4436 | pinctl |= AC_PINCTL_IN_EN; | ||
4437 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | ||
4438 | } else { | ||
4439 | pinctl = snd_hda_codec_read(codec, nid, 0, | ||
4440 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4441 | /* if PINCTL already set then skip */ | ||
4442 | /* Also, if both INPUT and OUTPUT are set, | ||
4443 | * it must be a BIOS bug; need to override, too | ||
4444 | */ | ||
4445 | if (!(pinctl & AC_PINCTL_IN_EN) || | ||
4446 | (pinctl & AC_PINCTL_OUT_EN)) { | ||
4447 | pinctl &= ~AC_PINCTL_OUT_EN; | ||
4448 | pinctl |= AC_PINCTL_IN_EN; | ||
4449 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | ||
4450 | } | ||
4451 | } | ||
4452 | conf = snd_hda_codec_get_pincfg(codec, nid); | ||
4453 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | ||
4454 | if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT)) | ||
4455 | stac_issue_unsol_event(codec, nid); | ||
4456 | } | ||
4457 | } | ||
4458 | for (i = 0; i < spec->num_dmics; i++) | ||
4459 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], | ||
4460 | AC_PINCTL_IN_EN); | ||
4461 | if (cfg->dig_out_pins[0]) | ||
4462 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0], | ||
4463 | AC_PINCTL_OUT_EN); | ||
4464 | if (cfg->dig_in_pin) | ||
4465 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | ||
4466 | AC_PINCTL_IN_EN); | ||
4467 | for (i = 0; i < spec->num_pwrs; i++) { | ||
4468 | hda_nid_t nid = spec->pwr_nids[i]; | ||
4469 | unsigned int pinctl, def_conf; | ||
4470 | |||
4471 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
4472 | def_conf = get_defcfg_connect(def_conf); | ||
4473 | if (def_conf == AC_JACK_PORT_NONE) { | ||
4474 | /* power off unused ports */ | ||
4475 | stac_toggle_power_map(codec, nid, 0); | ||
4476 | continue; | ||
4477 | } | ||
4478 | if (def_conf == AC_JACK_PORT_FIXED) { | ||
4479 | /* no need for jack detection for fixed pins */ | ||
4480 | stac_toggle_power_map(codec, nid, 1); | ||
4481 | continue; | ||
4482 | } | ||
4483 | /* power on when no jack detection is available */ | ||
4484 | /* or when the VREF is used for controlling LED */ | ||
4485 | if (!spec->hp_detect || | ||
4486 | spec->vref_mute_led_nid == nid || | ||
4487 | !is_jack_detectable(codec, nid)) { | ||
4488 | stac_toggle_power_map(codec, nid, 1); | ||
4489 | continue; | ||
4490 | } | ||
4491 | |||
4492 | if (is_nid_out_jack_pin(cfg, nid)) | ||
4493 | continue; /* already has an unsol event */ | ||
4494 | |||
4495 | pinctl = snd_hda_codec_read(codec, nid, 0, | ||
4496 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4497 | /* outputs are only ports capable of power management | ||
4498 | * any attempts on powering down a input port cause the | ||
4499 | * referenced VREF to act quirky. | ||
4500 | */ | ||
4501 | if (pinctl & AC_PINCTL_IN_EN) { | ||
4502 | stac_toggle_power_map(codec, nid, 1); | ||
4503 | continue; | ||
4504 | } | ||
4505 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { | ||
4506 | stac_issue_unsol_event(codec, nid); | ||
4507 | continue; | ||
4508 | } | ||
4509 | /* none of the above, turn the port OFF */ | ||
4510 | stac_toggle_power_map(codec, nid, 0); | ||
4511 | } | ||
4512 | |||
4513 | /* sync mute LED */ | ||
4514 | if (spec->gpio_led) { | ||
4515 | if (spec->vmaster_mute.hook) | ||
4516 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
4517 | else /* the very first init call doesn't have vmaster yet */ | ||
4518 | stac92xx_update_led_status(codec, false); | ||
4519 | } | ||
4520 | 3602 | ||
4521 | /* sync the power-map */ | 3603 | /* sync the power-map */ |
4522 | if (spec->num_pwrs) | 3604 | if (spec->num_pwrs) |
4523 | snd_hda_codec_write(codec, codec->afg, 0, | 3605 | snd_hda_codec_write(codec, codec->afg, 0, |
4524 | AC_VERB_IDT_SET_POWER_MAP, | 3606 | AC_VERB_IDT_SET_POWER_MAP, |
4525 | spec->power_map_bits); | 3607 | spec->power_map_bits); |
4526 | if (spec->dac_list) | ||
4527 | stac92xx_power_down(codec); | ||
4528 | return 0; | ||
4529 | } | ||
4530 | 3608 | ||
4531 | static void stac92xx_free_kctls(struct hda_codec *codec) | 3609 | /* power down inactive ADCs */ |
4532 | { | 3610 | if (spec->powerdown_adcs) { |
4533 | struct sigmatel_spec *spec = codec->spec; | 3611 | for (i = 0; i < spec->gen.num_all_adcs; i++) { |
4534 | 3612 | if (spec->active_adcs & (1 << i)) | |
4535 | if (spec->kctls.list) { | 3613 | continue; |
4536 | struct snd_kcontrol_new *kctl = spec->kctls.list; | 3614 | snd_hda_codec_write(codec, spec->gen.all_adcs[i], 0, |
4537 | int i; | 3615 | AC_VERB_SET_POWER_STATE, |
4538 | for (i = 0; i < spec->kctls.used; i++) | 3616 | AC_PWRST_D3); |
4539 | kfree(kctl[i].name); | 3617 | } |
4540 | } | 3618 | } |
4541 | snd_array_free(&spec->kctls); | ||
4542 | } | ||
4543 | 3619 | ||
4544 | static void stac92xx_shutup_pins(struct hda_codec *codec) | 3620 | return 0; |
4545 | { | ||
4546 | unsigned int i, def_conf; | ||
4547 | |||
4548 | if (codec->bus->shutdown) | ||
4549 | return; | ||
4550 | for (i = 0; i < codec->init_pins.used; i++) { | ||
4551 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
4552 | def_conf = snd_hda_codec_get_pincfg(codec, pin->nid); | ||
4553 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | ||
4554 | snd_hda_set_pin_ctl(codec, pin->nid, 0); | ||
4555 | } | ||
4556 | } | 3621 | } |
4557 | 3622 | ||
4558 | static void stac92xx_shutup(struct hda_codec *codec) | 3623 | static void stac_shutup(struct hda_codec *codec) |
4559 | { | 3624 | { |
4560 | struct sigmatel_spec *spec = codec->spec; | 3625 | struct sigmatel_spec *spec = codec->spec; |
4561 | 3626 | ||
4562 | stac92xx_shutup_pins(codec); | 3627 | snd_hda_shutup_pins(codec); |
4563 | 3628 | ||
4564 | if (spec->eapd_mask) | 3629 | if (spec->eapd_mask) |
4565 | stac_gpio_set(codec, spec->gpio_mask, | 3630 | stac_gpio_set(codec, spec->gpio_mask, |
@@ -4567,467 +3632,18 @@ static void stac92xx_shutup(struct hda_codec *codec) | |||
4567 | ~spec->eapd_mask); | 3632 | ~spec->eapd_mask); |
4568 | } | 3633 | } |
4569 | 3634 | ||
4570 | static void stac92xx_free(struct hda_codec *codec) | 3635 | static void stac_free(struct hda_codec *codec) |
4571 | { | 3636 | { |
4572 | struct sigmatel_spec *spec = codec->spec; | 3637 | struct sigmatel_spec *spec = codec->spec; |
4573 | 3638 | ||
4574 | if (! spec) | 3639 | if (!spec) |
4575 | return; | 3640 | return; |
4576 | 3641 | ||
3642 | snd_hda_gen_spec_free(&spec->gen); | ||
4577 | kfree(spec); | 3643 | kfree(spec); |
4578 | snd_hda_detach_beep_device(codec); | 3644 | snd_hda_detach_beep_device(codec); |
4579 | } | 3645 | } |
4580 | 3646 | ||
4581 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | ||
4582 | unsigned int flag) | ||
4583 | { | ||
4584 | unsigned int old_ctl, pin_ctl; | ||
4585 | |||
4586 | pin_ctl = snd_hda_codec_read(codec, nid, | ||
4587 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | ||
4588 | |||
4589 | if (pin_ctl & AC_PINCTL_IN_EN) { | ||
4590 | /* | ||
4591 | * we need to check the current set-up direction of | ||
4592 | * shared input pins since they can be switched via | ||
4593 | * "xxx as Output" mixer switch | ||
4594 | */ | ||
4595 | struct sigmatel_spec *spec = codec->spec; | ||
4596 | if (nid == spec->line_switch || nid == spec->mic_switch) | ||
4597 | return; | ||
4598 | } | ||
4599 | |||
4600 | old_ctl = pin_ctl; | ||
4601 | /* if setting pin direction bits, clear the current | ||
4602 | direction bits first */ | ||
4603 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) | ||
4604 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | ||
4605 | |||
4606 | pin_ctl |= flag; | ||
4607 | if (old_ctl != pin_ctl) | ||
4608 | snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl); | ||
4609 | } | ||
4610 | |||
4611 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | ||
4612 | unsigned int flag) | ||
4613 | { | ||
4614 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | ||
4615 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | ||
4616 | if (pin_ctl & flag) | ||
4617 | snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag); | ||
4618 | } | ||
4619 | |||
4620 | static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | ||
4621 | { | ||
4622 | if (!nid) | ||
4623 | return 0; | ||
4624 | return snd_hda_jack_detect(codec, nid); | ||
4625 | } | ||
4626 | |||
4627 | static void stac92xx_line_out_detect(struct hda_codec *codec, | ||
4628 | int presence) | ||
4629 | { | ||
4630 | struct sigmatel_spec *spec = codec->spec; | ||
4631 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4632 | int i; | ||
4633 | |||
4634 | if (cfg->speaker_outs == 0) | ||
4635 | return; | ||
4636 | |||
4637 | for (i = 0; i < cfg->line_outs; i++) { | ||
4638 | if (presence) | ||
4639 | break; | ||
4640 | presence = get_pin_presence(codec, cfg->line_out_pins[i]); | ||
4641 | if (presence) { | ||
4642 | unsigned int pinctl; | ||
4643 | pinctl = snd_hda_codec_read(codec, | ||
4644 | cfg->line_out_pins[i], 0, | ||
4645 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4646 | if (pinctl & AC_PINCTL_IN_EN) | ||
4647 | presence = 0; /* mic- or line-input */ | ||
4648 | } | ||
4649 | } | ||
4650 | |||
4651 | if (presence) { | ||
4652 | /* disable speakers */ | ||
4653 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4654 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4655 | AC_PINCTL_OUT_EN); | ||
4656 | if (spec->eapd_mask && spec->eapd_switch) | ||
4657 | stac_gpio_set(codec, spec->gpio_mask, | ||
4658 | spec->gpio_dir, spec->gpio_data & | ||
4659 | ~spec->eapd_mask); | ||
4660 | } else { | ||
4661 | /* enable speakers */ | ||
4662 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4663 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4664 | AC_PINCTL_OUT_EN); | ||
4665 | if (spec->eapd_mask && spec->eapd_switch) | ||
4666 | stac_gpio_set(codec, spec->gpio_mask, | ||
4667 | spec->gpio_dir, spec->gpio_data | | ||
4668 | spec->eapd_mask); | ||
4669 | } | ||
4670 | } | ||
4671 | |||
4672 | /* return non-zero if the hp-pin of the given array index isn't | ||
4673 | * a jack-detection target | ||
4674 | */ | ||
4675 | static int no_hp_sensing(struct sigmatel_spec *spec, int i) | ||
4676 | { | ||
4677 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4678 | |||
4679 | /* ignore sensing of shared line and mic jacks */ | ||
4680 | if (cfg->hp_pins[i] == spec->line_switch) | ||
4681 | return 1; | ||
4682 | if (cfg->hp_pins[i] == spec->mic_switch) | ||
4683 | return 1; | ||
4684 | /* ignore if the pin is set as line-out */ | ||
4685 | if (cfg->hp_pins[i] == spec->hp_switch) | ||
4686 | return 1; | ||
4687 | return 0; | ||
4688 | } | ||
4689 | |||
4690 | static void stac92xx_hp_detect(struct hda_codec *codec) | ||
4691 | { | ||
4692 | struct sigmatel_spec *spec = codec->spec; | ||
4693 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4694 | int i, presence; | ||
4695 | |||
4696 | presence = 0; | ||
4697 | if (spec->gpio_mute) | ||
4698 | presence = !(snd_hda_codec_read(codec, codec->afg, 0, | ||
4699 | AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute); | ||
4700 | |||
4701 | for (i = 0; i < cfg->hp_outs; i++) { | ||
4702 | if (presence) | ||
4703 | break; | ||
4704 | if (no_hp_sensing(spec, i)) | ||
4705 | continue; | ||
4706 | presence = get_pin_presence(codec, cfg->hp_pins[i]); | ||
4707 | if (presence) { | ||
4708 | unsigned int pinctl; | ||
4709 | pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, | ||
4710 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4711 | if (pinctl & AC_PINCTL_IN_EN) | ||
4712 | presence = 0; /* mic- or line-input */ | ||
4713 | } | ||
4714 | } | ||
4715 | |||
4716 | if (presence) { | ||
4717 | /* disable lineouts */ | ||
4718 | if (spec->hp_switch) | ||
4719 | stac92xx_reset_pinctl(codec, spec->hp_switch, | ||
4720 | AC_PINCTL_OUT_EN); | ||
4721 | for (i = 0; i < cfg->line_outs; i++) | ||
4722 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | ||
4723 | AC_PINCTL_OUT_EN); | ||
4724 | } else { | ||
4725 | /* enable lineouts */ | ||
4726 | if (spec->hp_switch) | ||
4727 | stac92xx_set_pinctl(codec, spec->hp_switch, | ||
4728 | AC_PINCTL_OUT_EN); | ||
4729 | for (i = 0; i < cfg->line_outs; i++) | ||
4730 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | ||
4731 | AC_PINCTL_OUT_EN); | ||
4732 | } | ||
4733 | stac92xx_line_out_detect(codec, presence); | ||
4734 | /* toggle hp outs */ | ||
4735 | for (i = 0; i < cfg->hp_outs; i++) { | ||
4736 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; | ||
4737 | if (no_hp_sensing(spec, i)) | ||
4738 | continue; | ||
4739 | if (1 /*presence*/) | ||
4740 | stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); | ||
4741 | #if 0 /* FIXME */ | ||
4742 | /* Resetting the pinctl like below may lead to (a sort of) regressions | ||
4743 | * on some devices since they use the HP pin actually for line/speaker | ||
4744 | * outs although the default pin config shows a different pin (that is | ||
4745 | * wrong and useless). | ||
4746 | * | ||
4747 | * So, it's basically a problem of default pin configs, likely a BIOS issue. | ||
4748 | * But, disabling the code below just works around it, and I'm too tired of | ||
4749 | * bug reports with such devices... | ||
4750 | */ | ||
4751 | else | ||
4752 | stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); | ||
4753 | #endif /* FIXME */ | ||
4754 | } | ||
4755 | } | ||
4756 | |||
4757 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | ||
4758 | int enable) | ||
4759 | { | ||
4760 | struct sigmatel_spec *spec = codec->spec; | ||
4761 | unsigned int idx, val; | ||
4762 | |||
4763 | for (idx = 0; idx < spec->num_pwrs; idx++) { | ||
4764 | if (spec->pwr_nids[idx] == nid) | ||
4765 | break; | ||
4766 | } | ||
4767 | if (idx >= spec->num_pwrs) | ||
4768 | return; | ||
4769 | |||
4770 | idx = 1 << idx; | ||
4771 | |||
4772 | val = spec->power_map_bits; | ||
4773 | if (enable) | ||
4774 | val &= ~idx; | ||
4775 | else | ||
4776 | val |= idx; | ||
4777 | |||
4778 | /* power down unused output ports */ | ||
4779 | if (val != spec->power_map_bits) { | ||
4780 | spec->power_map_bits = val; | ||
4781 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4782 | AC_VERB_IDT_SET_POWER_MAP, val); | ||
4783 | } | ||
4784 | } | ||
4785 | |||
4786 | static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) | ||
4787 | { | ||
4788 | stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); | ||
4789 | } | ||
4790 | |||
4791 | /* get the pin connection (fixed, none, etc) */ | ||
4792 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | ||
4793 | { | ||
4794 | struct sigmatel_spec *spec = codec->spec; | ||
4795 | unsigned int cfg; | ||
4796 | |||
4797 | cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]); | ||
4798 | return get_defcfg_connect(cfg); | ||
4799 | } | ||
4800 | |||
4801 | static int stac92xx_connected_ports(struct hda_codec *codec, | ||
4802 | const hda_nid_t *nids, int num_nids) | ||
4803 | { | ||
4804 | struct sigmatel_spec *spec = codec->spec; | ||
4805 | int idx, num; | ||
4806 | unsigned int def_conf; | ||
4807 | |||
4808 | for (num = 0; num < num_nids; num++) { | ||
4809 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4810 | if (spec->pin_nids[idx] == nids[num]) | ||
4811 | break; | ||
4812 | if (idx >= spec->num_pins) | ||
4813 | break; | ||
4814 | def_conf = stac_get_defcfg_connect(codec, idx); | ||
4815 | if (def_conf == AC_JACK_PORT_NONE) | ||
4816 | break; | ||
4817 | } | ||
4818 | return num; | ||
4819 | } | ||
4820 | |||
4821 | static void stac92xx_mic_detect(struct hda_codec *codec) | ||
4822 | { | ||
4823 | struct sigmatel_spec *spec = codec->spec; | ||
4824 | struct sigmatel_mic_route *mic; | ||
4825 | |||
4826 | if (get_pin_presence(codec, spec->ext_mic.pin)) | ||
4827 | mic = &spec->ext_mic; | ||
4828 | else if (get_pin_presence(codec, spec->dock_mic.pin)) | ||
4829 | mic = &spec->dock_mic; | ||
4830 | else | ||
4831 | mic = &spec->int_mic; | ||
4832 | if (mic->dmux_idx >= 0) | ||
4833 | snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, | ||
4834 | AC_VERB_SET_CONNECT_SEL, | ||
4835 | mic->dmux_idx); | ||
4836 | if (mic->mux_idx >= 0) | ||
4837 | snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, | ||
4838 | AC_VERB_SET_CONNECT_SEL, | ||
4839 | mic->mux_idx); | ||
4840 | } | ||
4841 | |||
4842 | static void handle_unsol_event(struct hda_codec *codec, | ||
4843 | struct hda_jack_tbl *event) | ||
4844 | { | ||
4845 | struct sigmatel_spec *spec = codec->spec; | ||
4846 | int data; | ||
4847 | |||
4848 | switch (event->action) { | ||
4849 | case STAC_HP_EVENT: | ||
4850 | case STAC_LO_EVENT: | ||
4851 | stac92xx_hp_detect(codec); | ||
4852 | break; | ||
4853 | case STAC_MIC_EVENT: | ||
4854 | stac92xx_mic_detect(codec); | ||
4855 | break; | ||
4856 | } | ||
4857 | |||
4858 | switch (event->action) { | ||
4859 | case STAC_HP_EVENT: | ||
4860 | case STAC_LO_EVENT: | ||
4861 | case STAC_MIC_EVENT: | ||
4862 | case STAC_INSERT_EVENT: | ||
4863 | case STAC_PWR_EVENT: | ||
4864 | if (spec->num_pwrs > 0) | ||
4865 | stac92xx_pin_sense(codec, event->nid); | ||
4866 | |||
4867 | switch (codec->subsystem_id) { | ||
4868 | case 0x103c308f: | ||
4869 | if (event->nid == 0xb) { | ||
4870 | int pin = AC_PINCTL_IN_EN; | ||
4871 | |||
4872 | if (get_pin_presence(codec, 0xa) | ||
4873 | && get_pin_presence(codec, 0xb)) | ||
4874 | pin |= AC_PINCTL_VREF_80; | ||
4875 | if (!get_pin_presence(codec, 0xb)) | ||
4876 | pin |= AC_PINCTL_VREF_80; | ||
4877 | |||
4878 | /* toggle VREF state based on mic + hp pin | ||
4879 | * status | ||
4880 | */ | ||
4881 | stac92xx_auto_set_pinctl(codec, 0x0a, pin); | ||
4882 | } | ||
4883 | } | ||
4884 | break; | ||
4885 | case STAC_VREF_EVENT: | ||
4886 | data = snd_hda_codec_read(codec, codec->afg, 0, | ||
4887 | AC_VERB_GET_GPIO_DATA, 0); | ||
4888 | /* toggle VREF state based on GPIOx status */ | ||
4889 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, | ||
4890 | !!(data & (1 << event->private_data))); | ||
4891 | break; | ||
4892 | } | ||
4893 | } | ||
4894 | |||
4895 | static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) | ||
4896 | { | ||
4897 | struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid); | ||
4898 | if (!event) | ||
4899 | return; | ||
4900 | handle_unsol_event(codec, event); | ||
4901 | } | ||
4902 | |||
4903 | static int hp_blike_system(u32 subsystem_id); | ||
4904 | |||
4905 | static void set_hp_led_gpio(struct hda_codec *codec) | ||
4906 | { | ||
4907 | struct sigmatel_spec *spec = codec->spec; | ||
4908 | unsigned int gpio; | ||
4909 | |||
4910 | if (spec->gpio_led) | ||
4911 | return; | ||
4912 | |||
4913 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); | ||
4914 | gpio &= AC_GPIO_IO_COUNT; | ||
4915 | if (gpio > 3) | ||
4916 | spec->gpio_led = 0x08; /* GPIO 3 */ | ||
4917 | else | ||
4918 | spec->gpio_led = 0x01; /* GPIO 0 */ | ||
4919 | } | ||
4920 | |||
4921 | /* | ||
4922 | * This method searches for the mute LED GPIO configuration | ||
4923 | * provided as OEM string in SMBIOS. The format of that string | ||
4924 | * is HP_Mute_LED_P_G or HP_Mute_LED_P | ||
4925 | * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) | ||
4926 | * that corresponds to the NOT muted state of the master volume | ||
4927 | * and G is the index of the GPIO to use as the mute LED control (0..9) | ||
4928 | * If _G portion is missing it is assigned based on the codec ID | ||
4929 | * | ||
4930 | * So, HP B-series like systems may have HP_Mute_LED_0 (current models) | ||
4931 | * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings | ||
4932 | * | ||
4933 | * | ||
4934 | * The dv-series laptops don't seem to have the HP_Mute_LED* strings in | ||
4935 | * SMBIOS - at least the ones I have seen do not have them - which include | ||
4936 | * my own system (HP Pavilion dv6-1110ax) and my cousin's | ||
4937 | * HP Pavilion dv9500t CTO. | ||
4938 | * Need more information on whether it is true across the entire series. | ||
4939 | * -- kunal | ||
4940 | */ | ||
4941 | static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | ||
4942 | { | ||
4943 | struct sigmatel_spec *spec = codec->spec; | ||
4944 | const struct dmi_device *dev = NULL; | ||
4945 | |||
4946 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | ||
4947 | get_int_hint(codec, "gpio_led_polarity", | ||
4948 | &spec->gpio_led_polarity); | ||
4949 | return 1; | ||
4950 | } | ||
4951 | if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { | ||
4952 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, | ||
4953 | NULL, dev))) { | ||
4954 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", | ||
4955 | &spec->gpio_led_polarity, | ||
4956 | &spec->gpio_led) == 2) { | ||
4957 | unsigned int max_gpio; | ||
4958 | max_gpio = snd_hda_param_read(codec, codec->afg, | ||
4959 | AC_PAR_GPIO_CAP); | ||
4960 | max_gpio &= AC_GPIO_IO_COUNT; | ||
4961 | if (spec->gpio_led < max_gpio) | ||
4962 | spec->gpio_led = 1 << spec->gpio_led; | ||
4963 | else | ||
4964 | spec->vref_mute_led_nid = spec->gpio_led; | ||
4965 | return 1; | ||
4966 | } | ||
4967 | if (sscanf(dev->name, "HP_Mute_LED_%d", | ||
4968 | &spec->gpio_led_polarity) == 1) { | ||
4969 | set_hp_led_gpio(codec); | ||
4970 | return 1; | ||
4971 | } | ||
4972 | /* BIOS bug: unfilled OEM string */ | ||
4973 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { | ||
4974 | set_hp_led_gpio(codec); | ||
4975 | switch (codec->subsystem_id) { | ||
4976 | case 0x103c148a: | ||
4977 | spec->gpio_led_polarity = 0; | ||
4978 | break; | ||
4979 | default: | ||
4980 | spec->gpio_led_polarity = 1; | ||
4981 | break; | ||
4982 | } | ||
4983 | return 1; | ||
4984 | } | ||
4985 | } | ||
4986 | |||
4987 | /* | ||
4988 | * Fallback case - if we don't find the DMI strings, | ||
4989 | * we statically set the GPIO - if not a B-series system | ||
4990 | * and default polarity is provided | ||
4991 | */ | ||
4992 | if (!hp_blike_system(codec->subsystem_id) && | ||
4993 | (default_polarity == 0 || default_polarity == 1)) { | ||
4994 | set_hp_led_gpio(codec); | ||
4995 | spec->gpio_led_polarity = default_polarity; | ||
4996 | return 1; | ||
4997 | } | ||
4998 | } | ||
4999 | return 0; | ||
5000 | } | ||
5001 | |||
5002 | static int hp_blike_system(u32 subsystem_id) | ||
5003 | { | ||
5004 | switch (subsystem_id) { | ||
5005 | case 0x103c1520: | ||
5006 | case 0x103c1521: | ||
5007 | case 0x103c1523: | ||
5008 | case 0x103c1524: | ||
5009 | case 0x103c1525: | ||
5010 | case 0x103c1722: | ||
5011 | case 0x103c1723: | ||
5012 | case 0x103c1724: | ||
5013 | case 0x103c1725: | ||
5014 | case 0x103c1726: | ||
5015 | case 0x103c1727: | ||
5016 | case 0x103c1728: | ||
5017 | case 0x103c1729: | ||
5018 | case 0x103c172a: | ||
5019 | case 0x103c172b: | ||
5020 | case 0x103c307e: | ||
5021 | case 0x103c307f: | ||
5022 | case 0x103c3080: | ||
5023 | case 0x103c3081: | ||
5024 | case 0x103c7007: | ||
5025 | case 0x103c7008: | ||
5026 | return 1; | ||
5027 | } | ||
5028 | return 0; | ||
5029 | } | ||
5030 | |||
5031 | #ifdef CONFIG_PROC_FS | 3647 | #ifdef CONFIG_PROC_FS |
5032 | static void stac92hd_proc_hook(struct snd_info_buffer *buffer, | 3648 | static void stac92hd_proc_hook(struct snd_info_buffer *buffer, |
5033 | struct hda_codec *codec, hda_nid_t nid) | 3649 | struct hda_codec *codec, hda_nid_t nid) |
@@ -5076,24 +3692,22 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer, | |||
5076 | #endif | 3692 | #endif |
5077 | 3693 | ||
5078 | #ifdef CONFIG_PM | 3694 | #ifdef CONFIG_PM |
5079 | static int stac92xx_resume(struct hda_codec *codec) | 3695 | static int stac_resume(struct hda_codec *codec) |
5080 | { | 3696 | { |
5081 | stac92xx_init(codec); | 3697 | codec->patch_ops.init(codec); |
5082 | snd_hda_codec_resume_amp(codec); | 3698 | snd_hda_codec_resume_amp(codec); |
5083 | snd_hda_codec_resume_cache(codec); | 3699 | snd_hda_codec_resume_cache(codec); |
5084 | /* fake event to set up pins again to override cached values */ | ||
5085 | stac_fake_hp_events(codec); | ||
5086 | return 0; | 3700 | return 0; |
5087 | } | 3701 | } |
5088 | 3702 | ||
5089 | static int stac92xx_suspend(struct hda_codec *codec) | 3703 | static int stac_suspend(struct hda_codec *codec) |
5090 | { | 3704 | { |
5091 | stac92xx_shutup(codec); | 3705 | stac_shutup(codec); |
5092 | return 0; | 3706 | return 0; |
5093 | } | 3707 | } |
5094 | 3708 | ||
5095 | static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | 3709 | static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg, |
5096 | unsigned int power_state) | 3710 | unsigned int power_state) |
5097 | { | 3711 | { |
5098 | unsigned int afg_power_state = power_state; | 3712 | unsigned int afg_power_state = power_state; |
5099 | struct sigmatel_spec *spec = codec->spec; | 3713 | struct sigmatel_spec *spec = codec->spec; |
@@ -5110,67 +3724,37 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
5110 | } | 3724 | } |
5111 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 3725 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, |
5112 | afg_power_state); | 3726 | afg_power_state); |
5113 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | 3727 | snd_hda_codec_set_power_to_all(codec, fg, power_state); |
5114 | } | 3728 | } |
5115 | #else | 3729 | #else |
5116 | #define stac92xx_suspend NULL | 3730 | #define stac_suspend NULL |
5117 | #define stac92xx_resume NULL | 3731 | #define stac_resume NULL |
5118 | #define stac92xx_set_power_state NULL | 3732 | #define stac_set_power_state NULL |
5119 | #endif /* CONFIG_PM */ | 3733 | #endif /* CONFIG_PM */ |
5120 | 3734 | ||
5121 | /* update mute-LED accoring to the master switch */ | 3735 | static const struct hda_codec_ops stac_patch_ops = { |
5122 | static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) | 3736 | .build_controls = snd_hda_gen_build_controls, |
5123 | { | 3737 | .build_pcms = snd_hda_gen_build_pcms, |
5124 | struct sigmatel_spec *spec = codec->spec; | 3738 | .init = stac_init, |
5125 | int muted = !enabled; | 3739 | .free = stac_free, |
5126 | |||
5127 | if (!spec->gpio_led) | ||
5128 | return; | ||
5129 | |||
5130 | /* LED state is inverted on these systems */ | ||
5131 | if (spec->gpio_led_polarity) | ||
5132 | muted = !muted; | ||
5133 | |||
5134 | if (!spec->vref_mute_led_nid) { | ||
5135 | if (muted) | ||
5136 | spec->gpio_data |= spec->gpio_led; | ||
5137 | else | ||
5138 | spec->gpio_data &= ~spec->gpio_led; | ||
5139 | stac_gpio_set(codec, spec->gpio_mask, | ||
5140 | spec->gpio_dir, spec->gpio_data); | ||
5141 | } else { | ||
5142 | spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD; | ||
5143 | stac_vrefout_set(codec, spec->vref_mute_led_nid, | ||
5144 | spec->vref_led); | ||
5145 | } | ||
5146 | } | ||
5147 | |||
5148 | static const struct hda_codec_ops stac92xx_patch_ops = { | ||
5149 | .build_controls = stac92xx_build_controls, | ||
5150 | .build_pcms = stac92xx_build_pcms, | ||
5151 | .init = stac92xx_init, | ||
5152 | .free = stac92xx_free, | ||
5153 | .unsol_event = snd_hda_jack_unsol_event, | 3740 | .unsol_event = snd_hda_jack_unsol_event, |
5154 | #ifdef CONFIG_PM | 3741 | #ifdef CONFIG_PM |
5155 | .suspend = stac92xx_suspend, | 3742 | .suspend = stac_suspend, |
5156 | .resume = stac92xx_resume, | 3743 | .resume = stac_resume, |
5157 | #endif | 3744 | #endif |
5158 | .reboot_notify = stac92xx_shutup, | 3745 | .reboot_notify = stac_shutup, |
5159 | }; | 3746 | }; |
5160 | 3747 | ||
5161 | static int alloc_stac_spec(struct hda_codec *codec, int num_pins, | 3748 | static int alloc_stac_spec(struct hda_codec *codec) |
5162 | const hda_nid_t *pin_nids) | ||
5163 | { | 3749 | { |
5164 | struct sigmatel_spec *spec; | 3750 | struct sigmatel_spec *spec; |
5165 | 3751 | ||
5166 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3752 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5167 | if (!spec) | 3753 | if (!spec) |
5168 | return -ENOMEM; | 3754 | return -ENOMEM; |
3755 | snd_hda_gen_spec_init(&spec->gen); | ||
5169 | codec->spec = spec; | 3756 | codec->spec = spec; |
5170 | codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */ | 3757 | codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */ |
5171 | spec->num_pins = num_pins; | ||
5172 | spec->pin_nids = pin_nids; | ||
5173 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | ||
5174 | return 0; | 3758 | return 0; |
5175 | } | 3759 | } |
5176 | 3760 | ||
@@ -5179,59 +3763,29 @@ static int patch_stac9200(struct hda_codec *codec) | |||
5179 | struct sigmatel_spec *spec; | 3763 | struct sigmatel_spec *spec; |
5180 | int err; | 3764 | int err; |
5181 | 3765 | ||
5182 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac9200_pin_nids), | 3766 | err = alloc_stac_spec(codec); |
5183 | stac9200_pin_nids); | ||
5184 | if (err < 0) | 3767 | if (err < 0) |
5185 | return err; | 3768 | return err; |
5186 | 3769 | ||
5187 | spec = codec->spec; | 3770 | spec = codec->spec; |
5188 | spec->linear_tone_beep = 1; | 3771 | spec->linear_tone_beep = 1; |
5189 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 3772 | spec->gen.own_eapd_ctl = 1; |
5190 | stac9200_models, | ||
5191 | stac9200_cfg_tbl); | ||
5192 | if (spec->board_config < 0) | ||
5193 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5194 | codec->chip_name); | ||
5195 | else | ||
5196 | stac92xx_set_config_regs(codec, | ||
5197 | stac9200_brd_tbl[spec->board_config]); | ||
5198 | |||
5199 | spec->multiout.max_channels = 2; | ||
5200 | spec->multiout.num_dacs = 1; | ||
5201 | spec->multiout.dac_nids = stac9200_dac_nids; | ||
5202 | spec->adc_nids = stac9200_adc_nids; | ||
5203 | spec->mux_nids = stac9200_mux_nids; | ||
5204 | spec->num_muxes = 1; | ||
5205 | spec->num_dmics = 0; | ||
5206 | spec->num_adcs = 1; | ||
5207 | spec->num_pwrs = 0; | ||
5208 | |||
5209 | if (spec->board_config == STAC_9200_M4 || | ||
5210 | spec->board_config == STAC_9200_M4_2 || | ||
5211 | spec->board_config == STAC_9200_OQO) | ||
5212 | spec->init = stac9200_eapd_init; | ||
5213 | else | ||
5214 | spec->init = stac9200_core_init; | ||
5215 | spec->mixer = stac9200_mixer; | ||
5216 | 3773 | ||
5217 | if (spec->board_config == STAC_9200_PANASONIC) { | 3774 | codec->patch_ops = stac_patch_ops; |
5218 | spec->gpio_mask = spec->gpio_dir = 0x09; | ||
5219 | spec->gpio_data = 0x00; | ||
5220 | } | ||
5221 | 3775 | ||
5222 | err = stac9200_parse_auto_config(codec); | 3776 | snd_hda_add_verbs(codec, stac9200_eapd_init); |
3777 | |||
3778 | snd_hda_pick_fixup(codec, stac9200_models, stac9200_fixup_tbl, | ||
3779 | stac9200_fixups); | ||
3780 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
3781 | |||
3782 | err = stac_parse_auto_config(codec); | ||
5223 | if (err < 0) { | 3783 | if (err < 0) { |
5224 | stac92xx_free(codec); | 3784 | stac_free(codec); |
5225 | return err; | 3785 | return err; |
5226 | } | 3786 | } |
5227 | 3787 | ||
5228 | /* CF-74 has no headphone detection, and the driver should *NOT* | 3788 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5229 | * do detection and HP/speaker toggle because the hardware does it. | ||
5230 | */ | ||
5231 | if (spec->board_config == STAC_9200_PANASONIC) | ||
5232 | spec->hp_detect = 0; | ||
5233 | |||
5234 | codec->patch_ops = stac92xx_patch_ops; | ||
5235 | 3789 | ||
5236 | return 0; | 3790 | return 0; |
5237 | } | 3791 | } |
@@ -5241,79 +3795,29 @@ static int patch_stac925x(struct hda_codec *codec) | |||
5241 | struct sigmatel_spec *spec; | 3795 | struct sigmatel_spec *spec; |
5242 | int err; | 3796 | int err; |
5243 | 3797 | ||
5244 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac925x_pin_nids), | 3798 | err = alloc_stac_spec(codec); |
5245 | stac925x_pin_nids); | ||
5246 | if (err < 0) | 3799 | if (err < 0) |
5247 | return err; | 3800 | return err; |
5248 | 3801 | ||
5249 | spec = codec->spec; | 3802 | spec = codec->spec; |
5250 | spec->linear_tone_beep = 1; | 3803 | spec->linear_tone_beep = 1; |
3804 | spec->gen.own_eapd_ctl = 1; | ||
5251 | 3805 | ||
5252 | /* Check first for codec ID */ | 3806 | codec->patch_ops = stac_patch_ops; |
5253 | spec->board_config = snd_hda_check_board_codec_sid_config(codec, | ||
5254 | STAC_925x_MODELS, | ||
5255 | stac925x_models, | ||
5256 | stac925x_codec_id_cfg_tbl); | ||
5257 | |||
5258 | /* Now checks for PCI ID, if codec ID is not found */ | ||
5259 | if (spec->board_config < 0) | ||
5260 | spec->board_config = snd_hda_check_board_config(codec, | ||
5261 | STAC_925x_MODELS, | ||
5262 | stac925x_models, | ||
5263 | stac925x_cfg_tbl); | ||
5264 | again: | ||
5265 | if (spec->board_config < 0) | ||
5266 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5267 | codec->chip_name); | ||
5268 | else | ||
5269 | stac92xx_set_config_regs(codec, | ||
5270 | stac925x_brd_tbl[spec->board_config]); | ||
5271 | |||
5272 | spec->multiout.max_channels = 2; | ||
5273 | spec->multiout.num_dacs = 1; | ||
5274 | spec->multiout.dac_nids = stac925x_dac_nids; | ||
5275 | spec->adc_nids = stac925x_adc_nids; | ||
5276 | spec->mux_nids = stac925x_mux_nids; | ||
5277 | spec->num_muxes = 1; | ||
5278 | spec->num_adcs = 1; | ||
5279 | spec->num_pwrs = 0; | ||
5280 | switch (codec->vendor_id) { | ||
5281 | case 0x83847632: /* STAC9202 */ | ||
5282 | case 0x83847633: /* STAC9202D */ | ||
5283 | case 0x83847636: /* STAC9251 */ | ||
5284 | case 0x83847637: /* STAC9251D */ | ||
5285 | spec->num_dmics = STAC925X_NUM_DMICS; | ||
5286 | spec->dmic_nids = stac925x_dmic_nids; | ||
5287 | spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids); | ||
5288 | spec->dmux_nids = stac925x_dmux_nids; | ||
5289 | break; | ||
5290 | default: | ||
5291 | spec->num_dmics = 0; | ||
5292 | break; | ||
5293 | } | ||
5294 | 3807 | ||
5295 | spec->init = stac925x_core_init; | 3808 | snd_hda_add_verbs(codec, stac925x_core_init); |
5296 | spec->mixer = stac925x_mixer; | 3809 | |
5297 | spec->num_caps = 1; | 3810 | snd_hda_pick_fixup(codec, stac925x_models, stac925x_fixup_tbl, |
5298 | spec->capvols = stac925x_capvols; | 3811 | stac925x_fixups); |
5299 | spec->capsws = stac925x_capsws; | 3812 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5300 | 3813 | ||
5301 | err = stac92xx_parse_auto_config(codec); | 3814 | err = stac_parse_auto_config(codec); |
5302 | if (!err) { | ||
5303 | if (spec->board_config < 0) { | ||
5304 | printk(KERN_WARNING "hda_codec: No auto-config is " | ||
5305 | "available, default to model=ref\n"); | ||
5306 | spec->board_config = STAC_925x_REF; | ||
5307 | goto again; | ||
5308 | } | ||
5309 | err = -EINVAL; | ||
5310 | } | ||
5311 | if (err < 0) { | 3815 | if (err < 0) { |
5312 | stac92xx_free(codec); | 3816 | stac_free(codec); |
5313 | return err; | 3817 | return err; |
5314 | } | 3818 | } |
5315 | 3819 | ||
5316 | codec->patch_ops = stac92xx_patch_ops; | 3820 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5317 | 3821 | ||
5318 | return 0; | 3822 | return 0; |
5319 | } | 3823 | } |
@@ -5321,467 +3825,181 @@ static int patch_stac925x(struct hda_codec *codec) | |||
5321 | static int patch_stac92hd73xx(struct hda_codec *codec) | 3825 | static int patch_stac92hd73xx(struct hda_codec *codec) |
5322 | { | 3826 | { |
5323 | struct sigmatel_spec *spec; | 3827 | struct sigmatel_spec *spec; |
5324 | hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; | ||
5325 | int err; | 3828 | int err; |
5326 | int num_dacs; | 3829 | int num_dacs; |
5327 | 3830 | ||
5328 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac92hd73xx_pin_nids), | 3831 | err = alloc_stac_spec(codec); |
5329 | stac92hd73xx_pin_nids); | ||
5330 | if (err < 0) | 3832 | if (err < 0) |
5331 | return err; | 3833 | return err; |
5332 | 3834 | ||
5333 | spec = codec->spec; | 3835 | spec = codec->spec; |
5334 | spec->linear_tone_beep = 0; | 3836 | spec->linear_tone_beep = 0; |
5335 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; | 3837 | spec->gen.mixer_nid = 0x1d; |
5336 | spec->board_config = snd_hda_check_board_config(codec, | 3838 | spec->have_spdif_mux = 1; |
5337 | STAC_92HD73XX_MODELS, | ||
5338 | stac92hd73xx_models, | ||
5339 | stac92hd73xx_cfg_tbl); | ||
5340 | /* check codec subsystem id if not found */ | ||
5341 | if (spec->board_config < 0) | ||
5342 | spec->board_config = | ||
5343 | snd_hda_check_board_codec_sid_config(codec, | ||
5344 | STAC_92HD73XX_MODELS, stac92hd73xx_models, | ||
5345 | stac92hd73xx_codec_id_cfg_tbl); | ||
5346 | again: | ||
5347 | if (spec->board_config < 0) | ||
5348 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5349 | codec->chip_name); | ||
5350 | else | ||
5351 | stac92xx_set_config_regs(codec, | ||
5352 | stac92hd73xx_brd_tbl[spec->board_config]); | ||
5353 | |||
5354 | num_dacs = snd_hda_get_connections(codec, 0x0a, | ||
5355 | conn, STAC92HD73_DAC_COUNT + 2) - 1; | ||
5356 | 3839 | ||
3840 | num_dacs = snd_hda_get_num_conns(codec, 0x0a) - 1; | ||
5357 | if (num_dacs < 3 || num_dacs > 5) { | 3841 | if (num_dacs < 3 || num_dacs > 5) { |
5358 | printk(KERN_WARNING "hda_codec: Could not determine " | 3842 | printk(KERN_WARNING "hda_codec: Could not determine " |
5359 | "number of channels defaulting to DAC count\n"); | 3843 | "number of channels defaulting to DAC count\n"); |
5360 | num_dacs = STAC92HD73_DAC_COUNT; | 3844 | num_dacs = 5; |
5361 | } | 3845 | } |
5362 | spec->init = stac92hd73xx_core_init; | 3846 | |
5363 | switch (num_dacs) { | 3847 | switch (num_dacs) { |
5364 | case 0x3: /* 6 Channel */ | 3848 | case 0x3: /* 6 Channel */ |
5365 | spec->aloopback_ctl = stac92hd73xx_6ch_loopback; | 3849 | spec->aloopback_ctl = &stac92hd73xx_6ch_loopback; |
5366 | break; | 3850 | break; |
5367 | case 0x4: /* 8 Channel */ | 3851 | case 0x4: /* 8 Channel */ |
5368 | spec->aloopback_ctl = stac92hd73xx_8ch_loopback; | 3852 | spec->aloopback_ctl = &stac92hd73xx_8ch_loopback; |
5369 | break; | 3853 | break; |
5370 | case 0x5: /* 10 Channel */ | 3854 | case 0x5: /* 10 Channel */ |
5371 | spec->aloopback_ctl = stac92hd73xx_10ch_loopback; | 3855 | spec->aloopback_ctl = &stac92hd73xx_10ch_loopback; |
5372 | break; | 3856 | break; |
5373 | } | 3857 | } |
5374 | spec->multiout.dac_nids = spec->dac_nids; | ||
5375 | 3858 | ||
5376 | spec->aloopback_mask = 0x01; | 3859 | spec->aloopback_mask = 0x01; |
5377 | spec->aloopback_shift = 8; | 3860 | spec->aloopback_shift = 8; |
5378 | 3861 | ||
5379 | spec->digbeep_nid = 0x1c; | 3862 | spec->digbeep_nid = 0x1c; |
5380 | spec->mux_nids = stac92hd73xx_mux_nids; | ||
5381 | spec->adc_nids = stac92hd73xx_adc_nids; | ||
5382 | spec->dmic_nids = stac92hd73xx_dmic_nids; | ||
5383 | spec->dmux_nids = stac92hd73xx_dmux_nids; | ||
5384 | spec->smux_nids = stac92hd73xx_smux_nids; | ||
5385 | |||
5386 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); | ||
5387 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); | ||
5388 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); | ||
5389 | |||
5390 | spec->num_caps = STAC92HD73XX_NUM_CAPS; | ||
5391 | spec->capvols = stac92hd73xx_capvols; | ||
5392 | spec->capsws = stac92hd73xx_capsws; | ||
5393 | |||
5394 | switch (spec->board_config) { | ||
5395 | case STAC_DELL_EQ: | ||
5396 | spec->init = dell_eq_core_init; | ||
5397 | /* fallthru */ | ||
5398 | case STAC_DELL_M6_AMIC: | ||
5399 | case STAC_DELL_M6_DMIC: | ||
5400 | case STAC_DELL_M6_BOTH: | ||
5401 | spec->num_smuxes = 0; | ||
5402 | spec->eapd_switch = 0; | ||
5403 | 3863 | ||
5404 | switch (spec->board_config) { | 3864 | /* GPIO0 High = Enable EAPD */ |
5405 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 3865 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
5406 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | 3866 | spec->gpio_data = 0x01; |
5407 | spec->num_dmics = 0; | 3867 | |
5408 | break; | 3868 | spec->eapd_switch = 1; |
5409 | case STAC_DELL_M6_DMIC: /* Digital Mics */ | ||
5410 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | ||
5411 | spec->num_dmics = 1; | ||
5412 | break; | ||
5413 | case STAC_DELL_M6_BOTH: /* Both */ | ||
5414 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); | ||
5415 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); | ||
5416 | spec->num_dmics = 1; | ||
5417 | break; | ||
5418 | } | ||
5419 | break; | ||
5420 | case STAC_ALIENWARE_M17X: | ||
5421 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | ||
5422 | spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); | ||
5423 | spec->eapd_switch = 0; | ||
5424 | break; | ||
5425 | default: | ||
5426 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | ||
5427 | spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); | ||
5428 | spec->eapd_switch = 1; | ||
5429 | break; | ||
5430 | } | ||
5431 | if (spec->board_config != STAC_92HD73XX_REF) { | ||
5432 | /* GPIO0 High = Enable EAPD */ | ||
5433 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | ||
5434 | spec->gpio_data = 0x01; | ||
5435 | } | ||
5436 | 3869 | ||
5437 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | 3870 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); |
5438 | spec->pwr_nids = stac92hd73xx_pwr_nids; | 3871 | spec->pwr_nids = stac92hd73xx_pwr_nids; |
5439 | 3872 | ||
5440 | err = stac92xx_parse_auto_config(codec); | 3873 | spec->gen.own_eapd_ctl = 1; |
3874 | spec->gen.power_down_unused = 1; | ||
5441 | 3875 | ||
5442 | if (!err) { | 3876 | codec->patch_ops = stac_patch_ops; |
5443 | if (spec->board_config < 0) { | 3877 | |
5444 | printk(KERN_WARNING "hda_codec: No auto-config is " | 3878 | snd_hda_pick_fixup(codec, stac92hd73xx_models, stac92hd73xx_fixup_tbl, |
5445 | "available, default to model=ref\n"); | 3879 | stac92hd73xx_fixups); |
5446 | spec->board_config = STAC_92HD73XX_REF; | 3880 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5447 | goto again; | ||
5448 | } | ||
5449 | err = -EINVAL; | ||
5450 | } | ||
5451 | 3881 | ||
3882 | if (!spec->volknob_init) | ||
3883 | snd_hda_add_verbs(codec, stac92hd73xx_core_init); | ||
3884 | |||
3885 | err = stac_parse_auto_config(codec); | ||
5452 | if (err < 0) { | 3886 | if (err < 0) { |
5453 | stac92xx_free(codec); | 3887 | stac_free(codec); |
5454 | return err; | 3888 | return err; |
5455 | } | 3889 | } |
5456 | 3890 | ||
5457 | if (spec->board_config == STAC_92HD73XX_NO_JD) | ||
5458 | spec->hp_detect = 0; | ||
5459 | |||
5460 | codec->patch_ops = stac92xx_patch_ops; | ||
5461 | |||
5462 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 3891 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
5463 | 3892 | ||
5464 | return 0; | 3893 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5465 | } | ||
5466 | |||
5467 | static int hp_bnb2011_with_dock(struct hda_codec *codec) | ||
5468 | { | ||
5469 | if (codec->vendor_id != 0x111d7605 && | ||
5470 | codec->vendor_id != 0x111d76d1) | ||
5471 | return 0; | ||
5472 | 3894 | ||
5473 | switch (codec->subsystem_id) { | ||
5474 | case 0x103c1618: | ||
5475 | case 0x103c1619: | ||
5476 | case 0x103c161a: | ||
5477 | case 0x103c161b: | ||
5478 | case 0x103c161c: | ||
5479 | case 0x103c161d: | ||
5480 | case 0x103c161e: | ||
5481 | case 0x103c161f: | ||
5482 | |||
5483 | case 0x103c162a: | ||
5484 | case 0x103c162b: | ||
5485 | |||
5486 | case 0x103c1630: | ||
5487 | case 0x103c1631: | ||
5488 | |||
5489 | case 0x103c1633: | ||
5490 | case 0x103c1634: | ||
5491 | case 0x103c1635: | ||
5492 | |||
5493 | case 0x103c3587: | ||
5494 | case 0x103c3588: | ||
5495 | case 0x103c3589: | ||
5496 | case 0x103c358a: | ||
5497 | |||
5498 | case 0x103c3667: | ||
5499 | case 0x103c3668: | ||
5500 | case 0x103c3669: | ||
5501 | |||
5502 | return 1; | ||
5503 | } | ||
5504 | return 0; | 3895 | return 0; |
5505 | } | 3896 | } |
5506 | 3897 | ||
5507 | static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid) | 3898 | static void stac_setup_gpio(struct hda_codec *codec) |
5508 | { | ||
5509 | struct sigmatel_spec *spec = codec->spec; | ||
5510 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5511 | int i; | ||
5512 | |||
5513 | spec->auto_pin_nids[spec->auto_pin_cnt] = nid; | ||
5514 | spec->auto_pin_cnt++; | ||
5515 | |||
5516 | if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN && | ||
5517 | get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) { | ||
5518 | for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) { | ||
5519 | if (nid == stac92hd83xxx_dmic_nids[i]) { | ||
5520 | spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid; | ||
5521 | spec->auto_dmic_cnt++; | ||
5522 | } | ||
5523 | } | ||
5524 | } | ||
5525 | } | ||
5526 | |||
5527 | static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid) | ||
5528 | { | ||
5529 | struct sigmatel_spec *spec = codec->spec; | ||
5530 | |||
5531 | spec->auto_adc_nids[spec->auto_adc_cnt] = nid; | ||
5532 | spec->auto_adc_cnt++; | ||
5533 | } | ||
5534 | |||
5535 | static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid) | ||
5536 | { | 3899 | { |
5537 | int i, j; | ||
5538 | struct sigmatel_spec *spec = codec->spec; | 3900 | struct sigmatel_spec *spec = codec->spec; |
5539 | 3901 | ||
5540 | for (i = 0; i < spec->auto_adc_cnt; i++) { | 3902 | if (spec->gpio_led) { |
5541 | if (get_connection_index(codec, | 3903 | if (!spec->vref_mute_led_nid) { |
5542 | spec->auto_adc_nids[i], nid) >= 0) { | 3904 | spec->gpio_mask |= spec->gpio_led; |
5543 | /* mux and volume for adc_nids[i] */ | 3905 | spec->gpio_dir |= spec->gpio_led; |
5544 | if (!spec->auto_mux_nids[i]) { | 3906 | spec->gpio_data |= spec->gpio_led; |
5545 | spec->auto_mux_nids[i] = nid; | 3907 | } else { |
5546 | /* 92hd codecs capture volume is in mux */ | 3908 | codec->patch_ops.set_power_state = |
5547 | spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid, | 3909 | stac_set_power_state; |
5548 | 3, 0, HDA_OUTPUT); | ||
5549 | } | ||
5550 | for (j = 0; j < spec->auto_dmic_cnt; j++) { | ||
5551 | if (get_connection_index(codec, nid, | ||
5552 | spec->auto_dmic_nids[j]) >= 0) { | ||
5553 | /* dmux for adc_nids[i] */ | ||
5554 | if (!spec->auto_dmux_nids[i]) | ||
5555 | spec->auto_dmux_nids[i] = nid; | ||
5556 | break; | ||
5557 | } | ||
5558 | } | ||
5559 | break; | ||
5560 | } | 3910 | } |
5561 | } | 3911 | } |
5562 | } | ||
5563 | |||
5564 | static void stac92hd8x_fill_auto_spec(struct hda_codec *codec) | ||
5565 | { | ||
5566 | hda_nid_t nid, end_nid; | ||
5567 | unsigned int wid_caps, wid_type; | ||
5568 | struct sigmatel_spec *spec = codec->spec; | ||
5569 | |||
5570 | end_nid = codec->start_nid + codec->num_nodes; | ||
5571 | |||
5572 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
5573 | wid_caps = get_wcaps(codec, nid); | ||
5574 | wid_type = get_wcaps_type(wid_caps); | ||
5575 | |||
5576 | if (wid_type == AC_WID_PIN) | ||
5577 | stac92hd8x_add_pin(codec, nid); | ||
5578 | |||
5579 | if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL)) | ||
5580 | stac92hd8x_add_adc(codec, nid); | ||
5581 | } | ||
5582 | 3912 | ||
5583 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 3913 | if (spec->mic_mute_led_gpio) { |
5584 | wid_caps = get_wcaps(codec, nid); | 3914 | spec->gpio_mask |= spec->mic_mute_led_gpio; |
5585 | wid_type = get_wcaps_type(wid_caps); | 3915 | spec->gpio_dir |= spec->mic_mute_led_gpio; |
3916 | spec->mic_mute_led_on = true; | ||
3917 | spec->gpio_data |= spec->mic_mute_led_gpio; | ||
5586 | 3918 | ||
5587 | if (wid_type == AC_WID_AUD_SEL) | 3919 | spec->gen.cap_sync_hook = stac_capture_led_hook; |
5588 | stac92hd8x_add_mux(codec, nid); | ||
5589 | } | 3920 | } |
5590 | |||
5591 | spec->pin_nids = spec->auto_pin_nids; | ||
5592 | spec->num_pins = spec->auto_pin_cnt; | ||
5593 | spec->adc_nids = spec->auto_adc_nids; | ||
5594 | spec->num_adcs = spec->auto_adc_cnt; | ||
5595 | spec->capvols = spec->auto_capvols; | ||
5596 | spec->capsws = spec->auto_capvols; | ||
5597 | spec->num_caps = spec->auto_adc_cnt; | ||
5598 | spec->mux_nids = spec->auto_mux_nids; | ||
5599 | spec->num_muxes = spec->auto_adc_cnt; | ||
5600 | spec->dmux_nids = spec->auto_dmux_nids; | ||
5601 | spec->num_dmuxes = spec->auto_adc_cnt; | ||
5602 | spec->dmic_nids = spec->auto_dmic_nids; | ||
5603 | spec->num_dmics = spec->auto_dmic_cnt; | ||
5604 | } | 3921 | } |
5605 | 3922 | ||
5606 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 3923 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
5607 | { | 3924 | { |
5608 | struct sigmatel_spec *spec; | 3925 | struct sigmatel_spec *spec; |
5609 | int default_polarity = -1; /* no default cfg */ | ||
5610 | int err; | 3926 | int err; |
5611 | 3927 | ||
5612 | err = alloc_stac_spec(codec, 0, NULL); /* pins filled later */ | 3928 | err = alloc_stac_spec(codec); |
5613 | if (err < 0) | 3929 | if (err < 0) |
5614 | return err; | 3930 | return err; |
5615 | 3931 | ||
5616 | if (hp_bnb2011_with_dock(codec)) { | ||
5617 | snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f); | ||
5618 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); | ||
5619 | } | ||
5620 | |||
5621 | codec->epss = 0; /* longer delay needed for D3 */ | 3932 | codec->epss = 0; /* longer delay needed for D3 */ |
5622 | stac92hd8x_fill_auto_spec(codec); | ||
5623 | 3933 | ||
5624 | spec = codec->spec; | 3934 | spec = codec->spec; |
5625 | spec->linear_tone_beep = 0; | 3935 | spec->linear_tone_beep = 0; |
5626 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 3936 | spec->gen.own_eapd_ctl = 1; |
3937 | spec->gen.power_down_unused = 1; | ||
3938 | spec->gen.mixer_nid = 0x1b; | ||
3939 | |||
5627 | spec->digbeep_nid = 0x21; | 3940 | spec->digbeep_nid = 0x21; |
5628 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 3941 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5629 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 3942 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5630 | spec->multiout.dac_nids = spec->dac_nids; | 3943 | spec->default_polarity = -1; /* no default cfg */ |
5631 | spec->init = stac92hd83xxx_core_init; | ||
5632 | |||
5633 | spec->board_config = snd_hda_check_board_config(codec, | ||
5634 | STAC_92HD83XXX_MODELS, | ||
5635 | stac92hd83xxx_models, | ||
5636 | stac92hd83xxx_cfg_tbl); | ||
5637 | /* check codec subsystem id if not found */ | ||
5638 | if (spec->board_config < 0) | ||
5639 | spec->board_config = | ||
5640 | snd_hda_check_board_codec_sid_config(codec, | ||
5641 | STAC_92HD83XXX_MODELS, stac92hd83xxx_models, | ||
5642 | stac92hd83xxx_codec_id_cfg_tbl); | ||
5643 | again: | ||
5644 | if (spec->board_config < 0) | ||
5645 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5646 | codec->chip_name); | ||
5647 | else | ||
5648 | stac92xx_set_config_regs(codec, | ||
5649 | stac92hd83xxx_brd_tbl[spec->board_config]); | ||
5650 | |||
5651 | codec->patch_ops = stac92xx_patch_ops; | ||
5652 | |||
5653 | switch (spec->board_config) { | ||
5654 | case STAC_HP_ZEPHYR: | ||
5655 | spec->init = stac92hd83xxx_hp_zephyr_init; | ||
5656 | break; | ||
5657 | case STAC_92HD83XXX_HP_LED: | ||
5658 | default_polarity = 0; | ||
5659 | break; | ||
5660 | case STAC_92HD83XXX_HP_INV_LED: | ||
5661 | default_polarity = 1; | ||
5662 | break; | ||
5663 | case STAC_92HD83XXX_HP_MIC_LED: | ||
5664 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ | ||
5665 | break; | ||
5666 | case STAC_92HD83XXX_HEADSET_JACK: | ||
5667 | spec->headset_jack = 1; | ||
5668 | break; | ||
5669 | } | ||
5670 | 3944 | ||
5671 | if (find_mute_led_cfg(codec, default_polarity)) | 3945 | codec->patch_ops = stac_patch_ops; |
5672 | snd_printd("mute LED gpio %d polarity %d\n", | ||
5673 | spec->gpio_led, | ||
5674 | spec->gpio_led_polarity); | ||
5675 | 3946 | ||
5676 | if (spec->gpio_led) { | 3947 | snd_hda_add_verbs(codec, stac92hd83xxx_core_init); |
5677 | if (!spec->vref_mute_led_nid) { | ||
5678 | spec->gpio_mask |= spec->gpio_led; | ||
5679 | spec->gpio_dir |= spec->gpio_led; | ||
5680 | spec->gpio_data |= spec->gpio_led; | ||
5681 | } else { | ||
5682 | codec->patch_ops.set_power_state = | ||
5683 | stac92xx_set_power_state; | ||
5684 | } | ||
5685 | } | ||
5686 | 3948 | ||
5687 | if (spec->mic_mute_led_gpio) { | 3949 | snd_hda_pick_fixup(codec, stac92hd83xxx_models, stac92hd83xxx_fixup_tbl, |
5688 | spec->gpio_mask |= spec->mic_mute_led_gpio; | 3950 | stac92hd83xxx_fixups); |
5689 | spec->gpio_dir |= spec->mic_mute_led_gpio; | 3951 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5690 | spec->mic_mute_led_on = true; | ||
5691 | spec->gpio_data |= spec->mic_mute_led_gpio; | ||
5692 | } | ||
5693 | 3952 | ||
5694 | err = stac92xx_parse_auto_config(codec); | 3953 | stac_setup_gpio(codec); |
5695 | if (!err) { | ||
5696 | if (spec->board_config < 0) { | ||
5697 | printk(KERN_WARNING "hda_codec: No auto-config is " | ||
5698 | "available, default to model=ref\n"); | ||
5699 | spec->board_config = STAC_92HD83XXX_REF; | ||
5700 | goto again; | ||
5701 | } | ||
5702 | err = -EINVAL; | ||
5703 | } | ||
5704 | 3954 | ||
3955 | err = stac_parse_auto_config(codec); | ||
5705 | if (err < 0) { | 3956 | if (err < 0) { |
5706 | stac92xx_free(codec); | 3957 | stac_free(codec); |
5707 | return err; | 3958 | return err; |
5708 | } | 3959 | } |
5709 | 3960 | ||
5710 | codec->proc_widget_hook = stac92hd_proc_hook; | 3961 | codec->proc_widget_hook = stac92hd_proc_hook; |
5711 | 3962 | ||
3963 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
3964 | |||
5712 | return 0; | 3965 | return 0; |
5713 | } | 3966 | } |
5714 | 3967 | ||
5715 | static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | 3968 | static const hda_nid_t stac92hd95_pwr_nids[] = { |
5716 | hda_nid_t dig0pin) | 3969 | 0x0a, 0x0b, 0x0c, 0x0d |
5717 | { | 3970 | }; |
5718 | struct sigmatel_spec *spec = codec->spec; | ||
5719 | int idx; | ||
5720 | |||
5721 | for (idx = 0; idx < spec->num_pins; idx++) | ||
5722 | if (spec->pin_nids[idx] == dig0pin) | ||
5723 | break; | ||
5724 | if ((idx + 2) >= spec->num_pins) | ||
5725 | return 0; | ||
5726 | 3971 | ||
5727 | /* dig1pin case */ | 3972 | static int patch_stac92hd95(struct hda_codec *codec) |
5728 | if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE) | 3973 | { |
5729 | return 2; | 3974 | struct sigmatel_spec *spec; |
3975 | int err; | ||
5730 | 3976 | ||
5731 | /* dig0pin + dig2pin case */ | 3977 | err = alloc_stac_spec(codec); |
5732 | if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE) | 3978 | if (err < 0) |
5733 | return 2; | 3979 | return err; |
5734 | if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE) | ||
5735 | return 1; | ||
5736 | else | ||
5737 | return 0; | ||
5738 | } | ||
5739 | 3980 | ||
5740 | /* HP dv7 bass switch - GPIO5 */ | 3981 | codec->epss = 0; /* longer delay needed for D3 */ |
5741 | #define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info | ||
5742 | static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, | ||
5743 | struct snd_ctl_elem_value *ucontrol) | ||
5744 | { | ||
5745 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
5746 | struct sigmatel_spec *spec = codec->spec; | ||
5747 | ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); | ||
5748 | return 0; | ||
5749 | } | ||
5750 | 3982 | ||
5751 | static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, | 3983 | spec = codec->spec; |
5752 | struct snd_ctl_elem_value *ucontrol) | 3984 | spec->linear_tone_beep = 0; |
5753 | { | 3985 | spec->gen.own_eapd_ctl = 1; |
5754 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 3986 | spec->gen.power_down_unused = 1; |
5755 | struct sigmatel_spec *spec = codec->spec; | ||
5756 | unsigned int gpio_data; | ||
5757 | 3987 | ||
5758 | gpio_data = (spec->gpio_data & ~0x20) | | 3988 | spec->digbeep_nid = 0x19; |
5759 | (ucontrol->value.integer.value[0] ? 0x20 : 0); | 3989 | spec->pwr_nids = stac92hd95_pwr_nids; |
5760 | if (gpio_data == spec->gpio_data) | 3990 | spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); |
5761 | return 0; | 3991 | spec->default_polarity = -1; /* no default cfg */ |
5762 | spec->gpio_data = gpio_data; | ||
5763 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | ||
5764 | return 1; | ||
5765 | } | ||
5766 | 3992 | ||
5767 | static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { | 3993 | codec->patch_ops = stac_patch_ops; |
5768 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5769 | .info = stac_hp_bass_gpio_info, | ||
5770 | .get = stac_hp_bass_gpio_get, | ||
5771 | .put = stac_hp_bass_gpio_put, | ||
5772 | }; | ||
5773 | 3994 | ||
5774 | static int stac_add_hp_bass_switch(struct hda_codec *codec) | 3995 | err = stac_parse_auto_config(codec); |
5775 | { | 3996 | if (err < 0) { |
5776 | struct sigmatel_spec *spec = codec->spec; | 3997 | stac_free(codec); |
3998 | return err; | ||
3999 | } | ||
5777 | 4000 | ||
5778 | if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl, | 4001 | codec->proc_widget_hook = stac92hd_proc_hook; |
5779 | "Bass Speaker Playback Switch", 0)) | ||
5780 | return -ENOMEM; | ||
5781 | 4002 | ||
5782 | spec->gpio_mask |= 0x20; | ||
5783 | spec->gpio_dir |= 0x20; | ||
5784 | spec->gpio_data |= 0x20; | ||
5785 | return 0; | 4003 | return 0; |
5786 | } | 4004 | } |
5787 | 4005 | ||
@@ -5789,82 +4007,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5789 | { | 4007 | { |
5790 | struct sigmatel_spec *spec; | 4008 | struct sigmatel_spec *spec; |
5791 | const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | 4009 | const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; |
5792 | unsigned int pin_cfg; | ||
5793 | int err; | 4010 | int err; |
5794 | 4011 | ||
5795 | err = alloc_stac_spec(codec, STAC92HD71BXX_NUM_PINS, | 4012 | err = alloc_stac_spec(codec); |
5796 | stac92hd71bxx_pin_nids_4port); | ||
5797 | if (err < 0) | 4013 | if (err < 0) |
5798 | return err; | 4014 | return err; |
5799 | 4015 | ||
5800 | spec = codec->spec; | 4016 | spec = codec->spec; |
5801 | spec->linear_tone_beep = 0; | 4017 | spec->linear_tone_beep = 0; |
5802 | codec->patch_ops = stac92xx_patch_ops; | 4018 | spec->gen.own_eapd_ctl = 1; |
5803 | switch (codec->vendor_id) { | 4019 | spec->gen.power_down_unused = 1; |
5804 | case 0x111d76b6: | 4020 | spec->gen.mixer_nid = 0x17; |
5805 | case 0x111d76b7: | 4021 | spec->have_spdif_mux = 1; |
5806 | break; | ||
5807 | case 0x111d7603: | ||
5808 | case 0x111d7608: | ||
5809 | /* On 92HD75Bx 0x27 isn't a pin nid */ | ||
5810 | spec->num_pins--; | ||
5811 | /* fallthrough */ | ||
5812 | default: | ||
5813 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; | ||
5814 | } | ||
5815 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | ||
5816 | spec->board_config = snd_hda_check_board_config(codec, | ||
5817 | STAC_92HD71BXX_MODELS, | ||
5818 | stac92hd71bxx_models, | ||
5819 | stac92hd71bxx_cfg_tbl); | ||
5820 | again: | ||
5821 | if (spec->board_config < 0) | ||
5822 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
5823 | codec->chip_name); | ||
5824 | else | ||
5825 | stac92xx_set_config_regs(codec, | ||
5826 | stac92hd71bxx_brd_tbl[spec->board_config]); | ||
5827 | 4022 | ||
5828 | if (spec->board_config != STAC_92HD71BXX_REF) { | 4023 | codec->patch_ops = stac_patch_ops; |
5829 | /* GPIO0 = EAPD */ | ||
5830 | spec->gpio_mask = 0x01; | ||
5831 | spec->gpio_dir = 0x01; | ||
5832 | spec->gpio_data = 0x01; | ||
5833 | } | ||
5834 | |||
5835 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
5836 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
5837 | 4024 | ||
5838 | spec->num_caps = STAC92HD71BXX_NUM_CAPS; | 4025 | /* GPIO0 = EAPD */ |
5839 | spec->capvols = stac92hd71bxx_capvols; | 4026 | spec->gpio_mask = 0x01; |
5840 | spec->capsws = stac92hd71bxx_capsws; | 4027 | spec->gpio_dir = 0x01; |
4028 | spec->gpio_data = 0x01; | ||
5841 | 4029 | ||
5842 | switch (codec->vendor_id) { | 4030 | switch (codec->vendor_id) { |
5843 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 4031 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
5844 | case 0x111d76b7: | 4032 | case 0x111d76b7: |
5845 | unmute_init++; | 4033 | unmute_init++; |
5846 | /* fallthru */ | ||
5847 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | ||
5848 | case 0x111d76b5: | ||
5849 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | ||
5850 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5851 | stac92hd71bxx_dmic_nids, | ||
5852 | STAC92HD71BXX_NUM_DMICS); | ||
5853 | break; | 4034 | break; |
5854 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 4035 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5855 | switch (spec->board_config) { | ||
5856 | case STAC_HP_M4: | ||
5857 | /* Enable VREF power saving on GPIO1 detect */ | ||
5858 | err = stac_add_event(codec, codec->afg, | ||
5859 | STAC_VREF_EVENT, 0x02); | ||
5860 | if (err < 0) | ||
5861 | return err; | ||
5862 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
5863 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); | ||
5864 | snd_hda_jack_detect_enable(codec, codec->afg, 0); | ||
5865 | spec->gpio_mask |= 0x02; | ||
5866 | break; | ||
5867 | } | ||
5868 | if ((codec->revision_id & 0xf) == 0 || | 4036 | if ((codec->revision_id & 0xf) == 0 || |
5869 | (codec->revision_id & 0xf) == 1) | 4037 | (codec->revision_id & 0xf) == 1) |
5870 | spec->stream_delay = 40; /* 40 milliseconds */ | 4038 | spec->stream_delay = 40; /* 40 milliseconds */ |
@@ -5873,158 +4041,45 @@ again: | |||
5873 | unmute_init++; | 4041 | unmute_init++; |
5874 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 4042 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
5875 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 4043 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
5876 | spec->dmic_nids = stac92hd71bxx_dmic_5port_nids; | ||
5877 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5878 | stac92hd71bxx_dmic_5port_nids, | ||
5879 | STAC92HD71BXX_NUM_DMICS - 1); | ||
5880 | break; | 4044 | break; |
5881 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 4045 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
5882 | if ((codec->revision_id & 0xf) == 1) | 4046 | if ((codec->revision_id & 0xf) == 1) |
5883 | spec->stream_delay = 40; /* 40 milliseconds */ | 4047 | spec->stream_delay = 40; /* 40 milliseconds */ |
5884 | 4048 | ||
5885 | /* fallthru */ | ||
5886 | default: | ||
5887 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | ||
5888 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5889 | stac92hd71bxx_dmic_nids, | ||
5890 | STAC92HD71BXX_NUM_DMICS); | ||
5891 | break; | 4049 | break; |
5892 | } | 4050 | } |
5893 | 4051 | ||
5894 | if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) | 4052 | if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) |
5895 | spec->init = stac92hd71bxx_core_init; | 4053 | snd_hda_add_verbs(codec, stac92hd71bxx_core_init); |
5896 | 4054 | ||
5897 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 4055 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
5898 | snd_hda_sequence_write_cache(codec, unmute_init); | 4056 | snd_hda_sequence_write_cache(codec, unmute_init); |
5899 | 4057 | ||
5900 | spec->aloopback_ctl = stac92hd71bxx_loopback; | 4058 | spec->aloopback_ctl = &stac92hd71bxx_loopback; |
5901 | spec->aloopback_mask = 0x50; | 4059 | spec->aloopback_mask = 0x50; |
5902 | spec->aloopback_shift = 0; | 4060 | spec->aloopback_shift = 0; |
5903 | 4061 | ||
5904 | spec->powerdown_adcs = 1; | 4062 | spec->powerdown_adcs = 1; |
5905 | spec->digbeep_nid = 0x26; | 4063 | spec->digbeep_nid = 0x26; |
5906 | spec->mux_nids = stac92hd71bxx_mux_nids; | 4064 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
5907 | spec->adc_nids = stac92hd71bxx_adc_nids; | ||
5908 | spec->smux_nids = stac92hd71bxx_smux_nids; | ||
5909 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 4065 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
5910 | 4066 | ||
5911 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 4067 | snd_hda_pick_fixup(codec, stac92hd71bxx_models, stac92hd71bxx_fixup_tbl, |
5912 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 4068 | stac92hd71bxx_fixups); |
5913 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 4069 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5914 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | ||
5915 | |||
5916 | snd_printdd("Found board config: %d\n", spec->board_config); | ||
5917 | |||
5918 | switch (spec->board_config) { | ||
5919 | case STAC_HP_M4: | ||
5920 | /* enable internal microphone */ | ||
5921 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); | ||
5922 | stac92xx_auto_set_pinctl(codec, 0x0e, | ||
5923 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | ||
5924 | /* fallthru */ | ||
5925 | case STAC_DELL_M4_2: | ||
5926 | spec->num_dmics = 0; | ||
5927 | spec->num_smuxes = 0; | ||
5928 | spec->num_dmuxes = 0; | ||
5929 | break; | ||
5930 | case STAC_DELL_M4_1: | ||
5931 | case STAC_DELL_M4_3: | ||
5932 | spec->num_dmics = 1; | ||
5933 | spec->num_smuxes = 0; | ||
5934 | spec->num_dmuxes = 1; | ||
5935 | break; | ||
5936 | case STAC_HP_DV4_1222NR: | ||
5937 | spec->num_dmics = 1; | ||
5938 | /* I don't know if it needs 1 or 2 smuxes - will wait for | ||
5939 | * bug reports to fix if needed | ||
5940 | */ | ||
5941 | spec->num_smuxes = 1; | ||
5942 | spec->num_dmuxes = 1; | ||
5943 | /* fallthrough */ | ||
5944 | case STAC_HP_DV4: | ||
5945 | spec->gpio_led = 0x01; | ||
5946 | /* fallthrough */ | ||
5947 | case STAC_HP_DV5: | ||
5948 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | ||
5949 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | ||
5950 | /* HP dv6 gives the headphone pin as a line-out. Thus we | ||
5951 | * need to set hp_detect flag here to force to enable HP | ||
5952 | * detection. | ||
5953 | */ | ||
5954 | spec->hp_detect = 1; | ||
5955 | break; | ||
5956 | case STAC_HP_HDX: | ||
5957 | spec->num_dmics = 1; | ||
5958 | spec->num_dmuxes = 1; | ||
5959 | spec->num_smuxes = 1; | ||
5960 | spec->gpio_led = 0x08; | ||
5961 | break; | ||
5962 | } | ||
5963 | 4070 | ||
5964 | if (hp_blike_system(codec->subsystem_id)) { | 4071 | stac_setup_gpio(codec); |
5965 | pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | ||
5966 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | ||
5967 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | ||
5968 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { | ||
5969 | /* It was changed in the BIOS to just satisfy MS DTM. | ||
5970 | * Lets turn it back into slaved HP | ||
5971 | */ | ||
5972 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | ||
5973 | | (AC_JACK_HP_OUT << | ||
5974 | AC_DEFCFG_DEVICE_SHIFT); | ||
5975 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | ||
5976 | | AC_DEFCFG_SEQUENCE))) | ||
5977 | | 0x1f; | ||
5978 | snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); | ||
5979 | } | ||
5980 | } | ||
5981 | |||
5982 | if (find_mute_led_cfg(codec, 1)) | ||
5983 | snd_printd("mute LED gpio %d polarity %d\n", | ||
5984 | spec->gpio_led, | ||
5985 | spec->gpio_led_polarity); | ||
5986 | |||
5987 | if (spec->gpio_led) { | ||
5988 | if (!spec->vref_mute_led_nid) { | ||
5989 | spec->gpio_mask |= spec->gpio_led; | ||
5990 | spec->gpio_dir |= spec->gpio_led; | ||
5991 | spec->gpio_data |= spec->gpio_led; | ||
5992 | } else { | ||
5993 | codec->patch_ops.set_power_state = | ||
5994 | stac92xx_set_power_state; | ||
5995 | } | ||
5996 | } | ||
5997 | |||
5998 | spec->multiout.dac_nids = spec->dac_nids; | ||
5999 | |||
6000 | err = stac92xx_parse_auto_config(codec); | ||
6001 | if (!err) { | ||
6002 | if (spec->board_config < 0) { | ||
6003 | printk(KERN_WARNING "hda_codec: No auto-config is " | ||
6004 | "available, default to model=ref\n"); | ||
6005 | spec->board_config = STAC_92HD71BXX_REF; | ||
6006 | goto again; | ||
6007 | } | ||
6008 | err = -EINVAL; | ||
6009 | } | ||
6010 | 4072 | ||
4073 | err = stac_parse_auto_config(codec); | ||
6011 | if (err < 0) { | 4074 | if (err < 0) { |
6012 | stac92xx_free(codec); | 4075 | stac_free(codec); |
6013 | return err; | 4076 | return err; |
6014 | } | 4077 | } |
6015 | 4078 | ||
6016 | /* enable bass on HP dv7 */ | ||
6017 | if (spec->board_config == STAC_HP_DV4 || | ||
6018 | spec->board_config == STAC_HP_DV5) { | ||
6019 | unsigned int cap; | ||
6020 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); | ||
6021 | cap &= AC_GPIO_IO_COUNT; | ||
6022 | if (cap >= 6) | ||
6023 | stac_add_hp_bass_switch(codec); | ||
6024 | } | ||
6025 | |||
6026 | codec->proc_widget_hook = stac92hd7x_proc_hook; | 4079 | codec->proc_widget_hook = stac92hd7x_proc_hook; |
6027 | 4080 | ||
4081 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
4082 | |||
6028 | return 0; | 4083 | return 0; |
6029 | } | 4084 | } |
6030 | 4085 | ||
@@ -6033,93 +4088,17 @@ static int patch_stac922x(struct hda_codec *codec) | |||
6033 | struct sigmatel_spec *spec; | 4088 | struct sigmatel_spec *spec; |
6034 | int err; | 4089 | int err; |
6035 | 4090 | ||
6036 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac922x_pin_nids), | 4091 | err = alloc_stac_spec(codec); |
6037 | stac922x_pin_nids); | ||
6038 | if (err < 0) | 4092 | if (err < 0) |
6039 | return err; | 4093 | return err; |
6040 | 4094 | ||
6041 | spec = codec->spec; | 4095 | spec = codec->spec; |
6042 | spec->linear_tone_beep = 1; | 4096 | spec->linear_tone_beep = 1; |
6043 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, | 4097 | spec->gen.own_eapd_ctl = 1; |
6044 | stac922x_models, | ||
6045 | stac922x_cfg_tbl); | ||
6046 | if (spec->board_config == STAC_INTEL_MAC_AUTO) { | ||
6047 | spec->gpio_mask = spec->gpio_dir = 0x03; | ||
6048 | spec->gpio_data = 0x03; | ||
6049 | /* Intel Macs have all same PCI SSID, so we need to check | ||
6050 | * codec SSID to distinguish the exact models | ||
6051 | */ | ||
6052 | printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); | ||
6053 | switch (codec->subsystem_id) { | ||
6054 | |||
6055 | case 0x106b0800: | ||
6056 | spec->board_config = STAC_INTEL_MAC_V1; | ||
6057 | break; | ||
6058 | case 0x106b0600: | ||
6059 | case 0x106b0700: | ||
6060 | spec->board_config = STAC_INTEL_MAC_V2; | ||
6061 | break; | ||
6062 | case 0x106b0e00: | ||
6063 | case 0x106b0f00: | ||
6064 | case 0x106b1600: | ||
6065 | case 0x106b1700: | ||
6066 | case 0x106b0200: | ||
6067 | case 0x106b1e00: | ||
6068 | spec->board_config = STAC_INTEL_MAC_V3; | ||
6069 | break; | ||
6070 | case 0x106b1a00: | ||
6071 | case 0x00000100: | ||
6072 | spec->board_config = STAC_INTEL_MAC_V4; | ||
6073 | break; | ||
6074 | case 0x106b0a00: | ||
6075 | case 0x106b2200: | ||
6076 | spec->board_config = STAC_INTEL_MAC_V5; | ||
6077 | break; | ||
6078 | default: | ||
6079 | spec->board_config = STAC_INTEL_MAC_V3; | ||
6080 | break; | ||
6081 | } | ||
6082 | } | ||
6083 | |||
6084 | again: | ||
6085 | if (spec->board_config < 0) | ||
6086 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
6087 | codec->chip_name); | ||
6088 | else | ||
6089 | stac92xx_set_config_regs(codec, | ||
6090 | stac922x_brd_tbl[spec->board_config]); | ||
6091 | |||
6092 | spec->adc_nids = stac922x_adc_nids; | ||
6093 | spec->mux_nids = stac922x_mux_nids; | ||
6094 | spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); | ||
6095 | spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids); | ||
6096 | spec->num_dmics = 0; | ||
6097 | spec->num_pwrs = 0; | ||
6098 | 4098 | ||
6099 | spec->init = stac922x_core_init; | 4099 | codec->patch_ops = stac_patch_ops; |
6100 | |||
6101 | spec->num_caps = STAC922X_NUM_CAPS; | ||
6102 | spec->capvols = stac922x_capvols; | ||
6103 | spec->capsws = stac922x_capsws; | ||
6104 | |||
6105 | spec->multiout.dac_nids = spec->dac_nids; | ||
6106 | |||
6107 | err = stac92xx_parse_auto_config(codec); | ||
6108 | if (!err) { | ||
6109 | if (spec->board_config < 0) { | ||
6110 | printk(KERN_WARNING "hda_codec: No auto-config is " | ||
6111 | "available, default to model=ref\n"); | ||
6112 | spec->board_config = STAC_D945_REF; | ||
6113 | goto again; | ||
6114 | } | ||
6115 | err = -EINVAL; | ||
6116 | } | ||
6117 | if (err < 0) { | ||
6118 | stac92xx_free(codec); | ||
6119 | return err; | ||
6120 | } | ||
6121 | 4100 | ||
6122 | codec->patch_ops = stac92xx_patch_ops; | 4101 | snd_hda_add_verbs(codec, stac922x_core_init); |
6123 | 4102 | ||
6124 | /* Fix Mux capture level; max to 2 */ | 4103 | /* Fix Mux capture level; max to 2 */ |
6125 | snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, | 4104 | snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, |
@@ -6128,122 +4107,67 @@ static int patch_stac922x(struct hda_codec *codec) | |||
6128 | (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 4107 | (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
6129 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 4108 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
6130 | 4109 | ||
4110 | snd_hda_pick_fixup(codec, stac922x_models, stac922x_fixup_tbl, | ||
4111 | stac922x_fixups); | ||
4112 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
4113 | |||
4114 | err = stac_parse_auto_config(codec); | ||
4115 | if (err < 0) { | ||
4116 | stac_free(codec); | ||
4117 | return err; | ||
4118 | } | ||
4119 | |||
4120 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
4121 | |||
6131 | return 0; | 4122 | return 0; |
6132 | } | 4123 | } |
6133 | 4124 | ||
4125 | static const char * const stac927x_spdif_labels[] = { | ||
4126 | "Digital Playback", "ADAT", "Analog Mux 1", | ||
4127 | "Analog Mux 2", "Analog Mux 3", NULL | ||
4128 | }; | ||
4129 | |||
6134 | static int patch_stac927x(struct hda_codec *codec) | 4130 | static int patch_stac927x(struct hda_codec *codec) |
6135 | { | 4131 | { |
6136 | struct sigmatel_spec *spec; | 4132 | struct sigmatel_spec *spec; |
6137 | int err; | 4133 | int err; |
6138 | 4134 | ||
6139 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac927x_pin_nids), | 4135 | err = alloc_stac_spec(codec); |
6140 | stac927x_pin_nids); | ||
6141 | if (err < 0) | 4136 | if (err < 0) |
6142 | return err; | 4137 | return err; |
6143 | 4138 | ||
6144 | spec = codec->spec; | 4139 | spec = codec->spec; |
6145 | spec->linear_tone_beep = 1; | 4140 | spec->linear_tone_beep = 1; |
6146 | codec->slave_dig_outs = stac927x_slave_dig_outs; | 4141 | spec->gen.own_eapd_ctl = 1; |
6147 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, | 4142 | spec->have_spdif_mux = 1; |
6148 | stac927x_models, | ||
6149 | stac927x_cfg_tbl); | ||
6150 | again: | ||
6151 | if (spec->board_config < 0) | ||
6152 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
6153 | codec->chip_name); | ||
6154 | else | ||
6155 | stac92xx_set_config_regs(codec, | ||
6156 | stac927x_brd_tbl[spec->board_config]); | ||
6157 | |||
6158 | spec->digbeep_nid = 0x23; | ||
6159 | spec->adc_nids = stac927x_adc_nids; | ||
6160 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); | ||
6161 | spec->mux_nids = stac927x_mux_nids; | ||
6162 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); | ||
6163 | spec->smux_nids = stac927x_smux_nids; | ||
6164 | spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); | ||
6165 | spec->spdif_labels = stac927x_spdif_labels; | 4143 | spec->spdif_labels = stac927x_spdif_labels; |
6166 | spec->dac_list = stac927x_dac_nids; | ||
6167 | spec->multiout.dac_nids = spec->dac_nids; | ||
6168 | |||
6169 | if (spec->board_config != STAC_D965_REF) { | ||
6170 | /* GPIO0 High = Enable EAPD */ | ||
6171 | spec->eapd_mask = spec->gpio_mask = 0x01; | ||
6172 | spec->gpio_dir = spec->gpio_data = 0x01; | ||
6173 | } | ||
6174 | 4144 | ||
6175 | switch (spec->board_config) { | 4145 | spec->digbeep_nid = 0x23; |
6176 | case STAC_D965_3ST: | ||
6177 | case STAC_D965_5ST: | ||
6178 | /* GPIO0 High = Enable EAPD */ | ||
6179 | spec->num_dmics = 0; | ||
6180 | spec->init = d965_core_init; | ||
6181 | break; | ||
6182 | case STAC_DELL_BIOS: | ||
6183 | switch (codec->subsystem_id) { | ||
6184 | case 0x10280209: | ||
6185 | case 0x1028022e: | ||
6186 | /* correct the device field to SPDIF out */ | ||
6187 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); | ||
6188 | break; | ||
6189 | } | ||
6190 | /* configure the analog microphone on some laptops */ | ||
6191 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); | ||
6192 | /* correct the front output jack as a hp out */ | ||
6193 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x0227011f); | ||
6194 | /* correct the front input jack as a mic */ | ||
6195 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130); | ||
6196 | /* fallthru */ | ||
6197 | case STAC_DELL_3ST: | ||
6198 | if (codec->subsystem_id != 0x1028022f) { | ||
6199 | /* GPIO2 High = Enable EAPD */ | ||
6200 | spec->eapd_mask = spec->gpio_mask = 0x04; | ||
6201 | spec->gpio_dir = spec->gpio_data = 0x04; | ||
6202 | } | ||
6203 | spec->dmic_nids = stac927x_dmic_nids; | ||
6204 | spec->num_dmics = STAC927X_NUM_DMICS; | ||
6205 | |||
6206 | spec->init = dell_3st_core_init; | ||
6207 | spec->dmux_nids = stac927x_dmux_nids; | ||
6208 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); | ||
6209 | break; | ||
6210 | case STAC_927X_VOLKNOB: | ||
6211 | spec->num_dmics = 0; | ||
6212 | spec->init = stac927x_volknob_core_init; | ||
6213 | break; | ||
6214 | default: | ||
6215 | spec->num_dmics = 0; | ||
6216 | spec->init = stac927x_core_init; | ||
6217 | break; | ||
6218 | } | ||
6219 | 4146 | ||
6220 | spec->num_caps = STAC927X_NUM_CAPS; | 4147 | /* GPIO0 High = Enable EAPD */ |
6221 | spec->capvols = stac927x_capvols; | 4148 | spec->eapd_mask = spec->gpio_mask = 0x01; |
6222 | spec->capsws = stac927x_capsws; | 4149 | spec->gpio_dir = spec->gpio_data = 0x01; |
6223 | 4150 | ||
6224 | spec->num_pwrs = 0; | 4151 | spec->aloopback_ctl = &stac927x_loopback; |
6225 | spec->aloopback_ctl = stac927x_loopback; | ||
6226 | spec->aloopback_mask = 0x40; | 4152 | spec->aloopback_mask = 0x40; |
6227 | spec->aloopback_shift = 0; | 4153 | spec->aloopback_shift = 0; |
6228 | spec->eapd_switch = 1; | 4154 | spec->eapd_switch = 1; |
6229 | 4155 | ||
6230 | err = stac92xx_parse_auto_config(codec); | 4156 | codec->patch_ops = stac_patch_ops; |
6231 | if (!err) { | 4157 | |
6232 | if (spec->board_config < 0) { | 4158 | snd_hda_pick_fixup(codec, stac927x_models, stac927x_fixup_tbl, |
6233 | printk(KERN_WARNING "hda_codec: No auto-config is " | 4159 | stac927x_fixups); |
6234 | "available, default to model=ref\n"); | 4160 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6235 | spec->board_config = STAC_D965_REF; | 4161 | |
6236 | goto again; | 4162 | if (!spec->volknob_init) |
6237 | } | 4163 | snd_hda_add_verbs(codec, stac927x_core_init); |
6238 | err = -EINVAL; | 4164 | |
6239 | } | 4165 | err = stac_parse_auto_config(codec); |
6240 | if (err < 0) { | 4166 | if (err < 0) { |
6241 | stac92xx_free(codec); | 4167 | stac_free(codec); |
6242 | return err; | 4168 | return err; |
6243 | } | 4169 | } |
6244 | 4170 | ||
6245 | codec->patch_ops = stac92xx_patch_ops; | ||
6246 | |||
6247 | codec->proc_widget_hook = stac927x_proc_hook; | 4171 | codec->proc_widget_hook = stac927x_proc_hook; |
6248 | 4172 | ||
6249 | /* | 4173 | /* |
@@ -6258,9 +4182,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
6258 | */ | 4182 | */ |
6259 | codec->bus->needs_damn_long_delay = 1; | 4183 | codec->bus->needs_damn_long_delay = 1; |
6260 | 4184 | ||
6261 | /* no jack detecion for ref-no-jd model */ | 4185 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
6262 | if (spec->board_config == STAC_D965_REF_NO_JD) | ||
6263 | spec->hp_detect = 0; | ||
6264 | 4186 | ||
6265 | return 0; | 4187 | return 0; |
6266 | } | 4188 | } |
@@ -6270,103 +4192,46 @@ static int patch_stac9205(struct hda_codec *codec) | |||
6270 | struct sigmatel_spec *spec; | 4192 | struct sigmatel_spec *spec; |
6271 | int err; | 4193 | int err; |
6272 | 4194 | ||
6273 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac9205_pin_nids), | 4195 | err = alloc_stac_spec(codec); |
6274 | stac9205_pin_nids); | ||
6275 | if (err < 0) | 4196 | if (err < 0) |
6276 | return err; | 4197 | return err; |
6277 | 4198 | ||
6278 | spec = codec->spec; | 4199 | spec = codec->spec; |
6279 | spec->linear_tone_beep = 1; | 4200 | spec->linear_tone_beep = 1; |
6280 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, | 4201 | spec->gen.own_eapd_ctl = 1; |
6281 | stac9205_models, | 4202 | spec->have_spdif_mux = 1; |
6282 | stac9205_cfg_tbl); | ||
6283 | again: | ||
6284 | if (spec->board_config < 0) | ||
6285 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
6286 | codec->chip_name); | ||
6287 | else | ||
6288 | stac92xx_set_config_regs(codec, | ||
6289 | stac9205_brd_tbl[spec->board_config]); | ||
6290 | 4203 | ||
6291 | spec->digbeep_nid = 0x23; | 4204 | spec->digbeep_nid = 0x23; |
6292 | spec->adc_nids = stac9205_adc_nids; | 4205 | |
6293 | spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); | 4206 | snd_hda_add_verbs(codec, stac9205_core_init); |
6294 | spec->mux_nids = stac9205_mux_nids; | 4207 | spec->aloopback_ctl = &stac9205_loopback; |
6295 | spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); | ||
6296 | spec->smux_nids = stac9205_smux_nids; | ||
6297 | spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids); | ||
6298 | spec->dmic_nids = stac9205_dmic_nids; | ||
6299 | spec->num_dmics = STAC9205_NUM_DMICS; | ||
6300 | spec->dmux_nids = stac9205_dmux_nids; | ||
6301 | spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids); | ||
6302 | spec->num_pwrs = 0; | ||
6303 | |||
6304 | spec->init = stac9205_core_init; | ||
6305 | spec->aloopback_ctl = stac9205_loopback; | ||
6306 | |||
6307 | spec->num_caps = STAC9205_NUM_CAPS; | ||
6308 | spec->capvols = stac9205_capvols; | ||
6309 | spec->capsws = stac9205_capsws; | ||
6310 | 4208 | ||
6311 | spec->aloopback_mask = 0x40; | 4209 | spec->aloopback_mask = 0x40; |
6312 | spec->aloopback_shift = 0; | 4210 | spec->aloopback_shift = 0; |
6313 | /* Turn on/off EAPD per HP plugging */ | ||
6314 | if (spec->board_config != STAC_9205_EAPD) | ||
6315 | spec->eapd_switch = 1; | ||
6316 | spec->multiout.dac_nids = spec->dac_nids; | ||
6317 | 4211 | ||
6318 | switch (spec->board_config){ | 4212 | /* GPIO0 High = EAPD */ |
6319 | case STAC_9205_DELL_M43: | 4213 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
6320 | /* Enable SPDIF in/out */ | 4214 | spec->gpio_data = 0x01; |
6321 | snd_hda_codec_set_pincfg(codec, 0x1f, 0x01441030); | ||
6322 | snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); | ||
6323 | 4215 | ||
6324 | /* Enable unsol response for GPIO4/Dock HP connection */ | 4216 | /* Turn on/off EAPD per HP plugging */ |
6325 | err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01); | 4217 | spec->eapd_switch = 1; |
6326 | if (err < 0) | ||
6327 | return err; | ||
6328 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
6329 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); | ||
6330 | snd_hda_jack_detect_enable(codec, codec->afg, 0); | ||
6331 | 4218 | ||
6332 | spec->gpio_dir = 0x0b; | 4219 | codec->patch_ops = stac_patch_ops; |
6333 | spec->eapd_mask = 0x01; | ||
6334 | spec->gpio_mask = 0x1b; | ||
6335 | spec->gpio_mute = 0x10; | ||
6336 | /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, | ||
6337 | * GPIO3 Low = DRM | ||
6338 | */ | ||
6339 | spec->gpio_data = 0x01; | ||
6340 | break; | ||
6341 | case STAC_9205_REF: | ||
6342 | /* SPDIF-In enabled */ | ||
6343 | break; | ||
6344 | default: | ||
6345 | /* GPIO0 High = EAPD */ | ||
6346 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | ||
6347 | spec->gpio_data = 0x01; | ||
6348 | break; | ||
6349 | } | ||
6350 | 4220 | ||
6351 | err = stac92xx_parse_auto_config(codec); | 4221 | snd_hda_pick_fixup(codec, stac9205_models, stac9205_fixup_tbl, |
6352 | if (!err) { | 4222 | stac9205_fixups); |
6353 | if (spec->board_config < 0) { | 4223 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6354 | printk(KERN_WARNING "hda_codec: No auto-config is " | 4224 | |
6355 | "available, default to model=ref\n"); | 4225 | err = stac_parse_auto_config(codec); |
6356 | spec->board_config = STAC_9205_REF; | ||
6357 | goto again; | ||
6358 | } | ||
6359 | err = -EINVAL; | ||
6360 | } | ||
6361 | if (err < 0) { | 4226 | if (err < 0) { |
6362 | stac92xx_free(codec); | 4227 | stac_free(codec); |
6363 | return err; | 4228 | return err; |
6364 | } | 4229 | } |
6365 | 4230 | ||
6366 | codec->patch_ops = stac92xx_patch_ops; | ||
6367 | |||
6368 | codec->proc_widget_hook = stac9205_proc_hook; | 4231 | codec->proc_widget_hook = stac9205_proc_hook; |
6369 | 4232 | ||
4233 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | ||
4234 | |||
6370 | return 0; | 4235 | return 0; |
6371 | } | 4236 | } |
6372 | 4237 | ||
@@ -6380,40 +4245,32 @@ static const struct hda_verb stac9872_core_init[] = { | |||
6380 | {} | 4245 | {} |
6381 | }; | 4246 | }; |
6382 | 4247 | ||
6383 | static const hda_nid_t stac9872_pin_nids[] = { | 4248 | static const struct hda_pintbl stac9872_vaio_pin_configs[] = { |
6384 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | 4249 | { 0x0a, 0x03211020 }, |
6385 | 0x11, 0x13, 0x14, | 4250 | { 0x0b, 0x411111f0 }, |
6386 | }; | 4251 | { 0x0c, 0x411111f0 }, |
6387 | 4252 | { 0x0d, 0x03a15030 }, | |
6388 | static const hda_nid_t stac9872_adc_nids[] = { | 4253 | { 0x0e, 0x411111f0 }, |
6389 | 0x8 /*,0x6*/ | 4254 | { 0x0f, 0x90170110 }, |
6390 | }; | 4255 | { 0x11, 0x411111f0 }, |
6391 | 4256 | { 0x13, 0x411111f0 }, | |
6392 | static const hda_nid_t stac9872_mux_nids[] = { | 4257 | { 0x14, 0x90a7013e }, |
6393 | 0x15 | 4258 | {} |
6394 | }; | ||
6395 | |||
6396 | static const unsigned long stac9872_capvols[] = { | ||
6397 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
6398 | }; | ||
6399 | #define stac9872_capsws stac9872_capvols | ||
6400 | |||
6401 | static const unsigned int stac9872_vaio_pin_configs[9] = { | ||
6402 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, | ||
6403 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, | ||
6404 | 0x90a7013e | ||
6405 | }; | 4259 | }; |
6406 | 4260 | ||
6407 | static const char * const stac9872_models[STAC_9872_MODELS] = { | 4261 | static const struct hda_model_fixup stac9872_models[] = { |
6408 | [STAC_9872_AUTO] = "auto", | 4262 | { .id = STAC_9872_VAIO, .name = "vaio" }, |
6409 | [STAC_9872_VAIO] = "vaio", | 4263 | {} |
6410 | }; | 4264 | }; |
6411 | 4265 | ||
6412 | static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | 4266 | static const struct hda_fixup stac9872_fixups[] = { |
6413 | [STAC_9872_VAIO] = stac9872_vaio_pin_configs, | 4267 | [STAC_9872_VAIO] = { |
4268 | .type = HDA_FIXUP_PINS, | ||
4269 | .v.pins = stac9872_vaio_pin_configs, | ||
4270 | }, | ||
6414 | }; | 4271 | }; |
6415 | 4272 | ||
6416 | static const struct snd_pci_quirk stac9872_cfg_tbl[] = { | 4273 | static const struct snd_pci_quirk stac9872_fixup_tbl[] = { |
6417 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, | 4274 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, |
6418 | "Sony VAIO F/S", STAC_9872_VAIO), | 4275 | "Sony VAIO F/S", STAC_9872_VAIO), |
6419 | {} /* terminator */ | 4276 | {} /* terminator */ |
@@ -6424,41 +4281,30 @@ static int patch_stac9872(struct hda_codec *codec) | |||
6424 | struct sigmatel_spec *spec; | 4281 | struct sigmatel_spec *spec; |
6425 | int err; | 4282 | int err; |
6426 | 4283 | ||
6427 | err = alloc_stac_spec(codec, ARRAY_SIZE(stac9872_pin_nids), | 4284 | err = alloc_stac_spec(codec); |
6428 | stac9872_pin_nids); | ||
6429 | if (err < 0) | 4285 | if (err < 0) |
6430 | return err; | 4286 | return err; |
6431 | 4287 | ||
6432 | spec = codec->spec; | 4288 | spec = codec->spec; |
6433 | spec->linear_tone_beep = 1; | 4289 | spec->linear_tone_beep = 1; |
4290 | spec->gen.own_eapd_ctl = 1; | ||
6434 | 4291 | ||
6435 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | 4292 | codec->patch_ops = stac_patch_ops; |
6436 | stac9872_models, | 4293 | |
6437 | stac9872_cfg_tbl); | 4294 | snd_hda_add_verbs(codec, stac9872_core_init); |
6438 | if (spec->board_config < 0) | 4295 | |
6439 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | 4296 | snd_hda_pick_fixup(codec, stac9872_models, stac9872_fixup_tbl, |
6440 | codec->chip_name); | 4297 | stac9872_fixups); |
6441 | else | 4298 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
6442 | stac92xx_set_config_regs(codec, | 4299 | |
6443 | stac9872_brd_tbl[spec->board_config]); | 4300 | err = stac_parse_auto_config(codec); |
6444 | |||
6445 | spec->multiout.dac_nids = spec->dac_nids; | ||
6446 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | ||
6447 | spec->adc_nids = stac9872_adc_nids; | ||
6448 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | ||
6449 | spec->mux_nids = stac9872_mux_nids; | ||
6450 | spec->init = stac9872_core_init; | ||
6451 | spec->num_caps = 1; | ||
6452 | spec->capvols = stac9872_capvols; | ||
6453 | spec->capsws = stac9872_capsws; | ||
6454 | |||
6455 | err = stac92xx_parse_auto_config(codec); | ||
6456 | if (err < 0) { | 4301 | if (err < 0) { |
6457 | stac92xx_free(codec); | 4302 | stac_free(codec); |
6458 | return -EINVAL; | 4303 | return -EINVAL; |
6459 | } | 4304 | } |
6460 | spec->input_mux = &spec->private_imux; | 4305 | |
6461 | codec->patch_ops = stac92xx_patch_ops; | 4306 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4307 | |||
6462 | return 0; | 4308 | return 0; |
6463 | } | 4309 | } |
6464 | 4310 | ||
@@ -6529,6 +4375,7 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
6529 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 4375 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
6530 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 4376 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |
6531 | { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, | 4377 | { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, |
4378 | { .id = 0x111d7695, .name = "92HD95", .patch = patch_stac92hd95 }, | ||
6532 | { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, | 4379 | { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, |
6533 | { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, | 4380 | { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, |
6534 | { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, | 4381 | { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 09bb64996d72..ca7d962a08a6 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "hda_local.h" | 56 | #include "hda_local.h" |
57 | #include "hda_auto_parser.h" | 57 | #include "hda_auto_parser.h" |
58 | #include "hda_jack.h" | 58 | #include "hda_jack.h" |
59 | #include "hda_generic.h" | ||
59 | 60 | ||
60 | /* Pin Widget NID */ | 61 | /* Pin Widget NID */ |
61 | #define VT1708_HP_PIN_NID 0x20 | 62 | #define VT1708_HP_PIN_NID 0x20 |
@@ -86,39 +87,6 @@ enum VIA_HDA_CODEC { | |||
86 | (spec)->codec_type == VT1812 ||\ | 87 | (spec)->codec_type == VT1812 ||\ |
87 | (spec)->codec_type == VT1802) | 88 | (spec)->codec_type == VT1802) |
88 | 89 | ||
89 | #define MAX_NID_PATH_DEPTH 5 | ||
90 | |||
91 | /* output-path: DAC -> ... -> pin | ||
92 | * idx[] contains the source index number of the next widget; | ||
93 | * e.g. idx[0] is the index of the DAC selected by path[1] widget | ||
94 | * multi[] indicates whether it's a selector widget with multi-connectors | ||
95 | * (i.e. the connection selection is mandatory) | ||
96 | * vol_ctl and mute_ctl contains the NIDs for the assigned mixers | ||
97 | */ | ||
98 | struct nid_path { | ||
99 | int depth; | ||
100 | hda_nid_t path[MAX_NID_PATH_DEPTH]; | ||
101 | unsigned char idx[MAX_NID_PATH_DEPTH]; | ||
102 | unsigned char multi[MAX_NID_PATH_DEPTH]; | ||
103 | unsigned int vol_ctl; | ||
104 | unsigned int mute_ctl; | ||
105 | }; | ||
106 | |||
107 | /* input-path */ | ||
108 | struct via_input { | ||
109 | hda_nid_t pin; /* input-pin or aa-mix */ | ||
110 | int adc_idx; /* ADC index to be used */ | ||
111 | int mux_idx; /* MUX index (if any) */ | ||
112 | const char *label; /* input-source label */ | ||
113 | }; | ||
114 | |||
115 | #define VIA_MAX_ADCS 3 | ||
116 | |||
117 | enum { | ||
118 | STREAM_MULTI_OUT = (1 << 0), | ||
119 | STREAM_INDEP_HP = (1 << 1), | ||
120 | }; | ||
121 | |||
122 | struct via_spec { | 90 | struct via_spec { |
123 | struct hda_gen_spec gen; | 91 | struct hda_gen_spec gen; |
124 | 92 | ||
@@ -129,77 +97,7 @@ struct via_spec { | |||
129 | const struct hda_verb *init_verbs[5]; | 97 | const struct hda_verb *init_verbs[5]; |
130 | unsigned int num_iverbs; | 98 | unsigned int num_iverbs; |
131 | 99 | ||
132 | char stream_name_analog[32]; | ||
133 | char stream_name_hp[32]; | ||
134 | const struct hda_pcm_stream *stream_analog_playback; | ||
135 | const struct hda_pcm_stream *stream_analog_capture; | ||
136 | |||
137 | char stream_name_digital[32]; | ||
138 | const struct hda_pcm_stream *stream_digital_playback; | ||
139 | const struct hda_pcm_stream *stream_digital_capture; | ||
140 | |||
141 | /* playback */ | ||
142 | struct hda_multi_out multiout; | ||
143 | hda_nid_t slave_dig_outs[2]; | ||
144 | hda_nid_t hp_dac_nid; | ||
145 | hda_nid_t speaker_dac_nid; | ||
146 | int hp_indep_shared; /* indep HP-DAC is shared with side ch */ | ||
147 | int opened_streams; /* STREAM_* bits */ | ||
148 | int active_streams; /* STREAM_* bits */ | ||
149 | int aamix_mode; /* loopback is enabled for output-path? */ | ||
150 | |||
151 | /* Output-paths: | ||
152 | * There are different output-paths depending on the setup. | ||
153 | * out_path, hp_path and speaker_path are primary paths. If both | ||
154 | * direct DAC and aa-loopback routes are available, these contain | ||
155 | * the former paths. Meanwhile *_mix_path contain the paths with | ||
156 | * loopback mixer. (Since the loopback is only for front channel, | ||
157 | * no out_mix_path for surround channels.) | ||
158 | * The HP output has another path, hp_indep_path, which is used in | ||
159 | * the independent-HP mode. | ||
160 | */ | ||
161 | struct nid_path out_path[HDA_SIDE + 1]; | ||
162 | struct nid_path out_mix_path; | ||
163 | struct nid_path hp_path; | ||
164 | struct nid_path hp_mix_path; | ||
165 | struct nid_path hp_indep_path; | ||
166 | struct nid_path speaker_path; | ||
167 | struct nid_path speaker_mix_path; | ||
168 | |||
169 | /* capture */ | ||
170 | unsigned int num_adc_nids; | ||
171 | hda_nid_t adc_nids[VIA_MAX_ADCS]; | ||
172 | hda_nid_t mux_nids[VIA_MAX_ADCS]; | ||
173 | hda_nid_t aa_mix_nid; | ||
174 | hda_nid_t dig_in_nid; | ||
175 | |||
176 | /* capture source */ | ||
177 | bool dyn_adc_switch; | ||
178 | int num_inputs; | ||
179 | struct via_input inputs[AUTO_CFG_MAX_INS + 1]; | ||
180 | unsigned int cur_mux[VIA_MAX_ADCS]; | ||
181 | |||
182 | /* dynamic DAC switching */ | ||
183 | unsigned int cur_dac_stream_tag; | ||
184 | unsigned int cur_dac_format; | ||
185 | unsigned int cur_hp_stream_tag; | ||
186 | unsigned int cur_hp_format; | ||
187 | |||
188 | /* dynamic ADC switching */ | ||
189 | hda_nid_t cur_adc; | ||
190 | unsigned int cur_adc_stream_tag; | ||
191 | unsigned int cur_adc_format; | ||
192 | |||
193 | /* PCM information */ | ||
194 | struct hda_pcm pcm_rec[3]; | ||
195 | |||
196 | /* dynamic controls, init_verbs and input_mux */ | ||
197 | struct auto_pin_cfg autocfg; | ||
198 | struct snd_array kctls; | ||
199 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | ||
200 | |||
201 | /* HP mode source */ | 100 | /* HP mode source */ |
202 | unsigned int hp_independent_mode; | ||
203 | unsigned int dmic_enabled; | 101 | unsigned int dmic_enabled; |
204 | unsigned int no_pin_power_ctl; | 102 | unsigned int no_pin_power_ctl; |
205 | enum VIA_HDA_CODEC codec_type; | 103 | enum VIA_HDA_CODEC codec_type; |
@@ -207,36 +105,22 @@ struct via_spec { | |||
207 | /* analog low-power control */ | 105 | /* analog low-power control */ |
208 | bool alc_mode; | 106 | bool alc_mode; |
209 | 107 | ||
210 | /* smart51 setup */ | ||
211 | unsigned int smart51_nums; | ||
212 | hda_nid_t smart51_pins[2]; | ||
213 | int smart51_idxs[2]; | ||
214 | const char *smart51_labels[2]; | ||
215 | unsigned int smart51_enabled; | ||
216 | |||
217 | /* work to check hp jack state */ | 108 | /* work to check hp jack state */ |
218 | struct hda_codec *codec; | ||
219 | struct delayed_work vt1708_hp_work; | ||
220 | int hp_work_active; | 109 | int hp_work_active; |
221 | int vt1708_jack_detect; | 110 | int vt1708_jack_detect; |
222 | int vt1708_hp_present; | ||
223 | 111 | ||
224 | void (*set_widgets_power_state)(struct hda_codec *codec); | 112 | void (*set_widgets_power_state)(struct hda_codec *codec); |
225 | unsigned int dac_stream_tag[4]; | 113 | unsigned int dac_stream_tag[4]; |
226 | |||
227 | struct hda_loopback_check loopback; | ||
228 | int num_loopbacks; | ||
229 | struct hda_amp_list loopback_list[8]; | ||
230 | |||
231 | /* bind capture-volume */ | ||
232 | struct hda_bind_ctls *bind_cap_vol; | ||
233 | struct hda_bind_ctls *bind_cap_sw; | ||
234 | |||
235 | struct mutex config_mutex; | ||
236 | }; | 114 | }; |
237 | 115 | ||
238 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); | 116 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); |
239 | static struct via_spec * via_new_spec(struct hda_codec *codec) | 117 | static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo, |
118 | struct hda_codec *codec, | ||
119 | struct snd_pcm_substream *substream, | ||
120 | int action); | ||
121 | static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl); | ||
122 | |||
123 | static struct via_spec *via_new_spec(struct hda_codec *codec) | ||
240 | { | 124 | { |
241 | struct via_spec *spec; | 125 | struct via_spec *spec; |
242 | 126 | ||
@@ -244,15 +128,15 @@ static struct via_spec * via_new_spec(struct hda_codec *codec) | |||
244 | if (spec == NULL) | 128 | if (spec == NULL) |
245 | return NULL; | 129 | return NULL; |
246 | 130 | ||
247 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | ||
248 | mutex_init(&spec->config_mutex); | ||
249 | codec->spec = spec; | 131 | codec->spec = spec; |
250 | spec->codec = codec; | 132 | snd_hda_gen_spec_init(&spec->gen); |
251 | spec->codec_type = get_codec_type(codec); | 133 | spec->codec_type = get_codec_type(codec); |
252 | /* VT1708BCE & VT1708S are almost same */ | 134 | /* VT1708BCE & VT1708S are almost same */ |
253 | if (spec->codec_type == VT1708BCE) | 135 | if (spec->codec_type == VT1708BCE) |
254 | spec->codec_type = VT1708S; | 136 | spec->codec_type = VT1708S; |
255 | snd_hda_gen_init(&spec->gen); | 137 | spec->no_pin_power_ctl = 1; |
138 | spec->gen.indep_hp = 1; | ||
139 | spec->gen.pcm_playback_hook = via_playback_pcm_hook; | ||
256 | return spec; | 140 | return spec; |
257 | } | 141 | } |
258 | 142 | ||
@@ -308,16 +192,6 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | |||
308 | return codec_type; | 192 | return codec_type; |
309 | }; | 193 | }; |
310 | 194 | ||
311 | #define VIA_JACK_EVENT 0x20 | ||
312 | #define VIA_HP_EVENT 0x01 | ||
313 | #define VIA_LINE_EVENT 0x03 | ||
314 | |||
315 | enum { | ||
316 | VIA_CTL_WIDGET_VOL, | ||
317 | VIA_CTL_WIDGET_MUTE, | ||
318 | VIA_CTL_WIDGET_ANALOG_MUTE, | ||
319 | }; | ||
320 | |||
321 | static void analog_low_current_mode(struct hda_codec *codec); | 195 | static void analog_low_current_mode(struct hda_codec *codec); |
322 | static bool is_aa_path_mute(struct hda_codec *codec); | 196 | static bool is_aa_path_mute(struct hda_codec *codec); |
323 | 197 | ||
@@ -325,31 +199,34 @@ static bool is_aa_path_mute(struct hda_codec *codec); | |||
325 | (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ | 199 | (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ |
326 | !is_aa_path_mute(codec)) | 200 | !is_aa_path_mute(codec)) |
327 | 201 | ||
328 | static void vt1708_stop_hp_work(struct via_spec *spec) | 202 | static void vt1708_stop_hp_work(struct hda_codec *codec) |
329 | { | 203 | { |
330 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) | 204 | struct via_spec *spec = codec->spec; |
205 | if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs) | ||
331 | return; | 206 | return; |
332 | if (spec->hp_work_active) { | 207 | if (spec->hp_work_active) { |
333 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1); | 208 | snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); |
334 | cancel_delayed_work_sync(&spec->vt1708_hp_work); | 209 | cancel_delayed_work_sync(&codec->jackpoll_work); |
335 | spec->hp_work_active = 0; | 210 | spec->hp_work_active = false; |
211 | codec->jackpoll_interval = 0; | ||
336 | } | 212 | } |
337 | } | 213 | } |
338 | 214 | ||
339 | static void vt1708_update_hp_work(struct via_spec *spec) | 215 | static void vt1708_update_hp_work(struct hda_codec *codec) |
340 | { | 216 | { |
341 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) | 217 | struct via_spec *spec = codec->spec; |
218 | if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs) | ||
342 | return; | 219 | return; |
343 | if (spec->vt1708_jack_detect && | 220 | if (spec->vt1708_jack_detect) { |
344 | (spec->active_streams || hp_detect_with_aa(spec->codec))) { | ||
345 | if (!spec->hp_work_active) { | 221 | if (!spec->hp_work_active) { |
346 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0); | 222 | codec->jackpoll_interval = msecs_to_jiffies(100); |
347 | schedule_delayed_work(&spec->vt1708_hp_work, | 223 | snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0); |
348 | msecs_to_jiffies(100)); | 224 | queue_delayed_work(codec->bus->workq, |
349 | spec->hp_work_active = 1; | 225 | &codec->jackpoll_work, 0); |
226 | spec->hp_work_active = true; | ||
350 | } | 227 | } |
351 | } else if (!hp_detect_with_aa(spec->codec)) | 228 | } else if (!hp_detect_with_aa(codec)) |
352 | vt1708_stop_hp_work(spec); | 229 | vt1708_stop_hp_work(codec); |
353 | } | 230 | } |
354 | 231 | ||
355 | static void set_widgets_power_state(struct hda_codec *codec) | 232 | static void set_widgets_power_state(struct hda_codec *codec) |
@@ -359,361 +236,10 @@ static void set_widgets_power_state(struct hda_codec *codec) | |||
359 | spec->set_widgets_power_state(codec); | 236 | spec->set_widgets_power_state(codec); |
360 | } | 237 | } |
361 | 238 | ||
362 | static int analog_input_switch_put(struct snd_kcontrol *kcontrol, | ||
363 | struct snd_ctl_elem_value *ucontrol) | ||
364 | { | ||
365 | int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
366 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
367 | |||
368 | set_widgets_power_state(codec); | ||
369 | analog_low_current_mode(snd_kcontrol_chip(kcontrol)); | ||
370 | vt1708_update_hp_work(codec->spec); | ||
371 | return change; | ||
372 | } | ||
373 | |||
374 | /* modify .put = snd_hda_mixer_amp_switch_put */ | ||
375 | #define ANALOG_INPUT_MUTE \ | ||
376 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
377 | .name = NULL, \ | ||
378 | .index = 0, \ | ||
379 | .info = snd_hda_mixer_amp_switch_info, \ | ||
380 | .get = snd_hda_mixer_amp_switch_get, \ | ||
381 | .put = analog_input_switch_put, \ | ||
382 | .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } | ||
383 | |||
384 | static const struct snd_kcontrol_new via_control_templates[] = { | ||
385 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
386 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
387 | ANALOG_INPUT_MUTE, | ||
388 | }; | ||
389 | |||
390 | |||
391 | /* add dynamic controls */ | ||
392 | static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec, | ||
393 | const struct snd_kcontrol_new *tmpl, | ||
394 | const char *name) | ||
395 | { | ||
396 | struct snd_kcontrol_new *knew; | ||
397 | |||
398 | knew = snd_array_new(&spec->kctls); | ||
399 | if (!knew) | ||
400 | return NULL; | ||
401 | *knew = *tmpl; | ||
402 | if (!name) | ||
403 | name = tmpl->name; | ||
404 | if (name) { | ||
405 | knew->name = kstrdup(name, GFP_KERNEL); | ||
406 | if (!knew->name) | ||
407 | return NULL; | ||
408 | } | ||
409 | return knew; | ||
410 | } | ||
411 | |||
412 | static int __via_add_control(struct via_spec *spec, int type, const char *name, | ||
413 | int idx, unsigned long val) | ||
414 | { | ||
415 | struct snd_kcontrol_new *knew; | ||
416 | |||
417 | knew = __via_clone_ctl(spec, &via_control_templates[type], name); | ||
418 | if (!knew) | ||
419 | return -ENOMEM; | ||
420 | knew->index = idx; | ||
421 | if (get_amp_nid_(val)) | ||
422 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
423 | knew->private_value = val; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | #define via_add_control(spec, type, name, val) \ | ||
428 | __via_add_control(spec, type, name, 0, val) | ||
429 | |||
430 | #define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL) | ||
431 | |||
432 | static void via_free_kctls(struct hda_codec *codec) | ||
433 | { | ||
434 | struct via_spec *spec = codec->spec; | ||
435 | |||
436 | if (spec->kctls.list) { | ||
437 | struct snd_kcontrol_new *kctl = spec->kctls.list; | ||
438 | int i; | ||
439 | for (i = 0; i < spec->kctls.used; i++) | ||
440 | kfree(kctl[i].name); | ||
441 | } | ||
442 | snd_array_free(&spec->kctls); | ||
443 | } | ||
444 | |||
445 | /* create input playback/capture controls for the given pin */ | ||
446 | static int via_new_analog_input(struct via_spec *spec, const char *ctlname, | ||
447 | int type_idx, int idx, int mix_nid) | ||
448 | { | ||
449 | char name[32]; | ||
450 | int err; | ||
451 | |||
452 | sprintf(name, "%s Playback Volume", ctlname); | ||
453 | err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx, | ||
454 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | ||
455 | if (err < 0) | ||
456 | return err; | ||
457 | sprintf(name, "%s Playback Switch", ctlname); | ||
458 | err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx, | ||
459 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | ||
460 | if (err < 0) | ||
461 | return err; | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | #define get_connection_index(codec, mux, nid) \ | ||
466 | snd_hda_get_conn_index(codec, mux, nid, 0) | ||
467 | |||
468 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | ||
469 | unsigned int mask) | ||
470 | { | ||
471 | unsigned int caps; | ||
472 | if (!nid) | ||
473 | return false; | ||
474 | caps = get_wcaps(codec, nid); | ||
475 | if (dir == HDA_INPUT) | ||
476 | caps &= AC_WCAP_IN_AMP; | ||
477 | else | ||
478 | caps &= AC_WCAP_OUT_AMP; | ||
479 | if (!caps) | ||
480 | return false; | ||
481 | if (query_amp_caps(codec, nid, dir) & mask) | ||
482 | return true; | ||
483 | return false; | ||
484 | } | ||
485 | |||
486 | #define have_mute(codec, nid, dir) \ | ||
487 | check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) | ||
488 | |||
489 | /* enable/disable the output-route mixers */ | ||
490 | static void activate_output_mix(struct hda_codec *codec, struct nid_path *path, | ||
491 | hda_nid_t mix_nid, int idx, bool enable) | ||
492 | { | ||
493 | int i, num, val; | ||
494 | |||
495 | if (!path) | ||
496 | return; | ||
497 | num = snd_hda_get_num_conns(codec, mix_nid); | ||
498 | for (i = 0; i < num; i++) { | ||
499 | if (i == idx) | ||
500 | val = AMP_IN_UNMUTE(i); | ||
501 | else | ||
502 | val = AMP_IN_MUTE(i); | ||
503 | snd_hda_codec_write(codec, mix_nid, 0, | ||
504 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | /* enable/disable the output-route */ | ||
509 | static void activate_output_path(struct hda_codec *codec, struct nid_path *path, | ||
510 | bool enable, bool force) | ||
511 | { | ||
512 | struct via_spec *spec = codec->spec; | ||
513 | int i; | ||
514 | for (i = 0; i < path->depth; i++) { | ||
515 | hda_nid_t src, dst; | ||
516 | int idx = path->idx[i]; | ||
517 | src = path->path[i]; | ||
518 | if (i < path->depth - 1) | ||
519 | dst = path->path[i + 1]; | ||
520 | else | ||
521 | dst = 0; | ||
522 | if (enable && path->multi[i]) | ||
523 | snd_hda_codec_write(codec, dst, 0, | ||
524 | AC_VERB_SET_CONNECT_SEL, idx); | ||
525 | if (!force && (dst == spec->aa_mix_nid)) | ||
526 | continue; | ||
527 | if (have_mute(codec, dst, HDA_INPUT)) | ||
528 | activate_output_mix(codec, path, dst, idx, enable); | ||
529 | if (!force && (src == path->vol_ctl || src == path->mute_ctl)) | ||
530 | continue; | ||
531 | if (have_mute(codec, src, HDA_OUTPUT)) { | ||
532 | int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE; | ||
533 | snd_hda_codec_write(codec, src, 0, | ||
534 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | |||
539 | /* set the given pin as output */ | ||
540 | static void init_output_pin(struct hda_codec *codec, hda_nid_t pin, | ||
541 | int pin_type) | ||
542 | { | ||
543 | if (!pin) | ||
544 | return; | ||
545 | snd_hda_set_pin_ctl(codec, pin, pin_type); | ||
546 | if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD) | ||
547 | snd_hda_codec_write(codec, pin, 0, | ||
548 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
549 | } | ||
550 | |||
551 | static void via_auto_init_output(struct hda_codec *codec, | ||
552 | struct nid_path *path, int pin_type) | ||
553 | { | ||
554 | unsigned int caps; | ||
555 | hda_nid_t pin; | ||
556 | |||
557 | if (!path->depth) | ||
558 | return; | ||
559 | pin = path->path[path->depth - 1]; | ||
560 | |||
561 | init_output_pin(codec, pin, pin_type); | ||
562 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
563 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | ||
564 | else | ||
565 | caps = 0; | ||
566 | if (caps & AC_AMPCAP_MUTE) { | ||
567 | unsigned int val; | ||
568 | val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | ||
569 | snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
570 | AMP_OUT_MUTE | val); | ||
571 | } | ||
572 | activate_output_path(codec, path, true, true); /* force on */ | ||
573 | } | ||
574 | |||
575 | static void via_auto_init_multi_out(struct hda_codec *codec) | ||
576 | { | ||
577 | struct via_spec *spec = codec->spec; | ||
578 | struct nid_path *path; | ||
579 | int i; | ||
580 | |||
581 | for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) { | ||
582 | path = &spec->out_path[i]; | ||
583 | if (!i && spec->aamix_mode && spec->out_mix_path.depth) | ||
584 | path = &spec->out_mix_path; | ||
585 | via_auto_init_output(codec, path, PIN_OUT); | ||
586 | } | ||
587 | } | ||
588 | |||
589 | /* deactivate the inactive headphone-paths */ | ||
590 | static void deactivate_hp_paths(struct hda_codec *codec) | ||
591 | { | ||
592 | struct via_spec *spec = codec->spec; | ||
593 | int shared = spec->hp_indep_shared; | ||
594 | |||
595 | if (spec->hp_independent_mode) { | ||
596 | activate_output_path(codec, &spec->hp_path, false, false); | ||
597 | activate_output_path(codec, &spec->hp_mix_path, false, false); | ||
598 | if (shared) | ||
599 | activate_output_path(codec, &spec->out_path[shared], | ||
600 | false, false); | ||
601 | } else if (spec->aamix_mode || !spec->hp_path.depth) { | ||
602 | activate_output_path(codec, &spec->hp_indep_path, false, false); | ||
603 | activate_output_path(codec, &spec->hp_path, false, false); | ||
604 | } else { | ||
605 | activate_output_path(codec, &spec->hp_indep_path, false, false); | ||
606 | activate_output_path(codec, &spec->hp_mix_path, false, false); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | static void via_auto_init_hp_out(struct hda_codec *codec) | ||
611 | { | ||
612 | struct via_spec *spec = codec->spec; | ||
613 | |||
614 | if (!spec->hp_path.depth) { | ||
615 | via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP); | ||
616 | return; | ||
617 | } | ||
618 | deactivate_hp_paths(codec); | ||
619 | if (spec->hp_independent_mode) | ||
620 | via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP); | ||
621 | else if (spec->aamix_mode) | ||
622 | via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP); | ||
623 | else | ||
624 | via_auto_init_output(codec, &spec->hp_path, PIN_HP); | ||
625 | } | ||
626 | |||
627 | static void via_auto_init_speaker_out(struct hda_codec *codec) | ||
628 | { | ||
629 | struct via_spec *spec = codec->spec; | ||
630 | |||
631 | if (!spec->autocfg.speaker_outs) | ||
632 | return; | ||
633 | if (!spec->speaker_path.depth) { | ||
634 | via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT); | ||
635 | return; | ||
636 | } | ||
637 | if (!spec->aamix_mode) { | ||
638 | activate_output_path(codec, &spec->speaker_mix_path, | ||
639 | false, false); | ||
640 | via_auto_init_output(codec, &spec->speaker_path, PIN_OUT); | ||
641 | } else { | ||
642 | activate_output_path(codec, &spec->speaker_path, false, false); | ||
643 | via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); | ||
648 | static void via_hp_automute(struct hda_codec *codec); | ||
649 | |||
650 | static void via_auto_init_analog_input(struct hda_codec *codec) | ||
651 | { | ||
652 | struct via_spec *spec = codec->spec; | ||
653 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
654 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | ||
655 | unsigned int ctl; | ||
656 | int i, num_conns; | ||
657 | |||
658 | /* init ADCs */ | ||
659 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
660 | hda_nid_t nid = spec->adc_nids[i]; | ||
661 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) || | ||
662 | !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)) | ||
663 | continue; | ||
664 | snd_hda_codec_write(codec, spec->adc_nids[i], 0, | ||
665 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
666 | AMP_IN_UNMUTE(0)); | ||
667 | } | ||
668 | |||
669 | /* init pins */ | ||
670 | for (i = 0; i < cfg->num_inputs; i++) { | ||
671 | hda_nid_t nid = cfg->inputs[i].pin; | ||
672 | if (spec->smart51_enabled && is_smart51_pins(codec, nid)) | ||
673 | ctl = PIN_OUT; | ||
674 | else { | ||
675 | ctl = PIN_IN; | ||
676 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | ||
677 | ctl |= snd_hda_get_default_vref(codec, nid); | ||
678 | } | ||
679 | snd_hda_set_pin_ctl(codec, nid, ctl); | ||
680 | } | ||
681 | |||
682 | /* init input-src */ | ||
683 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
684 | int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; | ||
685 | /* secondary ADCs must have the unique MUX */ | ||
686 | if (i > 0 && !spec->mux_nids[i]) | ||
687 | break; | ||
688 | if (spec->mux_nids[adc_idx]) { | ||
689 | int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; | ||
690 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, | ||
691 | AC_VERB_SET_CONNECT_SEL, | ||
692 | mux_idx); | ||
693 | } | ||
694 | if (spec->dyn_adc_switch) | ||
695 | break; /* only one input-src */ | ||
696 | } | ||
697 | |||
698 | /* init aa-mixer */ | ||
699 | if (!spec->aa_mix_nid) | ||
700 | return; | ||
701 | num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn, | ||
702 | ARRAY_SIZE(conn)); | ||
703 | for (i = 0; i < num_conns; i++) { | ||
704 | unsigned int caps = get_wcaps(codec, conn[i]); | ||
705 | if (get_wcaps_type(caps) == AC_WID_PIN) | ||
706 | snd_hda_codec_write(codec, spec->aa_mix_nid, 0, | ||
707 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
708 | AMP_IN_MUTE(i)); | ||
709 | } | ||
710 | } | ||
711 | |||
712 | static void update_power_state(struct hda_codec *codec, hda_nid_t nid, | 239 | static void update_power_state(struct hda_codec *codec, hda_nid_t nid, |
713 | unsigned int parm) | 240 | unsigned int parm) |
714 | { | 241 | { |
715 | if (snd_hda_codec_read(codec, nid, 0, | 242 | if (snd_hda_check_power_state(codec, nid, parm)) |
716 | AC_VERB_GET_POWER_STATE, 0) == parm) | ||
717 | return; | 243 | return; |
718 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | 244 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); |
719 | } | 245 | } |
@@ -723,8 +249,8 @@ static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
723 | { | 249 | { |
724 | struct via_spec *spec = codec->spec; | 250 | struct via_spec *spec = codec->spec; |
725 | unsigned int format; | 251 | unsigned int format; |
726 | if (snd_hda_codec_read(codec, nid, 0, | 252 | |
727 | AC_VERB_GET_POWER_STATE, 0) == parm) | 253 | if (snd_hda_check_power_state(codec, nid, parm)) |
728 | return; | 254 | return; |
729 | format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | 255 | format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); |
730 | if (format && (spec->dac_stream_tag[index] != format)) | 256 | if (format && (spec->dac_stream_tag[index] != format)) |
@@ -740,6 +266,23 @@ static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
740 | } | 266 | } |
741 | } | 267 | } |
742 | 268 | ||
269 | static bool smart51_enabled(struct hda_codec *codec) | ||
270 | { | ||
271 | struct via_spec *spec = codec->spec; | ||
272 | return spec->gen.ext_channel_count > 2; | ||
273 | } | ||
274 | |||
275 | static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin) | ||
276 | { | ||
277 | struct via_spec *spec = codec->spec; | ||
278 | int i; | ||
279 | |||
280 | for (i = 0; i < spec->gen.multi_ios; i++) | ||
281 | if (spec->gen.multi_io[i].pin == pin) | ||
282 | return true; | ||
283 | return false; | ||
284 | } | ||
285 | |||
743 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | 286 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, |
744 | unsigned int *affected_parm) | 287 | unsigned int *affected_parm) |
745 | { | 288 | { |
@@ -754,7 +297,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
754 | no_presence |= spec->no_pin_power_ctl; | 297 | no_presence |= spec->no_pin_power_ctl; |
755 | if (!no_presence) | 298 | if (!no_presence) |
756 | present = snd_hda_jack_detect(codec, nid); | 299 | present = snd_hda_jack_detect(codec, nid); |
757 | if ((spec->smart51_enabled && is_smart51_pins(codec, nid)) | 300 | if ((smart51_enabled(codec) && is_smart51_pins(codec, nid)) |
758 | || ((no_presence || present) | 301 | || ((no_presence || present) |
759 | && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { | 302 | && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { |
760 | *affected_parm = AC_PWRST_D0; /* if it's connected */ | 303 | *affected_parm = AC_PWRST_D0; /* if it's connected */ |
@@ -795,268 +338,18 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, | |||
795 | return 1; | 338 | return 1; |
796 | } | 339 | } |
797 | 340 | ||
798 | static const struct snd_kcontrol_new via_pin_power_ctl_enum = { | 341 | static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = { |
342 | { | ||
799 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 343 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
800 | .name = "Dynamic Power-Control", | 344 | .name = "Dynamic Power-Control", |
801 | .info = via_pin_power_ctl_info, | 345 | .info = via_pin_power_ctl_info, |
802 | .get = via_pin_power_ctl_get, | 346 | .get = via_pin_power_ctl_get, |
803 | .put = via_pin_power_ctl_put, | 347 | .put = via_pin_power_ctl_put, |
348 | }, | ||
349 | {} /* terminator */ | ||
804 | }; | 350 | }; |
805 | 351 | ||
806 | 352 | ||
807 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | ||
808 | struct snd_ctl_elem_info *uinfo) | ||
809 | { | ||
810 | static const char * const texts[] = { "OFF", "ON" }; | ||
811 | |||
812 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
813 | uinfo->count = 1; | ||
814 | uinfo->value.enumerated.items = 2; | ||
815 | if (uinfo->value.enumerated.item >= 2) | ||
816 | uinfo->value.enumerated.item = 1; | ||
817 | strcpy(uinfo->value.enumerated.name, | ||
818 | texts[uinfo->value.enumerated.item]); | ||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | static int via_independent_hp_get(struct snd_kcontrol *kcontrol, | ||
823 | struct snd_ctl_elem_value *ucontrol) | ||
824 | { | ||
825 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
826 | struct via_spec *spec = codec->spec; | ||
827 | |||
828 | ucontrol->value.enumerated.item[0] = spec->hp_independent_mode; | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | /* adjust spec->multiout setup according to the current flags */ | ||
833 | static void setup_playback_multi_pcm(struct via_spec *spec) | ||
834 | { | ||
835 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
836 | spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums; | ||
837 | spec->multiout.hp_nid = 0; | ||
838 | if (!spec->hp_independent_mode) { | ||
839 | if (!spec->hp_indep_shared) | ||
840 | spec->multiout.hp_nid = spec->hp_dac_nid; | ||
841 | } else { | ||
842 | if (spec->hp_indep_shared) | ||
843 | spec->multiout.num_dacs = cfg->line_outs - 1; | ||
844 | } | ||
845 | } | ||
846 | |||
847 | /* update DAC setups according to indep-HP switch; | ||
848 | * this function is called only when indep-HP is modified | ||
849 | */ | ||
850 | static void switch_indep_hp_dacs(struct hda_codec *codec) | ||
851 | { | ||
852 | struct via_spec *spec = codec->spec; | ||
853 | int shared = spec->hp_indep_shared; | ||
854 | hda_nid_t shared_dac, hp_dac; | ||
855 | |||
856 | if (!spec->opened_streams) | ||
857 | return; | ||
858 | |||
859 | shared_dac = shared ? spec->multiout.dac_nids[shared] : 0; | ||
860 | hp_dac = spec->hp_dac_nid; | ||
861 | if (spec->hp_independent_mode) { | ||
862 | /* switch to indep-HP mode */ | ||
863 | if (spec->active_streams & STREAM_MULTI_OUT) { | ||
864 | __snd_hda_codec_cleanup_stream(codec, hp_dac, 1); | ||
865 | __snd_hda_codec_cleanup_stream(codec, shared_dac, 1); | ||
866 | } | ||
867 | if (spec->active_streams & STREAM_INDEP_HP) | ||
868 | snd_hda_codec_setup_stream(codec, hp_dac, | ||
869 | spec->cur_hp_stream_tag, 0, | ||
870 | spec->cur_hp_format); | ||
871 | } else { | ||
872 | /* back to HP or shared-DAC */ | ||
873 | if (spec->active_streams & STREAM_INDEP_HP) | ||
874 | __snd_hda_codec_cleanup_stream(codec, hp_dac, 1); | ||
875 | if (spec->active_streams & STREAM_MULTI_OUT) { | ||
876 | hda_nid_t dac; | ||
877 | int ch; | ||
878 | if (shared_dac) { /* reset mutli-ch DAC */ | ||
879 | dac = shared_dac; | ||
880 | ch = shared * 2; | ||
881 | } else { /* reset HP DAC */ | ||
882 | dac = hp_dac; | ||
883 | ch = 0; | ||
884 | } | ||
885 | snd_hda_codec_setup_stream(codec, dac, | ||
886 | spec->cur_dac_stream_tag, ch, | ||
887 | spec->cur_dac_format); | ||
888 | } | ||
889 | } | ||
890 | setup_playback_multi_pcm(spec); | ||
891 | } | ||
892 | |||
893 | static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | ||
894 | struct snd_ctl_elem_value *ucontrol) | ||
895 | { | ||
896 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
897 | struct via_spec *spec = codec->spec; | ||
898 | int cur, shared; | ||
899 | |||
900 | mutex_lock(&spec->config_mutex); | ||
901 | cur = !!ucontrol->value.enumerated.item[0]; | ||
902 | if (spec->hp_independent_mode == cur) { | ||
903 | mutex_unlock(&spec->config_mutex); | ||
904 | return 0; | ||
905 | } | ||
906 | spec->hp_independent_mode = cur; | ||
907 | shared = spec->hp_indep_shared; | ||
908 | deactivate_hp_paths(codec); | ||
909 | if (cur) | ||
910 | activate_output_path(codec, &spec->hp_indep_path, true, false); | ||
911 | else { | ||
912 | if (shared) | ||
913 | activate_output_path(codec, &spec->out_path[shared], | ||
914 | true, false); | ||
915 | if (spec->aamix_mode || !spec->hp_path.depth) | ||
916 | activate_output_path(codec, &spec->hp_mix_path, | ||
917 | true, false); | ||
918 | else | ||
919 | activate_output_path(codec, &spec->hp_path, | ||
920 | true, false); | ||
921 | } | ||
922 | |||
923 | switch_indep_hp_dacs(codec); | ||
924 | mutex_unlock(&spec->config_mutex); | ||
925 | |||
926 | /* update jack power state */ | ||
927 | set_widgets_power_state(codec); | ||
928 | via_hp_automute(codec); | ||
929 | return 1; | ||
930 | } | ||
931 | |||
932 | static const struct snd_kcontrol_new via_hp_mixer = { | ||
933 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
934 | .name = "Independent HP", | ||
935 | .info = via_independent_hp_info, | ||
936 | .get = via_independent_hp_get, | ||
937 | .put = via_independent_hp_put, | ||
938 | }; | ||
939 | |||
940 | static int via_hp_build(struct hda_codec *codec) | ||
941 | { | ||
942 | struct via_spec *spec = codec->spec; | ||
943 | struct snd_kcontrol_new *knew; | ||
944 | hda_nid_t nid; | ||
945 | |||
946 | nid = spec->autocfg.hp_pins[0]; | ||
947 | knew = via_clone_control(spec, &via_hp_mixer); | ||
948 | if (knew == NULL) | ||
949 | return -ENOMEM; | ||
950 | |||
951 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static void notify_aa_path_ctls(struct hda_codec *codec) | ||
957 | { | ||
958 | struct via_spec *spec = codec->spec; | ||
959 | int i; | ||
960 | |||
961 | for (i = 0; i < spec->smart51_nums; i++) { | ||
962 | struct snd_kcontrol *ctl; | ||
963 | struct snd_ctl_elem_id id; | ||
964 | memset(&id, 0, sizeof(id)); | ||
965 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
966 | sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]); | ||
967 | ctl = snd_hda_find_mixer_ctl(codec, id.name); | ||
968 | if (ctl) | ||
969 | snd_ctl_notify(codec->bus->card, | ||
970 | SNDRV_CTL_EVENT_MASK_VALUE, | ||
971 | &ctl->id); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | static void mute_aa_path(struct hda_codec *codec, int mute) | ||
976 | { | ||
977 | struct via_spec *spec = codec->spec; | ||
978 | int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE; | ||
979 | int i; | ||
980 | |||
981 | /* check AA path's mute status */ | ||
982 | for (i = 0; i < spec->smart51_nums; i++) { | ||
983 | if (spec->smart51_idxs[i] < 0) | ||
984 | continue; | ||
985 | snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid, | ||
986 | HDA_INPUT, spec->smart51_idxs[i], | ||
987 | HDA_AMP_MUTE, val); | ||
988 | } | ||
989 | } | ||
990 | |||
991 | static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin) | ||
992 | { | ||
993 | struct via_spec *spec = codec->spec; | ||
994 | int i; | ||
995 | |||
996 | for (i = 0; i < spec->smart51_nums; i++) | ||
997 | if (spec->smart51_pins[i] == pin) | ||
998 | return true; | ||
999 | return false; | ||
1000 | } | ||
1001 | |||
1002 | static int via_smart51_get(struct snd_kcontrol *kcontrol, | ||
1003 | struct snd_ctl_elem_value *ucontrol) | ||
1004 | { | ||
1005 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1006 | struct via_spec *spec = codec->spec; | ||
1007 | |||
1008 | *ucontrol->value.integer.value = spec->smart51_enabled; | ||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | static int via_smart51_put(struct snd_kcontrol *kcontrol, | ||
1013 | struct snd_ctl_elem_value *ucontrol) | ||
1014 | { | ||
1015 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1016 | struct via_spec *spec = codec->spec; | ||
1017 | int out_in = *ucontrol->value.integer.value | ||
1018 | ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; | ||
1019 | int i; | ||
1020 | |||
1021 | for (i = 0; i < spec->smart51_nums; i++) { | ||
1022 | hda_nid_t nid = spec->smart51_pins[i]; | ||
1023 | unsigned int parm; | ||
1024 | |||
1025 | parm = snd_hda_codec_read(codec, nid, 0, | ||
1026 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1027 | parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | ||
1028 | parm |= out_in; | ||
1029 | snd_hda_set_pin_ctl(codec, nid, parm); | ||
1030 | if (out_in == AC_PINCTL_OUT_EN) { | ||
1031 | mute_aa_path(codec, 1); | ||
1032 | notify_aa_path_ctls(codec); | ||
1033 | } | ||
1034 | } | ||
1035 | spec->smart51_enabled = *ucontrol->value.integer.value; | ||
1036 | set_widgets_power_state(codec); | ||
1037 | return 1; | ||
1038 | } | ||
1039 | |||
1040 | static const struct snd_kcontrol_new via_smart51_mixer = { | ||
1041 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1042 | .name = "Smart 5.1", | ||
1043 | .count = 1, | ||
1044 | .info = snd_ctl_boolean_mono_info, | ||
1045 | .get = via_smart51_get, | ||
1046 | .put = via_smart51_put, | ||
1047 | }; | ||
1048 | |||
1049 | static int via_smart51_build(struct hda_codec *codec) | ||
1050 | { | ||
1051 | struct via_spec *spec = codec->spec; | ||
1052 | |||
1053 | if (!spec->smart51_nums) | ||
1054 | return 0; | ||
1055 | if (!via_clone_control(spec, &via_smart51_mixer)) | ||
1056 | return -ENOMEM; | ||
1057 | return 0; | ||
1058 | } | ||
1059 | |||
1060 | /* check AA path's mute status */ | 353 | /* check AA path's mute status */ |
1061 | static bool is_aa_path_mute(struct hda_codec *codec) | 354 | static bool is_aa_path_mute(struct hda_codec *codec) |
1062 | { | 355 | { |
@@ -1064,8 +357,8 @@ static bool is_aa_path_mute(struct hda_codec *codec) | |||
1064 | const struct hda_amp_list *p; | 357 | const struct hda_amp_list *p; |
1065 | int i, ch, v; | 358 | int i, ch, v; |
1066 | 359 | ||
1067 | for (i = 0; i < spec->num_loopbacks; i++) { | 360 | for (i = 0; i < spec->gen.num_loopbacks; i++) { |
1068 | p = &spec->loopback_list[i]; | 361 | p = &spec->gen.loopback_list[i]; |
1069 | for (ch = 0; ch < 2; ch++) { | 362 | for (ch = 0; ch < 2; ch++) { |
1070 | v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir, | 363 | v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir, |
1071 | p->idx); | 364 | p->idx); |
@@ -1086,7 +379,7 @@ static void __analog_low_current_mode(struct hda_codec *codec, bool force) | |||
1086 | if (spec->no_pin_power_ctl) | 379 | if (spec->no_pin_power_ctl) |
1087 | enable = false; | 380 | enable = false; |
1088 | else | 381 | else |
1089 | enable = is_aa_path_mute(codec) && !spec->opened_streams; | 382 | enable = is_aa_path_mute(codec) && !spec->gen.active_streams; |
1090 | if (enable == spec->alc_mode && !force) | 383 | if (enable == spec->alc_mode && !force) |
1091 | return; | 384 | return; |
1092 | spec->alc_mode = enable; | 385 | spec->alc_mode = enable; |
@@ -1131,366 +424,17 @@ static void analog_low_current_mode(struct hda_codec *codec) | |||
1131 | return __analog_low_current_mode(codec, false); | 424 | return __analog_low_current_mode(codec, false); |
1132 | } | 425 | } |
1133 | 426 | ||
1134 | /* | ||
1135 | * generic initialization of ADC, input mixers and output mixers | ||
1136 | */ | ||
1137 | static const struct hda_verb vt1708_init_verbs[] = { | ||
1138 | /* power down jack detect function */ | ||
1139 | {0x1, 0xf81, 0x1}, | ||
1140 | { } | ||
1141 | }; | ||
1142 | |||
1143 | static void set_stream_open(struct hda_codec *codec, int bit, bool active) | ||
1144 | { | ||
1145 | struct via_spec *spec = codec->spec; | ||
1146 | |||
1147 | if (active) | ||
1148 | spec->opened_streams |= bit; | ||
1149 | else | ||
1150 | spec->opened_streams &= ~bit; | ||
1151 | analog_low_current_mode(codec); | ||
1152 | } | ||
1153 | |||
1154 | static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo, | ||
1155 | struct hda_codec *codec, | ||
1156 | struct snd_pcm_substream *substream) | ||
1157 | { | ||
1158 | struct via_spec *spec = codec->spec; | ||
1159 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1160 | int err; | ||
1161 | |||
1162 | spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums; | ||
1163 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
1164 | set_stream_open(codec, STREAM_MULTI_OUT, true); | ||
1165 | err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
1166 | hinfo); | ||
1167 | if (err < 0) { | ||
1168 | set_stream_open(codec, STREAM_MULTI_OUT, false); | ||
1169 | return err; | ||
1170 | } | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo, | ||
1175 | struct hda_codec *codec, | ||
1176 | struct snd_pcm_substream *substream) | ||
1177 | { | ||
1178 | set_stream_open(codec, STREAM_MULTI_OUT, false); | ||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo, | ||
1183 | struct hda_codec *codec, | ||
1184 | struct snd_pcm_substream *substream) | ||
1185 | { | ||
1186 | struct via_spec *spec = codec->spec; | ||
1187 | |||
1188 | if (snd_BUG_ON(!spec->hp_dac_nid)) | ||
1189 | return -EINVAL; | ||
1190 | set_stream_open(codec, STREAM_INDEP_HP, true); | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo, | ||
1195 | struct hda_codec *codec, | ||
1196 | struct snd_pcm_substream *substream) | ||
1197 | { | ||
1198 | set_stream_open(codec, STREAM_INDEP_HP, false); | ||
1199 | return 0; | ||
1200 | } | ||
1201 | |||
1202 | static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1203 | struct hda_codec *codec, | ||
1204 | unsigned int stream_tag, | ||
1205 | unsigned int format, | ||
1206 | struct snd_pcm_substream *substream) | ||
1207 | { | ||
1208 | struct via_spec *spec = codec->spec; | ||
1209 | |||
1210 | mutex_lock(&spec->config_mutex); | ||
1211 | setup_playback_multi_pcm(spec); | ||
1212 | snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, | ||
1213 | format, substream); | ||
1214 | /* remember for dynamic DAC switch with indep-HP */ | ||
1215 | spec->active_streams |= STREAM_MULTI_OUT; | ||
1216 | spec->cur_dac_stream_tag = stream_tag; | ||
1217 | spec->cur_dac_format = format; | ||
1218 | mutex_unlock(&spec->config_mutex); | ||
1219 | vt1708_update_hp_work(spec); | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1224 | struct hda_codec *codec, | ||
1225 | unsigned int stream_tag, | ||
1226 | unsigned int format, | ||
1227 | struct snd_pcm_substream *substream) | ||
1228 | { | ||
1229 | struct via_spec *spec = codec->spec; | ||
1230 | |||
1231 | mutex_lock(&spec->config_mutex); | ||
1232 | if (spec->hp_independent_mode) | ||
1233 | snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, | ||
1234 | stream_tag, 0, format); | ||
1235 | spec->active_streams |= STREAM_INDEP_HP; | ||
1236 | spec->cur_hp_stream_tag = stream_tag; | ||
1237 | spec->cur_hp_format = format; | ||
1238 | mutex_unlock(&spec->config_mutex); | ||
1239 | vt1708_update_hp_work(spec); | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1244 | struct hda_codec *codec, | ||
1245 | struct snd_pcm_substream *substream) | ||
1246 | { | ||
1247 | struct via_spec *spec = codec->spec; | ||
1248 | |||
1249 | mutex_lock(&spec->config_mutex); | ||
1250 | snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
1251 | spec->active_streams &= ~STREAM_MULTI_OUT; | ||
1252 | mutex_unlock(&spec->config_mutex); | ||
1253 | vt1708_update_hp_work(spec); | ||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1257 | static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1258 | struct hda_codec *codec, | ||
1259 | struct snd_pcm_substream *substream) | ||
1260 | { | ||
1261 | struct via_spec *spec = codec->spec; | ||
1262 | |||
1263 | mutex_lock(&spec->config_mutex); | ||
1264 | if (spec->hp_independent_mode) | ||
1265 | snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); | ||
1266 | spec->active_streams &= ~STREAM_INDEP_HP; | ||
1267 | mutex_unlock(&spec->config_mutex); | ||
1268 | vt1708_update_hp_work(spec); | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | /* | ||
1273 | * Digital out | ||
1274 | */ | ||
1275 | static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
1276 | struct hda_codec *codec, | ||
1277 | struct snd_pcm_substream *substream) | ||
1278 | { | ||
1279 | struct via_spec *spec = codec->spec; | ||
1280 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
1281 | } | ||
1282 | |||
1283 | static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
1284 | struct hda_codec *codec, | ||
1285 | struct snd_pcm_substream *substream) | ||
1286 | { | ||
1287 | struct via_spec *spec = codec->spec; | ||
1288 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
1289 | } | ||
1290 | |||
1291 | static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1292 | struct hda_codec *codec, | ||
1293 | unsigned int stream_tag, | ||
1294 | unsigned int format, | ||
1295 | struct snd_pcm_substream *substream) | ||
1296 | { | ||
1297 | struct via_spec *spec = codec->spec; | ||
1298 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
1299 | stream_tag, format, substream); | ||
1300 | } | ||
1301 | |||
1302 | static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1303 | struct hda_codec *codec, | ||
1304 | struct snd_pcm_substream *substream) | ||
1305 | { | ||
1306 | struct via_spec *spec = codec->spec; | ||
1307 | snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | /* | ||
1312 | * Analog capture | ||
1313 | */ | ||
1314 | static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1315 | struct hda_codec *codec, | ||
1316 | unsigned int stream_tag, | ||
1317 | unsigned int format, | ||
1318 | struct snd_pcm_substream *substream) | ||
1319 | { | ||
1320 | struct via_spec *spec = codec->spec; | ||
1321 | |||
1322 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], | ||
1323 | stream_tag, 0, format); | ||
1324 | return 0; | ||
1325 | } | ||
1326 | |||
1327 | static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1328 | struct hda_codec *codec, | ||
1329 | struct snd_pcm_substream *substream) | ||
1330 | { | ||
1331 | struct via_spec *spec = codec->spec; | ||
1332 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | /* analog capture with dynamic ADC switching */ | ||
1337 | static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1338 | struct hda_codec *codec, | ||
1339 | unsigned int stream_tag, | ||
1340 | unsigned int format, | ||
1341 | struct snd_pcm_substream *substream) | ||
1342 | { | ||
1343 | struct via_spec *spec = codec->spec; | ||
1344 | int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx; | ||
1345 | |||
1346 | mutex_lock(&spec->config_mutex); | ||
1347 | spec->cur_adc = spec->adc_nids[adc_idx]; | ||
1348 | spec->cur_adc_stream_tag = stream_tag; | ||
1349 | spec->cur_adc_format = format; | ||
1350 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
1351 | mutex_unlock(&spec->config_mutex); | ||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1356 | struct hda_codec *codec, | ||
1357 | struct snd_pcm_substream *substream) | ||
1358 | { | ||
1359 | struct via_spec *spec = codec->spec; | ||
1360 | |||
1361 | mutex_lock(&spec->config_mutex); | ||
1362 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
1363 | spec->cur_adc = 0; | ||
1364 | mutex_unlock(&spec->config_mutex); | ||
1365 | return 0; | ||
1366 | } | ||
1367 | |||
1368 | /* re-setup the stream if running; called from input-src put */ | ||
1369 | static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | ||
1370 | { | ||
1371 | struct via_spec *spec = codec->spec; | ||
1372 | int adc_idx = spec->inputs[cur].adc_idx; | ||
1373 | hda_nid_t adc = spec->adc_nids[adc_idx]; | ||
1374 | bool ret = false; | ||
1375 | |||
1376 | mutex_lock(&spec->config_mutex); | ||
1377 | if (spec->cur_adc && spec->cur_adc != adc) { | ||
1378 | /* stream is running, let's swap the current ADC */ | ||
1379 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
1380 | spec->cur_adc = adc; | ||
1381 | snd_hda_codec_setup_stream(codec, adc, | ||
1382 | spec->cur_adc_stream_tag, 0, | ||
1383 | spec->cur_adc_format); | ||
1384 | ret = true; | ||
1385 | } | ||
1386 | mutex_unlock(&spec->config_mutex); | ||
1387 | return ret; | ||
1388 | } | ||
1389 | |||
1390 | static const struct hda_pcm_stream via_pcm_analog_playback = { | ||
1391 | .substreams = 1, | ||
1392 | .channels_min = 2, | ||
1393 | .channels_max = 8, | ||
1394 | /* NID is set in via_build_pcms */ | ||
1395 | .ops = { | ||
1396 | .open = via_playback_multi_pcm_open, | ||
1397 | .close = via_playback_multi_pcm_close, | ||
1398 | .prepare = via_playback_multi_pcm_prepare, | ||
1399 | .cleanup = via_playback_multi_pcm_cleanup | ||
1400 | }, | ||
1401 | }; | ||
1402 | |||
1403 | static const struct hda_pcm_stream via_pcm_hp_playback = { | ||
1404 | .substreams = 1, | ||
1405 | .channels_min = 2, | ||
1406 | .channels_max = 2, | ||
1407 | /* NID is set in via_build_pcms */ | ||
1408 | .ops = { | ||
1409 | .open = via_playback_hp_pcm_open, | ||
1410 | .close = via_playback_hp_pcm_close, | ||
1411 | .prepare = via_playback_hp_pcm_prepare, | ||
1412 | .cleanup = via_playback_hp_pcm_cleanup | ||
1413 | }, | ||
1414 | }; | ||
1415 | |||
1416 | static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { | ||
1417 | .substreams = 1, | ||
1418 | .channels_min = 2, | ||
1419 | .channels_max = 8, | ||
1420 | /* NID is set in via_build_pcms */ | ||
1421 | /* We got noisy outputs on the right channel on VT1708 when | ||
1422 | * 24bit samples are used. Until any workaround is found, | ||
1423 | * disable the 24bit format, so far. | ||
1424 | */ | ||
1425 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
1426 | .ops = { | ||
1427 | .open = via_playback_multi_pcm_open, | ||
1428 | .close = via_playback_multi_pcm_close, | ||
1429 | .prepare = via_playback_multi_pcm_prepare, | ||
1430 | .cleanup = via_playback_multi_pcm_cleanup | ||
1431 | }, | ||
1432 | }; | ||
1433 | |||
1434 | static const struct hda_pcm_stream via_pcm_analog_capture = { | ||
1435 | .substreams = 1, /* will be changed in via_build_pcms() */ | ||
1436 | .channels_min = 2, | ||
1437 | .channels_max = 2, | ||
1438 | /* NID is set in via_build_pcms */ | ||
1439 | .ops = { | ||
1440 | .prepare = via_capture_pcm_prepare, | ||
1441 | .cleanup = via_capture_pcm_cleanup | ||
1442 | }, | ||
1443 | }; | ||
1444 | |||
1445 | static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = { | ||
1446 | .substreams = 1, | ||
1447 | .channels_min = 2, | ||
1448 | .channels_max = 2, | ||
1449 | /* NID is set in via_build_pcms */ | ||
1450 | .ops = { | ||
1451 | .prepare = via_dyn_adc_capture_pcm_prepare, | ||
1452 | .cleanup = via_dyn_adc_capture_pcm_cleanup, | ||
1453 | }, | ||
1454 | }; | ||
1455 | |||
1456 | static const struct hda_pcm_stream via_pcm_digital_playback = { | ||
1457 | .substreams = 1, | ||
1458 | .channels_min = 2, | ||
1459 | .channels_max = 2, | ||
1460 | /* NID is set in via_build_pcms */ | ||
1461 | .ops = { | ||
1462 | .open = via_dig_playback_pcm_open, | ||
1463 | .close = via_dig_playback_pcm_close, | ||
1464 | .prepare = via_dig_playback_pcm_prepare, | ||
1465 | .cleanup = via_dig_playback_pcm_cleanup | ||
1466 | }, | ||
1467 | }; | ||
1468 | |||
1469 | static const struct hda_pcm_stream via_pcm_digital_capture = { | ||
1470 | .substreams = 1, | ||
1471 | .channels_min = 2, | ||
1472 | .channels_max = 2, | ||
1473 | }; | ||
1474 | |||
1475 | /* | ||
1476 | * slave controls for virtual master | ||
1477 | */ | ||
1478 | static const char * const via_slave_pfxs[] = { | ||
1479 | "Front", "Surround", "Center", "LFE", "Side", | ||
1480 | "Headphone", "Speaker", "Bass Speaker", | ||
1481 | NULL, | ||
1482 | }; | ||
1483 | |||
1484 | static int via_build_controls(struct hda_codec *codec) | 427 | static int via_build_controls(struct hda_codec *codec) |
1485 | { | 428 | { |
1486 | struct via_spec *spec = codec->spec; | 429 | struct via_spec *spec = codec->spec; |
1487 | struct snd_kcontrol *kctl; | ||
1488 | int err, i; | 430 | int err, i; |
1489 | 431 | ||
1490 | spec->no_pin_power_ctl = 1; | 432 | err = snd_hda_gen_build_controls(codec); |
433 | if (err < 0) | ||
434 | return err; | ||
435 | |||
1491 | if (spec->set_widgets_power_state) | 436 | if (spec->set_widgets_power_state) |
1492 | if (!via_clone_control(spec, &via_pin_power_ctl_enum)) | 437 | spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum; |
1493 | return -ENOMEM; | ||
1494 | 438 | ||
1495 | for (i = 0; i < spec->num_mixers; i++) { | 439 | for (i = 0; i < spec->num_mixers; i++) { |
1496 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 440 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
@@ -1498,152 +442,16 @@ static int via_build_controls(struct hda_codec *codec) | |||
1498 | return err; | 442 | return err; |
1499 | } | 443 | } |
1500 | 444 | ||
1501 | if (spec->multiout.dig_out_nid) { | ||
1502 | err = snd_hda_create_spdif_out_ctls(codec, | ||
1503 | spec->multiout.dig_out_nid, | ||
1504 | spec->multiout.dig_out_nid); | ||
1505 | if (err < 0) | ||
1506 | return err; | ||
1507 | err = snd_hda_create_spdif_share_sw(codec, | ||
1508 | &spec->multiout); | ||
1509 | if (err < 0) | ||
1510 | return err; | ||
1511 | spec->multiout.share_spdif = 1; | ||
1512 | } | ||
1513 | if (spec->dig_in_nid) { | ||
1514 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
1515 | if (err < 0) | ||
1516 | return err; | ||
1517 | } | ||
1518 | |||
1519 | /* if we have no master control, let's create it */ | ||
1520 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | ||
1521 | unsigned int vmaster_tlv[4]; | ||
1522 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | ||
1523 | HDA_OUTPUT, vmaster_tlv); | ||
1524 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | ||
1525 | vmaster_tlv, via_slave_pfxs, | ||
1526 | "Playback Volume"); | ||
1527 | if (err < 0) | ||
1528 | return err; | ||
1529 | } | ||
1530 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | ||
1531 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | ||
1532 | NULL, via_slave_pfxs, | ||
1533 | "Playback Switch"); | ||
1534 | if (err < 0) | ||
1535 | return err; | ||
1536 | } | ||
1537 | |||
1538 | /* assign Capture Source enums to NID */ | ||
1539 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
1540 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1541 | if (!spec->mux_nids[i]) | ||
1542 | continue; | ||
1543 | err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); | ||
1544 | if (err < 0) | ||
1545 | return err; | ||
1546 | } | ||
1547 | |||
1548 | via_free_kctls(codec); /* no longer needed */ | ||
1549 | |||
1550 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
1551 | if (err < 0) | ||
1552 | return err; | ||
1553 | |||
1554 | return 0; | 445 | return 0; |
1555 | } | 446 | } |
1556 | 447 | ||
1557 | static int via_build_pcms(struct hda_codec *codec) | 448 | static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo, |
449 | struct hda_codec *codec, | ||
450 | struct snd_pcm_substream *substream, | ||
451 | int action) | ||
1558 | { | 452 | { |
1559 | struct via_spec *spec = codec->spec; | 453 | analog_low_current_mode(codec); |
1560 | struct hda_pcm *info = spec->pcm_rec; | 454 | vt1708_update_hp_work(codec); |
1561 | |||
1562 | codec->num_pcms = 0; | ||
1563 | codec->pcm_info = info; | ||
1564 | |||
1565 | if (spec->multiout.num_dacs || spec->num_adc_nids) { | ||
1566 | snprintf(spec->stream_name_analog, | ||
1567 | sizeof(spec->stream_name_analog), | ||
1568 | "%s Analog", codec->chip_name); | ||
1569 | info->name = spec->stream_name_analog; | ||
1570 | |||
1571 | if (spec->multiout.num_dacs) { | ||
1572 | if (!spec->stream_analog_playback) | ||
1573 | spec->stream_analog_playback = | ||
1574 | &via_pcm_analog_playback; | ||
1575 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
1576 | *spec->stream_analog_playback; | ||
1577 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
1578 | spec->multiout.dac_nids[0]; | ||
1579 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
1580 | spec->multiout.max_channels; | ||
1581 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT | ||
1582 | && spec->autocfg.line_outs == 2) | ||
1583 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
1584 | snd_pcm_2_1_chmaps; | ||
1585 | } | ||
1586 | |||
1587 | if (!spec->stream_analog_capture) { | ||
1588 | if (spec->dyn_adc_switch) | ||
1589 | spec->stream_analog_capture = | ||
1590 | &via_pcm_dyn_adc_analog_capture; | ||
1591 | else | ||
1592 | spec->stream_analog_capture = | ||
1593 | &via_pcm_analog_capture; | ||
1594 | } | ||
1595 | if (spec->num_adc_nids) { | ||
1596 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
1597 | *spec->stream_analog_capture; | ||
1598 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
1599 | spec->adc_nids[0]; | ||
1600 | if (!spec->dyn_adc_switch) | ||
1601 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
1602 | spec->num_adc_nids; | ||
1603 | } | ||
1604 | codec->num_pcms++; | ||
1605 | info++; | ||
1606 | } | ||
1607 | |||
1608 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | ||
1609 | snprintf(spec->stream_name_digital, | ||
1610 | sizeof(spec->stream_name_digital), | ||
1611 | "%s Digital", codec->chip_name); | ||
1612 | info->name = spec->stream_name_digital; | ||
1613 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
1614 | if (spec->multiout.dig_out_nid) { | ||
1615 | if (!spec->stream_digital_playback) | ||
1616 | spec->stream_digital_playback = | ||
1617 | &via_pcm_digital_playback; | ||
1618 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | ||
1619 | *spec->stream_digital_playback; | ||
1620 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
1621 | spec->multiout.dig_out_nid; | ||
1622 | } | ||
1623 | if (spec->dig_in_nid) { | ||
1624 | if (!spec->stream_digital_capture) | ||
1625 | spec->stream_digital_capture = | ||
1626 | &via_pcm_digital_capture; | ||
1627 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
1628 | *spec->stream_digital_capture; | ||
1629 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
1630 | spec->dig_in_nid; | ||
1631 | } | ||
1632 | codec->num_pcms++; | ||
1633 | info++; | ||
1634 | } | ||
1635 | |||
1636 | if (spec->hp_dac_nid) { | ||
1637 | snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp), | ||
1638 | "%s HP", codec->chip_name); | ||
1639 | info->name = spec->stream_name_hp; | ||
1640 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback; | ||
1641 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
1642 | spec->hp_dac_nid; | ||
1643 | codec->num_pcms++; | ||
1644 | info++; | ||
1645 | } | ||
1646 | return 0; | ||
1647 | } | 455 | } |
1648 | 456 | ||
1649 | static void via_free(struct hda_codec *codec) | 457 | static void via_free(struct hda_codec *codec) |
@@ -1653,79 +461,22 @@ static void via_free(struct hda_codec *codec) | |||
1653 | if (!spec) | 461 | if (!spec) |
1654 | return; | 462 | return; |
1655 | 463 | ||
1656 | via_free_kctls(codec); | 464 | vt1708_stop_hp_work(codec); |
1657 | vt1708_stop_hp_work(spec); | 465 | snd_hda_gen_spec_free(&spec->gen); |
1658 | kfree(spec->bind_cap_vol); | ||
1659 | kfree(spec->bind_cap_sw); | ||
1660 | snd_hda_gen_free(&spec->gen); | ||
1661 | kfree(spec); | 466 | kfree(spec); |
1662 | } | 467 | } |
1663 | 468 | ||
1664 | /* mute/unmute outputs */ | ||
1665 | static void toggle_output_mutes(struct hda_codec *codec, int num_pins, | ||
1666 | hda_nid_t *pins, bool mute) | ||
1667 | { | ||
1668 | int i; | ||
1669 | for (i = 0; i < num_pins; i++) { | ||
1670 | unsigned int parm = snd_hda_codec_read(codec, pins[i], 0, | ||
1671 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1672 | if (parm & AC_PINCTL_IN_EN) | ||
1673 | continue; | ||
1674 | if (mute) | ||
1675 | parm &= ~AC_PINCTL_OUT_EN; | ||
1676 | else | ||
1677 | parm |= AC_PINCTL_OUT_EN; | ||
1678 | snd_hda_set_pin_ctl(codec, pins[i], parm); | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | /* mute internal speaker if line-out is plugged */ | ||
1683 | static void via_line_automute(struct hda_codec *codec, int present) | ||
1684 | { | ||
1685 | struct via_spec *spec = codec->spec; | ||
1686 | |||
1687 | if (!spec->autocfg.speaker_outs) | ||
1688 | return; | ||
1689 | if (!present) | ||
1690 | present = snd_hda_jack_detect(codec, | ||
1691 | spec->autocfg.line_out_pins[0]); | ||
1692 | toggle_output_mutes(codec, spec->autocfg.speaker_outs, | ||
1693 | spec->autocfg.speaker_pins, | ||
1694 | present); | ||
1695 | } | ||
1696 | |||
1697 | /* mute internal speaker if HP is plugged */ | ||
1698 | static void via_hp_automute(struct hda_codec *codec) | ||
1699 | { | ||
1700 | int present = 0; | ||
1701 | int nums; | ||
1702 | struct via_spec *spec = codec->spec; | ||
1703 | |||
1704 | if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] && | ||
1705 | (spec->codec_type != VT1708 || spec->vt1708_jack_detect) && | ||
1706 | is_jack_detectable(codec, spec->autocfg.hp_pins[0])) | ||
1707 | present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); | ||
1708 | |||
1709 | if (spec->smart51_enabled) | ||
1710 | nums = spec->autocfg.line_outs + spec->smart51_nums; | ||
1711 | else | ||
1712 | nums = spec->autocfg.line_outs; | ||
1713 | toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present); | ||
1714 | |||
1715 | via_line_automute(codec, present); | ||
1716 | } | ||
1717 | |||
1718 | #ifdef CONFIG_PM | 469 | #ifdef CONFIG_PM |
1719 | static int via_suspend(struct hda_codec *codec) | 470 | static int via_suspend(struct hda_codec *codec) |
1720 | { | 471 | { |
1721 | struct via_spec *spec = codec->spec; | 472 | struct via_spec *spec = codec->spec; |
1722 | vt1708_stop_hp_work(spec); | 473 | vt1708_stop_hp_work(codec); |
1723 | 474 | ||
1724 | if (spec->codec_type == VT1802) { | 475 | if (spec->codec_type == VT1802) { |
1725 | /* Fix pop noise on headphones */ | 476 | /* Fix pop noise on headphones */ |
1726 | int i; | 477 | int i; |
1727 | for (i = 0; i < spec->autocfg.hp_outs; i++) | 478 | for (i = 0; i < spec->gen.autocfg.hp_outs; i++) |
1728 | snd_hda_set_pin_ctl(codec, spec->autocfg.hp_pins[i], 0); | 479 | snd_hda_set_pin_ctl(codec, spec->gen.autocfg.hp_pins[i], 0); |
1729 | } | 480 | } |
1730 | 481 | ||
1731 | return 0; | 482 | return 0; |
@@ -1736,7 +487,10 @@ static int via_suspend(struct hda_codec *codec) | |||
1736 | static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 487 | static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
1737 | { | 488 | { |
1738 | struct via_spec *spec = codec->spec; | 489 | struct via_spec *spec = codec->spec; |
1739 | return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); | 490 | set_widgets_power_state(codec); |
491 | analog_low_current_mode(codec); | ||
492 | vt1708_update_hp_work(codec); | ||
493 | return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid); | ||
1740 | } | 494 | } |
1741 | #endif | 495 | #endif |
1742 | 496 | ||
@@ -1747,7 +501,7 @@ static int via_init(struct hda_codec *codec); | |||
1747 | 501 | ||
1748 | static const struct hda_codec_ops via_patch_ops = { | 502 | static const struct hda_codec_ops via_patch_ops = { |
1749 | .build_controls = via_build_controls, | 503 | .build_controls = via_build_controls, |
1750 | .build_pcms = via_build_pcms, | 504 | .build_pcms = snd_hda_gen_build_pcms, |
1751 | .init = via_init, | 505 | .init = via_init, |
1752 | .free = via_free, | 506 | .free = via_free, |
1753 | .unsol_event = snd_hda_jack_unsol_event, | 507 | .unsol_event = snd_hda_jack_unsol_event, |
@@ -1757,840 +511,12 @@ static const struct hda_codec_ops via_patch_ops = { | |||
1757 | #endif | 511 | #endif |
1758 | }; | 512 | }; |
1759 | 513 | ||
1760 | static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac) | ||
1761 | { | ||
1762 | struct via_spec *spec = codec->spec; | ||
1763 | int i; | ||
1764 | |||
1765 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
1766 | if (spec->multiout.dac_nids[i] == dac) | ||
1767 | return false; | ||
1768 | } | ||
1769 | if (spec->hp_dac_nid == dac) | ||
1770 | return false; | ||
1771 | return true; | ||
1772 | } | ||
1773 | |||
1774 | static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid, | ||
1775 | hda_nid_t target_dac, int with_aa_mix, | ||
1776 | struct nid_path *path, int depth) | ||
1777 | { | ||
1778 | struct via_spec *spec = codec->spec; | ||
1779 | hda_nid_t conn[8]; | ||
1780 | int i, nums; | ||
1781 | |||
1782 | if (nid == spec->aa_mix_nid) { | ||
1783 | if (!with_aa_mix) | ||
1784 | return false; | ||
1785 | with_aa_mix = 2; /* mark aa-mix is included */ | ||
1786 | } | ||
1787 | |||
1788 | nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn)); | ||
1789 | for (i = 0; i < nums; i++) { | ||
1790 | if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT) | ||
1791 | continue; | ||
1792 | if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) { | ||
1793 | /* aa-mix is requested but not included? */ | ||
1794 | if (!(spec->aa_mix_nid && with_aa_mix == 1)) | ||
1795 | goto found; | ||
1796 | } | ||
1797 | } | ||
1798 | if (depth >= MAX_NID_PATH_DEPTH) | ||
1799 | return false; | ||
1800 | for (i = 0; i < nums; i++) { | ||
1801 | unsigned int type; | ||
1802 | type = get_wcaps_type(get_wcaps(codec, conn[i])); | ||
1803 | if (type == AC_WID_AUD_OUT) | ||
1804 | continue; | ||
1805 | if (__parse_output_path(codec, conn[i], target_dac, | ||
1806 | with_aa_mix, path, depth + 1)) | ||
1807 | goto found; | ||
1808 | } | ||
1809 | return false; | ||
1810 | |||
1811 | found: | ||
1812 | path->path[path->depth] = conn[i]; | ||
1813 | path->idx[path->depth] = i; | ||
1814 | if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX) | ||
1815 | path->multi[path->depth] = 1; | ||
1816 | path->depth++; | ||
1817 | return true; | ||
1818 | } | ||
1819 | |||
1820 | static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, | ||
1821 | hda_nid_t target_dac, int with_aa_mix, | ||
1822 | struct nid_path *path) | ||
1823 | { | ||
1824 | if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) { | ||
1825 | path->path[path->depth] = nid; | ||
1826 | path->depth++; | ||
1827 | snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n", | ||
1828 | path->depth, path->path[0], path->path[1], | ||
1829 | path->path[2], path->path[3], path->path[4]); | ||
1830 | return true; | ||
1831 | } | ||
1832 | return false; | ||
1833 | } | ||
1834 | |||
1835 | static int via_auto_fill_dac_nids(struct hda_codec *codec) | ||
1836 | { | ||
1837 | struct via_spec *spec = codec->spec; | ||
1838 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1839 | int i; | ||
1840 | hda_nid_t nid; | ||
1841 | |||
1842 | spec->multiout.num_dacs = 0; | ||
1843 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
1844 | for (i = 0; i < cfg->line_outs; i++) { | ||
1845 | hda_nid_t dac = 0; | ||
1846 | nid = cfg->line_out_pins[i]; | ||
1847 | if (!nid) | ||
1848 | continue; | ||
1849 | if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i])) | ||
1850 | dac = spec->out_path[i].path[0]; | ||
1851 | if (!i && parse_output_path(codec, nid, dac, 1, | ||
1852 | &spec->out_mix_path)) | ||
1853 | dac = spec->out_mix_path.path[0]; | ||
1854 | if (dac) | ||
1855 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; | ||
1856 | } | ||
1857 | if (!spec->out_path[0].depth && spec->out_mix_path.depth) { | ||
1858 | spec->out_path[0] = spec->out_mix_path; | ||
1859 | spec->out_mix_path.depth = 0; | ||
1860 | } | ||
1861 | return 0; | ||
1862 | } | ||
1863 | |||
1864 | static int create_ch_ctls(struct hda_codec *codec, const char *pfx, | ||
1865 | int chs, bool check_dac, struct nid_path *path) | ||
1866 | { | ||
1867 | struct via_spec *spec = codec->spec; | ||
1868 | char name[32]; | ||
1869 | hda_nid_t dac, pin, sel, nid; | ||
1870 | int err; | ||
1871 | |||
1872 | dac = check_dac ? path->path[0] : 0; | ||
1873 | pin = path->path[path->depth - 1]; | ||
1874 | sel = path->depth > 1 ? path->path[1] : 0; | ||
1875 | |||
1876 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS)) | ||
1877 | nid = dac; | ||
1878 | else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS)) | ||
1879 | nid = pin; | ||
1880 | else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS)) | ||
1881 | nid = sel; | ||
1882 | else | ||
1883 | nid = 0; | ||
1884 | if (nid) { | ||
1885 | sprintf(name, "%s Playback Volume", pfx); | ||
1886 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, | ||
1887 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
1888 | if (err < 0) | ||
1889 | return err; | ||
1890 | path->vol_ctl = nid; | ||
1891 | } | ||
1892 | |||
1893 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE)) | ||
1894 | nid = dac; | ||
1895 | else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE)) | ||
1896 | nid = pin; | ||
1897 | else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE)) | ||
1898 | nid = sel; | ||
1899 | else | ||
1900 | nid = 0; | ||
1901 | if (nid) { | ||
1902 | sprintf(name, "%s Playback Switch", pfx); | ||
1903 | err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, | ||
1904 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | ||
1905 | if (err < 0) | ||
1906 | return err; | ||
1907 | path->mute_ctl = nid; | ||
1908 | } | ||
1909 | return 0; | ||
1910 | } | ||
1911 | |||
1912 | static void mangle_smart51(struct hda_codec *codec) | ||
1913 | { | ||
1914 | struct via_spec *spec = codec->spec; | ||
1915 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1916 | struct auto_pin_cfg_item *ins = cfg->inputs; | ||
1917 | int i, j, nums, attr; | ||
1918 | int pins[AUTO_CFG_MAX_INS]; | ||
1919 | |||
1920 | for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) { | ||
1921 | nums = 0; | ||
1922 | for (i = 0; i < cfg->num_inputs; i++) { | ||
1923 | unsigned int def; | ||
1924 | if (ins[i].type > AUTO_PIN_LINE_IN) | ||
1925 | continue; | ||
1926 | def = snd_hda_codec_get_pincfg(codec, ins[i].pin); | ||
1927 | if (snd_hda_get_input_pin_attr(def) != attr) | ||
1928 | continue; | ||
1929 | for (j = 0; j < nums; j++) | ||
1930 | if (ins[pins[j]].type < ins[i].type) { | ||
1931 | memmove(pins + j + 1, pins + j, | ||
1932 | (nums - j) * sizeof(int)); | ||
1933 | break; | ||
1934 | } | ||
1935 | pins[j] = i; | ||
1936 | nums++; | ||
1937 | } | ||
1938 | if (cfg->line_outs + nums < 3) | ||
1939 | continue; | ||
1940 | for (i = 0; i < nums; i++) { | ||
1941 | hda_nid_t pin = ins[pins[i]].pin; | ||
1942 | spec->smart51_pins[spec->smart51_nums++] = pin; | ||
1943 | cfg->line_out_pins[cfg->line_outs++] = pin; | ||
1944 | if (cfg->line_outs == 3) | ||
1945 | break; | ||
1946 | } | ||
1947 | return; | ||
1948 | } | ||
1949 | } | ||
1950 | |||
1951 | static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src) | ||
1952 | { | ||
1953 | dst->vol_ctl = src->vol_ctl; | ||
1954 | dst->mute_ctl = src->mute_ctl; | ||
1955 | } | ||
1956 | |||
1957 | /* add playback controls from the parsed DAC table */ | ||
1958 | static int via_auto_create_multi_out_ctls(struct hda_codec *codec) | ||
1959 | { | ||
1960 | struct via_spec *spec = codec->spec; | ||
1961 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1962 | struct nid_path *path; | ||
1963 | static const char * const chname[4] = { | ||
1964 | "Front", "Surround", NULL /* "CLFE" */, "Side" | ||
1965 | }; | ||
1966 | int i, idx, err; | ||
1967 | int old_line_outs; | ||
1968 | |||
1969 | /* check smart51 */ | ||
1970 | old_line_outs = cfg->line_outs; | ||
1971 | if (cfg->line_outs == 1) | ||
1972 | mangle_smart51(codec); | ||
1973 | |||
1974 | err = via_auto_fill_dac_nids(codec); | ||
1975 | if (err < 0) | ||
1976 | return err; | ||
1977 | |||
1978 | if (spec->multiout.num_dacs < 3) { | ||
1979 | spec->smart51_nums = 0; | ||
1980 | cfg->line_outs = old_line_outs; | ||
1981 | } | ||
1982 | for (i = 0; i < cfg->line_outs; i++) { | ||
1983 | hda_nid_t pin, dac; | ||
1984 | pin = cfg->line_out_pins[i]; | ||
1985 | dac = spec->multiout.dac_nids[i]; | ||
1986 | if (!pin || !dac) | ||
1987 | continue; | ||
1988 | path = spec->out_path + i; | ||
1989 | if (i == HDA_CLFE) { | ||
1990 | err = create_ch_ctls(codec, "Center", 1, true, path); | ||
1991 | if (err < 0) | ||
1992 | return err; | ||
1993 | err = create_ch_ctls(codec, "LFE", 2, true, path); | ||
1994 | if (err < 0) | ||
1995 | return err; | ||
1996 | } else { | ||
1997 | const char *pfx = chname[i]; | ||
1998 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
1999 | cfg->line_outs <= 2) | ||
2000 | pfx = i ? "Bass Speaker" : "Speaker"; | ||
2001 | err = create_ch_ctls(codec, pfx, 3, true, path); | ||
2002 | if (err < 0) | ||
2003 | return err; | ||
2004 | } | ||
2005 | if (path != spec->out_path + i) | ||
2006 | copy_path_mixer_ctls(&spec->out_path[i], path); | ||
2007 | if (path == spec->out_path && spec->out_mix_path.depth) | ||
2008 | copy_path_mixer_ctls(&spec->out_mix_path, path); | ||
2009 | } | ||
2010 | |||
2011 | idx = get_connection_index(codec, spec->aa_mix_nid, | ||
2012 | spec->multiout.dac_nids[0]); | ||
2013 | if (idx >= 0) { | ||
2014 | /* add control to mixer */ | ||
2015 | const char *name; | ||
2016 | name = spec->out_mix_path.depth ? | ||
2017 | "PCM Loopback Playback Volume" : "PCM Playback Volume"; | ||
2018 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, | ||
2019 | HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3, | ||
2020 | idx, HDA_INPUT)); | ||
2021 | if (err < 0) | ||
2022 | return err; | ||
2023 | name = spec->out_mix_path.depth ? | ||
2024 | "PCM Loopback Playback Switch" : "PCM Playback Switch"; | ||
2025 | err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, | ||
2026 | HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3, | ||
2027 | idx, HDA_INPUT)); | ||
2028 | if (err < 0) | ||
2029 | return err; | ||
2030 | } | ||
2031 | |||
2032 | cfg->line_outs = old_line_outs; | ||
2033 | |||
2034 | return 0; | ||
2035 | } | ||
2036 | |||
2037 | static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) | ||
2038 | { | ||
2039 | struct via_spec *spec = codec->spec; | ||
2040 | struct nid_path *path; | ||
2041 | bool check_dac; | ||
2042 | int i, err; | ||
2043 | |||
2044 | if (!pin) | ||
2045 | return 0; | ||
2046 | |||
2047 | if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) { | ||
2048 | for (i = HDA_SIDE; i >= HDA_CLFE; i--) { | ||
2049 | if (i < spec->multiout.num_dacs && | ||
2050 | parse_output_path(codec, pin, | ||
2051 | spec->multiout.dac_nids[i], 0, | ||
2052 | &spec->hp_indep_path)) { | ||
2053 | spec->hp_indep_shared = i; | ||
2054 | break; | ||
2055 | } | ||
2056 | } | ||
2057 | } | ||
2058 | if (spec->hp_indep_path.depth) { | ||
2059 | spec->hp_dac_nid = spec->hp_indep_path.path[0]; | ||
2060 | if (!spec->hp_indep_shared) | ||
2061 | spec->hp_path = spec->hp_indep_path; | ||
2062 | } | ||
2063 | /* optionally check front-path w/o AA-mix */ | ||
2064 | if (!spec->hp_path.depth) | ||
2065 | parse_output_path(codec, pin, | ||
2066 | spec->multiout.dac_nids[HDA_FRONT], 0, | ||
2067 | &spec->hp_path); | ||
2068 | |||
2069 | if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], | ||
2070 | 1, &spec->hp_mix_path) && !spec->hp_path.depth) | ||
2071 | return 0; | ||
2072 | |||
2073 | if (spec->hp_path.depth) { | ||
2074 | path = &spec->hp_path; | ||
2075 | check_dac = true; | ||
2076 | } else { | ||
2077 | path = &spec->hp_mix_path; | ||
2078 | check_dac = false; | ||
2079 | } | ||
2080 | err = create_ch_ctls(codec, "Headphone", 3, check_dac, path); | ||
2081 | if (err < 0) | ||
2082 | return err; | ||
2083 | if (check_dac) | ||
2084 | copy_path_mixer_ctls(&spec->hp_mix_path, path); | ||
2085 | else | ||
2086 | copy_path_mixer_ctls(&spec->hp_path, path); | ||
2087 | if (spec->hp_indep_path.depth) | ||
2088 | copy_path_mixer_ctls(&spec->hp_indep_path, path); | ||
2089 | return 0; | ||
2090 | } | ||
2091 | 514 | ||
2092 | static int via_auto_create_speaker_ctls(struct hda_codec *codec) | 515 | static const struct hda_verb vt1708_init_verbs[] = { |
2093 | { | 516 | /* power down jack detect function */ |
2094 | struct via_spec *spec = codec->spec; | 517 | {0x1, 0xf81, 0x1}, |
2095 | struct nid_path *path; | 518 | { } |
2096 | bool check_dac; | ||
2097 | hda_nid_t pin, dac = 0; | ||
2098 | int err; | ||
2099 | |||
2100 | pin = spec->autocfg.speaker_pins[0]; | ||
2101 | if (!spec->autocfg.speaker_outs || !pin) | ||
2102 | return 0; | ||
2103 | |||
2104 | if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path)) | ||
2105 | dac = spec->speaker_path.path[0]; | ||
2106 | if (!dac) | ||
2107 | parse_output_path(codec, pin, | ||
2108 | spec->multiout.dac_nids[HDA_FRONT], 0, | ||
2109 | &spec->speaker_path); | ||
2110 | if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], | ||
2111 | 1, &spec->speaker_mix_path) && !dac) | ||
2112 | return 0; | ||
2113 | |||
2114 | /* no AA-path for front? */ | ||
2115 | if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth) | ||
2116 | dac = 0; | ||
2117 | |||
2118 | spec->speaker_dac_nid = dac; | ||
2119 | spec->multiout.extra_out_nid[0] = dac; | ||
2120 | if (dac) { | ||
2121 | path = &spec->speaker_path; | ||
2122 | check_dac = true; | ||
2123 | } else { | ||
2124 | path = &spec->speaker_mix_path; | ||
2125 | check_dac = false; | ||
2126 | } | ||
2127 | err = create_ch_ctls(codec, "Speaker", 3, check_dac, path); | ||
2128 | if (err < 0) | ||
2129 | return err; | ||
2130 | if (check_dac) | ||
2131 | copy_path_mixer_ctls(&spec->speaker_mix_path, path); | ||
2132 | else | ||
2133 | copy_path_mixer_ctls(&spec->speaker_path, path); | ||
2134 | return 0; | ||
2135 | } | ||
2136 | |||
2137 | #define via_aamix_ctl_info via_pin_power_ctl_info | ||
2138 | |||
2139 | static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol, | ||
2140 | struct snd_ctl_elem_value *ucontrol) | ||
2141 | { | ||
2142 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2143 | struct via_spec *spec = codec->spec; | ||
2144 | ucontrol->value.enumerated.item[0] = spec->aamix_mode; | ||
2145 | return 0; | ||
2146 | } | ||
2147 | |||
2148 | static void update_aamix_paths(struct hda_codec *codec, int do_mix, | ||
2149 | struct nid_path *nomix, struct nid_path *mix) | ||
2150 | { | ||
2151 | if (do_mix) { | ||
2152 | activate_output_path(codec, nomix, false, false); | ||
2153 | activate_output_path(codec, mix, true, false); | ||
2154 | } else { | ||
2155 | activate_output_path(codec, mix, false, false); | ||
2156 | activate_output_path(codec, nomix, true, false); | ||
2157 | } | ||
2158 | } | ||
2159 | |||
2160 | static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol, | ||
2161 | struct snd_ctl_elem_value *ucontrol) | ||
2162 | { | ||
2163 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2164 | struct via_spec *spec = codec->spec; | ||
2165 | unsigned int val = ucontrol->value.enumerated.item[0]; | ||
2166 | |||
2167 | if (val == spec->aamix_mode) | ||
2168 | return 0; | ||
2169 | spec->aamix_mode = val; | ||
2170 | /* update front path */ | ||
2171 | update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path); | ||
2172 | /* update HP path */ | ||
2173 | if (!spec->hp_independent_mode) { | ||
2174 | update_aamix_paths(codec, val, &spec->hp_path, | ||
2175 | &spec->hp_mix_path); | ||
2176 | } | ||
2177 | /* update speaker path */ | ||
2178 | update_aamix_paths(codec, val, &spec->speaker_path, | ||
2179 | &spec->speaker_mix_path); | ||
2180 | return 1; | ||
2181 | } | ||
2182 | |||
2183 | static const struct snd_kcontrol_new via_aamix_ctl_enum = { | ||
2184 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2185 | .name = "Loopback Mixing", | ||
2186 | .info = via_aamix_ctl_info, | ||
2187 | .get = via_aamix_ctl_get, | ||
2188 | .put = via_aamix_ctl_put, | ||
2189 | }; | ||
2190 | |||
2191 | static int via_auto_create_loopback_switch(struct hda_codec *codec) | ||
2192 | { | ||
2193 | struct via_spec *spec = codec->spec; | ||
2194 | |||
2195 | if (!spec->aa_mix_nid) | ||
2196 | return 0; /* no loopback switching available */ | ||
2197 | if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth || | ||
2198 | spec->speaker_path.depth)) | ||
2199 | return 0; /* no loopback switching available */ | ||
2200 | if (!via_clone_control(spec, &via_aamix_ctl_enum)) | ||
2201 | return -ENOMEM; | ||
2202 | return 0; | ||
2203 | } | ||
2204 | |||
2205 | /* look for ADCs */ | ||
2206 | static int via_fill_adcs(struct hda_codec *codec) | ||
2207 | { | ||
2208 | struct via_spec *spec = codec->spec; | ||
2209 | hda_nid_t nid = codec->start_nid; | ||
2210 | int i; | ||
2211 | |||
2212 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
2213 | unsigned int wcaps = get_wcaps(codec, nid); | ||
2214 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) | ||
2215 | continue; | ||
2216 | if (wcaps & AC_WCAP_DIGITAL) | ||
2217 | continue; | ||
2218 | if (!(wcaps & AC_WCAP_CONN_LIST)) | ||
2219 | continue; | ||
2220 | if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids)) | ||
2221 | return -ENOMEM; | ||
2222 | spec->adc_nids[spec->num_adc_nids++] = nid; | ||
2223 | } | ||
2224 | return 0; | ||
2225 | } | ||
2226 | |||
2227 | /* input-src control */ | ||
2228 | static int via_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
2229 | struct snd_ctl_elem_info *uinfo) | ||
2230 | { | ||
2231 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2232 | struct via_spec *spec = codec->spec; | ||
2233 | |||
2234 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2235 | uinfo->count = 1; | ||
2236 | uinfo->value.enumerated.items = spec->num_inputs; | ||
2237 | if (uinfo->value.enumerated.item >= spec->num_inputs) | ||
2238 | uinfo->value.enumerated.item = spec->num_inputs - 1; | ||
2239 | strcpy(uinfo->value.enumerated.name, | ||
2240 | spec->inputs[uinfo->value.enumerated.item].label); | ||
2241 | return 0; | ||
2242 | } | ||
2243 | |||
2244 | static int via_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
2245 | struct snd_ctl_elem_value *ucontrol) | ||
2246 | { | ||
2247 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2248 | struct via_spec *spec = codec->spec; | ||
2249 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2250 | |||
2251 | ucontrol->value.enumerated.item[0] = spec->cur_mux[idx]; | ||
2252 | return 0; | ||
2253 | } | ||
2254 | |||
2255 | static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
2256 | struct snd_ctl_elem_value *ucontrol) | ||
2257 | { | ||
2258 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2259 | struct via_spec *spec = codec->spec; | ||
2260 | unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2261 | hda_nid_t mux; | ||
2262 | int cur; | ||
2263 | |||
2264 | cur = ucontrol->value.enumerated.item[0]; | ||
2265 | if (cur < 0 || cur >= spec->num_inputs) | ||
2266 | return -EINVAL; | ||
2267 | if (spec->cur_mux[idx] == cur) | ||
2268 | return 0; | ||
2269 | spec->cur_mux[idx] = cur; | ||
2270 | if (spec->dyn_adc_switch) { | ||
2271 | int adc_idx = spec->inputs[cur].adc_idx; | ||
2272 | mux = spec->mux_nids[adc_idx]; | ||
2273 | via_dyn_adc_pcm_resetup(codec, cur); | ||
2274 | } else { | ||
2275 | mux = spec->mux_nids[idx]; | ||
2276 | if (snd_BUG_ON(!mux)) | ||
2277 | return -EINVAL; | ||
2278 | } | ||
2279 | |||
2280 | if (mux) { | ||
2281 | /* switch to D0 beofre change index */ | ||
2282 | update_power_state(codec, mux, AC_PWRST_D0); | ||
2283 | snd_hda_codec_write(codec, mux, 0, | ||
2284 | AC_VERB_SET_CONNECT_SEL, | ||
2285 | spec->inputs[cur].mux_idx); | ||
2286 | } | ||
2287 | |||
2288 | /* update jack power state */ | ||
2289 | set_widgets_power_state(codec); | ||
2290 | return 0; | ||
2291 | } | ||
2292 | |||
2293 | static const struct snd_kcontrol_new via_input_src_ctl = { | ||
2294 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2295 | /* The multiple "Capture Source" controls confuse alsamixer | ||
2296 | * So call somewhat different.. | ||
2297 | */ | ||
2298 | /* .name = "Capture Source", */ | ||
2299 | .name = "Input Source", | ||
2300 | .info = via_mux_enum_info, | ||
2301 | .get = via_mux_enum_get, | ||
2302 | .put = via_mux_enum_put, | ||
2303 | }; | 519 | }; |
2304 | |||
2305 | static int create_input_src_ctls(struct hda_codec *codec, int count) | ||
2306 | { | ||
2307 | struct via_spec *spec = codec->spec; | ||
2308 | struct snd_kcontrol_new *knew; | ||
2309 | |||
2310 | if (spec->num_inputs <= 1 || !count) | ||
2311 | return 0; /* no need for single src */ | ||
2312 | |||
2313 | knew = via_clone_control(spec, &via_input_src_ctl); | ||
2314 | if (!knew) | ||
2315 | return -ENOMEM; | ||
2316 | knew->count = count; | ||
2317 | return 0; | ||
2318 | } | ||
2319 | |||
2320 | /* add the powersave loopback-list entry */ | ||
2321 | static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx) | ||
2322 | { | ||
2323 | struct hda_amp_list *list; | ||
2324 | |||
2325 | if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1) | ||
2326 | return; | ||
2327 | list = spec->loopback_list + spec->num_loopbacks; | ||
2328 | list->nid = mix; | ||
2329 | list->dir = HDA_INPUT; | ||
2330 | list->idx = idx; | ||
2331 | spec->num_loopbacks++; | ||
2332 | spec->loopback.amplist = spec->loopback_list; | ||
2333 | } | ||
2334 | |||
2335 | static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src, | ||
2336 | hda_nid_t dst) | ||
2337 | { | ||
2338 | return snd_hda_get_conn_index(codec, src, dst, 1) >= 0; | ||
2339 | } | ||
2340 | |||
2341 | /* add the input-route to the given pin */ | ||
2342 | static bool add_input_route(struct hda_codec *codec, hda_nid_t pin) | ||
2343 | { | ||
2344 | struct via_spec *spec = codec->spec; | ||
2345 | int c, idx; | ||
2346 | |||
2347 | spec->inputs[spec->num_inputs].adc_idx = -1; | ||
2348 | spec->inputs[spec->num_inputs].pin = pin; | ||
2349 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
2350 | if (spec->mux_nids[c]) { | ||
2351 | idx = get_connection_index(codec, spec->mux_nids[c], | ||
2352 | pin); | ||
2353 | if (idx < 0) | ||
2354 | continue; | ||
2355 | spec->inputs[spec->num_inputs].mux_idx = idx; | ||
2356 | } else { | ||
2357 | if (!is_reachable_nid(codec, spec->adc_nids[c], pin)) | ||
2358 | continue; | ||
2359 | } | ||
2360 | spec->inputs[spec->num_inputs].adc_idx = c; | ||
2361 | /* Can primary ADC satisfy all inputs? */ | ||
2362 | if (!spec->dyn_adc_switch && | ||
2363 | spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) { | ||
2364 | snd_printd(KERN_INFO | ||
2365 | "via: dynamic ADC switching enabled\n"); | ||
2366 | spec->dyn_adc_switch = 1; | ||
2367 | } | ||
2368 | return true; | ||
2369 | } | ||
2370 | return false; | ||
2371 | } | ||
2372 | |||
2373 | static int get_mux_nids(struct hda_codec *codec); | ||
2374 | |||
2375 | /* parse input-routes; fill ADCs, MUXs and input-src entries */ | ||
2376 | static int parse_analog_inputs(struct hda_codec *codec) | ||
2377 | { | ||
2378 | struct via_spec *spec = codec->spec; | ||
2379 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2380 | int i, err; | ||
2381 | |||
2382 | err = via_fill_adcs(codec); | ||
2383 | if (err < 0) | ||
2384 | return err; | ||
2385 | err = get_mux_nids(codec); | ||
2386 | if (err < 0) | ||
2387 | return err; | ||
2388 | |||
2389 | /* fill all input-routes */ | ||
2390 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2391 | if (add_input_route(codec, cfg->inputs[i].pin)) | ||
2392 | spec->inputs[spec->num_inputs++].label = | ||
2393 | hda_get_autocfg_input_label(codec, cfg, i); | ||
2394 | } | ||
2395 | |||
2396 | /* check for internal loopback recording */ | ||
2397 | if (spec->aa_mix_nid && | ||
2398 | add_input_route(codec, spec->aa_mix_nid)) | ||
2399 | spec->inputs[spec->num_inputs++].label = "Stereo Mixer"; | ||
2400 | |||
2401 | return 0; | ||
2402 | } | ||
2403 | |||
2404 | /* create analog-loopback volume/switch controls */ | ||
2405 | static int create_loopback_ctls(struct hda_codec *codec) | ||
2406 | { | ||
2407 | struct via_spec *spec = codec->spec; | ||
2408 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2409 | const char *prev_label = NULL; | ||
2410 | int type_idx = 0; | ||
2411 | int i, j, err, idx; | ||
2412 | |||
2413 | if (!spec->aa_mix_nid) | ||
2414 | return 0; | ||
2415 | |||
2416 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2417 | hda_nid_t pin = cfg->inputs[i].pin; | ||
2418 | const char *label = hda_get_autocfg_input_label(codec, cfg, i); | ||
2419 | |||
2420 | if (prev_label && !strcmp(label, prev_label)) | ||
2421 | type_idx++; | ||
2422 | else | ||
2423 | type_idx = 0; | ||
2424 | prev_label = label; | ||
2425 | idx = get_connection_index(codec, spec->aa_mix_nid, pin); | ||
2426 | if (idx >= 0) { | ||
2427 | err = via_new_analog_input(spec, label, type_idx, | ||
2428 | idx, spec->aa_mix_nid); | ||
2429 | if (err < 0) | ||
2430 | return err; | ||
2431 | add_loopback_list(spec, spec->aa_mix_nid, idx); | ||
2432 | } | ||
2433 | |||
2434 | /* remember the label for smart51 control */ | ||
2435 | for (j = 0; j < spec->smart51_nums; j++) { | ||
2436 | if (spec->smart51_pins[j] == pin) { | ||
2437 | spec->smart51_idxs[j] = idx; | ||
2438 | spec->smart51_labels[j] = label; | ||
2439 | break; | ||
2440 | } | ||
2441 | } | ||
2442 | } | ||
2443 | return 0; | ||
2444 | } | ||
2445 | |||
2446 | /* create mic-boost controls (if present) */ | ||
2447 | static int create_mic_boost_ctls(struct hda_codec *codec) | ||
2448 | { | ||
2449 | struct via_spec *spec = codec->spec; | ||
2450 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
2451 | const char *prev_label = NULL; | ||
2452 | int type_idx = 0; | ||
2453 | int i, err; | ||
2454 | |||
2455 | for (i = 0; i < cfg->num_inputs; i++) { | ||
2456 | hda_nid_t pin = cfg->inputs[i].pin; | ||
2457 | unsigned int caps; | ||
2458 | const char *label; | ||
2459 | char name[32]; | ||
2460 | |||
2461 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
2462 | continue; | ||
2463 | caps = query_amp_caps(codec, pin, HDA_INPUT); | ||
2464 | if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) | ||
2465 | continue; | ||
2466 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
2467 | if (prev_label && !strcmp(label, prev_label)) | ||
2468 | type_idx++; | ||
2469 | else | ||
2470 | type_idx = 0; | ||
2471 | prev_label = label; | ||
2472 | snprintf(name, sizeof(name), "%s Boost Volume", label); | ||
2473 | err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx, | ||
2474 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); | ||
2475 | if (err < 0) | ||
2476 | return err; | ||
2477 | } | ||
2478 | return 0; | ||
2479 | } | ||
2480 | |||
2481 | /* create capture and input-src controls for multiple streams */ | ||
2482 | static int create_multi_adc_ctls(struct hda_codec *codec) | ||
2483 | { | ||
2484 | struct via_spec *spec = codec->spec; | ||
2485 | int i, err; | ||
2486 | |||
2487 | /* create capture mixer elements */ | ||
2488 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
2489 | hda_nid_t adc = spec->adc_nids[i]; | ||
2490 | err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, | ||
2491 | "Capture Volume", i, | ||
2492 | HDA_COMPOSE_AMP_VAL(adc, 3, 0, | ||
2493 | HDA_INPUT)); | ||
2494 | if (err < 0) | ||
2495 | return err; | ||
2496 | err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE, | ||
2497 | "Capture Switch", i, | ||
2498 | HDA_COMPOSE_AMP_VAL(adc, 3, 0, | ||
2499 | HDA_INPUT)); | ||
2500 | if (err < 0) | ||
2501 | return err; | ||
2502 | } | ||
2503 | |||
2504 | /* input-source control */ | ||
2505 | for (i = 0; i < spec->num_adc_nids; i++) | ||
2506 | if (!spec->mux_nids[i]) | ||
2507 | break; | ||
2508 | err = create_input_src_ctls(codec, i); | ||
2509 | if (err < 0) | ||
2510 | return err; | ||
2511 | return 0; | ||
2512 | } | ||
2513 | |||
2514 | /* bind capture volume/switch */ | ||
2515 | static struct snd_kcontrol_new via_bind_cap_vol_ctl = | ||
2516 | HDA_BIND_VOL("Capture Volume", 0); | ||
2517 | static struct snd_kcontrol_new via_bind_cap_sw_ctl = | ||
2518 | HDA_BIND_SW("Capture Switch", 0); | ||
2519 | |||
2520 | static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret, | ||
2521 | struct hda_ctl_ops *ops) | ||
2522 | { | ||
2523 | struct hda_bind_ctls *ctl; | ||
2524 | int i; | ||
2525 | |||
2526 | ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL); | ||
2527 | if (!ctl) | ||
2528 | return -ENOMEM; | ||
2529 | ctl->ops = ops; | ||
2530 | for (i = 0; i < spec->num_adc_nids; i++) | ||
2531 | ctl->values[i] = | ||
2532 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT); | ||
2533 | *ctl_ret = ctl; | ||
2534 | return 0; | ||
2535 | } | ||
2536 | |||
2537 | /* create capture and input-src controls for dynamic ADC-switch case */ | ||
2538 | static int create_dyn_adc_ctls(struct hda_codec *codec) | ||
2539 | { | ||
2540 | struct via_spec *spec = codec->spec; | ||
2541 | struct snd_kcontrol_new *knew; | ||
2542 | int err; | ||
2543 | |||
2544 | /* set up the bind capture ctls */ | ||
2545 | err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol); | ||
2546 | if (err < 0) | ||
2547 | return err; | ||
2548 | err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw); | ||
2549 | if (err < 0) | ||
2550 | return err; | ||
2551 | |||
2552 | /* create capture mixer elements */ | ||
2553 | knew = via_clone_control(spec, &via_bind_cap_vol_ctl); | ||
2554 | if (!knew) | ||
2555 | return -ENOMEM; | ||
2556 | knew->private_value = (long)spec->bind_cap_vol; | ||
2557 | |||
2558 | knew = via_clone_control(spec, &via_bind_cap_sw_ctl); | ||
2559 | if (!knew) | ||
2560 | return -ENOMEM; | ||
2561 | knew->private_value = (long)spec->bind_cap_sw; | ||
2562 | |||
2563 | /* input-source control */ | ||
2564 | err = create_input_src_ctls(codec, 1); | ||
2565 | if (err < 0) | ||
2566 | return err; | ||
2567 | return 0; | ||
2568 | } | ||
2569 | |||
2570 | /* parse and create capture-related stuff */ | ||
2571 | static int via_auto_create_analog_input_ctls(struct hda_codec *codec) | ||
2572 | { | ||
2573 | struct via_spec *spec = codec->spec; | ||
2574 | int err; | ||
2575 | |||
2576 | err = parse_analog_inputs(codec); | ||
2577 | if (err < 0) | ||
2578 | return err; | ||
2579 | if (spec->dyn_adc_switch) | ||
2580 | err = create_dyn_adc_ctls(codec); | ||
2581 | else | ||
2582 | err = create_multi_adc_ctls(codec); | ||
2583 | if (err < 0) | ||
2584 | return err; | ||
2585 | err = create_loopback_ctls(codec); | ||
2586 | if (err < 0) | ||
2587 | return err; | ||
2588 | err = create_mic_boost_ctls(codec); | ||
2589 | if (err < 0) | ||
2590 | return err; | ||
2591 | return 0; | ||
2592 | } | ||
2593 | |||
2594 | static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) | 520 | static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) |
2595 | { | 521 | { |
2596 | unsigned int def_conf; | 522 | unsigned int def_conf; |
@@ -2633,102 +559,32 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, | |||
2633 | if (spec->vt1708_jack_detect == val) | 559 | if (spec->vt1708_jack_detect == val) |
2634 | return 0; | 560 | return 0; |
2635 | spec->vt1708_jack_detect = val; | 561 | spec->vt1708_jack_detect = val; |
2636 | if (spec->vt1708_jack_detect && | 562 | vt1708_update_hp_work(codec); |
2637 | snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) { | ||
2638 | mute_aa_path(codec, 1); | ||
2639 | notify_aa_path_ctls(codec); | ||
2640 | } | ||
2641 | via_hp_automute(codec); | ||
2642 | vt1708_update_hp_work(spec); | ||
2643 | return 1; | 563 | return 1; |
2644 | } | 564 | } |
2645 | 565 | ||
2646 | static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { | 566 | static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = { |
567 | { | ||
2647 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 568 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2648 | .name = "Jack Detect", | 569 | .name = "Jack Detect", |
2649 | .count = 1, | 570 | .count = 1, |
2650 | .info = snd_ctl_boolean_mono_info, | 571 | .info = snd_ctl_boolean_mono_info, |
2651 | .get = vt1708_jack_detect_get, | 572 | .get = vt1708_jack_detect_get, |
2652 | .put = vt1708_jack_detect_put, | 573 | .put = vt1708_jack_detect_put, |
574 | }, | ||
575 | {} /* terminator */ | ||
2653 | }; | 576 | }; |
2654 | 577 | ||
2655 | static void fill_dig_outs(struct hda_codec *codec); | 578 | static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) |
2656 | static void fill_dig_in(struct hda_codec *codec); | ||
2657 | |||
2658 | static int via_parse_auto_config(struct hda_codec *codec) | ||
2659 | { | ||
2660 | struct via_spec *spec = codec->spec; | ||
2661 | int err; | ||
2662 | |||
2663 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
2664 | if (err < 0) | ||
2665 | return err; | ||
2666 | if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) | ||
2667 | return -EINVAL; | ||
2668 | |||
2669 | err = via_auto_create_multi_out_ctls(codec); | ||
2670 | if (err < 0) | ||
2671 | return err; | ||
2672 | err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); | ||
2673 | if (err < 0) | ||
2674 | return err; | ||
2675 | err = via_auto_create_speaker_ctls(codec); | ||
2676 | if (err < 0) | ||
2677 | return err; | ||
2678 | err = via_auto_create_loopback_switch(codec); | ||
2679 | if (err < 0) | ||
2680 | return err; | ||
2681 | err = via_auto_create_analog_input_ctls(codec); | ||
2682 | if (err < 0) | ||
2683 | return err; | ||
2684 | |||
2685 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
2686 | |||
2687 | fill_dig_outs(codec); | ||
2688 | fill_dig_in(codec); | ||
2689 | |||
2690 | if (spec->kctls.list) | ||
2691 | spec->mixers[spec->num_mixers++] = spec->kctls.list; | ||
2692 | |||
2693 | |||
2694 | if (spec->hp_dac_nid && spec->hp_mix_path.depth) { | ||
2695 | err = via_hp_build(codec); | ||
2696 | if (err < 0) | ||
2697 | return err; | ||
2698 | } | ||
2699 | |||
2700 | err = via_smart51_build(codec); | ||
2701 | if (err < 0) | ||
2702 | return err; | ||
2703 | |||
2704 | /* assign slave outs */ | ||
2705 | if (spec->slave_dig_outs[0]) | ||
2706 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
2707 | |||
2708 | return 1; | ||
2709 | } | ||
2710 | |||
2711 | static void via_auto_init_dig_outs(struct hda_codec *codec) | ||
2712 | { | 579 | { |
2713 | struct via_spec *spec = codec->spec; | 580 | set_widgets_power_state(codec); |
2714 | if (spec->multiout.dig_out_nid) | 581 | snd_hda_gen_hp_automute(codec, tbl); |
2715 | init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT); | ||
2716 | if (spec->slave_dig_outs[0]) | ||
2717 | init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT); | ||
2718 | } | ||
2719 | |||
2720 | static void via_auto_init_dig_in(struct hda_codec *codec) | ||
2721 | { | ||
2722 | struct via_spec *spec = codec->spec; | ||
2723 | if (!spec->dig_in_nid) | ||
2724 | return; | ||
2725 | snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN); | ||
2726 | } | 582 | } |
2727 | 583 | ||
2728 | static void via_jack_output_event(struct hda_codec *codec, struct hda_jack_tbl *tbl) | 584 | static void via_line_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) |
2729 | { | 585 | { |
2730 | set_widgets_power_state(codec); | 586 | set_widgets_power_state(codec); |
2731 | via_hp_automute(codec); | 587 | snd_hda_gen_line_automute(codec, tbl); |
2732 | } | 588 | } |
2733 | 589 | ||
2734 | static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl) | 590 | static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl) |
@@ -2736,41 +592,55 @@ static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_t | |||
2736 | set_widgets_power_state(codec); | 592 | set_widgets_power_state(codec); |
2737 | } | 593 | } |
2738 | 594 | ||
2739 | /* initialize the unsolicited events */ | 595 | #define VIA_JACK_EVENT (HDA_GEN_LAST_EVENT + 1) |
2740 | static void via_auto_init_unsol_event(struct hda_codec *codec) | 596 | |
597 | static void via_set_jack_unsol_events(struct hda_codec *codec) | ||
2741 | { | 598 | { |
2742 | struct via_spec *spec = codec->spec; | 599 | struct via_spec *spec = codec->spec; |
2743 | struct auto_pin_cfg *cfg = &spec->autocfg; | 600 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
2744 | unsigned int ev; | 601 | hda_nid_t pin; |
2745 | int i; | 602 | int i; |
2746 | hda_jack_callback cb; | ||
2747 | |||
2748 | if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0])) | ||
2749 | snd_hda_jack_detect_enable_callback(codec, cfg->hp_pins[0], | ||
2750 | VIA_HP_EVENT | VIA_JACK_EVENT, | ||
2751 | via_jack_output_event); | ||
2752 | 603 | ||
604 | spec->gen.hp_automute_hook = via_hp_automute; | ||
2753 | if (cfg->speaker_pins[0]) | 605 | if (cfg->speaker_pins[0]) |
2754 | ev = VIA_LINE_EVENT; | 606 | spec->gen.line_automute_hook = via_line_automute; |
2755 | else | ||
2756 | ev = 0; | ||
2757 | cb = ev ? via_jack_output_event : via_jack_powerstate_event; | ||
2758 | 607 | ||
2759 | for (i = 0; i < cfg->line_outs; i++) { | 608 | for (i = 0; i < cfg->line_outs; i++) { |
2760 | if (cfg->line_out_pins[i] && | 609 | pin = cfg->line_out_pins[i]; |
2761 | is_jack_detectable(codec, cfg->line_out_pins[i])) | 610 | if (pin && !snd_hda_jack_tbl_get(codec, pin) && |
2762 | snd_hda_jack_detect_enable_callback(codec, cfg->line_out_pins[i], | 611 | is_jack_detectable(codec, pin)) |
2763 | ev | VIA_JACK_EVENT, cb); | 612 | snd_hda_jack_detect_enable_callback(codec, pin, |
613 | VIA_JACK_EVENT, | ||
614 | via_jack_powerstate_event); | ||
2764 | } | 615 | } |
2765 | 616 | ||
2766 | for (i = 0; i < cfg->num_inputs; i++) { | 617 | for (i = 0; i < cfg->num_inputs; i++) { |
2767 | if (is_jack_detectable(codec, cfg->inputs[i].pin)) | 618 | pin = cfg->line_out_pins[i]; |
2768 | snd_hda_jack_detect_enable_callback(codec, cfg->inputs[i].pin, | 619 | if (pin && !snd_hda_jack_tbl_get(codec, pin) && |
620 | is_jack_detectable(codec, pin)) | ||
621 | snd_hda_jack_detect_enable_callback(codec, pin, | ||
2769 | VIA_JACK_EVENT, | 622 | VIA_JACK_EVENT, |
2770 | via_jack_powerstate_event); | 623 | via_jack_powerstate_event); |
2771 | } | 624 | } |
2772 | } | 625 | } |
2773 | 626 | ||
627 | static int via_parse_auto_config(struct hda_codec *codec) | ||
628 | { | ||
629 | struct via_spec *spec = codec->spec; | ||
630 | int err; | ||
631 | |||
632 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); | ||
633 | if (err < 0) | ||
634 | return err; | ||
635 | |||
636 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); | ||
637 | if (err < 0) | ||
638 | return err; | ||
639 | |||
640 | via_set_jack_unsol_events(codec); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
2774 | static int via_init(struct hda_codec *codec) | 644 | static int via_init(struct hda_codec *codec) |
2775 | { | 645 | { |
2776 | struct via_spec *spec = codec->spec; | 646 | struct via_spec *spec = codec->spec; |
@@ -2783,63 +653,47 @@ static int via_init(struct hda_codec *codec) | |||
2783 | set_widgets_power_state(codec); | 653 | set_widgets_power_state(codec); |
2784 | __analog_low_current_mode(codec, true); | 654 | __analog_low_current_mode(codec, true); |
2785 | 655 | ||
2786 | via_auto_init_multi_out(codec); | 656 | snd_hda_gen_init(codec); |
2787 | via_auto_init_hp_out(codec); | ||
2788 | via_auto_init_speaker_out(codec); | ||
2789 | via_auto_init_analog_input(codec); | ||
2790 | via_auto_init_dig_outs(codec); | ||
2791 | via_auto_init_dig_in(codec); | ||
2792 | 657 | ||
2793 | via_auto_init_unsol_event(codec); | 658 | vt1708_update_hp_work(codec); |
2794 | |||
2795 | via_hp_automute(codec); | ||
2796 | vt1708_update_hp_work(spec); | ||
2797 | 659 | ||
2798 | return 0; | 660 | return 0; |
2799 | } | 661 | } |
2800 | 662 | ||
2801 | static void vt1708_update_hp_jack_state(struct work_struct *work) | 663 | static int vt1708_build_controls(struct hda_codec *codec) |
2802 | { | 664 | { |
2803 | struct via_spec *spec = container_of(work, struct via_spec, | 665 | /* In order not to create "Phantom Jack" controls, |
2804 | vt1708_hp_work.work); | 666 | temporary enable jackpoll */ |
2805 | if (spec->codec_type != VT1708) | 667 | int err; |
2806 | return; | 668 | int old_interval = codec->jackpoll_interval; |
2807 | snd_hda_jack_set_dirty_all(spec->codec); | 669 | codec->jackpoll_interval = msecs_to_jiffies(100); |
2808 | /* if jack state toggled */ | 670 | err = via_build_controls(codec); |
2809 | if (spec->vt1708_hp_present | 671 | codec->jackpoll_interval = old_interval; |
2810 | != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) { | 672 | return err; |
2811 | spec->vt1708_hp_present ^= 1; | ||
2812 | via_hp_automute(spec->codec); | ||
2813 | } | ||
2814 | if (spec->vt1708_jack_detect) | ||
2815 | schedule_delayed_work(&spec->vt1708_hp_work, | ||
2816 | msecs_to_jiffies(100)); | ||
2817 | } | 673 | } |
2818 | 674 | ||
2819 | static int get_mux_nids(struct hda_codec *codec) | 675 | static int vt1708_build_pcms(struct hda_codec *codec) |
2820 | { | 676 | { |
2821 | struct via_spec *spec = codec->spec; | 677 | struct via_spec *spec = codec->spec; |
2822 | hda_nid_t nid, conn[8]; | 678 | int i, err; |
2823 | unsigned int type; | 679 | |
2824 | int i, n; | 680 | err = snd_hda_gen_build_pcms(codec); |
2825 | 681 | if (err < 0 || codec->vendor_id != 0x11061708) | |
2826 | for (i = 0; i < spec->num_adc_nids; i++) { | 682 | return err; |
2827 | nid = spec->adc_nids[i]; | 683 | |
2828 | while (nid) { | 684 | /* We got noisy outputs on the right channel on VT1708 when |
2829 | type = get_wcaps_type(get_wcaps(codec, nid)); | 685 | * 24bit samples are used. Until any workaround is found, |
2830 | if (type == AC_WID_PIN) | 686 | * disable the 24bit format, so far. |
2831 | break; | 687 | */ |
2832 | n = snd_hda_get_connections(codec, nid, conn, | 688 | for (i = 0; i < codec->num_pcms; i++) { |
2833 | ARRAY_SIZE(conn)); | 689 | struct hda_pcm *info = &spec->gen.pcm_rec[i]; |
2834 | if (n <= 0) | 690 | if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || |
2835 | break; | 691 | info->pcm_type != HDA_PCM_TYPE_AUDIO) |
2836 | if (n > 1) { | 692 | continue; |
2837 | spec->mux_nids[i] = nid; | 693 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].formats = |
2838 | break; | 694 | SNDRV_PCM_FMTBIT_S16_LE; |
2839 | } | ||
2840 | nid = conn[0]; | ||
2841 | } | ||
2842 | } | 695 | } |
696 | |||
2843 | return 0; | 697 | return 0; |
2844 | } | 698 | } |
2845 | 699 | ||
@@ -2853,7 +707,15 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2853 | if (spec == NULL) | 707 | if (spec == NULL) |
2854 | return -ENOMEM; | 708 | return -ENOMEM; |
2855 | 709 | ||
2856 | spec->aa_mix_nid = 0x17; | 710 | spec->gen.mixer_nid = 0x17; |
711 | |||
712 | /* set jackpoll_interval while parsing the codec */ | ||
713 | codec->jackpoll_interval = msecs_to_jiffies(100); | ||
714 | spec->vt1708_jack_detect = 1; | ||
715 | |||
716 | /* don't support the input jack switching due to lack of unsol event */ | ||
717 | /* (it may work with polling, though, but it needs testing) */ | ||
718 | spec->gen.suppress_auto_mic = 1; | ||
2857 | 719 | ||
2858 | /* Add HP and CD pin config connect bit re-config action */ | 720 | /* Add HP and CD pin config connect bit re-config action */ |
2859 | vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); | 721 | vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); |
@@ -2867,18 +729,17 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2867 | } | 729 | } |
2868 | 730 | ||
2869 | /* add jack detect on/off control */ | 731 | /* add jack detect on/off control */ |
2870 | if (!via_clone_control(spec, &vt1708_jack_detect_ctl)) | 732 | spec->mixers[spec->num_mixers++] = vt1708_jack_detect_ctl; |
2871 | return -ENOMEM; | ||
2872 | |||
2873 | /* disable 32bit format on VT1708 */ | ||
2874 | if (codec->vendor_id == 0x11061708) | ||
2875 | spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; | ||
2876 | 733 | ||
2877 | spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs; | 734 | spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs; |
2878 | 735 | ||
2879 | codec->patch_ops = via_patch_ops; | 736 | codec->patch_ops = via_patch_ops; |
737 | codec->patch_ops.build_controls = vt1708_build_controls; | ||
738 | codec->patch_ops.build_pcms = vt1708_build_pcms; | ||
739 | |||
740 | /* clear jackpoll_interval again; it's set dynamically */ | ||
741 | codec->jackpoll_interval = 0; | ||
2880 | 742 | ||
2881 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); | ||
2882 | return 0; | 743 | return 0; |
2883 | } | 744 | } |
2884 | 745 | ||
@@ -2892,7 +753,7 @@ static int patch_vt1709(struct hda_codec *codec) | |||
2892 | if (spec == NULL) | 753 | if (spec == NULL) |
2893 | return -ENOMEM; | 754 | return -ENOMEM; |
2894 | 755 | ||
2895 | spec->aa_mix_nid = 0x18; | 756 | spec->gen.mixer_nid = 0x18; |
2896 | 757 | ||
2897 | err = via_parse_auto_config(codec); | 758 | err = via_parse_auto_config(codec); |
2898 | if (err < 0) { | 759 | if (err < 0) { |
@@ -2936,7 +797,7 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2936 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 797 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
2937 | parm = AC_PWRST_D3; | 798 | parm = AC_PWRST_D3; |
2938 | set_pin_power_state(codec, 0x19, &parm); | 799 | set_pin_power_state(codec, 0x19, &parm); |
2939 | if (spec->smart51_enabled) | 800 | if (smart51_enabled(codec)) |
2940 | set_pin_power_state(codec, 0x1b, &parm); | 801 | set_pin_power_state(codec, 0x1b, &parm); |
2941 | update_power_state(codec, 0x18, parm); | 802 | update_power_state(codec, 0x18, parm); |
2942 | update_power_state(codec, 0x11, parm); | 803 | update_power_state(codec, 0x11, parm); |
@@ -2945,7 +806,7 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2945 | if (is_8ch) { | 806 | if (is_8ch) { |
2946 | parm = AC_PWRST_D3; | 807 | parm = AC_PWRST_D3; |
2947 | set_pin_power_state(codec, 0x22, &parm); | 808 | set_pin_power_state(codec, 0x22, &parm); |
2948 | if (spec->smart51_enabled) | 809 | if (smart51_enabled(codec)) |
2949 | set_pin_power_state(codec, 0x1a, &parm); | 810 | set_pin_power_state(codec, 0x1a, &parm); |
2950 | update_power_state(codec, 0x26, parm); | 811 | update_power_state(codec, 0x26, parm); |
2951 | update_power_state(codec, 0x24, parm); | 812 | update_power_state(codec, 0x24, parm); |
@@ -2953,7 +814,7 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2953 | /* PW7(23h), SW2(27h), AOW2(25h) */ | 814 | /* PW7(23h), SW2(27h), AOW2(25h) */ |
2954 | parm = AC_PWRST_D3; | 815 | parm = AC_PWRST_D3; |
2955 | set_pin_power_state(codec, 0x23, &parm); | 816 | set_pin_power_state(codec, 0x23, &parm); |
2956 | if (spec->smart51_enabled) | 817 | if (smart51_enabled(codec)) |
2957 | set_pin_power_state(codec, 0x1a, &parm); | 818 | set_pin_power_state(codec, 0x1a, &parm); |
2958 | update_power_state(codec, 0x27, parm); | 819 | update_power_state(codec, 0x27, parm); |
2959 | update_power_state(codec, 0x25, parm); | 820 | update_power_state(codec, 0x25, parm); |
@@ -2973,7 +834,7 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2973 | if (is_8ch) { | 834 | if (is_8ch) { |
2974 | update_power_state(codec, 0x25, parm); | 835 | update_power_state(codec, 0x25, parm); |
2975 | update_power_state(codec, 0x27, parm); | 836 | update_power_state(codec, 0x27, parm); |
2976 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) | 837 | } else if (codec->vendor_id == 0x11064397 && spec->gen.indep_hp_enabled) |
2977 | update_power_state(codec, 0x25, parm); | 838 | update_power_state(codec, 0x25, parm); |
2978 | } | 839 | } |
2979 | 840 | ||
@@ -2991,7 +852,7 @@ static int patch_vt1708B(struct hda_codec *codec) | |||
2991 | if (spec == NULL) | 852 | if (spec == NULL) |
2992 | return -ENOMEM; | 853 | return -ENOMEM; |
2993 | 854 | ||
2994 | spec->aa_mix_nid = 0x16; | 855 | spec->gen.mixer_nid = 0x16; |
2995 | 856 | ||
2996 | /* automatic parse from the BIOS config */ | 857 | /* automatic parse from the BIOS config */ |
2997 | err = via_parse_auto_config(codec); | 858 | err = via_parse_auto_config(codec); |
@@ -3016,58 +877,6 @@ static const struct hda_verb vt1708S_init_verbs[] = { | |||
3016 | { } | 877 | { } |
3017 | }; | 878 | }; |
3018 | 879 | ||
3019 | /* fill out digital output widgets; one for master and one for slave outputs */ | ||
3020 | static void fill_dig_outs(struct hda_codec *codec) | ||
3021 | { | ||
3022 | struct via_spec *spec = codec->spec; | ||
3023 | int i; | ||
3024 | |||
3025 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
3026 | hda_nid_t nid; | ||
3027 | int conn; | ||
3028 | |||
3029 | nid = spec->autocfg.dig_out_pins[i]; | ||
3030 | if (!nid) | ||
3031 | continue; | ||
3032 | conn = snd_hda_get_connections(codec, nid, &nid, 1); | ||
3033 | if (conn < 1) | ||
3034 | continue; | ||
3035 | if (!spec->multiout.dig_out_nid) | ||
3036 | spec->multiout.dig_out_nid = nid; | ||
3037 | else { | ||
3038 | spec->slave_dig_outs[0] = nid; | ||
3039 | break; /* at most two dig outs */ | ||
3040 | } | ||
3041 | } | ||
3042 | } | ||
3043 | |||
3044 | static void fill_dig_in(struct hda_codec *codec) | ||
3045 | { | ||
3046 | struct via_spec *spec = codec->spec; | ||
3047 | hda_nid_t dig_nid; | ||
3048 | int i, err; | ||
3049 | |||
3050 | if (!spec->autocfg.dig_in_pin) | ||
3051 | return; | ||
3052 | |||
3053 | dig_nid = codec->start_nid; | ||
3054 | for (i = 0; i < codec->num_nodes; i++, dig_nid++) { | ||
3055 | unsigned int wcaps = get_wcaps(codec, dig_nid); | ||
3056 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) | ||
3057 | continue; | ||
3058 | if (!(wcaps & AC_WCAP_DIGITAL)) | ||
3059 | continue; | ||
3060 | if (!(wcaps & AC_WCAP_CONN_LIST)) | ||
3061 | continue; | ||
3062 | err = get_connection_index(codec, dig_nid, | ||
3063 | spec->autocfg.dig_in_pin); | ||
3064 | if (err >= 0) { | ||
3065 | spec->dig_in_nid = dig_nid; | ||
3066 | break; | ||
3067 | } | ||
3068 | } | ||
3069 | } | ||
3070 | |||
3071 | static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, | 880 | static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, |
3072 | int offset, int num_steps, int step_size) | 881 | int offset, int num_steps, int step_size) |
3073 | { | 882 | { |
@@ -3088,21 +897,10 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
3088 | if (spec == NULL) | 897 | if (spec == NULL) |
3089 | return -ENOMEM; | 898 | return -ENOMEM; |
3090 | 899 | ||
3091 | spec->aa_mix_nid = 0x16; | 900 | spec->gen.mixer_nid = 0x16; |
3092 | override_mic_boost(codec, 0x1a, 0, 3, 40); | 901 | override_mic_boost(codec, 0x1a, 0, 3, 40); |
3093 | override_mic_boost(codec, 0x1e, 0, 3, 40); | 902 | override_mic_boost(codec, 0x1e, 0, 3, 40); |
3094 | 903 | ||
3095 | /* automatic parse from the BIOS config */ | ||
3096 | err = via_parse_auto_config(codec); | ||
3097 | if (err < 0) { | ||
3098 | via_free(codec); | ||
3099 | return err; | ||
3100 | } | ||
3101 | |||
3102 | spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs; | ||
3103 | |||
3104 | codec->patch_ops = via_patch_ops; | ||
3105 | |||
3106 | /* correct names for VT1708BCE */ | 904 | /* correct names for VT1708BCE */ |
3107 | if (get_codec_type(codec) == VT1708BCE) { | 905 | if (get_codec_type(codec) == VT1708BCE) { |
3108 | kfree(codec->chip_name); | 906 | kfree(codec->chip_name); |
@@ -3119,6 +917,18 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
3119 | sizeof(codec->bus->card->mixername), | 917 | sizeof(codec->bus->card->mixername), |
3120 | "%s %s", codec->vendor_name, codec->chip_name); | 918 | "%s %s", codec->vendor_name, codec->chip_name); |
3121 | } | 919 | } |
920 | |||
921 | /* automatic parse from the BIOS config */ | ||
922 | err = via_parse_auto_config(codec); | ||
923 | if (err < 0) { | ||
924 | via_free(codec); | ||
925 | return err; | ||
926 | } | ||
927 | |||
928 | spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs; | ||
929 | |||
930 | codec->patch_ops = via_patch_ops; | ||
931 | |||
3122 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | 932 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; |
3123 | return 0; | 933 | return 0; |
3124 | } | 934 | } |
@@ -3173,7 +983,7 @@ static int patch_vt1702(struct hda_codec *codec) | |||
3173 | if (spec == NULL) | 983 | if (spec == NULL) |
3174 | return -ENOMEM; | 984 | return -ENOMEM; |
3175 | 985 | ||
3176 | spec->aa_mix_nid = 0x1a; | 986 | spec->gen.mixer_nid = 0x1a; |
3177 | 987 | ||
3178 | /* limit AA path volume to 0 dB */ | 988 | /* limit AA path volume to 0 dB */ |
3179 | snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT, | 989 | snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT, |
@@ -3240,17 +1050,17 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | |||
3240 | /* PW2 (26h), AOW2 (ah) */ | 1050 | /* PW2 (26h), AOW2 (ah) */ |
3241 | parm = AC_PWRST_D3; | 1051 | parm = AC_PWRST_D3; |
3242 | set_pin_power_state(codec, 0x26, &parm); | 1052 | set_pin_power_state(codec, 0x26, &parm); |
3243 | if (spec->smart51_enabled) | 1053 | if (smart51_enabled(codec)) |
3244 | set_pin_power_state(codec, 0x2b, &parm); | 1054 | set_pin_power_state(codec, 0x2b, &parm); |
3245 | update_power_state(codec, 0xa, parm); | 1055 | update_power_state(codec, 0xa, parm); |
3246 | 1056 | ||
3247 | /* PW0 (24h), AOW0 (8h) */ | 1057 | /* PW0 (24h), AOW0 (8h) */ |
3248 | parm = AC_PWRST_D3; | 1058 | parm = AC_PWRST_D3; |
3249 | set_pin_power_state(codec, 0x24, &parm); | 1059 | set_pin_power_state(codec, 0x24, &parm); |
3250 | if (!spec->hp_independent_mode) /* check for redirected HP */ | 1060 | if (!spec->gen.indep_hp_enabled) /* check for redirected HP */ |
3251 | set_pin_power_state(codec, 0x28, &parm); | 1061 | set_pin_power_state(codec, 0x28, &parm); |
3252 | update_power_state(codec, 0x8, parm); | 1062 | update_power_state(codec, 0x8, parm); |
3253 | if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3) | 1063 | if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3) |
3254 | parm = parm2; | 1064 | parm = parm2; |
3255 | update_power_state(codec, 0xb, parm); | 1065 | update_power_state(codec, 0xb, parm); |
3256 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | 1066 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ |
@@ -3259,11 +1069,11 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | |||
3259 | /* PW1 (25h), AOW1 (9h) */ | 1069 | /* PW1 (25h), AOW1 (9h) */ |
3260 | parm = AC_PWRST_D3; | 1070 | parm = AC_PWRST_D3; |
3261 | set_pin_power_state(codec, 0x25, &parm); | 1071 | set_pin_power_state(codec, 0x25, &parm); |
3262 | if (spec->smart51_enabled) | 1072 | if (smart51_enabled(codec)) |
3263 | set_pin_power_state(codec, 0x2a, &parm); | 1073 | set_pin_power_state(codec, 0x2a, &parm); |
3264 | update_power_state(codec, 0x9, parm); | 1074 | update_power_state(codec, 0x9, parm); |
3265 | 1075 | ||
3266 | if (spec->hp_independent_mode) { | 1076 | if (spec->gen.indep_hp_enabled) { |
3267 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ | 1077 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ |
3268 | parm = AC_PWRST_D3; | 1078 | parm = AC_PWRST_D3; |
3269 | set_pin_power_state(codec, 0x28, &parm); | 1079 | set_pin_power_state(codec, 0x28, &parm); |
@@ -3283,9 +1093,9 @@ static int add_secret_dac_path(struct hda_codec *codec) | |||
3283 | hda_nid_t conn[8]; | 1093 | hda_nid_t conn[8]; |
3284 | hda_nid_t nid; | 1094 | hda_nid_t nid; |
3285 | 1095 | ||
3286 | if (!spec->aa_mix_nid) | 1096 | if (!spec->gen.mixer_nid) |
3287 | return 0; | 1097 | return 0; |
3288 | nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn, | 1098 | nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn, |
3289 | ARRAY_SIZE(conn) - 1); | 1099 | ARRAY_SIZE(conn) - 1); |
3290 | for (i = 0; i < nums; i++) { | 1100 | for (i = 0; i < nums; i++) { |
3291 | if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) | 1101 | if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) |
@@ -3300,7 +1110,7 @@ static int add_secret_dac_path(struct hda_codec *codec) | |||
3300 | !(caps & AC_WCAP_DIGITAL)) { | 1110 | !(caps & AC_WCAP_DIGITAL)) { |
3301 | conn[nums++] = nid; | 1111 | conn[nums++] = nid; |
3302 | return snd_hda_override_conn_list(codec, | 1112 | return snd_hda_override_conn_list(codec, |
3303 | spec->aa_mix_nid, | 1113 | spec->gen.mixer_nid, |
3304 | nums, conn); | 1114 | nums, conn); |
3305 | } | 1115 | } |
3306 | } | 1116 | } |
@@ -3318,7 +1128,7 @@ static int patch_vt1718S(struct hda_codec *codec) | |||
3318 | if (spec == NULL) | 1128 | if (spec == NULL) |
3319 | return -ENOMEM; | 1129 | return -ENOMEM; |
3320 | 1130 | ||
3321 | spec->aa_mix_nid = 0x21; | 1131 | spec->gen.mixer_nid = 0x21; |
3322 | override_mic_boost(codec, 0x2b, 0, 3, 40); | 1132 | override_mic_boost(codec, 0x2b, 0, 3, 40); |
3323 | override_mic_boost(codec, 0x29, 0, 3, 40); | 1133 | override_mic_boost(codec, 0x29, 0, 3, 40); |
3324 | add_secret_dac_path(codec); | 1134 | add_secret_dac_path(codec); |
@@ -3449,7 +1259,7 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3449 | parm = AC_PWRST_D3; | 1259 | parm = AC_PWRST_D3; |
3450 | set_pin_power_state(codec, 0x19, &parm); | 1260 | set_pin_power_state(codec, 0x19, &parm); |
3451 | /* Smart 5.1 PW2(1bh) */ | 1261 | /* Smart 5.1 PW2(1bh) */ |
3452 | if (spec->smart51_enabled) | 1262 | if (smart51_enabled(codec)) |
3453 | set_pin_power_state(codec, 0x1b, &parm); | 1263 | set_pin_power_state(codec, 0x1b, &parm); |
3454 | update_power_state(codec, 0x18, parm); | 1264 | update_power_state(codec, 0x18, parm); |
3455 | update_power_state(codec, 0x11, parm); | 1265 | update_power_state(codec, 0x11, parm); |
@@ -3458,12 +1268,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3458 | parm = AC_PWRST_D3; | 1268 | parm = AC_PWRST_D3; |
3459 | set_pin_power_state(codec, 0x23, &parm); | 1269 | set_pin_power_state(codec, 0x23, &parm); |
3460 | /* Smart 5.1 PW1(1ah) */ | 1270 | /* Smart 5.1 PW1(1ah) */ |
3461 | if (spec->smart51_enabled) | 1271 | if (smart51_enabled(codec)) |
3462 | set_pin_power_state(codec, 0x1a, &parm); | 1272 | set_pin_power_state(codec, 0x1a, &parm); |
3463 | update_power_state(codec, 0x27, parm); | 1273 | update_power_state(codec, 0x27, parm); |
3464 | 1274 | ||
3465 | /* Smart 5.1 PW5(1eh) */ | 1275 | /* Smart 5.1 PW5(1eh) */ |
3466 | if (spec->smart51_enabled) | 1276 | if (smart51_enabled(codec)) |
3467 | set_pin_power_state(codec, 0x1e, &parm); | 1277 | set_pin_power_state(codec, 0x1e, &parm); |
3468 | update_power_state(codec, 0x25, parm); | 1278 | update_power_state(codec, 0x25, parm); |
3469 | 1279 | ||
@@ -3475,7 +1285,7 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3475 | mono_out = 0; | 1285 | mono_out = 0; |
3476 | else { | 1286 | else { |
3477 | present = snd_hda_jack_detect(codec, 0x1d); | 1287 | present = snd_hda_jack_detect(codec, 0x1d); |
3478 | if (!spec->hp_independent_mode && present) | 1288 | if (!spec->gen.indep_hp_enabled && present) |
3479 | mono_out = 0; | 1289 | mono_out = 0; |
3480 | else | 1290 | else |
3481 | mono_out = 1; | 1291 | mono_out = 1; |
@@ -3490,7 +1300,7 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3490 | set_pin_power_state(codec, 0x1c, &parm); | 1300 | set_pin_power_state(codec, 0x1c, &parm); |
3491 | set_pin_power_state(codec, 0x1d, &parm); | 1301 | set_pin_power_state(codec, 0x1d, &parm); |
3492 | /* HP Independent Mode, power on AOW3 */ | 1302 | /* HP Independent Mode, power on AOW3 */ |
3493 | if (spec->hp_independent_mode) | 1303 | if (spec->gen.indep_hp_enabled) |
3494 | update_power_state(codec, 0x25, parm); | 1304 | update_power_state(codec, 0x25, parm); |
3495 | 1305 | ||
3496 | /* force to D0 for internal Speaker */ | 1306 | /* force to D0 for internal Speaker */ |
@@ -3509,7 +1319,7 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
3509 | if (spec == NULL) | 1319 | if (spec == NULL) |
3510 | return -ENOMEM; | 1320 | return -ENOMEM; |
3511 | 1321 | ||
3512 | spec->aa_mix_nid = 0x16; | 1322 | spec->gen.mixer_nid = 0x16; |
3513 | override_mic_boost(codec, 0x1a, 0, 3, 40); | 1323 | override_mic_boost(codec, 0x1a, 0, 3, 40); |
3514 | override_mic_boost(codec, 0x1e, 0, 3, 40); | 1324 | override_mic_boost(codec, 0x1e, 0, 3, 40); |
3515 | 1325 | ||
@@ -3522,9 +1332,7 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
3522 | 1332 | ||
3523 | spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs; | 1333 | spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs; |
3524 | 1334 | ||
3525 | spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer; | 1335 | spec->mixers[spec->num_mixers++] = vt1716s_dmic_mixer; |
3526 | spec->num_mixers++; | ||
3527 | |||
3528 | spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer; | 1336 | spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer; |
3529 | 1337 | ||
3530 | codec->patch_ops = via_patch_ops; | 1338 | codec->patch_ops = via_patch_ops; |
@@ -3609,7 +1417,7 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3609 | update_power_state(codec, 0x35, parm); | 1417 | update_power_state(codec, 0x35, parm); |
3610 | } | 1418 | } |
3611 | 1419 | ||
3612 | if (spec->hp_independent_mode) | 1420 | if (spec->gen.indep_hp_enabled) |
3613 | update_power_state(codec, 0x9, AC_PWRST_D0); | 1421 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3614 | 1422 | ||
3615 | /* Class-D */ | 1423 | /* Class-D */ |
@@ -3707,7 +1515,7 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
3707 | if (spec == NULL) | 1515 | if (spec == NULL) |
3708 | return -ENOMEM; | 1516 | return -ENOMEM; |
3709 | 1517 | ||
3710 | spec->aa_mix_nid = 0x21; | 1518 | spec->gen.mixer_nid = 0x21; |
3711 | override_mic_boost(codec, 0x2b, 0, 3, 40); | 1519 | override_mic_boost(codec, 0x2b, 0, 3, 40); |
3712 | override_mic_boost(codec, 0x29, 0, 3, 40); | 1520 | override_mic_boost(codec, 0x29, 0, 3, 40); |
3713 | if (spec->codec_type == VT1802) | 1521 | if (spec->codec_type == VT1802) |
@@ -3778,7 +1586,7 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3778 | set_pin_power_state(codec, 0x25, &parm); | 1586 | set_pin_power_state(codec, 0x25, &parm); |
3779 | update_power_state(codec, 0x15, parm); | 1587 | update_power_state(codec, 0x15, parm); |
3780 | update_power_state(codec, 0x35, parm); | 1588 | update_power_state(codec, 0x35, parm); |
3781 | if (spec->hp_independent_mode) | 1589 | if (spec->gen.indep_hp_enabled) |
3782 | update_power_state(codec, 0x9, AC_PWRST_D0); | 1590 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3783 | 1591 | ||
3784 | /* Internal Speaker */ | 1592 | /* Internal Speaker */ |
@@ -3831,7 +1639,7 @@ static int patch_vt1812(struct hda_codec *codec) | |||
3831 | if (spec == NULL) | 1639 | if (spec == NULL) |
3832 | return -ENOMEM; | 1640 | return -ENOMEM; |
3833 | 1641 | ||
3834 | spec->aa_mix_nid = 0x21; | 1642 | spec->gen.mixer_nid = 0x21; |
3835 | override_mic_boost(codec, 0x2b, 0, 3, 40); | 1643 | override_mic_boost(codec, 0x2b, 0, 3, 40); |
3836 | override_mic_boost(codec, 0x29, 0, 3, 40); | 1644 | override_mic_boost(codec, 0x29, 0, 3, 40); |
3837 | add_secret_dac_path(codec); | 1645 | add_secret_dac_path(codec); |
@@ -3901,7 +1709,7 @@ static void set_widgets_power_state_vt3476(struct hda_codec *codec) | |||
3901 | parm = AC_PWRST_D3; | 1709 | parm = AC_PWRST_D3; |
3902 | set_pin_power_state(codec, 0x26, &parm); | 1710 | set_pin_power_state(codec, 0x26, &parm); |
3903 | update_power_state(codec, 0x36, parm); | 1711 | update_power_state(codec, 0x36, parm); |
3904 | if (spec->smart51_enabled) { | 1712 | if (smart51_enabled(codec)) { |
3905 | /* PW7(2bh), MW7(3bh), MUX7(1Bh) */ | 1713 | /* PW7(2bh), MW7(3bh), MUX7(1Bh) */ |
3906 | set_pin_power_state(codec, 0x2b, &parm); | 1714 | set_pin_power_state(codec, 0x2b, &parm); |
3907 | update_power_state(codec, 0x3b, parm); | 1715 | update_power_state(codec, 0x3b, parm); |
@@ -3913,7 +1721,7 @@ static void set_widgets_power_state_vt3476(struct hda_codec *codec) | |||
3913 | parm = AC_PWRST_D3; | 1721 | parm = AC_PWRST_D3; |
3914 | set_pin_power_state(codec, 0x25, &parm); | 1722 | set_pin_power_state(codec, 0x25, &parm); |
3915 | update_power_state(codec, 0x35, parm); | 1723 | update_power_state(codec, 0x35, parm); |
3916 | if (spec->smart51_enabled) { | 1724 | if (smart51_enabled(codec)) { |
3917 | /* PW6(2ah), MW6(3ah), MUX6(1ah) */ | 1725 | /* PW6(2ah), MW6(3ah), MUX6(1ah) */ |
3918 | set_pin_power_state(codec, 0x2a, &parm); | 1726 | set_pin_power_state(codec, 0x2a, &parm); |
3919 | update_power_state(codec, 0x3a, parm); | 1727 | update_power_state(codec, 0x3a, parm); |
@@ -3926,7 +1734,7 @@ static void set_widgets_power_state_vt3476(struct hda_codec *codec) | |||
3926 | set_pin_power_state(codec, 0x28, &parm); | 1734 | set_pin_power_state(codec, 0x28, &parm); |
3927 | update_power_state(codec, 0x38, parm); | 1735 | update_power_state(codec, 0x38, parm); |
3928 | update_power_state(codec, 0x18, parm); | 1736 | update_power_state(codec, 0x18, parm); |
3929 | if (spec->hp_independent_mode) | 1737 | if (spec->gen.indep_hp_enabled) |
3930 | update_conv_power_state(codec, 0xb, parm, 3); | 1738 | update_conv_power_state(codec, 0xb, parm, 3); |
3931 | parm2 = parm; /* for pin 0x0b */ | 1739 | parm2 = parm; /* for pin 0x0b */ |
3932 | 1740 | ||
@@ -3934,7 +1742,7 @@ static void set_widgets_power_state_vt3476(struct hda_codec *codec) | |||
3934 | parm = AC_PWRST_D3; | 1742 | parm = AC_PWRST_D3; |
3935 | set_pin_power_state(codec, 0x24, &parm); | 1743 | set_pin_power_state(codec, 0x24, &parm); |
3936 | update_power_state(codec, 0x34, parm); | 1744 | update_power_state(codec, 0x34, parm); |
3937 | if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3) | 1745 | if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3) |
3938 | parm = parm2; | 1746 | parm = parm2; |
3939 | update_conv_power_state(codec, 0x8, parm, 0); | 1747 | update_conv_power_state(codec, 0x8, parm, 0); |
3940 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | 1748 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ |
@@ -3951,7 +1759,7 @@ static int patch_vt3476(struct hda_codec *codec) | |||
3951 | if (spec == NULL) | 1759 | if (spec == NULL) |
3952 | return -ENOMEM; | 1760 | return -ENOMEM; |
3953 | 1761 | ||
3954 | spec->aa_mix_nid = 0x3f; | 1762 | spec->gen.mixer_nid = 0x3f; |
3955 | add_secret_dac_path(codec); | 1763 | add_secret_dac_path(codec); |
3956 | 1764 | ||
3957 | /* automatic parse from the BIOS config */ | 1765 | /* automatic parse from the BIOS config */ |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 3b9be752f3e2..b8fe40531b9c 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -3266,11 +3266,13 @@ static int check_default_spdif_aclink(struct pci_dev *pci) | |||
3266 | w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults); | 3266 | w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults); |
3267 | if (w) { | 3267 | if (w) { |
3268 | if (w->value) | 3268 | if (w->value) |
3269 | snd_printdd(KERN_INFO "intel8x0: Using SPDIF over " | 3269 | snd_printdd(KERN_INFO |
3270 | "AC-Link for %s\n", w->name); | 3270 | "intel8x0: Using SPDIF over AC-Link for %s\n", |
3271 | snd_pci_quirk_name(w)); | ||
3271 | else | 3272 | else |
3272 | snd_printdd(KERN_INFO "intel8x0: Using integrated " | 3273 | snd_printdd(KERN_INFO |
3273 | "SPDIF DMA for %s\n", w->name); | 3274 | "intel8x0: Using integrated SPDIF DMA for %s\n", |
3275 | snd_pci_quirk_name(w)); | ||
3274 | return w->value; | 3276 | return w->value; |
3275 | } | 3277 | } |
3276 | return 0; | 3278 | return 0; |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 9387533f70dc..c76ac1411210 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -2586,8 +2586,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2586 | else { | 2586 | else { |
2587 | quirk = snd_pci_quirk_lookup(pci, m3_amp_quirk_list); | 2587 | quirk = snd_pci_quirk_lookup(pci, m3_amp_quirk_list); |
2588 | if (quirk) { | 2588 | if (quirk) { |
2589 | snd_printdd(KERN_INFO "maestro3: set amp-gpio " | 2589 | snd_printdd(KERN_INFO |
2590 | "for '%s'\n", quirk->name); | 2590 | "maestro3: set amp-gpio for '%s'\n", |
2591 | snd_pci_quirk_name(quirk)); | ||
2591 | chip->amp_gpio = quirk->value; | 2592 | chip->amp_gpio = quirk->value; |
2592 | } else if (chip->allegro_flag) | 2593 | } else if (chip->allegro_flag) |
2593 | chip->amp_gpio = GPO_EXT_AMP_ALLEGRO; | 2594 | chip->amp_gpio = GPO_EXT_AMP_ALLEGRO; |
@@ -2597,8 +2598,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2597 | 2598 | ||
2598 | quirk = snd_pci_quirk_lookup(pci, m3_irda_quirk_list); | 2599 | quirk = snd_pci_quirk_lookup(pci, m3_irda_quirk_list); |
2599 | if (quirk) { | 2600 | if (quirk) { |
2600 | snd_printdd(KERN_INFO "maestro3: enabled irda workaround " | 2601 | snd_printdd(KERN_INFO |
2601 | "for '%s'\n", quirk->name); | 2602 | "maestro3: enabled irda workaround for '%s'\n", |
2603 | snd_pci_quirk_name(quirk)); | ||
2602 | chip->irda_workaround = 1; | 2604 | chip->irda_workaround = 1; |
2603 | } | 2605 | } |
2604 | quirk = snd_pci_quirk_lookup(pci, m3_hv_quirk_list); | 2606 | quirk = snd_pci_quirk_lookup(pci, m3_hv_quirk_list); |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 563a193e36a3..6febedb05936 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -1660,7 +1660,8 @@ static int snd_nm256_probe(struct pci_dev *pci, | |||
1660 | 1660 | ||
1661 | q = snd_pci_quirk_lookup(pci, nm256_quirks); | 1661 | q = snd_pci_quirk_lookup(pci, nm256_quirks); |
1662 | if (q) { | 1662 | if (q) { |
1663 | snd_printdd(KERN_INFO "nm256: Enabled quirk for %s.\n", q->name); | 1663 | snd_printdd(KERN_INFO "nm256: Enabled quirk for %s.\n", |
1664 | snd_pci_quirk_name(q)); | ||
1664 | switch (q->value) { | 1665 | switch (q->value) { |
1665 | case NM_BLACKLISTED: | 1666 | case NM_BLACKLISTED: |
1666 | printk(KERN_INFO "nm256: The device is blacklisted. " | 1667 | printk(KERN_INFO "nm256: The device is blacklisted. " |
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index b33db1e006e7..37b431b9b69d 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c | |||
@@ -1012,13 +1012,12 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err, | |||
1012 | enum pcxhr_async_err_src err_src, int pipe, | 1012 | enum pcxhr_async_err_src err_src, int pipe, |
1013 | int is_capture) | 1013 | int is_capture) |
1014 | { | 1014 | { |
1015 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1016 | static char* err_src_name[] = { | 1015 | static char* err_src_name[] = { |
1017 | [PCXHR_ERR_PIPE] = "Pipe", | 1016 | [PCXHR_ERR_PIPE] = "Pipe", |
1018 | [PCXHR_ERR_STREAM] = "Stream", | 1017 | [PCXHR_ERR_STREAM] = "Stream", |
1019 | [PCXHR_ERR_AUDIO] = "Audio" | 1018 | [PCXHR_ERR_AUDIO] = "Audio" |
1020 | }; | 1019 | }; |
1021 | #endif | 1020 | |
1022 | if (err & 0xfff) | 1021 | if (err & 0xfff) |
1023 | err &= 0xfff; | 1022 | err &= 0xfff; |
1024 | else | 1023 | else |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4fae81f21efb..94084cdb130c 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | |||
154 | #define HDSP_BIGENDIAN_MODE 0x200 | 154 | #define HDSP_BIGENDIAN_MODE 0x200 |
155 | #define HDSP_RD_MULTIPLE 0x400 | 155 | #define HDSP_RD_MULTIPLE 0x400 |
156 | #define HDSP_9652_ENABLE_MIXER 0x800 | 156 | #define HDSP_9652_ENABLE_MIXER 0x800 |
157 | #define HDSP_S200 0x800 | ||
158 | #define HDSP_S300 (0x100 | HDSP_S200) /* dummy, purpose of 0x100 unknown */ | ||
159 | #define HDSP_CYCLIC_MODE 0x1000 | ||
157 | #define HDSP_TDO 0x10000000 | 160 | #define HDSP_TDO 0x10000000 |
158 | 161 | ||
159 | #define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0) | 162 | #define HDSP_S_PROGRAM (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0) |
160 | #define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1) | 163 | #define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1) |
161 | 164 | ||
162 | /* Control Register bits */ | 165 | /* Control Register bits */ |
163 | 166 | ||
@@ -671,13 +674,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg) | |||
671 | 674 | ||
672 | static int hdsp_check_for_iobox (struct hdsp *hdsp) | 675 | static int hdsp_check_for_iobox (struct hdsp *hdsp) |
673 | { | 676 | { |
677 | int i; | ||
678 | |||
674 | if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; | 679 | if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; |
675 | if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { | 680 | for (i = 0; i < 500; i++) { |
676 | snd_printk("Hammerfall-DSP: no IO box connected!\n"); | 681 | if (0 == (hdsp_read(hdsp, HDSP_statusRegister) & |
677 | hdsp->state &= ~HDSP_FirmwareLoaded; | 682 | HDSP_ConfigError)) { |
678 | return -EIO; | 683 | if (i) { |
684 | snd_printd("Hammerfall-DSP: IO box found after %d ms\n", | ||
685 | (20 * i)); | ||
686 | } | ||
687 | return 0; | ||
688 | } | ||
689 | msleep(20); | ||
679 | } | 690 | } |
680 | return 0; | 691 | snd_printk(KERN_ERR "Hammerfall-DSP: no IO box connected!\n"); |
692 | hdsp->state &= ~HDSP_FirmwareLoaded; | ||
693 | return -EIO; | ||
681 | } | 694 | } |
682 | 695 | ||
683 | static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, | 696 | static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, |
@@ -728,6 +741,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
728 | 741 | ||
729 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { | 742 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { |
730 | snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); | 743 | snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); |
744 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | ||
731 | return -EIO; | 745 | return -EIO; |
732 | } | 746 | } |
733 | 747 | ||
@@ -737,17 +751,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { | |||
737 | hdsp_write(hdsp, HDSP_fifoData, cache[i]); | 751 | hdsp_write(hdsp, HDSP_fifoData, cache[i]); |
738 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { | 752 | if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { |
739 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); | 753 | snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); |
754 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | ||
740 | return -EIO; | 755 | return -EIO; |
741 | } | 756 | } |
742 | } | 757 | } |
743 | 758 | ||
744 | ssleep(3); | 759 | hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT); |
745 | 760 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); | |
746 | if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { | ||
747 | snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n"); | ||
748 | return -EIO; | ||
749 | } | ||
750 | 761 | ||
762 | ssleep(3); | ||
751 | #ifdef SNDRV_BIG_ENDIAN | 763 | #ifdef SNDRV_BIG_ENDIAN |
752 | hdsp->control2_register = HDSP_BIGENDIAN_MODE; | 764 | hdsp->control2_register = HDSP_BIGENDIAN_MODE; |
753 | #else | 765 | #else |
@@ -773,24 +785,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) | |||
773 | { | 785 | { |
774 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { | 786 | if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { |
775 | 787 | ||
776 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM); | 788 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); |
777 | hdsp_write (hdsp, HDSP_fifoData, 0); | 789 | hdsp_write(hdsp, HDSP_fifoData, 0); |
778 | if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) | ||
779 | return -EIO; | ||
780 | 790 | ||
781 | hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); | 791 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { |
792 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
793 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
794 | } | ||
795 | |||
796 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM); | ||
782 | hdsp_write (hdsp, HDSP_fifoData, 0); | 797 | hdsp_write (hdsp, HDSP_fifoData, 0); |
798 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { | ||
799 | hdsp->io_type = Multiface; | ||
800 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
801 | return 0; | ||
802 | } | ||
783 | 803 | ||
784 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { | 804 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); |
785 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); | 805 | hdsp_write(hdsp, HDSP_fifoData, 0); |
786 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | 806 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { |
787 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) | ||
788 | hdsp->io_type = RPM; | ||
789 | else | ||
790 | hdsp->io_type = Multiface; | ||
791 | } else { | ||
792 | hdsp->io_type = Digiface; | 807 | hdsp->io_type = Digiface; |
808 | snd_printk("Hammerfall-DSP: Digiface found\n"); | ||
809 | return 0; | ||
793 | } | 810 | } |
811 | |||
812 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
813 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
814 | hdsp_write(hdsp, HDSP_fifoData, 0); | ||
815 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { | ||
816 | hdsp->io_type = Multiface; | ||
817 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); | ||
822 | hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); | ||
823 | hdsp_write(hdsp, HDSP_fifoData, 0); | ||
824 | if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { | ||
825 | hdsp->io_type = Multiface; | ||
826 | snd_printk("Hammerfall-DSP: Multiface found\n"); | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | hdsp->io_type = RPM; | ||
831 | snd_printk("Hammerfall-DSP: RPM found\n"); | ||
832 | return 0; | ||
794 | } else { | 833 | } else { |
795 | /* firmware was already loaded, get iobox type */ | 834 | /* firmware was already loaded, get iobox type */ |
796 | if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) | 835 | if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) |
@@ -1674,171 +1713,50 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1674 | return change; | 1713 | return change; |
1675 | } | 1714 | } |
1676 | 1715 | ||
1677 | #define HDSP_SPDIF_OUT(xname, xindex) \ | 1716 | #define HDSP_TOGGLE_SETTING(xname, xindex) \ |
1678 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | 1717 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1679 | .info = snd_hdsp_info_spdif_bits, \ | 1718 | .name = xname, \ |
1680 | .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } | 1719 | .private_value = xindex, \ |
1681 | 1720 | .info = snd_hdsp_info_toggle_setting, \ | |
1682 | static int hdsp_spdif_out(struct hdsp *hdsp) | 1721 | .get = snd_hdsp_get_toggle_setting, \ |
1683 | { | 1722 | .put = snd_hdsp_put_toggle_setting \ |
1684 | return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0; | ||
1685 | } | ||
1686 | |||
1687 | static int hdsp_set_spdif_output(struct hdsp *hdsp, int out) | ||
1688 | { | ||
1689 | if (out) | ||
1690 | hdsp->control_register |= HDSP_SPDIFOpticalOut; | ||
1691 | else | ||
1692 | hdsp->control_register &= ~HDSP_SPDIFOpticalOut; | ||
1693 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1694 | return 0; | ||
1695 | } | ||
1696 | |||
1697 | #define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info | ||
1698 | |||
1699 | static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1700 | { | ||
1701 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1702 | |||
1703 | ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp); | ||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1708 | { | ||
1709 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1710 | int change; | ||
1711 | unsigned int val; | ||
1712 | |||
1713 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1714 | return -EBUSY; | ||
1715 | val = ucontrol->value.integer.value[0] & 1; | ||
1716 | spin_lock_irq(&hdsp->lock); | ||
1717 | change = (int)val != hdsp_spdif_out(hdsp); | ||
1718 | hdsp_set_spdif_output(hdsp, val); | ||
1719 | spin_unlock_irq(&hdsp->lock); | ||
1720 | return change; | ||
1721 | } | 1723 | } |
1722 | 1724 | ||
1723 | #define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ | 1725 | static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask) |
1724 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1725 | .info = snd_hdsp_info_spdif_bits, \ | ||
1726 | .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } | ||
1727 | |||
1728 | static int hdsp_spdif_professional(struct hdsp *hdsp) | ||
1729 | { | 1726 | { |
1730 | return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0; | 1727 | return (hdsp->control_register & regmask) ? 1 : 0; |
1731 | } | 1728 | } |
1732 | 1729 | ||
1733 | static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val) | 1730 | static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out) |
1734 | { | 1731 | { |
1735 | if (val) | 1732 | if (out) |
1736 | hdsp->control_register |= HDSP_SPDIFProfessional; | 1733 | hdsp->control_register |= regmask; |
1737 | else | 1734 | else |
1738 | hdsp->control_register &= ~HDSP_SPDIFProfessional; | 1735 | hdsp->control_register &= ~regmask; |
1739 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | 1736 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); |
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1744 | { | ||
1745 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1746 | 1737 | ||
1747 | ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp); | ||
1748 | return 0; | 1738 | return 0; |
1749 | } | 1739 | } |
1750 | 1740 | ||
1751 | static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1741 | #define snd_hdsp_info_toggle_setting snd_ctl_boolean_mono_info |
1752 | { | ||
1753 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1754 | int change; | ||
1755 | unsigned int val; | ||
1756 | |||
1757 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1758 | return -EBUSY; | ||
1759 | val = ucontrol->value.integer.value[0] & 1; | ||
1760 | spin_lock_irq(&hdsp->lock); | ||
1761 | change = (int)val != hdsp_spdif_professional(hdsp); | ||
1762 | hdsp_set_spdif_professional(hdsp, val); | ||
1763 | spin_unlock_irq(&hdsp->lock); | ||
1764 | return change; | ||
1765 | } | ||
1766 | |||
1767 | #define HDSP_SPDIF_EMPHASIS(xname, xindex) \ | ||
1768 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1769 | .info = snd_hdsp_info_spdif_bits, \ | ||
1770 | .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } | ||
1771 | 1742 | ||
1772 | static int hdsp_spdif_emphasis(struct hdsp *hdsp) | 1743 | static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol, |
1773 | { | 1744 | struct snd_ctl_elem_value *ucontrol) |
1774 | return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0; | ||
1775 | } | ||
1776 | |||
1777 | static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val) | ||
1778 | { | ||
1779 | if (val) | ||
1780 | hdsp->control_register |= HDSP_SPDIFEmphasis; | ||
1781 | else | ||
1782 | hdsp->control_register &= ~HDSP_SPDIFEmphasis; | ||
1783 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1788 | { | 1745 | { |
1789 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1746 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1747 | u32 regmask = kcontrol->private_value; | ||
1790 | 1748 | ||
1791 | ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp); | ||
1792 | return 0; | ||
1793 | } | ||
1794 | |||
1795 | static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1796 | { | ||
1797 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1798 | int change; | ||
1799 | unsigned int val; | ||
1800 | |||
1801 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
1802 | return -EBUSY; | ||
1803 | val = ucontrol->value.integer.value[0] & 1; | ||
1804 | spin_lock_irq(&hdsp->lock); | 1749 | spin_lock_irq(&hdsp->lock); |
1805 | change = (int)val != hdsp_spdif_emphasis(hdsp); | 1750 | ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask); |
1806 | hdsp_set_spdif_emphasis(hdsp, val); | ||
1807 | spin_unlock_irq(&hdsp->lock); | 1751 | spin_unlock_irq(&hdsp->lock); |
1808 | return change; | ||
1809 | } | ||
1810 | |||
1811 | #define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ | ||
1812 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
1813 | .info = snd_hdsp_info_spdif_bits, \ | ||
1814 | .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } | ||
1815 | |||
1816 | static int hdsp_spdif_nonaudio(struct hdsp *hdsp) | ||
1817 | { | ||
1818 | return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0; | ||
1819 | } | ||
1820 | |||
1821 | static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val) | ||
1822 | { | ||
1823 | if (val) | ||
1824 | hdsp->control_register |= HDSP_SPDIFNonAudio; | ||
1825 | else | ||
1826 | hdsp->control_register &= ~HDSP_SPDIFNonAudio; | ||
1827 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
1828 | return 0; | ||
1829 | } | ||
1830 | |||
1831 | static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1832 | { | ||
1833 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
1834 | |||
1835 | ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp); | ||
1836 | return 0; | 1752 | return 0; |
1837 | } | 1753 | } |
1838 | 1754 | ||
1839 | static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1755 | static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol, |
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1840 | { | 1757 | { |
1841 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | 1758 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); |
1759 | u32 regmask = kcontrol->private_value; | ||
1842 | int change; | 1760 | int change; |
1843 | unsigned int val; | 1761 | unsigned int val; |
1844 | 1762 | ||
@@ -1846,8 +1764,9 @@ static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd | |||
1846 | return -EBUSY; | 1764 | return -EBUSY; |
1847 | val = ucontrol->value.integer.value[0] & 1; | 1765 | val = ucontrol->value.integer.value[0] & 1; |
1848 | spin_lock_irq(&hdsp->lock); | 1766 | spin_lock_irq(&hdsp->lock); |
1849 | change = (int)val != hdsp_spdif_nonaudio(hdsp); | 1767 | change = (int) val != hdsp_toggle_setting(hdsp, regmask); |
1850 | hdsp_set_spdif_nonaudio(hdsp, val); | 1768 | if (change) |
1769 | hdsp_set_toggle_setting(hdsp, regmask, val); | ||
1851 | spin_unlock_irq(&hdsp->lock); | 1770 | spin_unlock_irq(&hdsp->lock); |
1852 | return change; | 1771 | return change; |
1853 | } | 1772 | } |
@@ -2451,114 +2370,6 @@ static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
2451 | return change; | 2370 | return change; |
2452 | } | 2371 | } |
2453 | 2372 | ||
2454 | #define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ | ||
2455 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2456 | .name = xname, \ | ||
2457 | .index = xindex, \ | ||
2458 | .info = snd_hdsp_info_xlr_breakout_cable, \ | ||
2459 | .get = snd_hdsp_get_xlr_breakout_cable, \ | ||
2460 | .put = snd_hdsp_put_xlr_breakout_cable \ | ||
2461 | } | ||
2462 | |||
2463 | static int hdsp_xlr_breakout_cable(struct hdsp *hdsp) | ||
2464 | { | ||
2465 | if (hdsp->control_register & HDSP_XLRBreakoutCable) | ||
2466 | return 1; | ||
2467 | return 0; | ||
2468 | } | ||
2469 | |||
2470 | static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode) | ||
2471 | { | ||
2472 | if (mode) | ||
2473 | hdsp->control_register |= HDSP_XLRBreakoutCable; | ||
2474 | else | ||
2475 | hdsp->control_register &= ~HDSP_XLRBreakoutCable; | ||
2476 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2477 | return 0; | ||
2478 | } | ||
2479 | |||
2480 | #define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info | ||
2481 | |||
2482 | static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2483 | { | ||
2484 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2485 | |||
2486 | ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp); | ||
2487 | return 0; | ||
2488 | } | ||
2489 | |||
2490 | static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2491 | { | ||
2492 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2493 | int change; | ||
2494 | int val; | ||
2495 | |||
2496 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2497 | return -EBUSY; | ||
2498 | val = ucontrol->value.integer.value[0] & 1; | ||
2499 | spin_lock_irq(&hdsp->lock); | ||
2500 | change = (int)val != hdsp_xlr_breakout_cable(hdsp); | ||
2501 | hdsp_set_xlr_breakout_cable(hdsp, val); | ||
2502 | spin_unlock_irq(&hdsp->lock); | ||
2503 | return change; | ||
2504 | } | ||
2505 | |||
2506 | /* (De)activates old RME Analog Extension Board | ||
2507 | These are connected to the internal ADAT connector | ||
2508 | Switching this on desactivates external ADAT | ||
2509 | */ | ||
2510 | #define HDSP_AEB(xname, xindex) \ | ||
2511 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2512 | .name = xname, \ | ||
2513 | .index = xindex, \ | ||
2514 | .info = snd_hdsp_info_aeb, \ | ||
2515 | .get = snd_hdsp_get_aeb, \ | ||
2516 | .put = snd_hdsp_put_aeb \ | ||
2517 | } | ||
2518 | |||
2519 | static int hdsp_aeb(struct hdsp *hdsp) | ||
2520 | { | ||
2521 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) | ||
2522 | return 1; | ||
2523 | return 0; | ||
2524 | } | ||
2525 | |||
2526 | static int hdsp_set_aeb(struct hdsp *hdsp, int mode) | ||
2527 | { | ||
2528 | if (mode) | ||
2529 | hdsp->control_register |= HDSP_AnalogExtensionBoard; | ||
2530 | else | ||
2531 | hdsp->control_register &= ~HDSP_AnalogExtensionBoard; | ||
2532 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2533 | return 0; | ||
2534 | } | ||
2535 | |||
2536 | #define snd_hdsp_info_aeb snd_ctl_boolean_mono_info | ||
2537 | |||
2538 | static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2539 | { | ||
2540 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2541 | |||
2542 | ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp); | ||
2543 | return 0; | ||
2544 | } | ||
2545 | |||
2546 | static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2547 | { | ||
2548 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2549 | int change; | ||
2550 | int val; | ||
2551 | |||
2552 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2553 | return -EBUSY; | ||
2554 | val = ucontrol->value.integer.value[0] & 1; | ||
2555 | spin_lock_irq(&hdsp->lock); | ||
2556 | change = (int)val != hdsp_aeb(hdsp); | ||
2557 | hdsp_set_aeb(hdsp, val); | ||
2558 | spin_unlock_irq(&hdsp->lock); | ||
2559 | return change; | ||
2560 | } | ||
2561 | |||
2562 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ | 2373 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ |
2563 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2374 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2564 | .name = xname, \ | 2375 | .name = xname, \ |
@@ -2747,58 +2558,6 @@ static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_c | |||
2747 | return 0; | 2558 | return 0; |
2748 | } | 2559 | } |
2749 | 2560 | ||
2750 | #define HDSP_LINE_OUT(xname, xindex) \ | ||
2751 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2752 | .name = xname, \ | ||
2753 | .index = xindex, \ | ||
2754 | .info = snd_hdsp_info_line_out, \ | ||
2755 | .get = snd_hdsp_get_line_out, \ | ||
2756 | .put = snd_hdsp_put_line_out \ | ||
2757 | } | ||
2758 | |||
2759 | static int hdsp_line_out(struct hdsp *hdsp) | ||
2760 | { | ||
2761 | return (hdsp->control_register & HDSP_LineOut) ? 1 : 0; | ||
2762 | } | ||
2763 | |||
2764 | static int hdsp_set_line_output(struct hdsp *hdsp, int out) | ||
2765 | { | ||
2766 | if (out) | ||
2767 | hdsp->control_register |= HDSP_LineOut; | ||
2768 | else | ||
2769 | hdsp->control_register &= ~HDSP_LineOut; | ||
2770 | hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); | ||
2771 | return 0; | ||
2772 | } | ||
2773 | |||
2774 | #define snd_hdsp_info_line_out snd_ctl_boolean_mono_info | ||
2775 | |||
2776 | static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2777 | { | ||
2778 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2779 | |||
2780 | spin_lock_irq(&hdsp->lock); | ||
2781 | ucontrol->value.integer.value[0] = hdsp_line_out(hdsp); | ||
2782 | spin_unlock_irq(&hdsp->lock); | ||
2783 | return 0; | ||
2784 | } | ||
2785 | |||
2786 | static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
2787 | { | ||
2788 | struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); | ||
2789 | int change; | ||
2790 | unsigned int val; | ||
2791 | |||
2792 | if (!snd_hdsp_use_is_exclusive(hdsp)) | ||
2793 | return -EBUSY; | ||
2794 | val = ucontrol->value.integer.value[0] & 1; | ||
2795 | spin_lock_irq(&hdsp->lock); | ||
2796 | change = (int)val != hdsp_line_out(hdsp); | ||
2797 | hdsp_set_line_output(hdsp, val); | ||
2798 | spin_unlock_irq(&hdsp->lock); | ||
2799 | return change; | ||
2800 | } | ||
2801 | |||
2802 | #define HDSP_PRECISE_POINTER(xname, xindex) \ | 2561 | #define HDSP_PRECISE_POINTER(xname, xindex) \ |
2803 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ | 2562 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ |
2804 | .name = xname, \ | 2563 | .name = xname, \ |
@@ -3190,7 +2949,7 @@ static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { | |||
3190 | HDSP_DA_GAIN("DA Gain", 0), | 2949 | HDSP_DA_GAIN("DA Gain", 0), |
3191 | HDSP_AD_GAIN("AD Gain", 0), | 2950 | HDSP_AD_GAIN("AD Gain", 0), |
3192 | HDSP_PHONE_GAIN("Phones Gain", 0), | 2951 | HDSP_PHONE_GAIN("Phones Gain", 0), |
3193 | HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), | 2952 | HDSP_TOGGLE_SETTING("XLR Breakout Cable", HDSP_XLRBreakoutCable), |
3194 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) | 2953 | HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) |
3195 | }; | 2954 | }; |
3196 | 2955 | ||
@@ -3232,10 +2991,10 @@ static struct snd_kcontrol_new snd_hdsp_controls[] = { | |||
3232 | }, | 2991 | }, |
3233 | HDSP_MIXER("Mixer", 0), | 2992 | HDSP_MIXER("Mixer", 0), |
3234 | HDSP_SPDIF_IN("IEC958 Input Connector", 0), | 2993 | HDSP_SPDIF_IN("IEC958 Input Connector", 0), |
3235 | HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0), | 2994 | HDSP_TOGGLE_SETTING("IEC958 Output also on ADAT1", HDSP_SPDIFOpticalOut), |
3236 | HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0), | 2995 | HDSP_TOGGLE_SETTING("IEC958 Professional Bit", HDSP_SPDIFProfessional), |
3237 | HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), | 2996 | HDSP_TOGGLE_SETTING("IEC958 Emphasis Bit", HDSP_SPDIFEmphasis), |
3238 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | 2997 | HDSP_TOGGLE_SETTING("IEC958 Non-audio Bit", HDSP_SPDIFNonAudio), |
3239 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 2998 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
3240 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 2999 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
3241 | { | 3000 | { |
@@ -3255,7 +3014,7 @@ HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0), | |||
3255 | HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), | 3014 | HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), |
3256 | HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), | 3015 | HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), |
3257 | HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), | 3016 | HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), |
3258 | HDSP_LINE_OUT("Line Out", 0), | 3017 | HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), |
3259 | HDSP_PRECISE_POINTER("Precise Pointer", 0), | 3018 | HDSP_PRECISE_POINTER("Precise Pointer", 0), |
3260 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), | 3019 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), |
3261 | }; | 3020 | }; |
@@ -3572,7 +3331,9 @@ static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { | |||
3572 | HDSP_MIXER("Mixer", 0) | 3331 | HDSP_MIXER("Mixer", 0) |
3573 | }; | 3332 | }; |
3574 | 3333 | ||
3575 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); | 3334 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = |
3335 | HDSP_TOGGLE_SETTING("Analog Extension Board", | ||
3336 | HDSP_AnalogExtensionBoard); | ||
3576 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; | 3337 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; |
3577 | 3338 | ||
3578 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) | 3339 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) |
@@ -3995,7 +3756,9 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | |||
3995 | } | 3756 | } |
3996 | snd_iprintf(buffer, "Phones Gain : %s\n", tmp); | 3757 | snd_iprintf(buffer, "Phones Gain : %s\n", tmp); |
3997 | 3758 | ||
3998 | snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no"); | 3759 | snd_iprintf(buffer, "XLR Breakout Cable : %s\n", |
3760 | hdsp_toggle_setting(hdsp, HDSP_XLRBreakoutCable) ? | ||
3761 | "yes" : "no"); | ||
3999 | 3762 | ||
4000 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) | 3763 | if (hdsp->control_register & HDSP_AnalogExtensionBoard) |
4001 | snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n"); | 3764 | snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n"); |
@@ -5026,29 +4789,38 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
5026 | for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) | 4789 | for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) |
5027 | info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); | 4790 | info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); |
5028 | info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); | 4791 | info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); |
5029 | info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); | 4792 | info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp, |
5030 | info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp); | 4793 | HDSP_SPDIFOpticalOut); |
5031 | info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp); | 4794 | info.spdif_professional = (unsigned char) |
5032 | info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp); | 4795 | hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional); |
4796 | info.spdif_emphasis = (unsigned char) | ||
4797 | hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis); | ||
4798 | info.spdif_nonaudio = (unsigned char) | ||
4799 | hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio); | ||
5033 | info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp); | 4800 | info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp); |
5034 | info.system_sample_rate = hdsp->system_sample_rate; | 4801 | info.system_sample_rate = hdsp->system_sample_rate; |
5035 | info.autosync_sample_rate = hdsp_external_sample_rate(hdsp); | 4802 | info.autosync_sample_rate = hdsp_external_sample_rate(hdsp); |
5036 | info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp); | 4803 | info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp); |
5037 | info.clock_source = (unsigned char)hdsp_clock_source(hdsp); | 4804 | info.clock_source = (unsigned char)hdsp_clock_source(hdsp); |
5038 | info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp); | 4805 | info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp); |
5039 | info.line_out = (unsigned char)hdsp_line_out(hdsp); | 4806 | info.line_out = (unsigned char) |
4807 | hdsp_toggle_setting(hdsp, HDSP_LineOut); | ||
5040 | if (hdsp->io_type == H9632) { | 4808 | if (hdsp->io_type == H9632) { |
5041 | info.da_gain = (unsigned char)hdsp_da_gain(hdsp); | 4809 | info.da_gain = (unsigned char)hdsp_da_gain(hdsp); |
5042 | info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp); | 4810 | info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp); |
5043 | info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); | 4811 | info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); |
5044 | info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); | 4812 | info.xlr_breakout_cable = |
4813 | (unsigned char)hdsp_toggle_setting(hdsp, | ||
4814 | HDSP_XLRBreakoutCable); | ||
5045 | 4815 | ||
5046 | } else if (hdsp->io_type == RPM) { | 4816 | } else if (hdsp->io_type == RPM) { |
5047 | info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); | 4817 | info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); |
5048 | info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); | 4818 | info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); |
5049 | } | 4819 | } |
5050 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) | 4820 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) |
5051 | info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); | 4821 | info.analog_extension_board = |
4822 | (unsigned char)hdsp_toggle_setting(hdsp, | ||
4823 | HDSP_AnalogExtensionBoard); | ||
5052 | spin_unlock_irqrestore(&hdsp->lock, flags); | 4824 | spin_unlock_irqrestore(&hdsp->lock, flags); |
5053 | if (copy_to_user(argp, &info, sizeof(info))) | 4825 | if (copy_to_user(argp, &info, sizeof(info))) |
5054 | return -EFAULT; | 4826 | return -EFAULT; |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 6442f611a07b..d756a3562706 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -2517,7 +2517,7 @@ static int check_dxs_list(struct pci_dev *pci, int revision) | |||
2517 | w = snd_pci_quirk_lookup(pci, dxs_whitelist); | 2517 | w = snd_pci_quirk_lookup(pci, dxs_whitelist); |
2518 | if (w) { | 2518 | if (w) { |
2519 | snd_printdd(KERN_INFO "via82xx: DXS white list for %s found\n", | 2519 | snd_printdd(KERN_INFO "via82xx: DXS white list for %s found\n", |
2520 | w->name); | 2520 | snd_pci_quirk_name(w)); |
2521 | return w->value; | 2521 | return w->value; |
2522 | } | 2522 | } |
2523 | 2523 | ||
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index c828f8189c25..e4d6dbb0342d 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -48,10 +48,10 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | |||
48 | "{Native Instruments, Audio 8 DJ}," | 48 | "{Native Instruments, Audio 8 DJ}," |
49 | "{Native Instruments, Traktor Audio 2}," | 49 | "{Native Instruments, Traktor Audio 2}," |
50 | "{Native Instruments, Session I/O}," | 50 | "{Native Instruments, Session I/O}," |
51 | "{Native Instruments, GuitarRig mobile}" | 51 | "{Native Instruments, GuitarRig mobile}," |
52 | "{Native Instruments, Traktor Kontrol X1}" | 52 | "{Native Instruments, Traktor Kontrol X1}," |
53 | "{Native Instruments, Traktor Kontrol S4}" | 53 | "{Native Instruments, Traktor Kontrol S4}," |
54 | "{Native Instruments, Maschine Controller}"); | 54 | "{Native Instruments, Maschine Controller}}"); |
55 | 55 | ||
56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
diff --git a/sound/usb/card.c b/sound/usb/card.c index ccf95cfe186f..803953a9bff3 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -646,7 +646,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | |||
646 | as->substream[0].need_setup_ep = | 646 | as->substream[0].need_setup_ep = |
647 | as->substream[1].need_setup_ep = true; | 647 | as->substream[1].need_setup_ep = true; |
648 | } | 648 | } |
649 | } | 649 | } |
650 | } else { | 650 | } else { |
651 | /* | 651 | /* |
652 | * otherwise we keep the rest of the system in the dark | 652 | * otherwise we keep the rest of the system in the dark |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index d82e378d37cb..81f70a719bb9 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -59,7 +59,12 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | |||
59 | 59 | ||
60 | /* Approximation based on number of samples per USB frame (ms), | 60 | /* Approximation based on number of samples per USB frame (ms), |
61 | some truncation for 44.1 but the estimate is good enough */ | 61 | some truncation for 44.1 but the estimate is good enough */ |
62 | est_delay = subs->last_delay - (frame_diff * rate / 1000); | 62 | est_delay = frame_diff * rate / 1000; |
63 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | ||
64 | est_delay = subs->last_delay - est_delay; | ||
65 | else | ||
66 | est_delay = subs->last_delay + est_delay; | ||
67 | |||
63 | if (est_delay < 0) | 68 | if (est_delay < 0) |
64 | est_delay = 0; | 69 | est_delay = 0; |
65 | return est_delay; | 70 | return est_delay; |
@@ -78,8 +83,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
78 | return SNDRV_PCM_POS_XRUN; | 83 | return SNDRV_PCM_POS_XRUN; |
79 | spin_lock(&subs->lock); | 84 | spin_lock(&subs->lock); |
80 | hwptr_done = subs->hwptr_done; | 85 | hwptr_done = subs->hwptr_done; |
81 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 86 | substream->runtime->delay = snd_usb_pcm_delay(subs, |
82 | substream->runtime->delay = snd_usb_pcm_delay(subs, | ||
83 | substream->runtime->rate); | 87 | substream->runtime->rate); |
84 | spin_unlock(&subs->lock); | 88 | spin_unlock(&subs->lock); |
85 | return hwptr_done / (substream->runtime->frame_bits >> 3); | 89 | return hwptr_done / (substream->runtime->frame_bits >> 3); |
@@ -1157,6 +1161,10 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1157 | int i, period_elapsed = 0; | 1161 | int i, period_elapsed = 0; |
1158 | unsigned long flags; | 1162 | unsigned long flags; |
1159 | unsigned char *cp; | 1163 | unsigned char *cp; |
1164 | int current_frame_number; | ||
1165 | |||
1166 | /* read frame number here, update pointer in critical section */ | ||
1167 | current_frame_number = usb_get_current_frame_number(subs->dev); | ||
1160 | 1168 | ||
1161 | stride = runtime->frame_bits >> 3; | 1169 | stride = runtime->frame_bits >> 3; |
1162 | 1170 | ||
@@ -1171,9 +1179,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1171 | if (!subs->txfr_quirk) | 1179 | if (!subs->txfr_quirk) |
1172 | bytes = frames * stride; | 1180 | bytes = frames * stride; |
1173 | if (bytes % (runtime->sample_bits >> 3) != 0) { | 1181 | if (bytes % (runtime->sample_bits >> 3) != 0) { |
1174 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1175 | int oldbytes = bytes; | 1182 | int oldbytes = bytes; |
1176 | #endif | ||
1177 | bytes = frames * stride; | 1183 | bytes = frames * stride; |
1178 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | 1184 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", |
1179 | oldbytes, bytes); | 1185 | oldbytes, bytes); |
@@ -1190,6 +1196,15 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1190 | subs->transfer_done -= runtime->period_size; | 1196 | subs->transfer_done -= runtime->period_size; |
1191 | period_elapsed = 1; | 1197 | period_elapsed = 1; |
1192 | } | 1198 | } |
1199 | /* capture delay is by construction limited to one URB, | ||
1200 | * reset delays here | ||
1201 | */ | ||
1202 | runtime->delay = subs->last_delay = 0; | ||
1203 | |||
1204 | /* realign last_frame_number */ | ||
1205 | subs->last_frame_number = current_frame_number; | ||
1206 | subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ | ||
1207 | |||
1193 | spin_unlock_irqrestore(&subs->lock, flags); | 1208 | spin_unlock_irqrestore(&subs->lock, flags); |
1194 | /* copy a data chunk */ | 1209 | /* copy a data chunk */ |
1195 | if (oldptr + bytes > runtime->buffer_size * stride) { | 1210 | if (oldptr + bytes > runtime->buffer_size * stride) { |