alc861vd_quirks.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * ALC660-VD/ALC861-VD quirk models
  3. * included by patch_realtek.c
  4. */
  5. /* ALC861-VD models */
  6. enum {
  7. ALC861VD_AUTO,
  8. ALC660VD_3ST,
  9. ALC660VD_3ST_DIG,
  10. ALC861VD_3ST,
  11. ALC861VD_3ST_DIG,
  12. ALC861VD_6ST_DIG,
  13. ALC861VD_MODEL_LAST,
  14. };
  15. #define ALC861VD_DIGOUT_NID 0x06
  16. static const hda_nid_t alc861vd_dac_nids[4] = {
  17. /* front, surr, clfe, side surr */
  18. 0x02, 0x03, 0x04, 0x05
  19. };
  20. /* dac_nids for ALC660vd are in a different order - according to
  21. * Realtek's driver.
  22. * This should probably result in a different mixer for 6stack models
  23. * of ALC660vd codecs, but for now there is only 3stack mixer
  24. * - and it is the same as in 861vd.
  25. * adc_nids in ALC660vd are (is) the same as in 861vd
  26. */
  27. static const hda_nid_t alc660vd_dac_nids[3] = {
  28. /* front, rear, clfe, rear_surr */
  29. 0x02, 0x04, 0x03
  30. };
  31. static const hda_nid_t alc861vd_adc_nids[1] = {
  32. /* ADC0 */
  33. 0x09,
  34. };
  35. static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
  36. /* input MUX */
  37. /* FIXME: should be a matrix-type input source selection */
  38. static const struct hda_input_mux alc861vd_capture_source = {
  39. .num_items = 4,
  40. .items = {
  41. { "Mic", 0x0 },
  42. { "Front Mic", 0x1 },
  43. { "Line", 0x2 },
  44. { "CD", 0x4 },
  45. },
  46. };
  47. /*
  48. * 2ch mode
  49. */
  50. static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
  51. { 2, NULL }
  52. };
  53. /*
  54. * 6ch mode
  55. */
  56. static const struct hda_verb alc861vd_6stack_ch6_init[] = {
  57. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  58. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  59. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  60. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  61. { } /* end */
  62. };
  63. /*
  64. * 8ch mode
  65. */
  66. static const struct hda_verb alc861vd_6stack_ch8_init[] = {
  67. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  68. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  69. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  70. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  71. { } /* end */
  72. };
  73. static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
  74. { 6, alc861vd_6stack_ch6_init },
  75. { 8, alc861vd_6stack_ch8_init },
  76. };
  77. static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
  78. {
  79. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  80. .name = "Channel Mode",
  81. .info = alc_ch_mode_info,
  82. .get = alc_ch_mode_get,
  83. .put = alc_ch_mode_put,
  84. },
  85. { } /* end */
  86. };
  87. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  88. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  89. */
  90. static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
  91. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  92. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  93. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  94. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  95. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
  96. HDA_OUTPUT),
  97. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
  98. HDA_OUTPUT),
  99. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  100. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  101. HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  102. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  103. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  104. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  105. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  106. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  107. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  108. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  109. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  110. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  111. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  112. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  113. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  114. { } /* end */
  115. };
  116. static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
  117. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  118. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  119. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  120. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  121. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  122. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  123. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  124. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  125. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  126. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  127. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  128. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  129. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  130. { } /* end */
  131. };
  132. static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
  133. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  134. /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
  135. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  136. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  137. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  138. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  139. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  140. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  141. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  142. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  143. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  144. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  145. { } /* end */
  146. };
  147. /*
  148. * generic initialization of ADC, input mixers and output mixers
  149. */
  150. static const struct hda_verb alc861vd_volume_init_verbs[] = {
  151. /*
  152. * Unmute ADC0 and set the default input to mic-in
  153. */
  154. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  155. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  156. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
  157. * the analog-loopback mixer widget
  158. */
  159. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  160. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  161. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  162. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  163. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  164. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  165. /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
  166. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  167. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  168. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  169. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  170. /*
  171. * Set up output mixers (0x02 - 0x05)
  172. */
  173. /* set vol=0 to output mixers */
  174. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  175. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  176. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  177. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  178. /* set up input amps for analog loopback */
  179. /* Amp Indices: DAC = 0, mixer = 1 */
  180. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  181. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  182. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  183. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  184. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  185. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  186. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  187. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  188. { }
  189. };
  190. /*
  191. * 3-stack pin configuration:
  192. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  193. */
  194. static const struct hda_verb alc861vd_3stack_init_verbs[] = {
  195. /*
  196. * Set pin mode and muting
  197. */
  198. /* set front pin widgets 0x14 for output */
  199. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  200. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  201. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  202. /* Mic (rear) pin: input vref at 80% */
  203. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  204. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  205. /* Front Mic pin: input vref at 80% */
  206. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  207. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  208. /* Line In pin: input */
  209. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  210. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  211. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  212. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  213. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  214. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  215. /* CD pin widget for input */
  216. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  217. { }
  218. };
  219. /*
  220. * 6-stack pin configuration:
  221. */
  222. static const struct hda_verb alc861vd_6stack_init_verbs[] = {
  223. /*
  224. * Set pin mode and muting
  225. */
  226. /* set front pin widgets 0x14 for output */
  227. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  228. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  229. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  230. /* Rear Pin: output 1 (0x0d) */
  231. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  232. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  233. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  234. /* CLFE Pin: output 2 (0x0e) */
  235. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  236. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  237. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  238. /* Side Pin: output 3 (0x0f) */
  239. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  240. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  241. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  242. /* Mic (rear) pin: input vref at 80% */
  243. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  244. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  245. /* Front Mic pin: input vref at 80% */
  246. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  247. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  248. /* Line In pin: input */
  249. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  250. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  251. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  252. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  253. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  254. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  255. /* CD pin widget for input */
  256. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  257. { }
  258. };
  259. static const struct hda_verb alc861vd_eapd_verbs[] = {
  260. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  261. { }
  262. };
  263. /*
  264. * configuration and preset
  265. */
  266. static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
  267. [ALC660VD_3ST] = "3stack-660",
  268. [ALC660VD_3ST_DIG] = "3stack-660-digout",
  269. [ALC861VD_3ST] = "3stack",
  270. [ALC861VD_3ST_DIG] = "3stack-digout",
  271. [ALC861VD_6ST_DIG] = "6stack-digout",
  272. [ALC861VD_AUTO] = "auto",
  273. };
  274. static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
  275. SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
  276. SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
  277. SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
  278. SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
  279. {}
  280. };
  281. static const struct alc_config_preset alc861vd_presets[] = {
  282. [ALC660VD_3ST] = {
  283. .mixers = { alc861vd_3st_mixer },
  284. .init_verbs = { alc861vd_volume_init_verbs,
  285. alc861vd_3stack_init_verbs },
  286. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  287. .dac_nids = alc660vd_dac_nids,
  288. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  289. .channel_mode = alc861vd_3stack_2ch_modes,
  290. .input_mux = &alc861vd_capture_source,
  291. },
  292. [ALC660VD_3ST_DIG] = {
  293. .mixers = { alc861vd_3st_mixer },
  294. .init_verbs = { alc861vd_volume_init_verbs,
  295. alc861vd_3stack_init_verbs },
  296. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  297. .dac_nids = alc660vd_dac_nids,
  298. .dig_out_nid = ALC861VD_DIGOUT_NID,
  299. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  300. .channel_mode = alc861vd_3stack_2ch_modes,
  301. .input_mux = &alc861vd_capture_source,
  302. },
  303. [ALC861VD_3ST] = {
  304. .mixers = { alc861vd_3st_mixer },
  305. .init_verbs = { alc861vd_volume_init_verbs,
  306. alc861vd_3stack_init_verbs },
  307. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  308. .dac_nids = alc861vd_dac_nids,
  309. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  310. .channel_mode = alc861vd_3stack_2ch_modes,
  311. .input_mux = &alc861vd_capture_source,
  312. },
  313. [ALC861VD_3ST_DIG] = {
  314. .mixers = { alc861vd_3st_mixer },
  315. .init_verbs = { alc861vd_volume_init_verbs,
  316. alc861vd_3stack_init_verbs },
  317. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  318. .dac_nids = alc861vd_dac_nids,
  319. .dig_out_nid = ALC861VD_DIGOUT_NID,
  320. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  321. .channel_mode = alc861vd_3stack_2ch_modes,
  322. .input_mux = &alc861vd_capture_source,
  323. },
  324. [ALC861VD_6ST_DIG] = {
  325. .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
  326. .init_verbs = { alc861vd_volume_init_verbs,
  327. alc861vd_6stack_init_verbs },
  328. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  329. .dac_nids = alc861vd_dac_nids,
  330. .dig_out_nid = ALC861VD_DIGOUT_NID,
  331. .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
  332. .channel_mode = alc861vd_6stack_modes,
  333. .input_mux = &alc861vd_capture_source,
  334. },
  335. };