alc861vd_quirks.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  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. ALC660VD_ASUS_V1S,
  11. ALC861VD_3ST,
  12. ALC861VD_3ST_DIG,
  13. ALC861VD_6ST_DIG,
  14. ALC861VD_LENOVO,
  15. ALC861VD_DALLAS,
  16. ALC861VD_HP,
  17. ALC861VD_MODEL_LAST,
  18. };
  19. #define ALC861VD_DIGOUT_NID 0x06
  20. static const hda_nid_t alc861vd_dac_nids[4] = {
  21. /* front, surr, clfe, side surr */
  22. 0x02, 0x03, 0x04, 0x05
  23. };
  24. /* dac_nids for ALC660vd are in a different order - according to
  25. * Realtek's driver.
  26. * This should probably result in a different mixer for 6stack models
  27. * of ALC660vd codecs, but for now there is only 3stack mixer
  28. * - and it is the same as in 861vd.
  29. * adc_nids in ALC660vd are (is) the same as in 861vd
  30. */
  31. static const hda_nid_t alc660vd_dac_nids[3] = {
  32. /* front, rear, clfe, rear_surr */
  33. 0x02, 0x04, 0x03
  34. };
  35. static const hda_nid_t alc861vd_adc_nids[1] = {
  36. /* ADC0 */
  37. 0x09,
  38. };
  39. static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
  40. /* input MUX */
  41. /* FIXME: should be a matrix-type input source selection */
  42. static const struct hda_input_mux alc861vd_capture_source = {
  43. .num_items = 4,
  44. .items = {
  45. { "Mic", 0x0 },
  46. { "Front Mic", 0x1 },
  47. { "Line", 0x2 },
  48. { "CD", 0x4 },
  49. },
  50. };
  51. static const struct hda_input_mux alc861vd_dallas_capture_source = {
  52. .num_items = 2,
  53. .items = {
  54. { "Mic", 0x0 },
  55. { "Internal Mic", 0x1 },
  56. },
  57. };
  58. static const struct hda_input_mux alc861vd_hp_capture_source = {
  59. .num_items = 2,
  60. .items = {
  61. { "Front Mic", 0x0 },
  62. { "ATAPI Mic", 0x1 },
  63. },
  64. };
  65. /*
  66. * 2ch mode
  67. */
  68. static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
  69. { 2, NULL }
  70. };
  71. /*
  72. * 6ch mode
  73. */
  74. static const struct hda_verb alc861vd_6stack_ch6_init[] = {
  75. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  76. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  77. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  78. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  79. { } /* end */
  80. };
  81. /*
  82. * 8ch mode
  83. */
  84. static const struct hda_verb alc861vd_6stack_ch8_init[] = {
  85. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  86. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  87. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  88. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  89. { } /* end */
  90. };
  91. static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
  92. { 6, alc861vd_6stack_ch6_init },
  93. { 8, alc861vd_6stack_ch8_init },
  94. };
  95. static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
  96. {
  97. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  98. .name = "Channel Mode",
  99. .info = alc_ch_mode_info,
  100. .get = alc_ch_mode_get,
  101. .put = alc_ch_mode_put,
  102. },
  103. { } /* end */
  104. };
  105. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  106. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  107. */
  108. static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
  109. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  110. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  111. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  112. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  113. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
  114. HDA_OUTPUT),
  115. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
  116. HDA_OUTPUT),
  117. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  118. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  119. HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  120. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  121. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  122. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  123. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  124. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  125. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  126. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  127. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  128. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  129. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  130. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  131. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  132. { } /* end */
  133. };
  134. static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
  135. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  136. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  137. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  138. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  139. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  140. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  141. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  142. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  143. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  144. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  145. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  146. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  147. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  148. { } /* end */
  149. };
  150. static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
  151. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  152. /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
  153. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  154. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  155. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  156. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  157. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  158. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  159. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  160. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  161. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  162. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  163. { } /* end */
  164. };
  165. /* Pin assignment: Speaker=0x14, HP = 0x15,
  166. * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
  167. */
  168. static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
  169. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  170. HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
  171. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  172. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  173. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  174. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  175. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  176. HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
  177. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  178. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  179. { } /* end */
  180. };
  181. /* Pin assignment: Speaker=0x14, Line-out = 0x15,
  182. * Front Mic=0x18, ATAPI Mic = 0x19,
  183. */
  184. static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
  185. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  186. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  187. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  188. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  189. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  190. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  191. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  192. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  193. { } /* end */
  194. };
  195. /*
  196. * generic initialization of ADC, input mixers and output mixers
  197. */
  198. static const struct hda_verb alc861vd_volume_init_verbs[] = {
  199. /*
  200. * Unmute ADC0 and set the default input to mic-in
  201. */
  202. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  203. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  204. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
  205. * the analog-loopback mixer widget
  206. */
  207. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  208. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  209. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  210. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  211. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  212. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  213. /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
  214. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  215. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  216. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  217. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  218. /*
  219. * Set up output mixers (0x02 - 0x05)
  220. */
  221. /* set vol=0 to output mixers */
  222. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  223. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  224. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  225. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  226. /* set up input amps for analog loopback */
  227. /* Amp Indices: DAC = 0, mixer = 1 */
  228. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  229. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  230. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  231. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  232. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  233. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  234. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  235. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  236. { }
  237. };
  238. /*
  239. * 3-stack pin configuration:
  240. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  241. */
  242. static const struct hda_verb alc861vd_3stack_init_verbs[] = {
  243. /*
  244. * Set pin mode and muting
  245. */
  246. /* set front pin widgets 0x14 for output */
  247. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  248. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  249. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  250. /* Mic (rear) pin: input vref at 80% */
  251. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  252. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  253. /* Front Mic pin: input vref at 80% */
  254. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  255. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  256. /* Line In pin: input */
  257. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  258. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  259. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  260. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  261. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  262. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  263. /* CD pin widget for input */
  264. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  265. { }
  266. };
  267. /*
  268. * 6-stack pin configuration:
  269. */
  270. static const struct hda_verb alc861vd_6stack_init_verbs[] = {
  271. /*
  272. * Set pin mode and muting
  273. */
  274. /* set front pin widgets 0x14 for output */
  275. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  276. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  277. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  278. /* Rear Pin: output 1 (0x0d) */
  279. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  280. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  281. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  282. /* CLFE Pin: output 2 (0x0e) */
  283. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  284. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  285. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  286. /* Side Pin: output 3 (0x0f) */
  287. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  288. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  289. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  290. /* Mic (rear) pin: input vref at 80% */
  291. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  292. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  293. /* Front Mic pin: input vref at 80% */
  294. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  295. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  296. /* Line In pin: input */
  297. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  298. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  299. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  300. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  301. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  302. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  303. /* CD pin widget for input */
  304. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  305. { }
  306. };
  307. static const struct hda_verb alc861vd_eapd_verbs[] = {
  308. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  309. { }
  310. };
  311. static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
  312. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  313. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  314. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  315. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  316. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  317. {}
  318. };
  319. static void alc861vd_lenovo_setup(struct hda_codec *codec)
  320. {
  321. struct alc_spec *spec = codec->spec;
  322. spec->autocfg.hp_pins[0] = 0x1b;
  323. spec->autocfg.speaker_pins[0] = 0x14;
  324. spec->automute = 1;
  325. spec->automute_mode = ALC_AUTOMUTE_AMP;
  326. }
  327. static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
  328. {
  329. alc_hp_automute(codec);
  330. alc88x_simple_mic_automute(codec);
  331. }
  332. static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
  333. unsigned int res)
  334. {
  335. switch (res >> 26) {
  336. case ALC_MIC_EVENT:
  337. alc88x_simple_mic_automute(codec);
  338. break;
  339. default:
  340. alc_sku_unsol_event(codec, res);
  341. break;
  342. }
  343. }
  344. static const struct hda_verb alc861vd_dallas_verbs[] = {
  345. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  346. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  347. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  348. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  349. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  350. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  351. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  352. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  353. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  354. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  355. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  356. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  357. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  358. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  359. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  360. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  361. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  362. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  363. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  364. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  365. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  366. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  367. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  368. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  369. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  370. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  371. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  372. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  373. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  374. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  375. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  376. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  377. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  378. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  379. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  380. { } /* end */
  381. };
  382. /* toggle speaker-output according to the hp-jack state */
  383. static void alc861vd_dallas_setup(struct hda_codec *codec)
  384. {
  385. struct alc_spec *spec = codec->spec;
  386. spec->autocfg.hp_pins[0] = 0x15;
  387. spec->autocfg.speaker_pins[0] = 0x14;
  388. spec->automute = 1;
  389. spec->automute_mode = ALC_AUTOMUTE_AMP;
  390. }
  391. /*
  392. * configuration and preset
  393. */
  394. static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
  395. [ALC660VD_3ST] = "3stack-660",
  396. [ALC660VD_3ST_DIG] = "3stack-660-digout",
  397. [ALC660VD_ASUS_V1S] = "asus-v1s",
  398. [ALC861VD_3ST] = "3stack",
  399. [ALC861VD_3ST_DIG] = "3stack-digout",
  400. [ALC861VD_6ST_DIG] = "6stack-digout",
  401. [ALC861VD_LENOVO] = "lenovo",
  402. [ALC861VD_DALLAS] = "dallas",
  403. [ALC861VD_HP] = "hp",
  404. [ALC861VD_AUTO] = "auto",
  405. };
  406. static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
  407. SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
  408. SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
  409. SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
  410. /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
  411. SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
  412. SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
  413. SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
  414. SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
  415. /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
  416. SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
  417. SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
  418. SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
  419. SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
  420. SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
  421. SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
  422. {}
  423. };
  424. static const struct alc_config_preset alc861vd_presets[] = {
  425. [ALC660VD_3ST] = {
  426. .mixers = { alc861vd_3st_mixer },
  427. .init_verbs = { alc861vd_volume_init_verbs,
  428. alc861vd_3stack_init_verbs },
  429. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  430. .dac_nids = alc660vd_dac_nids,
  431. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  432. .channel_mode = alc861vd_3stack_2ch_modes,
  433. .input_mux = &alc861vd_capture_source,
  434. },
  435. [ALC660VD_3ST_DIG] = {
  436. .mixers = { alc861vd_3st_mixer },
  437. .init_verbs = { alc861vd_volume_init_verbs,
  438. alc861vd_3stack_init_verbs },
  439. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  440. .dac_nids = alc660vd_dac_nids,
  441. .dig_out_nid = ALC861VD_DIGOUT_NID,
  442. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  443. .channel_mode = alc861vd_3stack_2ch_modes,
  444. .input_mux = &alc861vd_capture_source,
  445. },
  446. [ALC861VD_3ST] = {
  447. .mixers = { alc861vd_3st_mixer },
  448. .init_verbs = { alc861vd_volume_init_verbs,
  449. alc861vd_3stack_init_verbs },
  450. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  451. .dac_nids = alc861vd_dac_nids,
  452. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  453. .channel_mode = alc861vd_3stack_2ch_modes,
  454. .input_mux = &alc861vd_capture_source,
  455. },
  456. [ALC861VD_3ST_DIG] = {
  457. .mixers = { alc861vd_3st_mixer },
  458. .init_verbs = { alc861vd_volume_init_verbs,
  459. alc861vd_3stack_init_verbs },
  460. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  461. .dac_nids = alc861vd_dac_nids,
  462. .dig_out_nid = ALC861VD_DIGOUT_NID,
  463. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  464. .channel_mode = alc861vd_3stack_2ch_modes,
  465. .input_mux = &alc861vd_capture_source,
  466. },
  467. [ALC861VD_6ST_DIG] = {
  468. .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
  469. .init_verbs = { alc861vd_volume_init_verbs,
  470. alc861vd_6stack_init_verbs },
  471. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  472. .dac_nids = alc861vd_dac_nids,
  473. .dig_out_nid = ALC861VD_DIGOUT_NID,
  474. .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
  475. .channel_mode = alc861vd_6stack_modes,
  476. .input_mux = &alc861vd_capture_source,
  477. },
  478. [ALC861VD_LENOVO] = {
  479. .mixers = { alc861vd_lenovo_mixer },
  480. .init_verbs = { alc861vd_volume_init_verbs,
  481. alc861vd_3stack_init_verbs,
  482. alc861vd_eapd_verbs,
  483. alc861vd_lenovo_unsol_verbs },
  484. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  485. .dac_nids = alc660vd_dac_nids,
  486. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  487. .channel_mode = alc861vd_3stack_2ch_modes,
  488. .input_mux = &alc861vd_capture_source,
  489. .unsol_event = alc861vd_lenovo_unsol_event,
  490. .setup = alc861vd_lenovo_setup,
  491. .init_hook = alc861vd_lenovo_init_hook,
  492. },
  493. [ALC861VD_DALLAS] = {
  494. .mixers = { alc861vd_dallas_mixer },
  495. .init_verbs = { alc861vd_dallas_verbs },
  496. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  497. .dac_nids = alc861vd_dac_nids,
  498. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  499. .channel_mode = alc861vd_3stack_2ch_modes,
  500. .input_mux = &alc861vd_dallas_capture_source,
  501. .unsol_event = alc_sku_unsol_event,
  502. .setup = alc861vd_dallas_setup,
  503. .init_hook = alc_hp_automute,
  504. },
  505. [ALC861VD_HP] = {
  506. .mixers = { alc861vd_hp_mixer },
  507. .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
  508. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  509. .dac_nids = alc861vd_dac_nids,
  510. .dig_out_nid = ALC861VD_DIGOUT_NID,
  511. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  512. .channel_mode = alc861vd_3stack_2ch_modes,
  513. .input_mux = &alc861vd_hp_capture_source,
  514. .unsol_event = alc_sku_unsol_event,
  515. .setup = alc861vd_dallas_setup,
  516. .init_hook = alc_hp_automute,
  517. },
  518. [ALC660VD_ASUS_V1S] = {
  519. .mixers = { alc861vd_lenovo_mixer },
  520. .init_verbs = { alc861vd_volume_init_verbs,
  521. alc861vd_3stack_init_verbs,
  522. alc861vd_eapd_verbs,
  523. alc861vd_lenovo_unsol_verbs },
  524. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  525. .dac_nids = alc660vd_dac_nids,
  526. .dig_out_nid = ALC861VD_DIGOUT_NID,
  527. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  528. .channel_mode = alc861vd_3stack_2ch_modes,
  529. .input_mux = &alc861vd_capture_source,
  530. .unsol_event = alc861vd_lenovo_unsol_event,
  531. .setup = alc861vd_lenovo_setup,
  532. .init_hook = alc861vd_lenovo_init_hook,
  533. },
  534. };