alc880_quirks.c 33 KB

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