patch_analog.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*
  2. * HD audio interface patch for AD1981HD, AD1983, AD1986A
  3. *
  4. * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
  5. *
  6. * This driver is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This driver is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <sound/driver.h>
  21. #include <linux/init.h>
  22. #include <linux/delay.h>
  23. #include <linux/slab.h>
  24. #include <linux/pci.h>
  25. #include <sound/core.h>
  26. #include "hda_codec.h"
  27. #include "hda_local.h"
  28. struct ad198x_spec {
  29. snd_kcontrol_new_t *mixers[5];
  30. int num_mixers;
  31. const struct hda_verb *init_verbs[3]; /* initialization verbs
  32. * don't forget NULL termination!
  33. */
  34. unsigned int num_init_verbs;
  35. /* playback */
  36. struct hda_multi_out multiout; /* playback set-up
  37. * max_channels, dacs must be set
  38. * dig_out_nid and hp_nid are optional
  39. */
  40. /* capture */
  41. unsigned int num_adc_nids;
  42. hda_nid_t *adc_nids;
  43. hda_nid_t dig_in_nid; /* digital-in NID; optional */
  44. /* capture source */
  45. const struct hda_input_mux *input_mux;
  46. unsigned int cur_mux[3];
  47. /* channel model */
  48. const struct alc_channel_mode *channel_mode;
  49. int num_channel_mode;
  50. /* PCM information */
  51. struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
  52. struct semaphore amp_mutex; /* PCM volume/mute control mutex */
  53. unsigned int spdif_route;
  54. };
  55. /*
  56. * input MUX handling (common part)
  57. */
  58. static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  59. {
  60. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  61. struct ad198x_spec *spec = codec->spec;
  62. return snd_hda_input_mux_info(spec->input_mux, uinfo);
  63. }
  64. static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  65. {
  66. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  67. struct ad198x_spec *spec = codec->spec;
  68. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  69. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  70. return 0;
  71. }
  72. static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  73. {
  74. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  75. struct ad198x_spec *spec = codec->spec;
  76. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  77. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  78. spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
  79. }
  80. /*
  81. * initialization (common callbacks)
  82. */
  83. static int ad198x_init(struct hda_codec *codec)
  84. {
  85. struct ad198x_spec *spec = codec->spec;
  86. int i;
  87. for (i = 0; i < spec->num_init_verbs; i++)
  88. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  89. return 0;
  90. }
  91. static int ad198x_build_controls(struct hda_codec *codec)
  92. {
  93. struct ad198x_spec *spec = codec->spec;
  94. unsigned int i;
  95. int err;
  96. for (i = 0; i < spec->num_mixers; i++) {
  97. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  98. if (err < 0)
  99. return err;
  100. }
  101. if (spec->multiout.dig_out_nid) {
  102. err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
  103. if (err < 0)
  104. return err;
  105. }
  106. if (spec->dig_in_nid) {
  107. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  108. if (err < 0)
  109. return err;
  110. }
  111. return 0;
  112. }
  113. /*
  114. * Analog playback callbacks
  115. */
  116. static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
  117. struct hda_codec *codec,
  118. snd_pcm_substream_t *substream)
  119. {
  120. struct ad198x_spec *spec = codec->spec;
  121. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
  122. }
  123. static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  124. struct hda_codec *codec,
  125. unsigned int stream_tag,
  126. unsigned int format,
  127. snd_pcm_substream_t *substream)
  128. {
  129. struct ad198x_spec *spec = codec->spec;
  130. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
  131. format, substream);
  132. }
  133. static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  134. struct hda_codec *codec,
  135. snd_pcm_substream_t *substream)
  136. {
  137. struct ad198x_spec *spec = codec->spec;
  138. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  139. }
  140. /*
  141. * Digital out
  142. */
  143. static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  144. struct hda_codec *codec,
  145. snd_pcm_substream_t *substream)
  146. {
  147. struct ad198x_spec *spec = codec->spec;
  148. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  149. }
  150. static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  151. struct hda_codec *codec,
  152. snd_pcm_substream_t *substream)
  153. {
  154. struct ad198x_spec *spec = codec->spec;
  155. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  156. }
  157. /*
  158. * Analog capture
  159. */
  160. static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  161. struct hda_codec *codec,
  162. unsigned int stream_tag,
  163. unsigned int format,
  164. snd_pcm_substream_t *substream)
  165. {
  166. struct ad198x_spec *spec = codec->spec;
  167. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  168. stream_tag, 0, format);
  169. return 0;
  170. }
  171. static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  172. struct hda_codec *codec,
  173. snd_pcm_substream_t *substream)
  174. {
  175. struct ad198x_spec *spec = codec->spec;
  176. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  177. 0, 0, 0);
  178. return 0;
  179. }
  180. /*
  181. */
  182. static struct hda_pcm_stream ad198x_pcm_analog_playback = {
  183. .substreams = 1,
  184. .channels_min = 2,
  185. .channels_max = 6, /* changed later */
  186. .nid = 0, /* fill later */
  187. .ops = {
  188. .open = ad198x_playback_pcm_open,
  189. .prepare = ad198x_playback_pcm_prepare,
  190. .cleanup = ad198x_playback_pcm_cleanup
  191. },
  192. };
  193. static struct hda_pcm_stream ad198x_pcm_analog_capture = {
  194. .substreams = 1,
  195. .channels_min = 2,
  196. .channels_max = 2,
  197. .nid = 0, /* fill later */
  198. .ops = {
  199. .prepare = ad198x_capture_pcm_prepare,
  200. .cleanup = ad198x_capture_pcm_cleanup
  201. },
  202. };
  203. static struct hda_pcm_stream ad198x_pcm_digital_playback = {
  204. .substreams = 1,
  205. .channels_min = 2,
  206. .channels_max = 2,
  207. .nid = 0, /* fill later */
  208. .ops = {
  209. .open = ad198x_dig_playback_pcm_open,
  210. .close = ad198x_dig_playback_pcm_close
  211. },
  212. };
  213. static struct hda_pcm_stream ad198x_pcm_digital_capture = {
  214. .substreams = 1,
  215. .channels_min = 2,
  216. .channels_max = 2,
  217. /* NID is set in alc_build_pcms */
  218. };
  219. static int ad198x_build_pcms(struct hda_codec *codec)
  220. {
  221. struct ad198x_spec *spec = codec->spec;
  222. struct hda_pcm *info = spec->pcm_rec;
  223. codec->num_pcms = 1;
  224. codec->pcm_info = info;
  225. info->name = "AD198x Analog";
  226. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
  227. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
  228. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  229. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
  230. info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
  231. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  232. if (spec->multiout.dig_out_nid) {
  233. info++;
  234. codec->num_pcms++;
  235. info->name = "AD198x Digital";
  236. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
  237. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
  238. if (spec->dig_in_nid) {
  239. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
  240. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
  241. }
  242. }
  243. return 0;
  244. }
  245. static void ad198x_free(struct hda_codec *codec)
  246. {
  247. kfree(codec->spec);
  248. }
  249. #ifdef CONFIG_PM
  250. static int ad198x_resume(struct hda_codec *codec)
  251. {
  252. struct ad198x_spec *spec = codec->spec;
  253. int i;
  254. ad198x_init(codec);
  255. for (i = 0; i < spec->num_mixers; i++)
  256. snd_hda_resume_ctls(codec, spec->mixers[i]);
  257. if (spec->multiout.dig_out_nid)
  258. snd_hda_resume_spdif_out(codec);
  259. if (spec->dig_in_nid)
  260. snd_hda_resume_spdif_in(codec);
  261. return 0;
  262. }
  263. #endif
  264. static struct hda_codec_ops ad198x_patch_ops = {
  265. .build_controls = ad198x_build_controls,
  266. .build_pcms = ad198x_build_pcms,
  267. .init = ad198x_init,
  268. .free = ad198x_free,
  269. #ifdef CONFIG_PM
  270. .resume = ad198x_resume,
  271. #endif
  272. };
  273. /*
  274. * AD1986A specific
  275. */
  276. #define AD1986A_SPDIF_OUT 0x02
  277. #define AD1986A_FRONT_DAC 0x03
  278. #define AD1986A_SURR_DAC 0x04
  279. #define AD1986A_CLFE_DAC 0x05
  280. #define AD1986A_ADC 0x06
  281. static hda_nid_t ad1986a_dac_nids[3] = {
  282. AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
  283. };
  284. static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
  285. static struct hda_input_mux ad1986a_capture_source = {
  286. .num_items = 7,
  287. .items = {
  288. { "Mic", 0x0 },
  289. { "CD", 0x1 },
  290. { "Aux", 0x3 },
  291. { "Line", 0x4 },
  292. { "Mix", 0x5 },
  293. { "Mono", 0x6 },
  294. { "Phone", 0x7 },
  295. },
  296. };
  297. /*
  298. * PCM control
  299. *
  300. * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
  301. */
  302. #define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
  303. static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  304. {
  305. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  306. struct ad198x_spec *ad = codec->spec;
  307. down(&ad->amp_mutex);
  308. snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
  309. up(&ad->amp_mutex);
  310. return 0;
  311. }
  312. static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  313. {
  314. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  315. struct ad198x_spec *ad = codec->spec;
  316. int i, change = 0;
  317. down(&ad->amp_mutex);
  318. for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
  319. kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
  320. change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
  321. }
  322. kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
  323. up(&ad->amp_mutex);
  324. return change;
  325. }
  326. #define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
  327. static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  328. {
  329. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  330. struct ad198x_spec *ad = codec->spec;
  331. down(&ad->amp_mutex);
  332. snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
  333. up(&ad->amp_mutex);
  334. return 0;
  335. }
  336. static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  337. {
  338. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  339. struct ad198x_spec *ad = codec->spec;
  340. int i, change = 0;
  341. down(&ad->amp_mutex);
  342. for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
  343. kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
  344. change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
  345. }
  346. kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
  347. up(&ad->amp_mutex);
  348. return change;
  349. }
  350. /*
  351. * mixers
  352. */
  353. static snd_kcontrol_new_t ad1986a_mixers[] = {
  354. {
  355. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  356. .name = "PCM Playback Volume",
  357. .info = ad1986a_pcm_amp_vol_info,
  358. .get = ad1986a_pcm_amp_vol_get,
  359. .put = ad1986a_pcm_amp_vol_put,
  360. .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
  361. },
  362. {
  363. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  364. .name = "PCM Playback Switch",
  365. .info = ad1986a_pcm_amp_sw_info,
  366. .get = ad1986a_pcm_amp_sw_get,
  367. .put = ad1986a_pcm_amp_sw_put,
  368. .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
  369. },
  370. HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  371. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  372. HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  373. HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  374. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
  375. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
  376. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
  377. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
  378. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
  379. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
  380. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  381. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  382. HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  383. HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  384. HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
  385. HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  386. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  387. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  388. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
  389. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  390. HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
  391. HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
  392. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  393. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  394. {
  395. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  396. .name = "Capture Source",
  397. .info = ad198x_mux_enum_info,
  398. .get = ad198x_mux_enum_get,
  399. .put = ad198x_mux_enum_put,
  400. },
  401. HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
  402. { } /* end */
  403. };
  404. /*
  405. * initialization verbs
  406. */
  407. static struct hda_verb ad1986a_init_verbs[] = {
  408. /* Front, Surround, CLFE DAC; mute as default */
  409. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  410. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  411. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  412. /* Downmix - off */
  413. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  414. /* HP, Line-Out, Surround, CLFE selectors */
  415. {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
  416. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
  417. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  418. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  419. /* Mono selector */
  420. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
  421. /* Mic selector: Mic 1/2 pin */
  422. {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
  423. /* Line-in selector: Line-in */
  424. {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
  425. /* Mic 1/2 swap */
  426. {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
  427. /* Record selector: mic */
  428. {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
  429. /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
  430. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  431. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  432. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  433. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  434. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  435. /* PC beep */
  436. {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
  437. /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
  438. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  439. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  440. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  441. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  442. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  443. /* HP Pin */
  444. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  445. /* Front, Surround, CLFE Pins */
  446. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  447. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  448. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  449. /* Mono Pin */
  450. {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  451. /* Mic Pin */
  452. {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  453. /* Line, Aux, CD, Beep-In Pin */
  454. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  455. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  456. {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  457. {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  458. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  459. { } /* end */
  460. };
  461. static int patch_ad1986a(struct hda_codec *codec)
  462. {
  463. struct ad198x_spec *spec;
  464. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  465. if (spec == NULL)
  466. return -ENOMEM;
  467. init_MUTEX(&spec->amp_mutex);
  468. codec->spec = spec;
  469. spec->multiout.max_channels = 6;
  470. spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
  471. spec->multiout.dac_nids = ad1986a_dac_nids;
  472. spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
  473. spec->num_adc_nids = 1;
  474. spec->adc_nids = ad1986a_adc_nids;
  475. spec->input_mux = &ad1986a_capture_source;
  476. spec->num_mixers = 1;
  477. spec->mixers[0] = ad1986a_mixers;
  478. spec->num_init_verbs = 1;
  479. spec->init_verbs[0] = ad1986a_init_verbs;
  480. codec->patch_ops = ad198x_patch_ops;
  481. return 0;
  482. }
  483. /*
  484. * AD1983 specific
  485. */
  486. #define AD1983_SPDIF_OUT 0x02
  487. #define AD1983_DAC 0x03
  488. #define AD1983_ADC 0x04
  489. static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
  490. static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
  491. static struct hda_input_mux ad1983_capture_source = {
  492. .num_items = 4,
  493. .items = {
  494. { "Mic", 0x0 },
  495. { "Line", 0x1 },
  496. { "Mix", 0x2 },
  497. { "Mix Mono", 0x3 },
  498. },
  499. };
  500. /*
  501. * SPDIF playback route
  502. */
  503. static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  504. {
  505. static char *texts[] = { "PCM", "ADC" };
  506. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  507. uinfo->count = 1;
  508. uinfo->value.enumerated.items = 2;
  509. if (uinfo->value.enumerated.item > 1)
  510. uinfo->value.enumerated.item = 1;
  511. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  512. return 0;
  513. }
  514. static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  515. {
  516. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  517. struct ad198x_spec *spec = codec->spec;
  518. ucontrol->value.enumerated.item[0] = spec->spdif_route;
  519. return 0;
  520. }
  521. static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  522. {
  523. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  524. struct ad198x_spec *spec = codec->spec;
  525. if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
  526. spec->spdif_route = ucontrol->value.enumerated.item[0];
  527. snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
  528. AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
  529. return 1;
  530. }
  531. return 0;
  532. }
  533. static snd_kcontrol_new_t ad1983_mixers[] = {
  534. HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  535. HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
  536. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  537. HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  538. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
  539. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
  540. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  541. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  542. HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  543. HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  544. HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  545. HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  546. HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
  547. HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
  548. HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
  549. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  550. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  551. {
  552. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  553. .name = "Capture Source",
  554. .info = ad198x_mux_enum_info,
  555. .get = ad198x_mux_enum_get,
  556. .put = ad198x_mux_enum_put,
  557. },
  558. {
  559. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  560. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
  561. .info = ad1983_spdif_route_info,
  562. .get = ad1983_spdif_route_get,
  563. .put = ad1983_spdif_route_put,
  564. },
  565. { } /* end */
  566. };
  567. static struct hda_verb ad1983_init_verbs[] = {
  568. /* Front, HP, Mono; mute as default */
  569. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  570. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  571. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  572. /* Beep, PCM, Mic, Line-In: mute */
  573. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  574. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  575. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  576. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  577. /* Front, HP selectors; from Mix */
  578. {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
  579. {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
  580. /* Mono selector; from Mix */
  581. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
  582. /* Mic selector; Mic */
  583. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  584. /* Line-in selector: Line-in */
  585. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  586. /* Mic boost: 0dB */
  587. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  588. /* Record selector: mic */
  589. {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
  590. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  591. /* SPDIF route: PCM */
  592. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
  593. /* Front Pin */
  594. {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  595. /* HP Pin */
  596. {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  597. /* Mono Pin */
  598. {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  599. /* Mic Pin */
  600. {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  601. /* Line Pin */
  602. {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  603. { } /* end */
  604. };
  605. static int patch_ad1983(struct hda_codec *codec)
  606. {
  607. struct ad198x_spec *spec;
  608. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  609. if (spec == NULL)
  610. return -ENOMEM;
  611. init_MUTEX(&spec->amp_mutex);
  612. codec->spec = spec;
  613. spec->multiout.max_channels = 2;
  614. spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
  615. spec->multiout.dac_nids = ad1983_dac_nids;
  616. spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
  617. spec->num_adc_nids = 1;
  618. spec->adc_nids = ad1983_adc_nids;
  619. spec->input_mux = &ad1983_capture_source;
  620. spec->num_mixers = 1;
  621. spec->mixers[0] = ad1983_mixers;
  622. spec->num_init_verbs = 1;
  623. spec->init_verbs[0] = ad1983_init_verbs;
  624. spec->spdif_route = 0;
  625. codec->patch_ops = ad198x_patch_ops;
  626. return 0;
  627. }
  628. /*
  629. * AD1981 HD specific
  630. */
  631. #define AD1981_SPDIF_OUT 0x02
  632. #define AD1981_DAC 0x03
  633. #define AD1981_ADC 0x04
  634. static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
  635. static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
  636. /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
  637. static struct hda_input_mux ad1981_capture_source = {
  638. .num_items = 7,
  639. .items = {
  640. { "Front Mic", 0x0 },
  641. { "Line", 0x1 },
  642. { "Mix", 0x2 },
  643. { "Mix Mono", 0x3 },
  644. { "CD", 0x4 },
  645. { "Mic", 0x6 },
  646. { "Aux", 0x7 },
  647. },
  648. };
  649. static snd_kcontrol_new_t ad1981_mixers[] = {
  650. HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  651. HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
  652. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  653. HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  654. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
  655. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
  656. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  657. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  658. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  659. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  660. HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  661. HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  662. HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  663. HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  664. HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  665. HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  666. HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
  667. HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
  668. HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  669. HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
  670. HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
  671. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
  672. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  673. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  674. {
  675. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  676. .name = "Capture Source",
  677. .info = ad198x_mux_enum_info,
  678. .get = ad198x_mux_enum_get,
  679. .put = ad198x_mux_enum_put,
  680. },
  681. /* identical with AD1983 */
  682. {
  683. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  684. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
  685. .info = ad1983_spdif_route_info,
  686. .get = ad1983_spdif_route_get,
  687. .put = ad1983_spdif_route_put,
  688. },
  689. { } /* end */
  690. };
  691. static struct hda_verb ad1981_init_verbs[] = {
  692. /* Front, HP, Mono; mute as default */
  693. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  694. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  695. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  696. /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
  697. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  698. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  699. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  700. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  701. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  702. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  703. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  704. /* Front, HP selectors; from Mix */
  705. {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
  706. {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
  707. /* Mono selector; from Mix */
  708. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
  709. /* Mic Mixer; select Front Mic */
  710. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  711. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  712. /* Mic boost: 0dB */
  713. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  714. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  715. /* Record selector: Front mic */
  716. {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
  717. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  718. /* SPDIF route: PCM */
  719. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
  720. /* Front Pin */
  721. {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  722. /* HP Pin */
  723. {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  724. /* Mono Pin */
  725. {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  726. /* Front & Rear Mic Pins */
  727. {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  728. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  729. /* Line Pin */
  730. {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  731. /* Digital Beep */
  732. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
  733. /* Line-Out as Input: disabled */
  734. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  735. { } /* end */
  736. };
  737. static int patch_ad1981(struct hda_codec *codec)
  738. {
  739. struct ad198x_spec *spec;
  740. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  741. if (spec == NULL)
  742. return -ENOMEM;
  743. init_MUTEX(&spec->amp_mutex);
  744. codec->spec = spec;
  745. spec->multiout.max_channels = 2;
  746. spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
  747. spec->multiout.dac_nids = ad1981_dac_nids;
  748. spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
  749. spec->num_adc_nids = 1;
  750. spec->adc_nids = ad1981_adc_nids;
  751. spec->input_mux = &ad1981_capture_source;
  752. spec->num_mixers = 1;
  753. spec->mixers[0] = ad1981_mixers;
  754. spec->num_init_verbs = 1;
  755. spec->init_verbs[0] = ad1981_init_verbs;
  756. spec->spdif_route = 0;
  757. codec->patch_ops = ad198x_patch_ops;
  758. return 0;
  759. }
  760. /*
  761. * patch entries
  762. */
  763. struct hda_codec_preset snd_hda_preset_analog[] = {
  764. { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
  765. { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
  766. { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
  767. {} /* terminator */
  768. };