alc269_quirks.c 23 KB

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