alc880_quirks.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * ALC880 quirk models
  3. * included by patch_realtek.c
  4. */
  5. /* ALC880 board config type */
  6. enum {
  7. ALC880_AUTO,
  8. ALC880_3ST,
  9. ALC880_3ST_DIG,
  10. ALC880_5ST,
  11. ALC880_5ST_DIG,
  12. ALC880_Z71V,
  13. ALC880_6ST,
  14. ALC880_6ST_DIG,
  15. ALC880_ASUS,
  16. ALC880_ASUS_DIG,
  17. ALC880_ASUS_W1V,
  18. ALC880_ASUS_DIG2,
  19. ALC880_UNIWILL_DIG,
  20. #ifdef CONFIG_SND_DEBUG
  21. ALC880_TEST,
  22. #endif
  23. ALC880_MODEL_LAST /* last tag */
  24. };
  25. /*
  26. * ALC880 3-stack model
  27. *
  28. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
  29. * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
  30. * F-Mic = 0x1b, HP = 0x19
  31. */
  32. static const hda_nid_t alc880_dac_nids[4] = {
  33. /* front, rear, clfe, rear_surr */
  34. 0x02, 0x05, 0x04, 0x03
  35. };
  36. static const hda_nid_t alc880_adc_nids[3] = {
  37. /* ADC0-2 */
  38. 0x07, 0x08, 0x09,
  39. };
  40. /* The datasheet says the node 0x07 is connected from inputs,
  41. * but it shows zero connection in the real implementation on some devices.
  42. * Note: this is a 915GAV bug, fixed on 915GLV
  43. */
  44. static const hda_nid_t alc880_adc_nids_alt[2] = {
  45. /* ADC1-2 */
  46. 0x08, 0x09,
  47. };
  48. #define ALC880_DIGOUT_NID 0x06
  49. #define ALC880_DIGIN_NID 0x0a
  50. #define ALC880_PIN_CD_NID 0x1c
  51. static const struct hda_input_mux alc880_capture_source = {
  52. .num_items = 4,
  53. .items = {
  54. { "Mic", 0x0 },
  55. { "Front Mic", 0x3 },
  56. { "Line", 0x2 },
  57. { "CD", 0x4 },
  58. },
  59. };
  60. /* channel source setting (2/6 channel selection for 3-stack) */
  61. /* 2ch mode */
  62. static const struct hda_verb alc880_threestack_ch2_init[] = {
  63. /* set line-in to input, mute it */
  64. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  65. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  66. /* set mic-in to input vref 80%, mute it */
  67. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  68. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  69. { } /* end */
  70. };
  71. /* 6ch mode */
  72. static const struct hda_verb alc880_threestack_ch6_init[] = {
  73. /* set line-in to output, unmute it */
  74. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  75. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  76. /* set mic-in to output, unmute it */
  77. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  78. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  79. { } /* end */
  80. };
  81. static const struct hda_channel_mode alc880_threestack_modes[2] = {
  82. { 2, alc880_threestack_ch2_init },
  83. { 6, alc880_threestack_ch6_init },
  84. };
  85. static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
  86. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  87. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  88. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  89. HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
  90. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  91. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  92. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  93. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  94. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  95. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  96. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  97. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  98. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  99. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  100. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
  101. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
  102. HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
  103. {
  104. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  105. .name = "Channel Mode",
  106. .info = alc_ch_mode_info,
  107. .get = alc_ch_mode_get,
  108. .put = alc_ch_mode_put,
  109. },
  110. { } /* end */
  111. };
  112. /*
  113. * ALC880 5-stack model
  114. *
  115. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
  116. * Side = 0x02 (0xd)
  117. * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
  118. * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
  119. */
  120. /* additional mixers to alc880_three_stack_mixer */
  121. static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
  122. HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  123. HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
  124. { } /* end */
  125. };
  126. /* channel source setting (6/8 channel selection for 5-stack) */
  127. /* 6ch mode */
  128. static const struct hda_verb alc880_fivestack_ch6_init[] = {
  129. /* set line-in to input, mute it */
  130. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  131. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  132. { } /* end */
  133. };
  134. /* 8ch mode */
  135. static const struct hda_verb alc880_fivestack_ch8_init[] = {
  136. /* set line-in to output, unmute it */
  137. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  138. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  139. { } /* end */
  140. };
  141. static const struct hda_channel_mode alc880_fivestack_modes[2] = {
  142. { 6, alc880_fivestack_ch6_init },
  143. { 8, alc880_fivestack_ch8_init },
  144. };
  145. /*
  146. * ALC880 6-stack model
  147. *
  148. * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
  149. * Side = 0x05 (0x0f)
  150. * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
  151. * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
  152. */
  153. static const hda_nid_t alc880_6st_dac_nids[4] = {
  154. /* front, rear, clfe, rear_surr */
  155. 0x02, 0x03, 0x04, 0x05
  156. };
  157. static const struct hda_input_mux alc880_6stack_capture_source = {
  158. .num_items = 4,
  159. .items = {
  160. { "Mic", 0x0 },
  161. { "Front Mic", 0x1 },
  162. { "Line", 0x2 },
  163. { "CD", 0x4 },
  164. },
  165. };
  166. /* fixed 8-channels */
  167. static const struct hda_channel_mode alc880_sixstack_modes[1] = {
  168. { 8, NULL },
  169. };
  170. static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
  171. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  172. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  173. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  174. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  175. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  176. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  177. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  178. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  179. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  180. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  181. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  182. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  183. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  184. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  185. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  186. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  187. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  188. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  189. {
  190. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  191. .name = "Channel Mode",
  192. .info = alc_ch_mode_info,
  193. .get = alc_ch_mode_get,
  194. .put = alc_ch_mode_put,
  195. },
  196. { } /* end */
  197. };
  198. static const hda_nid_t alc880_w810_dac_nids[3] = {
  199. /* front, rear/surround, clfe */
  200. 0x02, 0x03, 0x04
  201. };
  202. /*
  203. * Z710V model
  204. *
  205. * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
  206. * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
  207. * Line = 0x1a
  208. */
  209. static const hda_nid_t alc880_z71v_dac_nids[1] = {
  210. 0x02
  211. };
  212. #define ALC880_Z71V_HP_DAC 0x03
  213. /* fixed 2 channels */
  214. static const struct hda_channel_mode alc880_2_jack_modes[1] = {
  215. { 2, NULL }
  216. };
  217. static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
  218. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  219. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  220. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  221. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  222. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  223. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  224. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  225. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  226. { } /* end */
  227. };
  228. /*
  229. * ALC880 ASUS model
  230. *
  231. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  232. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  233. * Mic = 0x18, Line = 0x1a
  234. */
  235. #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
  236. #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
  237. static const struct snd_kcontrol_new alc880_asus_mixer[] = {
  238. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  239. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  240. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  241. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  242. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  243. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  244. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  245. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  246. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  247. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  248. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  249. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  250. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  251. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  252. {
  253. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  254. .name = "Channel Mode",
  255. .info = alc_ch_mode_info,
  256. .get = alc_ch_mode_get,
  257. .put = alc_ch_mode_put,
  258. },
  259. { } /* end */
  260. };
  261. /*
  262. * ALC880 ASUS W1V model
  263. *
  264. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  265. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  266. * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
  267. */
  268. /* additional mixers to alc880_asus_mixer */
  269. static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
  270. HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
  271. HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
  272. { } /* end */
  273. };
  274. /*
  275. * initialize the codec volumes, etc
  276. */
  277. /*
  278. * generic initialization of ADC, input mixers and output mixers
  279. */
  280. static const struct hda_verb alc880_volume_init_verbs[] = {
  281. /*
  282. * Unmute ADC0-2 and set the default input to mic-in
  283. */
  284. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  285. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  286. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  287. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  288. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  289. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  290. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  291. * mixer widget
  292. * Note: PASD motherboards uses the Line In 2 as the input for front
  293. * panel mic (mic 2)
  294. */
  295. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  296. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  297. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  298. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  299. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  300. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  301. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  302. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  303. /*
  304. * Set up output mixers (0x0c - 0x0f)
  305. */
  306. /* set vol=0 to output mixers */
  307. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  308. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  309. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  310. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  311. /* set up input amps for analog loopback */
  312. /* Amp Indices: DAC = 0, mixer = 1 */
  313. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  314. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  315. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  316. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  317. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  318. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  319. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  320. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  321. { }
  322. };
  323. /*
  324. * 3-stack pin configuration:
  325. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  326. */
  327. static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
  328. /*
  329. * preset connection lists of input pins
  330. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  331. */
  332. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  333. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  334. {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
  335. /*
  336. * Set pin mode and muting
  337. */
  338. /* set front pin widgets 0x14 for output */
  339. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  340. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  341. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  342. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  343. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  344. /* Mic2 (as headphone out) for HP output */
  345. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  346. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  347. /* Line In pin widget for input */
  348. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  349. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  350. /* Line2 (as front mic) pin widget for input and vref at 80% */
  351. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  352. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  353. /* CD pin widget for input */
  354. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  355. { }
  356. };
  357. /*
  358. * 5-stack pin configuration:
  359. * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
  360. * line-in/side = 0x1a, f-mic = 0x1b
  361. */
  362. static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
  363. /*
  364. * preset connection lists of input pins
  365. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  366. */
  367. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  368. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
  369. /*
  370. * Set pin mode and muting
  371. */
  372. /* set pin widgets 0x14-0x17 for output */
  373. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  374. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  375. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  376. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  377. /* unmute pins for output (no gain on this amp) */
  378. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  379. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  380. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  381. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  382. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  383. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  384. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  385. /* Mic2 (as headphone out) for HP output */
  386. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  387. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  388. /* Line In pin widget for input */
  389. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  390. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  391. /* Line2 (as front mic) pin widget for input and vref at 80% */
  392. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  393. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  394. /* CD pin widget for input */
  395. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  396. { }
  397. };
  398. /*
  399. * Z71V pin configuration:
  400. * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
  401. */
  402. static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
  403. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  404. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  405. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  406. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  407. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  408. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  409. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  410. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  411. { }
  412. };
  413. /*
  414. * 6-stack pin configuration:
  415. * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
  416. * f-mic = 0x19, line = 0x1a, HP = 0x1b
  417. */
  418. static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
  419. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  420. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  421. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  422. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  423. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  424. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  425. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  426. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  427. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  428. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  429. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  430. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  431. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  432. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  433. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  434. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  435. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  436. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  437. { }
  438. };
  439. static const struct hda_verb alc880_beep_init_verbs[] = {
  440. { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
  441. { }
  442. };
  443. /*
  444. * ASUS pin configuration:
  445. * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
  446. */
  447. static const struct hda_verb alc880_pin_asus_init_verbs[] = {
  448. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
  449. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
  450. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
  451. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
  452. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  453. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  454. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  455. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  456. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  457. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  458. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  459. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  460. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  461. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  462. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  463. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  464. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  465. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  466. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  467. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  468. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  469. { }
  470. };
  471. /* Enable GPIO mask and set output */
  472. #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
  473. #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
  474. #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
  475. /*
  476. * Test configuration for debugging
  477. *
  478. * Almost all inputs/outputs are enabled. I/O pins can be configured via
  479. * enum controls.
  480. */
  481. #ifdef CONFIG_SND_DEBUG
  482. static const hda_nid_t alc880_test_dac_nids[4] = {
  483. 0x02, 0x03, 0x04, 0x05
  484. };
  485. static const struct hda_input_mux alc880_test_capture_source = {
  486. .num_items = 7,
  487. .items = {
  488. { "In-1", 0x0 },
  489. { "In-2", 0x1 },
  490. { "In-3", 0x2 },
  491. { "In-4", 0x3 },
  492. { "CD", 0x4 },
  493. { "Front", 0x5 },
  494. { "Surround", 0x6 },
  495. },
  496. };
  497. static const struct hda_channel_mode alc880_test_modes[4] = {
  498. { 2, NULL },
  499. { 4, NULL },
  500. { 6, NULL },
  501. { 8, NULL },
  502. };
  503. static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
  504. struct snd_ctl_elem_info *uinfo)
  505. {
  506. static const char * const texts[] = {
  507. "N/A", "Line Out", "HP Out",
  508. "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
  509. };
  510. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  511. uinfo->count = 1;
  512. uinfo->value.enumerated.items = 8;
  513. if (uinfo->value.enumerated.item >= 8)
  514. uinfo->value.enumerated.item = 7;
  515. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  516. return 0;
  517. }
  518. static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
  519. struct snd_ctl_elem_value *ucontrol)
  520. {
  521. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  522. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  523. unsigned int pin_ctl, item = 0;
  524. pin_ctl = snd_hda_codec_read(codec, nid, 0,
  525. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  526. if (pin_ctl & AC_PINCTL_OUT_EN) {
  527. if (pin_ctl & AC_PINCTL_HP_EN)
  528. item = 2;
  529. else
  530. item = 1;
  531. } else if (pin_ctl & AC_PINCTL_IN_EN) {
  532. switch (pin_ctl & AC_PINCTL_VREFEN) {
  533. case AC_PINCTL_VREF_HIZ: item = 3; break;
  534. case AC_PINCTL_VREF_50: item = 4; break;
  535. case AC_PINCTL_VREF_GRD: item = 5; break;
  536. case AC_PINCTL_VREF_80: item = 6; break;
  537. case AC_PINCTL_VREF_100: item = 7; break;
  538. }
  539. }
  540. ucontrol->value.enumerated.item[0] = item;
  541. return 0;
  542. }
  543. static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
  544. struct snd_ctl_elem_value *ucontrol)
  545. {
  546. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  547. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  548. static const unsigned int ctls[] = {
  549. 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
  550. AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
  551. AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
  552. AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
  553. AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
  554. AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
  555. };
  556. unsigned int old_ctl, new_ctl;
  557. old_ctl = snd_hda_codec_read(codec, nid, 0,
  558. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  559. new_ctl = ctls[ucontrol->value.enumerated.item[0]];
  560. if (old_ctl != new_ctl) {
  561. int val;
  562. snd_hda_codec_write_cache(codec, nid, 0,
  563. AC_VERB_SET_PIN_WIDGET_CONTROL,
  564. new_ctl);
  565. val = ucontrol->value.enumerated.item[0] >= 3 ?
  566. HDA_AMP_MUTE : 0;
  567. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  568. HDA_AMP_MUTE, val);
  569. return 1;
  570. }
  571. return 0;
  572. }
  573. static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
  574. struct snd_ctl_elem_info *uinfo)
  575. {
  576. static const char * const texts[] = {
  577. "Front", "Surround", "CLFE", "Side"
  578. };
  579. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  580. uinfo->count = 1;
  581. uinfo->value.enumerated.items = 4;
  582. if (uinfo->value.enumerated.item >= 4)
  583. uinfo->value.enumerated.item = 3;
  584. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  585. return 0;
  586. }
  587. static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
  588. struct snd_ctl_elem_value *ucontrol)
  589. {
  590. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  591. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  592. unsigned int sel;
  593. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
  594. ucontrol->value.enumerated.item[0] = sel & 3;
  595. return 0;
  596. }
  597. static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
  598. struct snd_ctl_elem_value *ucontrol)
  599. {
  600. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  601. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  602. unsigned int sel;
  603. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
  604. if (ucontrol->value.enumerated.item[0] != sel) {
  605. sel = ucontrol->value.enumerated.item[0] & 3;
  606. snd_hda_codec_write_cache(codec, nid, 0,
  607. AC_VERB_SET_CONNECT_SEL, sel);
  608. return 1;
  609. }
  610. return 0;
  611. }
  612. #define PIN_CTL_TEST(xname,nid) { \
  613. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  614. .name = xname, \
  615. .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
  616. .info = alc_test_pin_ctl_info, \
  617. .get = alc_test_pin_ctl_get, \
  618. .put = alc_test_pin_ctl_put, \
  619. .private_value = nid \
  620. }
  621. #define PIN_SRC_TEST(xname,nid) { \
  622. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  623. .name = xname, \
  624. .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
  625. .info = alc_test_pin_src_info, \
  626. .get = alc_test_pin_src_get, \
  627. .put = alc_test_pin_src_put, \
  628. .private_value = nid \
  629. }
  630. static const struct snd_kcontrol_new alc880_test_mixer[] = {
  631. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  632. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  633. HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  634. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  635. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  636. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  637. HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
  638. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  639. PIN_CTL_TEST("Front Pin Mode", 0x14),
  640. PIN_CTL_TEST("Surround Pin Mode", 0x15),
  641. PIN_CTL_TEST("CLFE Pin Mode", 0x16),
  642. PIN_CTL_TEST("Side Pin Mode", 0x17),
  643. PIN_CTL_TEST("In-1 Pin Mode", 0x18),
  644. PIN_CTL_TEST("In-2 Pin Mode", 0x19),
  645. PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
  646. PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
  647. PIN_SRC_TEST("In-1 Pin Source", 0x18),
  648. PIN_SRC_TEST("In-2 Pin Source", 0x19),
  649. PIN_SRC_TEST("In-3 Pin Source", 0x1a),
  650. PIN_SRC_TEST("In-4 Pin Source", 0x1b),
  651. HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
  652. HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
  653. HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
  654. HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
  655. HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
  656. HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
  657. HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
  658. HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
  659. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
  660. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
  661. {
  662. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  663. .name = "Channel Mode",
  664. .info = alc_ch_mode_info,
  665. .get = alc_ch_mode_get,
  666. .put = alc_ch_mode_put,
  667. },
  668. { } /* end */
  669. };
  670. static const struct hda_verb alc880_test_init_verbs[] = {
  671. /* Unmute inputs of 0x0c - 0x0f */
  672. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  673. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  674. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  675. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  676. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  677. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  678. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  679. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  680. /* Vol output for 0x0c-0x0f */
  681. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  682. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  683. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  684. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  685. /* Set output pins 0x14-0x17 */
  686. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  687. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  688. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  689. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  690. /* Unmute output pins 0x14-0x17 */
  691. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  692. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  693. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  694. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  695. /* Set input pins 0x18-0x1c */
  696. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  697. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  698. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  699. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  700. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  701. /* Mute input pins 0x18-0x1b */
  702. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  703. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  704. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  705. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  706. /* ADC set up */
  707. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  708. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  709. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  710. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  711. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  712. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  713. /* Analog input/passthru */
  714. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  715. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  716. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  717. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  718. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  719. { }
  720. };
  721. #endif
  722. /*
  723. */
  724. static const char * const alc880_models[ALC880_MODEL_LAST] = {
  725. [ALC880_3ST] = "3stack",
  726. [ALC880_3ST_DIG] = "3stack-digout",
  727. [ALC880_5ST] = "5stack",
  728. [ALC880_5ST_DIG] = "5stack-digout",
  729. [ALC880_Z71V] = "z71v",
  730. [ALC880_6ST] = "6stack",
  731. [ALC880_6ST_DIG] = "6stack-digout",
  732. [ALC880_ASUS] = "asus",
  733. [ALC880_ASUS_W1V] = "asus-w1v",
  734. [ALC880_ASUS_DIG] = "asus-dig",
  735. [ALC880_ASUS_DIG2] = "asus-dig2",
  736. #ifdef CONFIG_SND_DEBUG
  737. [ALC880_TEST] = "test",
  738. #endif
  739. [ALC880_AUTO] = "auto",
  740. };
  741. static const struct snd_pci_quirk alc880_cfg_tbl[] = {
  742. SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
  743. SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
  744. SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
  745. SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
  746. SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
  747. SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
  748. SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
  749. SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
  750. SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
  751. SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
  752. SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
  753. SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
  754. SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
  755. SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
  756. SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
  757. SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
  758. /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
  759. SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
  760. SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
  761. SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
  762. SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
  763. SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
  764. SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
  765. SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
  766. SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
  767. SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
  768. SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
  769. SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
  770. SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
  771. SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
  772. SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
  773. SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
  774. SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
  775. SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
  776. SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
  777. SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
  778. SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
  779. SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
  780. SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
  781. SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
  782. SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
  783. SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
  784. SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
  785. SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
  786. SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
  787. SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
  788. SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
  789. SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
  790. SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
  791. SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
  792. /* default Intel */
  793. SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
  794. SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
  795. SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
  796. {}
  797. };
  798. /*
  799. * ALC880 codec presets
  800. */
  801. static const struct alc_config_preset alc880_presets[] = {
  802. [ALC880_3ST] = {
  803. .mixers = { alc880_three_stack_mixer },
  804. .init_verbs = { alc880_volume_init_verbs,
  805. alc880_pin_3stack_init_verbs },
  806. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  807. .dac_nids = alc880_dac_nids,
  808. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  809. .channel_mode = alc880_threestack_modes,
  810. .need_dac_fix = 1,
  811. .input_mux = &alc880_capture_source,
  812. },
  813. [ALC880_3ST_DIG] = {
  814. .mixers = { alc880_three_stack_mixer },
  815. .init_verbs = { alc880_volume_init_verbs,
  816. alc880_pin_3stack_init_verbs },
  817. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  818. .dac_nids = alc880_dac_nids,
  819. .dig_out_nid = ALC880_DIGOUT_NID,
  820. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  821. .channel_mode = alc880_threestack_modes,
  822. .need_dac_fix = 1,
  823. .input_mux = &alc880_capture_source,
  824. },
  825. [ALC880_5ST] = {
  826. .mixers = { alc880_three_stack_mixer,
  827. alc880_five_stack_mixer},
  828. .init_verbs = { alc880_volume_init_verbs,
  829. alc880_pin_5stack_init_verbs },
  830. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  831. .dac_nids = alc880_dac_nids,
  832. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  833. .channel_mode = alc880_fivestack_modes,
  834. .input_mux = &alc880_capture_source,
  835. },
  836. [ALC880_5ST_DIG] = {
  837. .mixers = { alc880_three_stack_mixer,
  838. alc880_five_stack_mixer },
  839. .init_verbs = { alc880_volume_init_verbs,
  840. alc880_pin_5stack_init_verbs },
  841. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  842. .dac_nids = alc880_dac_nids,
  843. .dig_out_nid = ALC880_DIGOUT_NID,
  844. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  845. .channel_mode = alc880_fivestack_modes,
  846. .input_mux = &alc880_capture_source,
  847. },
  848. [ALC880_6ST] = {
  849. .mixers = { alc880_six_stack_mixer },
  850. .init_verbs = { alc880_volume_init_verbs,
  851. alc880_pin_6stack_init_verbs },
  852. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  853. .dac_nids = alc880_6st_dac_nids,
  854. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  855. .channel_mode = alc880_sixstack_modes,
  856. .input_mux = &alc880_6stack_capture_source,
  857. },
  858. [ALC880_6ST_DIG] = {
  859. .mixers = { alc880_six_stack_mixer },
  860. .init_verbs = { alc880_volume_init_verbs,
  861. alc880_pin_6stack_init_verbs },
  862. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  863. .dac_nids = alc880_6st_dac_nids,
  864. .dig_out_nid = ALC880_DIGOUT_NID,
  865. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  866. .channel_mode = alc880_sixstack_modes,
  867. .input_mux = &alc880_6stack_capture_source,
  868. },
  869. [ALC880_Z71V] = {
  870. .mixers = { alc880_z71v_mixer },
  871. .init_verbs = { alc880_volume_init_verbs,
  872. alc880_pin_z71v_init_verbs },
  873. .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
  874. .dac_nids = alc880_z71v_dac_nids,
  875. .dig_out_nid = ALC880_DIGOUT_NID,
  876. .hp_nid = 0x03,
  877. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  878. .channel_mode = alc880_2_jack_modes,
  879. .input_mux = &alc880_capture_source,
  880. },
  881. [ALC880_ASUS] = {
  882. .mixers = { alc880_asus_mixer },
  883. .init_verbs = { alc880_volume_init_verbs,
  884. alc880_pin_asus_init_verbs,
  885. alc880_gpio1_init_verbs },
  886. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  887. .dac_nids = alc880_asus_dac_nids,
  888. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  889. .channel_mode = alc880_asus_modes,
  890. .need_dac_fix = 1,
  891. .input_mux = &alc880_capture_source,
  892. },
  893. [ALC880_ASUS_DIG] = {
  894. .mixers = { alc880_asus_mixer },
  895. .init_verbs = { alc880_volume_init_verbs,
  896. alc880_pin_asus_init_verbs,
  897. alc880_gpio1_init_verbs },
  898. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  899. .dac_nids = alc880_asus_dac_nids,
  900. .dig_out_nid = ALC880_DIGOUT_NID,
  901. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  902. .channel_mode = alc880_asus_modes,
  903. .need_dac_fix = 1,
  904. .input_mux = &alc880_capture_source,
  905. },
  906. [ALC880_ASUS_DIG2] = {
  907. .mixers = { alc880_asus_mixer },
  908. .init_verbs = { alc880_volume_init_verbs,
  909. alc880_pin_asus_init_verbs,
  910. alc880_gpio2_init_verbs }, /* use GPIO2 */
  911. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  912. .dac_nids = alc880_asus_dac_nids,
  913. .dig_out_nid = ALC880_DIGOUT_NID,
  914. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  915. .channel_mode = alc880_asus_modes,
  916. .need_dac_fix = 1,
  917. .input_mux = &alc880_capture_source,
  918. },
  919. [ALC880_ASUS_W1V] = {
  920. .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
  921. .init_verbs = { alc880_volume_init_verbs,
  922. alc880_pin_asus_init_verbs,
  923. alc880_gpio1_init_verbs },
  924. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  925. .dac_nids = alc880_asus_dac_nids,
  926. .dig_out_nid = ALC880_DIGOUT_NID,
  927. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  928. .channel_mode = alc880_asus_modes,
  929. .need_dac_fix = 1,
  930. .input_mux = &alc880_capture_source,
  931. },
  932. [ALC880_UNIWILL_DIG] = {
  933. .mixers = { alc880_asus_mixer },
  934. .init_verbs = { alc880_volume_init_verbs,
  935. alc880_pin_asus_init_verbs },
  936. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  937. .dac_nids = alc880_asus_dac_nids,
  938. .dig_out_nid = ALC880_DIGOUT_NID,
  939. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  940. .channel_mode = alc880_asus_modes,
  941. .need_dac_fix = 1,
  942. .input_mux = &alc880_capture_source,
  943. },
  944. #ifdef CONFIG_SND_DEBUG
  945. [ALC880_TEST] = {
  946. .mixers = { alc880_test_mixer },
  947. .init_verbs = { alc880_test_init_verbs },
  948. .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
  949. .dac_nids = alc880_test_dac_nids,
  950. .dig_out_nid = ALC880_DIGOUT_NID,
  951. .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
  952. .channel_mode = alc880_test_modes,
  953. .input_mux = &alc880_test_capture_source,
  954. },
  955. #endif
  956. };