aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_via.c106
1 files changed, 104 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 59a173e88128..63e4871e5d8f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -35,6 +35,7 @@
35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ 35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36/* 2008-04-09 Lydia Wang Add Independent HP feature */ 36/* 2008-04-09 Lydia Wang Add Independent HP feature */
37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ 37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
38/* */ 39/* */
39/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 40/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40 41
@@ -87,6 +88,48 @@
87#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397) 88#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397)
88#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398) 89#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398)
89 90
91enum VIA_HDA_CODEC {
92 UNKNOWN = -1,
93 VT1708,
94 VT1709_10CH,
95 VT1709_6CH,
96 VT1708B_8CH,
97 VT1708B_4CH,
98 VT1708S,
99 VT1702,
100 CODEC_TYPES,
101};
102
103static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
104{
105 u16 ven_id = vendor_id >> 16;
106 u16 dev_id = vendor_id & 0xffff;
107 enum VIA_HDA_CODEC codec_type;
108
109 /* get codec type */
110 if (ven_id != 0x1106)
111 codec_type = UNKNOWN;
112 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
113 codec_type = VT1708;
114 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
115 codec_type = VT1709_10CH;
116 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
117 codec_type = VT1709_6CH;
118 else if (dev_id >= 0xe720 && dev_id <= 0xe723)
119 codec_type = VT1708B_8CH;
120 else if (dev_id >= 0xe724 && dev_id <= 0xe727)
121 codec_type = VT1708B_4CH;
122 else if ((dev_id & 0xfff) == 0x397
123 && (dev_id >> 12) < 8)
124 codec_type = VT1708S;
125 else if ((dev_id & 0xfff) == 0x398
126 && (dev_id >> 12) < 8)
127 codec_type = VT1702;
128 else
129 codec_type = UNKNOWN;
130 return codec_type;
131};
132
90#define VIA_HP_EVENT 0x01 133#define VIA_HP_EVENT 0x01
91#define VIA_GPIO_EVENT 0x02 134#define VIA_GPIO_EVENT 0x02
92 135
@@ -102,6 +145,48 @@ enum {
102 AUTO_SEQ_SIDE 145 AUTO_SEQ_SIDE
103}; 146};
104 147
148#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
149
150/* Some VT1708S based boards gets the micboost setting wrong, so we have
151 * to apply some brute-force and re-write the TLV's by software. */
152static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
153 unsigned int size, unsigned int __user *_tlv)
154{
155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
156 hda_nid_t nid = get_amp_nid(kcontrol);
157
158 if (get_codec_type(codec->vendor_id) == VT1708S
159 && (nid == 0x1a || nid == 0x1e)) {
160 if (size < 4 * sizeof(unsigned int))
161 return -ENOMEM;
162 if (put_user(1, _tlv)) /* SNDRV_CTL_TLVT_DB_SCALE */
163 return -EFAULT;
164 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
165 return -EFAULT;
166 if (put_user(0, _tlv + 2)) /* offset = 0 */
167 return -EFAULT;
168 if (put_user(1000, _tlv + 3)) /* step size = 10 dB */
169 return -EFAULT;
170 }
171 return 0;
172}
173
174static int mic_boost_volume_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
178 hda_nid_t nid = get_amp_nid(kcontrol);
179
180 if (get_codec_type(codec->vendor_id) == VT1708S
181 && (nid == 0x1a || nid == 0x1e)) {
182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
183 uinfo->count = 2;
184 uinfo->value.integer.min = 0;
185 uinfo->value.integer.max = 3;
186 }
187 return 0;
188}
189
105static struct snd_kcontrol_new vt1708_control_templates[] = { 190static struct snd_kcontrol_new vt1708_control_templates[] = {
106 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 191 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
107 HDA_CODEC_MUTE(NULL, 0, 0, 0), 192 HDA_CODEC_MUTE(NULL, 0, 0, 0),
@@ -2430,14 +2515,29 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
2430 2515
2431/* Patch for VT1708S */ 2516/* Patch for VT1708S */
2432 2517
2518/* VT1708S software backdoor based override for buggy hardware micboost
2519 * setting */
2520#define MIC_BOOST_VOLUME(xname, nid) { \
2521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2522 .name = xname, \
2523 .index = 0, \
2524 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2525 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2526 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
2527 .info = mic_boost_volume_info, \
2528 .get = snd_hda_mixer_amp_volume_get, \
2529 .put = snd_hda_mixer_amp_volume_put, \
2530 .tlv = { .c = mic_boost_tlv }, \
2531 .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
2532
2433/* capture mixer elements */ 2533/* capture mixer elements */
2434static struct snd_kcontrol_new vt1708S_capture_mixer[] = { 2534static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
2435 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 2535 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2436 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 2536 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2437 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 2537 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2438 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 2538 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2439 HDA_CODEC_VOLUME("Mic Boost", 0x1A, 0x0, HDA_INPUT), 2539 MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A),
2440 HDA_CODEC_VOLUME("Front Mic Boost", 0x1E, 0x0, HDA_INPUT), 2540 MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E),
2441 { 2541 {
2442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2443 /* The multiple "Capture Source" controls confuse alsamixer 2543 /* The multiple "Capture Source" controls confuse alsamixer
@@ -2472,6 +2572,8 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
2472 /* PW9, PW10 Output enable */ 2572 /* PW9, PW10 Output enable */
2473 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 2573 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 2574 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2575 /* Enable Mic Boost Volume backdoor */
2576 {0x1, 0xf98, 0x1},
2475 { } 2577 { }
2476}; 2578};
2477 2579