patch_analog.c 137 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361
  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/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. struct snd_kcontrol_new *mixers[5];
  30. int num_mixers;
  31. const struct hda_verb *init_verbs[5]; /* 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. unsigned int cur_eapd;
  41. unsigned int need_dac_fix;
  42. /* capture */
  43. unsigned int num_adc_nids;
  44. hda_nid_t *adc_nids;
  45. hda_nid_t dig_in_nid; /* digital-in NID; optional */
  46. /* capture source */
  47. const struct hda_input_mux *input_mux;
  48. hda_nid_t *capsrc_nids;
  49. unsigned int cur_mux[3];
  50. /* channel model */
  51. const struct hda_channel_mode *channel_mode;
  52. int num_channel_mode;
  53. /* PCM information */
  54. struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
  55. unsigned int spdif_route;
  56. /* dynamic controls, init_verbs and input_mux */
  57. struct auto_pin_cfg autocfg;
  58. struct snd_array kctls;
  59. struct hda_input_mux private_imux;
  60. hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  61. unsigned int jack_present :1;
  62. #ifdef CONFIG_SND_HDA_POWER_SAVE
  63. struct hda_loopback_check loopback;
  64. #endif
  65. /* for virtual master */
  66. hda_nid_t vmaster_nid;
  67. const char **slave_vols;
  68. const char **slave_sws;
  69. };
  70. /*
  71. * input MUX handling (common part)
  72. */
  73. static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  74. {
  75. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  76. struct ad198x_spec *spec = codec->spec;
  77. return snd_hda_input_mux_info(spec->input_mux, uinfo);
  78. }
  79. static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  80. {
  81. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  82. struct ad198x_spec *spec = codec->spec;
  83. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  84. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  85. return 0;
  86. }
  87. static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  88. {
  89. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  90. struct ad198x_spec *spec = codec->spec;
  91. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  92. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  93. spec->capsrc_nids[adc_idx],
  94. &spec->cur_mux[adc_idx]);
  95. }
  96. /*
  97. * initialization (common callbacks)
  98. */
  99. static int ad198x_init(struct hda_codec *codec)
  100. {
  101. struct ad198x_spec *spec = codec->spec;
  102. int i;
  103. for (i = 0; i < spec->num_init_verbs; i++)
  104. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  105. return 0;
  106. }
  107. static const char *ad_slave_vols[] = {
  108. "Front Playback Volume",
  109. "Surround Playback Volume",
  110. "Center Playback Volume",
  111. "LFE Playback Volume",
  112. "Side Playback Volume",
  113. "Headphone Playback Volume",
  114. "Mono Playback Volume",
  115. "Speaker Playback Volume",
  116. "IEC958 Playback Volume",
  117. NULL
  118. };
  119. static const char *ad_slave_sws[] = {
  120. "Front Playback Switch",
  121. "Surround Playback Switch",
  122. "Center Playback Switch",
  123. "LFE Playback Switch",
  124. "Side Playback Switch",
  125. "Headphone Playback Switch",
  126. "Mono Playback Switch",
  127. "Speaker Playback Switch",
  128. "IEC958 Playback Switch",
  129. NULL
  130. };
  131. static void ad198x_free_kctls(struct hda_codec *codec);
  132. static int ad198x_build_controls(struct hda_codec *codec)
  133. {
  134. struct ad198x_spec *spec = codec->spec;
  135. unsigned int i;
  136. int err;
  137. for (i = 0; i < spec->num_mixers; i++) {
  138. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  139. if (err < 0)
  140. return err;
  141. }
  142. if (spec->multiout.dig_out_nid) {
  143. err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
  144. if (err < 0)
  145. return err;
  146. err = snd_hda_create_spdif_share_sw(codec,
  147. &spec->multiout);
  148. if (err < 0)
  149. return err;
  150. spec->multiout.share_spdif = 1;
  151. }
  152. if (spec->dig_in_nid) {
  153. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  154. if (err < 0)
  155. return err;
  156. }
  157. /* if we have no master control, let's create it */
  158. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
  159. unsigned int vmaster_tlv[4];
  160. snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
  161. HDA_OUTPUT, vmaster_tlv);
  162. err = snd_hda_add_vmaster(codec, "Master Playback Volume",
  163. vmaster_tlv,
  164. (spec->slave_vols ?
  165. spec->slave_vols : ad_slave_vols));
  166. if (err < 0)
  167. return err;
  168. }
  169. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
  170. err = snd_hda_add_vmaster(codec, "Master Playback Switch",
  171. NULL,
  172. (spec->slave_sws ?
  173. spec->slave_sws : ad_slave_sws));
  174. if (err < 0)
  175. return err;
  176. }
  177. ad198x_free_kctls(codec); /* no longer needed */
  178. return 0;
  179. }
  180. #ifdef CONFIG_SND_HDA_POWER_SAVE
  181. static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
  182. {
  183. struct ad198x_spec *spec = codec->spec;
  184. return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
  185. }
  186. #endif
  187. /*
  188. * Analog playback callbacks
  189. */
  190. static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
  191. struct hda_codec *codec,
  192. struct snd_pcm_substream *substream)
  193. {
  194. struct ad198x_spec *spec = codec->spec;
  195. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
  196. hinfo);
  197. }
  198. static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  199. struct hda_codec *codec,
  200. unsigned int stream_tag,
  201. unsigned int format,
  202. struct snd_pcm_substream *substream)
  203. {
  204. struct ad198x_spec *spec = codec->spec;
  205. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
  206. format, substream);
  207. }
  208. static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  209. struct hda_codec *codec,
  210. struct snd_pcm_substream *substream)
  211. {
  212. struct ad198x_spec *spec = codec->spec;
  213. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  214. }
  215. /*
  216. * Digital out
  217. */
  218. static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  219. struct hda_codec *codec,
  220. struct snd_pcm_substream *substream)
  221. {
  222. struct ad198x_spec *spec = codec->spec;
  223. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  224. }
  225. static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  226. struct hda_codec *codec,
  227. struct snd_pcm_substream *substream)
  228. {
  229. struct ad198x_spec *spec = codec->spec;
  230. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  231. }
  232. static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  233. struct hda_codec *codec,
  234. unsigned int stream_tag,
  235. unsigned int format,
  236. struct snd_pcm_substream *substream)
  237. {
  238. struct ad198x_spec *spec = codec->spec;
  239. return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
  240. format, substream);
  241. }
  242. static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  243. struct hda_codec *codec,
  244. struct snd_pcm_substream *substream)
  245. {
  246. struct ad198x_spec *spec = codec->spec;
  247. return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
  248. }
  249. /*
  250. * Analog capture
  251. */
  252. static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  253. struct hda_codec *codec,
  254. unsigned int stream_tag,
  255. unsigned int format,
  256. struct snd_pcm_substream *substream)
  257. {
  258. struct ad198x_spec *spec = codec->spec;
  259. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  260. stream_tag, 0, format);
  261. return 0;
  262. }
  263. static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  264. struct hda_codec *codec,
  265. struct snd_pcm_substream *substream)
  266. {
  267. struct ad198x_spec *spec = codec->spec;
  268. snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
  269. return 0;
  270. }
  271. /*
  272. */
  273. static struct hda_pcm_stream ad198x_pcm_analog_playback = {
  274. .substreams = 1,
  275. .channels_min = 2,
  276. .channels_max = 6, /* changed later */
  277. .nid = 0, /* fill later */
  278. .ops = {
  279. .open = ad198x_playback_pcm_open,
  280. .prepare = ad198x_playback_pcm_prepare,
  281. .cleanup = ad198x_playback_pcm_cleanup
  282. },
  283. };
  284. static struct hda_pcm_stream ad198x_pcm_analog_capture = {
  285. .substreams = 1,
  286. .channels_min = 2,
  287. .channels_max = 2,
  288. .nid = 0, /* fill later */
  289. .ops = {
  290. .prepare = ad198x_capture_pcm_prepare,
  291. .cleanup = ad198x_capture_pcm_cleanup
  292. },
  293. };
  294. static struct hda_pcm_stream ad198x_pcm_digital_playback = {
  295. .substreams = 1,
  296. .channels_min = 2,
  297. .channels_max = 2,
  298. .nid = 0, /* fill later */
  299. .ops = {
  300. .open = ad198x_dig_playback_pcm_open,
  301. .close = ad198x_dig_playback_pcm_close,
  302. .prepare = ad198x_dig_playback_pcm_prepare,
  303. .cleanup = ad198x_dig_playback_pcm_cleanup
  304. },
  305. };
  306. static struct hda_pcm_stream ad198x_pcm_digital_capture = {
  307. .substreams = 1,
  308. .channels_min = 2,
  309. .channels_max = 2,
  310. /* NID is set in alc_build_pcms */
  311. };
  312. static int ad198x_build_pcms(struct hda_codec *codec)
  313. {
  314. struct ad198x_spec *spec = codec->spec;
  315. struct hda_pcm *info = spec->pcm_rec;
  316. codec->num_pcms = 1;
  317. codec->pcm_info = info;
  318. info->name = "AD198x Analog";
  319. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
  320. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
  321. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  322. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
  323. info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
  324. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  325. if (spec->multiout.dig_out_nid) {
  326. info++;
  327. codec->num_pcms++;
  328. info->name = "AD198x Digital";
  329. info->pcm_type = HDA_PCM_TYPE_SPDIF;
  330. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
  331. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
  332. if (spec->dig_in_nid) {
  333. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
  334. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
  335. }
  336. }
  337. return 0;
  338. }
  339. static void ad198x_free_kctls(struct hda_codec *codec)
  340. {
  341. struct ad198x_spec *spec = codec->spec;
  342. if (spec->kctls.list) {
  343. struct snd_kcontrol_new *kctl = spec->kctls.list;
  344. int i;
  345. for (i = 0; i < spec->kctls.used; i++)
  346. kfree(kctl[i].name);
  347. }
  348. snd_array_free(&spec->kctls);
  349. }
  350. static void ad198x_free(struct hda_codec *codec)
  351. {
  352. struct ad198x_spec *spec = codec->spec;
  353. if (!spec)
  354. return;
  355. ad198x_free_kctls(codec);
  356. kfree(codec->spec);
  357. }
  358. static struct hda_codec_ops ad198x_patch_ops = {
  359. .build_controls = ad198x_build_controls,
  360. .build_pcms = ad198x_build_pcms,
  361. .init = ad198x_init,
  362. .free = ad198x_free,
  363. #ifdef CONFIG_SND_HDA_POWER_SAVE
  364. .check_power_status = ad198x_check_power_status,
  365. #endif
  366. };
  367. /*
  368. * EAPD control
  369. * the private value = nid | (invert << 8)
  370. */
  371. #define ad198x_eapd_info snd_ctl_boolean_mono_info
  372. static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
  373. struct snd_ctl_elem_value *ucontrol)
  374. {
  375. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  376. struct ad198x_spec *spec = codec->spec;
  377. int invert = (kcontrol->private_value >> 8) & 1;
  378. if (invert)
  379. ucontrol->value.integer.value[0] = ! spec->cur_eapd;
  380. else
  381. ucontrol->value.integer.value[0] = spec->cur_eapd;
  382. return 0;
  383. }
  384. static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
  385. struct snd_ctl_elem_value *ucontrol)
  386. {
  387. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  388. struct ad198x_spec *spec = codec->spec;
  389. int invert = (kcontrol->private_value >> 8) & 1;
  390. hda_nid_t nid = kcontrol->private_value & 0xff;
  391. unsigned int eapd;
  392. eapd = !!ucontrol->value.integer.value[0];
  393. if (invert)
  394. eapd = !eapd;
  395. if (eapd == spec->cur_eapd)
  396. return 0;
  397. spec->cur_eapd = eapd;
  398. snd_hda_codec_write_cache(codec, nid,
  399. 0, AC_VERB_SET_EAPD_BTLENABLE,
  400. eapd ? 0x02 : 0x00);
  401. return 1;
  402. }
  403. static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
  404. struct snd_ctl_elem_info *uinfo);
  405. static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
  406. struct snd_ctl_elem_value *ucontrol);
  407. static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
  408. struct snd_ctl_elem_value *ucontrol);
  409. /*
  410. * AD1986A specific
  411. */
  412. #define AD1986A_SPDIF_OUT 0x02
  413. #define AD1986A_FRONT_DAC 0x03
  414. #define AD1986A_SURR_DAC 0x04
  415. #define AD1986A_CLFE_DAC 0x05
  416. #define AD1986A_ADC 0x06
  417. static hda_nid_t ad1986a_dac_nids[3] = {
  418. AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
  419. };
  420. static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
  421. static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
  422. static struct hda_input_mux ad1986a_capture_source = {
  423. .num_items = 7,
  424. .items = {
  425. { "Mic", 0x0 },
  426. { "CD", 0x1 },
  427. { "Aux", 0x3 },
  428. { "Line", 0x4 },
  429. { "Mix", 0x5 },
  430. { "Mono", 0x6 },
  431. { "Phone", 0x7 },
  432. },
  433. };
  434. static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
  435. .ops = &snd_hda_bind_vol,
  436. .values = {
  437. HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
  438. HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
  439. HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
  440. 0
  441. },
  442. };
  443. static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
  444. .ops = &snd_hda_bind_sw,
  445. .values = {
  446. HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
  447. HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
  448. HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
  449. 0
  450. },
  451. };
  452. /*
  453. * mixers
  454. */
  455. static struct snd_kcontrol_new ad1986a_mixers[] = {
  456. /*
  457. * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
  458. */
  459. HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
  460. HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
  461. HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  462. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  463. HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  464. HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  465. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
  466. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
  467. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
  468. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
  469. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
  470. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
  471. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  472. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  473. HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  474. HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  475. HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
  476. HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  477. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  478. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  479. HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
  480. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
  481. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  482. HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
  483. HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
  484. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  485. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  486. {
  487. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  488. .name = "Capture Source",
  489. .info = ad198x_mux_enum_info,
  490. .get = ad198x_mux_enum_get,
  491. .put = ad198x_mux_enum_put,
  492. },
  493. HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
  494. { } /* end */
  495. };
  496. /* additional mixers for 3stack mode */
  497. static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
  498. {
  499. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  500. .name = "Channel Mode",
  501. .info = ad198x_ch_mode_info,
  502. .get = ad198x_ch_mode_get,
  503. .put = ad198x_ch_mode_put,
  504. },
  505. { } /* end */
  506. };
  507. /* laptop model - 2ch only */
  508. static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
  509. /* master controls both pins 0x1a and 0x1b */
  510. static struct hda_bind_ctls ad1986a_laptop_master_vol = {
  511. .ops = &snd_hda_bind_vol,
  512. .values = {
  513. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  514. HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
  515. 0,
  516. },
  517. };
  518. static struct hda_bind_ctls ad1986a_laptop_master_sw = {
  519. .ops = &snd_hda_bind_sw,
  520. .values = {
  521. HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  522. HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
  523. 0,
  524. },
  525. };
  526. static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
  527. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  528. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  529. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  530. HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
  531. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  532. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  533. HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  534. HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  535. HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
  536. HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  537. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  538. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  539. HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
  540. /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
  541. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  542. HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
  543. HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
  544. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  545. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  546. {
  547. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  548. .name = "Capture Source",
  549. .info = ad198x_mux_enum_info,
  550. .get = ad198x_mux_enum_get,
  551. .put = ad198x_mux_enum_put,
  552. },
  553. { } /* end */
  554. };
  555. /* laptop-eapd model - 2ch only */
  556. static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
  557. .num_items = 3,
  558. .items = {
  559. { "Mic", 0x0 },
  560. { "Internal Mic", 0x4 },
  561. { "Mix", 0x5 },
  562. },
  563. };
  564. static struct hda_input_mux ad1986a_automic_capture_source = {
  565. .num_items = 2,
  566. .items = {
  567. { "Mic", 0x0 },
  568. { "Mix", 0x5 },
  569. },
  570. };
  571. static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
  572. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  573. HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
  574. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  575. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  576. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
  577. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
  578. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  579. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  580. HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
  581. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  582. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  583. {
  584. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  585. .name = "Capture Source",
  586. .info = ad198x_mux_enum_info,
  587. .get = ad198x_mux_enum_get,
  588. .put = ad198x_mux_enum_put,
  589. },
  590. {
  591. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  592. .name = "External Amplifier",
  593. .info = ad198x_eapd_info,
  594. .get = ad198x_eapd_get,
  595. .put = ad198x_eapd_put,
  596. .private_value = 0x1b | (1 << 8), /* port-D, inversed */
  597. },
  598. { } /* end */
  599. };
  600. static struct snd_kcontrol_new ad1986a_samsung_mixers[] = {
  601. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  602. HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
  603. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  604. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  605. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  606. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  607. HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
  608. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  609. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  610. {
  611. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  612. .name = "Capture Source",
  613. .info = ad198x_mux_enum_info,
  614. .get = ad198x_mux_enum_get,
  615. .put = ad198x_mux_enum_put,
  616. },
  617. {
  618. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  619. .name = "External Amplifier",
  620. .info = ad198x_eapd_info,
  621. .get = ad198x_eapd_get,
  622. .put = ad198x_eapd_put,
  623. .private_value = 0x1b | (1 << 8), /* port-D, inversed */
  624. },
  625. { } /* end */
  626. };
  627. /* re-connect the mic boost input according to the jack sensing */
  628. static void ad1986a_automic(struct hda_codec *codec)
  629. {
  630. unsigned int present;
  631. present = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_PIN_SENSE, 0);
  632. /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
  633. snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
  634. (present & AC_PINSENSE_PRESENCE) ? 0 : 2);
  635. }
  636. #define AD1986A_MIC_EVENT 0x36
  637. static void ad1986a_automic_unsol_event(struct hda_codec *codec,
  638. unsigned int res)
  639. {
  640. if ((res >> 26) != AD1986A_MIC_EVENT)
  641. return;
  642. ad1986a_automic(codec);
  643. }
  644. static int ad1986a_automic_init(struct hda_codec *codec)
  645. {
  646. ad198x_init(codec);
  647. ad1986a_automic(codec);
  648. return 0;
  649. }
  650. /* laptop-automute - 2ch only */
  651. static void ad1986a_update_hp(struct hda_codec *codec)
  652. {
  653. struct ad198x_spec *spec = codec->spec;
  654. unsigned int mute;
  655. if (spec->jack_present)
  656. mute = HDA_AMP_MUTE; /* mute internal speaker */
  657. else
  658. /* unmute internal speaker if necessary */
  659. mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
  660. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  661. HDA_AMP_MUTE, mute);
  662. }
  663. static void ad1986a_hp_automute(struct hda_codec *codec)
  664. {
  665. struct ad198x_spec *spec = codec->spec;
  666. unsigned int present;
  667. present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
  668. /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
  669. spec->jack_present = !(present & 0x80000000);
  670. ad1986a_update_hp(codec);
  671. }
  672. #define AD1986A_HP_EVENT 0x37
  673. static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
  674. {
  675. if ((res >> 26) != AD1986A_HP_EVENT)
  676. return;
  677. ad1986a_hp_automute(codec);
  678. }
  679. static int ad1986a_hp_init(struct hda_codec *codec)
  680. {
  681. ad198x_init(codec);
  682. ad1986a_hp_automute(codec);
  683. return 0;
  684. }
  685. /* bind hp and internal speaker mute (with plug check) */
  686. static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
  687. struct snd_ctl_elem_value *ucontrol)
  688. {
  689. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  690. long *valp = ucontrol->value.integer.value;
  691. int change;
  692. change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
  693. HDA_AMP_MUTE,
  694. valp[0] ? 0 : HDA_AMP_MUTE);
  695. change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
  696. HDA_AMP_MUTE,
  697. valp[1] ? 0 : HDA_AMP_MUTE);
  698. if (change)
  699. ad1986a_update_hp(codec);
  700. return change;
  701. }
  702. static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
  703. HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
  704. {
  705. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  706. .name = "Master Playback Switch",
  707. .info = snd_hda_mixer_amp_switch_info,
  708. .get = snd_hda_mixer_amp_switch_get,
  709. .put = ad1986a_hp_master_sw_put,
  710. .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
  711. },
  712. HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  713. HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  714. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
  715. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
  716. HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  717. HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  718. HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
  719. HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
  720. HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  721. HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
  722. HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
  723. {
  724. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  725. .name = "Capture Source",
  726. .info = ad198x_mux_enum_info,
  727. .get = ad198x_mux_enum_get,
  728. .put = ad198x_mux_enum_put,
  729. },
  730. {
  731. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  732. .name = "External Amplifier",
  733. .info = ad198x_eapd_info,
  734. .get = ad198x_eapd_get,
  735. .put = ad198x_eapd_put,
  736. .private_value = 0x1b | (1 << 8), /* port-D, inversed */
  737. },
  738. { } /* end */
  739. };
  740. /*
  741. * initialization verbs
  742. */
  743. static struct hda_verb ad1986a_init_verbs[] = {
  744. /* Front, Surround, CLFE DAC; mute as default */
  745. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  746. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  747. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  748. /* Downmix - off */
  749. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  750. /* HP, Line-Out, Surround, CLFE selectors */
  751. {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
  752. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
  753. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  754. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  755. /* Mono selector */
  756. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
  757. /* Mic selector: Mic 1/2 pin */
  758. {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
  759. /* Line-in selector: Line-in */
  760. {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
  761. /* Mic 1/2 swap */
  762. {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
  763. /* Record selector: mic */
  764. {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
  765. /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
  766. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  767. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  768. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  769. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  770. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  771. /* PC beep */
  772. {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
  773. /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
  774. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  775. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  776. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  777. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  778. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  779. /* HP Pin */
  780. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  781. /* Front, Surround, CLFE Pins */
  782. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  783. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  784. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  785. /* Mono Pin */
  786. {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  787. /* Mic Pin */
  788. {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  789. /* Line, Aux, CD, Beep-In Pin */
  790. {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  791. {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  792. {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  793. {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  794. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  795. { } /* end */
  796. };
  797. static struct hda_verb ad1986a_ch2_init[] = {
  798. /* Surround out -> Line In */
  799. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  800. /* Line-in selectors */
  801. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
  802. /* CLFE -> Mic in */
  803. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  804. /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
  805. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
  806. { } /* end */
  807. };
  808. static struct hda_verb ad1986a_ch4_init[] = {
  809. /* Surround out -> Surround */
  810. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  811. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
  812. /* CLFE -> Mic in */
  813. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  814. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
  815. { } /* end */
  816. };
  817. static struct hda_verb ad1986a_ch6_init[] = {
  818. /* Surround out -> Surround out */
  819. { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  820. { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
  821. /* CLFE -> CLFE */
  822. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  823. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
  824. { } /* end */
  825. };
  826. static struct hda_channel_mode ad1986a_modes[3] = {
  827. { 2, ad1986a_ch2_init },
  828. { 4, ad1986a_ch4_init },
  829. { 6, ad1986a_ch6_init },
  830. };
  831. /* eapd initialization */
  832. static struct hda_verb ad1986a_eapd_init_verbs[] = {
  833. {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
  834. {}
  835. };
  836. static struct hda_verb ad1986a_automic_verbs[] = {
  837. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  838. {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  839. /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
  840. {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
  841. {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
  842. {}
  843. };
  844. /* Ultra initialization */
  845. static struct hda_verb ad1986a_ultra_init[] = {
  846. /* eapd initialization */
  847. { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
  848. /* CLFE -> Mic in */
  849. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
  850. { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  851. { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
  852. { } /* end */
  853. };
  854. /* pin sensing on HP jack */
  855. static struct hda_verb ad1986a_hp_init_verbs[] = {
  856. {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
  857. {}
  858. };
  859. /* models */
  860. enum {
  861. AD1986A_6STACK,
  862. AD1986A_3STACK,
  863. AD1986A_LAPTOP,
  864. AD1986A_LAPTOP_EAPD,
  865. AD1986A_LAPTOP_AUTOMUTE,
  866. AD1986A_ULTRA,
  867. AD1986A_SAMSUNG,
  868. AD1986A_MODELS
  869. };
  870. static const char *ad1986a_models[AD1986A_MODELS] = {
  871. [AD1986A_6STACK] = "6stack",
  872. [AD1986A_3STACK] = "3stack",
  873. [AD1986A_LAPTOP] = "laptop",
  874. [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
  875. [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
  876. [AD1986A_ULTRA] = "ultra",
  877. [AD1986A_SAMSUNG] = "samsung",
  878. };
  879. static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
  880. SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
  881. SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
  882. SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
  883. SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
  884. SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
  885. SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
  886. SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
  887. SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
  888. SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
  889. SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
  890. SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
  891. SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
  892. SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
  893. SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
  894. SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
  895. SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
  896. SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
  897. SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
  898. SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
  899. SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_SAMSUNG),
  900. SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_SAMSUNG),
  901. SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_SAMSUNG),
  902. SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
  903. SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
  904. SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
  905. SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
  906. SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
  907. SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
  908. {}
  909. };
  910. #ifdef CONFIG_SND_HDA_POWER_SAVE
  911. static struct hda_amp_list ad1986a_loopbacks[] = {
  912. { 0x13, HDA_OUTPUT, 0 }, /* Mic */
  913. { 0x14, HDA_OUTPUT, 0 }, /* Phone */
  914. { 0x15, HDA_OUTPUT, 0 }, /* CD */
  915. { 0x16, HDA_OUTPUT, 0 }, /* Aux */
  916. { 0x17, HDA_OUTPUT, 0 }, /* Line */
  917. { } /* end */
  918. };
  919. #endif
  920. static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
  921. {
  922. unsigned int conf = snd_hda_codec_read(codec, nid, 0,
  923. AC_VERB_GET_CONFIG_DEFAULT, 0);
  924. return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
  925. }
  926. static int patch_ad1986a(struct hda_codec *codec)
  927. {
  928. struct ad198x_spec *spec;
  929. int board_config;
  930. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  931. if (spec == NULL)
  932. return -ENOMEM;
  933. codec->spec = spec;
  934. spec->multiout.max_channels = 6;
  935. spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
  936. spec->multiout.dac_nids = ad1986a_dac_nids;
  937. spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
  938. spec->num_adc_nids = 1;
  939. spec->adc_nids = ad1986a_adc_nids;
  940. spec->capsrc_nids = ad1986a_capsrc_nids;
  941. spec->input_mux = &ad1986a_capture_source;
  942. spec->num_mixers = 1;
  943. spec->mixers[0] = ad1986a_mixers;
  944. spec->num_init_verbs = 1;
  945. spec->init_verbs[0] = ad1986a_init_verbs;
  946. #ifdef CONFIG_SND_HDA_POWER_SAVE
  947. spec->loopback.amplist = ad1986a_loopbacks;
  948. #endif
  949. spec->vmaster_nid = 0x1b;
  950. codec->patch_ops = ad198x_patch_ops;
  951. /* override some parameters */
  952. board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
  953. ad1986a_models,
  954. ad1986a_cfg_tbl);
  955. switch (board_config) {
  956. case AD1986A_3STACK:
  957. spec->num_mixers = 2;
  958. spec->mixers[1] = ad1986a_3st_mixers;
  959. spec->num_init_verbs = 2;
  960. spec->init_verbs[1] = ad1986a_ch2_init;
  961. spec->channel_mode = ad1986a_modes;
  962. spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
  963. spec->need_dac_fix = 1;
  964. spec->multiout.max_channels = 2;
  965. spec->multiout.num_dacs = 1;
  966. break;
  967. case AD1986A_LAPTOP:
  968. spec->mixers[0] = ad1986a_laptop_mixers;
  969. spec->multiout.max_channels = 2;
  970. spec->multiout.num_dacs = 1;
  971. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  972. break;
  973. case AD1986A_LAPTOP_EAPD:
  974. spec->mixers[0] = ad1986a_laptop_eapd_mixers;
  975. spec->num_init_verbs = 2;
  976. spec->init_verbs[1] = ad1986a_eapd_init_verbs;
  977. spec->multiout.max_channels = 2;
  978. spec->multiout.num_dacs = 1;
  979. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  980. if (!is_jack_available(codec, 0x25))
  981. spec->multiout.dig_out_nid = 0;
  982. spec->input_mux = &ad1986a_laptop_eapd_capture_source;
  983. break;
  984. case AD1986A_SAMSUNG:
  985. spec->mixers[0] = ad1986a_samsung_mixers;
  986. spec->num_init_verbs = 3;
  987. spec->init_verbs[1] = ad1986a_eapd_init_verbs;
  988. spec->init_verbs[2] = ad1986a_automic_verbs;
  989. spec->multiout.max_channels = 2;
  990. spec->multiout.num_dacs = 1;
  991. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  992. if (!is_jack_available(codec, 0x25))
  993. spec->multiout.dig_out_nid = 0;
  994. spec->input_mux = &ad1986a_automic_capture_source;
  995. codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
  996. codec->patch_ops.init = ad1986a_automic_init;
  997. break;
  998. case AD1986A_LAPTOP_AUTOMUTE:
  999. spec->mixers[0] = ad1986a_laptop_automute_mixers;
  1000. spec->num_init_verbs = 3;
  1001. spec->init_verbs[1] = ad1986a_eapd_init_verbs;
  1002. spec->init_verbs[2] = ad1986a_hp_init_verbs;
  1003. spec->multiout.max_channels = 2;
  1004. spec->multiout.num_dacs = 1;
  1005. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  1006. if (!is_jack_available(codec, 0x25))
  1007. spec->multiout.dig_out_nid = 0;
  1008. spec->input_mux = &ad1986a_laptop_eapd_capture_source;
  1009. codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
  1010. codec->patch_ops.init = ad1986a_hp_init;
  1011. break;
  1012. case AD1986A_ULTRA:
  1013. spec->mixers[0] = ad1986a_laptop_eapd_mixers;
  1014. spec->num_init_verbs = 2;
  1015. spec->init_verbs[1] = ad1986a_ultra_init;
  1016. spec->multiout.max_channels = 2;
  1017. spec->multiout.num_dacs = 1;
  1018. spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
  1019. spec->multiout.dig_out_nid = 0;
  1020. break;
  1021. }
  1022. /* AD1986A has a hardware problem that it can't share a stream
  1023. * with multiple output pins. The copy of front to surrounds
  1024. * causes noisy or silent outputs at a certain timing, e.g.
  1025. * changing the volume.
  1026. * So, let's disable the shared stream.
  1027. */
  1028. spec->multiout.no_share_stream = 1;
  1029. return 0;
  1030. }
  1031. /*
  1032. * AD1983 specific
  1033. */
  1034. #define AD1983_SPDIF_OUT 0x02
  1035. #define AD1983_DAC 0x03
  1036. #define AD1983_ADC 0x04
  1037. static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
  1038. static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
  1039. static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
  1040. static struct hda_input_mux ad1983_capture_source = {
  1041. .num_items = 4,
  1042. .items = {
  1043. { "Mic", 0x0 },
  1044. { "Line", 0x1 },
  1045. { "Mix", 0x2 },
  1046. { "Mix Mono", 0x3 },
  1047. },
  1048. };
  1049. /*
  1050. * SPDIF playback route
  1051. */
  1052. static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  1053. {
  1054. static char *texts[] = { "PCM", "ADC" };
  1055. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1056. uinfo->count = 1;
  1057. uinfo->value.enumerated.items = 2;
  1058. if (uinfo->value.enumerated.item > 1)
  1059. uinfo->value.enumerated.item = 1;
  1060. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  1061. return 0;
  1062. }
  1063. static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1064. {
  1065. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1066. struct ad198x_spec *spec = codec->spec;
  1067. ucontrol->value.enumerated.item[0] = spec->spdif_route;
  1068. return 0;
  1069. }
  1070. static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  1071. {
  1072. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1073. struct ad198x_spec *spec = codec->spec;
  1074. if (ucontrol->value.enumerated.item[0] > 1)
  1075. return -EINVAL;
  1076. if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
  1077. spec->spdif_route = ucontrol->value.enumerated.item[0];
  1078. snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
  1079. AC_VERB_SET_CONNECT_SEL,
  1080. spec->spdif_route);
  1081. return 1;
  1082. }
  1083. return 0;
  1084. }
  1085. static struct snd_kcontrol_new ad1983_mixers[] = {
  1086. HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  1087. HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
  1088. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  1089. HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  1090. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
  1091. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
  1092. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  1093. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  1094. HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  1095. HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  1096. HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  1097. HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  1098. HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
  1099. HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
  1100. HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
  1101. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  1102. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  1103. {
  1104. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1105. .name = "Capture Source",
  1106. .info = ad198x_mux_enum_info,
  1107. .get = ad198x_mux_enum_get,
  1108. .put = ad198x_mux_enum_put,
  1109. },
  1110. {
  1111. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1112. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  1113. .info = ad1983_spdif_route_info,
  1114. .get = ad1983_spdif_route_get,
  1115. .put = ad1983_spdif_route_put,
  1116. },
  1117. { } /* end */
  1118. };
  1119. static struct hda_verb ad1983_init_verbs[] = {
  1120. /* Front, HP, Mono; mute as default */
  1121. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1122. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1123. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1124. /* Beep, PCM, Mic, Line-In: mute */
  1125. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1126. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1127. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1128. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1129. /* Front, HP selectors; from Mix */
  1130. {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
  1131. {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
  1132. /* Mono selector; from Mix */
  1133. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
  1134. /* Mic selector; Mic */
  1135. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  1136. /* Line-in selector: Line-in */
  1137. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  1138. /* Mic boost: 0dB */
  1139. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1140. /* Record selector: mic */
  1141. {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
  1142. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1143. /* SPDIF route: PCM */
  1144. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
  1145. /* Front Pin */
  1146. {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  1147. /* HP Pin */
  1148. {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  1149. /* Mono Pin */
  1150. {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  1151. /* Mic Pin */
  1152. {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  1153. /* Line Pin */
  1154. {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  1155. { } /* end */
  1156. };
  1157. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1158. static struct hda_amp_list ad1983_loopbacks[] = {
  1159. { 0x12, HDA_OUTPUT, 0 }, /* Mic */
  1160. { 0x13, HDA_OUTPUT, 0 }, /* Line */
  1161. { } /* end */
  1162. };
  1163. #endif
  1164. static int patch_ad1983(struct hda_codec *codec)
  1165. {
  1166. struct ad198x_spec *spec;
  1167. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1168. if (spec == NULL)
  1169. return -ENOMEM;
  1170. codec->spec = spec;
  1171. spec->multiout.max_channels = 2;
  1172. spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
  1173. spec->multiout.dac_nids = ad1983_dac_nids;
  1174. spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
  1175. spec->num_adc_nids = 1;
  1176. spec->adc_nids = ad1983_adc_nids;
  1177. spec->capsrc_nids = ad1983_capsrc_nids;
  1178. spec->input_mux = &ad1983_capture_source;
  1179. spec->num_mixers = 1;
  1180. spec->mixers[0] = ad1983_mixers;
  1181. spec->num_init_verbs = 1;
  1182. spec->init_verbs[0] = ad1983_init_verbs;
  1183. spec->spdif_route = 0;
  1184. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1185. spec->loopback.amplist = ad1983_loopbacks;
  1186. #endif
  1187. spec->vmaster_nid = 0x05;
  1188. codec->patch_ops = ad198x_patch_ops;
  1189. return 0;
  1190. }
  1191. /*
  1192. * AD1981 HD specific
  1193. */
  1194. #define AD1981_SPDIF_OUT 0x02
  1195. #define AD1981_DAC 0x03
  1196. #define AD1981_ADC 0x04
  1197. static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
  1198. static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
  1199. static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
  1200. /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
  1201. static struct hda_input_mux ad1981_capture_source = {
  1202. .num_items = 7,
  1203. .items = {
  1204. { "Front Mic", 0x0 },
  1205. { "Line", 0x1 },
  1206. { "Mix", 0x2 },
  1207. { "Mix Mono", 0x3 },
  1208. { "CD", 0x4 },
  1209. { "Mic", 0x6 },
  1210. { "Aux", 0x7 },
  1211. },
  1212. };
  1213. static struct snd_kcontrol_new ad1981_mixers[] = {
  1214. HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  1215. HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
  1216. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  1217. HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  1218. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
  1219. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
  1220. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  1221. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  1222. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  1223. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  1224. HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  1225. HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  1226. HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  1227. HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  1228. HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  1229. HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  1230. HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
  1231. HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
  1232. HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  1233. HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
  1234. HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
  1235. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
  1236. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  1237. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  1238. {
  1239. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1240. .name = "Capture Source",
  1241. .info = ad198x_mux_enum_info,
  1242. .get = ad198x_mux_enum_get,
  1243. .put = ad198x_mux_enum_put,
  1244. },
  1245. /* identical with AD1983 */
  1246. {
  1247. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1248. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  1249. .info = ad1983_spdif_route_info,
  1250. .get = ad1983_spdif_route_get,
  1251. .put = ad1983_spdif_route_put,
  1252. },
  1253. { } /* end */
  1254. };
  1255. static struct hda_verb ad1981_init_verbs[] = {
  1256. /* Front, HP, Mono; mute as default */
  1257. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1258. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1259. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1260. /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
  1261. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1262. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1263. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1264. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1265. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1266. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1267. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1268. /* Front, HP selectors; from Mix */
  1269. {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
  1270. {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
  1271. /* Mono selector; from Mix */
  1272. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
  1273. /* Mic Mixer; select Front Mic */
  1274. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1275. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1276. /* Mic boost: 0dB */
  1277. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1278. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1279. /* Record selector: Front mic */
  1280. {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
  1281. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1282. /* SPDIF route: PCM */
  1283. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
  1284. /* Front Pin */
  1285. {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  1286. /* HP Pin */
  1287. {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  1288. /* Mono Pin */
  1289. {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  1290. /* Front & Rear Mic Pins */
  1291. {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  1292. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  1293. /* Line Pin */
  1294. {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  1295. /* Digital Beep */
  1296. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
  1297. /* Line-Out as Input: disabled */
  1298. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1299. { } /* end */
  1300. };
  1301. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1302. static struct hda_amp_list ad1981_loopbacks[] = {
  1303. { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
  1304. { 0x13, HDA_OUTPUT, 0 }, /* Line */
  1305. { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
  1306. { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
  1307. { 0x1d, HDA_OUTPUT, 0 }, /* CD */
  1308. { } /* end */
  1309. };
  1310. #endif
  1311. /*
  1312. * Patch for HP nx6320
  1313. *
  1314. * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
  1315. * speaker output enabled _and_ mute-LED off.
  1316. */
  1317. #define AD1981_HP_EVENT 0x37
  1318. #define AD1981_MIC_EVENT 0x38
  1319. static struct hda_verb ad1981_hp_init_verbs[] = {
  1320. {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
  1321. /* pin sensing on HP and Mic jacks */
  1322. {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
  1323. {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
  1324. {}
  1325. };
  1326. /* turn on/off EAPD (+ mute HP) as a master switch */
  1327. static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
  1328. struct snd_ctl_elem_value *ucontrol)
  1329. {
  1330. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1331. struct ad198x_spec *spec = codec->spec;
  1332. if (! ad198x_eapd_put(kcontrol, ucontrol))
  1333. return 0;
  1334. /* change speaker pin appropriately */
  1335. snd_hda_codec_write(codec, 0x05, 0,
  1336. AC_VERB_SET_PIN_WIDGET_CONTROL,
  1337. spec->cur_eapd ? PIN_OUT : 0);
  1338. /* toggle HP mute appropriately */
  1339. snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
  1340. HDA_AMP_MUTE,
  1341. spec->cur_eapd ? 0 : HDA_AMP_MUTE);
  1342. return 1;
  1343. }
  1344. /* bind volumes of both NID 0x05 and 0x06 */
  1345. static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
  1346. .ops = &snd_hda_bind_vol,
  1347. .values = {
  1348. HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
  1349. HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
  1350. 0
  1351. },
  1352. };
  1353. /* mute internal speaker if HP is plugged */
  1354. static void ad1981_hp_automute(struct hda_codec *codec)
  1355. {
  1356. unsigned int present;
  1357. present = snd_hda_codec_read(codec, 0x06, 0,
  1358. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1359. snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
  1360. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  1361. }
  1362. /* toggle input of built-in and mic jack appropriately */
  1363. static void ad1981_hp_automic(struct hda_codec *codec)
  1364. {
  1365. static struct hda_verb mic_jack_on[] = {
  1366. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1367. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1368. {}
  1369. };
  1370. static struct hda_verb mic_jack_off[] = {
  1371. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
  1372. {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  1373. {}
  1374. };
  1375. unsigned int present;
  1376. present = snd_hda_codec_read(codec, 0x08, 0,
  1377. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1378. if (present)
  1379. snd_hda_sequence_write(codec, mic_jack_on);
  1380. else
  1381. snd_hda_sequence_write(codec, mic_jack_off);
  1382. }
  1383. /* unsolicited event for HP jack sensing */
  1384. static void ad1981_hp_unsol_event(struct hda_codec *codec,
  1385. unsigned int res)
  1386. {
  1387. res >>= 26;
  1388. switch (res) {
  1389. case AD1981_HP_EVENT:
  1390. ad1981_hp_automute(codec);
  1391. break;
  1392. case AD1981_MIC_EVENT:
  1393. ad1981_hp_automic(codec);
  1394. break;
  1395. }
  1396. }
  1397. static struct hda_input_mux ad1981_hp_capture_source = {
  1398. .num_items = 3,
  1399. .items = {
  1400. { "Mic", 0x0 },
  1401. { "Docking-Station", 0x1 },
  1402. { "Mix", 0x2 },
  1403. },
  1404. };
  1405. static struct snd_kcontrol_new ad1981_hp_mixers[] = {
  1406. HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
  1407. {
  1408. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1409. .name = "Master Playback Switch",
  1410. .info = ad198x_eapd_info,
  1411. .get = ad198x_eapd_get,
  1412. .put = ad1981_hp_master_sw_put,
  1413. .private_value = 0x05,
  1414. },
  1415. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  1416. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  1417. #if 0
  1418. /* FIXME: analog mic/line loopback doesn't work with my tests...
  1419. * (although recording is OK)
  1420. */
  1421. HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  1422. HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  1423. HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
  1424. HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
  1425. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
  1426. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
  1427. /* FIXME: does this laptop have analog CD connection? */
  1428. HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
  1429. HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
  1430. #endif
  1431. HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
  1432. HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
  1433. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  1434. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  1435. {
  1436. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1437. .name = "Capture Source",
  1438. .info = ad198x_mux_enum_info,
  1439. .get = ad198x_mux_enum_get,
  1440. .put = ad198x_mux_enum_put,
  1441. },
  1442. { } /* end */
  1443. };
  1444. /* initialize jack-sensing, too */
  1445. static int ad1981_hp_init(struct hda_codec *codec)
  1446. {
  1447. ad198x_init(codec);
  1448. ad1981_hp_automute(codec);
  1449. ad1981_hp_automic(codec);
  1450. return 0;
  1451. }
  1452. /* configuration for Toshiba Laptops */
  1453. static struct hda_verb ad1981_toshiba_init_verbs[] = {
  1454. {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
  1455. /* pin sensing on HP and Mic jacks */
  1456. {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
  1457. {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
  1458. {}
  1459. };
  1460. static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
  1461. HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
  1462. HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
  1463. { }
  1464. };
  1465. /* configuration for Lenovo Thinkpad T60 */
  1466. static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
  1467. HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  1468. HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
  1469. HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
  1470. HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  1471. HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
  1472. HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  1473. HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
  1474. HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
  1475. HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
  1476. HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
  1477. HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
  1478. {
  1479. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1480. .name = "Capture Source",
  1481. .info = ad198x_mux_enum_info,
  1482. .get = ad198x_mux_enum_get,
  1483. .put = ad198x_mux_enum_put,
  1484. },
  1485. /* identical with AD1983 */
  1486. {
  1487. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1488. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  1489. .info = ad1983_spdif_route_info,
  1490. .get = ad1983_spdif_route_get,
  1491. .put = ad1983_spdif_route_put,
  1492. },
  1493. { } /* end */
  1494. };
  1495. static struct hda_input_mux ad1981_thinkpad_capture_source = {
  1496. .num_items = 3,
  1497. .items = {
  1498. { "Mic", 0x0 },
  1499. { "Mix", 0x2 },
  1500. { "CD", 0x4 },
  1501. },
  1502. };
  1503. /* models */
  1504. enum {
  1505. AD1981_BASIC,
  1506. AD1981_HP,
  1507. AD1981_THINKPAD,
  1508. AD1981_TOSHIBA,
  1509. AD1981_MODELS
  1510. };
  1511. static const char *ad1981_models[AD1981_MODELS] = {
  1512. [AD1981_HP] = "hp",
  1513. [AD1981_THINKPAD] = "thinkpad",
  1514. [AD1981_BASIC] = "basic",
  1515. [AD1981_TOSHIBA] = "toshiba"
  1516. };
  1517. static struct snd_pci_quirk ad1981_cfg_tbl[] = {
  1518. SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
  1519. SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
  1520. /* All HP models */
  1521. SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
  1522. SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
  1523. /* Lenovo Thinkpad T60/X60/Z6xx */
  1524. SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
  1525. /* HP nx6320 (reversed SSID, H/W bug) */
  1526. SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
  1527. {}
  1528. };
  1529. static int patch_ad1981(struct hda_codec *codec)
  1530. {
  1531. struct ad198x_spec *spec;
  1532. int board_config;
  1533. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  1534. if (spec == NULL)
  1535. return -ENOMEM;
  1536. codec->spec = spec;
  1537. spec->multiout.max_channels = 2;
  1538. spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
  1539. spec->multiout.dac_nids = ad1981_dac_nids;
  1540. spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
  1541. spec->num_adc_nids = 1;
  1542. spec->adc_nids = ad1981_adc_nids;
  1543. spec->capsrc_nids = ad1981_capsrc_nids;
  1544. spec->input_mux = &ad1981_capture_source;
  1545. spec->num_mixers = 1;
  1546. spec->mixers[0] = ad1981_mixers;
  1547. spec->num_init_verbs = 1;
  1548. spec->init_verbs[0] = ad1981_init_verbs;
  1549. spec->spdif_route = 0;
  1550. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1551. spec->loopback.amplist = ad1981_loopbacks;
  1552. #endif
  1553. spec->vmaster_nid = 0x05;
  1554. codec->patch_ops = ad198x_patch_ops;
  1555. /* override some parameters */
  1556. board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
  1557. ad1981_models,
  1558. ad1981_cfg_tbl);
  1559. switch (board_config) {
  1560. case AD1981_HP:
  1561. spec->mixers[0] = ad1981_hp_mixers;
  1562. spec->num_init_verbs = 2;
  1563. spec->init_verbs[1] = ad1981_hp_init_verbs;
  1564. spec->multiout.dig_out_nid = 0;
  1565. spec->input_mux = &ad1981_hp_capture_source;
  1566. codec->patch_ops.init = ad1981_hp_init;
  1567. codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
  1568. break;
  1569. case AD1981_THINKPAD:
  1570. spec->mixers[0] = ad1981_thinkpad_mixers;
  1571. spec->input_mux = &ad1981_thinkpad_capture_source;
  1572. break;
  1573. case AD1981_TOSHIBA:
  1574. spec->mixers[0] = ad1981_hp_mixers;
  1575. spec->mixers[1] = ad1981_toshiba_mixers;
  1576. spec->num_init_verbs = 2;
  1577. spec->init_verbs[1] = ad1981_toshiba_init_verbs;
  1578. spec->multiout.dig_out_nid = 0;
  1579. spec->input_mux = &ad1981_hp_capture_source;
  1580. codec->patch_ops.init = ad1981_hp_init;
  1581. codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
  1582. break;
  1583. }
  1584. return 0;
  1585. }
  1586. /*
  1587. * AD1988
  1588. *
  1589. * Output pins and routes
  1590. *
  1591. * Pin Mix Sel DAC (*)
  1592. * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
  1593. * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
  1594. * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a
  1595. * port-D 0x12 (mute/hp) <- 0x29 <- 04
  1596. * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
  1597. * port-F 0x16 (mute) <- 0x2a <- 06
  1598. * port-G 0x24 (mute) <- 0x27 <- 05
  1599. * port-H 0x25 (mute) <- 0x28 <- 0a
  1600. * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
  1601. *
  1602. * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
  1603. * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
  1604. *
  1605. * Input pins and routes
  1606. *
  1607. * pin boost mix input # / adc input #
  1608. * port-A 0x11 -> 0x38 -> mix 2, ADC 0
  1609. * port-B 0x14 -> 0x39 -> mix 0, ADC 1
  1610. * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
  1611. * port-D 0x12 -> 0x3d -> mix 3, ADC 8
  1612. * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
  1613. * port-F 0x16 -> 0x3b -> mix 5, ADC 3
  1614. * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
  1615. * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
  1616. *
  1617. *
  1618. * DAC assignment
  1619. * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
  1620. * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
  1621. *
  1622. * Inputs of Analog Mix (0x20)
  1623. * 0:Port-B (front mic)
  1624. * 1:Port-C/G/H (line-in)
  1625. * 2:Port-A
  1626. * 3:Port-D (line-in/2)
  1627. * 4:Port-E/G/H (mic-in)
  1628. * 5:Port-F (mic2-in)
  1629. * 6:CD
  1630. * 7:Beep
  1631. *
  1632. * ADC selection
  1633. * 0:Port-A
  1634. * 1:Port-B (front mic-in)
  1635. * 2:Port-C (line-in)
  1636. * 3:Port-F (mic2-in)
  1637. * 4:Port-E (mic-in)
  1638. * 5:CD
  1639. * 6:Port-G
  1640. * 7:Port-H
  1641. * 8:Port-D (line-in/2)
  1642. * 9:Mix
  1643. *
  1644. * Proposed pin assignments by the datasheet
  1645. *
  1646. * 6-stack
  1647. * Port-A front headphone
  1648. * B front mic-in
  1649. * C rear line-in
  1650. * D rear front-out
  1651. * E rear mic-in
  1652. * F rear surround
  1653. * G rear CLFE
  1654. * H rear side
  1655. *
  1656. * 3-stack
  1657. * Port-A front headphone
  1658. * B front mic
  1659. * C rear line-in/surround
  1660. * D rear front-out
  1661. * E rear mic-in/CLFE
  1662. *
  1663. * laptop
  1664. * Port-A headphone
  1665. * B mic-in
  1666. * C docking station
  1667. * D internal speaker (with EAPD)
  1668. * E/F quad mic array
  1669. */
  1670. /* models */
  1671. enum {
  1672. AD1988_6STACK,
  1673. AD1988_6STACK_DIG,
  1674. AD1988_3STACK,
  1675. AD1988_3STACK_DIG,
  1676. AD1988_LAPTOP,
  1677. AD1988_LAPTOP_DIG,
  1678. AD1988_AUTO,
  1679. AD1988_MODEL_LAST,
  1680. };
  1681. /* reivision id to check workarounds */
  1682. #define AD1988A_REV2 0x100200
  1683. #define is_rev2(codec) \
  1684. ((codec)->vendor_id == 0x11d41988 && \
  1685. (codec)->revision_id == AD1988A_REV2)
  1686. /*
  1687. * mixers
  1688. */
  1689. static hda_nid_t ad1988_6stack_dac_nids[4] = {
  1690. 0x04, 0x06, 0x05, 0x0a
  1691. };
  1692. static hda_nid_t ad1988_3stack_dac_nids[3] = {
  1693. 0x04, 0x05, 0x0a
  1694. };
  1695. /* for AD1988A revision-2, DAC2-4 are swapped */
  1696. static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
  1697. 0x04, 0x05, 0x0a, 0x06
  1698. };
  1699. static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
  1700. 0x04, 0x0a, 0x06
  1701. };
  1702. static hda_nid_t ad1988_adc_nids[3] = {
  1703. 0x08, 0x09, 0x0f
  1704. };
  1705. static hda_nid_t ad1988_capsrc_nids[3] = {
  1706. 0x0c, 0x0d, 0x0e
  1707. };
  1708. #define AD1988_SPDIF_OUT 0x02
  1709. #define AD1988_SPDIF_OUT_HDMI 0x0b
  1710. #define AD1988_SPDIF_IN 0x07
  1711. static hda_nid_t ad1989b_slave_dig_outs[] = {
  1712. AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
  1713. };
  1714. static struct hda_input_mux ad1988_6stack_capture_source = {
  1715. .num_items = 5,
  1716. .items = {
  1717. { "Front Mic", 0x1 }, /* port-B */
  1718. { "Line", 0x2 }, /* port-C */
  1719. { "Mic", 0x4 }, /* port-E */
  1720. { "CD", 0x5 },
  1721. { "Mix", 0x9 },
  1722. },
  1723. };
  1724. static struct hda_input_mux ad1988_laptop_capture_source = {
  1725. .num_items = 3,
  1726. .items = {
  1727. { "Mic/Line", 0x1 }, /* port-B */
  1728. { "CD", 0x5 },
  1729. { "Mix", 0x9 },
  1730. },
  1731. };
  1732. /*
  1733. */
  1734. static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
  1735. struct snd_ctl_elem_info *uinfo)
  1736. {
  1737. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1738. struct ad198x_spec *spec = codec->spec;
  1739. return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
  1740. spec->num_channel_mode);
  1741. }
  1742. static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
  1743. struct snd_ctl_elem_value *ucontrol)
  1744. {
  1745. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1746. struct ad198x_spec *spec = codec->spec;
  1747. return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
  1748. spec->num_channel_mode, spec->multiout.max_channels);
  1749. }
  1750. static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
  1751. struct snd_ctl_elem_value *ucontrol)
  1752. {
  1753. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1754. struct ad198x_spec *spec = codec->spec;
  1755. int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
  1756. spec->num_channel_mode,
  1757. &spec->multiout.max_channels);
  1758. if (err >= 0 && spec->need_dac_fix)
  1759. spec->multiout.num_dacs = spec->multiout.max_channels / 2;
  1760. return err;
  1761. }
  1762. /* 6-stack mode */
  1763. static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
  1764. HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  1765. HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  1766. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
  1767. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
  1768. HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
  1769. { } /* end */
  1770. };
  1771. static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
  1772. HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  1773. HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  1774. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  1775. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
  1776. HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
  1777. { } /* end */
  1778. };
  1779. static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
  1780. HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
  1781. HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
  1782. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
  1783. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
  1784. HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
  1785. HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
  1786. HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
  1787. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
  1788. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
  1789. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
  1790. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
  1791. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
  1792. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
  1793. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
  1794. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
  1795. HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
  1796. HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  1797. HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  1798. HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  1799. HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
  1800. HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
  1801. { } /* end */
  1802. };
  1803. /* 3-stack mode */
  1804. static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
  1805. HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  1806. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
  1807. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
  1808. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
  1809. { } /* end */
  1810. };
  1811. static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
  1812. HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  1813. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
  1814. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
  1815. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
  1816. { } /* end */
  1817. };
  1818. static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
  1819. HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
  1820. HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
  1821. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
  1822. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
  1823. HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
  1824. HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
  1825. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
  1826. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
  1827. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
  1828. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
  1829. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
  1830. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
  1831. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
  1832. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
  1833. HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
  1834. HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  1835. HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  1836. HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  1837. HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
  1838. HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
  1839. {
  1840. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1841. .name = "Channel Mode",
  1842. .info = ad198x_ch_mode_info,
  1843. .get = ad198x_ch_mode_get,
  1844. .put = ad198x_ch_mode_put,
  1845. },
  1846. { } /* end */
  1847. };
  1848. /* laptop mode */
  1849. static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
  1850. HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  1851. HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
  1852. HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
  1853. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
  1854. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
  1855. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
  1856. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
  1857. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
  1858. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
  1859. HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
  1860. HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  1861. HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  1862. HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  1863. HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
  1864. {
  1865. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1866. .name = "External Amplifier",
  1867. .info = ad198x_eapd_info,
  1868. .get = ad198x_eapd_get,
  1869. .put = ad198x_eapd_put,
  1870. .private_value = 0x12 | (1 << 8), /* port-D, inversed */
  1871. },
  1872. { } /* end */
  1873. };
  1874. /* capture */
  1875. static struct snd_kcontrol_new ad1988_capture_mixers[] = {
  1876. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  1877. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  1878. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  1879. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  1880. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
  1881. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
  1882. {
  1883. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1884. /* The multiple "Capture Source" controls confuse alsamixer
  1885. * So call somewhat different..
  1886. */
  1887. /* .name = "Capture Source", */
  1888. .name = "Input Source",
  1889. .count = 3,
  1890. .info = ad198x_mux_enum_info,
  1891. .get = ad198x_mux_enum_get,
  1892. .put = ad198x_mux_enum_put,
  1893. },
  1894. { } /* end */
  1895. };
  1896. static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
  1897. struct snd_ctl_elem_info *uinfo)
  1898. {
  1899. static char *texts[] = {
  1900. "PCM", "ADC1", "ADC2", "ADC3"
  1901. };
  1902. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1903. uinfo->count = 1;
  1904. uinfo->value.enumerated.items = 4;
  1905. if (uinfo->value.enumerated.item >= 4)
  1906. uinfo->value.enumerated.item = 3;
  1907. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  1908. return 0;
  1909. }
  1910. static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
  1911. struct snd_ctl_elem_value *ucontrol)
  1912. {
  1913. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1914. unsigned int sel;
  1915. sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
  1916. AC_AMP_GET_INPUT);
  1917. if (!(sel & 0x80))
  1918. ucontrol->value.enumerated.item[0] = 0;
  1919. else {
  1920. sel = snd_hda_codec_read(codec, 0x0b, 0,
  1921. AC_VERB_GET_CONNECT_SEL, 0);
  1922. if (sel < 3)
  1923. sel++;
  1924. else
  1925. sel = 0;
  1926. ucontrol->value.enumerated.item[0] = sel;
  1927. }
  1928. return 0;
  1929. }
  1930. static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
  1931. struct snd_ctl_elem_value *ucontrol)
  1932. {
  1933. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1934. unsigned int val, sel;
  1935. int change;
  1936. val = ucontrol->value.enumerated.item[0];
  1937. if (val > 3)
  1938. return -EINVAL;
  1939. if (!val) {
  1940. sel = snd_hda_codec_read(codec, 0x1d, 0,
  1941. AC_VERB_GET_AMP_GAIN_MUTE,
  1942. AC_AMP_GET_INPUT);
  1943. change = sel & 0x80;
  1944. if (change) {
  1945. snd_hda_codec_write_cache(codec, 0x1d, 0,
  1946. AC_VERB_SET_AMP_GAIN_MUTE,
  1947. AMP_IN_UNMUTE(0));
  1948. snd_hda_codec_write_cache(codec, 0x1d, 0,
  1949. AC_VERB_SET_AMP_GAIN_MUTE,
  1950. AMP_IN_MUTE(1));
  1951. }
  1952. } else {
  1953. sel = snd_hda_codec_read(codec, 0x1d, 0,
  1954. AC_VERB_GET_AMP_GAIN_MUTE,
  1955. AC_AMP_GET_INPUT | 0x01);
  1956. change = sel & 0x80;
  1957. if (change) {
  1958. snd_hda_codec_write_cache(codec, 0x1d, 0,
  1959. AC_VERB_SET_AMP_GAIN_MUTE,
  1960. AMP_IN_MUTE(0));
  1961. snd_hda_codec_write_cache(codec, 0x1d, 0,
  1962. AC_VERB_SET_AMP_GAIN_MUTE,
  1963. AMP_IN_UNMUTE(1));
  1964. }
  1965. sel = snd_hda_codec_read(codec, 0x0b, 0,
  1966. AC_VERB_GET_CONNECT_SEL, 0) + 1;
  1967. change |= sel != val;
  1968. if (change)
  1969. snd_hda_codec_write_cache(codec, 0x0b, 0,
  1970. AC_VERB_SET_CONNECT_SEL,
  1971. val - 1);
  1972. }
  1973. return change;
  1974. }
  1975. static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
  1976. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  1977. {
  1978. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1979. .name = "IEC958 Playback Source",
  1980. .info = ad1988_spdif_playback_source_info,
  1981. .get = ad1988_spdif_playback_source_get,
  1982. .put = ad1988_spdif_playback_source_put,
  1983. },
  1984. { } /* end */
  1985. };
  1986. static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
  1987. HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
  1988. { } /* end */
  1989. };
  1990. static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
  1991. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  1992. HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
  1993. { } /* end */
  1994. };
  1995. /*
  1996. * initialization verbs
  1997. */
  1998. /*
  1999. * for 6-stack (+dig)
  2000. */
  2001. static struct hda_verb ad1988_6stack_init_verbs[] = {
  2002. /* Front, Surround, CLFE, side DAC; unmute as default */
  2003. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2004. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2005. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2006. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2007. /* Port-A front headphon path */
  2008. {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
  2009. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2010. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2011. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2012. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2013. /* Port-D line-out path */
  2014. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2015. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2016. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2017. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2018. /* Port-F surround path */
  2019. {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2020. {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2021. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2022. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2023. /* Port-G CLFE path */
  2024. {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2025. {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2026. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2027. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2028. /* Port-H side path */
  2029. {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2030. {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2031. {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2032. {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2033. /* Mono out path */
  2034. {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
  2035. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2036. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2037. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2038. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
  2039. /* Port-B front mic-in path */
  2040. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2041. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2042. {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2043. /* Port-C line-in path */
  2044. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2045. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2046. {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2047. {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
  2048. /* Port-E mic-in path */
  2049. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2050. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2051. {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2052. {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
  2053. /* Analog CD Input */
  2054. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2055. /* Analog Mix output amp */
  2056. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
  2057. { }
  2058. };
  2059. static struct hda_verb ad1988_capture_init_verbs[] = {
  2060. /* mute analog mix */
  2061. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2062. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2063. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2064. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2065. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2066. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  2067. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  2068. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  2069. /* select ADCs - front-mic */
  2070. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
  2071. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
  2072. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
  2073. /* ADCs; muted */
  2074. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2075. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2076. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2077. { }
  2078. };
  2079. static struct hda_verb ad1988_spdif_init_verbs[] = {
  2080. /* SPDIF out sel */
  2081. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
  2082. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
  2083. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2084. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2085. /* SPDIF out pin */
  2086. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  2087. { }
  2088. };
  2089. /* AD1989 has no ADC -> SPDIF route */
  2090. static struct hda_verb ad1989_spdif_init_verbs[] = {
  2091. /* SPDIF-1 out pin */
  2092. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  2093. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  2094. /* SPDIF-2/HDMI out pin */
  2095. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  2096. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  2097. { }
  2098. };
  2099. /*
  2100. * verbs for 3stack (+dig)
  2101. */
  2102. static struct hda_verb ad1988_3stack_ch2_init[] = {
  2103. /* set port-C to line-in */
  2104. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  2105. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  2106. /* set port-E to mic-in */
  2107. { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  2108. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  2109. { } /* end */
  2110. };
  2111. static struct hda_verb ad1988_3stack_ch6_init[] = {
  2112. /* set port-C to surround out */
  2113. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  2114. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  2115. /* set port-E to CLFE out */
  2116. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  2117. { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  2118. { } /* end */
  2119. };
  2120. static struct hda_channel_mode ad1988_3stack_modes[2] = {
  2121. { 2, ad1988_3stack_ch2_init },
  2122. { 6, ad1988_3stack_ch6_init },
  2123. };
  2124. static struct hda_verb ad1988_3stack_init_verbs[] = {
  2125. /* Front, Surround, CLFE, side DAC; unmute as default */
  2126. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2127. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2128. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2129. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2130. /* Port-A front headphon path */
  2131. {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
  2132. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2133. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2134. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2135. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2136. /* Port-D line-out path */
  2137. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2138. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2139. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2140. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2141. /* Mono out path */
  2142. {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
  2143. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2144. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2145. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2146. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
  2147. /* Port-B front mic-in path */
  2148. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2149. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2150. {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2151. /* Port-C line-in/surround path - 6ch mode as default */
  2152. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2153. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2154. {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2155. {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
  2156. {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
  2157. /* Port-E mic-in/CLFE path - 6ch mode as default */
  2158. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2159. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2160. {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2161. {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
  2162. {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
  2163. /* mute analog mix */
  2164. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2165. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2166. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2167. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2168. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2169. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  2170. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  2171. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  2172. /* select ADCs - front-mic */
  2173. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
  2174. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
  2175. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
  2176. /* ADCs; muted */
  2177. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2178. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2179. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2180. /* Analog Mix output amp */
  2181. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
  2182. { }
  2183. };
  2184. /*
  2185. * verbs for laptop mode (+dig)
  2186. */
  2187. static struct hda_verb ad1988_laptop_hp_on[] = {
  2188. /* unmute port-A and mute port-D */
  2189. { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  2190. { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  2191. { } /* end */
  2192. };
  2193. static struct hda_verb ad1988_laptop_hp_off[] = {
  2194. /* mute port-A and unmute port-D */
  2195. { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  2196. { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  2197. { } /* end */
  2198. };
  2199. #define AD1988_HP_EVENT 0x01
  2200. static struct hda_verb ad1988_laptop_init_verbs[] = {
  2201. /* Front, Surround, CLFE, side DAC; unmute as default */
  2202. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2203. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2204. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2205. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2206. /* Port-A front headphon path */
  2207. {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
  2208. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2209. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2210. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2211. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2212. /* unsolicited event for pin-sense */
  2213. {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
  2214. /* Port-D line-out path + EAPD */
  2215. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2216. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2217. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2218. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2219. {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
  2220. /* Mono out path */
  2221. {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
  2222. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2223. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2224. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2225. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
  2226. /* Port-B mic-in path */
  2227. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2228. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2229. {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2230. /* Port-C docking station - try to output */
  2231. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2232. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2233. {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2234. {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
  2235. /* mute analog mix */
  2236. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2237. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2238. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2239. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2240. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2241. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  2242. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  2243. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  2244. /* select ADCs - mic */
  2245. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
  2246. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
  2247. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
  2248. /* ADCs; muted */
  2249. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2250. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2251. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2252. /* Analog Mix output amp */
  2253. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
  2254. { }
  2255. };
  2256. static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
  2257. {
  2258. if ((res >> 26) != AD1988_HP_EVENT)
  2259. return;
  2260. if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
  2261. snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
  2262. else
  2263. snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
  2264. }
  2265. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2266. static struct hda_amp_list ad1988_loopbacks[] = {
  2267. { 0x20, HDA_INPUT, 0 }, /* Front Mic */
  2268. { 0x20, HDA_INPUT, 1 }, /* Line */
  2269. { 0x20, HDA_INPUT, 4 }, /* Mic */
  2270. { 0x20, HDA_INPUT, 6 }, /* CD */
  2271. { } /* end */
  2272. };
  2273. #endif
  2274. /*
  2275. * Automatic parse of I/O pins from the BIOS configuration
  2276. */
  2277. enum {
  2278. AD_CTL_WIDGET_VOL,
  2279. AD_CTL_WIDGET_MUTE,
  2280. AD_CTL_BIND_MUTE,
  2281. };
  2282. static struct snd_kcontrol_new ad1988_control_templates[] = {
  2283. HDA_CODEC_VOLUME(NULL, 0, 0, 0),
  2284. HDA_CODEC_MUTE(NULL, 0, 0, 0),
  2285. HDA_BIND_MUTE(NULL, 0, 0, 0),
  2286. };
  2287. /* add dynamic controls */
  2288. static int add_control(struct ad198x_spec *spec, int type, const char *name,
  2289. unsigned long val)
  2290. {
  2291. struct snd_kcontrol_new *knew;
  2292. snd_array_init(&spec->kctls, sizeof(*knew), 32);
  2293. knew = snd_array_new(&spec->kctls);
  2294. if (!knew)
  2295. return -ENOMEM;
  2296. *knew = ad1988_control_templates[type];
  2297. knew->name = kstrdup(name, GFP_KERNEL);
  2298. if (! knew->name)
  2299. return -ENOMEM;
  2300. knew->private_value = val;
  2301. return 0;
  2302. }
  2303. #define AD1988_PIN_CD_NID 0x18
  2304. #define AD1988_PIN_BEEP_NID 0x10
  2305. static hda_nid_t ad1988_mixer_nids[8] = {
  2306. /* A B C D E F G H */
  2307. 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
  2308. };
  2309. static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
  2310. {
  2311. static hda_nid_t idx_to_dac[8] = {
  2312. /* A B C D E F G H */
  2313. 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
  2314. };
  2315. static hda_nid_t idx_to_dac_rev2[8] = {
  2316. /* A B C D E F G H */
  2317. 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
  2318. };
  2319. if (is_rev2(codec))
  2320. return idx_to_dac_rev2[idx];
  2321. else
  2322. return idx_to_dac[idx];
  2323. }
  2324. static hda_nid_t ad1988_boost_nids[8] = {
  2325. 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
  2326. };
  2327. static int ad1988_pin_idx(hda_nid_t nid)
  2328. {
  2329. static hda_nid_t ad1988_io_pins[8] = {
  2330. 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
  2331. };
  2332. int i;
  2333. for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
  2334. if (ad1988_io_pins[i] == nid)
  2335. return i;
  2336. return 0; /* should be -1 */
  2337. }
  2338. static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
  2339. {
  2340. static int loopback_idx[8] = {
  2341. 2, 0, 1, 3, 4, 5, 1, 4
  2342. };
  2343. switch (nid) {
  2344. case AD1988_PIN_CD_NID:
  2345. return 6;
  2346. default:
  2347. return loopback_idx[ad1988_pin_idx(nid)];
  2348. }
  2349. }
  2350. static int ad1988_pin_to_adc_idx(hda_nid_t nid)
  2351. {
  2352. static int adc_idx[8] = {
  2353. 0, 1, 2, 8, 4, 3, 6, 7
  2354. };
  2355. switch (nid) {
  2356. case AD1988_PIN_CD_NID:
  2357. return 5;
  2358. default:
  2359. return adc_idx[ad1988_pin_idx(nid)];
  2360. }
  2361. }
  2362. /* fill in the dac_nids table from the parsed pin configuration */
  2363. static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
  2364. const struct auto_pin_cfg *cfg)
  2365. {
  2366. struct ad198x_spec *spec = codec->spec;
  2367. int i, idx;
  2368. spec->multiout.dac_nids = spec->private_dac_nids;
  2369. /* check the pins hardwired to audio widget */
  2370. for (i = 0; i < cfg->line_outs; i++) {
  2371. idx = ad1988_pin_idx(cfg->line_out_pins[i]);
  2372. spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
  2373. }
  2374. spec->multiout.num_dacs = cfg->line_outs;
  2375. return 0;
  2376. }
  2377. /* add playback controls from the parsed DAC table */
  2378. static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
  2379. const struct auto_pin_cfg *cfg)
  2380. {
  2381. char name[32];
  2382. static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
  2383. hda_nid_t nid;
  2384. int i, err;
  2385. for (i = 0; i < cfg->line_outs; i++) {
  2386. hda_nid_t dac = spec->multiout.dac_nids[i];
  2387. if (! dac)
  2388. continue;
  2389. nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
  2390. if (i == 2) {
  2391. /* Center/LFE */
  2392. err = add_control(spec, AD_CTL_WIDGET_VOL,
  2393. "Center Playback Volume",
  2394. HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
  2395. if (err < 0)
  2396. return err;
  2397. err = add_control(spec, AD_CTL_WIDGET_VOL,
  2398. "LFE Playback Volume",
  2399. HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
  2400. if (err < 0)
  2401. return err;
  2402. err = add_control(spec, AD_CTL_BIND_MUTE,
  2403. "Center Playback Switch",
  2404. HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
  2405. if (err < 0)
  2406. return err;
  2407. err = add_control(spec, AD_CTL_BIND_MUTE,
  2408. "LFE Playback Switch",
  2409. HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
  2410. if (err < 0)
  2411. return err;
  2412. } else {
  2413. sprintf(name, "%s Playback Volume", chname[i]);
  2414. err = add_control(spec, AD_CTL_WIDGET_VOL, name,
  2415. HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
  2416. if (err < 0)
  2417. return err;
  2418. sprintf(name, "%s Playback Switch", chname[i]);
  2419. err = add_control(spec, AD_CTL_BIND_MUTE, name,
  2420. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
  2421. if (err < 0)
  2422. return err;
  2423. }
  2424. }
  2425. return 0;
  2426. }
  2427. /* add playback controls for speaker and HP outputs */
  2428. static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
  2429. const char *pfx)
  2430. {
  2431. struct ad198x_spec *spec = codec->spec;
  2432. hda_nid_t nid;
  2433. int i, idx, err;
  2434. char name[32];
  2435. if (! pin)
  2436. return 0;
  2437. idx = ad1988_pin_idx(pin);
  2438. nid = ad1988_idx_to_dac(codec, idx);
  2439. /* check whether the corresponding DAC was already taken */
  2440. for (i = 0; i < spec->autocfg.line_outs; i++) {
  2441. hda_nid_t pin = spec->autocfg.line_out_pins[i];
  2442. hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
  2443. if (dac == nid)
  2444. break;
  2445. }
  2446. if (i >= spec->autocfg.line_outs) {
  2447. /* specify the DAC as the extra output */
  2448. if (!spec->multiout.hp_nid)
  2449. spec->multiout.hp_nid = nid;
  2450. else
  2451. spec->multiout.extra_out_nid[0] = nid;
  2452. /* control HP volume/switch on the output mixer amp */
  2453. sprintf(name, "%s Playback Volume", pfx);
  2454. err = add_control(spec, AD_CTL_WIDGET_VOL, name,
  2455. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  2456. if (err < 0)
  2457. return err;
  2458. }
  2459. nid = ad1988_mixer_nids[idx];
  2460. sprintf(name, "%s Playback Switch", pfx);
  2461. if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
  2462. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
  2463. return err;
  2464. return 0;
  2465. }
  2466. /* create input playback/capture controls for the given pin */
  2467. static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
  2468. const char *ctlname, int boost)
  2469. {
  2470. char name[32];
  2471. int err, idx;
  2472. sprintf(name, "%s Playback Volume", ctlname);
  2473. idx = ad1988_pin_to_loopback_idx(pin);
  2474. if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
  2475. HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
  2476. return err;
  2477. sprintf(name, "%s Playback Switch", ctlname);
  2478. if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
  2479. HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
  2480. return err;
  2481. if (boost) {
  2482. hda_nid_t bnid;
  2483. idx = ad1988_pin_idx(pin);
  2484. bnid = ad1988_boost_nids[idx];
  2485. if (bnid) {
  2486. sprintf(name, "%s Boost", ctlname);
  2487. return add_control(spec, AD_CTL_WIDGET_VOL, name,
  2488. HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
  2489. }
  2490. }
  2491. return 0;
  2492. }
  2493. /* create playback/capture controls for input pins */
  2494. static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
  2495. const struct auto_pin_cfg *cfg)
  2496. {
  2497. struct hda_input_mux *imux = &spec->private_imux;
  2498. int i, err;
  2499. for (i = 0; i < AUTO_PIN_LAST; i++) {
  2500. err = new_analog_input(spec, cfg->input_pins[i],
  2501. auto_pin_cfg_labels[i],
  2502. i <= AUTO_PIN_FRONT_MIC);
  2503. if (err < 0)
  2504. return err;
  2505. imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
  2506. imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
  2507. imux->num_items++;
  2508. }
  2509. imux->items[imux->num_items].label = "Mix";
  2510. imux->items[imux->num_items].index = 9;
  2511. imux->num_items++;
  2512. if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
  2513. "Analog Mix Playback Volume",
  2514. HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
  2515. return err;
  2516. if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
  2517. "Analog Mix Playback Switch",
  2518. HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
  2519. return err;
  2520. return 0;
  2521. }
  2522. static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
  2523. hda_nid_t nid, int pin_type,
  2524. int dac_idx)
  2525. {
  2526. /* set as output */
  2527. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
  2528. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
  2529. switch (nid) {
  2530. case 0x11: /* port-A - DAC 04 */
  2531. snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
  2532. break;
  2533. case 0x14: /* port-B - DAC 06 */
  2534. snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
  2535. break;
  2536. case 0x15: /* port-C - DAC 05 */
  2537. snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
  2538. break;
  2539. case 0x17: /* port-E - DAC 0a */
  2540. snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
  2541. break;
  2542. case 0x13: /* mono - DAC 04 */
  2543. snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
  2544. break;
  2545. }
  2546. }
  2547. static void ad1988_auto_init_multi_out(struct hda_codec *codec)
  2548. {
  2549. struct ad198x_spec *spec = codec->spec;
  2550. int i;
  2551. for (i = 0; i < spec->autocfg.line_outs; i++) {
  2552. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  2553. ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
  2554. }
  2555. }
  2556. static void ad1988_auto_init_extra_out(struct hda_codec *codec)
  2557. {
  2558. struct ad198x_spec *spec = codec->spec;
  2559. hda_nid_t pin;
  2560. pin = spec->autocfg.speaker_pins[0];
  2561. if (pin) /* connect to front */
  2562. ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  2563. pin = spec->autocfg.hp_pins[0];
  2564. if (pin) /* connect to front */
  2565. ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  2566. }
  2567. static void ad1988_auto_init_analog_input(struct hda_codec *codec)
  2568. {
  2569. struct ad198x_spec *spec = codec->spec;
  2570. int i, idx;
  2571. for (i = 0; i < AUTO_PIN_LAST; i++) {
  2572. hda_nid_t nid = spec->autocfg.input_pins[i];
  2573. if (! nid)
  2574. continue;
  2575. switch (nid) {
  2576. case 0x15: /* port-C */
  2577. snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
  2578. break;
  2579. case 0x17: /* port-E */
  2580. snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
  2581. break;
  2582. }
  2583. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  2584. i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
  2585. if (nid != AD1988_PIN_CD_NID)
  2586. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  2587. AMP_OUT_MUTE);
  2588. idx = ad1988_pin_idx(nid);
  2589. if (ad1988_boost_nids[idx])
  2590. snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
  2591. AC_VERB_SET_AMP_GAIN_MUTE,
  2592. AMP_OUT_ZERO);
  2593. }
  2594. }
  2595. /* parse the BIOS configuration and set up the alc_spec */
  2596. /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
  2597. static int ad1988_parse_auto_config(struct hda_codec *codec)
  2598. {
  2599. struct ad198x_spec *spec = codec->spec;
  2600. int err;
  2601. if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
  2602. return err;
  2603. if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
  2604. return err;
  2605. if (! spec->autocfg.line_outs)
  2606. return 0; /* can't find valid BIOS pin config */
  2607. if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
  2608. (err = ad1988_auto_create_extra_out(codec,
  2609. spec->autocfg.speaker_pins[0],
  2610. "Speaker")) < 0 ||
  2611. (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
  2612. "Headphone")) < 0 ||
  2613. (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
  2614. return err;
  2615. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  2616. if (spec->autocfg.dig_out_pin)
  2617. spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
  2618. if (spec->autocfg.dig_in_pin)
  2619. spec->dig_in_nid = AD1988_SPDIF_IN;
  2620. if (spec->kctls.list)
  2621. spec->mixers[spec->num_mixers++] = spec->kctls.list;
  2622. spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
  2623. spec->input_mux = &spec->private_imux;
  2624. return 1;
  2625. }
  2626. /* init callback for auto-configuration model -- overriding the default init */
  2627. static int ad1988_auto_init(struct hda_codec *codec)
  2628. {
  2629. ad198x_init(codec);
  2630. ad1988_auto_init_multi_out(codec);
  2631. ad1988_auto_init_extra_out(codec);
  2632. ad1988_auto_init_analog_input(codec);
  2633. return 0;
  2634. }
  2635. /*
  2636. */
  2637. static const char *ad1988_models[AD1988_MODEL_LAST] = {
  2638. [AD1988_6STACK] = "6stack",
  2639. [AD1988_6STACK_DIG] = "6stack-dig",
  2640. [AD1988_3STACK] = "3stack",
  2641. [AD1988_3STACK_DIG] = "3stack-dig",
  2642. [AD1988_LAPTOP] = "laptop",
  2643. [AD1988_LAPTOP_DIG] = "laptop-dig",
  2644. [AD1988_AUTO] = "auto",
  2645. };
  2646. static struct snd_pci_quirk ad1988_cfg_tbl[] = {
  2647. SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
  2648. SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
  2649. SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
  2650. SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
  2651. {}
  2652. };
  2653. static int patch_ad1988(struct hda_codec *codec)
  2654. {
  2655. struct ad198x_spec *spec;
  2656. int board_config;
  2657. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  2658. if (spec == NULL)
  2659. return -ENOMEM;
  2660. codec->spec = spec;
  2661. if (is_rev2(codec))
  2662. snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
  2663. board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
  2664. ad1988_models, ad1988_cfg_tbl);
  2665. if (board_config < 0) {
  2666. printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
  2667. board_config = AD1988_AUTO;
  2668. }
  2669. if (board_config == AD1988_AUTO) {
  2670. /* automatic parse from the BIOS config */
  2671. int err = ad1988_parse_auto_config(codec);
  2672. if (err < 0) {
  2673. ad198x_free(codec);
  2674. return err;
  2675. } else if (! err) {
  2676. printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n");
  2677. board_config = AD1988_6STACK;
  2678. }
  2679. }
  2680. switch (board_config) {
  2681. case AD1988_6STACK:
  2682. case AD1988_6STACK_DIG:
  2683. spec->multiout.max_channels = 8;
  2684. spec->multiout.num_dacs = 4;
  2685. if (is_rev2(codec))
  2686. spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
  2687. else
  2688. spec->multiout.dac_nids = ad1988_6stack_dac_nids;
  2689. spec->input_mux = &ad1988_6stack_capture_source;
  2690. spec->num_mixers = 2;
  2691. if (is_rev2(codec))
  2692. spec->mixers[0] = ad1988_6stack_mixers1_rev2;
  2693. else
  2694. spec->mixers[0] = ad1988_6stack_mixers1;
  2695. spec->mixers[1] = ad1988_6stack_mixers2;
  2696. spec->num_init_verbs = 1;
  2697. spec->init_verbs[0] = ad1988_6stack_init_verbs;
  2698. if (board_config == AD1988_6STACK_DIG) {
  2699. spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
  2700. spec->dig_in_nid = AD1988_SPDIF_IN;
  2701. }
  2702. break;
  2703. case AD1988_3STACK:
  2704. case AD1988_3STACK_DIG:
  2705. spec->multiout.max_channels = 6;
  2706. spec->multiout.num_dacs = 3;
  2707. if (is_rev2(codec))
  2708. spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
  2709. else
  2710. spec->multiout.dac_nids = ad1988_3stack_dac_nids;
  2711. spec->input_mux = &ad1988_6stack_capture_source;
  2712. spec->channel_mode = ad1988_3stack_modes;
  2713. spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
  2714. spec->num_mixers = 2;
  2715. if (is_rev2(codec))
  2716. spec->mixers[0] = ad1988_3stack_mixers1_rev2;
  2717. else
  2718. spec->mixers[0] = ad1988_3stack_mixers1;
  2719. spec->mixers[1] = ad1988_3stack_mixers2;
  2720. spec->num_init_verbs = 1;
  2721. spec->init_verbs[0] = ad1988_3stack_init_verbs;
  2722. if (board_config == AD1988_3STACK_DIG)
  2723. spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
  2724. break;
  2725. case AD1988_LAPTOP:
  2726. case AD1988_LAPTOP_DIG:
  2727. spec->multiout.max_channels = 2;
  2728. spec->multiout.num_dacs = 1;
  2729. spec->multiout.dac_nids = ad1988_3stack_dac_nids;
  2730. spec->input_mux = &ad1988_laptop_capture_source;
  2731. spec->num_mixers = 1;
  2732. spec->mixers[0] = ad1988_laptop_mixers;
  2733. spec->num_init_verbs = 1;
  2734. spec->init_verbs[0] = ad1988_laptop_init_verbs;
  2735. if (board_config == AD1988_LAPTOP_DIG)
  2736. spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
  2737. break;
  2738. }
  2739. spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
  2740. spec->adc_nids = ad1988_adc_nids;
  2741. spec->capsrc_nids = ad1988_capsrc_nids;
  2742. spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
  2743. spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
  2744. if (spec->multiout.dig_out_nid) {
  2745. if (codec->vendor_id >= 0x11d4989a) {
  2746. spec->mixers[spec->num_mixers++] =
  2747. ad1989_spdif_out_mixers;
  2748. spec->init_verbs[spec->num_init_verbs++] =
  2749. ad1989_spdif_init_verbs;
  2750. codec->slave_dig_outs = ad1989b_slave_dig_outs;
  2751. } else {
  2752. spec->mixers[spec->num_mixers++] =
  2753. ad1988_spdif_out_mixers;
  2754. spec->init_verbs[spec->num_init_verbs++] =
  2755. ad1988_spdif_init_verbs;
  2756. }
  2757. }
  2758. if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a)
  2759. spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
  2760. codec->patch_ops = ad198x_patch_ops;
  2761. switch (board_config) {
  2762. case AD1988_AUTO:
  2763. codec->patch_ops.init = ad1988_auto_init;
  2764. break;
  2765. case AD1988_LAPTOP:
  2766. case AD1988_LAPTOP_DIG:
  2767. codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
  2768. break;
  2769. }
  2770. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2771. spec->loopback.amplist = ad1988_loopbacks;
  2772. #endif
  2773. spec->vmaster_nid = 0x04;
  2774. return 0;
  2775. }
  2776. /*
  2777. * AD1884 / AD1984
  2778. *
  2779. * port-B - front line/mic-in
  2780. * port-E - aux in/out
  2781. * port-F - aux in/out
  2782. * port-C - rear line/mic-in
  2783. * port-D - rear line/hp-out
  2784. * port-A - front line/hp-out
  2785. *
  2786. * AD1984 = AD1884 + two digital mic-ins
  2787. *
  2788. * FIXME:
  2789. * For simplicity, we share the single DAC for both HP and line-outs
  2790. * right now. The inidividual playbacks could be easily implemented,
  2791. * but no build-up framework is given, so far.
  2792. */
  2793. static hda_nid_t ad1884_dac_nids[1] = {
  2794. 0x04,
  2795. };
  2796. static hda_nid_t ad1884_adc_nids[2] = {
  2797. 0x08, 0x09,
  2798. };
  2799. static hda_nid_t ad1884_capsrc_nids[2] = {
  2800. 0x0c, 0x0d,
  2801. };
  2802. #define AD1884_SPDIF_OUT 0x02
  2803. static struct hda_input_mux ad1884_capture_source = {
  2804. .num_items = 4,
  2805. .items = {
  2806. { "Front Mic", 0x0 },
  2807. { "Mic", 0x1 },
  2808. { "CD", 0x2 },
  2809. { "Mix", 0x3 },
  2810. },
  2811. };
  2812. static struct snd_kcontrol_new ad1884_base_mixers[] = {
  2813. HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  2814. /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
  2815. HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  2816. HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  2817. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
  2818. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
  2819. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  2820. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  2821. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
  2822. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
  2823. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
  2824. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
  2825. /*
  2826. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
  2827. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
  2828. HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
  2829. HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  2830. */
  2831. HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
  2832. HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
  2833. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  2834. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  2835. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  2836. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  2837. {
  2838. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  2839. /* The multiple "Capture Source" controls confuse alsamixer
  2840. * So call somewhat different..
  2841. */
  2842. /* .name = "Capture Source", */
  2843. .name = "Input Source",
  2844. .count = 2,
  2845. .info = ad198x_mux_enum_info,
  2846. .get = ad198x_mux_enum_get,
  2847. .put = ad198x_mux_enum_put,
  2848. },
  2849. /* SPDIF controls */
  2850. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  2851. {
  2852. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  2853. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  2854. /* identical with ad1983 */
  2855. .info = ad1983_spdif_route_info,
  2856. .get = ad1983_spdif_route_get,
  2857. .put = ad1983_spdif_route_put,
  2858. },
  2859. { } /* end */
  2860. };
  2861. static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
  2862. HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
  2863. HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
  2864. HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
  2865. HDA_INPUT),
  2866. HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
  2867. HDA_INPUT),
  2868. { } /* end */
  2869. };
  2870. /*
  2871. * initialization verbs
  2872. */
  2873. static struct hda_verb ad1884_init_verbs[] = {
  2874. /* DACs; mute as default */
  2875. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2876. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2877. /* Port-A (HP) mixer */
  2878. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2879. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2880. /* Port-A pin */
  2881. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2882. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2883. /* HP selector - select DAC2 */
  2884. {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
  2885. /* Port-D (Line-out) mixer */
  2886. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2887. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2888. /* Port-D pin */
  2889. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2890. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2891. /* Mono-out mixer */
  2892. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2893. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2894. /* Mono-out pin */
  2895. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2896. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2897. /* Mono selector */
  2898. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
  2899. /* Port-B (front mic) pin */
  2900. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2901. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2902. /* Port-C (rear mic) pin */
  2903. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2904. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2905. /* Analog mixer; mute as default */
  2906. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2907. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2908. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2909. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2910. /* Analog Mix output amp */
  2911. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
  2912. /* SPDIF output selector */
  2913. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
  2914. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  2915. { } /* end */
  2916. };
  2917. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2918. static struct hda_amp_list ad1884_loopbacks[] = {
  2919. { 0x20, HDA_INPUT, 0 }, /* Front Mic */
  2920. { 0x20, HDA_INPUT, 1 }, /* Mic */
  2921. { 0x20, HDA_INPUT, 2 }, /* CD */
  2922. { 0x20, HDA_INPUT, 4 }, /* Docking */
  2923. { } /* end */
  2924. };
  2925. #endif
  2926. static const char *ad1884_slave_vols[] = {
  2927. "PCM Playback Volume",
  2928. "Mic Playback Volume",
  2929. "Mono Playback Volume",
  2930. "Front Mic Playback Volume",
  2931. "Mic Playback Volume",
  2932. "CD Playback Volume",
  2933. "Internal Mic Playback Volume",
  2934. "Docking Mic Playback Volume"
  2935. "Beep Playback Volume",
  2936. "IEC958 Playback Volume",
  2937. NULL
  2938. };
  2939. static int patch_ad1884(struct hda_codec *codec)
  2940. {
  2941. struct ad198x_spec *spec;
  2942. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  2943. if (spec == NULL)
  2944. return -ENOMEM;
  2945. codec->spec = spec;
  2946. spec->multiout.max_channels = 2;
  2947. spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
  2948. spec->multiout.dac_nids = ad1884_dac_nids;
  2949. spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
  2950. spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
  2951. spec->adc_nids = ad1884_adc_nids;
  2952. spec->capsrc_nids = ad1884_capsrc_nids;
  2953. spec->input_mux = &ad1884_capture_source;
  2954. spec->num_mixers = 1;
  2955. spec->mixers[0] = ad1884_base_mixers;
  2956. spec->num_init_verbs = 1;
  2957. spec->init_verbs[0] = ad1884_init_verbs;
  2958. spec->spdif_route = 0;
  2959. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2960. spec->loopback.amplist = ad1884_loopbacks;
  2961. #endif
  2962. spec->vmaster_nid = 0x04;
  2963. /* we need to cover all playback volumes */
  2964. spec->slave_vols = ad1884_slave_vols;
  2965. codec->patch_ops = ad198x_patch_ops;
  2966. return 0;
  2967. }
  2968. /*
  2969. * Lenovo Thinkpad T61/X61
  2970. */
  2971. static struct hda_input_mux ad1984_thinkpad_capture_source = {
  2972. .num_items = 4,
  2973. .items = {
  2974. { "Mic", 0x0 },
  2975. { "Internal Mic", 0x1 },
  2976. { "Mix", 0x3 },
  2977. { "Docking-Station", 0x4 },
  2978. },
  2979. };
  2980. /*
  2981. * Dell Precision T3400
  2982. */
  2983. static struct hda_input_mux ad1984_dell_desktop_capture_source = {
  2984. .num_items = 3,
  2985. .items = {
  2986. { "Front Mic", 0x0 },
  2987. { "Line-In", 0x1 },
  2988. { "Mix", 0x3 },
  2989. },
  2990. };
  2991. static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
  2992. HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  2993. /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
  2994. HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  2995. HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  2996. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  2997. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  2998. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
  2999. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
  3000. HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
  3001. HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
  3002. HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
  3003. HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
  3004. HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
  3005. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
  3006. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
  3007. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3008. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3009. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  3010. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  3011. {
  3012. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3013. /* The multiple "Capture Source" controls confuse alsamixer
  3014. * So call somewhat different..
  3015. */
  3016. /* .name = "Capture Source", */
  3017. .name = "Input Source",
  3018. .count = 2,
  3019. .info = ad198x_mux_enum_info,
  3020. .get = ad198x_mux_enum_get,
  3021. .put = ad198x_mux_enum_put,
  3022. },
  3023. /* SPDIF controls */
  3024. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  3025. {
  3026. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3027. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  3028. /* identical with ad1983 */
  3029. .info = ad1983_spdif_route_info,
  3030. .get = ad1983_spdif_route_get,
  3031. .put = ad1983_spdif_route_put,
  3032. },
  3033. { } /* end */
  3034. };
  3035. /* additional verbs */
  3036. static struct hda_verb ad1984_thinkpad_init_verbs[] = {
  3037. /* Port-E (docking station mic) pin */
  3038. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3039. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3040. /* docking mic boost */
  3041. {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3042. /* Analog mixer - docking mic; mute as default */
  3043. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3044. /* enable EAPD bit */
  3045. {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  3046. { } /* end */
  3047. };
  3048. /*
  3049. * Dell Precision T3400
  3050. */
  3051. static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
  3052. HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  3053. HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  3054. HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  3055. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
  3056. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
  3057. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3058. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3059. HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
  3060. HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
  3061. /*
  3062. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
  3063. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
  3064. */
  3065. HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
  3066. HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
  3067. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3068. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3069. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  3070. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  3071. {
  3072. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3073. /* The multiple "Capture Source" controls confuse alsamixer
  3074. * So call somewhat different..
  3075. */
  3076. /* .name = "Capture Source", */
  3077. .name = "Input Source",
  3078. .count = 2,
  3079. .info = ad198x_mux_enum_info,
  3080. .get = ad198x_mux_enum_get,
  3081. .put = ad198x_mux_enum_put,
  3082. },
  3083. { } /* end */
  3084. };
  3085. /* Digial MIC ADC NID 0x05 + 0x06 */
  3086. static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
  3087. struct hda_codec *codec,
  3088. unsigned int stream_tag,
  3089. unsigned int format,
  3090. struct snd_pcm_substream *substream)
  3091. {
  3092. snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
  3093. stream_tag, 0, format);
  3094. return 0;
  3095. }
  3096. static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
  3097. struct hda_codec *codec,
  3098. struct snd_pcm_substream *substream)
  3099. {
  3100. snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
  3101. return 0;
  3102. }
  3103. static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
  3104. .substreams = 2,
  3105. .channels_min = 2,
  3106. .channels_max = 2,
  3107. .nid = 0x05,
  3108. .ops = {
  3109. .prepare = ad1984_pcm_dmic_prepare,
  3110. .cleanup = ad1984_pcm_dmic_cleanup
  3111. },
  3112. };
  3113. static int ad1984_build_pcms(struct hda_codec *codec)
  3114. {
  3115. struct ad198x_spec *spec = codec->spec;
  3116. struct hda_pcm *info;
  3117. int err;
  3118. err = ad198x_build_pcms(codec);
  3119. if (err < 0)
  3120. return err;
  3121. info = spec->pcm_rec + codec->num_pcms;
  3122. codec->num_pcms++;
  3123. info->name = "AD1984 Digital Mic";
  3124. info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
  3125. return 0;
  3126. }
  3127. /* models */
  3128. enum {
  3129. AD1984_BASIC,
  3130. AD1984_THINKPAD,
  3131. AD1984_DELL_DESKTOP,
  3132. AD1984_MODELS
  3133. };
  3134. static const char *ad1984_models[AD1984_MODELS] = {
  3135. [AD1984_BASIC] = "basic",
  3136. [AD1984_THINKPAD] = "thinkpad",
  3137. [AD1984_DELL_DESKTOP] = "dell_desktop",
  3138. };
  3139. static struct snd_pci_quirk ad1984_cfg_tbl[] = {
  3140. /* Lenovo Thinkpad T61/X61 */
  3141. SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
  3142. SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
  3143. {}
  3144. };
  3145. static int patch_ad1984(struct hda_codec *codec)
  3146. {
  3147. struct ad198x_spec *spec;
  3148. int board_config, err;
  3149. err = patch_ad1884(codec);
  3150. if (err < 0)
  3151. return err;
  3152. spec = codec->spec;
  3153. board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
  3154. ad1984_models, ad1984_cfg_tbl);
  3155. switch (board_config) {
  3156. case AD1984_BASIC:
  3157. /* additional digital mics */
  3158. spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
  3159. codec->patch_ops.build_pcms = ad1984_build_pcms;
  3160. break;
  3161. case AD1984_THINKPAD:
  3162. spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
  3163. spec->input_mux = &ad1984_thinkpad_capture_source;
  3164. spec->mixers[0] = ad1984_thinkpad_mixers;
  3165. spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
  3166. break;
  3167. case AD1984_DELL_DESKTOP:
  3168. spec->multiout.dig_out_nid = 0;
  3169. spec->input_mux = &ad1984_dell_desktop_capture_source;
  3170. spec->mixers[0] = ad1984_dell_desktop_mixers;
  3171. break;
  3172. }
  3173. return 0;
  3174. }
  3175. /*
  3176. * AD1883 / AD1884A / AD1984A / AD1984B
  3177. *
  3178. * port-B (0x14) - front mic-in
  3179. * port-E (0x1c) - rear mic-in
  3180. * port-F (0x16) - CD / ext out
  3181. * port-C (0x15) - rear line-in
  3182. * port-D (0x12) - rear line-out
  3183. * port-A (0x11) - front hp-out
  3184. *
  3185. * AD1984A = AD1884A + digital-mic
  3186. * AD1883 = equivalent with AD1984A
  3187. * AD1984B = AD1984A + extra SPDIF-out
  3188. *
  3189. * FIXME:
  3190. * We share the single DAC for both HP and line-outs (see AD1884/1984).
  3191. */
  3192. static hda_nid_t ad1884a_dac_nids[1] = {
  3193. 0x03,
  3194. };
  3195. #define ad1884a_adc_nids ad1884_adc_nids
  3196. #define ad1884a_capsrc_nids ad1884_capsrc_nids
  3197. #define AD1884A_SPDIF_OUT 0x02
  3198. static struct hda_input_mux ad1884a_capture_source = {
  3199. .num_items = 5,
  3200. .items = {
  3201. { "Front Mic", 0x0 },
  3202. { "Mic", 0x4 },
  3203. { "Line", 0x1 },
  3204. { "CD", 0x2 },
  3205. { "Mix", 0x3 },
  3206. },
  3207. };
  3208. static struct snd_kcontrol_new ad1884a_base_mixers[] = {
  3209. HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  3210. HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  3211. HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  3212. HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  3213. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
  3214. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
  3215. HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
  3216. HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
  3217. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3218. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3219. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
  3220. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
  3221. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
  3222. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
  3223. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
  3224. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
  3225. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
  3226. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
  3227. HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
  3228. HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
  3229. HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
  3230. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3231. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3232. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  3233. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  3234. {
  3235. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3236. /* The multiple "Capture Source" controls confuse alsamixer
  3237. * So call somewhat different..
  3238. */
  3239. /* .name = "Capture Source", */
  3240. .name = "Input Source",
  3241. .count = 2,
  3242. .info = ad198x_mux_enum_info,
  3243. .get = ad198x_mux_enum_get,
  3244. .put = ad198x_mux_enum_put,
  3245. },
  3246. /* SPDIF controls */
  3247. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  3248. {
  3249. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3250. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  3251. /* identical with ad1983 */
  3252. .info = ad1983_spdif_route_info,
  3253. .get = ad1983_spdif_route_get,
  3254. .put = ad1983_spdif_route_put,
  3255. },
  3256. { } /* end */
  3257. };
  3258. /*
  3259. * initialization verbs
  3260. */
  3261. static struct hda_verb ad1884a_init_verbs[] = {
  3262. /* DACs; unmute as default */
  3263. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
  3264. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
  3265. /* Port-A (HP) mixer - route only from analog mixer */
  3266. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3267. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3268. /* Port-A pin */
  3269. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3270. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3271. /* Port-D (Line-out) mixer - route only from analog mixer */
  3272. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3273. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3274. /* Port-D pin */
  3275. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3276. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3277. /* Mono-out mixer - route only from analog mixer */
  3278. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3279. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3280. /* Mono-out pin */
  3281. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3282. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3283. /* Port-B (front mic) pin */
  3284. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3285. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3286. /* Port-C (rear line-in) pin */
  3287. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3288. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3289. /* Port-E (rear mic) pin */
  3290. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3291. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3292. {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
  3293. /* Port-F (CD) pin */
  3294. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3295. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3296. /* Analog mixer; mute as default */
  3297. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3298. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3299. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3300. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3301. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
  3302. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  3303. /* Analog Mix output amp */
  3304. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3305. /* capture sources */
  3306. {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
  3307. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3308. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
  3309. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3310. /* SPDIF output amp */
  3311. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  3312. { } /* end */
  3313. };
  3314. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3315. static struct hda_amp_list ad1884a_loopbacks[] = {
  3316. { 0x20, HDA_INPUT, 0 }, /* Front Mic */
  3317. { 0x20, HDA_INPUT, 1 }, /* Mic */
  3318. { 0x20, HDA_INPUT, 2 }, /* CD */
  3319. { 0x20, HDA_INPUT, 4 }, /* Docking */
  3320. { } /* end */
  3321. };
  3322. #endif
  3323. /*
  3324. * Laptop model
  3325. *
  3326. * Port A: Headphone jack
  3327. * Port B: MIC jack
  3328. * Port C: Internal MIC
  3329. * Port D: Dock Line Out (if enabled)
  3330. * Port E: Dock Line In (if enabled)
  3331. * Port F: Internal speakers
  3332. */
  3333. static struct hda_input_mux ad1884a_laptop_capture_source = {
  3334. .num_items = 4,
  3335. .items = {
  3336. { "Mic", 0x0 }, /* port-B */
  3337. { "Internal Mic", 0x1 }, /* port-C */
  3338. { "Dock Mic", 0x4 }, /* port-E */
  3339. { "Mix", 0x3 },
  3340. },
  3341. };
  3342. static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
  3343. HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  3344. HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  3345. HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  3346. HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
  3347. HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
  3348. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3349. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3350. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
  3351. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
  3352. HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
  3353. HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
  3354. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
  3355. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
  3356. HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
  3357. HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
  3358. HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
  3359. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3360. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3361. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  3362. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  3363. {
  3364. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3365. /* The multiple "Capture Source" controls confuse alsamixer
  3366. * So call somewhat different..
  3367. */
  3368. /* .name = "Capture Source", */
  3369. .name = "Input Source",
  3370. .count = 2,
  3371. .info = ad198x_mux_enum_info,
  3372. .get = ad198x_mux_enum_get,
  3373. .put = ad198x_mux_enum_put,
  3374. },
  3375. { } /* end */
  3376. };
  3377. static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
  3378. HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  3379. HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  3380. HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
  3381. HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
  3382. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
  3383. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
  3384. HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
  3385. HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
  3386. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3387. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3388. { } /* end */
  3389. };
  3390. /* mute internal speaker if HP is plugged */
  3391. static void ad1884a_hp_automute(struct hda_codec *codec)
  3392. {
  3393. unsigned int present;
  3394. present = snd_hda_codec_read(codec, 0x11, 0,
  3395. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  3396. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  3397. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  3398. snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
  3399. present ? 0x00 : 0x02);
  3400. }
  3401. /* switch to external mic if plugged */
  3402. static void ad1884a_hp_automic(struct hda_codec *codec)
  3403. {
  3404. unsigned int present;
  3405. present = snd_hda_codec_read(codec, 0x14, 0,
  3406. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  3407. snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
  3408. present ? 0 : 1);
  3409. }
  3410. #define AD1884A_HP_EVENT 0x37
  3411. #define AD1884A_MIC_EVENT 0x36
  3412. /* unsolicited event for HP jack sensing */
  3413. static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
  3414. {
  3415. switch (res >> 26) {
  3416. case AD1884A_HP_EVENT:
  3417. ad1884a_hp_automute(codec);
  3418. break;
  3419. case AD1884A_MIC_EVENT:
  3420. ad1884a_hp_automic(codec);
  3421. break;
  3422. }
  3423. }
  3424. /* initialize jack-sensing, too */
  3425. static int ad1884a_hp_init(struct hda_codec *codec)
  3426. {
  3427. ad198x_init(codec);
  3428. ad1884a_hp_automute(codec);
  3429. ad1884a_hp_automic(codec);
  3430. return 0;
  3431. }
  3432. /* additional verbs for laptop model */
  3433. static struct hda_verb ad1884a_laptop_verbs[] = {
  3434. /* Port-A (HP) pin - always unmuted */
  3435. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3436. /* Port-F (int speaker) mixer - route only from analog mixer */
  3437. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3438. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3439. /* Port-F pin */
  3440. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3441. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3442. /* Port-C pin - internal mic-in */
  3443. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3444. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
  3445. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
  3446. /* analog mix */
  3447. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3448. /* unsolicited event for pin-sense */
  3449. {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
  3450. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
  3451. { } /* end */
  3452. };
  3453. /*
  3454. * Thinkpad X300
  3455. * 0x11 - HP
  3456. * 0x12 - speaker
  3457. * 0x14 - mic-in
  3458. * 0x17 - built-in mic
  3459. */
  3460. static struct hda_verb ad1984a_thinkpad_verbs[] = {
  3461. /* HP unmute */
  3462. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3463. /* analog mix */
  3464. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3465. /* turn on EAPD */
  3466. {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  3467. /* unsolicited event for pin-sense */
  3468. {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
  3469. /* internal mic - dmic */
  3470. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3471. /* set magic COEFs for dmic */
  3472. {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
  3473. {0x01, AC_VERB_SET_PROC_COEF, 0x08},
  3474. { } /* end */
  3475. };
  3476. static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
  3477. HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
  3478. HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
  3479. HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
  3480. HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
  3481. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3482. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3483. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
  3484. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
  3485. HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
  3486. HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
  3487. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3488. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3489. {
  3490. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3491. .name = "Capture Source",
  3492. .info = ad198x_mux_enum_info,
  3493. .get = ad198x_mux_enum_get,
  3494. .put = ad198x_mux_enum_put,
  3495. },
  3496. { } /* end */
  3497. };
  3498. static struct hda_input_mux ad1984a_thinkpad_capture_source = {
  3499. .num_items = 3,
  3500. .items = {
  3501. { "Mic", 0x0 },
  3502. { "Internal Mic", 0x5 },
  3503. { "Mix", 0x3 },
  3504. },
  3505. };
  3506. /* mute internal speaker if HP is plugged */
  3507. static void ad1984a_thinkpad_automute(struct hda_codec *codec)
  3508. {
  3509. unsigned int present;
  3510. present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0)
  3511. & AC_PINSENSE_PRESENCE;
  3512. snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
  3513. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  3514. }
  3515. /* unsolicited event for HP jack sensing */
  3516. static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
  3517. unsigned int res)
  3518. {
  3519. if ((res >> 26) != AD1884A_HP_EVENT)
  3520. return;
  3521. ad1984a_thinkpad_automute(codec);
  3522. }
  3523. /* initialize jack-sensing, too */
  3524. static int ad1984a_thinkpad_init(struct hda_codec *codec)
  3525. {
  3526. ad198x_init(codec);
  3527. ad1984a_thinkpad_automute(codec);
  3528. return 0;
  3529. }
  3530. /*
  3531. */
  3532. enum {
  3533. AD1884A_DESKTOP,
  3534. AD1884A_LAPTOP,
  3535. AD1884A_MOBILE,
  3536. AD1884A_THINKPAD,
  3537. AD1884A_MODELS
  3538. };
  3539. static const char *ad1884a_models[AD1884A_MODELS] = {
  3540. [AD1884A_DESKTOP] = "desktop",
  3541. [AD1884A_LAPTOP] = "laptop",
  3542. [AD1884A_MOBILE] = "mobile",
  3543. [AD1884A_THINKPAD] = "thinkpad",
  3544. };
  3545. static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
  3546. SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
  3547. SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
  3548. SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
  3549. SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
  3550. SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
  3551. SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
  3552. SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
  3553. {}
  3554. };
  3555. static int patch_ad1884a(struct hda_codec *codec)
  3556. {
  3557. struct ad198x_spec *spec;
  3558. int board_config;
  3559. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  3560. if (spec == NULL)
  3561. return -ENOMEM;
  3562. codec->spec = spec;
  3563. spec->multiout.max_channels = 2;
  3564. spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
  3565. spec->multiout.dac_nids = ad1884a_dac_nids;
  3566. spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
  3567. spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
  3568. spec->adc_nids = ad1884a_adc_nids;
  3569. spec->capsrc_nids = ad1884a_capsrc_nids;
  3570. spec->input_mux = &ad1884a_capture_source;
  3571. spec->num_mixers = 1;
  3572. spec->mixers[0] = ad1884a_base_mixers;
  3573. spec->num_init_verbs = 1;
  3574. spec->init_verbs[0] = ad1884a_init_verbs;
  3575. spec->spdif_route = 0;
  3576. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3577. spec->loopback.amplist = ad1884a_loopbacks;
  3578. #endif
  3579. codec->patch_ops = ad198x_patch_ops;
  3580. /* override some parameters */
  3581. board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
  3582. ad1884a_models,
  3583. ad1884a_cfg_tbl);
  3584. switch (board_config) {
  3585. case AD1884A_LAPTOP:
  3586. spec->mixers[0] = ad1884a_laptop_mixers;
  3587. spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
  3588. spec->multiout.dig_out_nid = 0;
  3589. spec->input_mux = &ad1884a_laptop_capture_source;
  3590. codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
  3591. codec->patch_ops.init = ad1884a_hp_init;
  3592. break;
  3593. case AD1884A_MOBILE:
  3594. spec->mixers[0] = ad1884a_mobile_mixers;
  3595. spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
  3596. spec->multiout.dig_out_nid = 0;
  3597. codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
  3598. codec->patch_ops.init = ad1884a_hp_init;
  3599. break;
  3600. case AD1884A_THINKPAD:
  3601. spec->mixers[0] = ad1984a_thinkpad_mixers;
  3602. spec->init_verbs[spec->num_init_verbs++] =
  3603. ad1984a_thinkpad_verbs;
  3604. spec->multiout.dig_out_nid = 0;
  3605. spec->input_mux = &ad1984a_thinkpad_capture_source;
  3606. codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
  3607. codec->patch_ops.init = ad1984a_thinkpad_init;
  3608. break;
  3609. }
  3610. return 0;
  3611. }
  3612. /*
  3613. * AD1882 / AD1882A
  3614. *
  3615. * port-A - front hp-out
  3616. * port-B - front mic-in
  3617. * port-C - rear line-in, shared surr-out (3stack)
  3618. * port-D - rear line-out
  3619. * port-E - rear mic-in, shared clfe-out (3stack)
  3620. * port-F - rear surr-out (6stack)
  3621. * port-G - rear clfe-out (6stack)
  3622. */
  3623. static hda_nid_t ad1882_dac_nids[3] = {
  3624. 0x04, 0x03, 0x05
  3625. };
  3626. static hda_nid_t ad1882_adc_nids[2] = {
  3627. 0x08, 0x09,
  3628. };
  3629. static hda_nid_t ad1882_capsrc_nids[2] = {
  3630. 0x0c, 0x0d,
  3631. };
  3632. #define AD1882_SPDIF_OUT 0x02
  3633. /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
  3634. static struct hda_input_mux ad1882_capture_source = {
  3635. .num_items = 5,
  3636. .items = {
  3637. { "Front Mic", 0x1 },
  3638. { "Mic", 0x4 },
  3639. { "Line", 0x2 },
  3640. { "CD", 0x3 },
  3641. { "Mix", 0x7 },
  3642. },
  3643. };
  3644. /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
  3645. static struct hda_input_mux ad1882a_capture_source = {
  3646. .num_items = 5,
  3647. .items = {
  3648. { "Front Mic", 0x1 },
  3649. { "Mic", 0x4},
  3650. { "Line", 0x2 },
  3651. { "Digital Mic", 0x06 },
  3652. { "Mix", 0x7 },
  3653. },
  3654. };
  3655. static struct snd_kcontrol_new ad1882_base_mixers[] = {
  3656. HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
  3657. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  3658. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
  3659. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
  3660. HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
  3661. HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
  3662. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
  3663. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
  3664. HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
  3665. HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
  3666. HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
  3667. HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
  3668. HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
  3669. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
  3670. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
  3671. {
  3672. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3673. /* The multiple "Capture Source" controls confuse alsamixer
  3674. * So call somewhat different..
  3675. */
  3676. /* .name = "Capture Source", */
  3677. .name = "Input Source",
  3678. .count = 2,
  3679. .info = ad198x_mux_enum_info,
  3680. .get = ad198x_mux_enum_get,
  3681. .put = ad198x_mux_enum_put,
  3682. },
  3683. /* SPDIF controls */
  3684. HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
  3685. {
  3686. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3687. .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
  3688. /* identical with ad1983 */
  3689. .info = ad1983_spdif_route_info,
  3690. .get = ad1983_spdif_route_get,
  3691. .put = ad1983_spdif_route_put,
  3692. },
  3693. { } /* end */
  3694. };
  3695. static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
  3696. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3697. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3698. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
  3699. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
  3700. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
  3701. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
  3702. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
  3703. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
  3704. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
  3705. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
  3706. { } /* end */
  3707. };
  3708. static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
  3709. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
  3710. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
  3711. HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
  3712. HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
  3713. HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
  3714. HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
  3715. HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
  3716. HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
  3717. HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
  3718. HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
  3719. HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
  3720. { } /* end */
  3721. };
  3722. static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
  3723. HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  3724. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
  3725. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
  3726. {
  3727. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3728. .name = "Channel Mode",
  3729. .info = ad198x_ch_mode_info,
  3730. .get = ad198x_ch_mode_get,
  3731. .put = ad198x_ch_mode_put,
  3732. },
  3733. { } /* end */
  3734. };
  3735. static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
  3736. HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  3737. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
  3738. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
  3739. { } /* end */
  3740. };
  3741. static struct hda_verb ad1882_ch2_init[] = {
  3742. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3743. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3744. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3745. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3746. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3747. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3748. { } /* end */
  3749. };
  3750. static struct hda_verb ad1882_ch4_init[] = {
  3751. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3752. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3753. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3754. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3755. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3756. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3757. { } /* end */
  3758. };
  3759. static struct hda_verb ad1882_ch6_init[] = {
  3760. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3761. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3762. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3763. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3764. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3765. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3766. { } /* end */
  3767. };
  3768. static struct hda_channel_mode ad1882_modes[3] = {
  3769. { 2, ad1882_ch2_init },
  3770. { 4, ad1882_ch4_init },
  3771. { 6, ad1882_ch6_init },
  3772. };
  3773. /*
  3774. * initialization verbs
  3775. */
  3776. static struct hda_verb ad1882_init_verbs[] = {
  3777. /* DACs; mute as default */
  3778. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3779. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3780. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3781. /* Port-A (HP) mixer */
  3782. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3783. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3784. /* Port-A pin */
  3785. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3786. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3787. /* HP selector - select DAC2 */
  3788. {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
  3789. /* Port-D (Line-out) mixer */
  3790. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3791. {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3792. /* Port-D pin */
  3793. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3794. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3795. /* Mono-out mixer */
  3796. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3797. {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  3798. /* Mono-out pin */
  3799. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3800. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3801. /* Port-B (front mic) pin */
  3802. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3803. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3804. {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
  3805. /* Port-C (line-in) pin */
  3806. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3807. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3808. {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
  3809. /* Port-C mixer - mute as input */
  3810. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3811. {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3812. /* Port-E (mic-in) pin */
  3813. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3814. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3815. {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
  3816. /* Port-E mixer - mute as input */
  3817. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3818. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3819. /* Port-F (surround) */
  3820. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3821. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3822. /* Port-G (CLFE) */
  3823. {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3824. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  3825. /* Analog mixer; mute as default */
  3826. /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
  3827. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3828. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3829. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3830. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3831. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3832. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  3833. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  3834. {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  3835. /* Analog Mix output amp */
  3836. {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
  3837. /* SPDIF output selector */
  3838. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  3839. {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
  3840. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
  3841. { } /* end */
  3842. };
  3843. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3844. static struct hda_amp_list ad1882_loopbacks[] = {
  3845. { 0x20, HDA_INPUT, 0 }, /* Front Mic */
  3846. { 0x20, HDA_INPUT, 1 }, /* Mic */
  3847. { 0x20, HDA_INPUT, 4 }, /* Line */
  3848. { 0x20, HDA_INPUT, 6 }, /* CD */
  3849. { } /* end */
  3850. };
  3851. #endif
  3852. /* models */
  3853. enum {
  3854. AD1882_3STACK,
  3855. AD1882_6STACK,
  3856. AD1882_MODELS
  3857. };
  3858. static const char *ad1882_models[AD1986A_MODELS] = {
  3859. [AD1882_3STACK] = "3stack",
  3860. [AD1882_6STACK] = "6stack",
  3861. };
  3862. static int patch_ad1882(struct hda_codec *codec)
  3863. {
  3864. struct ad198x_spec *spec;
  3865. int board_config;
  3866. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  3867. if (spec == NULL)
  3868. return -ENOMEM;
  3869. codec->spec = spec;
  3870. spec->multiout.max_channels = 6;
  3871. spec->multiout.num_dacs = 3;
  3872. spec->multiout.dac_nids = ad1882_dac_nids;
  3873. spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
  3874. spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
  3875. spec->adc_nids = ad1882_adc_nids;
  3876. spec->capsrc_nids = ad1882_capsrc_nids;
  3877. if (codec->vendor_id == 0x11d41882)
  3878. spec->input_mux = &ad1882_capture_source;
  3879. else
  3880. spec->input_mux = &ad1882a_capture_source;
  3881. spec->num_mixers = 2;
  3882. spec->mixers[0] = ad1882_base_mixers;
  3883. if (codec->vendor_id == 0x11d41882)
  3884. spec->mixers[1] = ad1882_loopback_mixers;
  3885. else
  3886. spec->mixers[1] = ad1882a_loopback_mixers;
  3887. spec->num_init_verbs = 1;
  3888. spec->init_verbs[0] = ad1882_init_verbs;
  3889. spec->spdif_route = 0;
  3890. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3891. spec->loopback.amplist = ad1882_loopbacks;
  3892. #endif
  3893. spec->vmaster_nid = 0x04;
  3894. codec->patch_ops = ad198x_patch_ops;
  3895. /* override some parameters */
  3896. board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
  3897. ad1882_models, NULL);
  3898. switch (board_config) {
  3899. default:
  3900. case AD1882_3STACK:
  3901. spec->num_mixers = 3;
  3902. spec->mixers[2] = ad1882_3stack_mixers;
  3903. spec->channel_mode = ad1882_modes;
  3904. spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
  3905. spec->need_dac_fix = 1;
  3906. spec->multiout.max_channels = 2;
  3907. spec->multiout.num_dacs = 1;
  3908. break;
  3909. case AD1882_6STACK:
  3910. spec->num_mixers = 3;
  3911. spec->mixers[2] = ad1882_6stack_mixers;
  3912. break;
  3913. }
  3914. return 0;
  3915. }
  3916. /*
  3917. * patch entries
  3918. */
  3919. static struct hda_codec_preset snd_hda_preset_analog[] = {
  3920. { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
  3921. { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
  3922. { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
  3923. { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
  3924. { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
  3925. { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
  3926. { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
  3927. { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
  3928. { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
  3929. { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
  3930. { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
  3931. { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
  3932. { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
  3933. { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
  3934. { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
  3935. {} /* terminator */
  3936. };
  3937. MODULE_ALIAS("snd-hda-codec-id:11d4*");
  3938. MODULE_LICENSE("GPL");
  3939. MODULE_DESCRIPTION("Analog Devices HD-audio codec");
  3940. static struct hda_codec_preset_list analog_list = {
  3941. .preset = snd_hda_preset_analog,
  3942. .owner = THIS_MODULE,
  3943. };
  3944. static int __init patch_analog_init(void)
  3945. {
  3946. return snd_hda_add_codec_preset(&analog_list);
  3947. }
  3948. static void __exit patch_analog_exit(void)
  3949. {
  3950. snd_hda_delete_codec_preset(&analog_list);
  3951. }
  3952. module_init(patch_analog_init)
  3953. module_exit(patch_analog_exit)