patch_analog.c 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087
  1. /*
  2. * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
  3. * AD1986A, AD1988
  4. *
  5. * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
  6. *
  7. * This driver is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This driver is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <linux/init.h>
  22. #include <linux/slab.h>
  23. #include <linux/pci.h>
  24. #include <linux/module.h>
  25. #include <sound/core.h>
  26. #include "hda_codec.h"
  27. #include "hda_local.h"
  28. #include "hda_auto_parser.h"
  29. #include "hda_beep.h"
  30. #include "hda_jack.h"
  31. #include "hda_generic.h"
  32. #define ENABLE_AD_STATIC_QUIRKS
  33. struct ad198x_spec {
  34. struct hda_gen_spec gen;
  35. /* for auto parser */
  36. int smux_paths[4];
  37. unsigned int cur_smux;
  38. hda_nid_t eapd_nid;
  39. unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
  40. #ifdef ENABLE_AD_STATIC_QUIRKS
  41. const struct snd_kcontrol_new *mixers[6];
  42. int num_mixers;
  43. const struct hda_verb *init_verbs[6]; /* initialization verbs
  44. * don't forget NULL termination!
  45. */
  46. unsigned int num_init_verbs;
  47. /* playback */
  48. struct hda_multi_out multiout; /* playback set-up
  49. * max_channels, dacs must be set
  50. * dig_out_nid and hp_nid are optional
  51. */
  52. unsigned int cur_eapd;
  53. unsigned int need_dac_fix;
  54. /* capture */
  55. unsigned int num_adc_nids;
  56. const hda_nid_t *adc_nids;
  57. hda_nid_t dig_in_nid; /* digital-in NID; optional */
  58. /* capture source */
  59. const struct hda_input_mux *input_mux;
  60. const hda_nid_t *capsrc_nids;
  61. unsigned int cur_mux[3];
  62. /* channel model */
  63. const struct hda_channel_mode *channel_mode;
  64. int num_channel_mode;
  65. /* PCM information */
  66. struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
  67. unsigned int spdif_route;
  68. unsigned int jack_present: 1;
  69. unsigned int inv_jack_detect: 1;/* inverted jack-detection */
  70. unsigned int analog_beep: 1; /* analog beep input present */
  71. unsigned int avoid_init_slave_vol:1;
  72. #ifdef CONFIG_PM
  73. struct hda_loopback_check loopback;
  74. #endif
  75. /* for virtual master */
  76. hda_nid_t vmaster_nid;
  77. const char * const *slave_vols;
  78. const char * const *slave_sws;
  79. #endif /* ENABLE_AD_STATIC_QUIRKS */
  80. };
  81. #ifdef ENABLE_AD_STATIC_QUIRKS
  82. /*
  83. * input MUX handling (common part)
  84. */
  85. static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  86. {
  87. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  88. struct ad198x_spec *spec = codec->spec;
  89. return snd_hda_input_mux_info(spec->input_mux, uinfo);
  90. }
  91. static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  92. {
  93. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  94. struct ad198x_spec *spec = codec->spec;
  95. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  96. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  97. return 0;
  98. }
  99. static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  100. {
  101. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  102. struct ad198x_spec *spec = codec->spec;
  103. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  104. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  105. spec->capsrc_nids[adc_idx],
  106. &spec->cur_mux[adc_idx]);
  107. }
  108. /*
  109. * initialization (common callbacks)
  110. */
  111. static int ad198x_init(struct hda_codec *codec)
  112. {
  113. struct ad198x_spec *spec = codec->spec;
  114. int i;
  115. for (i = 0; i < spec->num_init_verbs; i++)
  116. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  117. return 0;
  118. }
  119. static const char * const ad_slave_pfxs[] = {
  120. "Front", "Surround", "Center", "LFE", "Side",
  121. "Headphone", "Mono", "Speaker", "IEC958",
  122. NULL
  123. };
  124. static const char * const ad1988_6stack_fp_slave_pfxs[] = {
  125. "Front", "Surround", "Center", "LFE", "Side", "IEC958",
  126. NULL
  127. };
  128. #endif /* ENABLE_AD_STATIC_QUIRKS */
  129. #ifdef CONFIG_SND_HDA_INPUT_BEEP
  130. /* additional beep mixers; the actual parameters are overwritten at build */
  131. static const struct snd_kcontrol_new ad_beep_mixer[] = {
  132. HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
  133. HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
  134. { } /* end */
  135. };
  136. static const struct snd_kcontrol_new ad_beep2_mixer[] = {
  137. HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
  138. HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
  139. { } /* end */
  140. };
  141. #define set_beep_amp(spec, nid, idx, dir) \
  142. ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
  143. #else
  144. #define set_beep_amp(spec, nid, idx, dir) /* NOP */
  145. #endif
  146. #ifdef CONFIG_SND_HDA_INPUT_BEEP
  147. static int create_beep_ctls(struct hda_codec *codec)
  148. {
  149. struct ad198x_spec *spec = codec->spec;
  150. const struct snd_kcontrol_new *knew;
  151. if (!spec->beep_amp)
  152. return 0;
  153. knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
  154. for ( ; knew->name; knew++) {
  155. int err;
  156. struct snd_kcontrol *kctl;
  157. kctl = snd_ctl_new1(knew, codec);
  158. if (!kctl)
  159. return -ENOMEM;
  160. kctl->private_value = spec->beep_amp;
  161. err = snd_hda_ctl_add(codec, 0, kctl);
  162. if (err < 0)
  163. return err;
  164. }
  165. return 0;
  166. }
  167. #else
  168. #define create_beep_ctls(codec) 0
  169. #endif
  170. #ifdef ENABLE_AD_STATIC_QUIRKS
  171. static int ad198x_build_controls(struct hda_codec *codec)
  172. {
  173. struct ad198x_spec *spec = codec->spec;
  174. struct snd_kcontrol *kctl;
  175. unsigned int i;
  176. int err;
  177. for (i = 0; i < spec->num_mixers; i++) {
  178. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  179. if (err < 0)
  180. return err;
  181. }
  182. if (spec->multiout.dig_out_nid) {
  183. err = snd_hda_create_spdif_out_ctls(codec,
  184. spec->multiout.dig_out_nid,
  185. spec->multiout.dig_out_nid);
  186. if (err < 0)
  187. return err;
  188. err = snd_hda_create_spdif_share_sw(codec,
  189. &spec->multiout);
  190. if (err < 0)
  191. return err;
  192. spec->multiout.share_spdif = 1;
  193. }
  194. if (spec->dig_in_nid) {
  195. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  196. if (err < 0)
  197. return err;
  198. }
  199. /* create beep controls if needed */
  200. err = create_beep_ctls(codec);
  201. if (err < 0)
  202. return err;
  203. /* if we have no master control, let's create it */
  204. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
  205. unsigned int vmaster_tlv[4];
  206. snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
  207. HDA_OUTPUT, vmaster_tlv);
  208. err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
  209. vmaster_tlv,
  210. (spec->slave_vols ?
  211. spec->slave_vols : ad_slave_pfxs),
  212. "Playback Volume",
  213. !spec->avoid_init_slave_vol, NULL);
  214. if (err < 0)
  215. return err;
  216. }
  217. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
  218. err = snd_hda_add_vmaster(codec, "Master Playback Switch",
  219. NULL,
  220. (spec->slave_sws ?
  221. spec->slave_sws : ad_slave_pfxs),
  222. "Playback Switch");
  223. if (err < 0)
  224. return err;
  225. }
  226. /* assign Capture Source enums to NID */
  227. kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
  228. if (!kctl)
  229. kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
  230. for (i = 0; kctl && i < kctl->count; i++) {
  231. err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
  232. if (err < 0)
  233. return err;
  234. }
  235. /* assign IEC958 enums to NID */
  236. kctl = snd_hda_find_mixer_ctl(codec,
  237. SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
  238. if (kctl) {
  239. err = snd_hda_add_nid(codec, kctl, 0,
  240. spec->multiout.dig_out_nid);
  241. if (err < 0)
  242. return err;
  243. }
  244. return 0;
  245. }
  246. #ifdef CONFIG_PM
  247. static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
  248. {
  249. struct ad198x_spec *spec = codec->spec;
  250. return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
  251. }
  252. #endif
  253. /*
  254. * Analog playback callbacks
  255. */
  256. static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
  257. struct hda_codec *codec,
  258. struct snd_pcm_substream *substream)
  259. {
  260. struct ad198x_spec *spec = codec->spec;
  261. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
  262. hinfo);
  263. }
  264. static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  265. struct hda_codec *codec,
  266. unsigned int stream_tag,
  267. unsigned int format,
  268. struct snd_pcm_substream *substream)
  269. {
  270. struct ad198x_spec *spec = codec->spec;
  271. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
  272. format, substream);
  273. }
  274. static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  275. struct hda_codec *codec,
  276. struct snd_pcm_substream *substream)
  277. {
  278. struct ad198x_spec *spec = codec->spec;
  279. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  280. }
  281. /*
  282. * Digital out
  283. */
  284. static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  285. struct hda_codec *codec,
  286. struct snd_pcm_substream *substream)
  287. {
  288. struct ad198x_spec *spec = codec->spec;
  289. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  290. }
  291. static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  292. struct hda_codec *codec,
  293. struct snd_pcm_substream *substream)
  294. {
  295. struct ad198x_spec *spec = codec->spec;
  296. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  297. }
  298. static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  299. struct hda_codec *codec,
  300. unsigned int stream_tag,
  301. unsigned int format,
  302. struct snd_pcm_substream *substream)
  303. {
  304. struct ad198x_spec *spec = codec->spec;
  305. return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
  306. format, substream);
  307. }
  308. static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  309. struct hda_codec *codec,
  310. struct snd_pcm_substream *substream)
  311. {
  312. struct ad198x_spec *spec = codec->spec;
  313. return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
  314. }
  315. /*
  316. * Analog capture
  317. */
  318. static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  319. struct hda_codec *codec,
  320. unsigned int stream_tag,
  321. unsigned int format,
  322. struct snd_pcm_substream *substream)
  323. {
  324. struct ad198x_spec *spec = codec->spec;
  325. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  326. stream_tag, 0, format);
  327. return 0;
  328. }
  329. static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  330. struct hda_codec *codec,
  331. struct snd_pcm_substream *substream)
  332. {
  333. struct ad198x_spec *spec = codec->spec;
  334. snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
  335. return 0;
  336. }
  337. /*
  338. */
  339. static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
  340. .substreams = 1,
  341. .channels_min = 2,
  342. .channels_max = 6, /* changed later */
  343. .nid = 0, /* fill later */
  344. .ops = {
  345. .open = ad198x_playback_pcm_open,
  346. .prepare = ad198x_playback_pcm_prepare,
  347. .cleanup = ad198x_playback_pcm_cleanup,
  348. },
  349. };
  350. static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
  351. .substreams = 1,
  352. .channels_min = 2,
  353. .channels_max = 2,
  354. .nid = 0, /* fill later */
  355. .ops = {
  356. .prepare = ad198x_capture_pcm_prepare,
  357. .cleanup = ad198x_capture_pcm_cleanup
  358. },
  359. };
  360. static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
  361. .substreams = 1,
  362. .channels_min = 2,
  363. .channels_max = 2,
  364. .nid = 0, /* fill later */
  365. .ops = {
  366. .open = ad198x_dig_playback_pcm_open,
  367. .close = ad198x_dig_playback_pcm_close,
  368. .prepare = ad198x_dig_playback_pcm_prepare,
  369. .cleanup = ad198x_dig_playback_pcm_cleanup
  370. },
  371. };
  372. static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
  373. .substreams = 1,
  374. .channels_min = 2,
  375. .channels_max = 2,
  376. /* NID is set in alc_build_pcms */
  377. };
  378. static int ad198x_build_pcms(struct hda_codec *codec)
  379. {
  380. struct ad198x_spec *spec = codec->spec;
  381. struct hda_pcm *info = spec->pcm_rec;
  382. codec->num_pcms = 1;
  383. codec->pcm_info = info;
  384. info->name = "AD198x Analog";
  385. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
  386. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
  387. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  388. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
  389. info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
  390. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  391. if (spec->multiout.dig_out_nid) {
  392. info++;
  393. codec->num_pcms++;
  394. codec->spdif_status_reset = 1;
  395. info->name = "AD198x Digital";
  396. info->pcm_type = HDA_PCM_TYPE_SPDIF;
  397. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
  398. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
  399. if (spec->dig_in_nid) {
  400. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
  401. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
  402. }
  403. }
  404. return 0;
  405. }
  406. #endif /* ENABLE_AD_STATIC_QUIRKS */
  407. static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
  408. hda_nid_t hp)
  409. {
  410. if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
  411. snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
  412. !codec->inv_eapd ? 0x00 : 0x02);
  413. if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
  414. snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
  415. !codec->inv_eapd ? 0x00 : 0x02);
  416. }
  417. static void ad198x_power_eapd(struct hda_codec *codec)
  418. {
  419. /* We currently only handle front, HP */
  420. switch (codec->vendor_id) {
  421. case 0x11d41882:
  422. case 0x11d4882a:
  423. case 0x11d41884:
  424. case 0x11d41984:
  425. case 0x11d41883:
  426. case 0x11d4184a:
  427. case 0x11d4194a:
  428. case 0x11d4194b:
  429. case 0x11d41988:
  430. case 0x11d4198b:
  431. case 0x11d4989a:
  432. case 0x11d4989b:
  433. ad198x_power_eapd_write(codec, 0x12, 0x11);
  434. break;
  435. case 0x11d41981:
  436. case 0x11d41983:
  437. ad198x_power_eapd_write(codec, 0x05, 0x06);
  438. break;
  439. case 0x11d41986:
  440. ad198x_power_eapd_write(codec, 0x1b, 0x1a);
  441. break;
  442. }
  443. }
  444. static void ad198x_shutup(struct hda_codec *codec)
  445. {
  446. snd_hda_shutup_pins(codec);
  447. ad198x_power_eapd(codec);
  448. }
  449. static void ad198x_free(struct hda_codec *codec)
  450. {
  451. struct ad198x_spec *spec = codec->spec;
  452. if (!spec)
  453. return;
  454. snd_hda_gen_spec_free(&spec->gen);
  455. kfree(spec);
  456. snd_hda_detach_beep_device(codec);
  457. }
  458. #ifdef CONFIG_PM
  459. static int ad198x_suspend(struct hda_codec *codec)
  460. {
  461. ad198x_shutup(codec);
  462. return 0;
  463. }
  464. #endif
  465. #ifdef ENABLE_AD_STATIC_QUIRKS
  466. static const struct hda_codec_ops ad198x_patch_ops = {
  467. .build_controls = ad198x_build_controls,
  468. .build_pcms = ad198x_build_pcms,
  469. .init = ad198x_init,
  470. .free = ad198x_free,
  471. #ifdef CONFIG_PM
  472. .check_power_status = ad198x_check_power_status,
  473. .suspend = ad198x_suspend,
  474. #endif
  475. .reboot_notify = ad198x_shutup,
  476. };
  477. /*
  478. * EAPD control
  479. * the private value = nid
  480. */
  481. #define ad198x_eapd_info snd_ctl_boolean_mono_info
  482. static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
  483. struct snd_ctl_elem_value *ucontrol)
  484. {
  485. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  486. struct ad198x_spec *spec = codec->spec;
  487. if (codec->inv_eapd)
  488. ucontrol->value.integer.value[0] = ! spec->cur_eapd;
  489. else
  490. ucontrol->value.integer.value[0] = spec->cur_eapd;
  491. return 0;
  492. }
  493. static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
  494. struct snd_ctl_elem_value *ucontrol)
  495. {
  496. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  497. struct ad198x_spec *spec = codec->spec;
  498. hda_nid_t nid = kcontrol->private_value & 0xff;
  499. unsigned int eapd;
  500. eapd = !!ucontrol->value.integer.value[0];
  501. if (codec->inv_eapd)
  502. eapd = !eapd;
  503. if (eapd == spec->cur_eapd)
  504. return 0;
  505. spec->cur_eapd = eapd;
  506. snd_hda_codec_write_cache(codec, nid,
  507. 0, AC_VERB_SET_EAPD_BTLENABLE,
  508. eapd ? 0x02 : 0x00);
  509. return 1;
  510. }
  511. static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
  512. struct snd_ctl_elem_info *uinfo);
  513. static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
  514. struct snd_ctl_elem_value *ucontrol);
  515. static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
  516. struct snd_ctl_elem_value *ucontrol);
  517. #endif /* ENABLE_AD_STATIC_QUIRKS */
  518. /*
  519. * Automatic parse of I/O pins from the BIOS configuration
  520. */
  521. static int ad198x_auto_build_controls(struct hda_codec *codec)
  522. {
  523. int err;
  524. err = snd_hda_gen_build_controls(codec);
  525. if (err < 0)
  526. return err;
  527. err = create_beep_ctls(codec);
  528. if (err < 0)
  529. return err;
  530. return 0;
  531. }
  532. static const struct hda_codec_ops ad198x_auto_patch_ops = {
  533. .build_controls = ad198x_auto_build_controls,
  534. .build_pcms = snd_hda_gen_build_pcms,
  535. .init = snd_hda_gen_init,
  536. .free = snd_hda_gen_free,
  537. .unsol_event = snd_hda_jack_unsol_event,
  538. #ifdef CONFIG_PM
  539. .check_power_status = snd_hda_gen_check_power_status,
  540. .suspend = ad198x_suspend,
  541. #endif
  542. .reboot_notify = ad198x_shutup,
  543. };
  544. static int ad198x_parse_auto_config(struct hda_codec *codec)
  545. {
  546. struct ad198x_spec *spec = codec->spec;
  547. struct auto_pin_cfg *cfg = &spec->gen.autocfg;
  548. int err;
  549. codec->spdif_status_reset = 1;
  550. codec->no_trigger_sense = 1;
  551. codec->no_sticky_stream = 1;
  552. spec->gen.indep_hp = 1;
  553. err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
  554. if (err < 0)
  555. return err;
  556. err = snd_hda_gen_parse_auto_config(codec, cfg);
  557. if (err < 0)
  558. return err;
  559. codec->patch_ops = ad198x_auto_patch_ops;
  560. return 0;
  561. }
  562. /*
  563. * AD1986A specific
  564. */
  565. #ifdef ENABLE_AD_STATIC_QUIRKS
  566. #define AD1986A_SPDIF_OUT 0x02
  567. #define AD1986A_FRONT_DAC 0x03
  568. #define AD1986A_SURR_DAC 0x04
  569. #define AD1986A_CLFE_DAC 0x05
  570. #define AD1986A_ADC 0x06
  571. static const hda_nid_t ad1986a_dac_nids[3] = {
  572. AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
  573. };
  574. static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
  575. static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
  576. static const struct hda_input_mux ad1986a_capture_source = {
  577. .num_items = 7,
  578. .items = {
  579. { "Mic", 0x0 },
  580. { "CD", 0x1 },
  581. { "Aux", 0x3 },
  582. { "Line", 0x4 },
  583. { "Mix", 0x5 },
  584. { "Mono", 0x6 },
  585. { "Phone", 0x7 },
  586. },
  587. };
  588. static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
  589. .ops = &snd_hda_bind_vol,
  590. .values = {
  591. HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
  592. HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
  593. HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
  594. 0
  595. },
  596. };
  597. static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
  598. .ops = &snd_hda_bind_sw,
  599. .values = {
  600. HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
  601. HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
  602. HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
  603. 0
  604. },
  605. };
  606. /*
  607. * mixers
  608. */
  609. static const struct snd_kcontrol_new ad1986a_mixers[] = {
  610. /*
  611. * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
  612. */
  613. HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
  614. HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
  615. HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  616. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  617. HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  618. HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  619. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
  620. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
  621. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
  622. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
  623. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
  624. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
  625. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  626. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  627. HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  628. HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  629. HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
  630. HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  631. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  632. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  633. HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
  634. HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
  635. HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
  636. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  637. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  638. {
  639. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  640. .name = "Capture Source",
  641. .info = ad198x_mux_enum_info,
  642. .get = ad198x_mux_enum_get,
  643. .put = ad198x_mux_enum_put,
  644. },
  645. HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
  646. { } /* end */
  647. };
  648. /* additional mixers for 3stack mode */
  649. static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
  650. {
  651. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  652. .name = "Channel Mode",
  653. .info = ad198x_ch_mode_info,
  654. .get = ad198x_ch_mode_get,
  655. .put = ad198x_ch_mode_put,
  656. },
  657. { } /* end */
  658. };
  659. /* laptop model - 2ch only */
  660. static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
  661. /* master controls both pins 0x1a and 0x1b */
  662. static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
  663. .ops = &snd_hda_bind_vol,
  664. .values = {
  665. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  666. HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
  667. 0,
  668. },
  669. };
  670. static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
  671. .ops = &snd_hda_bind_sw,
  672. .values = {
  673. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  674. HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
  675. 0,
  676. },
  677. };
  678. static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
  679. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  680. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  681. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  682. HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
  683. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  684. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  685. HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  686. HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  687. HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
  688. HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  689. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  690. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  691. HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
  692. /*
  693. HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
  694. HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
  695. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  696. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  697. {
  698. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  699. .name = "Capture Source",
  700. .info = ad198x_mux_enum_info,
  701. .get = ad198x_mux_enum_get,
  702. .put = ad198x_mux_enum_put,
  703. },
  704. { } /* end */
  705. };
  706. /* laptop-eapd model - 2ch only */
  707. static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
  708. .num_items = 3,
  709. .items = {
  710. { "Mic", 0x0 },
  711. { "Internal Mic", 0x4 },
  712. { "Mix", 0x5 },
  713. },
  714. };
  715. static const struct hda_input_mux ad1986a_automic_capture_source = {
  716. .num_items = 2,
  717. .items = {
  718. { "Mic", 0x0 },
  719. { "Mix", 0x5 },
  720. },
  721. };
  722. static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
  723. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  724. HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
  725. { } /* end */
  726. };
  727. static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
  728. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  729. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  730. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  731. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  732. HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
  733. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  734. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  735. {
  736. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  737. .name = "Capture Source",
  738. .info = ad198x_mux_enum_info,
  739. .get = ad198x_mux_enum_get,
  740. .put = ad198x_mux_enum_put,
  741. },
  742. {
  743. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  744. .name = "External Amplifier",
  745. .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
  746. .info = ad198x_eapd_info,
  747. .get = ad198x_eapd_get,
  748. .put = ad198x_eapd_put,
  749. .private_value = 0x1b, /* port-D */
  750. },
  751. { } /* end */
  752. };
  753. static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
  754. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
  755. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
  756. { } /* end */
  757. };
  758. /* laptop-automute - 2ch only */
  759. static void ad1986a_update_hp(struct hda_codec *codec)
  760. {
  761. struct ad198x_spec *spec = codec->spec;
  762. unsigned int mute;
  763. if (spec->jack_present)
  764. mute = HDA_AMP_MUTE; /* mute internal speaker */
  765. else
  766. /* unmute internal speaker if necessary */
  767. mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
  768. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  769. HDA_AMP_MUTE, mute);
  770. }
  771. static void ad1986a_hp_automute(struct hda_codec *codec)
  772. {
  773. struct ad198x_spec *spec = codec->spec;
  774. spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
  775. if (spec->inv_jack_detect)
  776. spec->jack_present = !spec->jack_present;
  777. ad1986a_update_hp(codec);
  778. }
  779. #define AD1986A_HP_EVENT 0x37
  780. static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
  781. {
  782. if ((res >> 26) != AD1986A_HP_EVENT)
  783. return;
  784. ad1986a_hp_automute(codec);
  785. }
  786. static int ad1986a_hp_init(struct hda_codec *codec)
  787. {
  788. ad198x_init(codec);
  789. ad1986a_hp_automute(codec);
  790. return 0;
  791. }
  792. /* bind hp and internal speaker mute (with plug check) */
  793. static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
  794. struct snd_ctl_elem_value *ucontrol)
  795. {
  796. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  797. int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
  798. if (change)
  799. ad1986a_update_hp(codec);
  800. return change;
  801. }
  802. static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
  803. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  804. {
  805. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  806. .name = "Master Playback Switch",
  807. .subdevice = HDA_SUBDEV_AMP_FLAG,
  808. .info = snd_hda_mixer_amp_switch_info,
  809. .get = snd_hda_mixer_amp_switch_get,
  810. .put = ad1986a_hp_master_sw_put,
  811. .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  812. },
  813. { } /* end */
  814. };
  815. /*
  816. * initialization verbs
  817. */
  818. static const struct hda_verb ad1986a_init_verbs[] = {
  819. /* Front, Surround, CLFE DAC; mute as default */
  820. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  821. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  822. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  823. /* Downmix - off */
  824. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  825. /* HP, Line-Out, Surround, CLFE selectors */
  826. {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
  827. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
  828. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  829. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  830. /* Mono selector */
  831. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
  832. /* Mic selector: Mic 1/2 pin */
  833. {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
  834. /* Line-in selector: Line-in */
  835. {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
  836. /* Mic 1/2 swap */
  837. {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
  838. /* Record selector: mic */
  839. {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
  840. /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
  841. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  842. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  843. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  844. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  845. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  846. /* PC beep */
  847. {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
  848. /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
  849. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  850. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  851. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  852. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  853. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  854. /* HP Pin */
  855. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  856. /* Front, Surround, CLFE Pins */
  857. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  858. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  859. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  860. /* Mono Pin */
  861. {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  862. /* Mic Pin */
  863. {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  864. /* Line, Aux, CD, Beep-In Pin */
  865. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  866. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  867. {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  868. {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  869. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  870. { } /* end */
  871. };
  872. static const struct hda_verb ad1986a_ch2_init[] = {
  873. /* Surround out -> Line In */
  874. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  875. /* Line-in selectors */
  876. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
  877. /* CLFE -> Mic in */
  878. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  879. /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
  880. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
  881. { } /* end */
  882. };
  883. static const struct hda_verb ad1986a_ch4_init[] = {
  884. /* Surround out -> Surround */
  885. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  886. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
  887. /* CLFE -> Mic in */
  888. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  889. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
  890. { } /* end */
  891. };
  892. static const struct hda_verb ad1986a_ch6_init[] = {
  893. /* Surround out -> Surround out */
  894. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  895. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
  896. /* CLFE -> CLFE */
  897. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  898. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
  899. { } /* end */
  900. };
  901. static const struct hda_channel_mode ad1986a_modes[3] = {
  902. { 2, ad1986a_ch2_init },
  903. { 4, ad1986a_ch4_init },
  904. { 6, ad1986a_ch6_init },
  905. };
  906. /* eapd initialization */
  907. static const struct hda_verb ad1986a_eapd_init_verbs[] = {
  908. {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
  909. {}
  910. };
  911. /* pin sensing on HP jack */
  912. static const struct hda_verb ad1986a_hp_init_verbs[] = {
  913. {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
  914. {}
  915. };
  916. /* models */
  917. enum {
  918. AD1986A_AUTO,
  919. AD1986A_6STACK,
  920. AD1986A_3STACK,
  921. AD1986A_LAPTOP,
  922. AD1986A_LAPTOP_EAPD,
  923. AD1986A_LAPTOP_AUTOMUTE,
  924. AD1986A_MODELS
  925. };
  926. static const char * const ad1986a_models[AD1986A_MODELS] = {
  927. [AD1986A_AUTO] = "auto",
  928. [AD1986A_6STACK] = "6stack",
  929. [AD1986A_3STACK] = "3stack",
  930. [AD1986A_LAPTOP] = "laptop",
  931. [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
  932. [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
  933. };
  934. static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
  935. SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
  936. SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
  937. SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
  938. SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
  939. SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
  940. SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
  941. SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
  942. SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
  943. SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
  944. SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
  945. {}
  946. };
  947. #ifdef CONFIG_PM
  948. static const struct hda_amp_list ad1986a_loopbacks[] = {
  949. { 0x13, HDA_OUTPUT, 0 }, /* Mic */
  950. { 0x14, HDA_OUTPUT, 0 }, /* Phone */
  951. { 0x15, HDA_OUTPUT, 0 }, /* CD */
  952. { 0x16, HDA_OUTPUT, 0 }, /* Aux */
  953. { 0x17, HDA_OUTPUT, 0 }, /* Line */
  954. { } /* end */
  955. };
  956. #endif
  957. static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
  958. {
  959. unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
  960. return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
  961. }
  962. #endif /* ENABLE_AD_STATIC_QUIRKS */
  963. static int alloc_ad_spec(struct hda_codec *codec)
  964. {
  965. struct ad198x_spec *spec;
  966. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  967. if (!spec)
  968. return -ENOMEM;
  969. codec->spec = spec;
  970. snd_hda_gen_spec_init(&spec->gen);
  971. return 0;
  972. }
  973. /*
  974. * AD1986A fixup codes
  975. */
  976. /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
  977. static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
  978. const struct hda_fixup *fix, int action)
  979. {
  980. if (action == HDA_FIXUP_ACT_PRE_PROBE)
  981. codec->inv_jack_detect = 1;
  982. }
  983. enum {
  984. AD1986A_FIXUP_INV_JACK_DETECT,
  985. AD1986A_FIXUP_ULTRA,
  986. AD1986A_FIXUP_SAMSUNG,
  987. };
  988. static const struct hda_fixup ad1986a_fixups[] = {
  989. [AD1986A_FIXUP_INV_JACK_DETECT] = {
  990. .type = HDA_FIXUP_FUNC,
  991. .v.func = ad_fixup_inv_jack_detect,
  992. },
  993. [AD1986A_FIXUP_ULTRA] = {
  994. .type = HDA_FIXUP_PINS,
  995. .v.pins = (const struct hda_pintbl[]) {
  996. { 0x1b, 0x90170110 }, /* speaker */
  997. { 0x1d, 0x90a7013e }, /* int mic */
  998. {}
  999. },
  1000. },
  1001. [AD1986A_FIXUP_SAMSUNG] = {
  1002. .type = HDA_FIXUP_PINS,
  1003. .v.pins = (const struct hda_pintbl[]) {
  1004. { 0x1b, 0x90170110 }, /* speaker */
  1005. { 0x1d, 0x90a7013e }, /* int mic */
  1006. { 0x20, 0x411111f0 }, /* N/A */
  1007. { 0x24, 0x411111f0 }, /* N/A */
  1008. {}
  1009. },
  1010. },
  1011. };
  1012. static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
  1013. SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
  1014. SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
  1015. SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
  1016. {}
  1017. };
  1018. /*
  1019. */
  1020. static int ad1986a_parse_auto_config(struct hda_codec *codec)
  1021. {
  1022. int err;
  1023. struct ad198x_spec *spec;
  1024. err = alloc_ad_spec(codec);
  1025. if (err < 0)
  1026. return err;
  1027. spec = codec->spec;
  1028. /* AD1986A has the inverted EAPD implementation */
  1029. codec->inv_eapd = 1;
  1030. spec->gen.mixer_nid = 0x07;
  1031. spec->gen.beep_nid = 0x19;
  1032. set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
  1033. /* AD1986A has a hardware problem that it can't share a stream
  1034. * with multiple output pins. The copy of front to surrounds
  1035. * causes noisy or silent outputs at a certain timing, e.g.
  1036. * changing the volume.
  1037. * So, let's disable the shared stream.
  1038. */
  1039. spec->gen.multiout.no_share_stream = 1;
  1040. snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups);
  1041. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
  1042. err = ad198x_parse_auto_config(codec);
  1043. if (err < 0) {
  1044. snd_hda_gen_free(codec);
  1045. return err;
  1046. }
  1047. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
  1048. return 0;
  1049. }
  1050. #ifdef ENABLE_AD_STATIC_QUIRKS
  1051. static int patch_ad1986a(struct hda_codec *codec)
  1052. {
  1053. struct ad198x_spec *spec;
  1054. int err, board_config;
  1055. board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
  1056. ad1986a_models,
  1057. ad1986a_cfg_tbl);
  1058. if (board_config < 0) {
  1059. printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
  1060. codec->chip_name);
  1061. board_config = AD1986A_AUTO;
  1062. }
  1063. if (board_config == AD1986A_AUTO)
  1064. return ad1986a_parse_auto_config(codec);
  1065. err = alloc_ad_spec(codec);
  1066. if (err < 0)
  1067. return err;
  1068. spec = codec->spec;
  1069. err = snd_hda_attach_beep_device(codec, 0x19);
  1070. if (err < 0) {
  1071. ad198x_free(codec);
  1072. return err;
  1073. }
  1074. set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
  1075. spec->multiout.max_channels = 6;
  1076. spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
  1077. spec->multiout.dac_nids = ad1986a_dac_nids;
  1078. spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
  1079. spec->num_adc_nids = 1;
  1080. spec->adc_nids = ad1986a_adc_nids;
  1081. spec->capsrc_nids = ad1986a_capsrc_nids;
  1082. spec->input_mux = &ad1986a_capture_source;
  1083. spec->num_mixers = 1;
  1084. spec->mixers[0] = ad1986a_mixers;
  1085. spec->num_init_verbs = 1;
  1086. spec->init_verbs[0] = ad1986a_init_verbs;
  1087. #ifdef CONFIG_PM
  1088. spec->loopback.amplist = ad1986a_loopbacks;
  1089. #endif
  1090. spec->vmaster_nid = 0x1b;
  1091. codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
  1092. codec->patch_ops = ad198x_patch_ops;
  1093. /* override some parameters */
  1094. switch (board_config) {
  1095. case AD1986A_3STACK:
  1096. spec->num_mixers = 2;
  1097. spec->mixers[1] = ad1986a_3st_mixers;
  1098. spec->num_init_verbs = 2;
  1099. spec->init_verbs[1] = ad1986a_ch2_init;
  1100. spec->channel_mode = ad1986a_modes;
  1101. spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
  1102. spec->need_dac_fix = 1;
  1103. spec->multiout.max_channels = 2;
  1104. spec->multiout.num_dacs = 1;
  1105. break;
  1106. case AD1986A_LAPTOP:
  1107. spec->mixers[0] = ad1986a_laptop_mixers;
  1108. spec->multiout.max_channels = 2;
  1109. spec->multiout.num_dacs = 1;
  1110. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  1111. break;
  1112. case AD1986A_LAPTOP_EAPD:
  1113. spec->num_mixers = 3;
  1114. spec->mixers[0] = ad1986a_laptop_master_mixers;
  1115. spec->mixers[1] = ad1986a_laptop_eapd_mixers;
  1116. spec->mixers[2] = ad1986a_laptop_intmic_mixers;
  1117. spec->num_init_verbs = 2;
  1118. spec->init_verbs[1] = ad1986a_eapd_init_verbs;
  1119. spec->multiout.max_channels = 2;
  1120. spec->multiout.num_dacs = 1;
  1121. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  1122. if (!is_jack_available(codec, 0x25))
  1123. spec->multiout.dig_out_nid = 0;
  1124. spec->input_mux = &ad1986a_laptop_eapd_capture_source;
  1125. break;
  1126. case AD1986A_LAPTOP_AUTOMUTE:
  1127. spec->num_mixers = 3;
  1128. spec->mixers[0] = ad1986a_automute_master_mixers;
  1129. spec->mixers[1] = ad1986a_laptop_eapd_mixers;
  1130. spec->mixers[2] = ad1986a_laptop_intmic_mixers;
  1131. spec->num_init_verbs = 3;
  1132. spec->init_verbs[1] = ad1986a_eapd_init_verbs;
  1133. spec->init_verbs[2] = ad1986a_hp_init_verbs;
  1134. spec->multiout.max_channels = 2;
  1135. spec->multiout.num_dacs = 1;
  1136. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  1137. if (!is_jack_available(codec, 0x25))
  1138. spec->multiout.dig_out_nid = 0;
  1139. spec->input_mux = &ad1986a_laptop_eapd_capture_source;
  1140. codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
  1141. codec->patch_ops.init = ad1986a_hp_init;
  1142. /* Lenovo N100 seems to report the reversed bit
  1143. * for HP jack-sensing
  1144. */
  1145. spec->inv_jack_detect = 1;
  1146. break;
  1147. }
  1148. /* AD1986A has a hardware problem that it can't share a stream
  1149. * with multiple output pins. The copy of front to surrounds
  1150. * causes noisy or silent outputs at a certain timing, e.g.
  1151. * changing the volume.
  1152. * So, let's disable the shared stream.
  1153. */
  1154. spec->multiout.no_share_stream = 1;
  1155. codec->no_trigger_sense = 1;
  1156. codec->no_sticky_stream = 1;
  1157. return 0;
  1158. }
  1159. #else /* ENABLE_AD_STATIC_QUIRKS */
  1160. #define patch_ad1986a ad1986a_parse_auto_config
  1161. #endif /* ENABLE_AD_STATIC_QUIRKS */
  1162. /*
  1163. * AD1983 specific
  1164. */
  1165. /*
  1166. * SPDIF mux control for AD1983 auto-parser
  1167. */
  1168. static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
  1169. struct snd_ctl_elem_info *uinfo)
  1170. {
  1171. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1172. struct ad198x_spec *spec = codec->spec;
  1173. static const char * const texts2[] = { "PCM", "ADC" };
  1174. static const char * const texts3[] = { "PCM", "ADC1", "ADC2" };
  1175. hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
  1176. int num_conns = snd_hda_get_num_conns(codec, dig_out);
  1177. if (num_conns == 2)
  1178. return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2);
  1179. else if (num_conns == 3)
  1180. return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
  1181. else
  1182. return -EINVAL;
  1183. }
  1184. static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
  1185. struct snd_ctl_elem_value *ucontrol)
  1186. {
  1187. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1188. struct ad198x_spec *spec = codec->spec;
  1189. ucontrol->value.enumerated.item[0] = spec->cur_smux;
  1190. return 0;
  1191. }
  1192. static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
  1193. struct snd_ctl_elem_value *ucontrol)
  1194. {
  1195. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1196. struct ad198x_spec *spec = codec->spec;
  1197. unsigned int val = ucontrol->value.enumerated.item[0];
  1198. hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
  1199. int num_conns = snd_hda_get_num_conns(codec, dig_out);
  1200. if (val >= num_conns)
  1201. return -EINVAL;
  1202. if (spec->cur_smux == val)
  1203. return 0;
  1204. spec->cur_smux = val;
  1205. snd_hda_codec_write_cache(codec, dig_out, 0,
  1206. AC_VERB_SET_CONNECT_SEL, val);
  1207. return 1;
  1208. }
  1209. static struct snd_kcontrol_new ad1983_auto_smux_mixer = {
  1210. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1211. .name = "IEC958 Playback Source",
  1212. .info = ad1983_auto_smux_enum_info,
  1213. .get = ad1983_auto_smux_enum_get,
  1214. .put = ad1983_auto_smux_enum_put,
  1215. };
  1216. static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
  1217. {
  1218. struct ad198x_spec *spec = codec->spec;
  1219. hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
  1220. int num_conns;
  1221. if (!dig_out)
  1222. return 0;
  1223. num_conns = snd_hda_get_num_conns(codec, dig_out);
  1224. if (num_conns != 2 && num_conns != 3)
  1225. return 0;
  1226. if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer))
  1227. return -ENOMEM;
  1228. return 0;
  1229. }
  1230. static int patch_ad1983(struct hda_codec *codec)
  1231. {
  1232. struct ad198x_spec *spec;
  1233. int err;
  1234. err = alloc_ad_spec(codec);
  1235. if (err < 0)
  1236. return err;
  1237. spec = codec->spec;
  1238. spec->gen.beep_nid = 0x10;
  1239. set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
  1240. err = ad198x_parse_auto_config(codec);
  1241. if (err < 0)
  1242. goto error;
  1243. err = ad1983_add_spdif_mux_ctl(codec);
  1244. if (err < 0)
  1245. goto error;
  1246. return 0;
  1247. error:
  1248. snd_hda_gen_free(codec);
  1249. return err;
  1250. }
  1251. /*
  1252. * AD1981 HD specific
  1253. */
  1254. /* follow EAPD via vmaster hook */
  1255. static void ad_vmaster_eapd_hook(void *private_data, int enabled)
  1256. {
  1257. struct hda_codec *codec = private_data;
  1258. struct ad198x_spec *spec = codec->spec;
  1259. if (!spec->eapd_nid)
  1260. return;
  1261. snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
  1262. AC_VERB_SET_EAPD_BTLENABLE,
  1263. enabled ? 0x02 : 0x00);
  1264. }
  1265. static void ad1981_fixup_hp_eapd(struct hda_codec *codec,
  1266. const struct hda_fixup *fix, int action)
  1267. {
  1268. struct ad198x_spec *spec = codec->spec;
  1269. if (action == HDA_FIXUP_ACT_PRE_PROBE) {
  1270. spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
  1271. spec->eapd_nid = 0x05;
  1272. }
  1273. }
  1274. /* set the upper-limit for mixer amp to 0dB for avoiding the possible
  1275. * damage by overloading
  1276. */
  1277. static void ad1981_fixup_amp_override(struct hda_codec *codec,
  1278. const struct hda_fixup *fix, int action)
  1279. {
  1280. if (action == HDA_FIXUP_ACT_PRE_PROBE)
  1281. snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
  1282. (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
  1283. (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
  1284. (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
  1285. (1 << AC_AMPCAP_MUTE_SHIFT));
  1286. }
  1287. enum {
  1288. AD1981_FIXUP_AMP_OVERRIDE,
  1289. AD1981_FIXUP_HP_EAPD,
  1290. };
  1291. static const struct hda_fixup ad1981_fixups[] = {
  1292. [AD1981_FIXUP_AMP_OVERRIDE] = {
  1293. .type = HDA_FIXUP_FUNC,
  1294. .v.func = ad1981_fixup_amp_override,
  1295. },
  1296. [AD1981_FIXUP_HP_EAPD] = {
  1297. .type = HDA_FIXUP_FUNC,
  1298. .v.func = ad1981_fixup_hp_eapd,
  1299. .chained = true,
  1300. .chain_id = AD1981_FIXUP_AMP_OVERRIDE,
  1301. },
  1302. };
  1303. static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
  1304. SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
  1305. SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD),
  1306. SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
  1307. /* HP nx6320 (reversed SSID, H/W bug) */
  1308. SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD),
  1309. {}
  1310. };
  1311. static int patch_ad1981(struct hda_codec *codec)
  1312. {
  1313. struct ad198x_spec *spec;
  1314. int err;
  1315. err = alloc_ad_spec(codec);
  1316. if (err < 0)
  1317. return -ENOMEM;
  1318. spec = codec->spec;
  1319. spec->gen.mixer_nid = 0x0e;
  1320. spec->gen.beep_nid = 0x10;
  1321. set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
  1322. snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
  1323. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
  1324. err = ad198x_parse_auto_config(codec);
  1325. if (err < 0)
  1326. goto error;
  1327. err = ad1983_add_spdif_mux_ctl(codec);
  1328. if (err < 0)
  1329. goto error;
  1330. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
  1331. return 0;
  1332. error:
  1333. snd_hda_gen_free(codec);
  1334. return err;
  1335. }
  1336. /*
  1337. * AD1988
  1338. *
  1339. * Output pins and routes
  1340. *
  1341. * Pin Mix Sel DAC (*)
  1342. * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
  1343. * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
  1344. * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a
  1345. * port-D 0x12 (mute/hp) <- 0x29 <- 04
  1346. * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
  1347. * port-F 0x16 (mute) <- 0x2a <- 06
  1348. * port-G 0x24 (mute) <- 0x27 <- 05
  1349. * port-H 0x25 (mute) <- 0x28 <- 0a
  1350. * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
  1351. *
  1352. * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
  1353. * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
  1354. *
  1355. * Input pins and routes
  1356. *
  1357. * pin boost mix input # / adc input #
  1358. * port-A 0x11 -> 0x38 -> mix 2, ADC 0
  1359. * port-B 0x14 -> 0x39 -> mix 0, ADC 1
  1360. * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
  1361. * port-D 0x12 -> 0x3d -> mix 3, ADC 8
  1362. * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
  1363. * port-F 0x16 -> 0x3b -> mix 5, ADC 3
  1364. * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
  1365. * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
  1366. *
  1367. *
  1368. * DAC assignment
  1369. * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
  1370. * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
  1371. *
  1372. * Inputs of Analog Mix (0x20)
  1373. * 0:Port-B (front mic)
  1374. * 1:Port-C/G/H (line-in)
  1375. * 2:Port-A
  1376. * 3:Port-D (line-in/2)
  1377. * 4:Port-E/G/H (mic-in)
  1378. * 5:Port-F (mic2-in)
  1379. * 6:CD
  1380. * 7:Beep
  1381. *
  1382. * ADC selection
  1383. * 0:Port-A
  1384. * 1:Port-B (front mic-in)
  1385. * 2:Port-C (line-in)
  1386. * 3:Port-F (mic2-in)
  1387. * 4:Port-E (mic-in)
  1388. * 5:CD
  1389. * 6:Port-G
  1390. * 7:Port-H
  1391. * 8:Port-D (line-in/2)
  1392. * 9:Mix
  1393. *
  1394. * Proposed pin assignments by the datasheet
  1395. *
  1396. * 6-stack
  1397. * Port-A front headphone
  1398. * B front mic-in
  1399. * C rear line-in
  1400. * D rear front-out
  1401. * E rear mic-in
  1402. * F rear surround
  1403. * G rear CLFE
  1404. * H rear side
  1405. *
  1406. * 3-stack
  1407. * Port-A front headphone
  1408. * B front mic
  1409. * C rear line-in/surround
  1410. * D rear front-out
  1411. * E rear mic-in/CLFE
  1412. *
  1413. * laptop
  1414. * Port-A headphone
  1415. * B mic-in
  1416. * C docking station
  1417. * D internal speaker (with EAPD)
  1418. * E/F quad mic array
  1419. */
  1420. #ifdef ENABLE_AD_STATIC_QUIRKS
  1421. static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
  1422. struct snd_ctl_elem_info *uinfo)
  1423. {
  1424. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1425. struct ad198x_spec *spec = codec->spec;
  1426. return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
  1427. spec->num_channel_mode);
  1428. }
  1429. static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
  1430. struct snd_ctl_elem_value *ucontrol)
  1431. {
  1432. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1433. struct ad198x_spec *spec = codec->spec;
  1434. return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
  1435. spec->num_channel_mode, spec->multiout.max_channels);
  1436. }
  1437. static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
  1438. struct snd_ctl_elem_value *ucontrol)
  1439. {
  1440. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1441. struct ad198x_spec *spec = codec->spec;
  1442. int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
  1443. spec->num_channel_mode,
  1444. &spec->multiout.max_channels);
  1445. if (err >= 0 && spec->need_dac_fix)
  1446. spec->multiout.num_dacs = spec->multiout.max_channels / 2;
  1447. return err;
  1448. }
  1449. #endif /* ENABLE_AD_STATIC_QUIRKS */
  1450. static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
  1451. struct snd_ctl_elem_info *uinfo)
  1452. {
  1453. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1454. static const char * const texts[] = {
  1455. "PCM", "ADC1", "ADC2", "ADC3",
  1456. };
  1457. int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
  1458. if (num_conns > 4)
  1459. num_conns = 4;
  1460. return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts);
  1461. }
  1462. static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
  1463. struct snd_ctl_elem_value *ucontrol)
  1464. {
  1465. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1466. struct ad198x_spec *spec = codec->spec;
  1467. ucontrol->value.enumerated.item[0] = spec->cur_smux;
  1468. return 0;
  1469. }
  1470. static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
  1471. struct snd_ctl_elem_value *ucontrol)
  1472. {
  1473. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1474. struct ad198x_spec *spec = codec->spec;
  1475. unsigned int val = ucontrol->value.enumerated.item[0];
  1476. struct nid_path *path;
  1477. int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
  1478. if (val >= num_conns)
  1479. return -EINVAL;
  1480. if (spec->cur_smux == val)
  1481. return 0;
  1482. mutex_lock(&codec->control_mutex);
  1483. codec->cached_write = 1;
  1484. path = snd_hda_get_path_from_idx(codec,
  1485. spec->smux_paths[spec->cur_smux]);
  1486. if (path)
  1487. snd_hda_activate_path(codec, path, false, true);
  1488. path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]);
  1489. if (path)
  1490. snd_hda_activate_path(codec, path, true, true);
  1491. spec->cur_smux = val;
  1492. codec->cached_write = 0;
  1493. mutex_unlock(&codec->control_mutex);
  1494. snd_hda_codec_flush_cache(codec); /* flush the updates */
  1495. return 1;
  1496. }
  1497. static struct snd_kcontrol_new ad1988_auto_smux_mixer = {
  1498. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1499. .name = "IEC958 Playback Source",
  1500. .info = ad1988_auto_smux_enum_info,
  1501. .get = ad1988_auto_smux_enum_get,
  1502. .put = ad1988_auto_smux_enum_put,
  1503. };
  1504. static int ad1988_auto_init(struct hda_codec *codec)
  1505. {
  1506. struct ad198x_spec *spec = codec->spec;
  1507. int i, err;
  1508. err = snd_hda_gen_init(codec);
  1509. if (err < 0)
  1510. return err;
  1511. if (!spec->gen.autocfg.dig_outs)
  1512. return 0;
  1513. for (i = 0; i < 4; i++) {
  1514. struct nid_path *path;
  1515. path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]);
  1516. if (path)
  1517. snd_hda_activate_path(codec, path, path->active, false);
  1518. }
  1519. return 0;
  1520. }
  1521. static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
  1522. {
  1523. struct ad198x_spec *spec = codec->spec;
  1524. int i, num_conns;
  1525. /* we create four static faked paths, since AD codecs have odd
  1526. * widget connections regarding the SPDIF out source
  1527. */
  1528. static struct nid_path fake_paths[4] = {
  1529. {
  1530. .depth = 3,
  1531. .path = { 0x02, 0x1d, 0x1b },
  1532. .idx = { 0, 0, 0 },
  1533. .multi = { 0, 0, 0 },
  1534. },
  1535. {
  1536. .depth = 4,
  1537. .path = { 0x08, 0x0b, 0x1d, 0x1b },
  1538. .idx = { 0, 0, 1, 0 },
  1539. .multi = { 0, 1, 0, 0 },
  1540. },
  1541. {
  1542. .depth = 4,
  1543. .path = { 0x09, 0x0b, 0x1d, 0x1b },
  1544. .idx = { 0, 1, 1, 0 },
  1545. .multi = { 0, 1, 0, 0 },
  1546. },
  1547. {
  1548. .depth = 4,
  1549. .path = { 0x0f, 0x0b, 0x1d, 0x1b },
  1550. .idx = { 0, 2, 1, 0 },
  1551. .multi = { 0, 1, 0, 0 },
  1552. },
  1553. };
  1554. /* SPDIF source mux appears to be present only on AD1988A */
  1555. if (!spec->gen.autocfg.dig_outs ||
  1556. get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX)
  1557. return 0;
  1558. num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
  1559. if (num_conns != 3 && num_conns != 4)
  1560. return 0;
  1561. for (i = 0; i < num_conns; i++) {
  1562. struct nid_path *path = snd_array_new(&spec->gen.paths);
  1563. if (!path)
  1564. return -ENOMEM;
  1565. *path = fake_paths[i];
  1566. if (!i)
  1567. path->active = 1;
  1568. spec->smux_paths[i] = snd_hda_get_path_idx(codec, path);
  1569. }
  1570. if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer))
  1571. return -ENOMEM;
  1572. codec->patch_ops.init = ad1988_auto_init;
  1573. return 0;
  1574. }
  1575. /*
  1576. */
  1577. enum {
  1578. AD1988_FIXUP_6STACK_DIG,
  1579. };
  1580. static const struct hda_fixup ad1988_fixups[] = {
  1581. [AD1988_FIXUP_6STACK_DIG] = {
  1582. .type = HDA_FIXUP_PINS,
  1583. .v.pins = (const struct hda_pintbl[]) {
  1584. { 0x11, 0x02214130 }, /* front-hp */
  1585. { 0x12, 0x01014010 }, /* line-out */
  1586. { 0x14, 0x02a19122 }, /* front-mic */
  1587. { 0x15, 0x01813021 }, /* line-in */
  1588. { 0x16, 0x01011012 }, /* line-out */
  1589. { 0x17, 0x01a19020 }, /* mic */
  1590. { 0x1b, 0x0145f1f0 }, /* SPDIF */
  1591. { 0x24, 0x01016011 }, /* line-out */
  1592. { 0x25, 0x01012013 }, /* line-out */
  1593. { }
  1594. }
  1595. },
  1596. };
  1597. static const struct hda_model_fixup ad1988_fixup_models[] = {
  1598. { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" },
  1599. {}
  1600. };
  1601. static int patch_ad1988(struct hda_codec *codec)
  1602. {
  1603. struct ad198x_spec *spec;
  1604. int err;
  1605. err = alloc_ad_spec(codec);
  1606. if (err < 0)
  1607. return err;
  1608. spec = codec->spec;
  1609. spec->gen.mixer_nid = 0x20;
  1610. spec->gen.mixer_merge_nid = 0x21;
  1611. spec->gen.beep_nid = 0x10;
  1612. set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
  1613. snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
  1614. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
  1615. err = ad198x_parse_auto_config(codec);
  1616. if (err < 0)
  1617. goto error;
  1618. err = ad1988_add_spdif_mux_ctl(codec);
  1619. if (err < 0)
  1620. goto error;
  1621. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
  1622. return 0;
  1623. error:
  1624. snd_hda_gen_free(codec);
  1625. return err;
  1626. }
  1627. /*
  1628. * AD1884 / AD1984
  1629. *
  1630. * port-B - front line/mic-in
  1631. * port-E - aux in/out
  1632. * port-F - aux in/out
  1633. * port-C - rear line/mic-in
  1634. * port-D - rear line/hp-out
  1635. * port-A - front line/hp-out
  1636. *
  1637. * AD1984 = AD1884 + two digital mic-ins
  1638. *
  1639. * AD1883 / AD1884A / AD1984A / AD1984B
  1640. *
  1641. * port-B (0x14) - front mic-in
  1642. * port-E (0x1c) - rear mic-in
  1643. * port-F (0x16) - CD / ext out
  1644. * port-C (0x15) - rear line-in
  1645. * port-D (0x12) - rear line-out
  1646. * port-A (0x11) - front hp-out
  1647. *
  1648. * AD1984A = AD1884A + digital-mic
  1649. * AD1883 = equivalent with AD1984A
  1650. * AD1984B = AD1984A + extra SPDIF-out
  1651. */
  1652. /* set the upper-limit for mixer amp to 0dB for avoiding the possible
  1653. * damage by overloading
  1654. */
  1655. static void ad1884_fixup_amp_override(struct hda_codec *codec,
  1656. const struct hda_fixup *fix, int action)
  1657. {
  1658. if (action == HDA_FIXUP_ACT_PRE_PROBE)
  1659. snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
  1660. (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
  1661. (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
  1662. (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
  1663. (1 << AC_AMPCAP_MUTE_SHIFT));
  1664. }
  1665. /* toggle GPIO1 according to the mute state */
  1666. static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
  1667. {
  1668. struct hda_codec *codec = private_data;
  1669. struct ad198x_spec *spec = codec->spec;
  1670. if (spec->eapd_nid)
  1671. ad_vmaster_eapd_hook(private_data, enabled);
  1672. snd_hda_codec_update_cache(codec, 0x01, 0,
  1673. AC_VERB_SET_GPIO_DATA,
  1674. enabled ? 0x00 : 0x02);
  1675. }
  1676. static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
  1677. const struct hda_fixup *fix, int action)
  1678. {
  1679. struct ad198x_spec *spec = codec->spec;
  1680. static const struct hda_verb gpio_init_verbs[] = {
  1681. {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
  1682. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
  1683. {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
  1684. {},
  1685. };
  1686. switch (action) {
  1687. case HDA_FIXUP_ACT_PRE_PROBE:
  1688. spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
  1689. snd_hda_sequence_write_cache(codec, gpio_init_verbs);
  1690. break;
  1691. case HDA_FIXUP_ACT_PROBE:
  1692. if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
  1693. spec->eapd_nid = spec->gen.autocfg.line_out_pins[0];
  1694. else
  1695. spec->eapd_nid = spec->gen.autocfg.speaker_pins[0];
  1696. break;
  1697. }
  1698. }
  1699. /* set magic COEFs for dmic */
  1700. static const struct hda_verb ad1884_dmic_init_verbs[] = {
  1701. {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
  1702. {0x01, AC_VERB_SET_PROC_COEF, 0x08},
  1703. {}
  1704. };
  1705. enum {
  1706. AD1884_FIXUP_AMP_OVERRIDE,
  1707. AD1884_FIXUP_HP_EAPD,
  1708. AD1884_FIXUP_DMIC_COEF,
  1709. AD1884_FIXUP_HP_TOUCHSMART,
  1710. };
  1711. static const struct hda_fixup ad1884_fixups[] = {
  1712. [AD1884_FIXUP_AMP_OVERRIDE] = {
  1713. .type = HDA_FIXUP_FUNC,
  1714. .v.func = ad1884_fixup_amp_override,
  1715. },
  1716. [AD1884_FIXUP_HP_EAPD] = {
  1717. .type = HDA_FIXUP_FUNC,
  1718. .v.func = ad1884_fixup_hp_eapd,
  1719. .chained = true,
  1720. .chain_id = AD1884_FIXUP_AMP_OVERRIDE,
  1721. },
  1722. [AD1884_FIXUP_DMIC_COEF] = {
  1723. .type = HDA_FIXUP_VERBS,
  1724. .v.verbs = ad1884_dmic_init_verbs,
  1725. },
  1726. [AD1884_FIXUP_HP_TOUCHSMART] = {
  1727. .type = HDA_FIXUP_VERBS,
  1728. .v.verbs = ad1884_dmic_init_verbs,
  1729. .chained = true,
  1730. .chain_id = AD1884_FIXUP_HP_EAPD,
  1731. },
  1732. };
  1733. static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
  1734. SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART),
  1735. SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
  1736. SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_DMIC_COEF),
  1737. {}
  1738. };
  1739. static int patch_ad1884(struct hda_codec *codec)
  1740. {
  1741. struct ad198x_spec *spec;
  1742. int err;
  1743. err = alloc_ad_spec(codec);
  1744. if (err < 0)
  1745. return err;
  1746. spec = codec->spec;
  1747. spec->gen.mixer_nid = 0x20;
  1748. spec->gen.beep_nid = 0x10;
  1749. set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
  1750. snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
  1751. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
  1752. err = ad198x_parse_auto_config(codec);
  1753. if (err < 0)
  1754. goto error;
  1755. err = ad1983_add_spdif_mux_ctl(codec);
  1756. if (err < 0)
  1757. goto error;
  1758. snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
  1759. return 0;
  1760. error:
  1761. snd_hda_gen_free(codec);
  1762. return err;
  1763. }
  1764. /*
  1765. * AD1882 / AD1882A
  1766. *
  1767. * port-A - front hp-out
  1768. * port-B - front mic-in
  1769. * port-C - rear line-in, shared surr-out (3stack)
  1770. * port-D - rear line-out
  1771. * port-E - rear mic-in, shared clfe-out (3stack)
  1772. * port-F - rear surr-out (6stack)
  1773. * port-G - rear clfe-out (6stack)
  1774. */
  1775. static int patch_ad1882(struct hda_codec *codec)
  1776. {
  1777. struct ad198x_spec *spec;
  1778. int err;
  1779. err = alloc_ad_spec(codec);
  1780. if (err < 0)
  1781. return err;
  1782. spec = codec->spec;
  1783. spec->gen.mixer_nid = 0x20;
  1784. spec->gen.mixer_merge_nid = 0x21;
  1785. spec->gen.beep_nid = 0x10;
  1786. set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
  1787. err = ad198x_parse_auto_config(codec);
  1788. if (err < 0)
  1789. goto error;
  1790. err = ad1988_add_spdif_mux_ctl(codec);
  1791. if (err < 0)
  1792. goto error;
  1793. return 0;
  1794. error:
  1795. snd_hda_gen_free(codec);
  1796. return err;
  1797. }
  1798. /*
  1799. * patch entries
  1800. */
  1801. static const struct hda_codec_preset snd_hda_preset_analog[] = {
  1802. { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 },
  1803. { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
  1804. { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 },
  1805. { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
  1806. { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 },
  1807. { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 },
  1808. { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
  1809. { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
  1810. { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 },
  1811. { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
  1812. { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
  1813. { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
  1814. { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
  1815. { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
  1816. { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
  1817. {} /* terminator */
  1818. };
  1819. MODULE_ALIAS("snd-hda-codec-id:11d4*");
  1820. MODULE_LICENSE("GPL");
  1821. MODULE_DESCRIPTION("Analog Devices HD-audio codec");
  1822. static struct hda_codec_preset_list analog_list = {
  1823. .preset = snd_hda_preset_analog,
  1824. .owner = THIS_MODULE,
  1825. };
  1826. static int __init patch_analog_init(void)
  1827. {
  1828. return snd_hda_add_codec_preset(&analog_list);
  1829. }
  1830. static void __exit patch_analog_exit(void)
  1831. {
  1832. snd_hda_delete_codec_preset(&analog_list);
  1833. }
  1834. module_init(patch_analog_init)
  1835. module_exit(patch_analog_exit)