patch_realtek.c 435 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203
  1. /*
  2. * Universal Interface for Intel High Definition Audio Codec
  3. *
  4. * HD audio interface patch for ALC 260/880/882 codecs
  5. *
  6. * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
  7. * PeiSen Hou <pshou@realtek.com.tw>
  8. * Takashi Iwai <tiwai@suse.de>
  9. * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  10. *
  11. * This driver is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This driver is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. */
  25. #include <sound/driver.h>
  26. #include <linux/init.h>
  27. #include <linux/delay.h>
  28. #include <linux/slab.h>
  29. #include <linux/pci.h>
  30. #include <sound/core.h>
  31. #include "hda_codec.h"
  32. #include "hda_local.h"
  33. #define ALC880_FRONT_EVENT 0x01
  34. #define ALC880_DCVOL_EVENT 0x02
  35. #define ALC880_HP_EVENT 0x04
  36. #define ALC880_MIC_EVENT 0x08
  37. /* ALC880 board config type */
  38. enum {
  39. ALC880_3ST,
  40. ALC880_3ST_DIG,
  41. ALC880_5ST,
  42. ALC880_5ST_DIG,
  43. ALC880_W810,
  44. ALC880_Z71V,
  45. ALC880_6ST,
  46. ALC880_6ST_DIG,
  47. ALC880_F1734,
  48. ALC880_ASUS,
  49. ALC880_ASUS_DIG,
  50. ALC880_ASUS_W1V,
  51. ALC880_ASUS_DIG2,
  52. ALC880_FUJITSU,
  53. ALC880_UNIWILL_DIG,
  54. ALC880_UNIWILL,
  55. ALC880_UNIWILL_P53,
  56. ALC880_CLEVO,
  57. ALC880_TCL_S700,
  58. ALC880_LG,
  59. ALC880_LG_LW,
  60. #ifdef CONFIG_SND_DEBUG
  61. ALC880_TEST,
  62. #endif
  63. ALC880_AUTO,
  64. ALC880_MODEL_LAST /* last tag */
  65. };
  66. /* ALC260 models */
  67. enum {
  68. ALC260_BASIC,
  69. ALC260_HP,
  70. ALC260_HP_3013,
  71. ALC260_FUJITSU_S702X,
  72. ALC260_ACER,
  73. ALC260_WILL,
  74. ALC260_REPLACER_672V,
  75. #ifdef CONFIG_SND_DEBUG
  76. ALC260_TEST,
  77. #endif
  78. ALC260_AUTO,
  79. ALC260_MODEL_LAST /* last tag */
  80. };
  81. /* ALC262 models */
  82. enum {
  83. ALC262_BASIC,
  84. ALC262_HIPPO,
  85. ALC262_HIPPO_1,
  86. ALC262_FUJITSU,
  87. ALC262_HP_BPC,
  88. ALC262_HP_BPC_D7000_WL,
  89. ALC262_HP_BPC_D7000_WF,
  90. ALC262_HP_TC_T5735,
  91. ALC262_BENQ_ED8,
  92. ALC262_SONY_ASSAMD,
  93. ALC262_BENQ_T31,
  94. ALC262_ULTRA,
  95. ALC262_AUTO,
  96. ALC262_MODEL_LAST /* last tag */
  97. };
  98. /* ALC268 models */
  99. enum {
  100. ALC268_3ST,
  101. ALC268_TOSHIBA,
  102. ALC268_ACER,
  103. #ifdef CONFIG_SND_DEBUG
  104. ALC268_TEST,
  105. #endif
  106. ALC268_AUTO,
  107. ALC268_MODEL_LAST /* last tag */
  108. };
  109. /* ALC269 models */
  110. enum {
  111. ALC269_BASIC,
  112. ALC269_AUTO,
  113. ALC269_MODEL_LAST /* last tag */
  114. };
  115. /* ALC861 models */
  116. enum {
  117. ALC861_3ST,
  118. ALC660_3ST,
  119. ALC861_3ST_DIG,
  120. ALC861_6ST_DIG,
  121. ALC861_UNIWILL_M31,
  122. ALC861_TOSHIBA,
  123. ALC861_ASUS,
  124. ALC861_ASUS_LAPTOP,
  125. ALC861_AUTO,
  126. ALC861_MODEL_LAST,
  127. };
  128. /* ALC861-VD models */
  129. enum {
  130. ALC660VD_3ST,
  131. ALC660VD_3ST_DIG,
  132. ALC861VD_3ST,
  133. ALC861VD_3ST_DIG,
  134. ALC861VD_6ST_DIG,
  135. ALC861VD_LENOVO,
  136. ALC861VD_DALLAS,
  137. ALC861VD_HP,
  138. ALC861VD_AUTO,
  139. ALC861VD_MODEL_LAST,
  140. };
  141. /* ALC662 models */
  142. enum {
  143. ALC662_3ST_2ch_DIG,
  144. ALC662_3ST_6ch_DIG,
  145. ALC662_3ST_6ch,
  146. ALC662_5ST_DIG,
  147. ALC662_LENOVO_101E,
  148. ALC662_ASUS_EEEPC_P701,
  149. ALC662_AUTO,
  150. ALC662_MODEL_LAST,
  151. };
  152. /* ALC882 models */
  153. enum {
  154. ALC882_3ST_DIG,
  155. ALC882_6ST_DIG,
  156. ALC882_ARIMA,
  157. ALC882_W2JC,
  158. ALC882_TARGA,
  159. ALC882_ASUS_A7J,
  160. ALC882_ASUS_A7M,
  161. ALC885_MACPRO,
  162. ALC885_MBP3,
  163. ALC885_IMAC24,
  164. ALC882_AUTO,
  165. ALC882_MODEL_LAST,
  166. };
  167. /* ALC883 models */
  168. enum {
  169. ALC883_3ST_2ch_DIG,
  170. ALC883_3ST_6ch_DIG,
  171. ALC883_3ST_6ch,
  172. ALC883_6ST_DIG,
  173. ALC883_TARGA_DIG,
  174. ALC883_TARGA_2ch_DIG,
  175. ALC883_ACER,
  176. ALC883_ACER_ASPIRE,
  177. ALC883_MEDION,
  178. ALC883_MEDION_MD2,
  179. ALC883_LAPTOP_EAPD,
  180. ALC883_LENOVO_101E_2ch,
  181. ALC883_LENOVO_NB0763,
  182. ALC888_LENOVO_MS7195_DIG,
  183. ALC883_HAIER_W66,
  184. ALC888_6ST_HP,
  185. ALC888_3ST_HP,
  186. ALC883_MITAC,
  187. ALC883_AUTO,
  188. ALC883_MODEL_LAST,
  189. };
  190. /* for GPIO Poll */
  191. #define GPIO_MASK 0x03
  192. struct alc_spec {
  193. /* codec parameterization */
  194. struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
  195. unsigned int num_mixers;
  196. const struct hda_verb *init_verbs[5]; /* initialization verbs
  197. * don't forget NULL
  198. * termination!
  199. */
  200. unsigned int num_init_verbs;
  201. char *stream_name_analog; /* analog PCM stream */
  202. struct hda_pcm_stream *stream_analog_playback;
  203. struct hda_pcm_stream *stream_analog_capture;
  204. char *stream_name_digital; /* digital PCM stream */
  205. struct hda_pcm_stream *stream_digital_playback;
  206. struct hda_pcm_stream *stream_digital_capture;
  207. /* playback */
  208. struct hda_multi_out multiout; /* playback set-up
  209. * max_channels, dacs must be set
  210. * dig_out_nid and hp_nid are optional
  211. */
  212. /* capture */
  213. unsigned int num_adc_nids;
  214. hda_nid_t *adc_nids;
  215. hda_nid_t dig_in_nid; /* digital-in NID; optional */
  216. /* capture source */
  217. unsigned int num_mux_defs;
  218. const struct hda_input_mux *input_mux;
  219. unsigned int cur_mux[3];
  220. /* channel model */
  221. const struct hda_channel_mode *channel_mode;
  222. int num_channel_mode;
  223. int need_dac_fix;
  224. /* PCM information */
  225. struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
  226. /* dynamic controls, init_verbs and input_mux */
  227. struct auto_pin_cfg autocfg;
  228. unsigned int num_kctl_alloc, num_kctl_used;
  229. struct snd_kcontrol_new *kctl_alloc;
  230. struct hda_input_mux private_imux;
  231. hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  232. /* hooks */
  233. void (*init_hook)(struct hda_codec *codec);
  234. void (*unsol_event)(struct hda_codec *codec, unsigned int res);
  235. /* for pin sensing */
  236. unsigned int sense_updated: 1;
  237. unsigned int jack_present: 1;
  238. #ifdef CONFIG_SND_HDA_POWER_SAVE
  239. struct hda_loopback_check loopback;
  240. #endif
  241. };
  242. /*
  243. * configuration template - to be copied to the spec instance
  244. */
  245. struct alc_config_preset {
  246. struct snd_kcontrol_new *mixers[5]; /* should be identical size
  247. * with spec
  248. */
  249. const struct hda_verb *init_verbs[5];
  250. unsigned int num_dacs;
  251. hda_nid_t *dac_nids;
  252. hda_nid_t dig_out_nid; /* optional */
  253. hda_nid_t hp_nid; /* optional */
  254. unsigned int num_adc_nids;
  255. hda_nid_t *adc_nids;
  256. hda_nid_t dig_in_nid;
  257. unsigned int num_channel_mode;
  258. const struct hda_channel_mode *channel_mode;
  259. int need_dac_fix;
  260. unsigned int num_mux_defs;
  261. const struct hda_input_mux *input_mux;
  262. void (*unsol_event)(struct hda_codec *, unsigned int);
  263. void (*init_hook)(struct hda_codec *);
  264. #ifdef CONFIG_SND_HDA_POWER_SAVE
  265. struct hda_amp_list *loopbacks;
  266. #endif
  267. };
  268. /*
  269. * input MUX handling
  270. */
  271. static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
  272. struct snd_ctl_elem_info *uinfo)
  273. {
  274. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  275. struct alc_spec *spec = codec->spec;
  276. unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
  277. if (mux_idx >= spec->num_mux_defs)
  278. mux_idx = 0;
  279. return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
  280. }
  281. static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
  282. struct snd_ctl_elem_value *ucontrol)
  283. {
  284. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  285. struct alc_spec *spec = codec->spec;
  286. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  287. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  288. return 0;
  289. }
  290. static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
  291. struct snd_ctl_elem_value *ucontrol)
  292. {
  293. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  294. struct alc_spec *spec = codec->spec;
  295. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  296. unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
  297. return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
  298. spec->adc_nids[adc_idx],
  299. &spec->cur_mux[adc_idx]);
  300. }
  301. /*
  302. * channel mode setting
  303. */
  304. static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
  305. struct snd_ctl_elem_info *uinfo)
  306. {
  307. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  308. struct alc_spec *spec = codec->spec;
  309. return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
  310. spec->num_channel_mode);
  311. }
  312. static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
  313. struct snd_ctl_elem_value *ucontrol)
  314. {
  315. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  316. struct alc_spec *spec = codec->spec;
  317. return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
  318. spec->num_channel_mode,
  319. spec->multiout.max_channels);
  320. }
  321. static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
  322. struct snd_ctl_elem_value *ucontrol)
  323. {
  324. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  325. struct alc_spec *spec = codec->spec;
  326. int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
  327. spec->num_channel_mode,
  328. &spec->multiout.max_channels);
  329. if (err >= 0 && spec->need_dac_fix)
  330. spec->multiout.num_dacs = spec->multiout.max_channels / 2;
  331. return err;
  332. }
  333. /*
  334. * Control the mode of pin widget settings via the mixer. "pc" is used
  335. * instead of "%" to avoid consequences of accidently treating the % as
  336. * being part of a format specifier. Maximum allowed length of a value is
  337. * 63 characters plus NULL terminator.
  338. *
  339. * Note: some retasking pin complexes seem to ignore requests for input
  340. * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
  341. * are requested. Therefore order this list so that this behaviour will not
  342. * cause problems when mixer clients move through the enum sequentially.
  343. * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
  344. * March 2006.
  345. */
  346. static char *alc_pin_mode_names[] = {
  347. "Mic 50pc bias", "Mic 80pc bias",
  348. "Line in", "Line out", "Headphone out",
  349. };
  350. static unsigned char alc_pin_mode_values[] = {
  351. PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
  352. };
  353. /* The control can present all 5 options, or it can limit the options based
  354. * in the pin being assumed to be exclusively an input or an output pin. In
  355. * addition, "input" pins may or may not process the mic bias option
  356. * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
  357. * accept requests for bias as of chip versions up to March 2006) and/or
  358. * wiring in the computer.
  359. */
  360. #define ALC_PIN_DIR_IN 0x00
  361. #define ALC_PIN_DIR_OUT 0x01
  362. #define ALC_PIN_DIR_INOUT 0x02
  363. #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
  364. #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
  365. /* Info about the pin modes supported by the different pin direction modes.
  366. * For each direction the minimum and maximum values are given.
  367. */
  368. static signed char alc_pin_mode_dir_info[5][2] = {
  369. { 0, 2 }, /* ALC_PIN_DIR_IN */
  370. { 3, 4 }, /* ALC_PIN_DIR_OUT */
  371. { 0, 4 }, /* ALC_PIN_DIR_INOUT */
  372. { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
  373. { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
  374. };
  375. #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
  376. #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
  377. #define alc_pin_mode_n_items(_dir) \
  378. (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
  379. static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
  380. struct snd_ctl_elem_info *uinfo)
  381. {
  382. unsigned int item_num = uinfo->value.enumerated.item;
  383. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  384. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  385. uinfo->count = 1;
  386. uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
  387. if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
  388. item_num = alc_pin_mode_min(dir);
  389. strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
  390. return 0;
  391. }
  392. static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
  393. struct snd_ctl_elem_value *ucontrol)
  394. {
  395. unsigned int i;
  396. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  397. hda_nid_t nid = kcontrol->private_value & 0xffff;
  398. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  399. long *valp = ucontrol->value.integer.value;
  400. unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  401. AC_VERB_GET_PIN_WIDGET_CONTROL,
  402. 0x00);
  403. /* Find enumerated value for current pinctl setting */
  404. i = alc_pin_mode_min(dir);
  405. while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
  406. i++;
  407. *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
  408. return 0;
  409. }
  410. static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
  411. struct snd_ctl_elem_value *ucontrol)
  412. {
  413. signed int change;
  414. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  415. hda_nid_t nid = kcontrol->private_value & 0xffff;
  416. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  417. long val = *ucontrol->value.integer.value;
  418. unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  419. AC_VERB_GET_PIN_WIDGET_CONTROL,
  420. 0x00);
  421. if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
  422. val = alc_pin_mode_min(dir);
  423. change = pinctl != alc_pin_mode_values[val];
  424. if (change) {
  425. /* Set pin mode to that requested */
  426. snd_hda_codec_write_cache(codec, nid, 0,
  427. AC_VERB_SET_PIN_WIDGET_CONTROL,
  428. alc_pin_mode_values[val]);
  429. /* Also enable the retasking pin's input/output as required
  430. * for the requested pin mode. Enum values of 2 or less are
  431. * input modes.
  432. *
  433. * Dynamically switching the input/output buffers probably
  434. * reduces noise slightly (particularly on input) so we'll
  435. * do it. However, having both input and output buffers
  436. * enabled simultaneously doesn't seem to be problematic if
  437. * this turns out to be necessary in the future.
  438. */
  439. if (val <= 2) {
  440. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  441. HDA_AMP_MUTE, HDA_AMP_MUTE);
  442. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  443. HDA_AMP_MUTE, 0);
  444. } else {
  445. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  446. HDA_AMP_MUTE, HDA_AMP_MUTE);
  447. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  448. HDA_AMP_MUTE, 0);
  449. }
  450. }
  451. return change;
  452. }
  453. #define ALC_PIN_MODE(xname, nid, dir) \
  454. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  455. .info = alc_pin_mode_info, \
  456. .get = alc_pin_mode_get, \
  457. .put = alc_pin_mode_put, \
  458. .private_value = nid | (dir<<16) }
  459. /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
  460. * together using a mask with more than one bit set. This control is
  461. * currently used only by the ALC260 test model. At this stage they are not
  462. * needed for any "production" models.
  463. */
  464. #ifdef CONFIG_SND_DEBUG
  465. #define alc_gpio_data_info snd_ctl_boolean_mono_info
  466. static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
  467. struct snd_ctl_elem_value *ucontrol)
  468. {
  469. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  470. hda_nid_t nid = kcontrol->private_value & 0xffff;
  471. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  472. long *valp = ucontrol->value.integer.value;
  473. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  474. AC_VERB_GET_GPIO_DATA, 0x00);
  475. *valp = (val & mask) != 0;
  476. return 0;
  477. }
  478. static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
  479. struct snd_ctl_elem_value *ucontrol)
  480. {
  481. signed int change;
  482. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  483. hda_nid_t nid = kcontrol->private_value & 0xffff;
  484. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  485. long val = *ucontrol->value.integer.value;
  486. unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
  487. AC_VERB_GET_GPIO_DATA,
  488. 0x00);
  489. /* Set/unset the masked GPIO bit(s) as needed */
  490. change = (val == 0 ? 0 : mask) != (gpio_data & mask);
  491. if (val == 0)
  492. gpio_data &= ~mask;
  493. else
  494. gpio_data |= mask;
  495. snd_hda_codec_write_cache(codec, nid, 0,
  496. AC_VERB_SET_GPIO_DATA, gpio_data);
  497. return change;
  498. }
  499. #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
  500. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  501. .info = alc_gpio_data_info, \
  502. .get = alc_gpio_data_get, \
  503. .put = alc_gpio_data_put, \
  504. .private_value = nid | (mask<<16) }
  505. #endif /* CONFIG_SND_DEBUG */
  506. /* A switch control to allow the enabling of the digital IO pins on the
  507. * ALC260. This is incredibly simplistic; the intention of this control is
  508. * to provide something in the test model allowing digital outputs to be
  509. * identified if present. If models are found which can utilise these
  510. * outputs a more complete mixer control can be devised for those models if
  511. * necessary.
  512. */
  513. #ifdef CONFIG_SND_DEBUG
  514. #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
  515. static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
  516. struct snd_ctl_elem_value *ucontrol)
  517. {
  518. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  519. hda_nid_t nid = kcontrol->private_value & 0xffff;
  520. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  521. long *valp = ucontrol->value.integer.value;
  522. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  523. AC_VERB_GET_DIGI_CONVERT_1, 0x00);
  524. *valp = (val & mask) != 0;
  525. return 0;
  526. }
  527. static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
  528. struct snd_ctl_elem_value *ucontrol)
  529. {
  530. signed int change;
  531. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  532. hda_nid_t nid = kcontrol->private_value & 0xffff;
  533. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  534. long val = *ucontrol->value.integer.value;
  535. unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  536. AC_VERB_GET_DIGI_CONVERT_1,
  537. 0x00);
  538. /* Set/unset the masked control bit(s) as needed */
  539. change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
  540. if (val==0)
  541. ctrl_data &= ~mask;
  542. else
  543. ctrl_data |= mask;
  544. snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
  545. ctrl_data);
  546. return change;
  547. }
  548. #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
  549. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  550. .info = alc_spdif_ctrl_info, \
  551. .get = alc_spdif_ctrl_get, \
  552. .put = alc_spdif_ctrl_put, \
  553. .private_value = nid | (mask<<16) }
  554. #endif /* CONFIG_SND_DEBUG */
  555. /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
  556. * Again, this is only used in the ALC26x test models to help identify when
  557. * the EAPD line must be asserted for features to work.
  558. */
  559. #ifdef CONFIG_SND_DEBUG
  560. #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
  561. static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
  562. struct snd_ctl_elem_value *ucontrol)
  563. {
  564. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  565. hda_nid_t nid = kcontrol->private_value & 0xffff;
  566. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  567. long *valp = ucontrol->value.integer.value;
  568. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  569. AC_VERB_GET_EAPD_BTLENABLE, 0x00);
  570. *valp = (val & mask) != 0;
  571. return 0;
  572. }
  573. static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
  574. struct snd_ctl_elem_value *ucontrol)
  575. {
  576. int change;
  577. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  578. hda_nid_t nid = kcontrol->private_value & 0xffff;
  579. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  580. long val = *ucontrol->value.integer.value;
  581. unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  582. AC_VERB_GET_EAPD_BTLENABLE,
  583. 0x00);
  584. /* Set/unset the masked control bit(s) as needed */
  585. change = (!val ? 0 : mask) != (ctrl_data & mask);
  586. if (!val)
  587. ctrl_data &= ~mask;
  588. else
  589. ctrl_data |= mask;
  590. snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
  591. ctrl_data);
  592. return change;
  593. }
  594. #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
  595. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  596. .info = alc_eapd_ctrl_info, \
  597. .get = alc_eapd_ctrl_get, \
  598. .put = alc_eapd_ctrl_put, \
  599. .private_value = nid | (mask<<16) }
  600. #endif /* CONFIG_SND_DEBUG */
  601. /*
  602. * set up from the preset table
  603. */
  604. static void setup_preset(struct alc_spec *spec,
  605. const struct alc_config_preset *preset)
  606. {
  607. int i;
  608. for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
  609. spec->mixers[spec->num_mixers++] = preset->mixers[i];
  610. for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
  611. i++)
  612. spec->init_verbs[spec->num_init_verbs++] =
  613. preset->init_verbs[i];
  614. spec->channel_mode = preset->channel_mode;
  615. spec->num_channel_mode = preset->num_channel_mode;
  616. spec->need_dac_fix = preset->need_dac_fix;
  617. spec->multiout.max_channels = spec->channel_mode[0].channels;
  618. spec->multiout.num_dacs = preset->num_dacs;
  619. spec->multiout.dac_nids = preset->dac_nids;
  620. spec->multiout.dig_out_nid = preset->dig_out_nid;
  621. spec->multiout.hp_nid = preset->hp_nid;
  622. spec->num_mux_defs = preset->num_mux_defs;
  623. if (!spec->num_mux_defs)
  624. spec->num_mux_defs = 1;
  625. spec->input_mux = preset->input_mux;
  626. spec->num_adc_nids = preset->num_adc_nids;
  627. spec->adc_nids = preset->adc_nids;
  628. spec->dig_in_nid = preset->dig_in_nid;
  629. spec->unsol_event = preset->unsol_event;
  630. spec->init_hook = preset->init_hook;
  631. #ifdef CONFIG_SND_HDA_POWER_SAVE
  632. spec->loopback.amplist = preset->loopbacks;
  633. #endif
  634. }
  635. /* Enable GPIO mask and set output */
  636. static struct hda_verb alc_gpio1_init_verbs[] = {
  637. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  638. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  639. {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
  640. { }
  641. };
  642. static struct hda_verb alc_gpio2_init_verbs[] = {
  643. {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
  644. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
  645. {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
  646. { }
  647. };
  648. static struct hda_verb alc_gpio3_init_verbs[] = {
  649. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  650. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  651. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  652. { }
  653. };
  654. static void alc_sku_automute(struct hda_codec *codec)
  655. {
  656. struct alc_spec *spec = codec->spec;
  657. unsigned int mute;
  658. unsigned int present;
  659. unsigned int hp_nid = spec->autocfg.hp_pins[0];
  660. unsigned int sp_nid = spec->autocfg.speaker_pins[0];
  661. /* need to execute and sync at first */
  662. snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
  663. present = snd_hda_codec_read(codec, hp_nid, 0,
  664. AC_VERB_GET_PIN_SENSE, 0);
  665. spec->jack_present = (present & 0x80000000) != 0;
  666. if (spec->jack_present) {
  667. /* mute internal speaker */
  668. snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
  669. HDA_AMP_MUTE, HDA_AMP_MUTE);
  670. } else {
  671. /* unmute internal speaker if necessary */
  672. mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
  673. snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
  674. HDA_AMP_MUTE, mute);
  675. }
  676. }
  677. /* unsolicited event for HP jack sensing */
  678. static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
  679. {
  680. if (codec->vendor_id == 0x10ec0880)
  681. res >>= 28;
  682. else
  683. res >>= 26;
  684. if (res != ALC880_HP_EVENT)
  685. return;
  686. alc_sku_automute(codec);
  687. }
  688. /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
  689. * 31 ~ 16 : Manufacture ID
  690. * 15 ~ 8 : SKU ID
  691. * 7 ~ 0 : Assembly ID
  692. * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
  693. */
  694. static void alc_subsystem_id(struct hda_codec *codec,
  695. unsigned int porta, unsigned int porte,
  696. unsigned int portd)
  697. {
  698. unsigned int ass, tmp, i;
  699. unsigned nid;
  700. struct alc_spec *spec = codec->spec;
  701. ass = codec->subsystem_id & 0xffff;
  702. if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
  703. goto do_sku;
  704. /*
  705. * 31~30 : port conetcivity
  706. * 29~21 : reserve
  707. * 20 : PCBEEP input
  708. * 19~16 : Check sum (15:1)
  709. * 15~1 : Custom
  710. * 0 : override
  711. */
  712. nid = 0x1d;
  713. if (codec->vendor_id == 0x10ec0260)
  714. nid = 0x17;
  715. ass = snd_hda_codec_read(codec, nid, 0,
  716. AC_VERB_GET_CONFIG_DEFAULT, 0);
  717. if (!(ass & 1) && !(ass & 0x100000))
  718. return;
  719. if ((ass >> 30) != 1) /* no physical connection */
  720. return;
  721. /* check sum */
  722. tmp = 0;
  723. for (i = 1; i < 16; i++) {
  724. if ((ass >> i) && 1)
  725. tmp++;
  726. }
  727. if (((ass >> 16) & 0xf) != tmp)
  728. return;
  729. do_sku:
  730. /*
  731. * 0 : override
  732. * 1 : Swap Jack
  733. * 2 : 0 --> Desktop, 1 --> Laptop
  734. * 3~5 : External Amplifier control
  735. * 7~6 : Reserved
  736. */
  737. tmp = (ass & 0x38) >> 3; /* external Amp control */
  738. switch (tmp) {
  739. case 1:
  740. snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
  741. break;
  742. case 3:
  743. snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
  744. break;
  745. case 7:
  746. snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
  747. break;
  748. case 5: /* set EAPD output high */
  749. switch (codec->vendor_id) {
  750. case 0x10ec0260:
  751. snd_hda_codec_write(codec, 0x0f, 0,
  752. AC_VERB_SET_EAPD_BTLENABLE, 2);
  753. snd_hda_codec_write(codec, 0x10, 0,
  754. AC_VERB_SET_EAPD_BTLENABLE, 2);
  755. break;
  756. case 0x10ec0262:
  757. case 0x10ec0267:
  758. case 0x10ec0268:
  759. case 0x10ec0269:
  760. case 0x10ec0862:
  761. case 0x10ec0662:
  762. snd_hda_codec_write(codec, 0x14, 0,
  763. AC_VERB_SET_EAPD_BTLENABLE, 2);
  764. snd_hda_codec_write(codec, 0x15, 0,
  765. AC_VERB_SET_EAPD_BTLENABLE, 2);
  766. break;
  767. }
  768. switch (codec->vendor_id) {
  769. case 0x10ec0260:
  770. snd_hda_codec_write(codec, 0x1a, 0,
  771. AC_VERB_SET_COEF_INDEX, 7);
  772. tmp = snd_hda_codec_read(codec, 0x1a, 0,
  773. AC_VERB_GET_PROC_COEF, 0);
  774. snd_hda_codec_write(codec, 0x1a, 0,
  775. AC_VERB_SET_COEF_INDEX, 7);
  776. snd_hda_codec_write(codec, 0x1a, 0,
  777. AC_VERB_SET_PROC_COEF,
  778. tmp | 0x2010);
  779. break;
  780. case 0x10ec0262:
  781. case 0x10ec0880:
  782. case 0x10ec0882:
  783. case 0x10ec0883:
  784. case 0x10ec0885:
  785. case 0x10ec0888:
  786. snd_hda_codec_write(codec, 0x20, 0,
  787. AC_VERB_SET_COEF_INDEX, 7);
  788. tmp = snd_hda_codec_read(codec, 0x20, 0,
  789. AC_VERB_GET_PROC_COEF, 0);
  790. snd_hda_codec_write(codec, 0x20, 0,
  791. AC_VERB_SET_COEF_INDEX, 7);
  792. snd_hda_codec_write(codec, 0x20, 0,
  793. AC_VERB_SET_PROC_COEF,
  794. tmp | 0x2010);
  795. break;
  796. case 0x10ec0267:
  797. case 0x10ec0268:
  798. snd_hda_codec_write(codec, 0x20, 0,
  799. AC_VERB_SET_COEF_INDEX, 7);
  800. tmp = snd_hda_codec_read(codec, 0x20, 0,
  801. AC_VERB_GET_PROC_COEF, 0);
  802. snd_hda_codec_write(codec, 0x20, 0,
  803. AC_VERB_SET_COEF_INDEX, 7);
  804. snd_hda_codec_write(codec, 0x20, 0,
  805. AC_VERB_SET_PROC_COEF,
  806. tmp | 0x3000);
  807. break;
  808. }
  809. default:
  810. break;
  811. }
  812. /* is laptop and enable the function "Mute internal speaker
  813. * when the external headphone out jack is plugged"
  814. */
  815. if (!(ass & 0x4) || !(ass & 0x8000))
  816. return;
  817. /*
  818. * 10~8 : Jack location
  819. * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
  820. * 14~13: Resvered
  821. * 15 : 1 --> enable the function "Mute internal speaker
  822. * when the external headphone out jack is plugged"
  823. */
  824. if (!spec->autocfg.speaker_pins[0]) {
  825. if (spec->multiout.dac_nids[0])
  826. spec->autocfg.speaker_pins[0] =
  827. spec->multiout.dac_nids[0];
  828. else
  829. return;
  830. }
  831. if (!spec->autocfg.hp_pins[0]) {
  832. tmp = (ass >> 11) & 0x3; /* HP to chassis */
  833. if (tmp == 0)
  834. spec->autocfg.hp_pins[0] = porta;
  835. else if (tmp == 1)
  836. spec->autocfg.hp_pins[0] = porte;
  837. else if (tmp == 2)
  838. spec->autocfg.hp_pins[0] = portd;
  839. else
  840. return;
  841. }
  842. snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
  843. AC_VERB_SET_UNSOLICITED_ENABLE,
  844. AC_USRSP_EN | ALC880_HP_EVENT);
  845. spec->unsol_event = alc_sku_unsol_event;
  846. spec->init_hook = alc_sku_automute;
  847. }
  848. /*
  849. * Fix-up pin default configurations
  850. */
  851. struct alc_pincfg {
  852. hda_nid_t nid;
  853. u32 val;
  854. };
  855. static void alc_fix_pincfg(struct hda_codec *codec,
  856. const struct snd_pci_quirk *quirk,
  857. const struct alc_pincfg **pinfix)
  858. {
  859. const struct alc_pincfg *cfg;
  860. quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
  861. if (!quirk)
  862. return;
  863. cfg = pinfix[quirk->value];
  864. for (; cfg->nid; cfg++) {
  865. int i;
  866. u32 val = cfg->val;
  867. for (i = 0; i < 4; i++) {
  868. snd_hda_codec_write(codec, cfg->nid, 0,
  869. AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
  870. val & 0xff);
  871. val >>= 8;
  872. }
  873. }
  874. }
  875. /*
  876. * ALC880 3-stack model
  877. *
  878. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
  879. * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
  880. * F-Mic = 0x1b, HP = 0x19
  881. */
  882. static hda_nid_t alc880_dac_nids[4] = {
  883. /* front, rear, clfe, rear_surr */
  884. 0x02, 0x05, 0x04, 0x03
  885. };
  886. static hda_nid_t alc880_adc_nids[3] = {
  887. /* ADC0-2 */
  888. 0x07, 0x08, 0x09,
  889. };
  890. /* The datasheet says the node 0x07 is connected from inputs,
  891. * but it shows zero connection in the real implementation on some devices.
  892. * Note: this is a 915GAV bug, fixed on 915GLV
  893. */
  894. static hda_nid_t alc880_adc_nids_alt[2] = {
  895. /* ADC1-2 */
  896. 0x08, 0x09,
  897. };
  898. #define ALC880_DIGOUT_NID 0x06
  899. #define ALC880_DIGIN_NID 0x0a
  900. static struct hda_input_mux alc880_capture_source = {
  901. .num_items = 4,
  902. .items = {
  903. { "Mic", 0x0 },
  904. { "Front Mic", 0x3 },
  905. { "Line", 0x2 },
  906. { "CD", 0x4 },
  907. },
  908. };
  909. /* channel source setting (2/6 channel selection for 3-stack) */
  910. /* 2ch mode */
  911. static struct hda_verb alc880_threestack_ch2_init[] = {
  912. /* set line-in to input, mute it */
  913. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  914. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  915. /* set mic-in to input vref 80%, mute it */
  916. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  917. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  918. { } /* end */
  919. };
  920. /* 6ch mode */
  921. static struct hda_verb alc880_threestack_ch6_init[] = {
  922. /* set line-in to output, unmute it */
  923. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  924. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  925. /* set mic-in to output, unmute it */
  926. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  927. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  928. { } /* end */
  929. };
  930. static struct hda_channel_mode alc880_threestack_modes[2] = {
  931. { 2, alc880_threestack_ch2_init },
  932. { 6, alc880_threestack_ch6_init },
  933. };
  934. static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
  935. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  936. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  937. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  938. HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
  939. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  940. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  941. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  942. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  943. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  944. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  945. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  946. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  947. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  948. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  949. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
  950. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
  951. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  952. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  953. HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
  954. {
  955. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  956. .name = "Channel Mode",
  957. .info = alc_ch_mode_info,
  958. .get = alc_ch_mode_get,
  959. .put = alc_ch_mode_put,
  960. },
  961. { } /* end */
  962. };
  963. /* capture mixer elements */
  964. static struct snd_kcontrol_new alc880_capture_mixer[] = {
  965. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  966. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  967. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
  968. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
  969. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
  970. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
  971. {
  972. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  973. /* The multiple "Capture Source" controls confuse alsamixer
  974. * So call somewhat different..
  975. * FIXME: the controls appear in the "playback" view!
  976. */
  977. /* .name = "Capture Source", */
  978. .name = "Input Source",
  979. .count = 3,
  980. .info = alc_mux_enum_info,
  981. .get = alc_mux_enum_get,
  982. .put = alc_mux_enum_put,
  983. },
  984. { } /* end */
  985. };
  986. /* capture mixer elements (in case NID 0x07 not available) */
  987. static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
  988. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  989. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  990. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  991. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  992. {
  993. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  994. /* The multiple "Capture Source" controls confuse alsamixer
  995. * So call somewhat different..
  996. * FIXME: the controls appear in the "playback" view!
  997. */
  998. /* .name = "Capture Source", */
  999. .name = "Input Source",
  1000. .count = 2,
  1001. .info = alc_mux_enum_info,
  1002. .get = alc_mux_enum_get,
  1003. .put = alc_mux_enum_put,
  1004. },
  1005. { } /* end */
  1006. };
  1007. /*
  1008. * ALC880 5-stack model
  1009. *
  1010. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
  1011. * Side = 0x02 (0xd)
  1012. * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
  1013. * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
  1014. */
  1015. /* additional mixers to alc880_three_stack_mixer */
  1016. static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
  1017. HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1018. HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
  1019. { } /* end */
  1020. };
  1021. /* channel source setting (6/8 channel selection for 5-stack) */
  1022. /* 6ch mode */
  1023. static struct hda_verb alc880_fivestack_ch6_init[] = {
  1024. /* set line-in to input, mute it */
  1025. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  1026. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  1027. { } /* end */
  1028. };
  1029. /* 8ch mode */
  1030. static struct hda_verb alc880_fivestack_ch8_init[] = {
  1031. /* set line-in to output, unmute it */
  1032. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  1033. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  1034. { } /* end */
  1035. };
  1036. static struct hda_channel_mode alc880_fivestack_modes[2] = {
  1037. { 6, alc880_fivestack_ch6_init },
  1038. { 8, alc880_fivestack_ch8_init },
  1039. };
  1040. /*
  1041. * ALC880 6-stack model
  1042. *
  1043. * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
  1044. * Side = 0x05 (0x0f)
  1045. * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
  1046. * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
  1047. */
  1048. static hda_nid_t alc880_6st_dac_nids[4] = {
  1049. /* front, rear, clfe, rear_surr */
  1050. 0x02, 0x03, 0x04, 0x05
  1051. };
  1052. static struct hda_input_mux alc880_6stack_capture_source = {
  1053. .num_items = 4,
  1054. .items = {
  1055. { "Mic", 0x0 },
  1056. { "Front Mic", 0x1 },
  1057. { "Line", 0x2 },
  1058. { "CD", 0x4 },
  1059. },
  1060. };
  1061. /* fixed 8-channels */
  1062. static struct hda_channel_mode alc880_sixstack_modes[1] = {
  1063. { 8, NULL },
  1064. };
  1065. static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
  1066. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1067. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1068. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1069. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1070. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1071. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1072. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1073. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1074. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1075. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  1076. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1077. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1078. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1079. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1080. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1081. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1082. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1083. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1084. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1085. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1086. {
  1087. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1088. .name = "Channel Mode",
  1089. .info = alc_ch_mode_info,
  1090. .get = alc_ch_mode_get,
  1091. .put = alc_ch_mode_put,
  1092. },
  1093. { } /* end */
  1094. };
  1095. /*
  1096. * ALC880 W810 model
  1097. *
  1098. * W810 has rear IO for:
  1099. * Front (DAC 02)
  1100. * Surround (DAC 03)
  1101. * Center/LFE (DAC 04)
  1102. * Digital out (06)
  1103. *
  1104. * The system also has a pair of internal speakers, and a headphone jack.
  1105. * These are both connected to Line2 on the codec, hence to DAC 02.
  1106. *
  1107. * There is a variable resistor to control the speaker or headphone
  1108. * volume. This is a hardware-only device without a software API.
  1109. *
  1110. * Plugging headphones in will disable the internal speakers. This is
  1111. * implemented in hardware, not via the driver using jack sense. In
  1112. * a similar fashion, plugging into the rear socket marked "front" will
  1113. * disable both the speakers and headphones.
  1114. *
  1115. * For input, there's a microphone jack, and an "audio in" jack.
  1116. * These may not do anything useful with this driver yet, because I
  1117. * haven't setup any initialization verbs for these yet...
  1118. */
  1119. static hda_nid_t alc880_w810_dac_nids[3] = {
  1120. /* front, rear/surround, clfe */
  1121. 0x02, 0x03, 0x04
  1122. };
  1123. /* fixed 6 channels */
  1124. static struct hda_channel_mode alc880_w810_modes[1] = {
  1125. { 6, NULL }
  1126. };
  1127. /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
  1128. static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
  1129. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1130. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1131. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1132. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1133. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1134. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1135. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1136. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1137. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  1138. { } /* end */
  1139. };
  1140. /*
  1141. * Z710V model
  1142. *
  1143. * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
  1144. * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
  1145. * Line = 0x1a
  1146. */
  1147. static hda_nid_t alc880_z71v_dac_nids[1] = {
  1148. 0x02
  1149. };
  1150. #define ALC880_Z71V_HP_DAC 0x03
  1151. /* fixed 2 channels */
  1152. static struct hda_channel_mode alc880_2_jack_modes[1] = {
  1153. { 2, NULL }
  1154. };
  1155. static struct snd_kcontrol_new alc880_z71v_mixer[] = {
  1156. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1157. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1158. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1159. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  1160. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1161. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1162. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1163. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1164. { } /* end */
  1165. };
  1166. /* FIXME! */
  1167. /*
  1168. * ALC880 F1734 model
  1169. *
  1170. * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
  1171. * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
  1172. */
  1173. static hda_nid_t alc880_f1734_dac_nids[1] = {
  1174. 0x03
  1175. };
  1176. #define ALC880_F1734_HP_DAC 0x02
  1177. static struct snd_kcontrol_new alc880_f1734_mixer[] = {
  1178. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1179. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1180. HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1181. HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1182. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1183. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1184. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1185. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1186. { } /* end */
  1187. };
  1188. /* FIXME! */
  1189. /*
  1190. * ALC880 ASUS model
  1191. *
  1192. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  1193. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  1194. * Mic = 0x18, Line = 0x1a
  1195. */
  1196. #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
  1197. #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
  1198. static struct snd_kcontrol_new alc880_asus_mixer[] = {
  1199. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1200. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1201. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1202. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1203. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1204. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1205. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1206. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1207. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1208. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1209. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1210. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1211. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1212. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1213. {
  1214. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1215. .name = "Channel Mode",
  1216. .info = alc_ch_mode_info,
  1217. .get = alc_ch_mode_get,
  1218. .put = alc_ch_mode_put,
  1219. },
  1220. { } /* end */
  1221. };
  1222. /* FIXME! */
  1223. /*
  1224. * ALC880 ASUS W1V model
  1225. *
  1226. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  1227. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  1228. * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
  1229. */
  1230. /* additional mixers to alc880_asus_mixer */
  1231. static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
  1232. HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
  1233. HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
  1234. { } /* end */
  1235. };
  1236. /* additional mixers to alc880_asus_mixer */
  1237. static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
  1238. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1239. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1240. { } /* end */
  1241. };
  1242. /* TCL S700 */
  1243. static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
  1244. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1245. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  1246. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  1247. HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
  1248. HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
  1249. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
  1250. HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
  1251. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  1252. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  1253. {
  1254. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1255. /* The multiple "Capture Source" controls confuse alsamixer
  1256. * So call somewhat different..
  1257. * FIXME: the controls appear in the "playback" view!
  1258. */
  1259. /* .name = "Capture Source", */
  1260. .name = "Input Source",
  1261. .count = 1,
  1262. .info = alc_mux_enum_info,
  1263. .get = alc_mux_enum_get,
  1264. .put = alc_mux_enum_put,
  1265. },
  1266. { } /* end */
  1267. };
  1268. /* Uniwill */
  1269. static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
  1270. HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1271. HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
  1272. HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1273. HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1274. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1275. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1276. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1277. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1278. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1279. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1280. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1281. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1282. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1283. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1284. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1285. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1286. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1287. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1288. {
  1289. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1290. .name = "Channel Mode",
  1291. .info = alc_ch_mode_info,
  1292. .get = alc_ch_mode_get,
  1293. .put = alc_ch_mode_put,
  1294. },
  1295. { } /* end */
  1296. };
  1297. static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
  1298. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1299. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1300. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1301. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1302. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1303. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1304. HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1305. HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1306. HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1307. HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1308. { } /* end */
  1309. };
  1310. static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
  1311. HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1312. HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
  1313. HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1314. HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1315. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1316. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1317. { } /* end */
  1318. };
  1319. /*
  1320. * build control elements
  1321. */
  1322. static int alc_build_controls(struct hda_codec *codec)
  1323. {
  1324. struct alc_spec *spec = codec->spec;
  1325. int err;
  1326. int i;
  1327. for (i = 0; i < spec->num_mixers; i++) {
  1328. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  1329. if (err < 0)
  1330. return err;
  1331. }
  1332. if (spec->multiout.dig_out_nid) {
  1333. err = snd_hda_create_spdif_out_ctls(codec,
  1334. spec->multiout.dig_out_nid);
  1335. if (err < 0)
  1336. return err;
  1337. }
  1338. if (spec->dig_in_nid) {
  1339. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  1340. if (err < 0)
  1341. return err;
  1342. }
  1343. return 0;
  1344. }
  1345. /*
  1346. * initialize the codec volumes, etc
  1347. */
  1348. /*
  1349. * generic initialization of ADC, input mixers and output mixers
  1350. */
  1351. static struct hda_verb alc880_volume_init_verbs[] = {
  1352. /*
  1353. * Unmute ADC0-2 and set the default input to mic-in
  1354. */
  1355. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  1356. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1357. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  1358. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1359. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  1360. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1361. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  1362. * mixer widget
  1363. * Note: PASD motherboards uses the Line In 2 as the input for front
  1364. * panel mic (mic 2)
  1365. */
  1366. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  1367. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1368. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1369. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  1370. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  1371. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  1372. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  1373. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1374. /*
  1375. * Set up output mixers (0x0c - 0x0f)
  1376. */
  1377. /* set vol=0 to output mixers */
  1378. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1379. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1380. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1381. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1382. /* set up input amps for analog loopback */
  1383. /* Amp Indices: DAC = 0, mixer = 1 */
  1384. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1385. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1386. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1387. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1388. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1389. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1390. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1391. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1392. { }
  1393. };
  1394. /*
  1395. * 3-stack pin configuration:
  1396. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  1397. */
  1398. static struct hda_verb alc880_pin_3stack_init_verbs[] = {
  1399. /*
  1400. * preset connection lists of input pins
  1401. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  1402. */
  1403. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  1404. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1405. {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
  1406. /*
  1407. * Set pin mode and muting
  1408. */
  1409. /* set front pin widgets 0x14 for output */
  1410. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1411. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1412. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1413. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1414. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1415. /* Mic2 (as headphone out) for HP output */
  1416. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1417. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1418. /* Line In pin widget for input */
  1419. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1420. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1421. /* Line2 (as front mic) pin widget for input and vref at 80% */
  1422. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1423. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1424. /* CD pin widget for input */
  1425. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1426. { }
  1427. };
  1428. /*
  1429. * 5-stack pin configuration:
  1430. * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
  1431. * line-in/side = 0x1a, f-mic = 0x1b
  1432. */
  1433. static struct hda_verb alc880_pin_5stack_init_verbs[] = {
  1434. /*
  1435. * preset connection lists of input pins
  1436. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  1437. */
  1438. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1439. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
  1440. /*
  1441. * Set pin mode and muting
  1442. */
  1443. /* set pin widgets 0x14-0x17 for output */
  1444. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1445. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1446. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1447. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1448. /* unmute pins for output (no gain on this amp) */
  1449. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1450. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1451. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1452. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1453. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1454. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1455. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1456. /* Mic2 (as headphone out) for HP output */
  1457. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1458. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1459. /* Line In pin widget for input */
  1460. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1461. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1462. /* Line2 (as front mic) pin widget for input and vref at 80% */
  1463. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1464. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1465. /* CD pin widget for input */
  1466. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1467. { }
  1468. };
  1469. /*
  1470. * W810 pin configuration:
  1471. * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
  1472. */
  1473. static struct hda_verb alc880_pin_w810_init_verbs[] = {
  1474. /* hphone/speaker input selector: front DAC */
  1475. {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
  1476. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1477. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1478. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1479. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1480. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1481. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1482. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1483. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1484. { }
  1485. };
  1486. /*
  1487. * Z71V pin configuration:
  1488. * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
  1489. */
  1490. static struct hda_verb alc880_pin_z71v_init_verbs[] = {
  1491. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1492. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1493. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1494. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1495. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1496. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1497. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1498. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1499. { }
  1500. };
  1501. /*
  1502. * 6-stack pin configuration:
  1503. * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
  1504. * f-mic = 0x19, line = 0x1a, HP = 0x1b
  1505. */
  1506. static struct hda_verb alc880_pin_6stack_init_verbs[] = {
  1507. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1508. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1509. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1510. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1511. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1512. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1513. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1514. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1515. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1516. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1517. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1518. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1519. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1520. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1521. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1522. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1523. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1524. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1525. { }
  1526. };
  1527. /*
  1528. * Uniwill pin configuration:
  1529. * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
  1530. * line = 0x1a
  1531. */
  1532. static struct hda_verb alc880_uniwill_init_verbs[] = {
  1533. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1534. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1535. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1536. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1537. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1538. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1539. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1540. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1541. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1542. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1543. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1544. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1545. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1546. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1547. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1548. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1549. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1550. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1551. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1552. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1553. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1554. /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
  1555. /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
  1556. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1557. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  1558. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  1559. { }
  1560. };
  1561. /*
  1562. * Uniwill P53
  1563. * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
  1564. */
  1565. static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
  1566. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1567. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1568. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1569. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1570. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1571. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1572. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1573. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1574. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1575. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1576. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1577. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1578. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1579. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1580. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1581. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1582. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1583. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1584. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1585. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  1586. {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
  1587. { }
  1588. };
  1589. static struct hda_verb alc880_beep_init_verbs[] = {
  1590. { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
  1591. { }
  1592. };
  1593. /* toggle speaker-output according to the hp-jack state */
  1594. static void alc880_uniwill_hp_automute(struct hda_codec *codec)
  1595. {
  1596. unsigned int present;
  1597. unsigned char bits;
  1598. present = snd_hda_codec_read(codec, 0x14, 0,
  1599. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1600. bits = present ? HDA_AMP_MUTE : 0;
  1601. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  1602. HDA_AMP_MUTE, bits);
  1603. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  1604. HDA_AMP_MUTE, bits);
  1605. }
  1606. /* auto-toggle front mic */
  1607. static void alc880_uniwill_mic_automute(struct hda_codec *codec)
  1608. {
  1609. unsigned int present;
  1610. unsigned char bits;
  1611. present = snd_hda_codec_read(codec, 0x18, 0,
  1612. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1613. bits = present ? HDA_AMP_MUTE : 0;
  1614. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
  1615. }
  1616. static void alc880_uniwill_automute(struct hda_codec *codec)
  1617. {
  1618. alc880_uniwill_hp_automute(codec);
  1619. alc880_uniwill_mic_automute(codec);
  1620. }
  1621. static void alc880_uniwill_unsol_event(struct hda_codec *codec,
  1622. unsigned int res)
  1623. {
  1624. /* Looks like the unsol event is incompatible with the standard
  1625. * definition. 4bit tag is placed at 28 bit!
  1626. */
  1627. switch (res >> 28) {
  1628. case ALC880_HP_EVENT:
  1629. alc880_uniwill_hp_automute(codec);
  1630. break;
  1631. case ALC880_MIC_EVENT:
  1632. alc880_uniwill_mic_automute(codec);
  1633. break;
  1634. }
  1635. }
  1636. static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
  1637. {
  1638. unsigned int present;
  1639. unsigned char bits;
  1640. present = snd_hda_codec_read(codec, 0x14, 0,
  1641. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1642. bits = present ? HDA_AMP_MUTE : 0;
  1643. snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
  1644. }
  1645. static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
  1646. {
  1647. unsigned int present;
  1648. present = snd_hda_codec_read(codec, 0x21, 0,
  1649. AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
  1650. present &= HDA_AMP_VOLMASK;
  1651. snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
  1652. HDA_AMP_VOLMASK, present);
  1653. snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
  1654. HDA_AMP_VOLMASK, present);
  1655. }
  1656. static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
  1657. unsigned int res)
  1658. {
  1659. /* Looks like the unsol event is incompatible with the standard
  1660. * definition. 4bit tag is placed at 28 bit!
  1661. */
  1662. if ((res >> 28) == ALC880_HP_EVENT)
  1663. alc880_uniwill_p53_hp_automute(codec);
  1664. if ((res >> 28) == ALC880_DCVOL_EVENT)
  1665. alc880_uniwill_p53_dcvol_automute(codec);
  1666. }
  1667. /* FIXME! */
  1668. /*
  1669. * F1734 pin configuration:
  1670. * HP = 0x14, speaker-out = 0x15, mic = 0x18
  1671. */
  1672. static struct hda_verb alc880_pin_f1734_init_verbs[] = {
  1673. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
  1674. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
  1675. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
  1676. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
  1677. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1678. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1679. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1680. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1681. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1682. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1683. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1684. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1685. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1686. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1687. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1688. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1689. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1690. { }
  1691. };
  1692. /* FIXME! */
  1693. /*
  1694. * ASUS pin configuration:
  1695. * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
  1696. */
  1697. static struct hda_verb alc880_pin_asus_init_verbs[] = {
  1698. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
  1699. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
  1700. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
  1701. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
  1702. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1703. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1704. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1705. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1706. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1707. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1708. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1709. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1710. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1711. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1712. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1713. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1714. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1715. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1716. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1717. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1718. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1719. { }
  1720. };
  1721. /* Enable GPIO mask and set output */
  1722. #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
  1723. #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
  1724. /* Clevo m520g init */
  1725. static struct hda_verb alc880_pin_clevo_init_verbs[] = {
  1726. /* headphone output */
  1727. {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
  1728. /* line-out */
  1729. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1730. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1731. /* Line-in */
  1732. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1733. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1734. /* CD */
  1735. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1736. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1737. /* Mic1 (rear panel) */
  1738. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1739. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1740. /* Mic2 (front panel) */
  1741. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1742. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1743. /* headphone */
  1744. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1745. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1746. /* change to EAPD mode */
  1747. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1748. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  1749. { }
  1750. };
  1751. static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
  1752. /* change to EAPD mode */
  1753. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1754. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  1755. /* Headphone output */
  1756. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1757. /* Front output*/
  1758. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1759. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  1760. /* Line In pin widget for input */
  1761. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1762. /* CD pin widget for input */
  1763. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1764. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1765. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1766. /* change to EAPD mode */
  1767. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1768. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  1769. { }
  1770. };
  1771. /*
  1772. * LG m1 express dual
  1773. *
  1774. * Pin assignment:
  1775. * Rear Line-In/Out (blue): 0x14
  1776. * Build-in Mic-In: 0x15
  1777. * Speaker-out: 0x17
  1778. * HP-Out (green): 0x1b
  1779. * Mic-In/Out (red): 0x19
  1780. * SPDIF-Out: 0x1e
  1781. */
  1782. /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
  1783. static hda_nid_t alc880_lg_dac_nids[3] = {
  1784. 0x05, 0x02, 0x03
  1785. };
  1786. /* seems analog CD is not working */
  1787. static struct hda_input_mux alc880_lg_capture_source = {
  1788. .num_items = 3,
  1789. .items = {
  1790. { "Mic", 0x1 },
  1791. { "Line", 0x5 },
  1792. { "Internal Mic", 0x6 },
  1793. },
  1794. };
  1795. /* 2,4,6 channel modes */
  1796. static struct hda_verb alc880_lg_ch2_init[] = {
  1797. /* set line-in and mic-in to input */
  1798. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  1799. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  1800. { }
  1801. };
  1802. static struct hda_verb alc880_lg_ch4_init[] = {
  1803. /* set line-in to out and mic-in to input */
  1804. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1805. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  1806. { }
  1807. };
  1808. static struct hda_verb alc880_lg_ch6_init[] = {
  1809. /* set line-in and mic-in to output */
  1810. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1811. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1812. { }
  1813. };
  1814. static struct hda_channel_mode alc880_lg_ch_modes[3] = {
  1815. { 2, alc880_lg_ch2_init },
  1816. { 4, alc880_lg_ch4_init },
  1817. { 6, alc880_lg_ch6_init },
  1818. };
  1819. static struct snd_kcontrol_new alc880_lg_mixer[] = {
  1820. /* FIXME: it's not really "master" but front channels */
  1821. HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1822. HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
  1823. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1824. HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
  1825. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  1826. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  1827. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  1828. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  1829. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1830. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1831. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
  1832. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
  1833. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
  1834. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
  1835. {
  1836. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1837. .name = "Channel Mode",
  1838. .info = alc_ch_mode_info,
  1839. .get = alc_ch_mode_get,
  1840. .put = alc_ch_mode_put,
  1841. },
  1842. { } /* end */
  1843. };
  1844. static struct hda_verb alc880_lg_init_verbs[] = {
  1845. /* set capture source to mic-in */
  1846. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1847. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1848. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1849. /* mute all amp mixer inputs */
  1850. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
  1851. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  1852. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1853. /* line-in to input */
  1854. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1855. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1856. /* built-in mic */
  1857. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1858. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1859. /* speaker-out */
  1860. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1861. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1862. /* mic-in to input */
  1863. {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
  1864. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1865. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1866. /* HP-out */
  1867. {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
  1868. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1869. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1870. /* jack sense */
  1871. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
  1872. { }
  1873. };
  1874. /* toggle speaker-output according to the hp-jack state */
  1875. static void alc880_lg_automute(struct hda_codec *codec)
  1876. {
  1877. unsigned int present;
  1878. unsigned char bits;
  1879. present = snd_hda_codec_read(codec, 0x1b, 0,
  1880. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1881. bits = present ? HDA_AMP_MUTE : 0;
  1882. snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
  1883. HDA_AMP_MUTE, bits);
  1884. }
  1885. static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
  1886. {
  1887. /* Looks like the unsol event is incompatible with the standard
  1888. * definition. 4bit tag is placed at 28 bit!
  1889. */
  1890. if ((res >> 28) == 0x01)
  1891. alc880_lg_automute(codec);
  1892. }
  1893. /*
  1894. * LG LW20
  1895. *
  1896. * Pin assignment:
  1897. * Speaker-out: 0x14
  1898. * Mic-In: 0x18
  1899. * Built-in Mic-In: 0x19
  1900. * Line-In: 0x1b
  1901. * HP-Out: 0x1a
  1902. * SPDIF-Out: 0x1e
  1903. */
  1904. static struct hda_input_mux alc880_lg_lw_capture_source = {
  1905. .num_items = 3,
  1906. .items = {
  1907. { "Mic", 0x0 },
  1908. { "Internal Mic", 0x1 },
  1909. { "Line In", 0x2 },
  1910. },
  1911. };
  1912. #define alc880_lg_lw_modes alc880_threestack_modes
  1913. static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
  1914. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1915. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1916. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1917. HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
  1918. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1919. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1920. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1921. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1922. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1923. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1924. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1925. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1926. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  1927. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  1928. {
  1929. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1930. .name = "Channel Mode",
  1931. .info = alc_ch_mode_info,
  1932. .get = alc_ch_mode_get,
  1933. .put = alc_ch_mode_put,
  1934. },
  1935. { } /* end */
  1936. };
  1937. static struct hda_verb alc880_lg_lw_init_verbs[] = {
  1938. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1939. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  1940. {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
  1941. /* set capture source to mic-in */
  1942. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1943. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1944. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1945. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1946. /* speaker-out */
  1947. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1948. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1949. /* HP-out */
  1950. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1951. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1952. /* mic-in to input */
  1953. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1954. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1955. /* built-in mic */
  1956. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1957. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1958. /* jack sense */
  1959. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
  1960. { }
  1961. };
  1962. /* toggle speaker-output according to the hp-jack state */
  1963. static void alc880_lg_lw_automute(struct hda_codec *codec)
  1964. {
  1965. unsigned int present;
  1966. unsigned char bits;
  1967. present = snd_hda_codec_read(codec, 0x1b, 0,
  1968. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1969. bits = present ? HDA_AMP_MUTE : 0;
  1970. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  1971. HDA_AMP_MUTE, bits);
  1972. }
  1973. static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
  1974. {
  1975. /* Looks like the unsol event is incompatible with the standard
  1976. * definition. 4bit tag is placed at 28 bit!
  1977. */
  1978. if ((res >> 28) == 0x01)
  1979. alc880_lg_lw_automute(codec);
  1980. }
  1981. #ifdef CONFIG_SND_HDA_POWER_SAVE
  1982. static struct hda_amp_list alc880_loopbacks[] = {
  1983. { 0x0b, HDA_INPUT, 0 },
  1984. { 0x0b, HDA_INPUT, 1 },
  1985. { 0x0b, HDA_INPUT, 2 },
  1986. { 0x0b, HDA_INPUT, 3 },
  1987. { 0x0b, HDA_INPUT, 4 },
  1988. { } /* end */
  1989. };
  1990. static struct hda_amp_list alc880_lg_loopbacks[] = {
  1991. { 0x0b, HDA_INPUT, 1 },
  1992. { 0x0b, HDA_INPUT, 6 },
  1993. { 0x0b, HDA_INPUT, 7 },
  1994. { } /* end */
  1995. };
  1996. #endif
  1997. /*
  1998. * Common callbacks
  1999. */
  2000. static int alc_init(struct hda_codec *codec)
  2001. {
  2002. struct alc_spec *spec = codec->spec;
  2003. unsigned int i;
  2004. for (i = 0; i < spec->num_init_verbs; i++)
  2005. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  2006. if (spec->init_hook)
  2007. spec->init_hook(codec);
  2008. return 0;
  2009. }
  2010. static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
  2011. {
  2012. struct alc_spec *spec = codec->spec;
  2013. if (spec->unsol_event)
  2014. spec->unsol_event(codec, res);
  2015. }
  2016. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2017. static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
  2018. {
  2019. struct alc_spec *spec = codec->spec;
  2020. return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
  2021. }
  2022. #endif
  2023. /*
  2024. * Analog playback callbacks
  2025. */
  2026. static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
  2027. struct hda_codec *codec,
  2028. struct snd_pcm_substream *substream)
  2029. {
  2030. struct alc_spec *spec = codec->spec;
  2031. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
  2032. }
  2033. static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  2034. struct hda_codec *codec,
  2035. unsigned int stream_tag,
  2036. unsigned int format,
  2037. struct snd_pcm_substream *substream)
  2038. {
  2039. struct alc_spec *spec = codec->spec;
  2040. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
  2041. stream_tag, format, substream);
  2042. }
  2043. static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  2044. struct hda_codec *codec,
  2045. struct snd_pcm_substream *substream)
  2046. {
  2047. struct alc_spec *spec = codec->spec;
  2048. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  2049. }
  2050. /*
  2051. * Digital out
  2052. */
  2053. static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  2054. struct hda_codec *codec,
  2055. struct snd_pcm_substream *substream)
  2056. {
  2057. struct alc_spec *spec = codec->spec;
  2058. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  2059. }
  2060. static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  2061. struct hda_codec *codec,
  2062. unsigned int stream_tag,
  2063. unsigned int format,
  2064. struct snd_pcm_substream *substream)
  2065. {
  2066. struct alc_spec *spec = codec->spec;
  2067. return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
  2068. stream_tag, format, substream);
  2069. }
  2070. static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  2071. struct hda_codec *codec,
  2072. struct snd_pcm_substream *substream)
  2073. {
  2074. struct alc_spec *spec = codec->spec;
  2075. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  2076. }
  2077. /*
  2078. * Analog capture
  2079. */
  2080. static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  2081. struct hda_codec *codec,
  2082. unsigned int stream_tag,
  2083. unsigned int format,
  2084. struct snd_pcm_substream *substream)
  2085. {
  2086. struct alc_spec *spec = codec->spec;
  2087. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  2088. stream_tag, 0, format);
  2089. return 0;
  2090. }
  2091. static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  2092. struct hda_codec *codec,
  2093. struct snd_pcm_substream *substream)
  2094. {
  2095. struct alc_spec *spec = codec->spec;
  2096. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
  2097. 0, 0, 0);
  2098. return 0;
  2099. }
  2100. /*
  2101. */
  2102. static struct hda_pcm_stream alc880_pcm_analog_playback = {
  2103. .substreams = 1,
  2104. .channels_min = 2,
  2105. .channels_max = 8,
  2106. /* NID is set in alc_build_pcms */
  2107. .ops = {
  2108. .open = alc880_playback_pcm_open,
  2109. .prepare = alc880_playback_pcm_prepare,
  2110. .cleanup = alc880_playback_pcm_cleanup
  2111. },
  2112. };
  2113. static struct hda_pcm_stream alc880_pcm_analog_capture = {
  2114. .substreams = 2,
  2115. .channels_min = 2,
  2116. .channels_max = 2,
  2117. /* NID is set in alc_build_pcms */
  2118. .ops = {
  2119. .prepare = alc880_capture_pcm_prepare,
  2120. .cleanup = alc880_capture_pcm_cleanup
  2121. },
  2122. };
  2123. static struct hda_pcm_stream alc880_pcm_digital_playback = {
  2124. .substreams = 1,
  2125. .channels_min = 2,
  2126. .channels_max = 2,
  2127. /* NID is set in alc_build_pcms */
  2128. .ops = {
  2129. .open = alc880_dig_playback_pcm_open,
  2130. .close = alc880_dig_playback_pcm_close,
  2131. .prepare = alc880_dig_playback_pcm_prepare
  2132. },
  2133. };
  2134. static struct hda_pcm_stream alc880_pcm_digital_capture = {
  2135. .substreams = 1,
  2136. .channels_min = 2,
  2137. .channels_max = 2,
  2138. /* NID is set in alc_build_pcms */
  2139. };
  2140. /* Used by alc_build_pcms to flag that a PCM has no playback stream */
  2141. static struct hda_pcm_stream alc_pcm_null_playback = {
  2142. .substreams = 0,
  2143. .channels_min = 0,
  2144. .channels_max = 0,
  2145. };
  2146. static int alc_build_pcms(struct hda_codec *codec)
  2147. {
  2148. struct alc_spec *spec = codec->spec;
  2149. struct hda_pcm *info = spec->pcm_rec;
  2150. int i;
  2151. codec->num_pcms = 1;
  2152. codec->pcm_info = info;
  2153. info->name = spec->stream_name_analog;
  2154. if (spec->stream_analog_playback) {
  2155. snd_assert(spec->multiout.dac_nids, return -EINVAL);
  2156. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
  2157. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  2158. }
  2159. if (spec->stream_analog_capture) {
  2160. snd_assert(spec->adc_nids, return -EINVAL);
  2161. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
  2162. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  2163. }
  2164. if (spec->channel_mode) {
  2165. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
  2166. for (i = 0; i < spec->num_channel_mode; i++) {
  2167. if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
  2168. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
  2169. }
  2170. }
  2171. }
  2172. /* SPDIF for stream index #1 */
  2173. if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
  2174. codec->num_pcms = 2;
  2175. info = spec->pcm_rec + 1;
  2176. info->name = spec->stream_name_digital;
  2177. if (spec->multiout.dig_out_nid &&
  2178. spec->stream_digital_playback) {
  2179. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
  2180. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
  2181. }
  2182. if (spec->dig_in_nid &&
  2183. spec->stream_digital_capture) {
  2184. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
  2185. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
  2186. }
  2187. }
  2188. /* If the use of more than one ADC is requested for the current
  2189. * model, configure a second analog capture-only PCM.
  2190. */
  2191. /* Additional Analaog capture for index #2 */
  2192. if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
  2193. spec->adc_nids) {
  2194. codec->num_pcms = 3;
  2195. info = spec->pcm_rec + 2;
  2196. info->name = spec->stream_name_analog;
  2197. /* No playback stream for second PCM */
  2198. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
  2199. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
  2200. if (spec->stream_analog_capture) {
  2201. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
  2202. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
  2203. }
  2204. }
  2205. return 0;
  2206. }
  2207. static void alc_free(struct hda_codec *codec)
  2208. {
  2209. struct alc_spec *spec = codec->spec;
  2210. unsigned int i;
  2211. if (!spec)
  2212. return;
  2213. if (spec->kctl_alloc) {
  2214. for (i = 0; i < spec->num_kctl_used; i++)
  2215. kfree(spec->kctl_alloc[i].name);
  2216. kfree(spec->kctl_alloc);
  2217. }
  2218. kfree(spec);
  2219. }
  2220. /*
  2221. */
  2222. static struct hda_codec_ops alc_patch_ops = {
  2223. .build_controls = alc_build_controls,
  2224. .build_pcms = alc_build_pcms,
  2225. .init = alc_init,
  2226. .free = alc_free,
  2227. .unsol_event = alc_unsol_event,
  2228. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2229. .check_power_status = alc_check_power_status,
  2230. #endif
  2231. };
  2232. /*
  2233. * Test configuration for debugging
  2234. *
  2235. * Almost all inputs/outputs are enabled. I/O pins can be configured via
  2236. * enum controls.
  2237. */
  2238. #ifdef CONFIG_SND_DEBUG
  2239. static hda_nid_t alc880_test_dac_nids[4] = {
  2240. 0x02, 0x03, 0x04, 0x05
  2241. };
  2242. static struct hda_input_mux alc880_test_capture_source = {
  2243. .num_items = 7,
  2244. .items = {
  2245. { "In-1", 0x0 },
  2246. { "In-2", 0x1 },
  2247. { "In-3", 0x2 },
  2248. { "In-4", 0x3 },
  2249. { "CD", 0x4 },
  2250. { "Front", 0x5 },
  2251. { "Surround", 0x6 },
  2252. },
  2253. };
  2254. static struct hda_channel_mode alc880_test_modes[4] = {
  2255. { 2, NULL },
  2256. { 4, NULL },
  2257. { 6, NULL },
  2258. { 8, NULL },
  2259. };
  2260. static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
  2261. struct snd_ctl_elem_info *uinfo)
  2262. {
  2263. static char *texts[] = {
  2264. "N/A", "Line Out", "HP Out",
  2265. "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
  2266. };
  2267. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  2268. uinfo->count = 1;
  2269. uinfo->value.enumerated.items = 8;
  2270. if (uinfo->value.enumerated.item >= 8)
  2271. uinfo->value.enumerated.item = 7;
  2272. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  2273. return 0;
  2274. }
  2275. static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
  2276. struct snd_ctl_elem_value *ucontrol)
  2277. {
  2278. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2279. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2280. unsigned int pin_ctl, item = 0;
  2281. pin_ctl = snd_hda_codec_read(codec, nid, 0,
  2282. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  2283. if (pin_ctl & AC_PINCTL_OUT_EN) {
  2284. if (pin_ctl & AC_PINCTL_HP_EN)
  2285. item = 2;
  2286. else
  2287. item = 1;
  2288. } else if (pin_ctl & AC_PINCTL_IN_EN) {
  2289. switch (pin_ctl & AC_PINCTL_VREFEN) {
  2290. case AC_PINCTL_VREF_HIZ: item = 3; break;
  2291. case AC_PINCTL_VREF_50: item = 4; break;
  2292. case AC_PINCTL_VREF_GRD: item = 5; break;
  2293. case AC_PINCTL_VREF_80: item = 6; break;
  2294. case AC_PINCTL_VREF_100: item = 7; break;
  2295. }
  2296. }
  2297. ucontrol->value.enumerated.item[0] = item;
  2298. return 0;
  2299. }
  2300. static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
  2301. struct snd_ctl_elem_value *ucontrol)
  2302. {
  2303. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2304. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2305. static unsigned int ctls[] = {
  2306. 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
  2307. AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
  2308. AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
  2309. AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
  2310. AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
  2311. AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
  2312. };
  2313. unsigned int old_ctl, new_ctl;
  2314. old_ctl = snd_hda_codec_read(codec, nid, 0,
  2315. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  2316. new_ctl = ctls[ucontrol->value.enumerated.item[0]];
  2317. if (old_ctl != new_ctl) {
  2318. int val;
  2319. snd_hda_codec_write_cache(codec, nid, 0,
  2320. AC_VERB_SET_PIN_WIDGET_CONTROL,
  2321. new_ctl);
  2322. val = ucontrol->value.enumerated.item[0] >= 3 ?
  2323. HDA_AMP_MUTE : 0;
  2324. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  2325. HDA_AMP_MUTE, val);
  2326. return 1;
  2327. }
  2328. return 0;
  2329. }
  2330. static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
  2331. struct snd_ctl_elem_info *uinfo)
  2332. {
  2333. static char *texts[] = {
  2334. "Front", "Surround", "CLFE", "Side"
  2335. };
  2336. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  2337. uinfo->count = 1;
  2338. uinfo->value.enumerated.items = 4;
  2339. if (uinfo->value.enumerated.item >= 4)
  2340. uinfo->value.enumerated.item = 3;
  2341. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  2342. return 0;
  2343. }
  2344. static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
  2345. struct snd_ctl_elem_value *ucontrol)
  2346. {
  2347. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2348. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2349. unsigned int sel;
  2350. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
  2351. ucontrol->value.enumerated.item[0] = sel & 3;
  2352. return 0;
  2353. }
  2354. static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
  2355. struct snd_ctl_elem_value *ucontrol)
  2356. {
  2357. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2358. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2359. unsigned int sel;
  2360. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
  2361. if (ucontrol->value.enumerated.item[0] != sel) {
  2362. sel = ucontrol->value.enumerated.item[0] & 3;
  2363. snd_hda_codec_write_cache(codec, nid, 0,
  2364. AC_VERB_SET_CONNECT_SEL, sel);
  2365. return 1;
  2366. }
  2367. return 0;
  2368. }
  2369. #define PIN_CTL_TEST(xname,nid) { \
  2370. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  2371. .name = xname, \
  2372. .info = alc_test_pin_ctl_info, \
  2373. .get = alc_test_pin_ctl_get, \
  2374. .put = alc_test_pin_ctl_put, \
  2375. .private_value = nid \
  2376. }
  2377. #define PIN_SRC_TEST(xname,nid) { \
  2378. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  2379. .name = xname, \
  2380. .info = alc_test_pin_src_info, \
  2381. .get = alc_test_pin_src_get, \
  2382. .put = alc_test_pin_src_put, \
  2383. .private_value = nid \
  2384. }
  2385. static struct snd_kcontrol_new alc880_test_mixer[] = {
  2386. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  2387. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  2388. HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  2389. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  2390. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  2391. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  2392. HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
  2393. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  2394. PIN_CTL_TEST("Front Pin Mode", 0x14),
  2395. PIN_CTL_TEST("Surround Pin Mode", 0x15),
  2396. PIN_CTL_TEST("CLFE Pin Mode", 0x16),
  2397. PIN_CTL_TEST("Side Pin Mode", 0x17),
  2398. PIN_CTL_TEST("In-1 Pin Mode", 0x18),
  2399. PIN_CTL_TEST("In-2 Pin Mode", 0x19),
  2400. PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
  2401. PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
  2402. PIN_SRC_TEST("In-1 Pin Source", 0x18),
  2403. PIN_SRC_TEST("In-2 Pin Source", 0x19),
  2404. PIN_SRC_TEST("In-3 Pin Source", 0x1a),
  2405. PIN_SRC_TEST("In-4 Pin Source", 0x1b),
  2406. HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
  2407. HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
  2408. HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
  2409. HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
  2410. HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
  2411. HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
  2412. HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
  2413. HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
  2414. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
  2415. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
  2416. {
  2417. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  2418. .name = "Channel Mode",
  2419. .info = alc_ch_mode_info,
  2420. .get = alc_ch_mode_get,
  2421. .put = alc_ch_mode_put,
  2422. },
  2423. { } /* end */
  2424. };
  2425. static struct hda_verb alc880_test_init_verbs[] = {
  2426. /* Unmute inputs of 0x0c - 0x0f */
  2427. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2428. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2429. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2430. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2431. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2432. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2433. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2434. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2435. /* Vol output for 0x0c-0x0f */
  2436. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2437. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2438. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2439. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2440. /* Set output pins 0x14-0x17 */
  2441. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2442. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2443. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2444. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2445. /* Unmute output pins 0x14-0x17 */
  2446. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2447. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2448. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2449. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2450. /* Set input pins 0x18-0x1c */
  2451. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2452. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2453. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2454. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2455. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2456. /* Mute input pins 0x18-0x1b */
  2457. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2458. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2459. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2460. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2461. /* ADC set up */
  2462. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2463. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  2464. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2465. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  2466. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2467. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  2468. /* Analog input/passthru */
  2469. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2470. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2471. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2472. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2473. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2474. { }
  2475. };
  2476. #endif
  2477. /*
  2478. */
  2479. static const char *alc880_models[ALC880_MODEL_LAST] = {
  2480. [ALC880_3ST] = "3stack",
  2481. [ALC880_TCL_S700] = "tcl",
  2482. [ALC880_3ST_DIG] = "3stack-digout",
  2483. [ALC880_CLEVO] = "clevo",
  2484. [ALC880_5ST] = "5stack",
  2485. [ALC880_5ST_DIG] = "5stack-digout",
  2486. [ALC880_W810] = "w810",
  2487. [ALC880_Z71V] = "z71v",
  2488. [ALC880_6ST] = "6stack",
  2489. [ALC880_6ST_DIG] = "6stack-digout",
  2490. [ALC880_ASUS] = "asus",
  2491. [ALC880_ASUS_W1V] = "asus-w1v",
  2492. [ALC880_ASUS_DIG] = "asus-dig",
  2493. [ALC880_ASUS_DIG2] = "asus-dig2",
  2494. [ALC880_UNIWILL_DIG] = "uniwill",
  2495. [ALC880_UNIWILL_P53] = "uniwill-p53",
  2496. [ALC880_FUJITSU] = "fujitsu",
  2497. [ALC880_F1734] = "F1734",
  2498. [ALC880_LG] = "lg",
  2499. [ALC880_LG_LW] = "lg-lw",
  2500. #ifdef CONFIG_SND_DEBUG
  2501. [ALC880_TEST] = "test",
  2502. #endif
  2503. [ALC880_AUTO] = "auto",
  2504. };
  2505. static struct snd_pci_quirk alc880_cfg_tbl[] = {
  2506. SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
  2507. SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
  2508. SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
  2509. SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
  2510. SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
  2511. SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
  2512. SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
  2513. SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
  2514. SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
  2515. SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
  2516. SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
  2517. SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
  2518. SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
  2519. SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
  2520. SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
  2521. SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
  2522. SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
  2523. SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
  2524. /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
  2525. SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
  2526. SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
  2527. SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
  2528. SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
  2529. SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
  2530. SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
  2531. SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
  2532. SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
  2533. SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
  2534. SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
  2535. SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
  2536. SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
  2537. SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
  2538. SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
  2539. SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
  2540. SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
  2541. SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
  2542. SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
  2543. SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
  2544. SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
  2545. SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
  2546. SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
  2547. SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
  2548. SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
  2549. SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
  2550. SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
  2551. SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
  2552. SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
  2553. SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
  2554. SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
  2555. SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
  2556. SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
  2557. SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
  2558. SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
  2559. SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
  2560. SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
  2561. SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
  2562. SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
  2563. SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
  2564. SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
  2565. SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
  2566. SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
  2567. SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
  2568. SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
  2569. SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
  2570. SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
  2571. SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
  2572. SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
  2573. SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
  2574. SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
  2575. {}
  2576. };
  2577. /*
  2578. * ALC880 codec presets
  2579. */
  2580. static struct alc_config_preset alc880_presets[] = {
  2581. [ALC880_3ST] = {
  2582. .mixers = { alc880_three_stack_mixer },
  2583. .init_verbs = { alc880_volume_init_verbs,
  2584. alc880_pin_3stack_init_verbs },
  2585. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2586. .dac_nids = alc880_dac_nids,
  2587. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2588. .channel_mode = alc880_threestack_modes,
  2589. .need_dac_fix = 1,
  2590. .input_mux = &alc880_capture_source,
  2591. },
  2592. [ALC880_3ST_DIG] = {
  2593. .mixers = { alc880_three_stack_mixer },
  2594. .init_verbs = { alc880_volume_init_verbs,
  2595. alc880_pin_3stack_init_verbs },
  2596. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2597. .dac_nids = alc880_dac_nids,
  2598. .dig_out_nid = ALC880_DIGOUT_NID,
  2599. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2600. .channel_mode = alc880_threestack_modes,
  2601. .need_dac_fix = 1,
  2602. .input_mux = &alc880_capture_source,
  2603. },
  2604. [ALC880_TCL_S700] = {
  2605. .mixers = { alc880_tcl_s700_mixer },
  2606. .init_verbs = { alc880_volume_init_verbs,
  2607. alc880_pin_tcl_S700_init_verbs,
  2608. alc880_gpio2_init_verbs },
  2609. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2610. .dac_nids = alc880_dac_nids,
  2611. .hp_nid = 0x03,
  2612. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2613. .channel_mode = alc880_2_jack_modes,
  2614. .input_mux = &alc880_capture_source,
  2615. },
  2616. [ALC880_5ST] = {
  2617. .mixers = { alc880_three_stack_mixer,
  2618. alc880_five_stack_mixer},
  2619. .init_verbs = { alc880_volume_init_verbs,
  2620. alc880_pin_5stack_init_verbs },
  2621. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2622. .dac_nids = alc880_dac_nids,
  2623. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  2624. .channel_mode = alc880_fivestack_modes,
  2625. .input_mux = &alc880_capture_source,
  2626. },
  2627. [ALC880_5ST_DIG] = {
  2628. .mixers = { alc880_three_stack_mixer,
  2629. alc880_five_stack_mixer },
  2630. .init_verbs = { alc880_volume_init_verbs,
  2631. alc880_pin_5stack_init_verbs },
  2632. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2633. .dac_nids = alc880_dac_nids,
  2634. .dig_out_nid = ALC880_DIGOUT_NID,
  2635. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  2636. .channel_mode = alc880_fivestack_modes,
  2637. .input_mux = &alc880_capture_source,
  2638. },
  2639. [ALC880_6ST] = {
  2640. .mixers = { alc880_six_stack_mixer },
  2641. .init_verbs = { alc880_volume_init_verbs,
  2642. alc880_pin_6stack_init_verbs },
  2643. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  2644. .dac_nids = alc880_6st_dac_nids,
  2645. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  2646. .channel_mode = alc880_sixstack_modes,
  2647. .input_mux = &alc880_6stack_capture_source,
  2648. },
  2649. [ALC880_6ST_DIG] = {
  2650. .mixers = { alc880_six_stack_mixer },
  2651. .init_verbs = { alc880_volume_init_verbs,
  2652. alc880_pin_6stack_init_verbs },
  2653. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  2654. .dac_nids = alc880_6st_dac_nids,
  2655. .dig_out_nid = ALC880_DIGOUT_NID,
  2656. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  2657. .channel_mode = alc880_sixstack_modes,
  2658. .input_mux = &alc880_6stack_capture_source,
  2659. },
  2660. [ALC880_W810] = {
  2661. .mixers = { alc880_w810_base_mixer },
  2662. .init_verbs = { alc880_volume_init_verbs,
  2663. alc880_pin_w810_init_verbs,
  2664. alc880_gpio2_init_verbs },
  2665. .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
  2666. .dac_nids = alc880_w810_dac_nids,
  2667. .dig_out_nid = ALC880_DIGOUT_NID,
  2668. .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
  2669. .channel_mode = alc880_w810_modes,
  2670. .input_mux = &alc880_capture_source,
  2671. },
  2672. [ALC880_Z71V] = {
  2673. .mixers = { alc880_z71v_mixer },
  2674. .init_verbs = { alc880_volume_init_verbs,
  2675. alc880_pin_z71v_init_verbs },
  2676. .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
  2677. .dac_nids = alc880_z71v_dac_nids,
  2678. .dig_out_nid = ALC880_DIGOUT_NID,
  2679. .hp_nid = 0x03,
  2680. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2681. .channel_mode = alc880_2_jack_modes,
  2682. .input_mux = &alc880_capture_source,
  2683. },
  2684. [ALC880_F1734] = {
  2685. .mixers = { alc880_f1734_mixer },
  2686. .init_verbs = { alc880_volume_init_verbs,
  2687. alc880_pin_f1734_init_verbs },
  2688. .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
  2689. .dac_nids = alc880_f1734_dac_nids,
  2690. .hp_nid = 0x02,
  2691. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2692. .channel_mode = alc880_2_jack_modes,
  2693. .input_mux = &alc880_capture_source,
  2694. },
  2695. [ALC880_ASUS] = {
  2696. .mixers = { alc880_asus_mixer },
  2697. .init_verbs = { alc880_volume_init_verbs,
  2698. alc880_pin_asus_init_verbs,
  2699. alc880_gpio1_init_verbs },
  2700. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2701. .dac_nids = alc880_asus_dac_nids,
  2702. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2703. .channel_mode = alc880_asus_modes,
  2704. .need_dac_fix = 1,
  2705. .input_mux = &alc880_capture_source,
  2706. },
  2707. [ALC880_ASUS_DIG] = {
  2708. .mixers = { alc880_asus_mixer },
  2709. .init_verbs = { alc880_volume_init_verbs,
  2710. alc880_pin_asus_init_verbs,
  2711. alc880_gpio1_init_verbs },
  2712. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2713. .dac_nids = alc880_asus_dac_nids,
  2714. .dig_out_nid = ALC880_DIGOUT_NID,
  2715. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2716. .channel_mode = alc880_asus_modes,
  2717. .need_dac_fix = 1,
  2718. .input_mux = &alc880_capture_source,
  2719. },
  2720. [ALC880_ASUS_DIG2] = {
  2721. .mixers = { alc880_asus_mixer },
  2722. .init_verbs = { alc880_volume_init_verbs,
  2723. alc880_pin_asus_init_verbs,
  2724. alc880_gpio2_init_verbs }, /* use GPIO2 */
  2725. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2726. .dac_nids = alc880_asus_dac_nids,
  2727. .dig_out_nid = ALC880_DIGOUT_NID,
  2728. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2729. .channel_mode = alc880_asus_modes,
  2730. .need_dac_fix = 1,
  2731. .input_mux = &alc880_capture_source,
  2732. },
  2733. [ALC880_ASUS_W1V] = {
  2734. .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
  2735. .init_verbs = { alc880_volume_init_verbs,
  2736. alc880_pin_asus_init_verbs,
  2737. alc880_gpio1_init_verbs },
  2738. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2739. .dac_nids = alc880_asus_dac_nids,
  2740. .dig_out_nid = ALC880_DIGOUT_NID,
  2741. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2742. .channel_mode = alc880_asus_modes,
  2743. .need_dac_fix = 1,
  2744. .input_mux = &alc880_capture_source,
  2745. },
  2746. [ALC880_UNIWILL_DIG] = {
  2747. .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
  2748. .init_verbs = { alc880_volume_init_verbs,
  2749. alc880_pin_asus_init_verbs },
  2750. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2751. .dac_nids = alc880_asus_dac_nids,
  2752. .dig_out_nid = ALC880_DIGOUT_NID,
  2753. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2754. .channel_mode = alc880_asus_modes,
  2755. .need_dac_fix = 1,
  2756. .input_mux = &alc880_capture_source,
  2757. },
  2758. [ALC880_UNIWILL] = {
  2759. .mixers = { alc880_uniwill_mixer },
  2760. .init_verbs = { alc880_volume_init_verbs,
  2761. alc880_uniwill_init_verbs },
  2762. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2763. .dac_nids = alc880_asus_dac_nids,
  2764. .dig_out_nid = ALC880_DIGOUT_NID,
  2765. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2766. .channel_mode = alc880_threestack_modes,
  2767. .need_dac_fix = 1,
  2768. .input_mux = &alc880_capture_source,
  2769. .unsol_event = alc880_uniwill_unsol_event,
  2770. .init_hook = alc880_uniwill_automute,
  2771. },
  2772. [ALC880_UNIWILL_P53] = {
  2773. .mixers = { alc880_uniwill_p53_mixer },
  2774. .init_verbs = { alc880_volume_init_verbs,
  2775. alc880_uniwill_p53_init_verbs },
  2776. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2777. .dac_nids = alc880_asus_dac_nids,
  2778. .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
  2779. .channel_mode = alc880_threestack_modes,
  2780. .input_mux = &alc880_capture_source,
  2781. .unsol_event = alc880_uniwill_p53_unsol_event,
  2782. .init_hook = alc880_uniwill_p53_hp_automute,
  2783. },
  2784. [ALC880_FUJITSU] = {
  2785. .mixers = { alc880_fujitsu_mixer,
  2786. alc880_pcbeep_mixer, },
  2787. .init_verbs = { alc880_volume_init_verbs,
  2788. alc880_uniwill_p53_init_verbs,
  2789. alc880_beep_init_verbs },
  2790. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2791. .dac_nids = alc880_dac_nids,
  2792. .dig_out_nid = ALC880_DIGOUT_NID,
  2793. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2794. .channel_mode = alc880_2_jack_modes,
  2795. .input_mux = &alc880_capture_source,
  2796. .unsol_event = alc880_uniwill_p53_unsol_event,
  2797. .init_hook = alc880_uniwill_p53_hp_automute,
  2798. },
  2799. [ALC880_CLEVO] = {
  2800. .mixers = { alc880_three_stack_mixer },
  2801. .init_verbs = { alc880_volume_init_verbs,
  2802. alc880_pin_clevo_init_verbs },
  2803. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2804. .dac_nids = alc880_dac_nids,
  2805. .hp_nid = 0x03,
  2806. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2807. .channel_mode = alc880_threestack_modes,
  2808. .need_dac_fix = 1,
  2809. .input_mux = &alc880_capture_source,
  2810. },
  2811. [ALC880_LG] = {
  2812. .mixers = { alc880_lg_mixer },
  2813. .init_verbs = { alc880_volume_init_verbs,
  2814. alc880_lg_init_verbs },
  2815. .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
  2816. .dac_nids = alc880_lg_dac_nids,
  2817. .dig_out_nid = ALC880_DIGOUT_NID,
  2818. .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
  2819. .channel_mode = alc880_lg_ch_modes,
  2820. .need_dac_fix = 1,
  2821. .input_mux = &alc880_lg_capture_source,
  2822. .unsol_event = alc880_lg_unsol_event,
  2823. .init_hook = alc880_lg_automute,
  2824. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2825. .loopbacks = alc880_lg_loopbacks,
  2826. #endif
  2827. },
  2828. [ALC880_LG_LW] = {
  2829. .mixers = { alc880_lg_lw_mixer },
  2830. .init_verbs = { alc880_volume_init_verbs,
  2831. alc880_lg_lw_init_verbs },
  2832. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2833. .dac_nids = alc880_dac_nids,
  2834. .dig_out_nid = ALC880_DIGOUT_NID,
  2835. .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
  2836. .channel_mode = alc880_lg_lw_modes,
  2837. .input_mux = &alc880_lg_lw_capture_source,
  2838. .unsol_event = alc880_lg_lw_unsol_event,
  2839. .init_hook = alc880_lg_lw_automute,
  2840. },
  2841. #ifdef CONFIG_SND_DEBUG
  2842. [ALC880_TEST] = {
  2843. .mixers = { alc880_test_mixer },
  2844. .init_verbs = { alc880_test_init_verbs },
  2845. .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
  2846. .dac_nids = alc880_test_dac_nids,
  2847. .dig_out_nid = ALC880_DIGOUT_NID,
  2848. .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
  2849. .channel_mode = alc880_test_modes,
  2850. .input_mux = &alc880_test_capture_source,
  2851. },
  2852. #endif
  2853. };
  2854. /*
  2855. * Automatic parse of I/O pins from the BIOS configuration
  2856. */
  2857. #define NUM_CONTROL_ALLOC 32
  2858. #define NUM_VERB_ALLOC 32
  2859. enum {
  2860. ALC_CTL_WIDGET_VOL,
  2861. ALC_CTL_WIDGET_MUTE,
  2862. ALC_CTL_BIND_MUTE,
  2863. };
  2864. static struct snd_kcontrol_new alc880_control_templates[] = {
  2865. HDA_CODEC_VOLUME(NULL, 0, 0, 0),
  2866. HDA_CODEC_MUTE(NULL, 0, 0, 0),
  2867. HDA_BIND_MUTE(NULL, 0, 0, 0),
  2868. };
  2869. /* add dynamic controls */
  2870. static int add_control(struct alc_spec *spec, int type, const char *name,
  2871. unsigned long val)
  2872. {
  2873. struct snd_kcontrol_new *knew;
  2874. if (spec->num_kctl_used >= spec->num_kctl_alloc) {
  2875. int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
  2876. /* array + terminator */
  2877. knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
  2878. if (!knew)
  2879. return -ENOMEM;
  2880. if (spec->kctl_alloc) {
  2881. memcpy(knew, spec->kctl_alloc,
  2882. sizeof(*knew) * spec->num_kctl_alloc);
  2883. kfree(spec->kctl_alloc);
  2884. }
  2885. spec->kctl_alloc = knew;
  2886. spec->num_kctl_alloc = num;
  2887. }
  2888. knew = &spec->kctl_alloc[spec->num_kctl_used];
  2889. *knew = alc880_control_templates[type];
  2890. knew->name = kstrdup(name, GFP_KERNEL);
  2891. if (!knew->name)
  2892. return -ENOMEM;
  2893. knew->private_value = val;
  2894. spec->num_kctl_used++;
  2895. return 0;
  2896. }
  2897. #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
  2898. #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
  2899. #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
  2900. #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
  2901. #define alc880_is_input_pin(nid) ((nid) >= 0x18)
  2902. #define alc880_input_pin_idx(nid) ((nid) - 0x18)
  2903. #define alc880_idx_to_dac(nid) ((nid) + 0x02)
  2904. #define alc880_dac_to_idx(nid) ((nid) - 0x02)
  2905. #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
  2906. #define alc880_idx_to_selector(nid) ((nid) + 0x10)
  2907. #define ALC880_PIN_CD_NID 0x1c
  2908. /* fill in the dac_nids table from the parsed pin configuration */
  2909. static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
  2910. const struct auto_pin_cfg *cfg)
  2911. {
  2912. hda_nid_t nid;
  2913. int assigned[4];
  2914. int i, j;
  2915. memset(assigned, 0, sizeof(assigned));
  2916. spec->multiout.dac_nids = spec->private_dac_nids;
  2917. /* check the pins hardwired to audio widget */
  2918. for (i = 0; i < cfg->line_outs; i++) {
  2919. nid = cfg->line_out_pins[i];
  2920. if (alc880_is_fixed_pin(nid)) {
  2921. int idx = alc880_fixed_pin_idx(nid);
  2922. spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
  2923. assigned[idx] = 1;
  2924. }
  2925. }
  2926. /* left pins can be connect to any audio widget */
  2927. for (i = 0; i < cfg->line_outs; i++) {
  2928. nid = cfg->line_out_pins[i];
  2929. if (alc880_is_fixed_pin(nid))
  2930. continue;
  2931. /* search for an empty channel */
  2932. for (j = 0; j < cfg->line_outs; j++) {
  2933. if (!assigned[j]) {
  2934. spec->multiout.dac_nids[i] =
  2935. alc880_idx_to_dac(j);
  2936. assigned[j] = 1;
  2937. break;
  2938. }
  2939. }
  2940. }
  2941. spec->multiout.num_dacs = cfg->line_outs;
  2942. return 0;
  2943. }
  2944. /* add playback controls from the parsed DAC table */
  2945. static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
  2946. const struct auto_pin_cfg *cfg)
  2947. {
  2948. char name[32];
  2949. static const char *chname[4] = {
  2950. "Front", "Surround", NULL /*CLFE*/, "Side"
  2951. };
  2952. hda_nid_t nid;
  2953. int i, err;
  2954. for (i = 0; i < cfg->line_outs; i++) {
  2955. if (!spec->multiout.dac_nids[i])
  2956. continue;
  2957. nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
  2958. if (i == 2) {
  2959. /* Center/LFE */
  2960. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  2961. "Center Playback Volume",
  2962. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  2963. HDA_OUTPUT));
  2964. if (err < 0)
  2965. return err;
  2966. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  2967. "LFE Playback Volume",
  2968. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  2969. HDA_OUTPUT));
  2970. if (err < 0)
  2971. return err;
  2972. err = add_control(spec, ALC_CTL_BIND_MUTE,
  2973. "Center Playback Switch",
  2974. HDA_COMPOSE_AMP_VAL(nid, 1, 2,
  2975. HDA_INPUT));
  2976. if (err < 0)
  2977. return err;
  2978. err = add_control(spec, ALC_CTL_BIND_MUTE,
  2979. "LFE Playback Switch",
  2980. HDA_COMPOSE_AMP_VAL(nid, 2, 2,
  2981. HDA_INPUT));
  2982. if (err < 0)
  2983. return err;
  2984. } else {
  2985. sprintf(name, "%s Playback Volume", chname[i]);
  2986. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  2987. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  2988. HDA_OUTPUT));
  2989. if (err < 0)
  2990. return err;
  2991. sprintf(name, "%s Playback Switch", chname[i]);
  2992. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  2993. HDA_COMPOSE_AMP_VAL(nid, 3, 2,
  2994. HDA_INPUT));
  2995. if (err < 0)
  2996. return err;
  2997. }
  2998. }
  2999. return 0;
  3000. }
  3001. /* add playback controls for speaker and HP outputs */
  3002. static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
  3003. const char *pfx)
  3004. {
  3005. hda_nid_t nid;
  3006. int err;
  3007. char name[32];
  3008. if (!pin)
  3009. return 0;
  3010. if (alc880_is_fixed_pin(pin)) {
  3011. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  3012. /* specify the DAC as the extra output */
  3013. if (!spec->multiout.hp_nid)
  3014. spec->multiout.hp_nid = nid;
  3015. else
  3016. spec->multiout.extra_out_nid[0] = nid;
  3017. /* control HP volume/switch on the output mixer amp */
  3018. nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
  3019. sprintf(name, "%s Playback Volume", pfx);
  3020. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  3021. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  3022. if (err < 0)
  3023. return err;
  3024. sprintf(name, "%s Playback Switch", pfx);
  3025. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  3026. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
  3027. if (err < 0)
  3028. return err;
  3029. } else if (alc880_is_multi_pin(pin)) {
  3030. /* set manual connection */
  3031. /* we have only a switch on HP-out PIN */
  3032. sprintf(name, "%s Playback Switch", pfx);
  3033. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  3034. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  3035. if (err < 0)
  3036. return err;
  3037. }
  3038. return 0;
  3039. }
  3040. /* create input playback/capture controls for the given pin */
  3041. static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
  3042. const char *ctlname,
  3043. int idx, hda_nid_t mix_nid)
  3044. {
  3045. char name[32];
  3046. int err;
  3047. sprintf(name, "%s Playback Volume", ctlname);
  3048. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  3049. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  3050. if (err < 0)
  3051. return err;
  3052. sprintf(name, "%s Playback Switch", ctlname);
  3053. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  3054. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  3055. if (err < 0)
  3056. return err;
  3057. return 0;
  3058. }
  3059. /* create playback/capture controls for input pins */
  3060. static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
  3061. const struct auto_pin_cfg *cfg)
  3062. {
  3063. struct hda_input_mux *imux = &spec->private_imux;
  3064. int i, err, idx;
  3065. for (i = 0; i < AUTO_PIN_LAST; i++) {
  3066. if (alc880_is_input_pin(cfg->input_pins[i])) {
  3067. idx = alc880_input_pin_idx(cfg->input_pins[i]);
  3068. err = new_analog_input(spec, cfg->input_pins[i],
  3069. auto_pin_cfg_labels[i],
  3070. idx, 0x0b);
  3071. if (err < 0)
  3072. return err;
  3073. imux->items[imux->num_items].label =
  3074. auto_pin_cfg_labels[i];
  3075. imux->items[imux->num_items].index =
  3076. alc880_input_pin_idx(cfg->input_pins[i]);
  3077. imux->num_items++;
  3078. }
  3079. }
  3080. return 0;
  3081. }
  3082. static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
  3083. hda_nid_t nid, int pin_type,
  3084. int dac_idx)
  3085. {
  3086. /* set as output */
  3087. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  3088. pin_type);
  3089. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  3090. AMP_OUT_UNMUTE);
  3091. /* need the manual connection? */
  3092. if (alc880_is_multi_pin(nid)) {
  3093. struct alc_spec *spec = codec->spec;
  3094. int idx = alc880_multi_pin_idx(nid);
  3095. snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
  3096. AC_VERB_SET_CONNECT_SEL,
  3097. alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
  3098. }
  3099. }
  3100. static int get_pin_type(int line_out_type)
  3101. {
  3102. if (line_out_type == AUTO_PIN_HP_OUT)
  3103. return PIN_HP;
  3104. else
  3105. return PIN_OUT;
  3106. }
  3107. static void alc880_auto_init_multi_out(struct hda_codec *codec)
  3108. {
  3109. struct alc_spec *spec = codec->spec;
  3110. int i;
  3111. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  3112. for (i = 0; i < spec->autocfg.line_outs; i++) {
  3113. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  3114. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  3115. alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
  3116. }
  3117. }
  3118. static void alc880_auto_init_extra_out(struct hda_codec *codec)
  3119. {
  3120. struct alc_spec *spec = codec->spec;
  3121. hda_nid_t pin;
  3122. pin = spec->autocfg.speaker_pins[0];
  3123. if (pin) /* connect to front */
  3124. alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  3125. pin = spec->autocfg.hp_pins[0];
  3126. if (pin) /* connect to front */
  3127. alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  3128. }
  3129. static void alc880_auto_init_analog_input(struct hda_codec *codec)
  3130. {
  3131. struct alc_spec *spec = codec->spec;
  3132. int i;
  3133. for (i = 0; i < AUTO_PIN_LAST; i++) {
  3134. hda_nid_t nid = spec->autocfg.input_pins[i];
  3135. if (alc880_is_input_pin(nid)) {
  3136. snd_hda_codec_write(codec, nid, 0,
  3137. AC_VERB_SET_PIN_WIDGET_CONTROL,
  3138. i <= AUTO_PIN_FRONT_MIC ?
  3139. PIN_VREF80 : PIN_IN);
  3140. if (nid != ALC880_PIN_CD_NID)
  3141. snd_hda_codec_write(codec, nid, 0,
  3142. AC_VERB_SET_AMP_GAIN_MUTE,
  3143. AMP_OUT_MUTE);
  3144. }
  3145. }
  3146. }
  3147. /* parse the BIOS configuration and set up the alc_spec */
  3148. /* return 1 if successful, 0 if the proper config is not found,
  3149. * or a negative error code
  3150. */
  3151. static int alc880_parse_auto_config(struct hda_codec *codec)
  3152. {
  3153. struct alc_spec *spec = codec->spec;
  3154. int err;
  3155. static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
  3156. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  3157. alc880_ignore);
  3158. if (err < 0)
  3159. return err;
  3160. if (!spec->autocfg.line_outs)
  3161. return 0; /* can't find valid BIOS pin config */
  3162. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  3163. if (err < 0)
  3164. return err;
  3165. err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
  3166. if (err < 0)
  3167. return err;
  3168. err = alc880_auto_create_extra_out(spec,
  3169. spec->autocfg.speaker_pins[0],
  3170. "Speaker");
  3171. if (err < 0)
  3172. return err;
  3173. err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
  3174. "Headphone");
  3175. if (err < 0)
  3176. return err;
  3177. err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
  3178. if (err < 0)
  3179. return err;
  3180. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  3181. if (spec->autocfg.dig_out_pin)
  3182. spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
  3183. if (spec->autocfg.dig_in_pin)
  3184. spec->dig_in_nid = ALC880_DIGIN_NID;
  3185. if (spec->kctl_alloc)
  3186. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  3187. spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
  3188. spec->num_mux_defs = 1;
  3189. spec->input_mux = &spec->private_imux;
  3190. return 1;
  3191. }
  3192. /* additional initialization for auto-configuration model */
  3193. static void alc880_auto_init(struct hda_codec *codec)
  3194. {
  3195. alc880_auto_init_multi_out(codec);
  3196. alc880_auto_init_extra_out(codec);
  3197. alc880_auto_init_analog_input(codec);
  3198. }
  3199. /*
  3200. * OK, here we have finally the patch for ALC880
  3201. */
  3202. static int patch_alc880(struct hda_codec *codec)
  3203. {
  3204. struct alc_spec *spec;
  3205. int board_config;
  3206. int err;
  3207. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  3208. if (spec == NULL)
  3209. return -ENOMEM;
  3210. codec->spec = spec;
  3211. board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
  3212. alc880_models,
  3213. alc880_cfg_tbl);
  3214. if (board_config < 0) {
  3215. printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
  3216. "trying auto-probe from BIOS...\n");
  3217. board_config = ALC880_AUTO;
  3218. }
  3219. if (board_config == ALC880_AUTO) {
  3220. /* automatic parse from the BIOS config */
  3221. err = alc880_parse_auto_config(codec);
  3222. if (err < 0) {
  3223. alc_free(codec);
  3224. return err;
  3225. } else if (!err) {
  3226. printk(KERN_INFO
  3227. "hda_codec: Cannot set up configuration "
  3228. "from BIOS. Using 3-stack mode...\n");
  3229. board_config = ALC880_3ST;
  3230. }
  3231. }
  3232. if (board_config != ALC880_AUTO)
  3233. setup_preset(spec, &alc880_presets[board_config]);
  3234. spec->stream_name_analog = "ALC880 Analog";
  3235. spec->stream_analog_playback = &alc880_pcm_analog_playback;
  3236. spec->stream_analog_capture = &alc880_pcm_analog_capture;
  3237. spec->stream_name_digital = "ALC880 Digital";
  3238. spec->stream_digital_playback = &alc880_pcm_digital_playback;
  3239. spec->stream_digital_capture = &alc880_pcm_digital_capture;
  3240. if (!spec->adc_nids && spec->input_mux) {
  3241. /* check whether NID 0x07 is valid */
  3242. unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
  3243. /* get type */
  3244. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  3245. if (wcap != AC_WID_AUD_IN) {
  3246. spec->adc_nids = alc880_adc_nids_alt;
  3247. spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
  3248. spec->mixers[spec->num_mixers] =
  3249. alc880_capture_alt_mixer;
  3250. spec->num_mixers++;
  3251. } else {
  3252. spec->adc_nids = alc880_adc_nids;
  3253. spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
  3254. spec->mixers[spec->num_mixers] = alc880_capture_mixer;
  3255. spec->num_mixers++;
  3256. }
  3257. }
  3258. codec->patch_ops = alc_patch_ops;
  3259. if (board_config == ALC880_AUTO)
  3260. spec->init_hook = alc880_auto_init;
  3261. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3262. if (!spec->loopback.amplist)
  3263. spec->loopback.amplist = alc880_loopbacks;
  3264. #endif
  3265. return 0;
  3266. }
  3267. /*
  3268. * ALC260 support
  3269. */
  3270. static hda_nid_t alc260_dac_nids[1] = {
  3271. /* front */
  3272. 0x02,
  3273. };
  3274. static hda_nid_t alc260_adc_nids[1] = {
  3275. /* ADC0 */
  3276. 0x04,
  3277. };
  3278. static hda_nid_t alc260_adc_nids_alt[1] = {
  3279. /* ADC1 */
  3280. 0x05,
  3281. };
  3282. static hda_nid_t alc260_hp_adc_nids[2] = {
  3283. /* ADC1, 0 */
  3284. 0x05, 0x04
  3285. };
  3286. /* NIDs used when simultaneous access to both ADCs makes sense. Note that
  3287. * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
  3288. */
  3289. static hda_nid_t alc260_dual_adc_nids[2] = {
  3290. /* ADC0, ADC1 */
  3291. 0x04, 0x05
  3292. };
  3293. #define ALC260_DIGOUT_NID 0x03
  3294. #define ALC260_DIGIN_NID 0x06
  3295. static struct hda_input_mux alc260_capture_source = {
  3296. .num_items = 4,
  3297. .items = {
  3298. { "Mic", 0x0 },
  3299. { "Front Mic", 0x1 },
  3300. { "Line", 0x2 },
  3301. { "CD", 0x4 },
  3302. },
  3303. };
  3304. /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
  3305. * headphone jack and the internal CD lines since these are the only pins at
  3306. * which audio can appear. For flexibility, also allow the option of
  3307. * recording the mixer output on the second ADC (ADC0 doesn't have a
  3308. * connection to the mixer output).
  3309. */
  3310. static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
  3311. {
  3312. .num_items = 3,
  3313. .items = {
  3314. { "Mic/Line", 0x0 },
  3315. { "CD", 0x4 },
  3316. { "Headphone", 0x2 },
  3317. },
  3318. },
  3319. {
  3320. .num_items = 4,
  3321. .items = {
  3322. { "Mic/Line", 0x0 },
  3323. { "CD", 0x4 },
  3324. { "Headphone", 0x2 },
  3325. { "Mixer", 0x5 },
  3326. },
  3327. },
  3328. };
  3329. /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
  3330. * the Fujitsu S702x, but jacks are marked differently.
  3331. */
  3332. static struct hda_input_mux alc260_acer_capture_sources[2] = {
  3333. {
  3334. .num_items = 4,
  3335. .items = {
  3336. { "Mic", 0x0 },
  3337. { "Line", 0x2 },
  3338. { "CD", 0x4 },
  3339. { "Headphone", 0x5 },
  3340. },
  3341. },
  3342. {
  3343. .num_items = 5,
  3344. .items = {
  3345. { "Mic", 0x0 },
  3346. { "Line", 0x2 },
  3347. { "CD", 0x4 },
  3348. { "Headphone", 0x6 },
  3349. { "Mixer", 0x5 },
  3350. },
  3351. },
  3352. };
  3353. /*
  3354. * This is just place-holder, so there's something for alc_build_pcms to look
  3355. * at when it calculates the maximum number of channels. ALC260 has no mixer
  3356. * element which allows changing the channel mode, so the verb list is
  3357. * never used.
  3358. */
  3359. static struct hda_channel_mode alc260_modes[1] = {
  3360. { 2, NULL },
  3361. };
  3362. /* Mixer combinations
  3363. *
  3364. * basic: base_output + input + pc_beep + capture
  3365. * HP: base_output + input + capture_alt
  3366. * HP_3013: hp_3013 + input + capture
  3367. * fujitsu: fujitsu + capture
  3368. * acer: acer + capture
  3369. */
  3370. static struct snd_kcontrol_new alc260_base_output_mixer[] = {
  3371. HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3372. HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
  3373. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3374. HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
  3375. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  3376. HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
  3377. { } /* end */
  3378. };
  3379. static struct snd_kcontrol_new alc260_input_mixer[] = {
  3380. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3381. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3382. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3383. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3384. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3385. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3386. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
  3387. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
  3388. { } /* end */
  3389. };
  3390. static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
  3391. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
  3392. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
  3393. { } /* end */
  3394. };
  3395. static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
  3396. HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3397. HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  3398. HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
  3399. HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
  3400. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3401. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  3402. HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  3403. HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
  3404. { } /* end */
  3405. };
  3406. /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
  3407. * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
  3408. */
  3409. static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
  3410. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3411. HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
  3412. ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3413. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3414. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3415. HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
  3416. HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
  3417. ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3418. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3419. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3420. HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3421. HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
  3422. { } /* end */
  3423. };
  3424. /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
  3425. * versions of the ALC260 don't act on requests to enable mic bias from NID
  3426. * 0x0f (used to drive the headphone jack in these laptops). The ALC260
  3427. * datasheet doesn't mention this restriction. At this stage it's not clear
  3428. * whether this behaviour is intentional or is a hardware bug in chip
  3429. * revisions available in early 2006. Therefore for now allow the
  3430. * "Headphone Jack Mode" control to span all choices, but if it turns out
  3431. * that the lack of mic bias for this NID is intentional we could change the
  3432. * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
  3433. *
  3434. * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
  3435. * don't appear to make the mic bias available from the "line" jack, even
  3436. * though the NID used for this jack (0x14) can supply it. The theory is
  3437. * that perhaps Acer have included blocking capacitors between the ALC260
  3438. * and the output jack. If this turns out to be the case for all such
  3439. * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
  3440. * to ALC_PIN_DIR_INOUT_NOMICBIAS.
  3441. *
  3442. * The C20x Tablet series have a mono internal speaker which is controlled
  3443. * via the chip's Mono sum widget and pin complex, so include the necessary
  3444. * controls for such models. On models without a "mono speaker" the control
  3445. * won't do anything.
  3446. */
  3447. static struct snd_kcontrol_new alc260_acer_mixer[] = {
  3448. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3449. HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
  3450. ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
  3451. HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
  3452. HDA_OUTPUT),
  3453. HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
  3454. HDA_INPUT),
  3455. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3456. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3457. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3458. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3459. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3460. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3461. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3462. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3463. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3464. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3465. { } /* end */
  3466. };
  3467. /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
  3468. * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
  3469. */
  3470. static struct snd_kcontrol_new alc260_will_mixer[] = {
  3471. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3472. HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
  3473. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3474. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3475. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3476. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3477. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3478. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3479. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3480. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3481. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3482. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3483. { } /* end */
  3484. };
  3485. /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
  3486. * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
  3487. */
  3488. static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
  3489. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3490. HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
  3491. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3492. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3493. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3494. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
  3495. HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
  3496. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3497. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3498. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3499. { } /* end */
  3500. };
  3501. /* capture mixer elements */
  3502. static struct snd_kcontrol_new alc260_capture_mixer[] = {
  3503. HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
  3504. HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
  3505. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
  3506. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
  3507. {
  3508. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3509. /* The multiple "Capture Source" controls confuse alsamixer
  3510. * So call somewhat different..
  3511. * FIXME: the controls appear in the "playback" view!
  3512. */
  3513. /* .name = "Capture Source", */
  3514. .name = "Input Source",
  3515. .count = 2,
  3516. .info = alc_mux_enum_info,
  3517. .get = alc_mux_enum_get,
  3518. .put = alc_mux_enum_put,
  3519. },
  3520. { } /* end */
  3521. };
  3522. static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
  3523. HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
  3524. HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
  3525. {
  3526. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3527. /* The multiple "Capture Source" controls confuse alsamixer
  3528. * So call somewhat different..
  3529. * FIXME: the controls appear in the "playback" view!
  3530. */
  3531. /* .name = "Capture Source", */
  3532. .name = "Input Source",
  3533. .count = 1,
  3534. .info = alc_mux_enum_info,
  3535. .get = alc_mux_enum_get,
  3536. .put = alc_mux_enum_put,
  3537. },
  3538. { } /* end */
  3539. };
  3540. /*
  3541. * initialization verbs
  3542. */
  3543. static struct hda_verb alc260_init_verbs[] = {
  3544. /* Line In pin widget for input */
  3545. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3546. /* CD pin widget for input */
  3547. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3548. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3549. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3550. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3551. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3552. /* LINE-2 is used for line-out in rear */
  3553. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3554. /* select line-out */
  3555. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
  3556. /* LINE-OUT pin */
  3557. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3558. /* enable HP */
  3559. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3560. /* enable Mono */
  3561. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3562. /* mute capture amp left and right */
  3563. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3564. /* set connection select to line in (default select for this ADC) */
  3565. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3566. /* mute capture amp left and right */
  3567. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3568. /* set connection select to line in (default select for this ADC) */
  3569. {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
  3570. /* set vol=0 Line-Out mixer amp left and right */
  3571. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3572. /* unmute pin widget amp left and right (no gain on this amp) */
  3573. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3574. /* set vol=0 HP mixer amp left and right */
  3575. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3576. /* unmute pin widget amp left and right (no gain on this amp) */
  3577. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3578. /* set vol=0 Mono mixer amp left and right */
  3579. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3580. /* unmute pin widget amp left and right (no gain on this amp) */
  3581. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3582. /* unmute LINE-2 out pin */
  3583. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3584. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3585. * Line In 2 = 0x03
  3586. */
  3587. /* mute analog inputs */
  3588. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3589. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3590. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3591. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3592. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3593. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3594. /* mute Front out path */
  3595. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3596. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3597. /* mute Headphone out path */
  3598. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3599. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3600. /* mute Mono out path */
  3601. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3602. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3603. { }
  3604. };
  3605. #if 0 /* should be identical with alc260_init_verbs? */
  3606. static struct hda_verb alc260_hp_init_verbs[] = {
  3607. /* Headphone and output */
  3608. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  3609. /* mono output */
  3610. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3611. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3612. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3613. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3614. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3615. /* Line In pin widget for input */
  3616. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3617. /* Line-2 pin widget for output */
  3618. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3619. /* CD pin widget for input */
  3620. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3621. /* unmute amp left and right */
  3622. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
  3623. /* set connection select to line in (default select for this ADC) */
  3624. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3625. /* unmute Line-Out mixer amp left and right (volume = 0) */
  3626. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3627. /* mute pin widget amp left and right (no gain on this amp) */
  3628. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3629. /* unmute HP mixer amp left and right (volume = 0) */
  3630. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3631. /* mute pin widget amp left and right (no gain on this amp) */
  3632. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3633. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3634. * Line In 2 = 0x03
  3635. */
  3636. /* mute analog inputs */
  3637. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3638. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3639. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3640. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3641. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3642. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3643. /* Unmute Front out path */
  3644. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3645. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3646. /* Unmute Headphone out path */
  3647. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3648. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3649. /* Unmute Mono out path */
  3650. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3651. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3652. { }
  3653. };
  3654. #endif
  3655. static struct hda_verb alc260_hp_3013_init_verbs[] = {
  3656. /* Line out and output */
  3657. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3658. /* mono output */
  3659. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3660. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3661. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3662. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3663. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3664. /* Line In pin widget for input */
  3665. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3666. /* Headphone pin widget for output */
  3667. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  3668. /* CD pin widget for input */
  3669. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3670. /* unmute amp left and right */
  3671. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
  3672. /* set connection select to line in (default select for this ADC) */
  3673. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3674. /* unmute Line-Out mixer amp left and right (volume = 0) */
  3675. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3676. /* mute pin widget amp left and right (no gain on this amp) */
  3677. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3678. /* unmute HP mixer amp left and right (volume = 0) */
  3679. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3680. /* mute pin widget amp left and right (no gain on this amp) */
  3681. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3682. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3683. * Line In 2 = 0x03
  3684. */
  3685. /* mute analog inputs */
  3686. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3687. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3688. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3689. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3690. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3691. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3692. /* Unmute Front out path */
  3693. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3694. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3695. /* Unmute Headphone out path */
  3696. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3697. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3698. /* Unmute Mono out path */
  3699. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3700. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3701. { }
  3702. };
  3703. /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
  3704. * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
  3705. * audio = 0x16, internal speaker = 0x10.
  3706. */
  3707. static struct hda_verb alc260_fujitsu_init_verbs[] = {
  3708. /* Disable all GPIOs */
  3709. {0x01, AC_VERB_SET_GPIO_MASK, 0},
  3710. /* Internal speaker is connected to headphone pin */
  3711. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3712. /* Headphone/Line-out jack connects to Line1 pin; make it an output */
  3713. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3714. /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
  3715. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3716. /* Ensure all other unused pins are disabled and muted. */
  3717. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3718. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3719. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3720. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3721. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3722. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3723. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3724. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3725. /* Disable digital (SPDIF) pins */
  3726. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3727. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3728. /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
  3729. * when acting as an output.
  3730. */
  3731. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  3732. /* Start with output sum widgets muted and their output gains at min */
  3733. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3734. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3735. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3736. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3737. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3738. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3739. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3740. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3741. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3742. /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
  3743. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3744. /* Unmute Line1 pin widget output buffer since it starts as an output.
  3745. * If the pin mode is changed by the user the pin mode control will
  3746. * take care of enabling the pin's input/output buffers as needed.
  3747. * Therefore there's no need to enable the input buffer at this
  3748. * stage.
  3749. */
  3750. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3751. /* Unmute input buffer of pin widget used for Line-in (no equiv
  3752. * mixer ctrl)
  3753. */
  3754. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3755. /* Mute capture amp left and right */
  3756. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3757. /* Set ADC connection select to match default mixer setting - line
  3758. * in (on mic1 pin)
  3759. */
  3760. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  3761. /* Do the same for the second ADC: mute capture input amp and
  3762. * set ADC connection to line in (on mic1 pin)
  3763. */
  3764. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3765. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  3766. /* Mute all inputs to mixer widget (even unconnected ones) */
  3767. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  3768. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  3769. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  3770. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  3771. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  3772. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  3773. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  3774. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  3775. { }
  3776. };
  3777. /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
  3778. * similar laptops (adapted from Fujitsu init verbs).
  3779. */
  3780. static struct hda_verb alc260_acer_init_verbs[] = {
  3781. /* On TravelMate laptops, GPIO 0 enables the internal speaker and
  3782. * the headphone jack. Turn this on and rely on the standard mute
  3783. * methods whenever the user wants to turn these outputs off.
  3784. */
  3785. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  3786. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  3787. {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
  3788. /* Internal speaker/Headphone jack is connected to Line-out pin */
  3789. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3790. /* Internal microphone/Mic jack is connected to Mic1 pin */
  3791. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  3792. /* Line In jack is connected to Line1 pin */
  3793. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3794. /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
  3795. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3796. /* Ensure all other unused pins are disabled and muted. */
  3797. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3798. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3799. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3800. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3801. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3802. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3803. /* Disable digital (SPDIF) pins */
  3804. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3805. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3806. /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
  3807. * bus when acting as outputs.
  3808. */
  3809. {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
  3810. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  3811. /* Start with output sum widgets muted and their output gains at min */
  3812. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3813. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3814. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3815. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3816. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3817. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3818. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3819. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3820. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3821. /* Unmute Line-out pin widget amp left and right
  3822. * (no equiv mixer ctrl)
  3823. */
  3824. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3825. /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
  3826. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3827. /* Unmute Mic1 and Line1 pin widget input buffers since they start as
  3828. * inputs. If the pin mode is changed by the user the pin mode control
  3829. * will take care of enabling the pin's input/output buffers as needed.
  3830. * Therefore there's no need to enable the input buffer at this
  3831. * stage.
  3832. */
  3833. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3834. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3835. /* Mute capture amp left and right */
  3836. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3837. /* Set ADC connection select to match default mixer setting - mic
  3838. * (on mic1 pin)
  3839. */
  3840. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  3841. /* Do similar with the second ADC: mute capture input amp and
  3842. * set ADC connection to mic to match ALSA's default state.
  3843. */
  3844. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3845. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  3846. /* Mute all inputs to mixer widget (even unconnected ones) */
  3847. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  3848. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  3849. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  3850. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  3851. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  3852. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  3853. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  3854. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  3855. { }
  3856. };
  3857. static struct hda_verb alc260_will_verbs[] = {
  3858. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3859. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
  3860. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
  3861. {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  3862. {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
  3863. {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
  3864. {}
  3865. };
  3866. static struct hda_verb alc260_replacer_672v_verbs[] = {
  3867. {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  3868. {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
  3869. {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
  3870. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  3871. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  3872. {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
  3873. {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  3874. {}
  3875. };
  3876. /* toggle speaker-output according to the hp-jack state */
  3877. static void alc260_replacer_672v_automute(struct hda_codec *codec)
  3878. {
  3879. unsigned int present;
  3880. /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
  3881. present = snd_hda_codec_read(codec, 0x0f, 0,
  3882. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  3883. if (present) {
  3884. snd_hda_codec_write_cache(codec, 0x01, 0,
  3885. AC_VERB_SET_GPIO_DATA, 1);
  3886. snd_hda_codec_write_cache(codec, 0x0f, 0,
  3887. AC_VERB_SET_PIN_WIDGET_CONTROL,
  3888. PIN_HP);
  3889. } else {
  3890. snd_hda_codec_write_cache(codec, 0x01, 0,
  3891. AC_VERB_SET_GPIO_DATA, 0);
  3892. snd_hda_codec_write_cache(codec, 0x0f, 0,
  3893. AC_VERB_SET_PIN_WIDGET_CONTROL,
  3894. PIN_OUT);
  3895. }
  3896. }
  3897. static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
  3898. unsigned int res)
  3899. {
  3900. if ((res >> 26) == ALC880_HP_EVENT)
  3901. alc260_replacer_672v_automute(codec);
  3902. }
  3903. /* Test configuration for debugging, modelled after the ALC880 test
  3904. * configuration.
  3905. */
  3906. #ifdef CONFIG_SND_DEBUG
  3907. static hda_nid_t alc260_test_dac_nids[1] = {
  3908. 0x02,
  3909. };
  3910. static hda_nid_t alc260_test_adc_nids[2] = {
  3911. 0x04, 0x05,
  3912. };
  3913. /* For testing the ALC260, each input MUX needs its own definition since
  3914. * the signal assignments are different. This assumes that the first ADC
  3915. * is NID 0x04.
  3916. */
  3917. static struct hda_input_mux alc260_test_capture_sources[2] = {
  3918. {
  3919. .num_items = 7,
  3920. .items = {
  3921. { "MIC1 pin", 0x0 },
  3922. { "MIC2 pin", 0x1 },
  3923. { "LINE1 pin", 0x2 },
  3924. { "LINE2 pin", 0x3 },
  3925. { "CD pin", 0x4 },
  3926. { "LINE-OUT pin", 0x5 },
  3927. { "HP-OUT pin", 0x6 },
  3928. },
  3929. },
  3930. {
  3931. .num_items = 8,
  3932. .items = {
  3933. { "MIC1 pin", 0x0 },
  3934. { "MIC2 pin", 0x1 },
  3935. { "LINE1 pin", 0x2 },
  3936. { "LINE2 pin", 0x3 },
  3937. { "CD pin", 0x4 },
  3938. { "Mixer", 0x5 },
  3939. { "LINE-OUT pin", 0x6 },
  3940. { "HP-OUT pin", 0x7 },
  3941. },
  3942. },
  3943. };
  3944. static struct snd_kcontrol_new alc260_test_mixer[] = {
  3945. /* Output driver widgets */
  3946. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  3947. HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
  3948. HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3949. HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
  3950. HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3951. HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
  3952. /* Modes for retasking pin widgets
  3953. * Note: the ALC260 doesn't seem to act on requests to enable mic
  3954. * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
  3955. * mention this restriction. At this stage it's not clear whether
  3956. * this behaviour is intentional or is a hardware bug in chip
  3957. * revisions available at least up until early 2006. Therefore for
  3958. * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
  3959. * choices, but if it turns out that the lack of mic bias for these
  3960. * NIDs is intentional we could change their modes from
  3961. * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
  3962. */
  3963. ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
  3964. ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
  3965. ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
  3966. ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
  3967. ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
  3968. ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
  3969. /* Loopback mixer controls */
  3970. HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
  3971. HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
  3972. HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
  3973. HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
  3974. HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
  3975. HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
  3976. HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
  3977. HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
  3978. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3979. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3980. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3981. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3982. HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
  3983. HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
  3984. HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
  3985. HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
  3986. /* Controls for GPIO pins, assuming they are configured as outputs */
  3987. ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
  3988. ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
  3989. ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
  3990. ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
  3991. /* Switches to allow the digital IO pins to be enabled. The datasheet
  3992. * is ambigious as to which NID is which; testing on laptops which
  3993. * make this output available should provide clarification.
  3994. */
  3995. ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
  3996. ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
  3997. /* A switch allowing EAPD to be enabled. Some laptops seem to use
  3998. * this output to turn on an external amplifier.
  3999. */
  4000. ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
  4001. ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
  4002. { } /* end */
  4003. };
  4004. static struct hda_verb alc260_test_init_verbs[] = {
  4005. /* Enable all GPIOs as outputs with an initial value of 0 */
  4006. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
  4007. {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
  4008. {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
  4009. /* Enable retasking pins as output, initially without power amp */
  4010. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4011. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4012. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4013. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4014. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4015. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4016. /* Disable digital (SPDIF) pins initially, but users can enable
  4017. * them via a mixer switch. In the case of SPDIF-out, this initverb
  4018. * payload also sets the generation to 0, output to be in "consumer"
  4019. * PCM format, copyright asserted, no pre-emphasis and no validity
  4020. * control.
  4021. */
  4022. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  4023. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  4024. /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
  4025. * OUT1 sum bus when acting as an output.
  4026. */
  4027. {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
  4028. {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
  4029. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  4030. {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
  4031. /* Start with output sum widgets muted and their output gains at min */
  4032. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4033. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4034. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4035. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4036. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4037. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4038. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4039. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4040. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4041. /* Unmute retasking pin widget output buffers since the default
  4042. * state appears to be output. As the pin mode is changed by the
  4043. * user the pin mode control will take care of enabling the pin's
  4044. * input/output buffers as needed.
  4045. */
  4046. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4047. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4048. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4049. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4050. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4051. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4052. /* Also unmute the mono-out pin widget */
  4053. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4054. /* Mute capture amp left and right */
  4055. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4056. /* Set ADC connection select to match default mixer setting (mic1
  4057. * pin)
  4058. */
  4059. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  4060. /* Do the same for the second ADC: mute capture input amp and
  4061. * set ADC connection to mic1 pin
  4062. */
  4063. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4064. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  4065. /* Mute all inputs to mixer widget (even unconnected ones) */
  4066. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  4067. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  4068. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  4069. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  4070. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  4071. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  4072. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  4073. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  4074. { }
  4075. };
  4076. #endif
  4077. static struct hda_pcm_stream alc260_pcm_analog_playback = {
  4078. .substreams = 1,
  4079. .channels_min = 2,
  4080. .channels_max = 2,
  4081. };
  4082. static struct hda_pcm_stream alc260_pcm_analog_capture = {
  4083. .substreams = 1,
  4084. .channels_min = 2,
  4085. .channels_max = 2,
  4086. };
  4087. #define alc260_pcm_digital_playback alc880_pcm_digital_playback
  4088. #define alc260_pcm_digital_capture alc880_pcm_digital_capture
  4089. /*
  4090. * for BIOS auto-configuration
  4091. */
  4092. static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
  4093. const char *pfx)
  4094. {
  4095. hda_nid_t nid_vol;
  4096. unsigned long vol_val, sw_val;
  4097. char name[32];
  4098. int err;
  4099. if (nid >= 0x0f && nid < 0x11) {
  4100. nid_vol = nid - 0x7;
  4101. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
  4102. sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
  4103. } else if (nid == 0x11) {
  4104. nid_vol = nid - 0x7;
  4105. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
  4106. sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
  4107. } else if (nid >= 0x12 && nid <= 0x15) {
  4108. nid_vol = 0x08;
  4109. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
  4110. sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
  4111. } else
  4112. return 0; /* N/A */
  4113. snprintf(name, sizeof(name), "%s Playback Volume", pfx);
  4114. err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
  4115. if (err < 0)
  4116. return err;
  4117. snprintf(name, sizeof(name), "%s Playback Switch", pfx);
  4118. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
  4119. if (err < 0)
  4120. return err;
  4121. return 1;
  4122. }
  4123. /* add playback controls from the parsed DAC table */
  4124. static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
  4125. const struct auto_pin_cfg *cfg)
  4126. {
  4127. hda_nid_t nid;
  4128. int err;
  4129. spec->multiout.num_dacs = 1;
  4130. spec->multiout.dac_nids = spec->private_dac_nids;
  4131. spec->multiout.dac_nids[0] = 0x02;
  4132. nid = cfg->line_out_pins[0];
  4133. if (nid) {
  4134. err = alc260_add_playback_controls(spec, nid, "Front");
  4135. if (err < 0)
  4136. return err;
  4137. }
  4138. nid = cfg->speaker_pins[0];
  4139. if (nid) {
  4140. err = alc260_add_playback_controls(spec, nid, "Speaker");
  4141. if (err < 0)
  4142. return err;
  4143. }
  4144. nid = cfg->hp_pins[0];
  4145. if (nid) {
  4146. err = alc260_add_playback_controls(spec, nid, "Headphone");
  4147. if (err < 0)
  4148. return err;
  4149. }
  4150. return 0;
  4151. }
  4152. /* create playback/capture controls for input pins */
  4153. static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
  4154. const struct auto_pin_cfg *cfg)
  4155. {
  4156. struct hda_input_mux *imux = &spec->private_imux;
  4157. int i, err, idx;
  4158. for (i = 0; i < AUTO_PIN_LAST; i++) {
  4159. if (cfg->input_pins[i] >= 0x12) {
  4160. idx = cfg->input_pins[i] - 0x12;
  4161. err = new_analog_input(spec, cfg->input_pins[i],
  4162. auto_pin_cfg_labels[i], idx,
  4163. 0x07);
  4164. if (err < 0)
  4165. return err;
  4166. imux->items[imux->num_items].label =
  4167. auto_pin_cfg_labels[i];
  4168. imux->items[imux->num_items].index = idx;
  4169. imux->num_items++;
  4170. }
  4171. if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
  4172. idx = cfg->input_pins[i] - 0x09;
  4173. err = new_analog_input(spec, cfg->input_pins[i],
  4174. auto_pin_cfg_labels[i], idx,
  4175. 0x07);
  4176. if (err < 0)
  4177. return err;
  4178. imux->items[imux->num_items].label =
  4179. auto_pin_cfg_labels[i];
  4180. imux->items[imux->num_items].index = idx;
  4181. imux->num_items++;
  4182. }
  4183. }
  4184. return 0;
  4185. }
  4186. static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
  4187. hda_nid_t nid, int pin_type,
  4188. int sel_idx)
  4189. {
  4190. /* set as output */
  4191. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  4192. pin_type);
  4193. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  4194. AMP_OUT_UNMUTE);
  4195. /* need the manual connection? */
  4196. if (nid >= 0x12) {
  4197. int idx = nid - 0x12;
  4198. snd_hda_codec_write(codec, idx + 0x0b, 0,
  4199. AC_VERB_SET_CONNECT_SEL, sel_idx);
  4200. }
  4201. }
  4202. static void alc260_auto_init_multi_out(struct hda_codec *codec)
  4203. {
  4204. struct alc_spec *spec = codec->spec;
  4205. hda_nid_t nid;
  4206. alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
  4207. nid = spec->autocfg.line_out_pins[0];
  4208. if (nid) {
  4209. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  4210. alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
  4211. }
  4212. nid = spec->autocfg.speaker_pins[0];
  4213. if (nid)
  4214. alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
  4215. nid = spec->autocfg.hp_pins[0];
  4216. if (nid)
  4217. alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
  4218. }
  4219. #define ALC260_PIN_CD_NID 0x16
  4220. static void alc260_auto_init_analog_input(struct hda_codec *codec)
  4221. {
  4222. struct alc_spec *spec = codec->spec;
  4223. int i;
  4224. for (i = 0; i < AUTO_PIN_LAST; i++) {
  4225. hda_nid_t nid = spec->autocfg.input_pins[i];
  4226. if (nid >= 0x12) {
  4227. snd_hda_codec_write(codec, nid, 0,
  4228. AC_VERB_SET_PIN_WIDGET_CONTROL,
  4229. i <= AUTO_PIN_FRONT_MIC ?
  4230. PIN_VREF80 : PIN_IN);
  4231. if (nid != ALC260_PIN_CD_NID)
  4232. snd_hda_codec_write(codec, nid, 0,
  4233. AC_VERB_SET_AMP_GAIN_MUTE,
  4234. AMP_OUT_MUTE);
  4235. }
  4236. }
  4237. }
  4238. /*
  4239. * generic initialization of ADC, input mixers and output mixers
  4240. */
  4241. static struct hda_verb alc260_volume_init_verbs[] = {
  4242. /*
  4243. * Unmute ADC0-1 and set the default input to mic-in
  4244. */
  4245. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  4246. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4247. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  4248. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4249. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  4250. * mixer widget
  4251. * Note: PASD motherboards uses the Line In 2 as the input for
  4252. * front panel mic (mic 2)
  4253. */
  4254. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  4255. /* mute analog inputs */
  4256. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4257. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4258. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4259. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4260. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4261. /*
  4262. * Set up output mixers (0x08 - 0x0a)
  4263. */
  4264. /* set vol=0 to output mixers */
  4265. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4266. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4267. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4268. /* set up input amps for analog loopback */
  4269. /* Amp Indices: DAC = 0, mixer = 1 */
  4270. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4271. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4272. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4273. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4274. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4275. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4276. { }
  4277. };
  4278. static int alc260_parse_auto_config(struct hda_codec *codec)
  4279. {
  4280. struct alc_spec *spec = codec->spec;
  4281. unsigned int wcap;
  4282. int err;
  4283. static hda_nid_t alc260_ignore[] = { 0x17, 0 };
  4284. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  4285. alc260_ignore);
  4286. if (err < 0)
  4287. return err;
  4288. err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
  4289. if (err < 0)
  4290. return err;
  4291. if (!spec->kctl_alloc)
  4292. return 0; /* can't find valid BIOS pin config */
  4293. err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
  4294. if (err < 0)
  4295. return err;
  4296. spec->multiout.max_channels = 2;
  4297. if (spec->autocfg.dig_out_pin)
  4298. spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
  4299. if (spec->kctl_alloc)
  4300. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  4301. spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
  4302. spec->num_mux_defs = 1;
  4303. spec->input_mux = &spec->private_imux;
  4304. /* check whether NID 0x04 is valid */
  4305. wcap = get_wcaps(codec, 0x04);
  4306. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
  4307. if (wcap != AC_WID_AUD_IN) {
  4308. spec->adc_nids = alc260_adc_nids_alt;
  4309. spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
  4310. spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
  4311. } else {
  4312. spec->adc_nids = alc260_adc_nids;
  4313. spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
  4314. spec->mixers[spec->num_mixers] = alc260_capture_mixer;
  4315. }
  4316. spec->num_mixers++;
  4317. return 1;
  4318. }
  4319. /* additional initialization for auto-configuration model */
  4320. static void alc260_auto_init(struct hda_codec *codec)
  4321. {
  4322. alc260_auto_init_multi_out(codec);
  4323. alc260_auto_init_analog_input(codec);
  4324. }
  4325. #ifdef CONFIG_SND_HDA_POWER_SAVE
  4326. static struct hda_amp_list alc260_loopbacks[] = {
  4327. { 0x07, HDA_INPUT, 0 },
  4328. { 0x07, HDA_INPUT, 1 },
  4329. { 0x07, HDA_INPUT, 2 },
  4330. { 0x07, HDA_INPUT, 3 },
  4331. { 0x07, HDA_INPUT, 4 },
  4332. { } /* end */
  4333. };
  4334. #endif
  4335. /*
  4336. * ALC260 configurations
  4337. */
  4338. static const char *alc260_models[ALC260_MODEL_LAST] = {
  4339. [ALC260_BASIC] = "basic",
  4340. [ALC260_HP] = "hp",
  4341. [ALC260_HP_3013] = "hp-3013",
  4342. [ALC260_FUJITSU_S702X] = "fujitsu",
  4343. [ALC260_ACER] = "acer",
  4344. [ALC260_WILL] = "will",
  4345. [ALC260_REPLACER_672V] = "replacer",
  4346. #ifdef CONFIG_SND_DEBUG
  4347. [ALC260_TEST] = "test",
  4348. #endif
  4349. [ALC260_AUTO] = "auto",
  4350. };
  4351. static struct snd_pci_quirk alc260_cfg_tbl[] = {
  4352. SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
  4353. SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
  4354. SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
  4355. SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
  4356. SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
  4357. SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
  4358. SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
  4359. SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
  4360. SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
  4361. SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
  4362. SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
  4363. SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
  4364. SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
  4365. SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
  4366. SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
  4367. SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
  4368. SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
  4369. SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
  4370. {}
  4371. };
  4372. static struct alc_config_preset alc260_presets[] = {
  4373. [ALC260_BASIC] = {
  4374. .mixers = { alc260_base_output_mixer,
  4375. alc260_input_mixer,
  4376. alc260_pc_beep_mixer,
  4377. alc260_capture_mixer },
  4378. .init_verbs = { alc260_init_verbs },
  4379. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4380. .dac_nids = alc260_dac_nids,
  4381. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4382. .adc_nids = alc260_adc_nids,
  4383. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4384. .channel_mode = alc260_modes,
  4385. .input_mux = &alc260_capture_source,
  4386. },
  4387. [ALC260_HP] = {
  4388. .mixers = { alc260_base_output_mixer,
  4389. alc260_input_mixer,
  4390. alc260_capture_alt_mixer },
  4391. .init_verbs = { alc260_init_verbs },
  4392. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4393. .dac_nids = alc260_dac_nids,
  4394. .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
  4395. .adc_nids = alc260_hp_adc_nids,
  4396. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4397. .channel_mode = alc260_modes,
  4398. .input_mux = &alc260_capture_source,
  4399. },
  4400. [ALC260_HP_3013] = {
  4401. .mixers = { alc260_hp_3013_mixer,
  4402. alc260_input_mixer,
  4403. alc260_capture_alt_mixer },
  4404. .init_verbs = { alc260_hp_3013_init_verbs },
  4405. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4406. .dac_nids = alc260_dac_nids,
  4407. .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
  4408. .adc_nids = alc260_hp_adc_nids,
  4409. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4410. .channel_mode = alc260_modes,
  4411. .input_mux = &alc260_capture_source,
  4412. },
  4413. [ALC260_FUJITSU_S702X] = {
  4414. .mixers = { alc260_fujitsu_mixer,
  4415. alc260_capture_mixer },
  4416. .init_verbs = { alc260_fujitsu_init_verbs },
  4417. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4418. .dac_nids = alc260_dac_nids,
  4419. .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
  4420. .adc_nids = alc260_dual_adc_nids,
  4421. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4422. .channel_mode = alc260_modes,
  4423. .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
  4424. .input_mux = alc260_fujitsu_capture_sources,
  4425. },
  4426. [ALC260_ACER] = {
  4427. .mixers = { alc260_acer_mixer,
  4428. alc260_capture_mixer },
  4429. .init_verbs = { alc260_acer_init_verbs },
  4430. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4431. .dac_nids = alc260_dac_nids,
  4432. .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
  4433. .adc_nids = alc260_dual_adc_nids,
  4434. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4435. .channel_mode = alc260_modes,
  4436. .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
  4437. .input_mux = alc260_acer_capture_sources,
  4438. },
  4439. [ALC260_WILL] = {
  4440. .mixers = { alc260_will_mixer,
  4441. alc260_capture_mixer },
  4442. .init_verbs = { alc260_init_verbs, alc260_will_verbs },
  4443. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4444. .dac_nids = alc260_dac_nids,
  4445. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4446. .adc_nids = alc260_adc_nids,
  4447. .dig_out_nid = ALC260_DIGOUT_NID,
  4448. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4449. .channel_mode = alc260_modes,
  4450. .input_mux = &alc260_capture_source,
  4451. },
  4452. [ALC260_REPLACER_672V] = {
  4453. .mixers = { alc260_replacer_672v_mixer,
  4454. alc260_capture_mixer },
  4455. .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
  4456. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4457. .dac_nids = alc260_dac_nids,
  4458. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4459. .adc_nids = alc260_adc_nids,
  4460. .dig_out_nid = ALC260_DIGOUT_NID,
  4461. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4462. .channel_mode = alc260_modes,
  4463. .input_mux = &alc260_capture_source,
  4464. .unsol_event = alc260_replacer_672v_unsol_event,
  4465. .init_hook = alc260_replacer_672v_automute,
  4466. },
  4467. #ifdef CONFIG_SND_DEBUG
  4468. [ALC260_TEST] = {
  4469. .mixers = { alc260_test_mixer,
  4470. alc260_capture_mixer },
  4471. .init_verbs = { alc260_test_init_verbs },
  4472. .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
  4473. .dac_nids = alc260_test_dac_nids,
  4474. .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
  4475. .adc_nids = alc260_test_adc_nids,
  4476. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4477. .channel_mode = alc260_modes,
  4478. .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
  4479. .input_mux = alc260_test_capture_sources,
  4480. },
  4481. #endif
  4482. };
  4483. static int patch_alc260(struct hda_codec *codec)
  4484. {
  4485. struct alc_spec *spec;
  4486. int err, board_config;
  4487. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  4488. if (spec == NULL)
  4489. return -ENOMEM;
  4490. codec->spec = spec;
  4491. board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
  4492. alc260_models,
  4493. alc260_cfg_tbl);
  4494. if (board_config < 0) {
  4495. snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
  4496. "trying auto-probe from BIOS...\n");
  4497. board_config = ALC260_AUTO;
  4498. }
  4499. if (board_config == ALC260_AUTO) {
  4500. /* automatic parse from the BIOS config */
  4501. err = alc260_parse_auto_config(codec);
  4502. if (err < 0) {
  4503. alc_free(codec);
  4504. return err;
  4505. } else if (!err) {
  4506. printk(KERN_INFO
  4507. "hda_codec: Cannot set up configuration "
  4508. "from BIOS. Using base mode...\n");
  4509. board_config = ALC260_BASIC;
  4510. }
  4511. }
  4512. if (board_config != ALC260_AUTO)
  4513. setup_preset(spec, &alc260_presets[board_config]);
  4514. spec->stream_name_analog = "ALC260 Analog";
  4515. spec->stream_analog_playback = &alc260_pcm_analog_playback;
  4516. spec->stream_analog_capture = &alc260_pcm_analog_capture;
  4517. spec->stream_name_digital = "ALC260 Digital";
  4518. spec->stream_digital_playback = &alc260_pcm_digital_playback;
  4519. spec->stream_digital_capture = &alc260_pcm_digital_capture;
  4520. codec->patch_ops = alc_patch_ops;
  4521. if (board_config == ALC260_AUTO)
  4522. spec->init_hook = alc260_auto_init;
  4523. #ifdef CONFIG_SND_HDA_POWER_SAVE
  4524. if (!spec->loopback.amplist)
  4525. spec->loopback.amplist = alc260_loopbacks;
  4526. #endif
  4527. return 0;
  4528. }
  4529. /*
  4530. * ALC882 support
  4531. *
  4532. * ALC882 is almost identical with ALC880 but has cleaner and more flexible
  4533. * configuration. Each pin widget can choose any input DACs and a mixer.
  4534. * Each ADC is connected from a mixer of all inputs. This makes possible
  4535. * 6-channel independent captures.
  4536. *
  4537. * In addition, an independent DAC for the multi-playback (not used in this
  4538. * driver yet).
  4539. */
  4540. #define ALC882_DIGOUT_NID 0x06
  4541. #define ALC882_DIGIN_NID 0x0a
  4542. static struct hda_channel_mode alc882_ch_modes[1] = {
  4543. { 8, NULL }
  4544. };
  4545. static hda_nid_t alc882_dac_nids[4] = {
  4546. /* front, rear, clfe, rear_surr */
  4547. 0x02, 0x03, 0x04, 0x05
  4548. };
  4549. /* identical with ALC880 */
  4550. #define alc882_adc_nids alc880_adc_nids
  4551. #define alc882_adc_nids_alt alc880_adc_nids_alt
  4552. /* input MUX */
  4553. /* FIXME: should be a matrix-type input source selection */
  4554. static struct hda_input_mux alc882_capture_source = {
  4555. .num_items = 4,
  4556. .items = {
  4557. { "Mic", 0x0 },
  4558. { "Front Mic", 0x1 },
  4559. { "Line", 0x2 },
  4560. { "CD", 0x4 },
  4561. },
  4562. };
  4563. #define alc882_mux_enum_info alc_mux_enum_info
  4564. #define alc882_mux_enum_get alc_mux_enum_get
  4565. static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
  4566. struct snd_ctl_elem_value *ucontrol)
  4567. {
  4568. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  4569. struct alc_spec *spec = codec->spec;
  4570. const struct hda_input_mux *imux = spec->input_mux;
  4571. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  4572. static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
  4573. hda_nid_t nid = capture_mixers[adc_idx];
  4574. unsigned int *cur_val = &spec->cur_mux[adc_idx];
  4575. unsigned int i, idx;
  4576. idx = ucontrol->value.enumerated.item[0];
  4577. if (idx >= imux->num_items)
  4578. idx = imux->num_items - 1;
  4579. if (*cur_val == idx)
  4580. return 0;
  4581. for (i = 0; i < imux->num_items; i++) {
  4582. unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
  4583. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
  4584. imux->items[i].index,
  4585. HDA_AMP_MUTE, v);
  4586. }
  4587. *cur_val = idx;
  4588. return 1;
  4589. }
  4590. /*
  4591. * 2ch mode
  4592. */
  4593. static struct hda_verb alc882_3ST_ch2_init[] = {
  4594. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  4595. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  4596. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  4597. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  4598. { } /* end */
  4599. };
  4600. /*
  4601. * 6ch mode
  4602. */
  4603. static struct hda_verb alc882_3ST_ch6_init[] = {
  4604. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4605. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  4606. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  4607. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4608. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  4609. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  4610. { } /* end */
  4611. };
  4612. static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
  4613. { 2, alc882_3ST_ch2_init },
  4614. { 6, alc882_3ST_ch6_init },
  4615. };
  4616. /*
  4617. * 6ch mode
  4618. */
  4619. static struct hda_verb alc882_sixstack_ch6_init[] = {
  4620. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  4621. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4622. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4623. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4624. { } /* end */
  4625. };
  4626. /*
  4627. * 8ch mode
  4628. */
  4629. static struct hda_verb alc882_sixstack_ch8_init[] = {
  4630. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4631. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4632. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4633. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4634. { } /* end */
  4635. };
  4636. static struct hda_channel_mode alc882_sixstack_modes[2] = {
  4637. { 6, alc882_sixstack_ch6_init },
  4638. { 8, alc882_sixstack_ch8_init },
  4639. };
  4640. /*
  4641. * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
  4642. */
  4643. /*
  4644. * 2ch mode
  4645. */
  4646. static struct hda_verb alc885_mbp_ch2_init[] = {
  4647. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  4648. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4649. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4650. { } /* end */
  4651. };
  4652. /*
  4653. * 6ch mode
  4654. */
  4655. static struct hda_verb alc885_mbp_ch6_init[] = {
  4656. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4657. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4658. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  4659. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4660. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4661. { } /* end */
  4662. };
  4663. static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
  4664. { 2, alc885_mbp_ch2_init },
  4665. { 6, alc885_mbp_ch6_init },
  4666. };
  4667. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  4668. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  4669. */
  4670. static struct snd_kcontrol_new alc882_base_mixer[] = {
  4671. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4672. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4673. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  4674. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  4675. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  4676. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  4677. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  4678. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  4679. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  4680. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  4681. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  4682. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4683. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4684. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4685. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4686. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4687. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4688. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4689. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  4690. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  4691. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  4692. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4693. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4694. { } /* end */
  4695. };
  4696. static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
  4697. HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
  4698. HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
  4699. HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
  4700. HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
  4701. HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4702. HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4703. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
  4704. HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
  4705. HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
  4706. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
  4707. { } /* end */
  4708. };
  4709. static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
  4710. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4711. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4712. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4713. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4714. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4715. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4716. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4717. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4718. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4719. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4720. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4721. { } /* end */
  4722. };
  4723. static struct snd_kcontrol_new alc882_targa_mixer[] = {
  4724. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4725. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4726. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  4727. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4728. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4729. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4730. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4731. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4732. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4733. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4734. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  4735. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  4736. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  4737. { } /* end */
  4738. };
  4739. /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
  4740. * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
  4741. */
  4742. static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
  4743. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4744. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  4745. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  4746. HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  4747. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4748. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4749. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4750. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4751. HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
  4752. HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
  4753. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4754. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4755. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4756. { } /* end */
  4757. };
  4758. static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
  4759. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4760. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4761. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  4762. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4763. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4764. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4765. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4766. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4767. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4768. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4769. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4770. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4771. { } /* end */
  4772. };
  4773. static struct snd_kcontrol_new alc882_chmode_mixer[] = {
  4774. {
  4775. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  4776. .name = "Channel Mode",
  4777. .info = alc_ch_mode_info,
  4778. .get = alc_ch_mode_get,
  4779. .put = alc_ch_mode_put,
  4780. },
  4781. { } /* end */
  4782. };
  4783. static struct hda_verb alc882_init_verbs[] = {
  4784. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  4785. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4786. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4787. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4788. /* Rear mixer */
  4789. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4790. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4791. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4792. /* CLFE mixer */
  4793. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4794. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4795. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4796. /* Side mixer */
  4797. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4798. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4799. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4800. /* Front Pin: output 0 (0x0c) */
  4801. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4802. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4803. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  4804. /* Rear Pin: output 1 (0x0d) */
  4805. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4806. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4807. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  4808. /* CLFE Pin: output 2 (0x0e) */
  4809. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4810. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4811. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  4812. /* Side Pin: output 3 (0x0f) */
  4813. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4814. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4815. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  4816. /* Mic (rear) pin: input vref at 80% */
  4817. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  4818. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4819. /* Front Mic pin: input vref at 80% */
  4820. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  4821. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4822. /* Line In pin: input */
  4823. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  4824. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4825. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  4826. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  4827. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4828. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  4829. /* CD pin widget for input */
  4830. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  4831. /* FIXME: use matrix-type input source selection */
  4832. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  4833. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  4834. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4835. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4836. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4837. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4838. /* Input mixer2 */
  4839. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4840. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4841. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4842. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4843. /* Input mixer3 */
  4844. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4845. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4846. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4847. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4848. /* ADC1: mute amp left and right */
  4849. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4850. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  4851. /* ADC2: mute amp left and right */
  4852. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4853. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  4854. /* ADC3: mute amp left and right */
  4855. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4856. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  4857. { }
  4858. };
  4859. static struct hda_verb alc882_eapd_verbs[] = {
  4860. /* change to EAPD mode */
  4861. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  4862. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  4863. { }
  4864. };
  4865. /* Mac Pro test */
  4866. static struct snd_kcontrol_new alc882_macpro_mixer[] = {
  4867. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4868. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4869. HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  4870. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
  4871. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
  4872. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4873. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4874. { } /* end */
  4875. };
  4876. static struct hda_verb alc882_macpro_init_verbs[] = {
  4877. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  4878. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4879. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4880. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4881. /* Front Pin: output 0 (0x0c) */
  4882. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4883. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4884. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  4885. /* Front Mic pin: input vref at 80% */
  4886. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  4887. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4888. /* Speaker: output */
  4889. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4890. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4891. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
  4892. /* Headphone output (output 0 - 0x0c) */
  4893. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  4894. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4895. {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
  4896. /* FIXME: use matrix-type input source selection */
  4897. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  4898. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  4899. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4900. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4901. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4902. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4903. /* Input mixer2 */
  4904. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4905. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4906. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4907. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4908. /* Input mixer3 */
  4909. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4910. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4911. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4912. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4913. /* ADC1: mute amp left and right */
  4914. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4915. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  4916. /* ADC2: mute amp left and right */
  4917. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4918. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  4919. /* ADC3: mute amp left and right */
  4920. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4921. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  4922. { }
  4923. };
  4924. /* Macbook Pro rev3 */
  4925. static struct hda_verb alc885_mbp3_init_verbs[] = {
  4926. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  4927. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4928. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4929. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4930. /* Rear mixer */
  4931. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4932. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4933. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4934. /* Front Pin: output 0 (0x0c) */
  4935. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4936. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4937. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  4938. /* HP Pin: output 0 (0x0d) */
  4939. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
  4940. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4941. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  4942. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  4943. /* Mic (rear) pin: input vref at 80% */
  4944. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  4945. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4946. /* Front Mic pin: input vref at 80% */
  4947. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  4948. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4949. /* Line In pin: use output 1 when in LineOut mode */
  4950. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  4951. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  4952. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
  4953. /* FIXME: use matrix-type input source selection */
  4954. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  4955. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  4956. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4957. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4958. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4959. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4960. /* Input mixer2 */
  4961. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4962. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4963. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4964. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4965. /* Input mixer3 */
  4966. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4967. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4968. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4969. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4970. /* ADC1: mute amp left and right */
  4971. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4972. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  4973. /* ADC2: mute amp left and right */
  4974. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4975. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  4976. /* ADC3: mute amp left and right */
  4977. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4978. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  4979. { }
  4980. };
  4981. /* iMac 24 mixer. */
  4982. static struct snd_kcontrol_new alc885_imac24_mixer[] = {
  4983. HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
  4984. HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
  4985. { } /* end */
  4986. };
  4987. /* iMac 24 init verbs. */
  4988. static struct hda_verb alc885_imac24_init_verbs[] = {
  4989. /* Internal speakers: output 0 (0x0c) */
  4990. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4991. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4992. {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
  4993. /* Internal speakers: output 0 (0x0c) */
  4994. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4995. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4996. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
  4997. /* Headphone: output 0 (0x0c) */
  4998. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  4999. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5000. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  5001. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  5002. /* Front Mic: input vref at 80% */
  5003. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5004. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5005. { }
  5006. };
  5007. /* Toggle speaker-output according to the hp-jack state */
  5008. static void alc885_imac24_automute(struct hda_codec *codec)
  5009. {
  5010. unsigned int present;
  5011. present = snd_hda_codec_read(codec, 0x14, 0,
  5012. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5013. snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
  5014. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5015. snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
  5016. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5017. }
  5018. /* Processes unsolicited events. */
  5019. static void alc885_imac24_unsol_event(struct hda_codec *codec,
  5020. unsigned int res)
  5021. {
  5022. /* Headphone insertion or removal. */
  5023. if ((res >> 26) == ALC880_HP_EVENT)
  5024. alc885_imac24_automute(codec);
  5025. }
  5026. static void alc885_mbp3_automute(struct hda_codec *codec)
  5027. {
  5028. unsigned int present;
  5029. present = snd_hda_codec_read(codec, 0x15, 0,
  5030. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5031. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  5032. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5033. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  5034. HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
  5035. }
  5036. static void alc885_mbp3_unsol_event(struct hda_codec *codec,
  5037. unsigned int res)
  5038. {
  5039. /* Headphone insertion or removal. */
  5040. if ((res >> 26) == ALC880_HP_EVENT)
  5041. alc885_mbp3_automute(codec);
  5042. }
  5043. static struct hda_verb alc882_targa_verbs[] = {
  5044. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5045. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5046. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5047. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5048. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5049. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5050. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5051. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  5052. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  5053. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  5054. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  5055. { } /* end */
  5056. };
  5057. /* toggle speaker-output according to the hp-jack state */
  5058. static void alc882_targa_automute(struct hda_codec *codec)
  5059. {
  5060. unsigned int present;
  5061. present = snd_hda_codec_read(codec, 0x14, 0,
  5062. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5063. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  5064. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5065. snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
  5066. present ? 1 : 3);
  5067. }
  5068. static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
  5069. {
  5070. /* Looks like the unsol event is incompatible with the standard
  5071. * definition. 4bit tag is placed at 26 bit!
  5072. */
  5073. if (((res >> 26) == ALC880_HP_EVENT)) {
  5074. alc882_targa_automute(codec);
  5075. }
  5076. }
  5077. static struct hda_verb alc882_asus_a7j_verbs[] = {
  5078. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5079. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5080. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5081. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5082. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5083. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5084. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5085. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5086. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5087. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5088. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5089. { } /* end */
  5090. };
  5091. static struct hda_verb alc882_asus_a7m_verbs[] = {
  5092. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5093. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5094. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5095. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5096. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5097. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5098. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5099. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5100. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5101. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5102. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5103. { } /* end */
  5104. };
  5105. static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
  5106. {
  5107. unsigned int gpiostate, gpiomask, gpiodir;
  5108. gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
  5109. AC_VERB_GET_GPIO_DATA, 0);
  5110. if (!muted)
  5111. gpiostate |= (1 << pin);
  5112. else
  5113. gpiostate &= ~(1 << pin);
  5114. gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
  5115. AC_VERB_GET_GPIO_MASK, 0);
  5116. gpiomask |= (1 << pin);
  5117. gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
  5118. AC_VERB_GET_GPIO_DIRECTION, 0);
  5119. gpiodir |= (1 << pin);
  5120. snd_hda_codec_write(codec, codec->afg, 0,
  5121. AC_VERB_SET_GPIO_MASK, gpiomask);
  5122. snd_hda_codec_write(codec, codec->afg, 0,
  5123. AC_VERB_SET_GPIO_DIRECTION, gpiodir);
  5124. msleep(1);
  5125. snd_hda_codec_write(codec, codec->afg, 0,
  5126. AC_VERB_SET_GPIO_DATA, gpiostate);
  5127. }
  5128. /* set up GPIO at initialization */
  5129. static void alc885_macpro_init_hook(struct hda_codec *codec)
  5130. {
  5131. alc882_gpio_mute(codec, 0, 0);
  5132. alc882_gpio_mute(codec, 1, 0);
  5133. }
  5134. /* set up GPIO and update auto-muting at initialization */
  5135. static void alc885_imac24_init_hook(struct hda_codec *codec)
  5136. {
  5137. alc885_macpro_init_hook(codec);
  5138. alc885_imac24_automute(codec);
  5139. }
  5140. /*
  5141. * generic initialization of ADC, input mixers and output mixers
  5142. */
  5143. static struct hda_verb alc882_auto_init_verbs[] = {
  5144. /*
  5145. * Unmute ADC0-2 and set the default input to mic-in
  5146. */
  5147. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  5148. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5149. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  5150. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5151. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  5152. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5153. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  5154. * mixer widget
  5155. * Note: PASD motherboards uses the Line In 2 as the input for
  5156. * front panel mic (mic 2)
  5157. */
  5158. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  5159. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5160. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  5161. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5162. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5163. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5164. /*
  5165. * Set up output mixers (0x0c - 0x0f)
  5166. */
  5167. /* set vol=0 to output mixers */
  5168. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5169. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5170. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5171. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5172. /* set up input amps for analog loopback */
  5173. /* Amp Indices: DAC = 0, mixer = 1 */
  5174. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5175. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5176. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5177. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5178. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5179. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5180. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5181. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5182. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5183. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5184. /* FIXME: use matrix-type input source selection */
  5185. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  5186. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  5187. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5188. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5189. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5190. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5191. /* Input mixer2 */
  5192. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5193. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5194. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5195. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5196. /* Input mixer3 */
  5197. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5198. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5199. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5200. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5201. { }
  5202. };
  5203. /* capture mixer elements */
  5204. static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
  5205. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5206. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5207. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5208. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5209. {
  5210. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5211. /* The multiple "Capture Source" controls confuse alsamixer
  5212. * So call somewhat different..
  5213. * FIXME: the controls appear in the "playback" view!
  5214. */
  5215. /* .name = "Capture Source", */
  5216. .name = "Input Source",
  5217. .count = 2,
  5218. .info = alc882_mux_enum_info,
  5219. .get = alc882_mux_enum_get,
  5220. .put = alc882_mux_enum_put,
  5221. },
  5222. { } /* end */
  5223. };
  5224. static struct snd_kcontrol_new alc882_capture_mixer[] = {
  5225. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  5226. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  5227. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
  5228. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
  5229. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
  5230. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
  5231. {
  5232. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5233. /* The multiple "Capture Source" controls confuse alsamixer
  5234. * So call somewhat different..
  5235. * FIXME: the controls appear in the "playback" view!
  5236. */
  5237. /* .name = "Capture Source", */
  5238. .name = "Input Source",
  5239. .count = 3,
  5240. .info = alc882_mux_enum_info,
  5241. .get = alc882_mux_enum_get,
  5242. .put = alc882_mux_enum_put,
  5243. },
  5244. { } /* end */
  5245. };
  5246. #ifdef CONFIG_SND_HDA_POWER_SAVE
  5247. #define alc882_loopbacks alc880_loopbacks
  5248. #endif
  5249. /* pcm configuration: identiacal with ALC880 */
  5250. #define alc882_pcm_analog_playback alc880_pcm_analog_playback
  5251. #define alc882_pcm_analog_capture alc880_pcm_analog_capture
  5252. #define alc882_pcm_digital_playback alc880_pcm_digital_playback
  5253. #define alc882_pcm_digital_capture alc880_pcm_digital_capture
  5254. /*
  5255. * configuration and preset
  5256. */
  5257. static const char *alc882_models[ALC882_MODEL_LAST] = {
  5258. [ALC882_3ST_DIG] = "3stack-dig",
  5259. [ALC882_6ST_DIG] = "6stack-dig",
  5260. [ALC882_ARIMA] = "arima",
  5261. [ALC882_W2JC] = "w2jc",
  5262. [ALC882_TARGA] = "targa",
  5263. [ALC882_ASUS_A7J] = "asus-a7j",
  5264. [ALC882_ASUS_A7M] = "asus-a7m",
  5265. [ALC885_MACPRO] = "macpro",
  5266. [ALC885_MBP3] = "mbp3",
  5267. [ALC885_IMAC24] = "imac24",
  5268. [ALC882_AUTO] = "auto",
  5269. };
  5270. static struct snd_pci_quirk alc882_cfg_tbl[] = {
  5271. SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
  5272. SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
  5273. SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
  5274. SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
  5275. SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
  5276. SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
  5277. SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
  5278. SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
  5279. SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
  5280. SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
  5281. SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
  5282. {}
  5283. };
  5284. static struct alc_config_preset alc882_presets[] = {
  5285. [ALC882_3ST_DIG] = {
  5286. .mixers = { alc882_base_mixer },
  5287. .init_verbs = { alc882_init_verbs },
  5288. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5289. .dac_nids = alc882_dac_nids,
  5290. .dig_out_nid = ALC882_DIGOUT_NID,
  5291. .dig_in_nid = ALC882_DIGIN_NID,
  5292. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5293. .channel_mode = alc882_ch_modes,
  5294. .need_dac_fix = 1,
  5295. .input_mux = &alc882_capture_source,
  5296. },
  5297. [ALC882_6ST_DIG] = {
  5298. .mixers = { alc882_base_mixer, alc882_chmode_mixer },
  5299. .init_verbs = { alc882_init_verbs },
  5300. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5301. .dac_nids = alc882_dac_nids,
  5302. .dig_out_nid = ALC882_DIGOUT_NID,
  5303. .dig_in_nid = ALC882_DIGIN_NID,
  5304. .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
  5305. .channel_mode = alc882_sixstack_modes,
  5306. .input_mux = &alc882_capture_source,
  5307. },
  5308. [ALC882_ARIMA] = {
  5309. .mixers = { alc882_base_mixer, alc882_chmode_mixer },
  5310. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
  5311. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5312. .dac_nids = alc882_dac_nids,
  5313. .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
  5314. .channel_mode = alc882_sixstack_modes,
  5315. .input_mux = &alc882_capture_source,
  5316. },
  5317. [ALC882_W2JC] = {
  5318. .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
  5319. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
  5320. alc880_gpio1_init_verbs },
  5321. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5322. .dac_nids = alc882_dac_nids,
  5323. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  5324. .channel_mode = alc880_threestack_modes,
  5325. .need_dac_fix = 1,
  5326. .input_mux = &alc882_capture_source,
  5327. .dig_out_nid = ALC882_DIGOUT_NID,
  5328. },
  5329. [ALC885_MBP3] = {
  5330. .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
  5331. .init_verbs = { alc885_mbp3_init_verbs,
  5332. alc880_gpio1_init_verbs },
  5333. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5334. .dac_nids = alc882_dac_nids,
  5335. .channel_mode = alc885_mbp_6ch_modes,
  5336. .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
  5337. .input_mux = &alc882_capture_source,
  5338. .dig_out_nid = ALC882_DIGOUT_NID,
  5339. .dig_in_nid = ALC882_DIGIN_NID,
  5340. .unsol_event = alc885_mbp3_unsol_event,
  5341. .init_hook = alc885_mbp3_automute,
  5342. },
  5343. [ALC885_MACPRO] = {
  5344. .mixers = { alc882_macpro_mixer },
  5345. .init_verbs = { alc882_macpro_init_verbs },
  5346. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5347. .dac_nids = alc882_dac_nids,
  5348. .dig_out_nid = ALC882_DIGOUT_NID,
  5349. .dig_in_nid = ALC882_DIGIN_NID,
  5350. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5351. .channel_mode = alc882_ch_modes,
  5352. .input_mux = &alc882_capture_source,
  5353. .init_hook = alc885_macpro_init_hook,
  5354. },
  5355. [ALC885_IMAC24] = {
  5356. .mixers = { alc885_imac24_mixer },
  5357. .init_verbs = { alc885_imac24_init_verbs },
  5358. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5359. .dac_nids = alc882_dac_nids,
  5360. .dig_out_nid = ALC882_DIGOUT_NID,
  5361. .dig_in_nid = ALC882_DIGIN_NID,
  5362. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5363. .channel_mode = alc882_ch_modes,
  5364. .input_mux = &alc882_capture_source,
  5365. .unsol_event = alc885_imac24_unsol_event,
  5366. .init_hook = alc885_imac24_init_hook,
  5367. },
  5368. [ALC882_TARGA] = {
  5369. .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
  5370. alc882_capture_mixer },
  5371. .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
  5372. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5373. .dac_nids = alc882_dac_nids,
  5374. .dig_out_nid = ALC882_DIGOUT_NID,
  5375. .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
  5376. .adc_nids = alc882_adc_nids,
  5377. .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
  5378. .channel_mode = alc882_3ST_6ch_modes,
  5379. .need_dac_fix = 1,
  5380. .input_mux = &alc882_capture_source,
  5381. .unsol_event = alc882_targa_unsol_event,
  5382. .init_hook = alc882_targa_automute,
  5383. },
  5384. [ALC882_ASUS_A7J] = {
  5385. .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
  5386. alc882_capture_mixer },
  5387. .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
  5388. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5389. .dac_nids = alc882_dac_nids,
  5390. .dig_out_nid = ALC882_DIGOUT_NID,
  5391. .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
  5392. .adc_nids = alc882_adc_nids,
  5393. .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
  5394. .channel_mode = alc882_3ST_6ch_modes,
  5395. .need_dac_fix = 1,
  5396. .input_mux = &alc882_capture_source,
  5397. },
  5398. [ALC882_ASUS_A7M] = {
  5399. .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
  5400. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
  5401. alc880_gpio1_init_verbs,
  5402. alc882_asus_a7m_verbs },
  5403. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5404. .dac_nids = alc882_dac_nids,
  5405. .dig_out_nid = ALC882_DIGOUT_NID,
  5406. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  5407. .channel_mode = alc880_threestack_modes,
  5408. .need_dac_fix = 1,
  5409. .input_mux = &alc882_capture_source,
  5410. },
  5411. };
  5412. /*
  5413. * Pin config fixes
  5414. */
  5415. enum {
  5416. PINFIX_ABIT_AW9D_MAX
  5417. };
  5418. static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
  5419. { 0x15, 0x01080104 }, /* side */
  5420. { 0x16, 0x01011012 }, /* rear */
  5421. { 0x17, 0x01016011 }, /* clfe */
  5422. { }
  5423. };
  5424. static const struct alc_pincfg *alc882_pin_fixes[] = {
  5425. [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
  5426. };
  5427. static struct snd_pci_quirk alc882_pinfix_tbl[] = {
  5428. SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
  5429. {}
  5430. };
  5431. /*
  5432. * BIOS auto configuration
  5433. */
  5434. static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
  5435. hda_nid_t nid, int pin_type,
  5436. int dac_idx)
  5437. {
  5438. /* set as output */
  5439. struct alc_spec *spec = codec->spec;
  5440. int idx;
  5441. if (spec->multiout.dac_nids[dac_idx] == 0x25)
  5442. idx = 4;
  5443. else
  5444. idx = spec->multiout.dac_nids[dac_idx] - 2;
  5445. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  5446. pin_type);
  5447. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  5448. AMP_OUT_UNMUTE);
  5449. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
  5450. }
  5451. static void alc882_auto_init_multi_out(struct hda_codec *codec)
  5452. {
  5453. struct alc_spec *spec = codec->spec;
  5454. int i;
  5455. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  5456. for (i = 0; i <= HDA_SIDE; i++) {
  5457. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  5458. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  5459. if (nid)
  5460. alc882_auto_set_output_and_unmute(codec, nid, pin_type,
  5461. i);
  5462. }
  5463. }
  5464. static void alc882_auto_init_hp_out(struct hda_codec *codec)
  5465. {
  5466. struct alc_spec *spec = codec->spec;
  5467. hda_nid_t pin;
  5468. pin = spec->autocfg.hp_pins[0];
  5469. if (pin) /* connect to front */
  5470. /* use dac 0 */
  5471. alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  5472. }
  5473. #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
  5474. #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
  5475. static void alc882_auto_init_analog_input(struct hda_codec *codec)
  5476. {
  5477. struct alc_spec *spec = codec->spec;
  5478. int i;
  5479. for (i = 0; i < AUTO_PIN_LAST; i++) {
  5480. hda_nid_t nid = spec->autocfg.input_pins[i];
  5481. if (alc882_is_input_pin(nid)) {
  5482. snd_hda_codec_write(codec, nid, 0,
  5483. AC_VERB_SET_PIN_WIDGET_CONTROL,
  5484. i <= AUTO_PIN_FRONT_MIC ?
  5485. PIN_VREF80 : PIN_IN);
  5486. if (nid != ALC882_PIN_CD_NID)
  5487. snd_hda_codec_write(codec, nid, 0,
  5488. AC_VERB_SET_AMP_GAIN_MUTE,
  5489. AMP_OUT_MUTE);
  5490. }
  5491. }
  5492. }
  5493. /* add mic boosts if needed */
  5494. static int alc_auto_add_mic_boost(struct hda_codec *codec)
  5495. {
  5496. struct alc_spec *spec = codec->spec;
  5497. int err;
  5498. hda_nid_t nid;
  5499. nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
  5500. if (nid) {
  5501. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  5502. "Mic Boost",
  5503. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  5504. if (err < 0)
  5505. return err;
  5506. }
  5507. nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
  5508. if (nid) {
  5509. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  5510. "Front Mic Boost",
  5511. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  5512. if (err < 0)
  5513. return err;
  5514. }
  5515. return 0;
  5516. }
  5517. /* almost identical with ALC880 parser... */
  5518. static int alc882_parse_auto_config(struct hda_codec *codec)
  5519. {
  5520. struct alc_spec *spec = codec->spec;
  5521. int err = alc880_parse_auto_config(codec);
  5522. if (err < 0)
  5523. return err;
  5524. else if (!err)
  5525. return 0; /* no config found */
  5526. err = alc_auto_add_mic_boost(codec);
  5527. if (err < 0)
  5528. return err;
  5529. /* hack - override the init verbs */
  5530. spec->init_verbs[0] = alc882_auto_init_verbs;
  5531. return 1; /* config found */
  5532. }
  5533. /* additional initialization for auto-configuration model */
  5534. static void alc882_auto_init(struct hda_codec *codec)
  5535. {
  5536. alc882_auto_init_multi_out(codec);
  5537. alc882_auto_init_hp_out(codec);
  5538. alc882_auto_init_analog_input(codec);
  5539. }
  5540. static int patch_alc882(struct hda_codec *codec)
  5541. {
  5542. struct alc_spec *spec;
  5543. int err, board_config;
  5544. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  5545. if (spec == NULL)
  5546. return -ENOMEM;
  5547. codec->spec = spec;
  5548. board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
  5549. alc882_models,
  5550. alc882_cfg_tbl);
  5551. if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
  5552. /* Pick up systems that don't supply PCI SSID */
  5553. switch (codec->subsystem_id) {
  5554. case 0x106b0c00: /* Mac Pro */
  5555. board_config = ALC885_MACPRO;
  5556. break;
  5557. case 0x106b1000: /* iMac 24 */
  5558. board_config = ALC885_IMAC24;
  5559. break;
  5560. case 0x106b2c00: /* Macbook Pro rev3 */
  5561. board_config = ALC885_MBP3;
  5562. break;
  5563. default:
  5564. printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
  5565. "trying auto-probe from BIOS...\n");
  5566. board_config = ALC882_AUTO;
  5567. }
  5568. }
  5569. alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
  5570. if (board_config == ALC882_AUTO) {
  5571. /* automatic parse from the BIOS config */
  5572. err = alc882_parse_auto_config(codec);
  5573. if (err < 0) {
  5574. alc_free(codec);
  5575. return err;
  5576. } else if (!err) {
  5577. printk(KERN_INFO
  5578. "hda_codec: Cannot set up configuration "
  5579. "from BIOS. Using base mode...\n");
  5580. board_config = ALC882_3ST_DIG;
  5581. }
  5582. }
  5583. if (board_config != ALC882_AUTO)
  5584. setup_preset(spec, &alc882_presets[board_config]);
  5585. spec->stream_name_analog = "ALC882 Analog";
  5586. spec->stream_analog_playback = &alc882_pcm_analog_playback;
  5587. spec->stream_analog_capture = &alc882_pcm_analog_capture;
  5588. spec->stream_name_digital = "ALC882 Digital";
  5589. spec->stream_digital_playback = &alc882_pcm_digital_playback;
  5590. spec->stream_digital_capture = &alc882_pcm_digital_capture;
  5591. if (!spec->adc_nids && spec->input_mux) {
  5592. /* check whether NID 0x07 is valid */
  5593. unsigned int wcap = get_wcaps(codec, 0x07);
  5594. /* get type */
  5595. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  5596. if (wcap != AC_WID_AUD_IN) {
  5597. spec->adc_nids = alc882_adc_nids_alt;
  5598. spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
  5599. spec->mixers[spec->num_mixers] =
  5600. alc882_capture_alt_mixer;
  5601. spec->num_mixers++;
  5602. } else {
  5603. spec->adc_nids = alc882_adc_nids;
  5604. spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
  5605. spec->mixers[spec->num_mixers] = alc882_capture_mixer;
  5606. spec->num_mixers++;
  5607. }
  5608. }
  5609. codec->patch_ops = alc_patch_ops;
  5610. if (board_config == ALC882_AUTO)
  5611. spec->init_hook = alc882_auto_init;
  5612. #ifdef CONFIG_SND_HDA_POWER_SAVE
  5613. if (!spec->loopback.amplist)
  5614. spec->loopback.amplist = alc882_loopbacks;
  5615. #endif
  5616. return 0;
  5617. }
  5618. /*
  5619. * ALC883 support
  5620. *
  5621. * ALC883 is almost identical with ALC880 but has cleaner and more flexible
  5622. * configuration. Each pin widget can choose any input DACs and a mixer.
  5623. * Each ADC is connected from a mixer of all inputs. This makes possible
  5624. * 6-channel independent captures.
  5625. *
  5626. * In addition, an independent DAC for the multi-playback (not used in this
  5627. * driver yet).
  5628. */
  5629. #define ALC883_DIGOUT_NID 0x06
  5630. #define ALC883_DIGIN_NID 0x0a
  5631. static hda_nid_t alc883_dac_nids[4] = {
  5632. /* front, rear, clfe, rear_surr */
  5633. 0x02, 0x04, 0x03, 0x05
  5634. };
  5635. static hda_nid_t alc883_adc_nids[2] = {
  5636. /* ADC1-2 */
  5637. 0x08, 0x09,
  5638. };
  5639. /* input MUX */
  5640. /* FIXME: should be a matrix-type input source selection */
  5641. static struct hda_input_mux alc883_capture_source = {
  5642. .num_items = 4,
  5643. .items = {
  5644. { "Mic", 0x0 },
  5645. { "Front Mic", 0x1 },
  5646. { "Line", 0x2 },
  5647. { "CD", 0x4 },
  5648. },
  5649. };
  5650. static struct hda_input_mux alc883_lenovo_101e_capture_source = {
  5651. .num_items = 2,
  5652. .items = {
  5653. { "Mic", 0x1 },
  5654. { "Line", 0x2 },
  5655. },
  5656. };
  5657. static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
  5658. .num_items = 4,
  5659. .items = {
  5660. { "Mic", 0x0 },
  5661. { "iMic", 0x1 },
  5662. { "Line", 0x2 },
  5663. { "CD", 0x4 },
  5664. },
  5665. };
  5666. #define alc883_mux_enum_info alc_mux_enum_info
  5667. #define alc883_mux_enum_get alc_mux_enum_get
  5668. static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
  5669. struct snd_ctl_elem_value *ucontrol)
  5670. {
  5671. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  5672. struct alc_spec *spec = codec->spec;
  5673. const struct hda_input_mux *imux = spec->input_mux;
  5674. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  5675. static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
  5676. hda_nid_t nid = capture_mixers[adc_idx];
  5677. unsigned int *cur_val = &spec->cur_mux[adc_idx];
  5678. unsigned int i, idx;
  5679. idx = ucontrol->value.enumerated.item[0];
  5680. if (idx >= imux->num_items)
  5681. idx = imux->num_items - 1;
  5682. if (*cur_val == idx)
  5683. return 0;
  5684. for (i = 0; i < imux->num_items; i++) {
  5685. unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
  5686. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
  5687. imux->items[i].index,
  5688. HDA_AMP_MUTE, v);
  5689. }
  5690. *cur_val = idx;
  5691. return 1;
  5692. }
  5693. /*
  5694. * 2ch mode
  5695. */
  5696. static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
  5697. { 2, NULL }
  5698. };
  5699. /*
  5700. * 2ch mode
  5701. */
  5702. static struct hda_verb alc883_3ST_ch2_init[] = {
  5703. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  5704. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5705. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  5706. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5707. { } /* end */
  5708. };
  5709. /*
  5710. * 4ch mode
  5711. */
  5712. static struct hda_verb alc883_3ST_ch4_init[] = {
  5713. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  5714. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5715. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5716. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5717. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  5718. { } /* end */
  5719. };
  5720. /*
  5721. * 6ch mode
  5722. */
  5723. static struct hda_verb alc883_3ST_ch6_init[] = {
  5724. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5725. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5726. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  5727. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5728. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5729. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  5730. { } /* end */
  5731. };
  5732. static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
  5733. { 2, alc883_3ST_ch2_init },
  5734. { 4, alc883_3ST_ch4_init },
  5735. { 6, alc883_3ST_ch6_init },
  5736. };
  5737. /*
  5738. * 6ch mode
  5739. */
  5740. static struct hda_verb alc883_sixstack_ch6_init[] = {
  5741. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  5742. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5743. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5744. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5745. { } /* end */
  5746. };
  5747. /*
  5748. * 8ch mode
  5749. */
  5750. static struct hda_verb alc883_sixstack_ch8_init[] = {
  5751. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5752. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5753. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5754. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5755. { } /* end */
  5756. };
  5757. static struct hda_channel_mode alc883_sixstack_modes[2] = {
  5758. { 6, alc883_sixstack_ch6_init },
  5759. { 8, alc883_sixstack_ch8_init },
  5760. };
  5761. static struct hda_verb alc883_medion_eapd_verbs[] = {
  5762. /* eanable EAPD on medion laptop */
  5763. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  5764. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  5765. { }
  5766. };
  5767. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  5768. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  5769. */
  5770. static struct snd_kcontrol_new alc883_base_mixer[] = {
  5771. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5772. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5773. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  5774. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  5775. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5776. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5777. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5778. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5779. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  5780. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  5781. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5782. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5783. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5784. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5785. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5786. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5787. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5788. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5789. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5790. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5791. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5792. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  5793. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  5794. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5795. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5796. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5797. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5798. {
  5799. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5800. /* .name = "Capture Source", */
  5801. .name = "Input Source",
  5802. .count = 2,
  5803. .info = alc883_mux_enum_info,
  5804. .get = alc883_mux_enum_get,
  5805. .put = alc883_mux_enum_put,
  5806. },
  5807. { } /* end */
  5808. };
  5809. static struct snd_kcontrol_new alc883_mitac_mixer[] = {
  5810. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5811. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5812. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5813. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5814. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5815. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5816. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  5817. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5818. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5819. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5820. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5821. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5822. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5823. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5824. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5825. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5826. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5827. {
  5828. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5829. /* .name = "Capture Source", */
  5830. .name = "Input Source",
  5831. .count = 2,
  5832. .info = alc883_mux_enum_info,
  5833. .get = alc883_mux_enum_get,
  5834. .put = alc883_mux_enum_put,
  5835. },
  5836. { } /* end */
  5837. };
  5838. static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
  5839. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5840. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5841. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5842. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5843. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5844. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5845. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5846. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5847. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5848. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5849. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5850. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5851. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5852. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  5853. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  5854. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5855. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5856. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5857. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5858. {
  5859. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5860. /* .name = "Capture Source", */
  5861. .name = "Input Source",
  5862. .count = 2,
  5863. .info = alc883_mux_enum_info,
  5864. .get = alc883_mux_enum_get,
  5865. .put = alc883_mux_enum_put,
  5866. },
  5867. { } /* end */
  5868. };
  5869. static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
  5870. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5871. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5872. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  5873. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  5874. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5875. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5876. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5877. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5878. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5879. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5880. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5881. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5882. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5883. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5884. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5885. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5886. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5887. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5888. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5889. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  5890. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  5891. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5892. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5893. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5894. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5895. {
  5896. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5897. /* .name = "Capture Source", */
  5898. .name = "Input Source",
  5899. .count = 2,
  5900. .info = alc883_mux_enum_info,
  5901. .get = alc883_mux_enum_get,
  5902. .put = alc883_mux_enum_put,
  5903. },
  5904. { } /* end */
  5905. };
  5906. static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
  5907. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5908. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  5909. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  5910. HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  5911. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5912. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5913. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
  5914. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  5915. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5916. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5917. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5918. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5919. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5920. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5921. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5922. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5923. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5924. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5925. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5926. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  5927. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  5928. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5929. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5930. {
  5931. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5932. /* .name = "Capture Source", */
  5933. .name = "Input Source",
  5934. .count = 1,
  5935. .info = alc883_mux_enum_info,
  5936. .get = alc883_mux_enum_get,
  5937. .put = alc883_mux_enum_put,
  5938. },
  5939. { } /* end */
  5940. };
  5941. static struct snd_kcontrol_new alc883_tagra_mixer[] = {
  5942. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5943. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  5944. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5945. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  5946. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  5947. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5948. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5949. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5950. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5951. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5952. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5953. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5954. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5955. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5956. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5957. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5958. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5959. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5960. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5961. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5962. {
  5963. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5964. /* .name = "Capture Source", */
  5965. .name = "Input Source",
  5966. .count = 2,
  5967. .info = alc883_mux_enum_info,
  5968. .get = alc883_mux_enum_get,
  5969. .put = alc883_mux_enum_put,
  5970. },
  5971. { } /* end */
  5972. };
  5973. static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
  5974. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5975. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  5976. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5977. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5978. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5979. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5980. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5981. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5982. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5983. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5984. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5985. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5986. {
  5987. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5988. /* .name = "Capture Source", */
  5989. .name = "Input Source",
  5990. .count = 2,
  5991. .info = alc883_mux_enum_info,
  5992. .get = alc883_mux_enum_get,
  5993. .put = alc883_mux_enum_put,
  5994. },
  5995. { } /* end */
  5996. };
  5997. static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
  5998. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5999. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6000. HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  6001. HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
  6002. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6003. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6004. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6005. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6006. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6007. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6008. {
  6009. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6010. /* .name = "Capture Source", */
  6011. .name = "Input Source",
  6012. .count = 1,
  6013. .info = alc883_mux_enum_info,
  6014. .get = alc883_mux_enum_get,
  6015. .put = alc883_mux_enum_put,
  6016. },
  6017. { } /* end */
  6018. };
  6019. static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
  6020. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6021. HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
  6022. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6023. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6024. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6025. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6026. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6027. HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6028. HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6029. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6030. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6031. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6032. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6033. {
  6034. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6035. /* .name = "Capture Source", */
  6036. .name = "Input Source",
  6037. .count = 2,
  6038. .info = alc883_mux_enum_info,
  6039. .get = alc883_mux_enum_get,
  6040. .put = alc883_mux_enum_put,
  6041. },
  6042. { } /* end */
  6043. };
  6044. static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
  6045. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6046. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6047. HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  6048. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6049. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6050. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6051. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6052. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6053. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6054. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6055. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6056. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6057. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6058. {
  6059. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6060. /* .name = "Capture Source", */
  6061. .name = "Input Source",
  6062. .count = 2,
  6063. .info = alc883_mux_enum_info,
  6064. .get = alc883_mux_enum_get,
  6065. .put = alc883_mux_enum_put,
  6066. },
  6067. { } /* end */
  6068. };
  6069. static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
  6070. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6071. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6072. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  6073. HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
  6074. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  6075. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  6076. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  6077. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  6078. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  6079. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  6080. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6081. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6082. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6083. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6084. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6085. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6086. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6087. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6088. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6089. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6090. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6091. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6092. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6093. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6094. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6095. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6096. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6097. {
  6098. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6099. /* .name = "Capture Source", */
  6100. .name = "Input Source",
  6101. .count = 2,
  6102. .info = alc883_mux_enum_info,
  6103. .get = alc883_mux_enum_get,
  6104. .put = alc883_mux_enum_put,
  6105. },
  6106. { } /* end */
  6107. };
  6108. static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
  6109. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6110. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6111. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  6112. HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
  6113. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  6114. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  6115. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  6116. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  6117. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6118. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6119. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6120. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6121. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6122. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6123. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6124. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6125. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6126. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6127. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6128. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6129. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6130. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6131. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6132. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6133. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6134. {
  6135. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6136. /* .name = "Capture Source", */
  6137. .name = "Input Source",
  6138. .count = 2,
  6139. .info = alc883_mux_enum_info,
  6140. .get = alc883_mux_enum_get,
  6141. .put = alc883_mux_enum_put,
  6142. },
  6143. { } /* end */
  6144. };
  6145. static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
  6146. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6147. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6148. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6149. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6150. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6151. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6152. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6153. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6154. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6155. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6156. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6157. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6158. {
  6159. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6160. /* .name = "Capture Source", */
  6161. .name = "Input Source",
  6162. .count = 2,
  6163. .info = alc883_mux_enum_info,
  6164. .get = alc883_mux_enum_get,
  6165. .put = alc883_mux_enum_put,
  6166. },
  6167. { } /* end */
  6168. };
  6169. static struct snd_kcontrol_new alc883_chmode_mixer[] = {
  6170. {
  6171. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6172. .name = "Channel Mode",
  6173. .info = alc_ch_mode_info,
  6174. .get = alc_ch_mode_get,
  6175. .put = alc_ch_mode_put,
  6176. },
  6177. { } /* end */
  6178. };
  6179. static struct hda_verb alc883_init_verbs[] = {
  6180. /* ADC1: mute amp left and right */
  6181. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6182. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  6183. /* ADC2: mute amp left and right */
  6184. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6185. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  6186. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  6187. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6188. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6189. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6190. /* Rear mixer */
  6191. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6192. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6193. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6194. /* CLFE mixer */
  6195. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6196. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6197. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6198. /* Side mixer */
  6199. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6200. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6201. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6202. /* mute analog input loopbacks */
  6203. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6204. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6205. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  6206. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  6207. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  6208. /* Front Pin: output 0 (0x0c) */
  6209. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6210. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6211. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  6212. /* Rear Pin: output 1 (0x0d) */
  6213. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6214. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6215. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  6216. /* CLFE Pin: output 2 (0x0e) */
  6217. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6218. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6219. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  6220. /* Side Pin: output 3 (0x0f) */
  6221. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6222. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6223. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  6224. /* Mic (rear) pin: input vref at 80% */
  6225. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  6226. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6227. /* Front Mic pin: input vref at 80% */
  6228. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  6229. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6230. /* Line In pin: input */
  6231. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  6232. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6233. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  6234. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6235. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6236. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  6237. /* CD pin widget for input */
  6238. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  6239. /* FIXME: use matrix-type input source selection */
  6240. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  6241. /* Input mixer2 */
  6242. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6243. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6244. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6245. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6246. /* Input mixer3 */
  6247. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6248. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6249. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6250. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6251. { }
  6252. };
  6253. /* toggle speaker-output according to the hp-jack state */
  6254. static void alc883_mitac_hp_automute(struct hda_codec *codec)
  6255. {
  6256. unsigned int present;
  6257. present = snd_hda_codec_read(codec, 0x15, 0,
  6258. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6259. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6260. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6261. snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
  6262. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6263. }
  6264. /* auto-toggle front mic */
  6265. /*
  6266. static void alc883_mitac_mic_automute(struct hda_codec *codec)
  6267. {
  6268. unsigned int present;
  6269. unsigned char bits;
  6270. present = snd_hda_codec_read(codec, 0x18, 0,
  6271. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6272. bits = present ? HDA_AMP_MUTE : 0;
  6273. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
  6274. }
  6275. */
  6276. static void alc883_mitac_automute(struct hda_codec *codec)
  6277. {
  6278. alc883_mitac_hp_automute(codec);
  6279. /* alc883_mitac_mic_automute(codec); */
  6280. }
  6281. static void alc883_mitac_unsol_event(struct hda_codec *codec,
  6282. unsigned int res)
  6283. {
  6284. switch (res >> 26) {
  6285. case ALC880_HP_EVENT:
  6286. alc883_mitac_hp_automute(codec);
  6287. break;
  6288. case ALC880_MIC_EVENT:
  6289. /* alc883_mitac_mic_automute(codec); */
  6290. break;
  6291. }
  6292. }
  6293. static struct hda_verb alc883_mitac_verbs[] = {
  6294. /* HP */
  6295. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6296. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6297. /* Subwoofer */
  6298. {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
  6299. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6300. /* enable unsolicited event */
  6301. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6302. /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
  6303. { } /* end */
  6304. };
  6305. static struct hda_verb alc883_tagra_verbs[] = {
  6306. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6307. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6308. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6309. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6310. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  6311. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  6312. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  6313. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6314. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  6315. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  6316. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  6317. { } /* end */
  6318. };
  6319. static struct hda_verb alc883_lenovo_101e_verbs[] = {
  6320. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6321. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
  6322. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
  6323. { } /* end */
  6324. };
  6325. static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
  6326. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6327. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6328. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6329. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6330. { } /* end */
  6331. };
  6332. static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
  6333. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6334. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6335. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6336. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
  6337. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6338. { } /* end */
  6339. };
  6340. static struct hda_verb alc883_haier_w66_verbs[] = {
  6341. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6342. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6343. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6344. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  6345. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6346. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6347. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6348. { } /* end */
  6349. };
  6350. static struct hda_verb alc888_6st_hp_verbs[] = {
  6351. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
  6352. {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
  6353. {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
  6354. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
  6355. { }
  6356. };
  6357. static struct hda_verb alc888_3st_hp_verbs[] = {
  6358. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
  6359. {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
  6360. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
  6361. { }
  6362. };
  6363. static struct hda_verb alc888_3st_hp_2ch_init[] = {
  6364. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  6365. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  6366. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  6367. { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  6368. { }
  6369. };
  6370. static struct hda_verb alc888_3st_hp_6ch_init[] = {
  6371. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  6372. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  6373. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  6374. { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  6375. { }
  6376. };
  6377. static struct hda_channel_mode alc888_3st_hp_modes[2] = {
  6378. { 2, alc888_3st_hp_2ch_init },
  6379. { 6, alc888_3st_hp_6ch_init },
  6380. };
  6381. /* toggle front-jack and RCA according to the hp-jack state */
  6382. static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
  6383. {
  6384. unsigned int present;
  6385. present = snd_hda_codec_read(codec, 0x1b, 0,
  6386. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6387. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6388. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6389. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6390. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6391. }
  6392. /* toggle RCA according to the front-jack state */
  6393. static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
  6394. {
  6395. unsigned int present;
  6396. present = snd_hda_codec_read(codec, 0x14, 0,
  6397. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6398. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6399. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6400. }
  6401. static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
  6402. unsigned int res)
  6403. {
  6404. if ((res >> 26) == ALC880_HP_EVENT)
  6405. alc888_lenovo_ms7195_front_automute(codec);
  6406. if ((res >> 26) == ALC880_FRONT_EVENT)
  6407. alc888_lenovo_ms7195_rca_automute(codec);
  6408. }
  6409. static struct hda_verb alc883_medion_md2_verbs[] = {
  6410. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6411. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6412. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6413. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6414. { } /* end */
  6415. };
  6416. /* toggle speaker-output according to the hp-jack state */
  6417. static void alc883_medion_md2_automute(struct hda_codec *codec)
  6418. {
  6419. unsigned int present;
  6420. present = snd_hda_codec_read(codec, 0x14, 0,
  6421. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6422. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6423. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6424. }
  6425. static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
  6426. unsigned int res)
  6427. {
  6428. if ((res >> 26) == ALC880_HP_EVENT)
  6429. alc883_medion_md2_automute(codec);
  6430. }
  6431. /* toggle speaker-output according to the hp-jack state */
  6432. static void alc883_tagra_automute(struct hda_codec *codec)
  6433. {
  6434. unsigned int present;
  6435. unsigned char bits;
  6436. present = snd_hda_codec_read(codec, 0x14, 0,
  6437. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6438. bits = present ? HDA_AMP_MUTE : 0;
  6439. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  6440. HDA_AMP_MUTE, bits);
  6441. snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
  6442. present ? 1 : 3);
  6443. }
  6444. static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
  6445. {
  6446. if ((res >> 26) == ALC880_HP_EVENT)
  6447. alc883_tagra_automute(codec);
  6448. }
  6449. static void alc883_haier_w66_automute(struct hda_codec *codec)
  6450. {
  6451. unsigned int present;
  6452. unsigned char bits;
  6453. present = snd_hda_codec_read(codec, 0x1b, 0,
  6454. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6455. bits = present ? 0x80 : 0;
  6456. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6457. 0x80, bits);
  6458. }
  6459. static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
  6460. unsigned int res)
  6461. {
  6462. if ((res >> 26) == ALC880_HP_EVENT)
  6463. alc883_haier_w66_automute(codec);
  6464. }
  6465. static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
  6466. {
  6467. unsigned int present;
  6468. unsigned char bits;
  6469. present = snd_hda_codec_read(codec, 0x14, 0,
  6470. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6471. bits = present ? HDA_AMP_MUTE : 0;
  6472. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6473. HDA_AMP_MUTE, bits);
  6474. }
  6475. static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
  6476. {
  6477. unsigned int present;
  6478. unsigned char bits;
  6479. present = snd_hda_codec_read(codec, 0x1b, 0,
  6480. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6481. bits = present ? HDA_AMP_MUTE : 0;
  6482. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6483. HDA_AMP_MUTE, bits);
  6484. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6485. HDA_AMP_MUTE, bits);
  6486. }
  6487. static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
  6488. unsigned int res)
  6489. {
  6490. if ((res >> 26) == ALC880_HP_EVENT)
  6491. alc883_lenovo_101e_all_automute(codec);
  6492. if ((res >> 26) == ALC880_FRONT_EVENT)
  6493. alc883_lenovo_101e_ispeaker_automute(codec);
  6494. }
  6495. /* toggle speaker-output according to the hp-jack state */
  6496. static void alc883_acer_aspire_automute(struct hda_codec *codec)
  6497. {
  6498. unsigned int present;
  6499. present = snd_hda_codec_read(codec, 0x14, 0,
  6500. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6501. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6502. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6503. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  6504. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6505. }
  6506. static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
  6507. unsigned int res)
  6508. {
  6509. if ((res >> 26) == ALC880_HP_EVENT)
  6510. alc883_acer_aspire_automute(codec);
  6511. }
  6512. static struct hda_verb alc883_acer_eapd_verbs[] = {
  6513. /* HP Pin: output 0 (0x0c) */
  6514. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6515. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6516. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  6517. /* Front Pin: output 0 (0x0c) */
  6518. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6519. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6520. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6521. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
  6522. /* eanable EAPD on medion laptop */
  6523. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  6524. {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
  6525. /* enable unsolicited event */
  6526. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6527. { }
  6528. };
  6529. /*
  6530. * generic initialization of ADC, input mixers and output mixers
  6531. */
  6532. static struct hda_verb alc883_auto_init_verbs[] = {
  6533. /*
  6534. * Unmute ADC0-2 and set the default input to mic-in
  6535. */
  6536. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  6537. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6538. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  6539. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6540. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  6541. * mixer widget
  6542. * Note: PASD motherboards uses the Line In 2 as the input for
  6543. * front panel mic (mic 2)
  6544. */
  6545. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  6546. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6547. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6548. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  6549. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  6550. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  6551. /*
  6552. * Set up output mixers (0x0c - 0x0f)
  6553. */
  6554. /* set vol=0 to output mixers */
  6555. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6556. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6557. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6558. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6559. /* set up input amps for analog loopback */
  6560. /* Amp Indices: DAC = 0, mixer = 1 */
  6561. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6562. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6563. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6564. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6565. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6566. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6567. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6568. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6569. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6570. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6571. /* FIXME: use matrix-type input source selection */
  6572. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  6573. /* Input mixer1 */
  6574. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6575. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6576. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6577. /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
  6578. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6579. /* Input mixer2 */
  6580. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6581. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6582. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6583. /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
  6584. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6585. { }
  6586. };
  6587. /* capture mixer elements */
  6588. static struct snd_kcontrol_new alc883_capture_mixer[] = {
  6589. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6590. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6591. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6592. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6593. {
  6594. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6595. /* The multiple "Capture Source" controls confuse alsamixer
  6596. * So call somewhat different..
  6597. * FIXME: the controls appear in the "playback" view!
  6598. */
  6599. /* .name = "Capture Source", */
  6600. .name = "Input Source",
  6601. .count = 2,
  6602. .info = alc882_mux_enum_info,
  6603. .get = alc882_mux_enum_get,
  6604. .put = alc882_mux_enum_put,
  6605. },
  6606. { } /* end */
  6607. };
  6608. #ifdef CONFIG_SND_HDA_POWER_SAVE
  6609. #define alc883_loopbacks alc880_loopbacks
  6610. #endif
  6611. /* pcm configuration: identiacal with ALC880 */
  6612. #define alc883_pcm_analog_playback alc880_pcm_analog_playback
  6613. #define alc883_pcm_analog_capture alc880_pcm_analog_capture
  6614. #define alc883_pcm_digital_playback alc880_pcm_digital_playback
  6615. #define alc883_pcm_digital_capture alc880_pcm_digital_capture
  6616. /*
  6617. * configuration and preset
  6618. */
  6619. static const char *alc883_models[ALC883_MODEL_LAST] = {
  6620. [ALC883_3ST_2ch_DIG] = "3stack-dig",
  6621. [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
  6622. [ALC883_3ST_6ch] = "3stack-6ch",
  6623. [ALC883_6ST_DIG] = "6stack-dig",
  6624. [ALC883_TARGA_DIG] = "targa-dig",
  6625. [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
  6626. [ALC883_ACER] = "acer",
  6627. [ALC883_ACER_ASPIRE] = "acer-aspire",
  6628. [ALC883_MEDION] = "medion",
  6629. [ALC883_MEDION_MD2] = "medion-md2",
  6630. [ALC883_LAPTOP_EAPD] = "laptop-eapd",
  6631. [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
  6632. [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
  6633. [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
  6634. [ALC883_HAIER_W66] = "haier-w66",
  6635. [ALC888_6ST_HP] = "6stack-hp",
  6636. [ALC888_3ST_HP] = "3stack-hp",
  6637. [ALC883_MITAC] = "mitac",
  6638. [ALC883_AUTO] = "auto",
  6639. };
  6640. static struct snd_pci_quirk alc883_cfg_tbl[] = {
  6641. SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
  6642. SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
  6643. SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
  6644. SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
  6645. SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
  6646. SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
  6647. SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
  6648. SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
  6649. SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
  6650. SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
  6651. SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
  6652. SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
  6653. SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
  6654. SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
  6655. SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
  6656. SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
  6657. SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
  6658. SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
  6659. SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
  6660. SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
  6661. SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
  6662. SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
  6663. SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
  6664. SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
  6665. SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
  6666. SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
  6667. SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
  6668. SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
  6669. SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
  6670. SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
  6671. SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
  6672. SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
  6673. SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
  6674. SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
  6675. SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
  6676. SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
  6677. SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
  6678. SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
  6679. SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
  6680. SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6681. SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6682. SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6683. SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
  6684. SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
  6685. SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
  6686. {}
  6687. };
  6688. static struct alc_config_preset alc883_presets[] = {
  6689. [ALC883_3ST_2ch_DIG] = {
  6690. .mixers = { alc883_3ST_2ch_mixer },
  6691. .init_verbs = { alc883_init_verbs },
  6692. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6693. .dac_nids = alc883_dac_nids,
  6694. .dig_out_nid = ALC883_DIGOUT_NID,
  6695. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6696. .adc_nids = alc883_adc_nids,
  6697. .dig_in_nid = ALC883_DIGIN_NID,
  6698. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6699. .channel_mode = alc883_3ST_2ch_modes,
  6700. .input_mux = &alc883_capture_source,
  6701. },
  6702. [ALC883_3ST_6ch_DIG] = {
  6703. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  6704. .init_verbs = { alc883_init_verbs },
  6705. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6706. .dac_nids = alc883_dac_nids,
  6707. .dig_out_nid = ALC883_DIGOUT_NID,
  6708. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6709. .adc_nids = alc883_adc_nids,
  6710. .dig_in_nid = ALC883_DIGIN_NID,
  6711. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6712. .channel_mode = alc883_3ST_6ch_modes,
  6713. .need_dac_fix = 1,
  6714. .input_mux = &alc883_capture_source,
  6715. },
  6716. [ALC883_3ST_6ch] = {
  6717. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  6718. .init_verbs = { alc883_init_verbs },
  6719. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6720. .dac_nids = alc883_dac_nids,
  6721. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6722. .adc_nids = alc883_adc_nids,
  6723. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6724. .channel_mode = alc883_3ST_6ch_modes,
  6725. .need_dac_fix = 1,
  6726. .input_mux = &alc883_capture_source,
  6727. },
  6728. [ALC883_6ST_DIG] = {
  6729. .mixers = { alc883_base_mixer, alc883_chmode_mixer },
  6730. .init_verbs = { alc883_init_verbs },
  6731. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6732. .dac_nids = alc883_dac_nids,
  6733. .dig_out_nid = ALC883_DIGOUT_NID,
  6734. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6735. .adc_nids = alc883_adc_nids,
  6736. .dig_in_nid = ALC883_DIGIN_NID,
  6737. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  6738. .channel_mode = alc883_sixstack_modes,
  6739. .input_mux = &alc883_capture_source,
  6740. },
  6741. [ALC883_TARGA_DIG] = {
  6742. .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
  6743. .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
  6744. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6745. .dac_nids = alc883_dac_nids,
  6746. .dig_out_nid = ALC883_DIGOUT_NID,
  6747. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6748. .adc_nids = alc883_adc_nids,
  6749. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6750. .channel_mode = alc883_3ST_6ch_modes,
  6751. .need_dac_fix = 1,
  6752. .input_mux = &alc883_capture_source,
  6753. .unsol_event = alc883_tagra_unsol_event,
  6754. .init_hook = alc883_tagra_automute,
  6755. },
  6756. [ALC883_TARGA_2ch_DIG] = {
  6757. .mixers = { alc883_tagra_2ch_mixer},
  6758. .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
  6759. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6760. .dac_nids = alc883_dac_nids,
  6761. .dig_out_nid = ALC883_DIGOUT_NID,
  6762. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6763. .adc_nids = alc883_adc_nids,
  6764. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6765. .channel_mode = alc883_3ST_2ch_modes,
  6766. .input_mux = &alc883_capture_source,
  6767. .unsol_event = alc883_tagra_unsol_event,
  6768. .init_hook = alc883_tagra_automute,
  6769. },
  6770. [ALC883_ACER] = {
  6771. .mixers = { alc883_base_mixer },
  6772. /* On TravelMate laptops, GPIO 0 enables the internal speaker
  6773. * and the headphone jack. Turn this on and rely on the
  6774. * standard mute methods whenever the user wants to turn
  6775. * these outputs off.
  6776. */
  6777. .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
  6778. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6779. .dac_nids = alc883_dac_nids,
  6780. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6781. .adc_nids = alc883_adc_nids,
  6782. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6783. .channel_mode = alc883_3ST_2ch_modes,
  6784. .input_mux = &alc883_capture_source,
  6785. },
  6786. [ALC883_ACER_ASPIRE] = {
  6787. .mixers = { alc883_acer_aspire_mixer },
  6788. .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
  6789. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6790. .dac_nids = alc883_dac_nids,
  6791. .dig_out_nid = ALC883_DIGOUT_NID,
  6792. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6793. .adc_nids = alc883_adc_nids,
  6794. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6795. .channel_mode = alc883_3ST_2ch_modes,
  6796. .input_mux = &alc883_capture_source,
  6797. .unsol_event = alc883_acer_aspire_unsol_event,
  6798. .init_hook = alc883_acer_aspire_automute,
  6799. },
  6800. [ALC883_MEDION] = {
  6801. .mixers = { alc883_fivestack_mixer,
  6802. alc883_chmode_mixer },
  6803. .init_verbs = { alc883_init_verbs,
  6804. alc883_medion_eapd_verbs },
  6805. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6806. .dac_nids = alc883_dac_nids,
  6807. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6808. .adc_nids = alc883_adc_nids,
  6809. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  6810. .channel_mode = alc883_sixstack_modes,
  6811. .input_mux = &alc883_capture_source,
  6812. },
  6813. [ALC883_MEDION_MD2] = {
  6814. .mixers = { alc883_medion_md2_mixer},
  6815. .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
  6816. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6817. .dac_nids = alc883_dac_nids,
  6818. .dig_out_nid = ALC883_DIGOUT_NID,
  6819. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6820. .adc_nids = alc883_adc_nids,
  6821. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6822. .channel_mode = alc883_3ST_2ch_modes,
  6823. .input_mux = &alc883_capture_source,
  6824. .unsol_event = alc883_medion_md2_unsol_event,
  6825. .init_hook = alc883_medion_md2_automute,
  6826. },
  6827. [ALC883_LAPTOP_EAPD] = {
  6828. .mixers = { alc883_base_mixer },
  6829. .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
  6830. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6831. .dac_nids = alc883_dac_nids,
  6832. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6833. .adc_nids = alc883_adc_nids,
  6834. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6835. .channel_mode = alc883_3ST_2ch_modes,
  6836. .input_mux = &alc883_capture_source,
  6837. },
  6838. [ALC883_LENOVO_101E_2ch] = {
  6839. .mixers = { alc883_lenovo_101e_2ch_mixer},
  6840. .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
  6841. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6842. .dac_nids = alc883_dac_nids,
  6843. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6844. .adc_nids = alc883_adc_nids,
  6845. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6846. .channel_mode = alc883_3ST_2ch_modes,
  6847. .input_mux = &alc883_lenovo_101e_capture_source,
  6848. .unsol_event = alc883_lenovo_101e_unsol_event,
  6849. .init_hook = alc883_lenovo_101e_all_automute,
  6850. },
  6851. [ALC883_LENOVO_NB0763] = {
  6852. .mixers = { alc883_lenovo_nb0763_mixer },
  6853. .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
  6854. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6855. .dac_nids = alc883_dac_nids,
  6856. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6857. .adc_nids = alc883_adc_nids,
  6858. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6859. .channel_mode = alc883_3ST_2ch_modes,
  6860. .need_dac_fix = 1,
  6861. .input_mux = &alc883_lenovo_nb0763_capture_source,
  6862. .unsol_event = alc883_medion_md2_unsol_event,
  6863. .init_hook = alc883_medion_md2_automute,
  6864. },
  6865. [ALC888_LENOVO_MS7195_DIG] = {
  6866. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  6867. .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
  6868. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6869. .dac_nids = alc883_dac_nids,
  6870. .dig_out_nid = ALC883_DIGOUT_NID,
  6871. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6872. .adc_nids = alc883_adc_nids,
  6873. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6874. .channel_mode = alc883_3ST_6ch_modes,
  6875. .need_dac_fix = 1,
  6876. .input_mux = &alc883_capture_source,
  6877. .unsol_event = alc883_lenovo_ms7195_unsol_event,
  6878. .init_hook = alc888_lenovo_ms7195_front_automute,
  6879. },
  6880. [ALC883_HAIER_W66] = {
  6881. .mixers = { alc883_tagra_2ch_mixer},
  6882. .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
  6883. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6884. .dac_nids = alc883_dac_nids,
  6885. .dig_out_nid = ALC883_DIGOUT_NID,
  6886. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6887. .adc_nids = alc883_adc_nids,
  6888. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6889. .channel_mode = alc883_3ST_2ch_modes,
  6890. .input_mux = &alc883_capture_source,
  6891. .unsol_event = alc883_haier_w66_unsol_event,
  6892. .init_hook = alc883_haier_w66_automute,
  6893. },
  6894. [ALC888_6ST_HP] = {
  6895. .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
  6896. .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
  6897. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6898. .dac_nids = alc883_dac_nids,
  6899. .dig_out_nid = ALC883_DIGOUT_NID,
  6900. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6901. .adc_nids = alc883_adc_nids,
  6902. .dig_in_nid = ALC883_DIGIN_NID,
  6903. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  6904. .channel_mode = alc883_sixstack_modes,
  6905. .input_mux = &alc883_capture_source,
  6906. },
  6907. [ALC888_3ST_HP] = {
  6908. .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
  6909. .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
  6910. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6911. .dac_nids = alc883_dac_nids,
  6912. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6913. .adc_nids = alc883_adc_nids,
  6914. .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
  6915. .channel_mode = alc888_3st_hp_modes,
  6916. .need_dac_fix = 1,
  6917. .input_mux = &alc883_capture_source,
  6918. },
  6919. [ALC883_MITAC] = {
  6920. .mixers = { alc883_mitac_mixer },
  6921. .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
  6922. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6923. .dac_nids = alc883_dac_nids,
  6924. .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
  6925. .adc_nids = alc883_adc_nids,
  6926. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6927. .channel_mode = alc883_3ST_2ch_modes,
  6928. .input_mux = &alc883_capture_source,
  6929. .unsol_event = alc883_mitac_unsol_event,
  6930. .init_hook = alc883_mitac_automute,
  6931. },
  6932. };
  6933. /*
  6934. * BIOS auto configuration
  6935. */
  6936. static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
  6937. hda_nid_t nid, int pin_type,
  6938. int dac_idx)
  6939. {
  6940. /* set as output */
  6941. struct alc_spec *spec = codec->spec;
  6942. int idx;
  6943. if (spec->multiout.dac_nids[dac_idx] == 0x25)
  6944. idx = 4;
  6945. else
  6946. idx = spec->multiout.dac_nids[dac_idx] - 2;
  6947. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  6948. pin_type);
  6949. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  6950. AMP_OUT_UNMUTE);
  6951. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
  6952. }
  6953. static void alc883_auto_init_multi_out(struct hda_codec *codec)
  6954. {
  6955. struct alc_spec *spec = codec->spec;
  6956. int i;
  6957. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  6958. for (i = 0; i <= HDA_SIDE; i++) {
  6959. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  6960. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  6961. if (nid)
  6962. alc883_auto_set_output_and_unmute(codec, nid, pin_type,
  6963. i);
  6964. }
  6965. }
  6966. static void alc883_auto_init_hp_out(struct hda_codec *codec)
  6967. {
  6968. struct alc_spec *spec = codec->spec;
  6969. hda_nid_t pin;
  6970. pin = spec->autocfg.hp_pins[0];
  6971. if (pin) /* connect to front */
  6972. /* use dac 0 */
  6973. alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  6974. }
  6975. #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
  6976. #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
  6977. static void alc883_auto_init_analog_input(struct hda_codec *codec)
  6978. {
  6979. struct alc_spec *spec = codec->spec;
  6980. int i;
  6981. for (i = 0; i < AUTO_PIN_LAST; i++) {
  6982. hda_nid_t nid = spec->autocfg.input_pins[i];
  6983. if (alc883_is_input_pin(nid)) {
  6984. snd_hda_codec_write(codec, nid, 0,
  6985. AC_VERB_SET_PIN_WIDGET_CONTROL,
  6986. (i <= AUTO_PIN_FRONT_MIC ?
  6987. PIN_VREF80 : PIN_IN));
  6988. if (nid != ALC883_PIN_CD_NID)
  6989. snd_hda_codec_write(codec, nid, 0,
  6990. AC_VERB_SET_AMP_GAIN_MUTE,
  6991. AMP_OUT_MUTE);
  6992. }
  6993. }
  6994. }
  6995. /* almost identical with ALC880 parser... */
  6996. static int alc883_parse_auto_config(struct hda_codec *codec)
  6997. {
  6998. struct alc_spec *spec = codec->spec;
  6999. int err = alc880_parse_auto_config(codec);
  7000. if (err < 0)
  7001. return err;
  7002. else if (!err)
  7003. return 0; /* no config found */
  7004. err = alc_auto_add_mic_boost(codec);
  7005. if (err < 0)
  7006. return err;
  7007. /* hack - override the init verbs */
  7008. spec->init_verbs[0] = alc883_auto_init_verbs;
  7009. spec->mixers[spec->num_mixers] = alc883_capture_mixer;
  7010. spec->num_mixers++;
  7011. return 1; /* config found */
  7012. }
  7013. /* additional initialization for auto-configuration model */
  7014. static void alc883_auto_init(struct hda_codec *codec)
  7015. {
  7016. alc883_auto_init_multi_out(codec);
  7017. alc883_auto_init_hp_out(codec);
  7018. alc883_auto_init_analog_input(codec);
  7019. }
  7020. static int patch_alc883(struct hda_codec *codec)
  7021. {
  7022. struct alc_spec *spec;
  7023. int err, board_config;
  7024. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  7025. if (spec == NULL)
  7026. return -ENOMEM;
  7027. codec->spec = spec;
  7028. board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
  7029. alc883_models,
  7030. alc883_cfg_tbl);
  7031. if (board_config < 0) {
  7032. printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
  7033. "trying auto-probe from BIOS...\n");
  7034. board_config = ALC883_AUTO;
  7035. }
  7036. if (board_config == ALC883_AUTO) {
  7037. /* automatic parse from the BIOS config */
  7038. err = alc883_parse_auto_config(codec);
  7039. if (err < 0) {
  7040. alc_free(codec);
  7041. return err;
  7042. } else if (!err) {
  7043. printk(KERN_INFO
  7044. "hda_codec: Cannot set up configuration "
  7045. "from BIOS. Using base mode...\n");
  7046. board_config = ALC883_3ST_2ch_DIG;
  7047. }
  7048. }
  7049. if (board_config != ALC883_AUTO)
  7050. setup_preset(spec, &alc883_presets[board_config]);
  7051. spec->stream_name_analog = "ALC883 Analog";
  7052. spec->stream_analog_playback = &alc883_pcm_analog_playback;
  7053. spec->stream_analog_capture = &alc883_pcm_analog_capture;
  7054. spec->stream_name_digital = "ALC883 Digital";
  7055. spec->stream_digital_playback = &alc883_pcm_digital_playback;
  7056. spec->stream_digital_capture = &alc883_pcm_digital_capture;
  7057. if (!spec->adc_nids && spec->input_mux) {
  7058. spec->adc_nids = alc883_adc_nids;
  7059. spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
  7060. }
  7061. codec->patch_ops = alc_patch_ops;
  7062. if (board_config == ALC883_AUTO)
  7063. spec->init_hook = alc883_auto_init;
  7064. #ifdef CONFIG_SND_HDA_POWER_SAVE
  7065. if (!spec->loopback.amplist)
  7066. spec->loopback.amplist = alc883_loopbacks;
  7067. #endif
  7068. return 0;
  7069. }
  7070. /*
  7071. * ALC262 support
  7072. */
  7073. #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
  7074. #define ALC262_DIGIN_NID ALC880_DIGIN_NID
  7075. #define alc262_dac_nids alc260_dac_nids
  7076. #define alc262_adc_nids alc882_adc_nids
  7077. #define alc262_adc_nids_alt alc882_adc_nids_alt
  7078. #define alc262_modes alc260_modes
  7079. #define alc262_capture_source alc882_capture_source
  7080. static struct snd_kcontrol_new alc262_base_mixer[] = {
  7081. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7082. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7083. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7084. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7085. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7086. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7087. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7088. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7089. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7090. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7091. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7092. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7093. /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7094. HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
  7095. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
  7096. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7097. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  7098. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  7099. { } /* end */
  7100. };
  7101. static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
  7102. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7103. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7104. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7105. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7106. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7107. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7108. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7109. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7110. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7111. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7112. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7113. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7114. /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7115. HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
  7116. /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
  7117. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7118. { } /* end */
  7119. };
  7120. static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
  7121. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7122. HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7123. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7124. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  7125. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  7126. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7127. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7128. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7129. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7130. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7131. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7132. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7133. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7134. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7135. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7136. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7137. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
  7138. HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
  7139. HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
  7140. { } /* end */
  7141. };
  7142. static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
  7143. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7144. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7145. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  7146. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7147. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  7148. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  7149. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7150. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7151. HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
  7152. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7153. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7154. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7155. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7156. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7157. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
  7158. { } /* end */
  7159. };
  7160. static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
  7161. HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7162. HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7163. HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
  7164. { } /* end */
  7165. };
  7166. static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
  7167. .ops = &snd_hda_bind_vol,
  7168. .values = {
  7169. HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
  7170. HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
  7171. 0
  7172. },
  7173. };
  7174. static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
  7175. .ops = &snd_hda_bind_sw,
  7176. .values = {
  7177. HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  7178. HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
  7179. 0
  7180. },
  7181. };
  7182. /* mute/unmute internal speaker according to the hp jack and mute state */
  7183. static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
  7184. {
  7185. struct alc_spec *spec = codec->spec;
  7186. unsigned int mute;
  7187. if (force || !spec->sense_updated) {
  7188. unsigned int present;
  7189. present = snd_hda_codec_read(codec, 0x15, 0,
  7190. AC_VERB_GET_PIN_SENSE, 0);
  7191. spec->jack_present = (present & 0x80000000) != 0;
  7192. spec->sense_updated = 1;
  7193. }
  7194. if (spec->jack_present)
  7195. mute = (0x7080 | ((0)<<8)); /* mute internal speaker */
  7196. else /* unmute internal speaker if necessary */
  7197. mute = (0x7000 | ((0)<<8));
  7198. snd_hda_codec_write(codec, 0x0c, 0,
  7199. AC_VERB_SET_AMP_GAIN_MUTE, mute );
  7200. }
  7201. static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
  7202. unsigned int res)
  7203. {
  7204. if ((res >> 26) != ALC880_HP_EVENT)
  7205. return;
  7206. alc262_hp_t5735_automute(codec, 1);
  7207. }
  7208. static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
  7209. {
  7210. alc262_hp_t5735_automute(codec, 1);
  7211. }
  7212. static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
  7213. HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
  7214. HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
  7215. HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7216. HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7217. HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7218. HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7219. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  7220. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7221. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7222. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7223. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7224. { } /* end */
  7225. };
  7226. static struct hda_verb alc262_hp_t5735_verbs[] = {
  7227. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  7228. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7229. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  7230. { }
  7231. };
  7232. /* bind hp and internal speaker mute (with plug check) */
  7233. static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
  7234. struct snd_ctl_elem_value *ucontrol)
  7235. {
  7236. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7237. long *valp = ucontrol->value.integer.value;
  7238. int change;
  7239. /* change hp mute */
  7240. change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
  7241. HDA_AMP_MUTE,
  7242. valp[0] ? 0 : HDA_AMP_MUTE);
  7243. change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
  7244. HDA_AMP_MUTE,
  7245. valp[1] ? 0 : HDA_AMP_MUTE);
  7246. if (change) {
  7247. /* change speaker according to HP jack state */
  7248. struct alc_spec *spec = codec->spec;
  7249. unsigned int mute;
  7250. if (spec->jack_present)
  7251. mute = HDA_AMP_MUTE;
  7252. else
  7253. mute = snd_hda_codec_amp_read(codec, 0x15, 0,
  7254. HDA_OUTPUT, 0);
  7255. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7256. HDA_AMP_MUTE, mute);
  7257. }
  7258. return change;
  7259. }
  7260. static struct snd_kcontrol_new alc262_sony_mixer[] = {
  7261. HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7262. {
  7263. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7264. .name = "Master Playback Switch",
  7265. .info = snd_hda_mixer_amp_switch_info,
  7266. .get = snd_hda_mixer_amp_switch_get,
  7267. .put = alc262_sony_master_sw_put,
  7268. .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
  7269. },
  7270. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7271. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7272. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7273. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7274. { } /* end */
  7275. };
  7276. static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
  7277. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7278. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7279. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7280. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7281. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7282. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7283. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7284. { } /* end */
  7285. };
  7286. #define alc262_capture_mixer alc882_capture_mixer
  7287. #define alc262_capture_alt_mixer alc882_capture_alt_mixer
  7288. /*
  7289. * generic initialization of ADC, input mixers and output mixers
  7290. */
  7291. static struct hda_verb alc262_init_verbs[] = {
  7292. /*
  7293. * Unmute ADC0-2 and set the default input to mic-in
  7294. */
  7295. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  7296. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7297. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  7298. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7299. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  7300. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7301. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  7302. * mixer widget
  7303. * Note: PASD motherboards uses the Line In 2 as the input for
  7304. * front panel mic (mic 2)
  7305. */
  7306. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  7307. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  7308. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  7309. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  7310. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  7311. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  7312. /*
  7313. * Set up output mixers (0x0c - 0x0e)
  7314. */
  7315. /* set vol=0 to output mixers */
  7316. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7317. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7318. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7319. /* set up input amps for analog loopback */
  7320. /* Amp Indices: DAC = 0, mixer = 1 */
  7321. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7322. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7323. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7324. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7325. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7326. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7327. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7328. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7329. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7330. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7331. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7332. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7333. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7334. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7335. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7336. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7337. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7338. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  7339. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  7340. /* FIXME: use matrix-type input source selection */
  7341. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  7342. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  7343. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7344. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7345. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7346. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7347. /* Input mixer2 */
  7348. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7349. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7350. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7351. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7352. /* Input mixer3 */
  7353. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7354. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7355. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7356. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7357. { }
  7358. };
  7359. static struct hda_verb alc262_hippo_unsol_verbs[] = {
  7360. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7361. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7362. {}
  7363. };
  7364. static struct hda_verb alc262_hippo1_unsol_verbs[] = {
  7365. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7366. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  7367. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7368. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7369. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7370. {}
  7371. };
  7372. static struct hda_verb alc262_sony_unsol_verbs[] = {
  7373. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7374. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  7375. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
  7376. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7377. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7378. };
  7379. /* mute/unmute internal speaker according to the hp jack and mute state */
  7380. static void alc262_hippo_automute(struct hda_codec *codec)
  7381. {
  7382. struct alc_spec *spec = codec->spec;
  7383. unsigned int mute;
  7384. unsigned int present;
  7385. /* need to execute and sync at first */
  7386. snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
  7387. present = snd_hda_codec_read(codec, 0x15, 0,
  7388. AC_VERB_GET_PIN_SENSE, 0);
  7389. spec->jack_present = (present & 0x80000000) != 0;
  7390. if (spec->jack_present) {
  7391. /* mute internal speaker */
  7392. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7393. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7394. } else {
  7395. /* unmute internal speaker if necessary */
  7396. mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
  7397. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7398. HDA_AMP_MUTE, mute);
  7399. }
  7400. }
  7401. /* unsolicited event for HP jack sensing */
  7402. static void alc262_hippo_unsol_event(struct hda_codec *codec,
  7403. unsigned int res)
  7404. {
  7405. if ((res >> 26) != ALC880_HP_EVENT)
  7406. return;
  7407. alc262_hippo_automute(codec);
  7408. }
  7409. static void alc262_hippo1_automute(struct hda_codec *codec)
  7410. {
  7411. unsigned int mute;
  7412. unsigned int present;
  7413. snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
  7414. present = snd_hda_codec_read(codec, 0x1b, 0,
  7415. AC_VERB_GET_PIN_SENSE, 0);
  7416. present = (present & 0x80000000) != 0;
  7417. if (present) {
  7418. /* mute internal speaker */
  7419. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7420. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7421. } else {
  7422. /* unmute internal speaker if necessary */
  7423. mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
  7424. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7425. HDA_AMP_MUTE, mute);
  7426. }
  7427. }
  7428. /* unsolicited event for HP jack sensing */
  7429. static void alc262_hippo1_unsol_event(struct hda_codec *codec,
  7430. unsigned int res)
  7431. {
  7432. if ((res >> 26) != ALC880_HP_EVENT)
  7433. return;
  7434. alc262_hippo1_automute(codec);
  7435. }
  7436. /*
  7437. * fujitsu model
  7438. * 0x14 = headphone/spdif-out, 0x15 = internal speaker
  7439. */
  7440. #define ALC_HP_EVENT 0x37
  7441. static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
  7442. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  7443. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7444. {}
  7445. };
  7446. static struct hda_input_mux alc262_fujitsu_capture_source = {
  7447. .num_items = 3,
  7448. .items = {
  7449. { "Mic", 0x0 },
  7450. { "Int Mic", 0x1 },
  7451. { "CD", 0x4 },
  7452. },
  7453. };
  7454. static struct hda_input_mux alc262_HP_capture_source = {
  7455. .num_items = 5,
  7456. .items = {
  7457. { "Mic", 0x0 },
  7458. { "Front Mic", 0x1 },
  7459. { "Line", 0x2 },
  7460. { "CD", 0x4 },
  7461. { "AUX IN", 0x6 },
  7462. },
  7463. };
  7464. static struct hda_input_mux alc262_HP_D7000_capture_source = {
  7465. .num_items = 4,
  7466. .items = {
  7467. { "Mic", 0x0 },
  7468. { "Front Mic", 0x2 },
  7469. { "Line", 0x1 },
  7470. { "CD", 0x4 },
  7471. },
  7472. };
  7473. /* mute/unmute internal speaker according to the hp jack and mute state */
  7474. static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
  7475. {
  7476. struct alc_spec *spec = codec->spec;
  7477. unsigned int mute;
  7478. if (force || !spec->sense_updated) {
  7479. unsigned int present;
  7480. /* need to execute and sync at first */
  7481. snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
  7482. present = snd_hda_codec_read(codec, 0x14, 0,
  7483. AC_VERB_GET_PIN_SENSE, 0);
  7484. spec->jack_present = (present & 0x80000000) != 0;
  7485. spec->sense_updated = 1;
  7486. }
  7487. if (spec->jack_present) {
  7488. /* mute internal speaker */
  7489. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  7490. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7491. } else {
  7492. /* unmute internal speaker if necessary */
  7493. mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
  7494. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  7495. HDA_AMP_MUTE, mute);
  7496. }
  7497. }
  7498. /* unsolicited event for HP jack sensing */
  7499. static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
  7500. unsigned int res)
  7501. {
  7502. if ((res >> 26) != ALC_HP_EVENT)
  7503. return;
  7504. alc262_fujitsu_automute(codec, 1);
  7505. }
  7506. /* bind volumes of both NID 0x0c and 0x0d */
  7507. static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
  7508. .ops = &snd_hda_bind_vol,
  7509. .values = {
  7510. HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
  7511. HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
  7512. 0
  7513. },
  7514. };
  7515. /* bind hp and internal speaker mute (with plug check) */
  7516. static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
  7517. struct snd_ctl_elem_value *ucontrol)
  7518. {
  7519. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7520. long *valp = ucontrol->value.integer.value;
  7521. int change;
  7522. change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
  7523. HDA_AMP_MUTE,
  7524. valp[0] ? 0 : HDA_AMP_MUTE);
  7525. change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
  7526. HDA_AMP_MUTE,
  7527. valp[1] ? 0 : HDA_AMP_MUTE);
  7528. if (change)
  7529. alc262_fujitsu_automute(codec, 0);
  7530. return change;
  7531. }
  7532. static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
  7533. HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
  7534. {
  7535. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7536. .name = "Master Playback Switch",
  7537. .info = snd_hda_mixer_amp_switch_info,
  7538. .get = snd_hda_mixer_amp_switch_get,
  7539. .put = alc262_fujitsu_master_sw_put,
  7540. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  7541. },
  7542. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7543. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7544. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7545. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7546. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7547. HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
  7548. HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  7549. HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  7550. { } /* end */
  7551. };
  7552. /* additional init verbs for Benq laptops */
  7553. static struct hda_verb alc262_EAPD_verbs[] = {
  7554. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  7555. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  7556. {}
  7557. };
  7558. static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
  7559. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  7560. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7561. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  7562. {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
  7563. {}
  7564. };
  7565. /* Samsung Q1 Ultra Vista model setup */
  7566. static struct snd_kcontrol_new alc262_ultra_mixer[] = {
  7567. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7568. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7569. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7570. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7571. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7572. HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
  7573. { } /* end */
  7574. };
  7575. static struct hda_verb alc262_ultra_verbs[] = {
  7576. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7577. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7578. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7579. /* Mic is on Node 0x19 */
  7580. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7581. {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
  7582. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7583. {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
  7584. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7585. {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
  7586. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7587. {}
  7588. };
  7589. static struct hda_input_mux alc262_ultra_capture_source = {
  7590. .num_items = 1,
  7591. .items = {
  7592. { "Mic", 0x1 },
  7593. },
  7594. };
  7595. /* mute/unmute internal speaker according to the hp jack and mute state */
  7596. static void alc262_ultra_automute(struct hda_codec *codec)
  7597. {
  7598. struct alc_spec *spec = codec->spec;
  7599. unsigned int mute;
  7600. unsigned int present;
  7601. /* need to execute and sync at first */
  7602. snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
  7603. present = snd_hda_codec_read(codec, 0x15, 0,
  7604. AC_VERB_GET_PIN_SENSE, 0);
  7605. spec->jack_present = (present & 0x80000000) != 0;
  7606. if (spec->jack_present) {
  7607. /* mute internal speaker */
  7608. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7609. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7610. } else {
  7611. /* unmute internal speaker if necessary */
  7612. mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
  7613. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7614. HDA_AMP_MUTE, mute);
  7615. }
  7616. }
  7617. /* unsolicited event for HP jack sensing */
  7618. static void alc262_ultra_unsol_event(struct hda_codec *codec,
  7619. unsigned int res)
  7620. {
  7621. if ((res >> 26) != ALC880_HP_EVENT)
  7622. return;
  7623. alc262_ultra_automute(codec);
  7624. }
  7625. /* add playback controls from the parsed DAC table */
  7626. static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
  7627. const struct auto_pin_cfg *cfg)
  7628. {
  7629. hda_nid_t nid;
  7630. int err;
  7631. spec->multiout.num_dacs = 1; /* only use one dac */
  7632. spec->multiout.dac_nids = spec->private_dac_nids;
  7633. spec->multiout.dac_nids[0] = 2;
  7634. nid = cfg->line_out_pins[0];
  7635. if (nid) {
  7636. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  7637. "Front Playback Volume",
  7638. HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
  7639. if (err < 0)
  7640. return err;
  7641. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7642. "Front Playback Switch",
  7643. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  7644. if (err < 0)
  7645. return err;
  7646. }
  7647. nid = cfg->speaker_pins[0];
  7648. if (nid) {
  7649. if (nid == 0x16) {
  7650. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  7651. "Speaker Playback Volume",
  7652. HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
  7653. HDA_OUTPUT));
  7654. if (err < 0)
  7655. return err;
  7656. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7657. "Speaker Playback Switch",
  7658. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  7659. HDA_OUTPUT));
  7660. if (err < 0)
  7661. return err;
  7662. } else {
  7663. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7664. "Speaker Playback Switch",
  7665. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  7666. HDA_OUTPUT));
  7667. if (err < 0)
  7668. return err;
  7669. }
  7670. }
  7671. nid = cfg->hp_pins[0];
  7672. if (nid) {
  7673. /* spec->multiout.hp_nid = 2; */
  7674. if (nid == 0x16) {
  7675. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  7676. "Headphone Playback Volume",
  7677. HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
  7678. HDA_OUTPUT));
  7679. if (err < 0)
  7680. return err;
  7681. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7682. "Headphone Playback Switch",
  7683. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  7684. HDA_OUTPUT));
  7685. if (err < 0)
  7686. return err;
  7687. } else {
  7688. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7689. "Headphone Playback Switch",
  7690. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  7691. HDA_OUTPUT));
  7692. if (err < 0)
  7693. return err;
  7694. }
  7695. }
  7696. return 0;
  7697. }
  7698. /* identical with ALC880 */
  7699. #define alc262_auto_create_analog_input_ctls \
  7700. alc880_auto_create_analog_input_ctls
  7701. /*
  7702. * generic initialization of ADC, input mixers and output mixers
  7703. */
  7704. static struct hda_verb alc262_volume_init_verbs[] = {
  7705. /*
  7706. * Unmute ADC0-2 and set the default input to mic-in
  7707. */
  7708. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  7709. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7710. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  7711. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7712. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  7713. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7714. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  7715. * mixer widget
  7716. * Note: PASD motherboards uses the Line In 2 as the input for
  7717. * front panel mic (mic 2)
  7718. */
  7719. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  7720. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  7721. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  7722. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  7723. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  7724. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  7725. /*
  7726. * Set up output mixers (0x0c - 0x0f)
  7727. */
  7728. /* set vol=0 to output mixers */
  7729. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7730. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7731. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7732. /* set up input amps for analog loopback */
  7733. /* Amp Indices: DAC = 0, mixer = 1 */
  7734. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7735. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7736. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7737. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7738. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7739. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7740. /* FIXME: use matrix-type input source selection */
  7741. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  7742. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  7743. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7744. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7745. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7746. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7747. /* Input mixer2 */
  7748. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7749. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7750. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7751. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7752. /* Input mixer3 */
  7753. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7754. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7755. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7756. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7757. { }
  7758. };
  7759. static struct hda_verb alc262_HP_BPC_init_verbs[] = {
  7760. /*
  7761. * Unmute ADC0-2 and set the default input to mic-in
  7762. */
  7763. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  7764. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7765. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  7766. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7767. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  7768. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7769. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  7770. * mixer widget
  7771. * Note: PASD motherboards uses the Line In 2 as the input for
  7772. * front panel mic (mic 2)
  7773. */
  7774. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  7775. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  7776. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  7777. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  7778. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  7779. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  7780. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  7781. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  7782. /*
  7783. * Set up output mixers (0x0c - 0x0e)
  7784. */
  7785. /* set vol=0 to output mixers */
  7786. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7787. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7788. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7789. /* set up input amps for analog loopback */
  7790. /* Amp Indices: DAC = 0, mixer = 1 */
  7791. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7792. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7793. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7794. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7795. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7796. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7797. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7798. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  7799. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  7800. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  7801. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  7802. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  7803. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  7804. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7805. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7806. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7807. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7808. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7809. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  7810. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7811. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7812. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  7813. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7814. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7815. /* FIXME: use matrix-type input source selection */
  7816. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  7817. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  7818. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7819. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  7820. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  7821. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  7822. /* Input mixer2 */
  7823. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7824. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  7825. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  7826. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  7827. /* Input mixer3 */
  7828. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7829. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  7830. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  7831. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  7832. { }
  7833. };
  7834. static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
  7835. /*
  7836. * Unmute ADC0-2 and set the default input to mic-in
  7837. */
  7838. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  7839. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7840. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  7841. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7842. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  7843. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7844. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  7845. * mixer widget
  7846. * Note: PASD motherboards uses the Line In 2 as the input for front
  7847. * panel mic (mic 2)
  7848. */
  7849. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  7850. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  7851. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  7852. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  7853. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  7854. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  7855. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  7856. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  7857. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  7858. /*
  7859. * Set up output mixers (0x0c - 0x0e)
  7860. */
  7861. /* set vol=0 to output mixers */
  7862. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7863. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7864. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7865. /* set up input amps for analog loopback */
  7866. /* Amp Indices: DAC = 0, mixer = 1 */
  7867. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7868. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7869. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7870. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7871. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7872. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7873. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
  7874. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
  7875. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
  7876. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
  7877. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
  7878. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
  7879. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
  7880. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  7881. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  7882. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  7883. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  7884. /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
  7885. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7886. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7887. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  7888. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7889. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  7890. /* FIXME: use matrix-type input source selection */
  7891. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  7892. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  7893. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
  7894. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
  7895. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
  7896. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
  7897. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
  7898. /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  7899. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
  7900. /* Input mixer2 */
  7901. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7902. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7903. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  7904. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  7905. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  7906. /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  7907. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
  7908. /* Input mixer3 */
  7909. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7910. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7911. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  7912. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  7913. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  7914. /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  7915. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
  7916. { }
  7917. };
  7918. #ifdef CONFIG_SND_HDA_POWER_SAVE
  7919. #define alc262_loopbacks alc880_loopbacks
  7920. #endif
  7921. /* pcm configuration: identiacal with ALC880 */
  7922. #define alc262_pcm_analog_playback alc880_pcm_analog_playback
  7923. #define alc262_pcm_analog_capture alc880_pcm_analog_capture
  7924. #define alc262_pcm_digital_playback alc880_pcm_digital_playback
  7925. #define alc262_pcm_digital_capture alc880_pcm_digital_capture
  7926. /*
  7927. * BIOS auto configuration
  7928. */
  7929. static int alc262_parse_auto_config(struct hda_codec *codec)
  7930. {
  7931. struct alc_spec *spec = codec->spec;
  7932. int err;
  7933. static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
  7934. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  7935. alc262_ignore);
  7936. if (err < 0)
  7937. return err;
  7938. if (!spec->autocfg.line_outs)
  7939. return 0; /* can't find valid BIOS pin config */
  7940. err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
  7941. if (err < 0)
  7942. return err;
  7943. err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
  7944. if (err < 0)
  7945. return err;
  7946. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  7947. if (spec->autocfg.dig_out_pin)
  7948. spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
  7949. if (spec->autocfg.dig_in_pin)
  7950. spec->dig_in_nid = ALC262_DIGIN_NID;
  7951. if (spec->kctl_alloc)
  7952. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  7953. spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
  7954. spec->num_mux_defs = 1;
  7955. spec->input_mux = &spec->private_imux;
  7956. err = alc_auto_add_mic_boost(codec);
  7957. if (err < 0)
  7958. return err;
  7959. return 1;
  7960. }
  7961. #define alc262_auto_init_multi_out alc882_auto_init_multi_out
  7962. #define alc262_auto_init_hp_out alc882_auto_init_hp_out
  7963. #define alc262_auto_init_analog_input alc882_auto_init_analog_input
  7964. /* init callback for auto-configuration model -- overriding the default init */
  7965. static void alc262_auto_init(struct hda_codec *codec)
  7966. {
  7967. alc262_auto_init_multi_out(codec);
  7968. alc262_auto_init_hp_out(codec);
  7969. alc262_auto_init_analog_input(codec);
  7970. }
  7971. /*
  7972. * configuration and preset
  7973. */
  7974. static const char *alc262_models[ALC262_MODEL_LAST] = {
  7975. [ALC262_BASIC] = "basic",
  7976. [ALC262_HIPPO] = "hippo",
  7977. [ALC262_HIPPO_1] = "hippo_1",
  7978. [ALC262_FUJITSU] = "fujitsu",
  7979. [ALC262_HP_BPC] = "hp-bpc",
  7980. [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
  7981. [ALC262_HP_TC_T5735] = "hp-tc-t5735",
  7982. [ALC262_BENQ_ED8] = "benq",
  7983. [ALC262_BENQ_T31] = "benq-t31",
  7984. [ALC262_SONY_ASSAMD] = "sony-assamd",
  7985. [ALC262_ULTRA] = "ultra",
  7986. [ALC262_AUTO] = "auto",
  7987. };
  7988. static struct snd_pci_quirk alc262_cfg_tbl[] = {
  7989. SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
  7990. SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
  7991. SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
  7992. SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
  7993. SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
  7994. SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
  7995. SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
  7996. SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
  7997. SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
  7998. SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
  7999. SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8000. SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8001. SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8002. SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8003. SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8004. SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8005. SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8006. SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
  8007. SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
  8008. SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
  8009. SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
  8010. ALC262_HP_TC_T5735),
  8011. SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8012. SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
  8013. SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8014. SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8015. SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
  8016. SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
  8017. SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
  8018. SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
  8019. SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
  8020. SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
  8021. {}
  8022. };
  8023. static struct alc_config_preset alc262_presets[] = {
  8024. [ALC262_BASIC] = {
  8025. .mixers = { alc262_base_mixer },
  8026. .init_verbs = { alc262_init_verbs },
  8027. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8028. .dac_nids = alc262_dac_nids,
  8029. .hp_nid = 0x03,
  8030. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8031. .channel_mode = alc262_modes,
  8032. .input_mux = &alc262_capture_source,
  8033. },
  8034. [ALC262_HIPPO] = {
  8035. .mixers = { alc262_base_mixer },
  8036. .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
  8037. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8038. .dac_nids = alc262_dac_nids,
  8039. .hp_nid = 0x03,
  8040. .dig_out_nid = ALC262_DIGOUT_NID,
  8041. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8042. .channel_mode = alc262_modes,
  8043. .input_mux = &alc262_capture_source,
  8044. .unsol_event = alc262_hippo_unsol_event,
  8045. .init_hook = alc262_hippo_automute,
  8046. },
  8047. [ALC262_HIPPO_1] = {
  8048. .mixers = { alc262_hippo1_mixer },
  8049. .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
  8050. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8051. .dac_nids = alc262_dac_nids,
  8052. .hp_nid = 0x02,
  8053. .dig_out_nid = ALC262_DIGOUT_NID,
  8054. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8055. .channel_mode = alc262_modes,
  8056. .input_mux = &alc262_capture_source,
  8057. .unsol_event = alc262_hippo1_unsol_event,
  8058. .init_hook = alc262_hippo1_automute,
  8059. },
  8060. [ALC262_FUJITSU] = {
  8061. .mixers = { alc262_fujitsu_mixer },
  8062. .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
  8063. alc262_fujitsu_unsol_verbs },
  8064. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8065. .dac_nids = alc262_dac_nids,
  8066. .hp_nid = 0x03,
  8067. .dig_out_nid = ALC262_DIGOUT_NID,
  8068. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8069. .channel_mode = alc262_modes,
  8070. .input_mux = &alc262_fujitsu_capture_source,
  8071. .unsol_event = alc262_fujitsu_unsol_event,
  8072. },
  8073. [ALC262_HP_BPC] = {
  8074. .mixers = { alc262_HP_BPC_mixer },
  8075. .init_verbs = { alc262_HP_BPC_init_verbs },
  8076. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8077. .dac_nids = alc262_dac_nids,
  8078. .hp_nid = 0x03,
  8079. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8080. .channel_mode = alc262_modes,
  8081. .input_mux = &alc262_HP_capture_source,
  8082. },
  8083. [ALC262_HP_BPC_D7000_WF] = {
  8084. .mixers = { alc262_HP_BPC_WildWest_mixer },
  8085. .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
  8086. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8087. .dac_nids = alc262_dac_nids,
  8088. .hp_nid = 0x03,
  8089. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8090. .channel_mode = alc262_modes,
  8091. .input_mux = &alc262_HP_D7000_capture_source,
  8092. },
  8093. [ALC262_HP_BPC_D7000_WL] = {
  8094. .mixers = { alc262_HP_BPC_WildWest_mixer,
  8095. alc262_HP_BPC_WildWest_option_mixer },
  8096. .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
  8097. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8098. .dac_nids = alc262_dac_nids,
  8099. .hp_nid = 0x03,
  8100. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8101. .channel_mode = alc262_modes,
  8102. .input_mux = &alc262_HP_D7000_capture_source,
  8103. },
  8104. [ALC262_HP_TC_T5735] = {
  8105. .mixers = { alc262_hp_t5735_mixer },
  8106. .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
  8107. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8108. .dac_nids = alc262_dac_nids,
  8109. .hp_nid = 0x03,
  8110. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8111. .channel_mode = alc262_modes,
  8112. .input_mux = &alc262_capture_source,
  8113. .unsol_event = alc262_hp_t5735_unsol_event,
  8114. .init_hook = alc262_hp_t5735_init_hook,
  8115. },
  8116. [ALC262_BENQ_ED8] = {
  8117. .mixers = { alc262_base_mixer },
  8118. .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
  8119. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8120. .dac_nids = alc262_dac_nids,
  8121. .hp_nid = 0x03,
  8122. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8123. .channel_mode = alc262_modes,
  8124. .input_mux = &alc262_capture_source,
  8125. },
  8126. [ALC262_SONY_ASSAMD] = {
  8127. .mixers = { alc262_sony_mixer },
  8128. .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
  8129. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8130. .dac_nids = alc262_dac_nids,
  8131. .hp_nid = 0x02,
  8132. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8133. .channel_mode = alc262_modes,
  8134. .input_mux = &alc262_capture_source,
  8135. .unsol_event = alc262_hippo_unsol_event,
  8136. .init_hook = alc262_hippo_automute,
  8137. },
  8138. [ALC262_BENQ_T31] = {
  8139. .mixers = { alc262_benq_t31_mixer },
  8140. .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
  8141. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8142. .dac_nids = alc262_dac_nids,
  8143. .hp_nid = 0x03,
  8144. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8145. .channel_mode = alc262_modes,
  8146. .input_mux = &alc262_capture_source,
  8147. .unsol_event = alc262_hippo_unsol_event,
  8148. .init_hook = alc262_hippo_automute,
  8149. },
  8150. [ALC262_ULTRA] = {
  8151. .mixers = { alc262_ultra_mixer },
  8152. .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
  8153. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8154. .dac_nids = alc262_dac_nids,
  8155. .hp_nid = 0x03,
  8156. .dig_out_nid = ALC262_DIGOUT_NID,
  8157. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8158. .channel_mode = alc262_modes,
  8159. .input_mux = &alc262_ultra_capture_source,
  8160. .unsol_event = alc262_ultra_unsol_event,
  8161. .init_hook = alc262_ultra_automute,
  8162. },
  8163. };
  8164. static int patch_alc262(struct hda_codec *codec)
  8165. {
  8166. struct alc_spec *spec;
  8167. int board_config;
  8168. int err;
  8169. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  8170. if (spec == NULL)
  8171. return -ENOMEM;
  8172. codec->spec = spec;
  8173. #if 0
  8174. /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
  8175. * under-run
  8176. */
  8177. {
  8178. int tmp;
  8179. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
  8180. tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
  8181. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
  8182. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
  8183. }
  8184. #endif
  8185. board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
  8186. alc262_models,
  8187. alc262_cfg_tbl);
  8188. if (board_config < 0) {
  8189. printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
  8190. "trying auto-probe from BIOS...\n");
  8191. board_config = ALC262_AUTO;
  8192. }
  8193. if (board_config == ALC262_AUTO) {
  8194. /* automatic parse from the BIOS config */
  8195. err = alc262_parse_auto_config(codec);
  8196. if (err < 0) {
  8197. alc_free(codec);
  8198. return err;
  8199. } else if (!err) {
  8200. printk(KERN_INFO
  8201. "hda_codec: Cannot set up configuration "
  8202. "from BIOS. Using base mode...\n");
  8203. board_config = ALC262_BASIC;
  8204. }
  8205. }
  8206. if (board_config != ALC262_AUTO)
  8207. setup_preset(spec, &alc262_presets[board_config]);
  8208. spec->stream_name_analog = "ALC262 Analog";
  8209. spec->stream_analog_playback = &alc262_pcm_analog_playback;
  8210. spec->stream_analog_capture = &alc262_pcm_analog_capture;
  8211. spec->stream_name_digital = "ALC262 Digital";
  8212. spec->stream_digital_playback = &alc262_pcm_digital_playback;
  8213. spec->stream_digital_capture = &alc262_pcm_digital_capture;
  8214. if (!spec->adc_nids && spec->input_mux) {
  8215. /* check whether NID 0x07 is valid */
  8216. unsigned int wcap = get_wcaps(codec, 0x07);
  8217. /* get type */
  8218. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  8219. if (wcap != AC_WID_AUD_IN) {
  8220. spec->adc_nids = alc262_adc_nids_alt;
  8221. spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
  8222. spec->mixers[spec->num_mixers] =
  8223. alc262_capture_alt_mixer;
  8224. spec->num_mixers++;
  8225. } else {
  8226. spec->adc_nids = alc262_adc_nids;
  8227. spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
  8228. spec->mixers[spec->num_mixers] = alc262_capture_mixer;
  8229. spec->num_mixers++;
  8230. }
  8231. }
  8232. codec->patch_ops = alc_patch_ops;
  8233. if (board_config == ALC262_AUTO)
  8234. spec->init_hook = alc262_auto_init;
  8235. #ifdef CONFIG_SND_HDA_POWER_SAVE
  8236. if (!spec->loopback.amplist)
  8237. spec->loopback.amplist = alc262_loopbacks;
  8238. #endif
  8239. return 0;
  8240. }
  8241. /*
  8242. * ALC268 channel source setting (2 channel)
  8243. */
  8244. #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
  8245. #define alc268_modes alc260_modes
  8246. static hda_nid_t alc268_dac_nids[2] = {
  8247. /* front, hp */
  8248. 0x02, 0x03
  8249. };
  8250. static hda_nid_t alc268_adc_nids[2] = {
  8251. /* ADC0-1 */
  8252. 0x08, 0x07
  8253. };
  8254. static hda_nid_t alc268_adc_nids_alt[1] = {
  8255. /* ADC0 */
  8256. 0x08
  8257. };
  8258. static struct snd_kcontrol_new alc268_base_mixer[] = {
  8259. /* output mixer control */
  8260. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  8261. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  8262. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  8263. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  8264. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8265. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  8266. HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
  8267. { }
  8268. };
  8269. static struct hda_verb alc268_eapd_verbs[] = {
  8270. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8271. {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8272. { }
  8273. };
  8274. /* Toshiba specific */
  8275. #define alc268_toshiba_automute alc262_hippo_automute
  8276. static struct hda_verb alc268_toshiba_verbs[] = {
  8277. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8278. { } /* end */
  8279. };
  8280. /* Acer specific */
  8281. /* bind volumes of both NID 0x02 and 0x03 */
  8282. static struct hda_bind_ctls alc268_acer_bind_master_vol = {
  8283. .ops = &snd_hda_bind_vol,
  8284. .values = {
  8285. HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
  8286. HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
  8287. 0
  8288. },
  8289. };
  8290. /* mute/unmute internal speaker according to the hp jack and mute state */
  8291. static void alc268_acer_automute(struct hda_codec *codec, int force)
  8292. {
  8293. struct alc_spec *spec = codec->spec;
  8294. unsigned int mute;
  8295. if (force || !spec->sense_updated) {
  8296. unsigned int present;
  8297. present = snd_hda_codec_read(codec, 0x14, 0,
  8298. AC_VERB_GET_PIN_SENSE, 0);
  8299. spec->jack_present = (present & 0x80000000) != 0;
  8300. spec->sense_updated = 1;
  8301. }
  8302. if (spec->jack_present)
  8303. mute = HDA_AMP_MUTE; /* mute internal speaker */
  8304. else /* unmute internal speaker if necessary */
  8305. mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
  8306. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  8307. HDA_AMP_MUTE, mute);
  8308. }
  8309. /* bind hp and internal speaker mute (with plug check) */
  8310. static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
  8311. struct snd_ctl_elem_value *ucontrol)
  8312. {
  8313. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  8314. long *valp = ucontrol->value.integer.value;
  8315. int change;
  8316. change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
  8317. HDA_AMP_MUTE,
  8318. valp[0] ? 0 : HDA_AMP_MUTE);
  8319. change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
  8320. HDA_AMP_MUTE,
  8321. valp[1] ? 0 : HDA_AMP_MUTE);
  8322. if (change)
  8323. alc268_acer_automute(codec, 0);
  8324. return change;
  8325. }
  8326. static struct snd_kcontrol_new alc268_acer_mixer[] = {
  8327. /* output mixer control */
  8328. HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
  8329. {
  8330. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8331. .name = "Master Playback Switch",
  8332. .info = snd_hda_mixer_amp_switch_info,
  8333. .get = snd_hda_mixer_amp_switch_get,
  8334. .put = alc268_acer_master_sw_put,
  8335. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  8336. },
  8337. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8338. HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
  8339. HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
  8340. { }
  8341. };
  8342. static struct hda_verb alc268_acer_verbs[] = {
  8343. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8344. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  8345. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8346. { }
  8347. };
  8348. /* unsolicited event for HP jack sensing */
  8349. static void alc268_toshiba_unsol_event(struct hda_codec *codec,
  8350. unsigned int res)
  8351. {
  8352. if ((res >> 26) != ALC880_HP_EVENT)
  8353. return;
  8354. alc268_toshiba_automute(codec);
  8355. }
  8356. static void alc268_acer_unsol_event(struct hda_codec *codec,
  8357. unsigned int res)
  8358. {
  8359. if ((res >> 26) != ALC880_HP_EVENT)
  8360. return;
  8361. alc268_acer_automute(codec, 1);
  8362. }
  8363. static void alc268_acer_init_hook(struct hda_codec *codec)
  8364. {
  8365. alc268_acer_automute(codec, 1);
  8366. }
  8367. /*
  8368. * generic initialization of ADC, input mixers and output mixers
  8369. */
  8370. static struct hda_verb alc268_base_init_verbs[] = {
  8371. /* Unmute DAC0-1 and set vol = 0 */
  8372. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8373. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8374. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8375. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8376. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8377. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8378. /*
  8379. * Set up output mixers (0x0c - 0x0e)
  8380. */
  8381. /* set vol=0 to output mixers */
  8382. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8383. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8384. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8385. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
  8386. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8387. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8388. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  8389. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  8390. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  8391. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8392. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8393. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8394. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8395. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8396. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8397. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8398. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8399. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8400. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8401. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8402. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8403. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8404. /* Unmute Selector 23h,24h and set the default input to mic-in */
  8405. {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
  8406. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8407. {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
  8408. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8409. { }
  8410. };
  8411. /*
  8412. * generic initialization of ADC, input mixers and output mixers
  8413. */
  8414. static struct hda_verb alc268_volume_init_verbs[] = {
  8415. /* set output DAC */
  8416. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8417. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8418. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8419. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8420. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8421. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8422. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8423. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8424. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8425. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8426. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8427. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8428. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8429. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8430. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8431. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8432. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8433. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8434. /* set PCBEEP vol = 0 */
  8435. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
  8436. { }
  8437. };
  8438. #define alc268_mux_enum_info alc_mux_enum_info
  8439. #define alc268_mux_enum_get alc_mux_enum_get
  8440. static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
  8441. struct snd_ctl_elem_value *ucontrol)
  8442. {
  8443. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  8444. struct alc_spec *spec = codec->spec;
  8445. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  8446. static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
  8447. hda_nid_t nid = capture_mixers[adc_idx];
  8448. return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
  8449. nid,
  8450. &spec->cur_mux[adc_idx]);
  8451. }
  8452. static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
  8453. HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8454. HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
  8455. {
  8456. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8457. /* The multiple "Capture Source" controls confuse alsamixer
  8458. * So call somewhat different..
  8459. * FIXME: the controls appear in the "playback" view!
  8460. */
  8461. /* .name = "Capture Source", */
  8462. .name = "Input Source",
  8463. .count = 1,
  8464. .info = alc268_mux_enum_info,
  8465. .get = alc268_mux_enum_get,
  8466. .put = alc268_mux_enum_put,
  8467. },
  8468. { } /* end */
  8469. };
  8470. static struct snd_kcontrol_new alc268_capture_mixer[] = {
  8471. HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8472. HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
  8473. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
  8474. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
  8475. {
  8476. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8477. /* The multiple "Capture Source" controls confuse alsamixer
  8478. * So call somewhat different..
  8479. * FIXME: the controls appear in the "playback" view!
  8480. */
  8481. /* .name = "Capture Source", */
  8482. .name = "Input Source",
  8483. .count = 2,
  8484. .info = alc268_mux_enum_info,
  8485. .get = alc268_mux_enum_get,
  8486. .put = alc268_mux_enum_put,
  8487. },
  8488. { } /* end */
  8489. };
  8490. static struct hda_input_mux alc268_capture_source = {
  8491. .num_items = 4,
  8492. .items = {
  8493. { "Mic", 0x0 },
  8494. { "Front Mic", 0x1 },
  8495. { "Line", 0x2 },
  8496. { "CD", 0x3 },
  8497. },
  8498. };
  8499. #ifdef CONFIG_SND_DEBUG
  8500. static struct snd_kcontrol_new alc268_test_mixer[] = {
  8501. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  8502. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  8503. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  8504. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  8505. /* Volume widgets */
  8506. HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  8507. HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  8508. HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  8509. HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
  8510. HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
  8511. HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
  8512. HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
  8513. HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
  8514. HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
  8515. HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
  8516. HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
  8517. HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
  8518. HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
  8519. HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),
  8520. HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8521. HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
  8522. HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
  8523. HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
  8524. /* Modes for retasking pin widgets */
  8525. ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
  8526. ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
  8527. ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
  8528. ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
  8529. /* Controls for GPIO pins, assuming they are configured as outputs */
  8530. ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
  8531. ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
  8532. ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
  8533. ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
  8534. /* Switches to allow the digital SPDIF output pin to be enabled.
  8535. * The ALC268 does not have an SPDIF input.
  8536. */
  8537. ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
  8538. /* A switch allowing EAPD to be enabled. Some laptops seem to use
  8539. * this output to turn on an external amplifier.
  8540. */
  8541. ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
  8542. ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
  8543. { } /* end */
  8544. };
  8545. #endif
  8546. /* create input playback/capture controls for the given pin */
  8547. static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
  8548. const char *ctlname, int idx)
  8549. {
  8550. char name[32];
  8551. int err;
  8552. sprintf(name, "%s Playback Volume", ctlname);
  8553. if (nid == 0x14) {
  8554. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  8555. HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
  8556. HDA_OUTPUT));
  8557. if (err < 0)
  8558. return err;
  8559. } else if (nid == 0x15) {
  8560. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  8561. HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
  8562. HDA_OUTPUT));
  8563. if (err < 0)
  8564. return err;
  8565. } else
  8566. return -1;
  8567. sprintf(name, "%s Playback Switch", ctlname);
  8568. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  8569. HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
  8570. if (err < 0)
  8571. return err;
  8572. return 0;
  8573. }
  8574. /* add playback controls from the parsed DAC table */
  8575. static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
  8576. const struct auto_pin_cfg *cfg)
  8577. {
  8578. hda_nid_t nid;
  8579. int err;
  8580. spec->multiout.num_dacs = 2; /* only use one dac */
  8581. spec->multiout.dac_nids = spec->private_dac_nids;
  8582. spec->multiout.dac_nids[0] = 2;
  8583. spec->multiout.dac_nids[1] = 3;
  8584. nid = cfg->line_out_pins[0];
  8585. if (nid)
  8586. alc268_new_analog_output(spec, nid, "Front", 0);
  8587. nid = cfg->speaker_pins[0];
  8588. if (nid == 0x1d) {
  8589. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  8590. "Speaker Playback Volume",
  8591. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  8592. if (err < 0)
  8593. return err;
  8594. }
  8595. nid = cfg->hp_pins[0];
  8596. if (nid)
  8597. alc268_new_analog_output(spec, nid, "Headphone", 0);
  8598. nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
  8599. if (nid == 0x16) {
  8600. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  8601. "Mono Playback Switch",
  8602. HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
  8603. if (err < 0)
  8604. return err;
  8605. }
  8606. return 0;
  8607. }
  8608. /* create playback/capture controls for input pins */
  8609. static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
  8610. const struct auto_pin_cfg *cfg)
  8611. {
  8612. struct hda_input_mux *imux = &spec->private_imux;
  8613. int i, idx1;
  8614. for (i = 0; i < AUTO_PIN_LAST; i++) {
  8615. switch(cfg->input_pins[i]) {
  8616. case 0x18:
  8617. idx1 = 0; /* Mic 1 */
  8618. break;
  8619. case 0x19:
  8620. idx1 = 1; /* Mic 2 */
  8621. break;
  8622. case 0x1a:
  8623. idx1 = 2; /* Line In */
  8624. break;
  8625. case 0x1c:
  8626. idx1 = 3; /* CD */
  8627. break;
  8628. default:
  8629. continue;
  8630. }
  8631. imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
  8632. imux->items[imux->num_items].index = idx1;
  8633. imux->num_items++;
  8634. }
  8635. return 0;
  8636. }
  8637. static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
  8638. {
  8639. struct alc_spec *spec = codec->spec;
  8640. hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
  8641. hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
  8642. hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
  8643. unsigned int dac_vol1, dac_vol2;
  8644. if (speaker_nid) {
  8645. snd_hda_codec_write(codec, speaker_nid, 0,
  8646. AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
  8647. snd_hda_codec_write(codec, 0x0f, 0,
  8648. AC_VERB_SET_AMP_GAIN_MUTE,
  8649. AMP_IN_UNMUTE(1));
  8650. snd_hda_codec_write(codec, 0x10, 0,
  8651. AC_VERB_SET_AMP_GAIN_MUTE,
  8652. AMP_IN_UNMUTE(1));
  8653. } else {
  8654. snd_hda_codec_write(codec, 0x0f, 0,
  8655. AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
  8656. snd_hda_codec_write(codec, 0x10, 0,
  8657. AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
  8658. }
  8659. dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
  8660. if (line_nid == 0x14)
  8661. dac_vol2 = AMP_OUT_ZERO;
  8662. else if (line_nid == 0x15)
  8663. dac_vol1 = AMP_OUT_ZERO;
  8664. if (hp_nid == 0x14)
  8665. dac_vol2 = AMP_OUT_ZERO;
  8666. else if (hp_nid == 0x15)
  8667. dac_vol1 = AMP_OUT_ZERO;
  8668. if (line_nid != 0x16 || hp_nid != 0x16 ||
  8669. spec->autocfg.line_out_pins[1] != 0x16 ||
  8670. spec->autocfg.line_out_pins[2] != 0x16)
  8671. dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
  8672. snd_hda_codec_write(codec, 0x02, 0,
  8673. AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
  8674. snd_hda_codec_write(codec, 0x03, 0,
  8675. AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
  8676. }
  8677. /* pcm configuration: identiacal with ALC880 */
  8678. #define alc268_pcm_analog_playback alc880_pcm_analog_playback
  8679. #define alc268_pcm_analog_capture alc880_pcm_analog_capture
  8680. #define alc268_pcm_digital_playback alc880_pcm_digital_playback
  8681. /*
  8682. * BIOS auto configuration
  8683. */
  8684. static int alc268_parse_auto_config(struct hda_codec *codec)
  8685. {
  8686. struct alc_spec *spec = codec->spec;
  8687. int err;
  8688. static hda_nid_t alc268_ignore[] = { 0 };
  8689. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  8690. alc268_ignore);
  8691. if (err < 0)
  8692. return err;
  8693. if (!spec->autocfg.line_outs)
  8694. return 0; /* can't find valid BIOS pin config */
  8695. err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
  8696. if (err < 0)
  8697. return err;
  8698. err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
  8699. if (err < 0)
  8700. return err;
  8701. spec->multiout.max_channels = 2;
  8702. /* digital only support output */
  8703. if (spec->autocfg.dig_out_pin)
  8704. spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
  8705. if (spec->kctl_alloc)
  8706. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  8707. spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
  8708. spec->num_mux_defs = 1;
  8709. spec->input_mux = &spec->private_imux;
  8710. err = alc_auto_add_mic_boost(codec);
  8711. if (err < 0)
  8712. return err;
  8713. return 1;
  8714. }
  8715. #define alc268_auto_init_multi_out alc882_auto_init_multi_out
  8716. #define alc268_auto_init_hp_out alc882_auto_init_hp_out
  8717. #define alc268_auto_init_analog_input alc882_auto_init_analog_input
  8718. /* init callback for auto-configuration model -- overriding the default init */
  8719. static void alc268_auto_init(struct hda_codec *codec)
  8720. {
  8721. alc268_auto_init_multi_out(codec);
  8722. alc268_auto_init_hp_out(codec);
  8723. alc268_auto_init_mono_speaker_out(codec);
  8724. alc268_auto_init_analog_input(codec);
  8725. }
  8726. /*
  8727. * configuration and preset
  8728. */
  8729. static const char *alc268_models[ALC268_MODEL_LAST] = {
  8730. [ALC268_3ST] = "3stack",
  8731. [ALC268_TOSHIBA] = "toshiba",
  8732. [ALC268_ACER] = "acer",
  8733. #ifdef CONFIG_SND_DEBUG
  8734. [ALC268_TEST] = "test",
  8735. #endif
  8736. [ALC268_AUTO] = "auto",
  8737. };
  8738. static struct snd_pci_quirk alc268_cfg_tbl[] = {
  8739. SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
  8740. SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
  8741. SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
  8742. SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
  8743. SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
  8744. SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
  8745. SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
  8746. {}
  8747. };
  8748. static struct alc_config_preset alc268_presets[] = {
  8749. [ALC268_3ST] = {
  8750. .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
  8751. .init_verbs = { alc268_base_init_verbs },
  8752. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  8753. .dac_nids = alc268_dac_nids,
  8754. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  8755. .adc_nids = alc268_adc_nids_alt,
  8756. .hp_nid = 0x03,
  8757. .dig_out_nid = ALC268_DIGOUT_NID,
  8758. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  8759. .channel_mode = alc268_modes,
  8760. .input_mux = &alc268_capture_source,
  8761. },
  8762. [ALC268_TOSHIBA] = {
  8763. .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
  8764. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  8765. alc268_toshiba_verbs },
  8766. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  8767. .dac_nids = alc268_dac_nids,
  8768. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  8769. .adc_nids = alc268_adc_nids_alt,
  8770. .hp_nid = 0x03,
  8771. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  8772. .channel_mode = alc268_modes,
  8773. .input_mux = &alc268_capture_source,
  8774. .unsol_event = alc268_toshiba_unsol_event,
  8775. .init_hook = alc268_toshiba_automute,
  8776. },
  8777. [ALC268_ACER] = {
  8778. .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
  8779. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  8780. alc268_acer_verbs },
  8781. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  8782. .dac_nids = alc268_dac_nids,
  8783. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  8784. .adc_nids = alc268_adc_nids_alt,
  8785. .hp_nid = 0x02,
  8786. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  8787. .channel_mode = alc268_modes,
  8788. .input_mux = &alc268_capture_source,
  8789. .unsol_event = alc268_acer_unsol_event,
  8790. .init_hook = alc268_acer_init_hook,
  8791. },
  8792. #ifdef CONFIG_SND_DEBUG
  8793. [ALC268_TEST] = {
  8794. .mixers = { alc268_test_mixer, alc268_capture_mixer },
  8795. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  8796. alc268_volume_init_verbs },
  8797. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  8798. .dac_nids = alc268_dac_nids,
  8799. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  8800. .adc_nids = alc268_adc_nids_alt,
  8801. .hp_nid = 0x03,
  8802. .dig_out_nid = ALC268_DIGOUT_NID,
  8803. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  8804. .channel_mode = alc268_modes,
  8805. .input_mux = &alc268_capture_source,
  8806. },
  8807. #endif
  8808. };
  8809. static int patch_alc268(struct hda_codec *codec)
  8810. {
  8811. struct alc_spec *spec;
  8812. int board_config;
  8813. int err;
  8814. spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
  8815. if (spec == NULL)
  8816. return -ENOMEM;
  8817. codec->spec = spec;
  8818. board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
  8819. alc268_models,
  8820. alc268_cfg_tbl);
  8821. if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
  8822. printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
  8823. "trying auto-probe from BIOS...\n");
  8824. board_config = ALC268_AUTO;
  8825. }
  8826. if (board_config == ALC268_AUTO) {
  8827. /* automatic parse from the BIOS config */
  8828. err = alc268_parse_auto_config(codec);
  8829. if (err < 0) {
  8830. alc_free(codec);
  8831. return err;
  8832. } else if (!err) {
  8833. printk(KERN_INFO
  8834. "hda_codec: Cannot set up configuration "
  8835. "from BIOS. Using base mode...\n");
  8836. board_config = ALC268_3ST;
  8837. }
  8838. }
  8839. if (board_config != ALC268_AUTO)
  8840. setup_preset(spec, &alc268_presets[board_config]);
  8841. spec->stream_name_analog = "ALC268 Analog";
  8842. spec->stream_analog_playback = &alc268_pcm_analog_playback;
  8843. spec->stream_analog_capture = &alc268_pcm_analog_capture;
  8844. spec->stream_name_digital = "ALC268 Digital";
  8845. spec->stream_digital_playback = &alc268_pcm_digital_playback;
  8846. if (board_config == ALC268_AUTO) {
  8847. if (!spec->adc_nids && spec->input_mux) {
  8848. /* check whether NID 0x07 is valid */
  8849. unsigned int wcap = get_wcaps(codec, 0x07);
  8850. /* get type */
  8851. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  8852. if (wcap != AC_WID_AUD_IN) {
  8853. spec->adc_nids = alc268_adc_nids_alt;
  8854. spec->num_adc_nids =
  8855. ARRAY_SIZE(alc268_adc_nids_alt);
  8856. spec->mixers[spec->num_mixers] =
  8857. alc268_capture_alt_mixer;
  8858. spec->num_mixers++;
  8859. } else {
  8860. spec->adc_nids = alc268_adc_nids;
  8861. spec->num_adc_nids =
  8862. ARRAY_SIZE(alc268_adc_nids);
  8863. spec->mixers[spec->num_mixers] =
  8864. alc268_capture_mixer;
  8865. spec->num_mixers++;
  8866. }
  8867. }
  8868. }
  8869. codec->patch_ops = alc_patch_ops;
  8870. if (board_config == ALC268_AUTO)
  8871. spec->init_hook = alc268_auto_init;
  8872. return 0;
  8873. }
  8874. /*
  8875. * ALC269 channel source setting (2 channel)
  8876. */
  8877. #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
  8878. #define alc269_dac_nids alc260_dac_nids
  8879. static hda_nid_t alc269_adc_nids[1] = {
  8880. /* ADC1 */
  8881. 0x07,
  8882. };
  8883. #define alc269_modes alc260_modes
  8884. #define alc269_capture_source alc880_lg_lw_capture_source
  8885. static struct snd_kcontrol_new alc269_base_mixer[] = {
  8886. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  8887. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  8888. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  8889. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  8890. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  8891. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  8892. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8893. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  8894. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  8895. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  8896. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  8897. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  8898. { } /* end */
  8899. };
  8900. /* capture mixer elements */
  8901. static struct snd_kcontrol_new alc269_capture_mixer[] = {
  8902. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  8903. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  8904. {
  8905. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8906. /* The multiple "Capture Source" controls confuse alsamixer
  8907. * So call somewhat different..
  8908. * FIXME: the controls appear in the "playback" view!
  8909. */
  8910. /* .name = "Capture Source", */
  8911. .name = "Input Source",
  8912. .count = 1,
  8913. .info = alc_mux_enum_info,
  8914. .get = alc_mux_enum_get,
  8915. .put = alc_mux_enum_put,
  8916. },
  8917. { } /* end */
  8918. };
  8919. /*
  8920. * generic initialization of ADC, input mixers and output mixers
  8921. */
  8922. static struct hda_verb alc269_init_verbs[] = {
  8923. /*
  8924. * Unmute ADC0 and set the default input to mic-in
  8925. */
  8926. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8927. /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
  8928. * analog-loopback mixer widget
  8929. * Note: PASD motherboards uses the Line In 2 as the input for
  8930. * front panel mic (mic 2)
  8931. */
  8932. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  8933. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  8934. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  8935. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  8936. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  8937. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  8938. /*
  8939. * Set up output mixers (0x0c - 0x0e)
  8940. */
  8941. /* set vol=0 to output mixers */
  8942. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8943. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8944. /* set up input amps for analog loopback */
  8945. /* Amp Indices: DAC = 0, mixer = 1 */
  8946. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8947. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8948. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8949. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8950. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8951. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8952. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  8953. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8954. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  8955. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  8956. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  8957. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  8958. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  8959. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8960. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8961. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8962. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8963. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8964. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8965. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8966. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  8967. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  8968. /* FIXME: use matrix-type input source selection */
  8969. /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
  8970. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  8971. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8972. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  8973. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  8974. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  8975. /* set EAPD */
  8976. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8977. {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8978. { }
  8979. };
  8980. /* add playback controls from the parsed DAC table */
  8981. static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
  8982. const struct auto_pin_cfg *cfg)
  8983. {
  8984. hda_nid_t nid;
  8985. int err;
  8986. spec->multiout.num_dacs = 1; /* only use one dac */
  8987. spec->multiout.dac_nids = spec->private_dac_nids;
  8988. spec->multiout.dac_nids[0] = 2;
  8989. nid = cfg->line_out_pins[0];
  8990. if (nid) {
  8991. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  8992. "Front Playback Volume",
  8993. HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
  8994. if (err < 0)
  8995. return err;
  8996. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  8997. "Front Playback Switch",
  8998. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  8999. if (err < 0)
  9000. return err;
  9001. }
  9002. nid = cfg->speaker_pins[0];
  9003. if (nid) {
  9004. if (!cfg->line_out_pins[0]) {
  9005. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  9006. "Speaker Playback Volume",
  9007. HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
  9008. HDA_OUTPUT));
  9009. if (err < 0)
  9010. return err;
  9011. }
  9012. if (nid == 0x16) {
  9013. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9014. "Speaker Playback Switch",
  9015. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  9016. HDA_OUTPUT));
  9017. if (err < 0)
  9018. return err;
  9019. } else {
  9020. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9021. "Speaker Playback Switch",
  9022. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  9023. HDA_OUTPUT));
  9024. if (err < 0)
  9025. return err;
  9026. }
  9027. }
  9028. nid = cfg->hp_pins[0];
  9029. if (nid) {
  9030. /* spec->multiout.hp_nid = 2; */
  9031. if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
  9032. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  9033. "Headphone Playback Volume",
  9034. HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
  9035. HDA_OUTPUT));
  9036. if (err < 0)
  9037. return err;
  9038. }
  9039. if (nid == 0x16) {
  9040. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9041. "Headphone Playback Switch",
  9042. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  9043. HDA_OUTPUT));
  9044. if (err < 0)
  9045. return err;
  9046. } else {
  9047. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9048. "Headphone Playback Switch",
  9049. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  9050. HDA_OUTPUT));
  9051. if (err < 0)
  9052. return err;
  9053. }
  9054. }
  9055. return 0;
  9056. }
  9057. #define alc269_auto_create_analog_input_ctls \
  9058. alc880_auto_create_analog_input_ctls
  9059. #ifdef CONFIG_SND_HDA_POWER_SAVE
  9060. #define alc269_loopbacks alc880_loopbacks
  9061. #endif
  9062. /* pcm configuration: identiacal with ALC880 */
  9063. #define alc269_pcm_analog_playback alc880_pcm_analog_playback
  9064. #define alc269_pcm_analog_capture alc880_pcm_analog_capture
  9065. #define alc269_pcm_digital_playback alc880_pcm_digital_playback
  9066. #define alc269_pcm_digital_capture alc880_pcm_digital_capture
  9067. /*
  9068. * BIOS auto configuration
  9069. */
  9070. static int alc269_parse_auto_config(struct hda_codec *codec)
  9071. {
  9072. struct alc_spec *spec = codec->spec;
  9073. int err;
  9074. static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
  9075. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  9076. alc269_ignore);
  9077. if (err < 0)
  9078. return err;
  9079. err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
  9080. if (err < 0)
  9081. return err;
  9082. err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
  9083. if (err < 0)
  9084. return err;
  9085. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  9086. if (spec->autocfg.dig_out_pin)
  9087. spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
  9088. if (spec->kctl_alloc)
  9089. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  9090. spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
  9091. spec->num_mux_defs = 1;
  9092. spec->input_mux = &spec->private_imux;
  9093. err = alc_auto_add_mic_boost(codec);
  9094. if (err < 0)
  9095. return err;
  9096. return 1;
  9097. }
  9098. #define alc269_auto_init_multi_out alc882_auto_init_multi_out
  9099. #define alc269_auto_init_hp_out alc882_auto_init_hp_out
  9100. #define alc269_auto_init_analog_input alc882_auto_init_analog_input
  9101. /* init callback for auto-configuration model -- overriding the default init */
  9102. static void alc269_auto_init(struct hda_codec *codec)
  9103. {
  9104. alc269_auto_init_multi_out(codec);
  9105. alc269_auto_init_hp_out(codec);
  9106. alc269_auto_init_analog_input(codec);
  9107. }
  9108. /*
  9109. * configuration and preset
  9110. */
  9111. static const char *alc269_models[ALC269_MODEL_LAST] = {
  9112. [ALC269_BASIC] = "basic",
  9113. };
  9114. static struct snd_pci_quirk alc269_cfg_tbl[] = {
  9115. {}
  9116. };
  9117. static struct alc_config_preset alc269_presets[] = {
  9118. [ALC269_BASIC] = {
  9119. .mixers = { alc269_base_mixer },
  9120. .init_verbs = { alc269_init_verbs },
  9121. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  9122. .dac_nids = alc269_dac_nids,
  9123. .hp_nid = 0x03,
  9124. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  9125. .channel_mode = alc269_modes,
  9126. .input_mux = &alc269_capture_source,
  9127. },
  9128. };
  9129. static int patch_alc269(struct hda_codec *codec)
  9130. {
  9131. struct alc_spec *spec;
  9132. int board_config;
  9133. int err;
  9134. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  9135. if (spec == NULL)
  9136. return -ENOMEM;
  9137. codec->spec = spec;
  9138. board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
  9139. alc269_models,
  9140. alc269_cfg_tbl);
  9141. if (board_config < 0) {
  9142. printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
  9143. "trying auto-probe from BIOS...\n");
  9144. board_config = ALC269_AUTO;
  9145. }
  9146. if (board_config == ALC269_AUTO) {
  9147. /* automatic parse from the BIOS config */
  9148. err = alc269_parse_auto_config(codec);
  9149. if (err < 0) {
  9150. alc_free(codec);
  9151. return err;
  9152. } else if (!err) {
  9153. printk(KERN_INFO
  9154. "hda_codec: Cannot set up configuration "
  9155. "from BIOS. Using base mode...\n");
  9156. board_config = ALC269_BASIC;
  9157. }
  9158. }
  9159. if (board_config != ALC269_AUTO)
  9160. setup_preset(spec, &alc269_presets[board_config]);
  9161. spec->stream_name_analog = "ALC269 Analog";
  9162. spec->stream_analog_playback = &alc269_pcm_analog_playback;
  9163. spec->stream_analog_capture = &alc269_pcm_analog_capture;
  9164. spec->stream_name_digital = "ALC269 Digital";
  9165. spec->stream_digital_playback = &alc269_pcm_digital_playback;
  9166. spec->stream_digital_capture = &alc269_pcm_digital_capture;
  9167. spec->adc_nids = alc269_adc_nids;
  9168. spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
  9169. spec->mixers[spec->num_mixers] = alc269_capture_mixer;
  9170. spec->num_mixers++;
  9171. codec->patch_ops = alc_patch_ops;
  9172. if (board_config == ALC269_AUTO)
  9173. spec->init_hook = alc269_auto_init;
  9174. #ifdef CONFIG_SND_HDA_POWER_SAVE
  9175. if (!spec->loopback.amplist)
  9176. spec->loopback.amplist = alc269_loopbacks;
  9177. #endif
  9178. return 0;
  9179. }
  9180. /*
  9181. * ALC861 channel source setting (2/6 channel selection for 3-stack)
  9182. */
  9183. /*
  9184. * set the path ways for 2 channel output
  9185. * need to set the codec line out and mic 1 pin widgets to inputs
  9186. */
  9187. static struct hda_verb alc861_threestack_ch2_init[] = {
  9188. /* set pin widget 1Ah (line in) for input */
  9189. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9190. /* set pin widget 18h (mic1/2) for input, for mic also enable
  9191. * the vref
  9192. */
  9193. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9194. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
  9195. #if 0
  9196. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9197. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
  9198. #endif
  9199. { } /* end */
  9200. };
  9201. /*
  9202. * 6ch mode
  9203. * need to set the codec line out and mic 1 pin widgets to outputs
  9204. */
  9205. static struct hda_verb alc861_threestack_ch6_init[] = {
  9206. /* set pin widget 1Ah (line in) for output (Back Surround)*/
  9207. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9208. /* set pin widget 18h (mic1) for output (CLFE)*/
  9209. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9210. { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9211. { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9212. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
  9213. #if 0
  9214. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9215. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
  9216. #endif
  9217. { } /* end */
  9218. };
  9219. static struct hda_channel_mode alc861_threestack_modes[2] = {
  9220. { 2, alc861_threestack_ch2_init },
  9221. { 6, alc861_threestack_ch6_init },
  9222. };
  9223. /* Set mic1 as input and unmute the mixer */
  9224. static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
  9225. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9226. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9227. { } /* end */
  9228. };
  9229. /* Set mic1 as output and mute mixer */
  9230. static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
  9231. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9232. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9233. { } /* end */
  9234. };
  9235. static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
  9236. { 2, alc861_uniwill_m31_ch2_init },
  9237. { 4, alc861_uniwill_m31_ch4_init },
  9238. };
  9239. /* Set mic1 and line-in as input and unmute the mixer */
  9240. static struct hda_verb alc861_asus_ch2_init[] = {
  9241. /* set pin widget 1Ah (line in) for input */
  9242. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9243. /* set pin widget 18h (mic1/2) for input, for mic also enable
  9244. * the vref
  9245. */
  9246. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9247. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
  9248. #if 0
  9249. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9250. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
  9251. #endif
  9252. { } /* end */
  9253. };
  9254. /* Set mic1 nad line-in as output and mute mixer */
  9255. static struct hda_verb alc861_asus_ch6_init[] = {
  9256. /* set pin widget 1Ah (line in) for output (Back Surround)*/
  9257. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9258. /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
  9259. /* set pin widget 18h (mic1) for output (CLFE)*/
  9260. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9261. /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
  9262. { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9263. { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9264. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
  9265. #if 0
  9266. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9267. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
  9268. #endif
  9269. { } /* end */
  9270. };
  9271. static struct hda_channel_mode alc861_asus_modes[2] = {
  9272. { 2, alc861_asus_ch2_init },
  9273. { 6, alc861_asus_ch6_init },
  9274. };
  9275. /* patch-ALC861 */
  9276. static struct snd_kcontrol_new alc861_base_mixer[] = {
  9277. /* output mixer control */
  9278. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9279. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9280. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9281. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9282. HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
  9283. /*Input mixer control */
  9284. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9285. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9286. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9287. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9288. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9289. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9290. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9291. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9292. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9293. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9294. /* Capture mixer control */
  9295. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9296. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9297. {
  9298. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9299. .name = "Capture Source",
  9300. .count = 1,
  9301. .info = alc_mux_enum_info,
  9302. .get = alc_mux_enum_get,
  9303. .put = alc_mux_enum_put,
  9304. },
  9305. { } /* end */
  9306. };
  9307. static struct snd_kcontrol_new alc861_3ST_mixer[] = {
  9308. /* output mixer control */
  9309. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9310. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9311. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9312. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9313. /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
  9314. /* Input mixer control */
  9315. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9316. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9317. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9318. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9319. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9320. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9321. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9322. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9323. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9324. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9325. /* Capture mixer control */
  9326. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9327. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9328. {
  9329. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9330. .name = "Capture Source",
  9331. .count = 1,
  9332. .info = alc_mux_enum_info,
  9333. .get = alc_mux_enum_get,
  9334. .put = alc_mux_enum_put,
  9335. },
  9336. {
  9337. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9338. .name = "Channel Mode",
  9339. .info = alc_ch_mode_info,
  9340. .get = alc_ch_mode_get,
  9341. .put = alc_ch_mode_put,
  9342. .private_value = ARRAY_SIZE(alc861_threestack_modes),
  9343. },
  9344. { } /* end */
  9345. };
  9346. static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
  9347. /* output mixer control */
  9348. HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9349. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9350. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9351. /*Capture mixer control */
  9352. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9353. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9354. {
  9355. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9356. .name = "Capture Source",
  9357. .count = 1,
  9358. .info = alc_mux_enum_info,
  9359. .get = alc_mux_enum_get,
  9360. .put = alc_mux_enum_put,
  9361. },
  9362. { } /* end */
  9363. };
  9364. static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
  9365. /* output mixer control */
  9366. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9367. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9368. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9369. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9370. /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
  9371. /* Input mixer control */
  9372. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9373. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9374. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9375. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9376. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9377. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9378. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9379. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9380. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9381. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9382. /* Capture mixer control */
  9383. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9384. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9385. {
  9386. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9387. .name = "Capture Source",
  9388. .count = 1,
  9389. .info = alc_mux_enum_info,
  9390. .get = alc_mux_enum_get,
  9391. .put = alc_mux_enum_put,
  9392. },
  9393. {
  9394. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9395. .name = "Channel Mode",
  9396. .info = alc_ch_mode_info,
  9397. .get = alc_ch_mode_get,
  9398. .put = alc_ch_mode_put,
  9399. .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
  9400. },
  9401. { } /* end */
  9402. };
  9403. static struct snd_kcontrol_new alc861_asus_mixer[] = {
  9404. /* output mixer control */
  9405. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9406. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9407. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9408. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9409. HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
  9410. /* Input mixer control */
  9411. HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9412. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  9413. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9414. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9415. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9416. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9417. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9418. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9419. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9420. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
  9421. /* Capture mixer control */
  9422. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9423. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9424. {
  9425. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9426. .name = "Capture Source",
  9427. .count = 1,
  9428. .info = alc_mux_enum_info,
  9429. .get = alc_mux_enum_get,
  9430. .put = alc_mux_enum_put,
  9431. },
  9432. {
  9433. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9434. .name = "Channel Mode",
  9435. .info = alc_ch_mode_info,
  9436. .get = alc_ch_mode_get,
  9437. .put = alc_ch_mode_put,
  9438. .private_value = ARRAY_SIZE(alc861_asus_modes),
  9439. },
  9440. { }
  9441. };
  9442. /* additional mixer */
  9443. static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
  9444. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9445. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9446. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
  9447. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
  9448. { }
  9449. };
  9450. /*
  9451. * generic initialization of ADC, input mixers and output mixers
  9452. */
  9453. static struct hda_verb alc861_base_init_verbs[] = {
  9454. /*
  9455. * Unmute ADC0 and set the default input to mic-in
  9456. */
  9457. /* port-A for surround (rear panel) */
  9458. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9459. { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9460. /* port-B for mic-in (rear panel) with vref */
  9461. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9462. /* port-C for line-in (rear panel) */
  9463. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9464. /* port-D for Front */
  9465. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9466. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9467. /* port-E for HP out (front panel) */
  9468. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  9469. /* route front PCM to HP */
  9470. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9471. /* port-F for mic-in (front panel) with vref */
  9472. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9473. /* port-G for CLFE (rear panel) */
  9474. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9475. { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9476. /* port-H for side (rear panel) */
  9477. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9478. { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9479. /* CD-in */
  9480. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9481. /* route front mic to ADC1*/
  9482. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9483. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9484. /* Unmute DAC0~3 & spdif out*/
  9485. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9486. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9487. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9488. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9489. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9490. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9491. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9492. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9493. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9494. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9495. /* Unmute Stereo Mixer 15 */
  9496. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9497. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9498. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9499. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9500. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9501. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9502. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9503. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9504. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9505. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9506. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9507. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9508. /* hp used DAC 3 (Front) */
  9509. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9510. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9511. { }
  9512. };
  9513. static struct hda_verb alc861_threestack_init_verbs[] = {
  9514. /*
  9515. * Unmute ADC0 and set the default input to mic-in
  9516. */
  9517. /* port-A for surround (rear panel) */
  9518. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9519. /* port-B for mic-in (rear panel) with vref */
  9520. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9521. /* port-C for line-in (rear panel) */
  9522. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9523. /* port-D for Front */
  9524. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9525. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9526. /* port-E for HP out (front panel) */
  9527. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  9528. /* route front PCM to HP */
  9529. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9530. /* port-F for mic-in (front panel) with vref */
  9531. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9532. /* port-G for CLFE (rear panel) */
  9533. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9534. /* port-H for side (rear panel) */
  9535. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9536. /* CD-in */
  9537. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9538. /* route front mic to ADC1*/
  9539. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9540. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9541. /* Unmute DAC0~3 & spdif out*/
  9542. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9543. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9544. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9545. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9546. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9547. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9548. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9549. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9550. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9551. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9552. /* Unmute Stereo Mixer 15 */
  9553. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9554. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9555. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9556. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9557. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9558. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9559. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9560. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9561. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9562. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9563. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9564. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9565. /* hp used DAC 3 (Front) */
  9566. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9567. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9568. { }
  9569. };
  9570. static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
  9571. /*
  9572. * Unmute ADC0 and set the default input to mic-in
  9573. */
  9574. /* port-A for surround (rear panel) */
  9575. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9576. /* port-B for mic-in (rear panel) with vref */
  9577. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9578. /* port-C for line-in (rear panel) */
  9579. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9580. /* port-D for Front */
  9581. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9582. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9583. /* port-E for HP out (front panel) */
  9584. /* this has to be set to VREF80 */
  9585. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9586. /* route front PCM to HP */
  9587. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9588. /* port-F for mic-in (front panel) with vref */
  9589. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9590. /* port-G for CLFE (rear panel) */
  9591. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9592. /* port-H for side (rear panel) */
  9593. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9594. /* CD-in */
  9595. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9596. /* route front mic to ADC1*/
  9597. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9598. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9599. /* Unmute DAC0~3 & spdif out*/
  9600. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9601. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9602. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9603. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9604. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9605. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9606. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9607. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9608. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9609. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9610. /* Unmute Stereo Mixer 15 */
  9611. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9612. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9613. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9614. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9615. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9616. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9617. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9618. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9619. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9620. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9621. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9622. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9623. /* hp used DAC 3 (Front) */
  9624. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9625. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9626. { }
  9627. };
  9628. static struct hda_verb alc861_asus_init_verbs[] = {
  9629. /*
  9630. * Unmute ADC0 and set the default input to mic-in
  9631. */
  9632. /* port-A for surround (rear panel)
  9633. * according to codec#0 this is the HP jack
  9634. */
  9635. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
  9636. /* route front PCM to HP */
  9637. { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
  9638. /* port-B for mic-in (rear panel) with vref */
  9639. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9640. /* port-C for line-in (rear panel) */
  9641. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9642. /* port-D for Front */
  9643. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9644. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9645. /* port-E for HP out (front panel) */
  9646. /* this has to be set to VREF80 */
  9647. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9648. /* route front PCM to HP */
  9649. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9650. /* port-F for mic-in (front panel) with vref */
  9651. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9652. /* port-G for CLFE (rear panel) */
  9653. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9654. /* port-H for side (rear panel) */
  9655. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9656. /* CD-in */
  9657. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9658. /* route front mic to ADC1*/
  9659. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9660. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9661. /* Unmute DAC0~3 & spdif out*/
  9662. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9663. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9664. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9665. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9666. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9667. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9668. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9669. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9670. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9671. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9672. /* Unmute Stereo Mixer 15 */
  9673. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9674. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9675. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9676. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9677. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9678. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9679. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9680. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9681. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9682. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9683. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9684. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9685. /* hp used DAC 3 (Front) */
  9686. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9687. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9688. { }
  9689. };
  9690. /* additional init verbs for ASUS laptops */
  9691. static struct hda_verb alc861_asus_laptop_init_verbs[] = {
  9692. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
  9693. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
  9694. { }
  9695. };
  9696. /*
  9697. * generic initialization of ADC, input mixers and output mixers
  9698. */
  9699. static struct hda_verb alc861_auto_init_verbs[] = {
  9700. /*
  9701. * Unmute ADC0 and set the default input to mic-in
  9702. */
  9703. /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
  9704. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9705. /* Unmute DAC0~3 & spdif out*/
  9706. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9707. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9708. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9709. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9710. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9711. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9712. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9713. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9714. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9715. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9716. /* Unmute Stereo Mixer 15 */
  9717. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9718. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9719. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9720. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
  9721. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9722. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9723. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9724. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9725. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9726. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9727. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9728. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9729. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  9730. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  9731. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9732. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9733. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  9734. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  9735. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9736. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9737. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
  9738. { }
  9739. };
  9740. static struct hda_verb alc861_toshiba_init_verbs[] = {
  9741. {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  9742. { }
  9743. };
  9744. /* toggle speaker-output according to the hp-jack state */
  9745. static void alc861_toshiba_automute(struct hda_codec *codec)
  9746. {
  9747. unsigned int present;
  9748. present = snd_hda_codec_read(codec, 0x0f, 0,
  9749. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  9750. snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
  9751. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  9752. snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
  9753. HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
  9754. }
  9755. static void alc861_toshiba_unsol_event(struct hda_codec *codec,
  9756. unsigned int res)
  9757. {
  9758. if ((res >> 26) == ALC880_HP_EVENT)
  9759. alc861_toshiba_automute(codec);
  9760. }
  9761. /* pcm configuration: identiacal with ALC880 */
  9762. #define alc861_pcm_analog_playback alc880_pcm_analog_playback
  9763. #define alc861_pcm_analog_capture alc880_pcm_analog_capture
  9764. #define alc861_pcm_digital_playback alc880_pcm_digital_playback
  9765. #define alc861_pcm_digital_capture alc880_pcm_digital_capture
  9766. #define ALC861_DIGOUT_NID 0x07
  9767. static struct hda_channel_mode alc861_8ch_modes[1] = {
  9768. { 8, NULL }
  9769. };
  9770. static hda_nid_t alc861_dac_nids[4] = {
  9771. /* front, surround, clfe, side */
  9772. 0x03, 0x06, 0x05, 0x04
  9773. };
  9774. static hda_nid_t alc660_dac_nids[3] = {
  9775. /* front, clfe, surround */
  9776. 0x03, 0x05, 0x06
  9777. };
  9778. static hda_nid_t alc861_adc_nids[1] = {
  9779. /* ADC0-2 */
  9780. 0x08,
  9781. };
  9782. static struct hda_input_mux alc861_capture_source = {
  9783. .num_items = 5,
  9784. .items = {
  9785. { "Mic", 0x0 },
  9786. { "Front Mic", 0x3 },
  9787. { "Line", 0x1 },
  9788. { "CD", 0x4 },
  9789. { "Mixer", 0x5 },
  9790. },
  9791. };
  9792. /* fill in the dac_nids table from the parsed pin configuration */
  9793. static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
  9794. const struct auto_pin_cfg *cfg)
  9795. {
  9796. int i;
  9797. hda_nid_t nid;
  9798. spec->multiout.dac_nids = spec->private_dac_nids;
  9799. for (i = 0; i < cfg->line_outs; i++) {
  9800. nid = cfg->line_out_pins[i];
  9801. if (nid) {
  9802. if (i >= ARRAY_SIZE(alc861_dac_nids))
  9803. continue;
  9804. spec->multiout.dac_nids[i] = alc861_dac_nids[i];
  9805. }
  9806. }
  9807. spec->multiout.num_dacs = cfg->line_outs;
  9808. return 0;
  9809. }
  9810. /* add playback controls from the parsed DAC table */
  9811. static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
  9812. const struct auto_pin_cfg *cfg)
  9813. {
  9814. char name[32];
  9815. static const char *chname[4] = {
  9816. "Front", "Surround", NULL /*CLFE*/, "Side"
  9817. };
  9818. hda_nid_t nid;
  9819. int i, idx, err;
  9820. for (i = 0; i < cfg->line_outs; i++) {
  9821. nid = spec->multiout.dac_nids[i];
  9822. if (!nid)
  9823. continue;
  9824. if (nid == 0x05) {
  9825. /* Center/LFE */
  9826. err = add_control(spec, ALC_CTL_BIND_MUTE,
  9827. "Center Playback Switch",
  9828. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  9829. HDA_OUTPUT));
  9830. if (err < 0)
  9831. return err;
  9832. err = add_control(spec, ALC_CTL_BIND_MUTE,
  9833. "LFE Playback Switch",
  9834. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  9835. HDA_OUTPUT));
  9836. if (err < 0)
  9837. return err;
  9838. } else {
  9839. for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
  9840. idx++)
  9841. if (nid == alc861_dac_nids[idx])
  9842. break;
  9843. sprintf(name, "%s Playback Switch", chname[idx]);
  9844. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  9845. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  9846. HDA_OUTPUT));
  9847. if (err < 0)
  9848. return err;
  9849. }
  9850. }
  9851. return 0;
  9852. }
  9853. static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
  9854. {
  9855. int err;
  9856. hda_nid_t nid;
  9857. if (!pin)
  9858. return 0;
  9859. if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
  9860. nid = 0x03;
  9861. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9862. "Headphone Playback Switch",
  9863. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  9864. if (err < 0)
  9865. return err;
  9866. spec->multiout.hp_nid = nid;
  9867. }
  9868. return 0;
  9869. }
  9870. /* create playback/capture controls for input pins */
  9871. static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
  9872. const struct auto_pin_cfg *cfg)
  9873. {
  9874. struct hda_input_mux *imux = &spec->private_imux;
  9875. int i, err, idx, idx1;
  9876. for (i = 0; i < AUTO_PIN_LAST; i++) {
  9877. switch (cfg->input_pins[i]) {
  9878. case 0x0c:
  9879. idx1 = 1;
  9880. idx = 2; /* Line In */
  9881. break;
  9882. case 0x0f:
  9883. idx1 = 2;
  9884. idx = 2; /* Line In */
  9885. break;
  9886. case 0x0d:
  9887. idx1 = 0;
  9888. idx = 1; /* Mic In */
  9889. break;
  9890. case 0x10:
  9891. idx1 = 3;
  9892. idx = 1; /* Mic In */
  9893. break;
  9894. case 0x11:
  9895. idx1 = 4;
  9896. idx = 0; /* CD */
  9897. break;
  9898. default:
  9899. continue;
  9900. }
  9901. err = new_analog_input(spec, cfg->input_pins[i],
  9902. auto_pin_cfg_labels[i], idx, 0x15);
  9903. if (err < 0)
  9904. return err;
  9905. imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
  9906. imux->items[imux->num_items].index = idx1;
  9907. imux->num_items++;
  9908. }
  9909. return 0;
  9910. }
  9911. static struct snd_kcontrol_new alc861_capture_mixer[] = {
  9912. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9913. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9914. {
  9915. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9916. /* The multiple "Capture Source" controls confuse alsamixer
  9917. * So call somewhat different..
  9918. *FIXME: the controls appear in the "playback" view!
  9919. */
  9920. /* .name = "Capture Source", */
  9921. .name = "Input Source",
  9922. .count = 1,
  9923. .info = alc_mux_enum_info,
  9924. .get = alc_mux_enum_get,
  9925. .put = alc_mux_enum_put,
  9926. },
  9927. { } /* end */
  9928. };
  9929. static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
  9930. hda_nid_t nid,
  9931. int pin_type, int dac_idx)
  9932. {
  9933. /* set as output */
  9934. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  9935. pin_type);
  9936. snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  9937. AMP_OUT_UNMUTE);
  9938. }
  9939. static void alc861_auto_init_multi_out(struct hda_codec *codec)
  9940. {
  9941. struct alc_spec *spec = codec->spec;
  9942. int i;
  9943. alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
  9944. for (i = 0; i < spec->autocfg.line_outs; i++) {
  9945. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  9946. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  9947. if (nid)
  9948. alc861_auto_set_output_and_unmute(codec, nid, pin_type,
  9949. spec->multiout.dac_nids[i]);
  9950. }
  9951. }
  9952. static void alc861_auto_init_hp_out(struct hda_codec *codec)
  9953. {
  9954. struct alc_spec *spec = codec->spec;
  9955. hda_nid_t pin;
  9956. pin = spec->autocfg.hp_pins[0];
  9957. if (pin) /* connect to front */
  9958. alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
  9959. spec->multiout.dac_nids[0]);
  9960. }
  9961. static void alc861_auto_init_analog_input(struct hda_codec *codec)
  9962. {
  9963. struct alc_spec *spec = codec->spec;
  9964. int i;
  9965. for (i = 0; i < AUTO_PIN_LAST; i++) {
  9966. hda_nid_t nid = spec->autocfg.input_pins[i];
  9967. if (nid >= 0x0c && nid <= 0x11) {
  9968. snd_hda_codec_write(codec, nid, 0,
  9969. AC_VERB_SET_PIN_WIDGET_CONTROL,
  9970. i <= AUTO_PIN_FRONT_MIC ?
  9971. PIN_VREF80 : PIN_IN);
  9972. }
  9973. }
  9974. }
  9975. /* parse the BIOS configuration and set up the alc_spec */
  9976. /* return 1 if successful, 0 if the proper config is not found,
  9977. * or a negative error code
  9978. */
  9979. static int alc861_parse_auto_config(struct hda_codec *codec)
  9980. {
  9981. struct alc_spec *spec = codec->spec;
  9982. int err;
  9983. static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
  9984. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  9985. alc861_ignore);
  9986. if (err < 0)
  9987. return err;
  9988. if (!spec->autocfg.line_outs)
  9989. return 0; /* can't find valid BIOS pin config */
  9990. err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
  9991. if (err < 0)
  9992. return err;
  9993. err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
  9994. if (err < 0)
  9995. return err;
  9996. err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  9997. if (err < 0)
  9998. return err;
  9999. err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
  10000. if (err < 0)
  10001. return err;
  10002. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  10003. if (spec->autocfg.dig_out_pin)
  10004. spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
  10005. if (spec->kctl_alloc)
  10006. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  10007. spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
  10008. spec->num_mux_defs = 1;
  10009. spec->input_mux = &spec->private_imux;
  10010. spec->adc_nids = alc861_adc_nids;
  10011. spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
  10012. spec->mixers[spec->num_mixers] = alc861_capture_mixer;
  10013. spec->num_mixers++;
  10014. return 1;
  10015. }
  10016. /* additional initialization for auto-configuration model */
  10017. static void alc861_auto_init(struct hda_codec *codec)
  10018. {
  10019. alc861_auto_init_multi_out(codec);
  10020. alc861_auto_init_hp_out(codec);
  10021. alc861_auto_init_analog_input(codec);
  10022. }
  10023. #ifdef CONFIG_SND_HDA_POWER_SAVE
  10024. static struct hda_amp_list alc861_loopbacks[] = {
  10025. { 0x15, HDA_INPUT, 0 },
  10026. { 0x15, HDA_INPUT, 1 },
  10027. { 0x15, HDA_INPUT, 2 },
  10028. { 0x15, HDA_INPUT, 3 },
  10029. { } /* end */
  10030. };
  10031. #endif
  10032. /*
  10033. * configuration and preset
  10034. */
  10035. static const char *alc861_models[ALC861_MODEL_LAST] = {
  10036. [ALC861_3ST] = "3stack",
  10037. [ALC660_3ST] = "3stack-660",
  10038. [ALC861_3ST_DIG] = "3stack-dig",
  10039. [ALC861_6ST_DIG] = "6stack-dig",
  10040. [ALC861_UNIWILL_M31] = "uniwill-m31",
  10041. [ALC861_TOSHIBA] = "toshiba",
  10042. [ALC861_ASUS] = "asus",
  10043. [ALC861_ASUS_LAPTOP] = "asus-laptop",
  10044. [ALC861_AUTO] = "auto",
  10045. };
  10046. static struct snd_pci_quirk alc861_cfg_tbl[] = {
  10047. SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
  10048. SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
  10049. SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
  10050. SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
  10051. SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
  10052. SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
  10053. SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
  10054. /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
  10055. * Any other models that need this preset?
  10056. */
  10057. /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
  10058. SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
  10059. SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
  10060. SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
  10061. SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
  10062. SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
  10063. /* FIXME: the below seems conflict */
  10064. /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
  10065. SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
  10066. SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
  10067. {}
  10068. };
  10069. static struct alc_config_preset alc861_presets[] = {
  10070. [ALC861_3ST] = {
  10071. .mixers = { alc861_3ST_mixer },
  10072. .init_verbs = { alc861_threestack_init_verbs },
  10073. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10074. .dac_nids = alc861_dac_nids,
  10075. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10076. .channel_mode = alc861_threestack_modes,
  10077. .need_dac_fix = 1,
  10078. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10079. .adc_nids = alc861_adc_nids,
  10080. .input_mux = &alc861_capture_source,
  10081. },
  10082. [ALC861_3ST_DIG] = {
  10083. .mixers = { alc861_base_mixer },
  10084. .init_verbs = { alc861_threestack_init_verbs },
  10085. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10086. .dac_nids = alc861_dac_nids,
  10087. .dig_out_nid = ALC861_DIGOUT_NID,
  10088. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10089. .channel_mode = alc861_threestack_modes,
  10090. .need_dac_fix = 1,
  10091. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10092. .adc_nids = alc861_adc_nids,
  10093. .input_mux = &alc861_capture_source,
  10094. },
  10095. [ALC861_6ST_DIG] = {
  10096. .mixers = { alc861_base_mixer },
  10097. .init_verbs = { alc861_base_init_verbs },
  10098. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10099. .dac_nids = alc861_dac_nids,
  10100. .dig_out_nid = ALC861_DIGOUT_NID,
  10101. .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
  10102. .channel_mode = alc861_8ch_modes,
  10103. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10104. .adc_nids = alc861_adc_nids,
  10105. .input_mux = &alc861_capture_source,
  10106. },
  10107. [ALC660_3ST] = {
  10108. .mixers = { alc861_3ST_mixer },
  10109. .init_verbs = { alc861_threestack_init_verbs },
  10110. .num_dacs = ARRAY_SIZE(alc660_dac_nids),
  10111. .dac_nids = alc660_dac_nids,
  10112. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10113. .channel_mode = alc861_threestack_modes,
  10114. .need_dac_fix = 1,
  10115. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10116. .adc_nids = alc861_adc_nids,
  10117. .input_mux = &alc861_capture_source,
  10118. },
  10119. [ALC861_UNIWILL_M31] = {
  10120. .mixers = { alc861_uniwill_m31_mixer },
  10121. .init_verbs = { alc861_uniwill_m31_init_verbs },
  10122. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10123. .dac_nids = alc861_dac_nids,
  10124. .dig_out_nid = ALC861_DIGOUT_NID,
  10125. .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
  10126. .channel_mode = alc861_uniwill_m31_modes,
  10127. .need_dac_fix = 1,
  10128. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10129. .adc_nids = alc861_adc_nids,
  10130. .input_mux = &alc861_capture_source,
  10131. },
  10132. [ALC861_TOSHIBA] = {
  10133. .mixers = { alc861_toshiba_mixer },
  10134. .init_verbs = { alc861_base_init_verbs,
  10135. alc861_toshiba_init_verbs },
  10136. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10137. .dac_nids = alc861_dac_nids,
  10138. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  10139. .channel_mode = alc883_3ST_2ch_modes,
  10140. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10141. .adc_nids = alc861_adc_nids,
  10142. .input_mux = &alc861_capture_source,
  10143. .unsol_event = alc861_toshiba_unsol_event,
  10144. .init_hook = alc861_toshiba_automute,
  10145. },
  10146. [ALC861_ASUS] = {
  10147. .mixers = { alc861_asus_mixer },
  10148. .init_verbs = { alc861_asus_init_verbs },
  10149. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10150. .dac_nids = alc861_dac_nids,
  10151. .dig_out_nid = ALC861_DIGOUT_NID,
  10152. .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
  10153. .channel_mode = alc861_asus_modes,
  10154. .need_dac_fix = 1,
  10155. .hp_nid = 0x06,
  10156. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10157. .adc_nids = alc861_adc_nids,
  10158. .input_mux = &alc861_capture_source,
  10159. },
  10160. [ALC861_ASUS_LAPTOP] = {
  10161. .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
  10162. .init_verbs = { alc861_asus_init_verbs,
  10163. alc861_asus_laptop_init_verbs },
  10164. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10165. .dac_nids = alc861_dac_nids,
  10166. .dig_out_nid = ALC861_DIGOUT_NID,
  10167. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  10168. .channel_mode = alc883_3ST_2ch_modes,
  10169. .need_dac_fix = 1,
  10170. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10171. .adc_nids = alc861_adc_nids,
  10172. .input_mux = &alc861_capture_source,
  10173. },
  10174. };
  10175. static int patch_alc861(struct hda_codec *codec)
  10176. {
  10177. struct alc_spec *spec;
  10178. int board_config;
  10179. int err;
  10180. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  10181. if (spec == NULL)
  10182. return -ENOMEM;
  10183. codec->spec = spec;
  10184. board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
  10185. alc861_models,
  10186. alc861_cfg_tbl);
  10187. if (board_config < 0) {
  10188. printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
  10189. "trying auto-probe from BIOS...\n");
  10190. board_config = ALC861_AUTO;
  10191. }
  10192. if (board_config == ALC861_AUTO) {
  10193. /* automatic parse from the BIOS config */
  10194. err = alc861_parse_auto_config(codec);
  10195. if (err < 0) {
  10196. alc_free(codec);
  10197. return err;
  10198. } else if (!err) {
  10199. printk(KERN_INFO
  10200. "hda_codec: Cannot set up configuration "
  10201. "from BIOS. Using base mode...\n");
  10202. board_config = ALC861_3ST_DIG;
  10203. }
  10204. }
  10205. if (board_config != ALC861_AUTO)
  10206. setup_preset(spec, &alc861_presets[board_config]);
  10207. spec->stream_name_analog = "ALC861 Analog";
  10208. spec->stream_analog_playback = &alc861_pcm_analog_playback;
  10209. spec->stream_analog_capture = &alc861_pcm_analog_capture;
  10210. spec->stream_name_digital = "ALC861 Digital";
  10211. spec->stream_digital_playback = &alc861_pcm_digital_playback;
  10212. spec->stream_digital_capture = &alc861_pcm_digital_capture;
  10213. codec->patch_ops = alc_patch_ops;
  10214. if (board_config == ALC861_AUTO)
  10215. spec->init_hook = alc861_auto_init;
  10216. #ifdef CONFIG_SND_HDA_POWER_SAVE
  10217. if (!spec->loopback.amplist)
  10218. spec->loopback.amplist = alc861_loopbacks;
  10219. #endif
  10220. return 0;
  10221. }
  10222. /*
  10223. * ALC861-VD support
  10224. *
  10225. * Based on ALC882
  10226. *
  10227. * In addition, an independent DAC
  10228. */
  10229. #define ALC861VD_DIGOUT_NID 0x06
  10230. static hda_nid_t alc861vd_dac_nids[4] = {
  10231. /* front, surr, clfe, side surr */
  10232. 0x02, 0x03, 0x04, 0x05
  10233. };
  10234. /* dac_nids for ALC660vd are in a different order - according to
  10235. * Realtek's driver.
  10236. * This should probably tesult in a different mixer for 6stack models
  10237. * of ALC660vd codecs, but for now there is only 3stack mixer
  10238. * - and it is the same as in 861vd.
  10239. * adc_nids in ALC660vd are (is) the same as in 861vd
  10240. */
  10241. static hda_nid_t alc660vd_dac_nids[3] = {
  10242. /* front, rear, clfe, rear_surr */
  10243. 0x02, 0x04, 0x03
  10244. };
  10245. static hda_nid_t alc861vd_adc_nids[1] = {
  10246. /* ADC0 */
  10247. 0x09,
  10248. };
  10249. /* input MUX */
  10250. /* FIXME: should be a matrix-type input source selection */
  10251. static struct hda_input_mux alc861vd_capture_source = {
  10252. .num_items = 4,
  10253. .items = {
  10254. { "Mic", 0x0 },
  10255. { "Front Mic", 0x1 },
  10256. { "Line", 0x2 },
  10257. { "CD", 0x4 },
  10258. },
  10259. };
  10260. static struct hda_input_mux alc861vd_dallas_capture_source = {
  10261. .num_items = 3,
  10262. .items = {
  10263. { "Front Mic", 0x0 },
  10264. { "ATAPI Mic", 0x1 },
  10265. { "Line In", 0x5 },
  10266. },
  10267. };
  10268. static struct hda_input_mux alc861vd_hp_capture_source = {
  10269. .num_items = 2,
  10270. .items = {
  10271. { "Front Mic", 0x0 },
  10272. { "ATAPI Mic", 0x1 },
  10273. },
  10274. };
  10275. #define alc861vd_mux_enum_info alc_mux_enum_info
  10276. #define alc861vd_mux_enum_get alc_mux_enum_get
  10277. static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
  10278. struct snd_ctl_elem_value *ucontrol)
  10279. {
  10280. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  10281. struct alc_spec *spec = codec->spec;
  10282. const struct hda_input_mux *imux = spec->input_mux;
  10283. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  10284. static hda_nid_t capture_mixers[1] = { 0x22 };
  10285. hda_nid_t nid = capture_mixers[adc_idx];
  10286. unsigned int *cur_val = &spec->cur_mux[adc_idx];
  10287. unsigned int i, idx;
  10288. idx = ucontrol->value.enumerated.item[0];
  10289. if (idx >= imux->num_items)
  10290. idx = imux->num_items - 1;
  10291. if (*cur_val == idx)
  10292. return 0;
  10293. for (i = 0; i < imux->num_items; i++) {
  10294. unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
  10295. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
  10296. imux->items[i].index,
  10297. HDA_AMP_MUTE, v);
  10298. }
  10299. *cur_val = idx;
  10300. return 1;
  10301. }
  10302. /*
  10303. * 2ch mode
  10304. */
  10305. static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
  10306. { 2, NULL }
  10307. };
  10308. /*
  10309. * 6ch mode
  10310. */
  10311. static struct hda_verb alc861vd_6stack_ch6_init[] = {
  10312. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  10313. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10314. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10315. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10316. { } /* end */
  10317. };
  10318. /*
  10319. * 8ch mode
  10320. */
  10321. static struct hda_verb alc861vd_6stack_ch8_init[] = {
  10322. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10323. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10324. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10325. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10326. { } /* end */
  10327. };
  10328. static struct hda_channel_mode alc861vd_6stack_modes[2] = {
  10329. { 6, alc861vd_6stack_ch6_init },
  10330. { 8, alc861vd_6stack_ch8_init },
  10331. };
  10332. static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
  10333. {
  10334. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  10335. .name = "Channel Mode",
  10336. .info = alc_ch_mode_info,
  10337. .get = alc_ch_mode_get,
  10338. .put = alc_ch_mode_put,
  10339. },
  10340. { } /* end */
  10341. };
  10342. static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
  10343. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  10344. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  10345. {
  10346. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  10347. /* The multiple "Capture Source" controls confuse alsamixer
  10348. * So call somewhat different..
  10349. *FIXME: the controls appear in the "playback" view!
  10350. */
  10351. /* .name = "Capture Source", */
  10352. .name = "Input Source",
  10353. .count = 1,
  10354. .info = alc861vd_mux_enum_info,
  10355. .get = alc861vd_mux_enum_get,
  10356. .put = alc861vd_mux_enum_put,
  10357. },
  10358. { } /* end */
  10359. };
  10360. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  10361. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  10362. */
  10363. static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
  10364. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10365. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10366. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10367. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  10368. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
  10369. HDA_OUTPUT),
  10370. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
  10371. HDA_OUTPUT),
  10372. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  10373. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  10374. HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  10375. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  10376. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10377. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10378. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10379. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10380. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10381. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10382. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10383. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  10384. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  10385. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10386. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10387. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10388. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10389. { } /* end */
  10390. };
  10391. static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
  10392. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10393. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10394. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10395. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10396. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10397. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10398. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10399. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10400. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10401. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  10402. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  10403. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10404. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10405. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10406. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10407. { } /* end */
  10408. };
  10409. static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
  10410. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10411. /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
  10412. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  10413. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10414. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10415. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10416. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10417. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10418. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10419. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10420. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10421. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10422. { } /* end */
  10423. };
  10424. /* Pin assignment: Front=0x14, HP = 0x15,
  10425. * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
  10426. */
  10427. static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
  10428. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10429. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10430. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10431. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  10432. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10433. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10434. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10435. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10436. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10437. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10438. { } /* end */
  10439. };
  10440. /* Pin assignment: Speaker=0x14, Line-out = 0x15,
  10441. * Front Mic=0x18, ATAPI Mic = 0x19,
  10442. */
  10443. static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
  10444. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10445. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10446. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10447. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  10448. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10449. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10450. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10451. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10452. { } /* end */
  10453. };
  10454. /*
  10455. * generic initialization of ADC, input mixers and output mixers
  10456. */
  10457. static struct hda_verb alc861vd_volume_init_verbs[] = {
  10458. /*
  10459. * Unmute ADC0 and set the default input to mic-in
  10460. */
  10461. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  10462. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10463. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
  10464. * the analog-loopback mixer widget
  10465. */
  10466. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  10467. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10468. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10469. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  10470. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  10471. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  10472. /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
  10473. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10474. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10475. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10476. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  10477. /*
  10478. * Set up output mixers (0x02 - 0x05)
  10479. */
  10480. /* set vol=0 to output mixers */
  10481. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10482. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10483. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10484. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10485. /* set up input amps for analog loopback */
  10486. /* Amp Indices: DAC = 0, mixer = 1 */
  10487. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10488. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10489. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10490. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10491. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10492. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10493. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10494. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10495. { }
  10496. };
  10497. /*
  10498. * 3-stack pin configuration:
  10499. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  10500. */
  10501. static struct hda_verb alc861vd_3stack_init_verbs[] = {
  10502. /*
  10503. * Set pin mode and muting
  10504. */
  10505. /* set front pin widgets 0x14 for output */
  10506. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10507. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10508. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  10509. /* Mic (rear) pin: input vref at 80% */
  10510. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10511. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10512. /* Front Mic pin: input vref at 80% */
  10513. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10514. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10515. /* Line In pin: input */
  10516. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10517. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10518. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  10519. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  10520. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10521. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  10522. /* CD pin widget for input */
  10523. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10524. { }
  10525. };
  10526. /*
  10527. * 6-stack pin configuration:
  10528. */
  10529. static struct hda_verb alc861vd_6stack_init_verbs[] = {
  10530. /*
  10531. * Set pin mode and muting
  10532. */
  10533. /* set front pin widgets 0x14 for output */
  10534. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10535. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10536. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  10537. /* Rear Pin: output 1 (0x0d) */
  10538. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10539. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10540. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  10541. /* CLFE Pin: output 2 (0x0e) */
  10542. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10543. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10544. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  10545. /* Side Pin: output 3 (0x0f) */
  10546. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10547. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10548. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  10549. /* Mic (rear) pin: input vref at 80% */
  10550. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10551. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10552. /* Front Mic pin: input vref at 80% */
  10553. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10554. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10555. /* Line In pin: input */
  10556. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10557. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10558. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  10559. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  10560. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10561. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  10562. /* CD pin widget for input */
  10563. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10564. { }
  10565. };
  10566. static struct hda_verb alc861vd_eapd_verbs[] = {
  10567. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  10568. { }
  10569. };
  10570. static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
  10571. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10572. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10573. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  10574. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  10575. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  10576. {}
  10577. };
  10578. /* toggle speaker-output according to the hp-jack state */
  10579. static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
  10580. {
  10581. unsigned int present;
  10582. unsigned char bits;
  10583. present = snd_hda_codec_read(codec, 0x1b, 0,
  10584. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10585. bits = present ? HDA_AMP_MUTE : 0;
  10586. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  10587. HDA_AMP_MUTE, bits);
  10588. }
  10589. static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
  10590. {
  10591. unsigned int present;
  10592. unsigned char bits;
  10593. present = snd_hda_codec_read(codec, 0x18, 0,
  10594. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10595. bits = present ? HDA_AMP_MUTE : 0;
  10596. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
  10597. HDA_AMP_MUTE, bits);
  10598. }
  10599. static void alc861vd_lenovo_automute(struct hda_codec *codec)
  10600. {
  10601. alc861vd_lenovo_hp_automute(codec);
  10602. alc861vd_lenovo_mic_automute(codec);
  10603. }
  10604. static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
  10605. unsigned int res)
  10606. {
  10607. switch (res >> 26) {
  10608. case ALC880_HP_EVENT:
  10609. alc861vd_lenovo_hp_automute(codec);
  10610. break;
  10611. case ALC880_MIC_EVENT:
  10612. alc861vd_lenovo_mic_automute(codec);
  10613. break;
  10614. }
  10615. }
  10616. static struct hda_verb alc861vd_dallas_verbs[] = {
  10617. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10618. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10619. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10620. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10621. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10622. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10623. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10624. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10625. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10626. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10627. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10628. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10629. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10630. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10631. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10632. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10633. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10634. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10635. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10636. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10637. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  10638. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10639. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  10640. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10641. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10642. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10643. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10644. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10645. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10646. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  10647. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  10648. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  10649. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10650. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  10651. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  10652. { } /* end */
  10653. };
  10654. /* toggle speaker-output according to the hp-jack state */
  10655. static void alc861vd_dallas_automute(struct hda_codec *codec)
  10656. {
  10657. unsigned int present;
  10658. present = snd_hda_codec_read(codec, 0x15, 0,
  10659. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10660. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  10661. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  10662. }
  10663. static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
  10664. {
  10665. if ((res >> 26) == ALC880_HP_EVENT)
  10666. alc861vd_dallas_automute(codec);
  10667. }
  10668. #ifdef CONFIG_SND_HDA_POWER_SAVE
  10669. #define alc861vd_loopbacks alc880_loopbacks
  10670. #endif
  10671. /* pcm configuration: identiacal with ALC880 */
  10672. #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
  10673. #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
  10674. #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
  10675. #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
  10676. /*
  10677. * configuration and preset
  10678. */
  10679. static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
  10680. [ALC660VD_3ST] = "3stack-660",
  10681. [ALC660VD_3ST_DIG] = "3stack-660-digout",
  10682. [ALC861VD_3ST] = "3stack",
  10683. [ALC861VD_3ST_DIG] = "3stack-digout",
  10684. [ALC861VD_6ST_DIG] = "6stack-digout",
  10685. [ALC861VD_LENOVO] = "lenovo",
  10686. [ALC861VD_DALLAS] = "dallas",
  10687. [ALC861VD_HP] = "hp",
  10688. [ALC861VD_AUTO] = "auto",
  10689. };
  10690. static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
  10691. SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
  10692. SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
  10693. SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
  10694. SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
  10695. SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
  10696. SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
  10697. SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
  10698. /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
  10699. SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
  10700. SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
  10701. SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
  10702. SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
  10703. SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
  10704. SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
  10705. {}
  10706. };
  10707. static struct alc_config_preset alc861vd_presets[] = {
  10708. [ALC660VD_3ST] = {
  10709. .mixers = { alc861vd_3st_mixer },
  10710. .init_verbs = { alc861vd_volume_init_verbs,
  10711. alc861vd_3stack_init_verbs },
  10712. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  10713. .dac_nids = alc660vd_dac_nids,
  10714. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  10715. .adc_nids = alc861vd_adc_nids,
  10716. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10717. .channel_mode = alc861vd_3stack_2ch_modes,
  10718. .input_mux = &alc861vd_capture_source,
  10719. },
  10720. [ALC660VD_3ST_DIG] = {
  10721. .mixers = { alc861vd_3st_mixer },
  10722. .init_verbs = { alc861vd_volume_init_verbs,
  10723. alc861vd_3stack_init_verbs },
  10724. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  10725. .dac_nids = alc660vd_dac_nids,
  10726. .dig_out_nid = ALC861VD_DIGOUT_NID,
  10727. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  10728. .adc_nids = alc861vd_adc_nids,
  10729. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10730. .channel_mode = alc861vd_3stack_2ch_modes,
  10731. .input_mux = &alc861vd_capture_source,
  10732. },
  10733. [ALC861VD_3ST] = {
  10734. .mixers = { alc861vd_3st_mixer },
  10735. .init_verbs = { alc861vd_volume_init_verbs,
  10736. alc861vd_3stack_init_verbs },
  10737. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  10738. .dac_nids = alc861vd_dac_nids,
  10739. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10740. .channel_mode = alc861vd_3stack_2ch_modes,
  10741. .input_mux = &alc861vd_capture_source,
  10742. },
  10743. [ALC861VD_3ST_DIG] = {
  10744. .mixers = { alc861vd_3st_mixer },
  10745. .init_verbs = { alc861vd_volume_init_verbs,
  10746. alc861vd_3stack_init_verbs },
  10747. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  10748. .dac_nids = alc861vd_dac_nids,
  10749. .dig_out_nid = ALC861VD_DIGOUT_NID,
  10750. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10751. .channel_mode = alc861vd_3stack_2ch_modes,
  10752. .input_mux = &alc861vd_capture_source,
  10753. },
  10754. [ALC861VD_6ST_DIG] = {
  10755. .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
  10756. .init_verbs = { alc861vd_volume_init_verbs,
  10757. alc861vd_6stack_init_verbs },
  10758. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  10759. .dac_nids = alc861vd_dac_nids,
  10760. .dig_out_nid = ALC861VD_DIGOUT_NID,
  10761. .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
  10762. .channel_mode = alc861vd_6stack_modes,
  10763. .input_mux = &alc861vd_capture_source,
  10764. },
  10765. [ALC861VD_LENOVO] = {
  10766. .mixers = { alc861vd_lenovo_mixer },
  10767. .init_verbs = { alc861vd_volume_init_verbs,
  10768. alc861vd_3stack_init_verbs,
  10769. alc861vd_eapd_verbs,
  10770. alc861vd_lenovo_unsol_verbs },
  10771. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  10772. .dac_nids = alc660vd_dac_nids,
  10773. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  10774. .adc_nids = alc861vd_adc_nids,
  10775. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10776. .channel_mode = alc861vd_3stack_2ch_modes,
  10777. .input_mux = &alc861vd_capture_source,
  10778. .unsol_event = alc861vd_lenovo_unsol_event,
  10779. .init_hook = alc861vd_lenovo_automute,
  10780. },
  10781. [ALC861VD_DALLAS] = {
  10782. .mixers = { alc861vd_dallas_mixer },
  10783. .init_verbs = { alc861vd_dallas_verbs },
  10784. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  10785. .dac_nids = alc861vd_dac_nids,
  10786. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  10787. .adc_nids = alc861vd_adc_nids,
  10788. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10789. .channel_mode = alc861vd_3stack_2ch_modes,
  10790. .input_mux = &alc861vd_dallas_capture_source,
  10791. .unsol_event = alc861vd_dallas_unsol_event,
  10792. .init_hook = alc861vd_dallas_automute,
  10793. },
  10794. [ALC861VD_HP] = {
  10795. .mixers = { alc861vd_hp_mixer },
  10796. .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
  10797. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  10798. .dac_nids = alc861vd_dac_nids,
  10799. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  10800. .dig_out_nid = ALC861VD_DIGOUT_NID,
  10801. .adc_nids = alc861vd_adc_nids,
  10802. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  10803. .channel_mode = alc861vd_3stack_2ch_modes,
  10804. .input_mux = &alc861vd_hp_capture_source,
  10805. .unsol_event = alc861vd_dallas_unsol_event,
  10806. .init_hook = alc861vd_dallas_automute,
  10807. },
  10808. };
  10809. /*
  10810. * BIOS auto configuration
  10811. */
  10812. static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
  10813. hda_nid_t nid, int pin_type, int dac_idx)
  10814. {
  10815. /* set as output */
  10816. snd_hda_codec_write(codec, nid, 0,
  10817. AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
  10818. snd_hda_codec_write(codec, nid, 0,
  10819. AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
  10820. }
  10821. static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
  10822. {
  10823. struct alc_spec *spec = codec->spec;
  10824. int i;
  10825. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  10826. for (i = 0; i <= HDA_SIDE; i++) {
  10827. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  10828. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  10829. if (nid)
  10830. alc861vd_auto_set_output_and_unmute(codec, nid,
  10831. pin_type, i);
  10832. }
  10833. }
  10834. static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
  10835. {
  10836. struct alc_spec *spec = codec->spec;
  10837. hda_nid_t pin;
  10838. pin = spec->autocfg.hp_pins[0];
  10839. if (pin) /* connect to front and use dac 0 */
  10840. alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  10841. }
  10842. #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
  10843. #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
  10844. static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
  10845. {
  10846. struct alc_spec *spec = codec->spec;
  10847. int i;
  10848. for (i = 0; i < AUTO_PIN_LAST; i++) {
  10849. hda_nid_t nid = spec->autocfg.input_pins[i];
  10850. if (alc861vd_is_input_pin(nid)) {
  10851. snd_hda_codec_write(codec, nid, 0,
  10852. AC_VERB_SET_PIN_WIDGET_CONTROL,
  10853. i <= AUTO_PIN_FRONT_MIC ?
  10854. PIN_VREF80 : PIN_IN);
  10855. if (nid != ALC861VD_PIN_CD_NID)
  10856. snd_hda_codec_write(codec, nid, 0,
  10857. AC_VERB_SET_AMP_GAIN_MUTE,
  10858. AMP_OUT_MUTE);
  10859. }
  10860. }
  10861. }
  10862. #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
  10863. #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
  10864. /* add playback controls from the parsed DAC table */
  10865. /* Based on ALC880 version. But ALC861VD has separate,
  10866. * different NIDs for mute/unmute switch and volume control */
  10867. static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
  10868. const struct auto_pin_cfg *cfg)
  10869. {
  10870. char name[32];
  10871. static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
  10872. hda_nid_t nid_v, nid_s;
  10873. int i, err;
  10874. for (i = 0; i < cfg->line_outs; i++) {
  10875. if (!spec->multiout.dac_nids[i])
  10876. continue;
  10877. nid_v = alc861vd_idx_to_mixer_vol(
  10878. alc880_dac_to_idx(
  10879. spec->multiout.dac_nids[i]));
  10880. nid_s = alc861vd_idx_to_mixer_switch(
  10881. alc880_dac_to_idx(
  10882. spec->multiout.dac_nids[i]));
  10883. if (i == 2) {
  10884. /* Center/LFE */
  10885. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  10886. "Center Playback Volume",
  10887. HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
  10888. HDA_OUTPUT));
  10889. if (err < 0)
  10890. return err;
  10891. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  10892. "LFE Playback Volume",
  10893. HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
  10894. HDA_OUTPUT));
  10895. if (err < 0)
  10896. return err;
  10897. err = add_control(spec, ALC_CTL_BIND_MUTE,
  10898. "Center Playback Switch",
  10899. HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
  10900. HDA_INPUT));
  10901. if (err < 0)
  10902. return err;
  10903. err = add_control(spec, ALC_CTL_BIND_MUTE,
  10904. "LFE Playback Switch",
  10905. HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
  10906. HDA_INPUT));
  10907. if (err < 0)
  10908. return err;
  10909. } else {
  10910. sprintf(name, "%s Playback Volume", chname[i]);
  10911. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  10912. HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
  10913. HDA_OUTPUT));
  10914. if (err < 0)
  10915. return err;
  10916. sprintf(name, "%s Playback Switch", chname[i]);
  10917. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  10918. HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
  10919. HDA_INPUT));
  10920. if (err < 0)
  10921. return err;
  10922. }
  10923. }
  10924. return 0;
  10925. }
  10926. /* add playback controls for speaker and HP outputs */
  10927. /* Based on ALC880 version. But ALC861VD has separate,
  10928. * different NIDs for mute/unmute switch and volume control */
  10929. static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
  10930. hda_nid_t pin, const char *pfx)
  10931. {
  10932. hda_nid_t nid_v, nid_s;
  10933. int err;
  10934. char name[32];
  10935. if (!pin)
  10936. return 0;
  10937. if (alc880_is_fixed_pin(pin)) {
  10938. nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  10939. /* specify the DAC as the extra output */
  10940. if (!spec->multiout.hp_nid)
  10941. spec->multiout.hp_nid = nid_v;
  10942. else
  10943. spec->multiout.extra_out_nid[0] = nid_v;
  10944. /* control HP volume/switch on the output mixer amp */
  10945. nid_v = alc861vd_idx_to_mixer_vol(
  10946. alc880_fixed_pin_idx(pin));
  10947. nid_s = alc861vd_idx_to_mixer_switch(
  10948. alc880_fixed_pin_idx(pin));
  10949. sprintf(name, "%s Playback Volume", pfx);
  10950. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  10951. HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
  10952. if (err < 0)
  10953. return err;
  10954. sprintf(name, "%s Playback Switch", pfx);
  10955. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  10956. HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
  10957. if (err < 0)
  10958. return err;
  10959. } else if (alc880_is_multi_pin(pin)) {
  10960. /* set manual connection */
  10961. /* we have only a switch on HP-out PIN */
  10962. sprintf(name, "%s Playback Switch", pfx);
  10963. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  10964. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  10965. if (err < 0)
  10966. return err;
  10967. }
  10968. return 0;
  10969. }
  10970. /* parse the BIOS configuration and set up the alc_spec
  10971. * return 1 if successful, 0 if the proper config is not found,
  10972. * or a negative error code
  10973. * Based on ALC880 version - had to change it to override
  10974. * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
  10975. static int alc861vd_parse_auto_config(struct hda_codec *codec)
  10976. {
  10977. struct alc_spec *spec = codec->spec;
  10978. int err;
  10979. static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
  10980. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  10981. alc861vd_ignore);
  10982. if (err < 0)
  10983. return err;
  10984. if (!spec->autocfg.line_outs)
  10985. return 0; /* can't find valid BIOS pin config */
  10986. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  10987. if (err < 0)
  10988. return err;
  10989. err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
  10990. if (err < 0)
  10991. return err;
  10992. err = alc861vd_auto_create_extra_out(spec,
  10993. spec->autocfg.speaker_pins[0],
  10994. "Speaker");
  10995. if (err < 0)
  10996. return err;
  10997. err = alc861vd_auto_create_extra_out(spec,
  10998. spec->autocfg.hp_pins[0],
  10999. "Headphone");
  11000. if (err < 0)
  11001. return err;
  11002. err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
  11003. if (err < 0)
  11004. return err;
  11005. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  11006. if (spec->autocfg.dig_out_pin)
  11007. spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
  11008. if (spec->kctl_alloc)
  11009. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  11010. spec->init_verbs[spec->num_init_verbs++]
  11011. = alc861vd_volume_init_verbs;
  11012. spec->num_mux_defs = 1;
  11013. spec->input_mux = &spec->private_imux;
  11014. err = alc_auto_add_mic_boost(codec);
  11015. if (err < 0)
  11016. return err;
  11017. return 1;
  11018. }
  11019. /* additional initialization for auto-configuration model */
  11020. static void alc861vd_auto_init(struct hda_codec *codec)
  11021. {
  11022. alc861vd_auto_init_multi_out(codec);
  11023. alc861vd_auto_init_hp_out(codec);
  11024. alc861vd_auto_init_analog_input(codec);
  11025. }
  11026. static int patch_alc861vd(struct hda_codec *codec)
  11027. {
  11028. struct alc_spec *spec;
  11029. int err, board_config;
  11030. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  11031. if (spec == NULL)
  11032. return -ENOMEM;
  11033. codec->spec = spec;
  11034. board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
  11035. alc861vd_models,
  11036. alc861vd_cfg_tbl);
  11037. if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
  11038. printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
  11039. "ALC861VD, trying auto-probe from BIOS...\n");
  11040. board_config = ALC861VD_AUTO;
  11041. }
  11042. if (board_config == ALC861VD_AUTO) {
  11043. /* automatic parse from the BIOS config */
  11044. err = alc861vd_parse_auto_config(codec);
  11045. if (err < 0) {
  11046. alc_free(codec);
  11047. return err;
  11048. } else if (!err) {
  11049. printk(KERN_INFO
  11050. "hda_codec: Cannot set up configuration "
  11051. "from BIOS. Using base mode...\n");
  11052. board_config = ALC861VD_3ST;
  11053. }
  11054. }
  11055. if (board_config != ALC861VD_AUTO)
  11056. setup_preset(spec, &alc861vd_presets[board_config]);
  11057. spec->stream_name_analog = "ALC861VD Analog";
  11058. spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
  11059. spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
  11060. spec->stream_name_digital = "ALC861VD Digital";
  11061. spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
  11062. spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
  11063. spec->adc_nids = alc861vd_adc_nids;
  11064. spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
  11065. spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
  11066. spec->num_mixers++;
  11067. codec->patch_ops = alc_patch_ops;
  11068. if (board_config == ALC861VD_AUTO)
  11069. spec->init_hook = alc861vd_auto_init;
  11070. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11071. if (!spec->loopback.amplist)
  11072. spec->loopback.amplist = alc861vd_loopbacks;
  11073. #endif
  11074. return 0;
  11075. }
  11076. /*
  11077. * ALC662 support
  11078. *
  11079. * ALC662 is almost identical with ALC880 but has cleaner and more flexible
  11080. * configuration. Each pin widget can choose any input DACs and a mixer.
  11081. * Each ADC is connected from a mixer of all inputs. This makes possible
  11082. * 6-channel independent captures.
  11083. *
  11084. * In addition, an independent DAC for the multi-playback (not used in this
  11085. * driver yet).
  11086. */
  11087. #define ALC662_DIGOUT_NID 0x06
  11088. #define ALC662_DIGIN_NID 0x0a
  11089. static hda_nid_t alc662_dac_nids[4] = {
  11090. /* front, rear, clfe, rear_surr */
  11091. 0x02, 0x03, 0x04
  11092. };
  11093. static hda_nid_t alc662_adc_nids[1] = {
  11094. /* ADC1-2 */
  11095. 0x09,
  11096. };
  11097. /* input MUX */
  11098. /* FIXME: should be a matrix-type input source selection */
  11099. static struct hda_input_mux alc662_capture_source = {
  11100. .num_items = 4,
  11101. .items = {
  11102. { "Mic", 0x0 },
  11103. { "Front Mic", 0x1 },
  11104. { "Line", 0x2 },
  11105. { "CD", 0x4 },
  11106. },
  11107. };
  11108. static struct hda_input_mux alc662_lenovo_101e_capture_source = {
  11109. .num_items = 2,
  11110. .items = {
  11111. { "Mic", 0x1 },
  11112. { "Line", 0x2 },
  11113. },
  11114. };
  11115. static struct hda_input_mux alc662_eeepc_capture_source = {
  11116. .num_items = 2,
  11117. .items = {
  11118. { "i-Mic", 0x1 },
  11119. { "e-Mic", 0x0 },
  11120. },
  11121. };
  11122. #define alc662_mux_enum_info alc_mux_enum_info
  11123. #define alc662_mux_enum_get alc_mux_enum_get
  11124. static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
  11125. struct snd_ctl_elem_value *ucontrol)
  11126. {
  11127. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  11128. struct alc_spec *spec = codec->spec;
  11129. const struct hda_input_mux *imux = spec->input_mux;
  11130. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  11131. static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
  11132. hda_nid_t nid = capture_mixers[adc_idx];
  11133. unsigned int *cur_val = &spec->cur_mux[adc_idx];
  11134. unsigned int i, idx;
  11135. idx = ucontrol->value.enumerated.item[0];
  11136. if (idx >= imux->num_items)
  11137. idx = imux->num_items - 1;
  11138. if (*cur_val == idx)
  11139. return 0;
  11140. for (i = 0; i < imux->num_items; i++) {
  11141. unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
  11142. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
  11143. imux->items[i].index,
  11144. HDA_AMP_MUTE, v);
  11145. }
  11146. *cur_val = idx;
  11147. return 1;
  11148. }
  11149. /*
  11150. * 2ch mode
  11151. */
  11152. static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
  11153. { 2, NULL }
  11154. };
  11155. /*
  11156. * 2ch mode
  11157. */
  11158. static struct hda_verb alc662_3ST_ch2_init[] = {
  11159. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  11160. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  11161. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  11162. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  11163. { } /* end */
  11164. };
  11165. /*
  11166. * 6ch mode
  11167. */
  11168. static struct hda_verb alc662_3ST_ch6_init[] = {
  11169. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11170. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  11171. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  11172. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11173. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  11174. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  11175. { } /* end */
  11176. };
  11177. static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
  11178. { 2, alc662_3ST_ch2_init },
  11179. { 6, alc662_3ST_ch6_init },
  11180. };
  11181. /*
  11182. * 2ch mode
  11183. */
  11184. static struct hda_verb alc662_sixstack_ch6_init[] = {
  11185. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  11186. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  11187. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11188. { } /* end */
  11189. };
  11190. /*
  11191. * 6ch mode
  11192. */
  11193. static struct hda_verb alc662_sixstack_ch8_init[] = {
  11194. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11195. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11196. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11197. { } /* end */
  11198. };
  11199. static struct hda_channel_mode alc662_5stack_modes[2] = {
  11200. { 2, alc662_sixstack_ch6_init },
  11201. { 6, alc662_sixstack_ch8_init },
  11202. };
  11203. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  11204. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  11205. */
  11206. static struct snd_kcontrol_new alc662_base_mixer[] = {
  11207. /* output mixer control */
  11208. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  11209. HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
  11210. HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  11211. HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  11212. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  11213. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  11214. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
  11215. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
  11216. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11217. /*Input mixer control */
  11218. HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
  11219. HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
  11220. HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
  11221. HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
  11222. HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
  11223. HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
  11224. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
  11225. HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
  11226. { } /* end */
  11227. };
  11228. static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
  11229. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11230. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11231. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11232. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  11233. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  11234. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11235. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11236. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11237. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11238. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11239. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11240. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  11241. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  11242. { } /* end */
  11243. };
  11244. static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
  11245. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11246. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11247. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  11248. HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
  11249. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  11250. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  11251. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
  11252. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
  11253. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11254. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  11255. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  11256. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11257. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11258. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11259. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11260. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11261. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11262. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  11263. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  11264. { } /* end */
  11265. };
  11266. static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
  11267. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11268. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11269. HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  11270. HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
  11271. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11272. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11273. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11274. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11275. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11276. { } /* end */
  11277. };
  11278. static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
  11279. HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  11280. HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11281. HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11282. HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
  11283. HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11284. HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11285. HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
  11286. HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11287. HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11288. { } /* end */
  11289. };
  11290. static struct snd_kcontrol_new alc662_chmode_mixer[] = {
  11291. {
  11292. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  11293. .name = "Channel Mode",
  11294. .info = alc_ch_mode_info,
  11295. .get = alc_ch_mode_get,
  11296. .put = alc_ch_mode_put,
  11297. },
  11298. { } /* end */
  11299. };
  11300. static struct hda_verb alc662_init_verbs[] = {
  11301. /* ADC: mute amp left and right */
  11302. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11303. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  11304. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  11305. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11306. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11307. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  11308. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  11309. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  11310. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11311. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11312. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11313. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11314. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11315. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11316. /* Front Pin: output 0 (0x0c) */
  11317. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11318. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11319. /* Rear Pin: output 1 (0x0d) */
  11320. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11321. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11322. /* CLFE Pin: output 2 (0x0e) */
  11323. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11324. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11325. /* Mic (rear) pin: input vref at 80% */
  11326. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  11327. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11328. /* Front Mic pin: input vref at 80% */
  11329. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  11330. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11331. /* Line In pin: input */
  11332. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11333. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11334. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  11335. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  11336. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11337. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  11338. /* CD pin widget for input */
  11339. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11340. /* FIXME: use matrix-type input source selection */
  11341. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  11342. /* Input mixer */
  11343. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11344. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11345. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  11346. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  11347. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11348. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11349. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  11350. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  11351. { }
  11352. };
  11353. static struct hda_verb alc662_sue_init_verbs[] = {
  11354. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
  11355. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
  11356. {}
  11357. };
  11358. static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
  11359. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  11360. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  11361. {}
  11362. };
  11363. /*
  11364. * generic initialization of ADC, input mixers and output mixers
  11365. */
  11366. static struct hda_verb alc662_auto_init_verbs[] = {
  11367. /*
  11368. * Unmute ADC and set the default input to mic-in
  11369. */
  11370. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  11371. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11372. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  11373. * mixer widget
  11374. * Note: PASD motherboards uses the Line In 2 as the input for front
  11375. * panel mic (mic 2)
  11376. */
  11377. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  11378. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11379. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11380. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  11381. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  11382. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  11383. /*
  11384. * Set up output mixers (0x0c - 0x0f)
  11385. */
  11386. /* set vol=0 to output mixers */
  11387. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11388. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11389. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11390. /* set up input amps for analog loopback */
  11391. /* Amp Indices: DAC = 0, mixer = 1 */
  11392. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11393. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11394. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11395. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11396. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11397. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11398. /* FIXME: use matrix-type input source selection */
  11399. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  11400. /* Input mixer */
  11401. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11402. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11403. { }
  11404. };
  11405. /* capture mixer elements */
  11406. static struct snd_kcontrol_new alc662_capture_mixer[] = {
  11407. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  11408. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  11409. {
  11410. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  11411. /* The multiple "Capture Source" controls confuse alsamixer
  11412. * So call somewhat different..
  11413. * FIXME: the controls appear in the "playback" view!
  11414. */
  11415. /* .name = "Capture Source", */
  11416. .name = "Input Source",
  11417. .count = 1,
  11418. .info = alc662_mux_enum_info,
  11419. .get = alc662_mux_enum_get,
  11420. .put = alc662_mux_enum_put,
  11421. },
  11422. { } /* end */
  11423. };
  11424. static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
  11425. {
  11426. unsigned int present;
  11427. unsigned char bits;
  11428. present = snd_hda_codec_read(codec, 0x14, 0,
  11429. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11430. bits = present ? HDA_AMP_MUTE : 0;
  11431. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  11432. HDA_AMP_MUTE, bits);
  11433. }
  11434. static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
  11435. {
  11436. unsigned int present;
  11437. unsigned char bits;
  11438. present = snd_hda_codec_read(codec, 0x1b, 0,
  11439. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11440. bits = present ? HDA_AMP_MUTE : 0;
  11441. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  11442. HDA_AMP_MUTE, bits);
  11443. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  11444. HDA_AMP_MUTE, bits);
  11445. }
  11446. static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
  11447. unsigned int res)
  11448. {
  11449. if ((res >> 26) == ALC880_HP_EVENT)
  11450. alc662_lenovo_101e_all_automute(codec);
  11451. if ((res >> 26) == ALC880_FRONT_EVENT)
  11452. alc662_lenovo_101e_ispeaker_automute(codec);
  11453. }
  11454. static void alc662_eeepc_mic_automute(struct hda_codec *codec)
  11455. {
  11456. unsigned int present;
  11457. present = snd_hda_codec_read(codec, 0x18, 0,
  11458. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11459. snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11460. 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
  11461. snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11462. 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
  11463. snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11464. 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
  11465. snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11466. 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
  11467. }
  11468. /* unsolicited event for HP jack sensing */
  11469. static void alc662_eeepc_unsol_event(struct hda_codec *codec,
  11470. unsigned int res)
  11471. {
  11472. if ((res >> 26) == ALC880_HP_EVENT)
  11473. alc262_hippo1_automute( codec );
  11474. if ((res >> 26) == ALC880_MIC_EVENT)
  11475. alc662_eeepc_mic_automute(codec);
  11476. }
  11477. static void alc662_eeepc_inithook(struct hda_codec *codec)
  11478. {
  11479. alc262_hippo1_automute( codec );
  11480. alc662_eeepc_mic_automute(codec);
  11481. }
  11482. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11483. #define alc662_loopbacks alc880_loopbacks
  11484. #endif
  11485. /* pcm configuration: identiacal with ALC880 */
  11486. #define alc662_pcm_analog_playback alc880_pcm_analog_playback
  11487. #define alc662_pcm_analog_capture alc880_pcm_analog_capture
  11488. #define alc662_pcm_digital_playback alc880_pcm_digital_playback
  11489. #define alc662_pcm_digital_capture alc880_pcm_digital_capture
  11490. /*
  11491. * configuration and preset
  11492. */
  11493. static const char *alc662_models[ALC662_MODEL_LAST] = {
  11494. [ALC662_3ST_2ch_DIG] = "3stack-dig",
  11495. [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
  11496. [ALC662_3ST_6ch] = "3stack-6ch",
  11497. [ALC662_5ST_DIG] = "6stack-dig",
  11498. [ALC662_LENOVO_101E] = "lenovo-101e",
  11499. [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
  11500. [ALC662_AUTO] = "auto",
  11501. };
  11502. static struct snd_pci_quirk alc662_cfg_tbl[] = {
  11503. SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
  11504. SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
  11505. {}
  11506. };
  11507. static struct alc_config_preset alc662_presets[] = {
  11508. [ALC662_3ST_2ch_DIG] = {
  11509. .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
  11510. .init_verbs = { alc662_init_verbs },
  11511. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11512. .dac_nids = alc662_dac_nids,
  11513. .dig_out_nid = ALC662_DIGOUT_NID,
  11514. .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
  11515. .adc_nids = alc662_adc_nids,
  11516. .dig_in_nid = ALC662_DIGIN_NID,
  11517. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11518. .channel_mode = alc662_3ST_2ch_modes,
  11519. .input_mux = &alc662_capture_source,
  11520. },
  11521. [ALC662_3ST_6ch_DIG] = {
  11522. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
  11523. alc662_capture_mixer },
  11524. .init_verbs = { alc662_init_verbs },
  11525. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11526. .dac_nids = alc662_dac_nids,
  11527. .dig_out_nid = ALC662_DIGOUT_NID,
  11528. .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
  11529. .adc_nids = alc662_adc_nids,
  11530. .dig_in_nid = ALC662_DIGIN_NID,
  11531. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  11532. .channel_mode = alc662_3ST_6ch_modes,
  11533. .need_dac_fix = 1,
  11534. .input_mux = &alc662_capture_source,
  11535. },
  11536. [ALC662_3ST_6ch] = {
  11537. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
  11538. alc662_capture_mixer },
  11539. .init_verbs = { alc662_init_verbs },
  11540. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11541. .dac_nids = alc662_dac_nids,
  11542. .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
  11543. .adc_nids = alc662_adc_nids,
  11544. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  11545. .channel_mode = alc662_3ST_6ch_modes,
  11546. .need_dac_fix = 1,
  11547. .input_mux = &alc662_capture_source,
  11548. },
  11549. [ALC662_5ST_DIG] = {
  11550. .mixers = { alc662_base_mixer, alc662_chmode_mixer,
  11551. alc662_capture_mixer },
  11552. .init_verbs = { alc662_init_verbs },
  11553. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11554. .dac_nids = alc662_dac_nids,
  11555. .dig_out_nid = ALC662_DIGOUT_NID,
  11556. .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
  11557. .adc_nids = alc662_adc_nids,
  11558. .dig_in_nid = ALC662_DIGIN_NID,
  11559. .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
  11560. .channel_mode = alc662_5stack_modes,
  11561. .input_mux = &alc662_capture_source,
  11562. },
  11563. [ALC662_LENOVO_101E] = {
  11564. .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
  11565. .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
  11566. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11567. .dac_nids = alc662_dac_nids,
  11568. .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
  11569. .adc_nids = alc662_adc_nids,
  11570. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11571. .channel_mode = alc662_3ST_2ch_modes,
  11572. .input_mux = &alc662_lenovo_101e_capture_source,
  11573. .unsol_event = alc662_lenovo_101e_unsol_event,
  11574. .init_hook = alc662_lenovo_101e_all_automute,
  11575. },
  11576. [ALC662_ASUS_EEEPC_P701] = {
  11577. .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
  11578. .init_verbs = { alc662_init_verbs,
  11579. alc662_eeepc_sue_init_verbs },
  11580. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11581. .dac_nids = alc662_dac_nids,
  11582. .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
  11583. .adc_nids = alc662_adc_nids,
  11584. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11585. .channel_mode = alc662_3ST_2ch_modes,
  11586. .input_mux = &alc662_eeepc_capture_source,
  11587. .unsol_event = alc662_eeepc_unsol_event,
  11588. .init_hook = alc662_eeepc_inithook,
  11589. },
  11590. };
  11591. /*
  11592. * BIOS auto configuration
  11593. */
  11594. /* add playback controls from the parsed DAC table */
  11595. static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
  11596. const struct auto_pin_cfg *cfg)
  11597. {
  11598. char name[32];
  11599. static const char *chname[4] = {
  11600. "Front", "Surround", NULL /*CLFE*/, "Side"
  11601. };
  11602. hda_nid_t nid;
  11603. int i, err;
  11604. for (i = 0; i < cfg->line_outs; i++) {
  11605. if (!spec->multiout.dac_nids[i])
  11606. continue;
  11607. nid = alc880_idx_to_dac(i);
  11608. if (i == 2) {
  11609. /* Center/LFE */
  11610. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  11611. "Center Playback Volume",
  11612. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  11613. HDA_OUTPUT));
  11614. if (err < 0)
  11615. return err;
  11616. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  11617. "LFE Playback Volume",
  11618. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  11619. HDA_OUTPUT));
  11620. if (err < 0)
  11621. return err;
  11622. err = add_control(spec, ALC_CTL_BIND_MUTE,
  11623. "Center Playback Switch",
  11624. HDA_COMPOSE_AMP_VAL(nid, 1, 2,
  11625. HDA_INPUT));
  11626. if (err < 0)
  11627. return err;
  11628. err = add_control(spec, ALC_CTL_BIND_MUTE,
  11629. "LFE Playback Switch",
  11630. HDA_COMPOSE_AMP_VAL(nid, 2, 2,
  11631. HDA_INPUT));
  11632. if (err < 0)
  11633. return err;
  11634. } else {
  11635. sprintf(name, "%s Playback Volume", chname[i]);
  11636. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  11637. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  11638. HDA_OUTPUT));
  11639. if (err < 0)
  11640. return err;
  11641. sprintf(name, "%s Playback Switch", chname[i]);
  11642. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  11643. HDA_COMPOSE_AMP_VAL(nid, 3, 2,
  11644. HDA_INPUT));
  11645. if (err < 0)
  11646. return err;
  11647. }
  11648. }
  11649. return 0;
  11650. }
  11651. /* add playback controls for speaker and HP outputs */
  11652. static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
  11653. const char *pfx)
  11654. {
  11655. hda_nid_t nid;
  11656. int err;
  11657. char name[32];
  11658. if (!pin)
  11659. return 0;
  11660. if (alc880_is_fixed_pin(pin)) {
  11661. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  11662. /* printk("DAC nid=%x\n",nid); */
  11663. /* specify the DAC as the extra output */
  11664. if (!spec->multiout.hp_nid)
  11665. spec->multiout.hp_nid = nid;
  11666. else
  11667. spec->multiout.extra_out_nid[0] = nid;
  11668. /* control HP volume/switch on the output mixer amp */
  11669. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  11670. sprintf(name, "%s Playback Volume", pfx);
  11671. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  11672. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  11673. if (err < 0)
  11674. return err;
  11675. sprintf(name, "%s Playback Switch", pfx);
  11676. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  11677. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
  11678. if (err < 0)
  11679. return err;
  11680. } else if (alc880_is_multi_pin(pin)) {
  11681. /* set manual connection */
  11682. /* we have only a switch on HP-out PIN */
  11683. sprintf(name, "%s Playback Switch", pfx);
  11684. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  11685. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  11686. if (err < 0)
  11687. return err;
  11688. }
  11689. return 0;
  11690. }
  11691. /* create playback/capture controls for input pins */
  11692. static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
  11693. const struct auto_pin_cfg *cfg)
  11694. {
  11695. struct hda_input_mux *imux = &spec->private_imux;
  11696. int i, err, idx;
  11697. for (i = 0; i < AUTO_PIN_LAST; i++) {
  11698. if (alc880_is_input_pin(cfg->input_pins[i])) {
  11699. idx = alc880_input_pin_idx(cfg->input_pins[i]);
  11700. err = new_analog_input(spec, cfg->input_pins[i],
  11701. auto_pin_cfg_labels[i],
  11702. idx, 0x0b);
  11703. if (err < 0)
  11704. return err;
  11705. imux->items[imux->num_items].label =
  11706. auto_pin_cfg_labels[i];
  11707. imux->items[imux->num_items].index =
  11708. alc880_input_pin_idx(cfg->input_pins[i]);
  11709. imux->num_items++;
  11710. }
  11711. }
  11712. return 0;
  11713. }
  11714. static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
  11715. hda_nid_t nid, int pin_type,
  11716. int dac_idx)
  11717. {
  11718. /* set as output */
  11719. snd_hda_codec_write(codec, nid, 0,
  11720. AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
  11721. snd_hda_codec_write(codec, nid, 0,
  11722. AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
  11723. /* need the manual connection? */
  11724. if (alc880_is_multi_pin(nid)) {
  11725. struct alc_spec *spec = codec->spec;
  11726. int idx = alc880_multi_pin_idx(nid);
  11727. snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
  11728. AC_VERB_SET_CONNECT_SEL,
  11729. alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
  11730. }
  11731. }
  11732. static void alc662_auto_init_multi_out(struct hda_codec *codec)
  11733. {
  11734. struct alc_spec *spec = codec->spec;
  11735. int i;
  11736. for (i = 0; i <= HDA_SIDE; i++) {
  11737. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  11738. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  11739. if (nid)
  11740. alc662_auto_set_output_and_unmute(codec, nid, pin_type,
  11741. i);
  11742. }
  11743. }
  11744. static void alc662_auto_init_hp_out(struct hda_codec *codec)
  11745. {
  11746. struct alc_spec *spec = codec->spec;
  11747. hda_nid_t pin;
  11748. pin = spec->autocfg.hp_pins[0];
  11749. if (pin) /* connect to front */
  11750. /* use dac 0 */
  11751. alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  11752. }
  11753. #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
  11754. #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
  11755. static void alc662_auto_init_analog_input(struct hda_codec *codec)
  11756. {
  11757. struct alc_spec *spec = codec->spec;
  11758. int i;
  11759. for (i = 0; i < AUTO_PIN_LAST; i++) {
  11760. hda_nid_t nid = spec->autocfg.input_pins[i];
  11761. if (alc662_is_input_pin(nid)) {
  11762. snd_hda_codec_write(codec, nid, 0,
  11763. AC_VERB_SET_PIN_WIDGET_CONTROL,
  11764. (i <= AUTO_PIN_FRONT_MIC ?
  11765. PIN_VREF80 : PIN_IN));
  11766. if (nid != ALC662_PIN_CD_NID)
  11767. snd_hda_codec_write(codec, nid, 0,
  11768. AC_VERB_SET_AMP_GAIN_MUTE,
  11769. AMP_OUT_MUTE);
  11770. }
  11771. }
  11772. }
  11773. static int alc662_parse_auto_config(struct hda_codec *codec)
  11774. {
  11775. struct alc_spec *spec = codec->spec;
  11776. int err;
  11777. static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
  11778. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  11779. alc662_ignore);
  11780. if (err < 0)
  11781. return err;
  11782. if (!spec->autocfg.line_outs)
  11783. return 0; /* can't find valid BIOS pin config */
  11784. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  11785. if (err < 0)
  11786. return err;
  11787. err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
  11788. if (err < 0)
  11789. return err;
  11790. err = alc662_auto_create_extra_out(spec,
  11791. spec->autocfg.speaker_pins[0],
  11792. "Speaker");
  11793. if (err < 0)
  11794. return err;
  11795. err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
  11796. "Headphone");
  11797. if (err < 0)
  11798. return err;
  11799. err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
  11800. if (err < 0)
  11801. return err;
  11802. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  11803. if (spec->autocfg.dig_out_pin)
  11804. spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
  11805. if (spec->kctl_alloc)
  11806. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  11807. spec->num_mux_defs = 1;
  11808. spec->input_mux = &spec->private_imux;
  11809. spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
  11810. spec->mixers[spec->num_mixers] = alc662_capture_mixer;
  11811. spec->num_mixers++;
  11812. return 1;
  11813. }
  11814. /* additional initialization for auto-configuration model */
  11815. static void alc662_auto_init(struct hda_codec *codec)
  11816. {
  11817. alc662_auto_init_multi_out(codec);
  11818. alc662_auto_init_hp_out(codec);
  11819. alc662_auto_init_analog_input(codec);
  11820. }
  11821. static int patch_alc662(struct hda_codec *codec)
  11822. {
  11823. struct alc_spec *spec;
  11824. int err, board_config;
  11825. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  11826. if (!spec)
  11827. return -ENOMEM;
  11828. codec->spec = spec;
  11829. board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
  11830. alc662_models,
  11831. alc662_cfg_tbl);
  11832. if (board_config < 0) {
  11833. printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
  11834. "trying auto-probe from BIOS...\n");
  11835. board_config = ALC662_AUTO;
  11836. }
  11837. if (board_config == ALC662_AUTO) {
  11838. /* automatic parse from the BIOS config */
  11839. err = alc662_parse_auto_config(codec);
  11840. if (err < 0) {
  11841. alc_free(codec);
  11842. return err;
  11843. } else if (!err) {
  11844. printk(KERN_INFO
  11845. "hda_codec: Cannot set up configuration "
  11846. "from BIOS. Using base mode...\n");
  11847. board_config = ALC662_3ST_2ch_DIG;
  11848. }
  11849. }
  11850. if (board_config != ALC662_AUTO)
  11851. setup_preset(spec, &alc662_presets[board_config]);
  11852. spec->stream_name_analog = "ALC662 Analog";
  11853. spec->stream_analog_playback = &alc662_pcm_analog_playback;
  11854. spec->stream_analog_capture = &alc662_pcm_analog_capture;
  11855. spec->stream_name_digital = "ALC662 Digital";
  11856. spec->stream_digital_playback = &alc662_pcm_digital_playback;
  11857. spec->stream_digital_capture = &alc662_pcm_digital_capture;
  11858. if (!spec->adc_nids && spec->input_mux) {
  11859. spec->adc_nids = alc662_adc_nids;
  11860. spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
  11861. }
  11862. codec->patch_ops = alc_patch_ops;
  11863. if (board_config == ALC662_AUTO)
  11864. spec->init_hook = alc662_auto_init;
  11865. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11866. if (!spec->loopback.amplist)
  11867. spec->loopback.amplist = alc662_loopbacks;
  11868. #endif
  11869. return 0;
  11870. }
  11871. /*
  11872. * patch entries
  11873. */
  11874. struct hda_codec_preset snd_hda_preset_realtek[] = {
  11875. { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
  11876. { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
  11877. { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
  11878. { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
  11879. { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
  11880. { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
  11881. .patch = patch_alc861 },
  11882. { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
  11883. { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
  11884. { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
  11885. { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
  11886. .patch = patch_alc883 },
  11887. { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
  11888. .patch = patch_alc662 },
  11889. { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
  11890. { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
  11891. { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
  11892. { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
  11893. { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
  11894. { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
  11895. {} /* terminator */
  11896. };