aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorKailang Yang <kailang@realtek.com>2013-11-08 02:54:49 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-08 07:52:59 -0500
commit9a22a8f558d09a83965d2bbe168294eb8ffb70e9 (patch)
tree4e950292303f998c97c3d5790ed9ccd1ce3ded51 /sound/pci/hda
parent885845d78551be7bf8570f6283df8b7a7797c4d1 (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.c104
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 */
580static int alc_read_coef_idx(struct hda_codec *codec, 580
581 unsigned int coef_idx) 581static 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
591static 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
596static 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 */
601static unsigned int alc_get_coef0(struct hda_codec *codec) 610static 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,
3171static void alc_headset_mode_default(struct hda_codec *codec) 3201static 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)
3194static void alc_headset_mode_ctia(struct hda_codec *codec) 3230static 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)
3216static void alc_headset_mode_omtp(struct hda_codec *codec) 3258static 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
3447static 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
3390static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, 3462static 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
3693static const struct hda_fixup alc269_fixups[] = { 3767static 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
4002static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4090static 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),