alc861vd_quirks.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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. /*
  133. * generic initialization of ADC, input mixers and output mixers
  134. */
  135. static const struct hda_verb alc861vd_volume_init_verbs[] = {
  136. /*
  137. * Unmute ADC0 and set the default input to mic-in
  138. */
  139. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  140. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  141. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
  142. * the analog-loopback mixer widget
  143. */
  144. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  145. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  146. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  147. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  148. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  149. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  150. /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
  151. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  152. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  153. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  154. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  155. /*
  156. * Set up output mixers (0x02 - 0x05)
  157. */
  158. /* set vol=0 to output mixers */
  159. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  160. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  161. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  162. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  163. /* set up input amps for analog loopback */
  164. /* Amp Indices: DAC = 0, mixer = 1 */
  165. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  166. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  167. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  168. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  169. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  170. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  171. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  172. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  173. { }
  174. };
  175. /*
  176. * 3-stack pin configuration:
  177. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  178. */
  179. static const struct hda_verb alc861vd_3stack_init_verbs[] = {
  180. /*
  181. * Set pin mode and muting
  182. */
  183. /* set front pin widgets 0x14 for output */
  184. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  185. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  186. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  187. /* Mic (rear) pin: input vref at 80% */
  188. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  189. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  190. /* Front Mic pin: input vref at 80% */
  191. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  192. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  193. /* Line In pin: input */
  194. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  195. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  196. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  197. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  198. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  199. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  200. /* CD pin widget for input */
  201. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  202. { }
  203. };
  204. /*
  205. * 6-stack pin configuration:
  206. */
  207. static const struct hda_verb alc861vd_6stack_init_verbs[] = {
  208. /*
  209. * Set pin mode and muting
  210. */
  211. /* set front pin widgets 0x14 for output */
  212. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  213. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  214. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  215. /* Rear Pin: output 1 (0x0d) */
  216. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  217. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  218. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  219. /* CLFE Pin: output 2 (0x0e) */
  220. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  221. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  222. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  223. /* Side Pin: output 3 (0x0f) */
  224. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  225. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  226. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  227. /* Mic (rear) pin: input vref at 80% */
  228. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  229. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  230. /* Front Mic pin: input vref at 80% */
  231. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  232. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  233. /* Line In pin: input */
  234. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  235. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  236. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  237. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  238. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  239. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  240. /* CD pin widget for input */
  241. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  242. { }
  243. };
  244. /*
  245. * configuration and preset
  246. */
  247. static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
  248. [ALC660VD_3ST] = "3stack-660",
  249. [ALC660VD_3ST_DIG] = "3stack-660-digout",
  250. [ALC861VD_3ST] = "3stack",
  251. [ALC861VD_3ST_DIG] = "3stack-digout",
  252. [ALC861VD_6ST_DIG] = "6stack-digout",
  253. [ALC861VD_AUTO] = "auto",
  254. };
  255. static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
  256. SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
  257. SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
  258. SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
  259. SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
  260. {}
  261. };
  262. static const struct alc_config_preset alc861vd_presets[] = {
  263. [ALC660VD_3ST] = {
  264. .mixers = { alc861vd_3st_mixer },
  265. .init_verbs = { alc861vd_volume_init_verbs,
  266. alc861vd_3stack_init_verbs },
  267. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  268. .dac_nids = alc660vd_dac_nids,
  269. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  270. .channel_mode = alc861vd_3stack_2ch_modes,
  271. .input_mux = &alc861vd_capture_source,
  272. },
  273. [ALC660VD_3ST_DIG] = {
  274. .mixers = { alc861vd_3st_mixer },
  275. .init_verbs = { alc861vd_volume_init_verbs,
  276. alc861vd_3stack_init_verbs },
  277. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  278. .dac_nids = alc660vd_dac_nids,
  279. .dig_out_nid = ALC861VD_DIGOUT_NID,
  280. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  281. .channel_mode = alc861vd_3stack_2ch_modes,
  282. .input_mux = &alc861vd_capture_source,
  283. },
  284. [ALC861VD_3ST] = {
  285. .mixers = { alc861vd_3st_mixer },
  286. .init_verbs = { alc861vd_volume_init_verbs,
  287. alc861vd_3stack_init_verbs },
  288. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  289. .dac_nids = alc861vd_dac_nids,
  290. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  291. .channel_mode = alc861vd_3stack_2ch_modes,
  292. .input_mux = &alc861vd_capture_source,
  293. },
  294. [ALC861VD_3ST_DIG] = {
  295. .mixers = { alc861vd_3st_mixer },
  296. .init_verbs = { alc861vd_volume_init_verbs,
  297. alc861vd_3stack_init_verbs },
  298. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  299. .dac_nids = alc861vd_dac_nids,
  300. .dig_out_nid = ALC861VD_DIGOUT_NID,
  301. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  302. .channel_mode = alc861vd_3stack_2ch_modes,
  303. .input_mux = &alc861vd_capture_source,
  304. },
  305. [ALC861VD_6ST_DIG] = {
  306. .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
  307. .init_verbs = { alc861vd_volume_init_verbs,
  308. alc861vd_6stack_init_verbs },
  309. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  310. .dac_nids = alc861vd_dac_nids,
  311. .dig_out_nid = ALC861VD_DIGOUT_NID,
  312. .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
  313. .channel_mode = alc861vd_6stack_modes,
  314. .input_mux = &alc861vd_capture_source,
  315. },
  316. };