alc662_quirks.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * ALC662/ALC663/ALC665/ALC670 quirk models
  3. * included by patch_realtek.c
  4. */
  5. /* ALC662 models */
  6. enum {
  7. ALC662_AUTO,
  8. ALC662_3ST_2ch_DIG,
  9. ALC662_3ST_6ch_DIG,
  10. ALC662_3ST_6ch,
  11. ALC662_5ST_DIG,
  12. ALC662_ASUS_EEEPC_EP20,
  13. ALC662_MODEL_LAST,
  14. };
  15. #define ALC662_DIGOUT_NID 0x06
  16. #define ALC662_DIGIN_NID 0x0a
  17. static const hda_nid_t alc662_dac_nids[3] = {
  18. /* front, rear, clfe */
  19. 0x02, 0x03, 0x04
  20. };
  21. static const hda_nid_t alc272_dac_nids[2] = {
  22. 0x02, 0x03
  23. };
  24. static const hda_nid_t alc662_adc_nids[2] = {
  25. /* ADC1-2 */
  26. 0x09, 0x08
  27. };
  28. static const hda_nid_t alc272_adc_nids[1] = {
  29. /* ADC1-2 */
  30. 0x08,
  31. };
  32. static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
  33. static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
  34. /* input MUX */
  35. /* FIXME: should be a matrix-type input source selection */
  36. static const struct hda_input_mux alc662_capture_source = {
  37. .num_items = 4,
  38. .items = {
  39. { "Mic", 0x0 },
  40. { "Front Mic", 0x1 },
  41. { "Line", 0x2 },
  42. { "CD", 0x4 },
  43. },
  44. };
  45. static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
  46. .num_items = 2,
  47. .items = {
  48. { "Mic", 0x1 },
  49. { "Line", 0x2 },
  50. },
  51. };
  52. static const struct hda_input_mux alc663_capture_source = {
  53. .num_items = 3,
  54. .items = {
  55. { "Mic", 0x0 },
  56. { "Front Mic", 0x1 },
  57. { "Line", 0x2 },
  58. },
  59. };
  60. /*
  61. * 2ch mode
  62. */
  63. static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
  64. { 2, NULL }
  65. };
  66. /*
  67. * 2ch mode
  68. */
  69. static const struct hda_verb alc662_3ST_ch2_init[] = {
  70. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  71. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  72. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  73. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  74. { } /* end */
  75. };
  76. /*
  77. * 6ch mode
  78. */
  79. static const struct hda_verb alc662_3ST_ch6_init[] = {
  80. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  81. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  82. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  83. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  84. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  85. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  86. { } /* end */
  87. };
  88. static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
  89. { 2, alc662_3ST_ch2_init },
  90. { 6, alc662_3ST_ch6_init },
  91. };
  92. /*
  93. * 2ch mode
  94. */
  95. static const struct hda_verb alc662_sixstack_ch6_init[] = {
  96. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  97. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  98. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  99. { } /* end */
  100. };
  101. /*
  102. * 6ch mode
  103. */
  104. static const struct hda_verb alc662_sixstack_ch8_init[] = {
  105. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  106. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  107. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  108. { } /* end */
  109. };
  110. static const struct hda_channel_mode alc662_5stack_modes[2] = {
  111. { 2, alc662_sixstack_ch6_init },
  112. { 6, alc662_sixstack_ch8_init },
  113. };
  114. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  115. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  116. */
  117. static const struct snd_kcontrol_new alc662_base_mixer[] = {
  118. /* output mixer control */
  119. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  120. HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
  121. HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  122. HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
  123. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  124. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  125. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
  126. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
  127. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  128. /*Input mixer control */
  129. HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
  130. HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
  131. HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
  132. HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
  133. HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
  134. HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
  135. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
  136. HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
  137. { } /* end */
  138. };
  139. static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
  140. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  141. HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
  142. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  143. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  144. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  145. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  146. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  147. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  148. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  149. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  150. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  151. { } /* end */
  152. };
  153. static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
  154. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  155. HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
  156. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  157. HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
  158. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  159. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  160. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
  161. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
  162. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  163. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  164. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  165. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  166. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  167. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  168. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  169. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  170. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  171. { } /* end */
  172. };
  173. static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
  174. ALC262_HIPPO_MASTER_SWITCH,
  175. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  176. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  177. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  178. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  179. HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
  180. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  181. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  182. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  183. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  184. { } /* end */
  185. };
  186. static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
  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 struct hda_verb alc662_init_verbs[] = {
  197. /* ADC: mute amp left and right */
  198. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  199. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  200. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  201. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  202. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  203. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  204. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  205. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  206. /* Front Pin: output 0 (0x0c) */
  207. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  208. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  209. /* Rear Pin: output 1 (0x0d) */
  210. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  211. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  212. /* CLFE Pin: output 2 (0x0e) */
  213. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  214. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  215. /* Mic (rear) pin: input vref at 80% */
  216. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  217. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  218. /* Front Mic pin: input vref at 80% */
  219. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  220. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  221. /* Line In pin: input */
  222. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  223. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  224. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  225. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  226. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  227. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  228. /* CD pin widget for input */
  229. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  230. /* FIXME: use matrix-type input source selection */
  231. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  232. /* Input mixer */
  233. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  234. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  235. { }
  236. };
  237. static const struct hda_verb alc662_eapd_init_verbs[] = {
  238. /* always trun on EAPD */
  239. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  240. {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
  241. { }
  242. };
  243. /* Set Unsolicited Event*/
  244. static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
  245. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  246. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  247. {}
  248. };
  249. static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
  250. {
  251. struct alc_spec *spec = codec->spec;
  252. spec->autocfg.hp_pins[0] = 0x14;
  253. spec->autocfg.speaker_pins[0] = 0x1b;
  254. spec->automute = 1;
  255. spec->automute_mode = ALC_AUTOMUTE_AMP;
  256. }
  257. /*
  258. * configuration and preset
  259. */
  260. static const char * const alc662_models[ALC662_MODEL_LAST] = {
  261. [ALC662_3ST_2ch_DIG] = "3stack-dig",
  262. [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
  263. [ALC662_3ST_6ch] = "3stack-6ch",
  264. [ALC662_5ST_DIG] = "5stack-dig",
  265. [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
  266. [ALC662_AUTO] = "auto",
  267. };
  268. static const struct snd_pci_quirk alc662_cfg_tbl[] = {
  269. SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
  270. SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
  271. SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
  272. ALC662_3ST_6ch_DIG),
  273. SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
  274. ALC662_3ST_6ch_DIG),
  275. SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
  276. SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
  277. ALC662_3ST_6ch_DIG),
  278. {}
  279. };
  280. static const struct alc_config_preset alc662_presets[] = {
  281. [ALC662_3ST_2ch_DIG] = {
  282. .mixers = { alc662_3ST_2ch_mixer },
  283. .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
  284. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  285. .dac_nids = alc662_dac_nids,
  286. .dig_out_nid = ALC662_DIGOUT_NID,
  287. .dig_in_nid = ALC662_DIGIN_NID,
  288. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  289. .channel_mode = alc662_3ST_2ch_modes,
  290. .input_mux = &alc662_capture_source,
  291. },
  292. [ALC662_3ST_6ch_DIG] = {
  293. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
  294. .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
  295. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  296. .dac_nids = alc662_dac_nids,
  297. .dig_out_nid = ALC662_DIGOUT_NID,
  298. .dig_in_nid = ALC662_DIGIN_NID,
  299. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  300. .channel_mode = alc662_3ST_6ch_modes,
  301. .need_dac_fix = 1,
  302. .input_mux = &alc662_capture_source,
  303. },
  304. [ALC662_3ST_6ch] = {
  305. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
  306. .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
  307. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  308. .dac_nids = alc662_dac_nids,
  309. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  310. .channel_mode = alc662_3ST_6ch_modes,
  311. .need_dac_fix = 1,
  312. .input_mux = &alc662_capture_source,
  313. },
  314. [ALC662_5ST_DIG] = {
  315. .mixers = { alc662_base_mixer, alc662_chmode_mixer },
  316. .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
  317. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  318. .dac_nids = alc662_dac_nids,
  319. .dig_out_nid = ALC662_DIGOUT_NID,
  320. .dig_in_nid = ALC662_DIGIN_NID,
  321. .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
  322. .channel_mode = alc662_5stack_modes,
  323. .input_mux = &alc662_capture_source,
  324. },
  325. [ALC662_ASUS_EEEPC_EP20] = {
  326. .mixers = { alc662_eeepc_ep20_mixer,
  327. alc662_chmode_mixer },
  328. .init_verbs = { alc662_init_verbs,
  329. alc662_eapd_init_verbs,
  330. alc662_eeepc_ep20_sue_init_verbs },
  331. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  332. .dac_nids = alc662_dac_nids,
  333. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  334. .channel_mode = alc662_3ST_6ch_modes,
  335. .input_mux = &alc662_lenovo_101e_capture_source,
  336. .unsol_event = alc_sku_unsol_event,
  337. .setup = alc662_eeepc_ep20_setup,
  338. .init_hook = alc_inithook,
  339. },
  340. };