diff options
author | Kailang Yang <kailang@realtek.com> | 2013-11-08 02:54:49 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-11-08 07:52:59 -0500 |
commit | 9a22a8f558d09a83965d2bbe168294eb8ffb70e9 (patch) | |
tree | 4e950292303f998c97c3d5790ed9ccd1ce3ded51 /sound/pci/hda | |
parent | 885845d78551be7bf8570f6283df8b7a7797c4d1 (diff) |
ALSA: hda/realtek - Add new codec ALC255/ALC3234 UAJ supported
New codec ALC255/ALC3234 support multifunction jacks.
It used for menual select the input device.
Signed-off-by: Kailang Yang <kailang@realtek.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6a214662700e..24d924d563aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -577,26 +577,35 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) | |||
577 | /* | 577 | /* |
578 | * COEF access helper functions | 578 | * COEF access helper functions |
579 | */ | 579 | */ |
580 | static int alc_read_coef_idx(struct hda_codec *codec, | 580 | |
581 | unsigned int coef_idx) | 581 | static int alc_read_coefex_idx(struct hda_codec *codec, |
582 | hda_nid_t nid, | ||
583 | unsigned int coef_idx) | ||
582 | { | 584 | { |
583 | unsigned int val; | 585 | unsigned int val; |
584 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, | 586 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
585 | coef_idx); | 587 | coef_idx); |
586 | val = snd_hda_codec_read(codec, 0x20, 0, | 588 | val = snd_hda_codec_read(codec, nid, 0, |
587 | AC_VERB_GET_PROC_COEF, 0); | 589 | AC_VERB_GET_PROC_COEF, 0); |
588 | return val; | 590 | return val; |
589 | } | 591 | } |
590 | 592 | ||
591 | static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, | 593 | #define alc_read_coef_idx(codec, coef_idx) \ |
594 | alc_read_coefex_idx(codec, 0x20, coef_idx) | ||
595 | |||
596 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, | ||
597 | unsigned int coef_idx, | ||
592 | unsigned int coef_val) | 598 | unsigned int coef_val) |
593 | { | 599 | { |
594 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, | 600 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
595 | coef_idx); | 601 | coef_idx); |
596 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, | 602 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, |
597 | coef_val); | 603 | coef_val); |
598 | } | 604 | } |
599 | 605 | ||
606 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ | ||
607 | alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) | ||
608 | |||
600 | /* a special bypass for COEF 0; read the cached value at the second time */ | 609 | /* a special bypass for COEF 0; read the cached value at the second time */ |
601 | static unsigned int alc_get_coef0(struct hda_codec *codec) | 610 | static unsigned int alc_get_coef0(struct hda_codec *codec) |
602 | { | 611 | { |
@@ -3109,6 +3118,19 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) | |||
3109 | int val; | 3118 | int val; |
3110 | 3119 | ||
3111 | switch (codec->vendor_id) { | 3120 | switch (codec->vendor_id) { |
3121 | case 0x10ec0255: | ||
3122 | /* LDO and MISC control */ | ||
3123 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | ||
3124 | /* UAJ function set to menual mode */ | ||
3125 | alc_write_coef_idx(codec, 0x45, 0xd089); | ||
3126 | /* Direct Drive HP Amp control(Set to verb control)*/ | ||
3127 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | ||
3128 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); | ||
3129 | /* Set MIC2 Vref gate with HP */ | ||
3130 | alc_write_coef_idx(codec, 0x06, 0x6104); | ||
3131 | /* Direct Drive HP Amp control */ | ||
3132 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | ||
3133 | break; | ||
3112 | case 0x10ec0283: | 3134 | case 0x10ec0283: |
3113 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3135 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3114 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3136 | alc_write_coef_idx(codec, 0x45, 0xc429); |
@@ -3140,6 +3162,14 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
3140 | int val; | 3162 | int val; |
3141 | 3163 | ||
3142 | switch (codec->vendor_id) { | 3164 | switch (codec->vendor_id) { |
3165 | case 0x10ec0255: | ||
3166 | alc_write_coef_idx(codec, 0x45, 0xc489); | ||
3167 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
3168 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | ||
3169 | /* Set MIC2 Vref gate to normal */ | ||
3170 | alc_write_coef_idx(codec, 0x06, 0x6100); | ||
3171 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
3172 | break; | ||
3143 | case 0x10ec0283: | 3173 | case 0x10ec0283: |
3144 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3174 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3145 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3175 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
@@ -3171,6 +3201,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
3171 | static void alc_headset_mode_default(struct hda_codec *codec) | 3201 | static void alc_headset_mode_default(struct hda_codec *codec) |
3172 | { | 3202 | { |
3173 | switch (codec->vendor_id) { | 3203 | switch (codec->vendor_id) { |
3204 | case 0x10ec0255: | ||
3205 | alc_write_coef_idx(codec, 0x45, 0xc089); | ||
3206 | alc_write_coef_idx(codec, 0x45, 0xc489); | ||
3207 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | ||
3208 | alc_write_coef_idx(codec, 0x49, 0x0049); | ||
3209 | break; | ||
3174 | case 0x10ec0283: | 3210 | case 0x10ec0283: |
3175 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3211 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3176 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3212 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
@@ -3194,6 +3230,12 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
3194 | static void alc_headset_mode_ctia(struct hda_codec *codec) | 3230 | static void alc_headset_mode_ctia(struct hda_codec *codec) |
3195 | { | 3231 | { |
3196 | switch (codec->vendor_id) { | 3232 | switch (codec->vendor_id) { |
3233 | case 0x10ec0255: | ||
3234 | /* Set to CTIA type */ | ||
3235 | alc_write_coef_idx(codec, 0x45, 0xd489); | ||
3236 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
3237 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | ||
3238 | break; | ||
3197 | case 0x10ec0283: | 3239 | case 0x10ec0283: |
3198 | alc_write_coef_idx(codec, 0x45, 0xd429); | 3240 | alc_write_coef_idx(codec, 0x45, 0xd429); |
3199 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3241 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
@@ -3216,6 +3258,12 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
3216 | static void alc_headset_mode_omtp(struct hda_codec *codec) | 3258 | static void alc_headset_mode_omtp(struct hda_codec *codec) |
3217 | { | 3259 | { |
3218 | switch (codec->vendor_id) { | 3260 | switch (codec->vendor_id) { |
3261 | case 0x10ec0255: | ||
3262 | /* Set to OMTP Type */ | ||
3263 | alc_write_coef_idx(codec, 0x45, 0xe489); | ||
3264 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
3265 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | ||
3266 | break; | ||
3219 | case 0x10ec0283: | 3267 | case 0x10ec0283: |
3220 | alc_write_coef_idx(codec, 0x45, 0xe429); | 3268 | alc_write_coef_idx(codec, 0x45, 0xe429); |
3221 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3269 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
@@ -3241,6 +3289,15 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
3241 | struct alc_spec *spec = codec->spec; | 3289 | struct alc_spec *spec = codec->spec; |
3242 | 3290 | ||
3243 | switch (codec->vendor_id) { | 3291 | switch (codec->vendor_id) { |
3292 | case 0x10ec0255: | ||
3293 | /* combo jack auto switch control(Check type)*/ | ||
3294 | alc_write_coef_idx(codec, 0x45, 0xd089); | ||
3295 | /* combo jack auto switch control(Vref conteol) */ | ||
3296 | alc_write_coef_idx(codec, 0x49, 0x0149); | ||
3297 | msleep(300); | ||
3298 | val = alc_read_coef_idx(codec, 0x46); | ||
3299 | is_ctia = (val & 0x0070) == 0x0070; | ||
3300 | break; | ||
3244 | case 0x10ec0283: | 3301 | case 0x10ec0283: |
3245 | alc_write_coef_idx(codec, 0x45, 0xd029); | 3302 | alc_write_coef_idx(codec, 0x45, 0xd029); |
3246 | msleep(300); | 3303 | msleep(300); |
@@ -3387,6 +3444,21 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | |||
3387 | alc_fixup_headset_mode(codec, fix, action); | 3444 | alc_fixup_headset_mode(codec, fix, action); |
3388 | } | 3445 | } |
3389 | 3446 | ||
3447 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, | ||
3448 | const struct hda_fixup *fix, int action) | ||
3449 | { | ||
3450 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3451 | /* Set to iphone type */ | ||
3452 | alc_write_coef_idx(codec, 0x1b, 0x880b); | ||
3453 | alc_write_coef_idx(codec, 0x45, 0xd089); | ||
3454 | alc_write_coef_idx(codec, 0x1b, 0x080b); | ||
3455 | alc_write_coef_idx(codec, 0x46, 0x0004); | ||
3456 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | ||
3457 | msleep(30); | ||
3458 | } | ||
3459 | alc_fixup_headset_mode(codec, fix, action); | ||
3460 | } | ||
3461 | |||
3390 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 3462 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3391 | const struct hda_fixup *fix, int action) | 3463 | const struct hda_fixup *fix, int action) |
3392 | { | 3464 | { |
@@ -3688,6 +3760,8 @@ enum { | |||
3688 | ALC283_FIXUP_INT_MIC, | 3760 | ALC283_FIXUP_INT_MIC, |
3689 | ALC290_FIXUP_MONO_SPEAKERS, | 3761 | ALC290_FIXUP_MONO_SPEAKERS, |
3690 | ALC269_FIXUP_THINKPAD_ACPI, | 3762 | ALC269_FIXUP_THINKPAD_ACPI, |
3763 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
3764 | ALC255_FIXUP_HEADSET_MODE, | ||
3691 | }; | 3765 | }; |
3692 | 3766 | ||
3693 | static const struct hda_fixup alc269_fixups[] = { | 3767 | static const struct hda_fixup alc269_fixups[] = { |
@@ -3997,6 +4071,20 @@ static const struct hda_fixup alc269_fixups[] = { | |||
3997 | .chained = true, | 4071 | .chained = true, |
3998 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | 4072 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST |
3999 | }, | 4073 | }, |
4074 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { | ||
4075 | .type = HDA_FIXUP_PINS, | ||
4076 | .v.pins = (const struct hda_pintbl[]) { | ||
4077 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
4078 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | ||
4079 | { } | ||
4080 | }, | ||
4081 | .chained = true, | ||
4082 | .chain_id = ALC255_FIXUP_HEADSET_MODE | ||
4083 | }, | ||
4084 | [ALC255_FIXUP_HEADSET_MODE] = { | ||
4085 | .type = HDA_FIXUP_FUNC, | ||
4086 | .v.func = alc_fixup_headset_mode_alc255, | ||
4087 | }, | ||
4000 | }; | 4088 | }; |
4001 | 4089 | ||
4002 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4090 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -4039,6 +4127,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4039 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4127 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4040 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4128 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4041 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), | 4129 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), |
4130 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4131 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4042 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4132 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4043 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4133 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4044 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4134 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |