alc269_quirks.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * ALC269/ALC270/ALC275/ALC276 quirk models
  3. * included by patch_realtek.c
  4. */
  5. /* ALC269 models */
  6. enum {
  7. ALC269_AUTO,
  8. ALC269_BASIC,
  9. ALC269_QUANTA_FL1,
  10. ALC269_AMIC,
  11. ALC269_DMIC,
  12. ALC269VB_AMIC,
  13. ALC269VB_DMIC,
  14. ALC269_LIFEBOOK,
  15. ALC269_MODEL_LAST /* last tag */
  16. };
  17. /*
  18. * ALC269 channel source setting (2 channel)
  19. */
  20. #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
  21. #define alc269_dac_nids alc260_dac_nids
  22. static const hda_nid_t alc269_adc_nids[1] = {
  23. /* ADC1 */
  24. 0x08,
  25. };
  26. static const hda_nid_t alc269_capsrc_nids[1] = {
  27. 0x23,
  28. };
  29. static const hda_nid_t alc269vb_adc_nids[1] = {
  30. /* ADC1 */
  31. 0x09,
  32. };
  33. static const hda_nid_t alc269vb_capsrc_nids[1] = {
  34. 0x22,
  35. };
  36. #define alc269_modes alc260_modes
  37. #define alc269_capture_source alc880_lg_lw_capture_source
  38. static const struct snd_kcontrol_new alc269_base_mixer[] = {
  39. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  40. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  41. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  42. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  43. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  44. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  45. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  46. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  47. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  48. HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
  49. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  50. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  51. { } /* end */
  52. };
  53. /* Acer specific */
  54. /* bind volumes of both NID 0x02 and 0x03 */
  55. static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
  56. .ops = &snd_hda_bind_vol,
  57. .values = {
  58. HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
  59. HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
  60. 0
  61. },
  62. };
  63. #define alc268_acer_master_sw_get alc262_hp_master_sw_get
  64. #define alc268_acer_master_sw_put alc262_hp_master_sw_put
  65. static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
  66. /* output mixer control */
  67. HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
  68. {
  69. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  70. .name = "Master Playback Switch",
  71. .subdevice = HDA_SUBDEV_AMP_FLAG,
  72. .info = snd_hda_mixer_amp_switch_info,
  73. .get = snd_hda_mixer_amp_switch_get,
  74. .put = alc268_acer_master_sw_put,
  75. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  76. },
  77. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  78. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  79. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  80. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  81. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  82. HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
  83. { }
  84. };
  85. static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
  86. /* output mixer control */
  87. HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
  88. {
  89. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  90. .name = "Master Playback Switch",
  91. .subdevice = HDA_SUBDEV_AMP_FLAG,
  92. .info = snd_hda_mixer_amp_switch_info,
  93. .get = snd_hda_mixer_amp_switch_get,
  94. .put = alc268_acer_master_sw_put,
  95. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  96. },
  97. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  98. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  99. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  100. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  101. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  102. HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
  103. HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
  104. HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
  105. HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
  106. { }
  107. };
  108. static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
  109. HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  110. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  111. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  112. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  113. { } /* end */
  114. };
  115. static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
  116. HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  117. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  118. HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  119. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  120. { } /* end */
  121. };
  122. static const struct snd_kcontrol_new alc269_asus_mixer[] = {
  123. HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  124. HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
  125. { } /* end */
  126. };
  127. /* capture mixer elements */
  128. static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
  129. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  130. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  131. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  132. HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
  133. { } /* end */
  134. };
  135. static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
  136. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  137. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  138. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  139. { } /* end */
  140. };
  141. static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
  142. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  143. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  144. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  145. HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
  146. { } /* end */
  147. };
  148. static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
  149. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  150. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  151. HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
  152. { } /* end */
  153. };
  154. static const struct hda_verb alc269_quanta_fl1_verbs[] = {
  155. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  156. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  157. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  158. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
  159. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  160. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  161. { }
  162. };
  163. static const struct hda_verb alc269_lifebook_verbs[] = {
  164. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  165. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
  166. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  167. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  168. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
  169. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  170. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  171. {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
  172. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  173. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  174. { }
  175. };
  176. /* toggle speaker-output according to the hp-jack state */
  177. static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
  178. {
  179. alc_hp_automute(codec);
  180. snd_hda_codec_write(codec, 0x20, 0,
  181. AC_VERB_SET_COEF_INDEX, 0x0c);
  182. snd_hda_codec_write(codec, 0x20, 0,
  183. AC_VERB_SET_PROC_COEF, 0x680);
  184. snd_hda_codec_write(codec, 0x20, 0,
  185. AC_VERB_SET_COEF_INDEX, 0x0c);
  186. snd_hda_codec_write(codec, 0x20, 0,
  187. AC_VERB_SET_PROC_COEF, 0x480);
  188. }
  189. #define alc269_lifebook_speaker_automute \
  190. alc269_quanta_fl1_speaker_automute
  191. static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
  192. {
  193. unsigned int present_laptop;
  194. unsigned int present_dock;
  195. present_laptop = snd_hda_jack_detect(codec, 0x18);
  196. present_dock = snd_hda_jack_detect(codec, 0x1b);
  197. /* Laptop mic port overrides dock mic port, design decision */
  198. if (present_dock)
  199. snd_hda_codec_write(codec, 0x23, 0,
  200. AC_VERB_SET_CONNECT_SEL, 0x3);
  201. if (present_laptop)
  202. snd_hda_codec_write(codec, 0x23, 0,
  203. AC_VERB_SET_CONNECT_SEL, 0x0);
  204. if (!present_dock && !present_laptop)
  205. snd_hda_codec_write(codec, 0x23, 0,
  206. AC_VERB_SET_CONNECT_SEL, 0x1);
  207. }
  208. static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
  209. unsigned int res)
  210. {
  211. switch (res >> 26) {
  212. case ALC_HP_EVENT:
  213. alc269_quanta_fl1_speaker_automute(codec);
  214. break;
  215. case ALC_MIC_EVENT:
  216. alc_mic_automute(codec);
  217. break;
  218. }
  219. }
  220. static void alc269_lifebook_unsol_event(struct hda_codec *codec,
  221. unsigned int res)
  222. {
  223. if ((res >> 26) == ALC_HP_EVENT)
  224. alc269_lifebook_speaker_automute(codec);
  225. if ((res >> 26) == ALC_MIC_EVENT)
  226. alc269_lifebook_mic_autoswitch(codec);
  227. }
  228. static void alc269_quanta_fl1_setup(struct hda_codec *codec)
  229. {
  230. struct alc_spec *spec = codec->spec;
  231. spec->autocfg.hp_pins[0] = 0x15;
  232. spec->autocfg.speaker_pins[0] = 0x14;
  233. spec->automute_mixer_nid[0] = 0x0c;
  234. spec->automute = 1;
  235. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  236. spec->ext_mic_pin = 0x18;
  237. spec->int_mic_pin = 0x19;
  238. spec->auto_mic = 1;
  239. }
  240. static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
  241. {
  242. alc269_quanta_fl1_speaker_automute(codec);
  243. alc_mic_automute(codec);
  244. }
  245. static void alc269_lifebook_setup(struct hda_codec *codec)
  246. {
  247. struct alc_spec *spec = codec->spec;
  248. spec->autocfg.hp_pins[0] = 0x15;
  249. spec->autocfg.hp_pins[1] = 0x1a;
  250. spec->autocfg.speaker_pins[0] = 0x14;
  251. spec->automute_mixer_nid[0] = 0x0c;
  252. spec->automute = 1;
  253. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  254. }
  255. static void alc269_lifebook_init_hook(struct hda_codec *codec)
  256. {
  257. alc269_lifebook_speaker_automute(codec);
  258. alc269_lifebook_mic_autoswitch(codec);
  259. }
  260. static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
  261. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  262. {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
  263. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
  264. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
  265. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  266. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  267. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  268. {}
  269. };
  270. static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
  271. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  272. {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
  273. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
  274. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
  275. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  276. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  277. {}
  278. };
  279. static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
  280. {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
  281. {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
  282. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
  283. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
  284. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  285. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  286. {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  287. {}
  288. };
  289. static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
  290. {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
  291. {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
  292. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
  293. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
  294. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  295. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
  296. {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  297. {}
  298. };
  299. static void alc269_laptop_amic_setup(struct hda_codec *codec)
  300. {
  301. struct alc_spec *spec = codec->spec;
  302. spec->autocfg.hp_pins[0] = 0x15;
  303. spec->autocfg.speaker_pins[0] = 0x14;
  304. spec->automute_mixer_nid[0] = 0x0c;
  305. spec->automute = 1;
  306. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  307. spec->ext_mic_pin = 0x18;
  308. spec->int_mic_pin = 0x19;
  309. spec->auto_mic = 1;
  310. }
  311. static void alc269_laptop_dmic_setup(struct hda_codec *codec)
  312. {
  313. struct alc_spec *spec = codec->spec;
  314. spec->autocfg.hp_pins[0] = 0x15;
  315. spec->autocfg.speaker_pins[0] = 0x14;
  316. spec->automute_mixer_nid[0] = 0x0c;
  317. spec->automute = 1;
  318. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  319. spec->ext_mic_pin = 0x18;
  320. spec->int_mic_pin = 0x12;
  321. spec->auto_mic = 1;
  322. }
  323. static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
  324. {
  325. struct alc_spec *spec = codec->spec;
  326. spec->autocfg.hp_pins[0] = 0x21;
  327. spec->autocfg.speaker_pins[0] = 0x14;
  328. spec->automute_mixer_nid[0] = 0x0c;
  329. spec->automute = 1;
  330. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  331. spec->ext_mic_pin = 0x18;
  332. spec->int_mic_pin = 0x19;
  333. spec->auto_mic = 1;
  334. }
  335. static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
  336. {
  337. struct alc_spec *spec = codec->spec;
  338. spec->autocfg.hp_pins[0] = 0x21;
  339. spec->autocfg.speaker_pins[0] = 0x14;
  340. spec->automute_mixer_nid[0] = 0x0c;
  341. spec->automute = 1;
  342. spec->automute_mode = ALC_AUTOMUTE_MIXER;
  343. spec->ext_mic_pin = 0x18;
  344. spec->int_mic_pin = 0x12;
  345. spec->auto_mic = 1;
  346. }
  347. /*
  348. * generic initialization of ADC, input mixers and output mixers
  349. */
  350. static const struct hda_verb alc269_init_verbs[] = {
  351. /*
  352. * Unmute ADC0 and set the default input to mic-in
  353. */
  354. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  355. /*
  356. * Set up output mixers (0x02 - 0x03)
  357. */
  358. /* set vol=0 to output mixers */
  359. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  360. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  361. /* set up input amps for analog loopback */
  362. /* Amp Indices: DAC = 0, mixer = 1 */
  363. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  364. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  365. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  366. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  367. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  368. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  369. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  370. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  371. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  372. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  373. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  374. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  375. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  376. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  377. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  378. /* FIXME: use Mux-type input source selection */
  379. /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
  380. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  381. {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
  382. /* set EAPD */
  383. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  384. { }
  385. };
  386. static const struct hda_verb alc269vb_init_verbs[] = {
  387. /*
  388. * Unmute ADC0 and set the default input to mic-in
  389. */
  390. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  391. /*
  392. * Set up output mixers (0x02 - 0x03)
  393. */
  394. /* set vol=0 to output mixers */
  395. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  396. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  397. /* set up input amps for analog loopback */
  398. /* Amp Indices: DAC = 0, mixer = 1 */
  399. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  400. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  401. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  402. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  403. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  404. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  405. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  406. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  407. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  408. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  409. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  410. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  411. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  412. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  413. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  414. /* FIXME: use Mux-type input source selection */
  415. /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
  416. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  417. {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
  418. /* set EAPD */
  419. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  420. { }
  421. };
  422. /*
  423. * configuration and preset
  424. */
  425. static const char * const alc269_models[ALC269_MODEL_LAST] = {
  426. [ALC269_BASIC] = "basic",
  427. [ALC269_QUANTA_FL1] = "quanta",
  428. [ALC269_AMIC] = "laptop-amic",
  429. [ALC269_DMIC] = "laptop-dmic",
  430. [ALC269_LIFEBOOK] = "lifebook",
  431. [ALC269_AUTO] = "auto",
  432. };
  433. static const struct snd_pci_quirk alc269_cfg_tbl[] = {
  434. SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
  435. SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
  436. ALC269_AMIC),
  437. SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
  438. SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
  439. SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
  440. SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
  441. SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
  442. SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
  443. SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
  444. SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
  445. SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
  446. SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
  447. SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
  448. SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
  449. SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
  450. SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
  451. SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
  452. SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
  453. SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
  454. SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
  455. SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
  456. SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
  457. SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
  458. SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
  459. SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
  460. SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
  461. SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
  462. SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
  463. SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
  464. SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
  465. SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
  466. SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
  467. SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
  468. SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
  469. SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
  470. SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
  471. SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
  472. SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
  473. SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
  474. SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
  475. SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
  476. SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
  477. SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
  478. SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
  479. {}
  480. };
  481. static const struct alc_config_preset alc269_presets[] = {
  482. [ALC269_BASIC] = {
  483. .mixers = { alc269_base_mixer },
  484. .init_verbs = { alc269_init_verbs },
  485. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  486. .dac_nids = alc269_dac_nids,
  487. .hp_nid = 0x03,
  488. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  489. .channel_mode = alc269_modes,
  490. .input_mux = &alc269_capture_source,
  491. },
  492. [ALC269_QUANTA_FL1] = {
  493. .mixers = { alc269_quanta_fl1_mixer },
  494. .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
  495. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  496. .dac_nids = alc269_dac_nids,
  497. .hp_nid = 0x03,
  498. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  499. .channel_mode = alc269_modes,
  500. .input_mux = &alc269_capture_source,
  501. .unsol_event = alc269_quanta_fl1_unsol_event,
  502. .setup = alc269_quanta_fl1_setup,
  503. .init_hook = alc269_quanta_fl1_init_hook,
  504. },
  505. [ALC269_AMIC] = {
  506. .mixers = { alc269_laptop_mixer },
  507. .cap_mixer = alc269_laptop_analog_capture_mixer,
  508. .init_verbs = { alc269_init_verbs,
  509. alc269_laptop_amic_init_verbs },
  510. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  511. .dac_nids = alc269_dac_nids,
  512. .hp_nid = 0x03,
  513. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  514. .channel_mode = alc269_modes,
  515. .unsol_event = alc_sku_unsol_event,
  516. .setup = alc269_laptop_amic_setup,
  517. .init_hook = alc_inithook,
  518. },
  519. [ALC269_DMIC] = {
  520. .mixers = { alc269_laptop_mixer },
  521. .cap_mixer = alc269_laptop_digital_capture_mixer,
  522. .init_verbs = { alc269_init_verbs,
  523. alc269_laptop_dmic_init_verbs },
  524. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  525. .dac_nids = alc269_dac_nids,
  526. .hp_nid = 0x03,
  527. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  528. .channel_mode = alc269_modes,
  529. .unsol_event = alc_sku_unsol_event,
  530. .setup = alc269_laptop_dmic_setup,
  531. .init_hook = alc_inithook,
  532. },
  533. [ALC269VB_AMIC] = {
  534. .mixers = { alc269vb_laptop_mixer },
  535. .cap_mixer = alc269vb_laptop_analog_capture_mixer,
  536. .init_verbs = { alc269vb_init_verbs,
  537. alc269vb_laptop_amic_init_verbs },
  538. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  539. .dac_nids = alc269_dac_nids,
  540. .hp_nid = 0x03,
  541. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  542. .channel_mode = alc269_modes,
  543. .unsol_event = alc_sku_unsol_event,
  544. .setup = alc269vb_laptop_amic_setup,
  545. .init_hook = alc_inithook,
  546. },
  547. [ALC269VB_DMIC] = {
  548. .mixers = { alc269vb_laptop_mixer },
  549. .cap_mixer = alc269vb_laptop_digital_capture_mixer,
  550. .init_verbs = { alc269vb_init_verbs,
  551. alc269vb_laptop_dmic_init_verbs },
  552. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  553. .dac_nids = alc269_dac_nids,
  554. .hp_nid = 0x03,
  555. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  556. .channel_mode = alc269_modes,
  557. .unsol_event = alc_sku_unsol_event,
  558. .setup = alc269vb_laptop_dmic_setup,
  559. .init_hook = alc_inithook,
  560. },
  561. [ALC269_LIFEBOOK] = {
  562. .mixers = { alc269_lifebook_mixer },
  563. .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
  564. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  565. .dac_nids = alc269_dac_nids,
  566. .hp_nid = 0x03,
  567. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  568. .channel_mode = alc269_modes,
  569. .input_mux = &alc269_capture_source,
  570. .unsol_event = alc269_lifebook_unsol_event,
  571. .setup = alc269_lifebook_setup,
  572. .init_hook = alc269_lifebook_init_hook,
  573. },
  574. };