patch_realtek.c 451 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679
  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 <linux/init.h>
  26. #include <linux/delay.h>
  27. #include <linux/slab.h>
  28. #include <linux/pci.h>
  29. #include <sound/core.h>
  30. #include "hda_codec.h"
  31. #include "hda_local.h"
  32. #define ALC880_FRONT_EVENT 0x01
  33. #define ALC880_DCVOL_EVENT 0x02
  34. #define ALC880_HP_EVENT 0x04
  35. #define ALC880_MIC_EVENT 0x08
  36. /* ALC880 board config type */
  37. enum {
  38. ALC880_3ST,
  39. ALC880_3ST_DIG,
  40. ALC880_5ST,
  41. ALC880_5ST_DIG,
  42. ALC880_W810,
  43. ALC880_Z71V,
  44. ALC880_6ST,
  45. ALC880_6ST_DIG,
  46. ALC880_F1734,
  47. ALC880_ASUS,
  48. ALC880_ASUS_DIG,
  49. ALC880_ASUS_W1V,
  50. ALC880_ASUS_DIG2,
  51. ALC880_FUJITSU,
  52. ALC880_UNIWILL_DIG,
  53. ALC880_UNIWILL,
  54. ALC880_UNIWILL_P53,
  55. ALC880_CLEVO,
  56. ALC880_TCL_S700,
  57. ALC880_LG,
  58. ALC880_LG_LW,
  59. #ifdef CONFIG_SND_DEBUG
  60. ALC880_TEST,
  61. #endif
  62. ALC880_AUTO,
  63. ALC880_MODEL_LAST /* last tag */
  64. };
  65. /* ALC260 models */
  66. enum {
  67. ALC260_BASIC,
  68. ALC260_HP,
  69. ALC260_HP_3013,
  70. ALC260_FUJITSU_S702X,
  71. ALC260_ACER,
  72. ALC260_WILL,
  73. ALC260_REPLACER_672V,
  74. #ifdef CONFIG_SND_DEBUG
  75. ALC260_TEST,
  76. #endif
  77. ALC260_AUTO,
  78. ALC260_MODEL_LAST /* last tag */
  79. };
  80. /* ALC262 models */
  81. enum {
  82. ALC262_BASIC,
  83. ALC262_HIPPO,
  84. ALC262_HIPPO_1,
  85. ALC262_FUJITSU,
  86. ALC262_HP_BPC,
  87. ALC262_HP_BPC_D7000_WL,
  88. ALC262_HP_BPC_D7000_WF,
  89. ALC262_HP_TC_T5735,
  90. ALC262_HP_RP5700,
  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. ALC268_DELL,
  104. ALC268_ZEPTO,
  105. #ifdef CONFIG_SND_DEBUG
  106. ALC268_TEST,
  107. #endif
  108. ALC268_AUTO,
  109. ALC268_MODEL_LAST /* last tag */
  110. };
  111. /* ALC269 models */
  112. enum {
  113. ALC269_BASIC,
  114. ALC269_AUTO,
  115. ALC269_MODEL_LAST /* last tag */
  116. };
  117. /* ALC861 models */
  118. enum {
  119. ALC861_3ST,
  120. ALC660_3ST,
  121. ALC861_3ST_DIG,
  122. ALC861_6ST_DIG,
  123. ALC861_UNIWILL_M31,
  124. ALC861_TOSHIBA,
  125. ALC861_ASUS,
  126. ALC861_ASUS_LAPTOP,
  127. ALC861_AUTO,
  128. ALC861_MODEL_LAST,
  129. };
  130. /* ALC861-VD models */
  131. enum {
  132. ALC660VD_3ST,
  133. ALC660VD_3ST_DIG,
  134. ALC861VD_3ST,
  135. ALC861VD_3ST_DIG,
  136. ALC861VD_6ST_DIG,
  137. ALC861VD_LENOVO,
  138. ALC861VD_DALLAS,
  139. ALC861VD_HP,
  140. ALC861VD_AUTO,
  141. ALC861VD_MODEL_LAST,
  142. };
  143. /* ALC662 models */
  144. enum {
  145. ALC662_3ST_2ch_DIG,
  146. ALC662_3ST_6ch_DIG,
  147. ALC662_3ST_6ch,
  148. ALC662_5ST_DIG,
  149. ALC662_LENOVO_101E,
  150. ALC662_ASUS_EEEPC_P701,
  151. ALC662_ASUS_EEEPC_EP20,
  152. ALC662_AUTO,
  153. ALC662_MODEL_LAST,
  154. };
  155. /* ALC882 models */
  156. enum {
  157. ALC882_3ST_DIG,
  158. ALC882_6ST_DIG,
  159. ALC882_ARIMA,
  160. ALC882_W2JC,
  161. ALC882_TARGA,
  162. ALC882_ASUS_A7J,
  163. ALC882_ASUS_A7M,
  164. ALC885_MACPRO,
  165. ALC885_MBP3,
  166. ALC885_IMAC24,
  167. ALC882_AUTO,
  168. ALC882_MODEL_LAST,
  169. };
  170. /* ALC883 models */
  171. enum {
  172. ALC883_3ST_2ch_DIG,
  173. ALC883_3ST_6ch_DIG,
  174. ALC883_3ST_6ch,
  175. ALC883_6ST_DIG,
  176. ALC883_TARGA_DIG,
  177. ALC883_TARGA_2ch_DIG,
  178. ALC883_ACER,
  179. ALC883_ACER_ASPIRE,
  180. ALC883_MEDION,
  181. ALC883_MEDION_MD2,
  182. ALC883_LAPTOP_EAPD,
  183. ALC883_LENOVO_101E_2ch,
  184. ALC883_LENOVO_NB0763,
  185. ALC888_LENOVO_MS7195_DIG,
  186. ALC883_HAIER_W66,
  187. ALC888_6ST_HP,
  188. ALC888_3ST_HP,
  189. ALC888_6ST_DELL,
  190. ALC883_MITAC,
  191. ALC883_AUTO,
  192. ALC883_MODEL_LAST,
  193. };
  194. /* for GPIO Poll */
  195. #define GPIO_MASK 0x03
  196. struct alc_spec {
  197. /* codec parameterization */
  198. struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
  199. unsigned int num_mixers;
  200. const struct hda_verb *init_verbs[5]; /* initialization verbs
  201. * don't forget NULL
  202. * termination!
  203. */
  204. unsigned int num_init_verbs;
  205. char *stream_name_analog; /* analog PCM stream */
  206. struct hda_pcm_stream *stream_analog_playback;
  207. struct hda_pcm_stream *stream_analog_capture;
  208. struct hda_pcm_stream *stream_analog_alt_playback;
  209. struct hda_pcm_stream *stream_analog_alt_capture;
  210. char *stream_name_digital; /* digital PCM stream */
  211. struct hda_pcm_stream *stream_digital_playback;
  212. struct hda_pcm_stream *stream_digital_capture;
  213. /* playback */
  214. struct hda_multi_out multiout; /* playback set-up
  215. * max_channels, dacs must be set
  216. * dig_out_nid and hp_nid are optional
  217. */
  218. hda_nid_t alt_dac_nid;
  219. /* capture */
  220. unsigned int num_adc_nids;
  221. hda_nid_t *adc_nids;
  222. hda_nid_t *capsrc_nids;
  223. hda_nid_t dig_in_nid; /* digital-in NID; optional */
  224. /* capture source */
  225. unsigned int num_mux_defs;
  226. const struct hda_input_mux *input_mux;
  227. unsigned int cur_mux[3];
  228. /* channel model */
  229. const struct hda_channel_mode *channel_mode;
  230. int num_channel_mode;
  231. int need_dac_fix;
  232. /* PCM information */
  233. struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
  234. /* dynamic controls, init_verbs and input_mux */
  235. struct auto_pin_cfg autocfg;
  236. unsigned int num_kctl_alloc, num_kctl_used;
  237. struct snd_kcontrol_new *kctl_alloc;
  238. struct hda_input_mux private_imux;
  239. hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  240. /* hooks */
  241. void (*init_hook)(struct hda_codec *codec);
  242. void (*unsol_event)(struct hda_codec *codec, unsigned int res);
  243. /* for pin sensing */
  244. unsigned int sense_updated: 1;
  245. unsigned int jack_present: 1;
  246. unsigned int master_sw: 1;
  247. /* for virtual master */
  248. hda_nid_t vmaster_nid;
  249. u32 vmaster_tlv[4];
  250. #ifdef CONFIG_SND_HDA_POWER_SAVE
  251. struct hda_loopback_check loopback;
  252. #endif
  253. };
  254. /*
  255. * configuration template - to be copied to the spec instance
  256. */
  257. struct alc_config_preset {
  258. struct snd_kcontrol_new *mixers[5]; /* should be identical size
  259. * with spec
  260. */
  261. const struct hda_verb *init_verbs[5];
  262. unsigned int num_dacs;
  263. hda_nid_t *dac_nids;
  264. hda_nid_t dig_out_nid; /* optional */
  265. hda_nid_t hp_nid; /* optional */
  266. unsigned int num_adc_nids;
  267. hda_nid_t *adc_nids;
  268. hda_nid_t *capsrc_nids;
  269. hda_nid_t dig_in_nid;
  270. unsigned int num_channel_mode;
  271. const struct hda_channel_mode *channel_mode;
  272. int need_dac_fix;
  273. unsigned int num_mux_defs;
  274. const struct hda_input_mux *input_mux;
  275. void (*unsol_event)(struct hda_codec *, unsigned int);
  276. void (*init_hook)(struct hda_codec *);
  277. #ifdef CONFIG_SND_HDA_POWER_SAVE
  278. struct hda_amp_list *loopbacks;
  279. #endif
  280. };
  281. /*
  282. * input MUX handling
  283. */
  284. static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
  285. struct snd_ctl_elem_info *uinfo)
  286. {
  287. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  288. struct alc_spec *spec = codec->spec;
  289. unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
  290. if (mux_idx >= spec->num_mux_defs)
  291. mux_idx = 0;
  292. return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
  293. }
  294. static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
  295. struct snd_ctl_elem_value *ucontrol)
  296. {
  297. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  298. struct alc_spec *spec = codec->spec;
  299. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  300. ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  301. return 0;
  302. }
  303. static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
  304. struct snd_ctl_elem_value *ucontrol)
  305. {
  306. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  307. struct alc_spec *spec = codec->spec;
  308. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  309. unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
  310. hda_nid_t nid = spec->capsrc_nids ?
  311. spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
  312. return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
  313. nid, &spec->cur_mux[adc_idx]);
  314. }
  315. /*
  316. * channel mode setting
  317. */
  318. static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
  319. struct snd_ctl_elem_info *uinfo)
  320. {
  321. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  322. struct alc_spec *spec = codec->spec;
  323. return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
  324. spec->num_channel_mode);
  325. }
  326. static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
  327. struct snd_ctl_elem_value *ucontrol)
  328. {
  329. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  330. struct alc_spec *spec = codec->spec;
  331. return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
  332. spec->num_channel_mode,
  333. spec->multiout.max_channels);
  334. }
  335. static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
  336. struct snd_ctl_elem_value *ucontrol)
  337. {
  338. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  339. struct alc_spec *spec = codec->spec;
  340. int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
  341. spec->num_channel_mode,
  342. &spec->multiout.max_channels);
  343. if (err >= 0 && spec->need_dac_fix)
  344. spec->multiout.num_dacs = spec->multiout.max_channels / 2;
  345. return err;
  346. }
  347. /*
  348. * Control the mode of pin widget settings via the mixer. "pc" is used
  349. * instead of "%" to avoid consequences of accidently treating the % as
  350. * being part of a format specifier. Maximum allowed length of a value is
  351. * 63 characters plus NULL terminator.
  352. *
  353. * Note: some retasking pin complexes seem to ignore requests for input
  354. * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
  355. * are requested. Therefore order this list so that this behaviour will not
  356. * cause problems when mixer clients move through the enum sequentially.
  357. * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
  358. * March 2006.
  359. */
  360. static char *alc_pin_mode_names[] = {
  361. "Mic 50pc bias", "Mic 80pc bias",
  362. "Line in", "Line out", "Headphone out",
  363. };
  364. static unsigned char alc_pin_mode_values[] = {
  365. PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
  366. };
  367. /* The control can present all 5 options, or it can limit the options based
  368. * in the pin being assumed to be exclusively an input or an output pin. In
  369. * addition, "input" pins may or may not process the mic bias option
  370. * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
  371. * accept requests for bias as of chip versions up to March 2006) and/or
  372. * wiring in the computer.
  373. */
  374. #define ALC_PIN_DIR_IN 0x00
  375. #define ALC_PIN_DIR_OUT 0x01
  376. #define ALC_PIN_DIR_INOUT 0x02
  377. #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
  378. #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
  379. /* Info about the pin modes supported by the different pin direction modes.
  380. * For each direction the minimum and maximum values are given.
  381. */
  382. static signed char alc_pin_mode_dir_info[5][2] = {
  383. { 0, 2 }, /* ALC_PIN_DIR_IN */
  384. { 3, 4 }, /* ALC_PIN_DIR_OUT */
  385. { 0, 4 }, /* ALC_PIN_DIR_INOUT */
  386. { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
  387. { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
  388. };
  389. #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
  390. #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
  391. #define alc_pin_mode_n_items(_dir) \
  392. (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
  393. static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
  394. struct snd_ctl_elem_info *uinfo)
  395. {
  396. unsigned int item_num = uinfo->value.enumerated.item;
  397. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  398. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  399. uinfo->count = 1;
  400. uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
  401. if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
  402. item_num = alc_pin_mode_min(dir);
  403. strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
  404. return 0;
  405. }
  406. static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
  407. struct snd_ctl_elem_value *ucontrol)
  408. {
  409. unsigned int i;
  410. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  411. hda_nid_t nid = kcontrol->private_value & 0xffff;
  412. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  413. long *valp = ucontrol->value.integer.value;
  414. unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  415. AC_VERB_GET_PIN_WIDGET_CONTROL,
  416. 0x00);
  417. /* Find enumerated value for current pinctl setting */
  418. i = alc_pin_mode_min(dir);
  419. while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
  420. i++;
  421. *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
  422. return 0;
  423. }
  424. static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
  425. struct snd_ctl_elem_value *ucontrol)
  426. {
  427. signed int change;
  428. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  429. hda_nid_t nid = kcontrol->private_value & 0xffff;
  430. unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  431. long val = *ucontrol->value.integer.value;
  432. unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  433. AC_VERB_GET_PIN_WIDGET_CONTROL,
  434. 0x00);
  435. if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
  436. val = alc_pin_mode_min(dir);
  437. change = pinctl != alc_pin_mode_values[val];
  438. if (change) {
  439. /* Set pin mode to that requested */
  440. snd_hda_codec_write_cache(codec, nid, 0,
  441. AC_VERB_SET_PIN_WIDGET_CONTROL,
  442. alc_pin_mode_values[val]);
  443. /* Also enable the retasking pin's input/output as required
  444. * for the requested pin mode. Enum values of 2 or less are
  445. * input modes.
  446. *
  447. * Dynamically switching the input/output buffers probably
  448. * reduces noise slightly (particularly on input) so we'll
  449. * do it. However, having both input and output buffers
  450. * enabled simultaneously doesn't seem to be problematic if
  451. * this turns out to be necessary in the future.
  452. */
  453. if (val <= 2) {
  454. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  455. HDA_AMP_MUTE, HDA_AMP_MUTE);
  456. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  457. HDA_AMP_MUTE, 0);
  458. } else {
  459. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  460. HDA_AMP_MUTE, HDA_AMP_MUTE);
  461. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  462. HDA_AMP_MUTE, 0);
  463. }
  464. }
  465. return change;
  466. }
  467. #define ALC_PIN_MODE(xname, nid, dir) \
  468. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  469. .info = alc_pin_mode_info, \
  470. .get = alc_pin_mode_get, \
  471. .put = alc_pin_mode_put, \
  472. .private_value = nid | (dir<<16) }
  473. /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
  474. * together using a mask with more than one bit set. This control is
  475. * currently used only by the ALC260 test model. At this stage they are not
  476. * needed for any "production" models.
  477. */
  478. #ifdef CONFIG_SND_DEBUG
  479. #define alc_gpio_data_info snd_ctl_boolean_mono_info
  480. static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
  481. struct snd_ctl_elem_value *ucontrol)
  482. {
  483. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  484. hda_nid_t nid = kcontrol->private_value & 0xffff;
  485. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  486. long *valp = ucontrol->value.integer.value;
  487. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  488. AC_VERB_GET_GPIO_DATA, 0x00);
  489. *valp = (val & mask) != 0;
  490. return 0;
  491. }
  492. static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
  493. struct snd_ctl_elem_value *ucontrol)
  494. {
  495. signed int change;
  496. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  497. hda_nid_t nid = kcontrol->private_value & 0xffff;
  498. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  499. long val = *ucontrol->value.integer.value;
  500. unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
  501. AC_VERB_GET_GPIO_DATA,
  502. 0x00);
  503. /* Set/unset the masked GPIO bit(s) as needed */
  504. change = (val == 0 ? 0 : mask) != (gpio_data & mask);
  505. if (val == 0)
  506. gpio_data &= ~mask;
  507. else
  508. gpio_data |= mask;
  509. snd_hda_codec_write_cache(codec, nid, 0,
  510. AC_VERB_SET_GPIO_DATA, gpio_data);
  511. return change;
  512. }
  513. #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
  514. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  515. .info = alc_gpio_data_info, \
  516. .get = alc_gpio_data_get, \
  517. .put = alc_gpio_data_put, \
  518. .private_value = nid | (mask<<16) }
  519. #endif /* CONFIG_SND_DEBUG */
  520. /* A switch control to allow the enabling of the digital IO pins on the
  521. * ALC260. This is incredibly simplistic; the intention of this control is
  522. * to provide something in the test model allowing digital outputs to be
  523. * identified if present. If models are found which can utilise these
  524. * outputs a more complete mixer control can be devised for those models if
  525. * necessary.
  526. */
  527. #ifdef CONFIG_SND_DEBUG
  528. #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
  529. static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
  530. struct snd_ctl_elem_value *ucontrol)
  531. {
  532. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  533. hda_nid_t nid = kcontrol->private_value & 0xffff;
  534. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  535. long *valp = ucontrol->value.integer.value;
  536. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  537. AC_VERB_GET_DIGI_CONVERT_1, 0x00);
  538. *valp = (val & mask) != 0;
  539. return 0;
  540. }
  541. static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
  542. struct snd_ctl_elem_value *ucontrol)
  543. {
  544. signed int change;
  545. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  546. hda_nid_t nid = kcontrol->private_value & 0xffff;
  547. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  548. long val = *ucontrol->value.integer.value;
  549. unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  550. AC_VERB_GET_DIGI_CONVERT_1,
  551. 0x00);
  552. /* Set/unset the masked control bit(s) as needed */
  553. change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
  554. if (val==0)
  555. ctrl_data &= ~mask;
  556. else
  557. ctrl_data |= mask;
  558. snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
  559. ctrl_data);
  560. return change;
  561. }
  562. #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
  563. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  564. .info = alc_spdif_ctrl_info, \
  565. .get = alc_spdif_ctrl_get, \
  566. .put = alc_spdif_ctrl_put, \
  567. .private_value = nid | (mask<<16) }
  568. #endif /* CONFIG_SND_DEBUG */
  569. /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
  570. * Again, this is only used in the ALC26x test models to help identify when
  571. * the EAPD line must be asserted for features to work.
  572. */
  573. #ifdef CONFIG_SND_DEBUG
  574. #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
  575. static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
  576. struct snd_ctl_elem_value *ucontrol)
  577. {
  578. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  579. hda_nid_t nid = kcontrol->private_value & 0xffff;
  580. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  581. long *valp = ucontrol->value.integer.value;
  582. unsigned int val = snd_hda_codec_read(codec, nid, 0,
  583. AC_VERB_GET_EAPD_BTLENABLE, 0x00);
  584. *valp = (val & mask) != 0;
  585. return 0;
  586. }
  587. static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
  588. struct snd_ctl_elem_value *ucontrol)
  589. {
  590. int change;
  591. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  592. hda_nid_t nid = kcontrol->private_value & 0xffff;
  593. unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  594. long val = *ucontrol->value.integer.value;
  595. unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  596. AC_VERB_GET_EAPD_BTLENABLE,
  597. 0x00);
  598. /* Set/unset the masked control bit(s) as needed */
  599. change = (!val ? 0 : mask) != (ctrl_data & mask);
  600. if (!val)
  601. ctrl_data &= ~mask;
  602. else
  603. ctrl_data |= mask;
  604. snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
  605. ctrl_data);
  606. return change;
  607. }
  608. #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
  609. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  610. .info = alc_eapd_ctrl_info, \
  611. .get = alc_eapd_ctrl_get, \
  612. .put = alc_eapd_ctrl_put, \
  613. .private_value = nid | (mask<<16) }
  614. #endif /* CONFIG_SND_DEBUG */
  615. /*
  616. * set up from the preset table
  617. */
  618. static void setup_preset(struct alc_spec *spec,
  619. const struct alc_config_preset *preset)
  620. {
  621. int i;
  622. for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
  623. spec->mixers[spec->num_mixers++] = preset->mixers[i];
  624. for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
  625. i++)
  626. spec->init_verbs[spec->num_init_verbs++] =
  627. preset->init_verbs[i];
  628. spec->channel_mode = preset->channel_mode;
  629. spec->num_channel_mode = preset->num_channel_mode;
  630. spec->need_dac_fix = preset->need_dac_fix;
  631. spec->multiout.max_channels = spec->channel_mode[0].channels;
  632. spec->multiout.num_dacs = preset->num_dacs;
  633. spec->multiout.dac_nids = preset->dac_nids;
  634. spec->multiout.dig_out_nid = preset->dig_out_nid;
  635. spec->multiout.hp_nid = preset->hp_nid;
  636. spec->num_mux_defs = preset->num_mux_defs;
  637. if (!spec->num_mux_defs)
  638. spec->num_mux_defs = 1;
  639. spec->input_mux = preset->input_mux;
  640. spec->num_adc_nids = preset->num_adc_nids;
  641. spec->adc_nids = preset->adc_nids;
  642. spec->capsrc_nids = preset->capsrc_nids;
  643. spec->dig_in_nid = preset->dig_in_nid;
  644. spec->unsol_event = preset->unsol_event;
  645. spec->init_hook = preset->init_hook;
  646. #ifdef CONFIG_SND_HDA_POWER_SAVE
  647. spec->loopback.amplist = preset->loopbacks;
  648. #endif
  649. }
  650. /* Enable GPIO mask and set output */
  651. static struct hda_verb alc_gpio1_init_verbs[] = {
  652. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  653. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  654. {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
  655. { }
  656. };
  657. static struct hda_verb alc_gpio2_init_verbs[] = {
  658. {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
  659. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
  660. {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
  661. { }
  662. };
  663. static struct hda_verb alc_gpio3_init_verbs[] = {
  664. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  665. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  666. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  667. { }
  668. };
  669. static void alc_sku_automute(struct hda_codec *codec)
  670. {
  671. struct alc_spec *spec = codec->spec;
  672. unsigned int present;
  673. unsigned int hp_nid = spec->autocfg.hp_pins[0];
  674. unsigned int sp_nid = spec->autocfg.speaker_pins[0];
  675. /* need to execute and sync at first */
  676. snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
  677. present = snd_hda_codec_read(codec, hp_nid, 0,
  678. AC_VERB_GET_PIN_SENSE, 0);
  679. spec->jack_present = (present & 0x80000000) != 0;
  680. snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  681. spec->jack_present ? 0 : PIN_OUT);
  682. }
  683. /* unsolicited event for HP jack sensing */
  684. static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
  685. {
  686. if (codec->vendor_id == 0x10ec0880)
  687. res >>= 28;
  688. else
  689. res >>= 26;
  690. if (res != ALC880_HP_EVENT)
  691. return;
  692. alc_sku_automute(codec);
  693. }
  694. /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
  695. * 31 ~ 16 : Manufacture ID
  696. * 15 ~ 8 : SKU ID
  697. * 7 ~ 0 : Assembly ID
  698. * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
  699. */
  700. static void alc_subsystem_id(struct hda_codec *codec,
  701. unsigned int porta, unsigned int porte,
  702. unsigned int portd)
  703. {
  704. unsigned int ass, tmp, i;
  705. unsigned nid;
  706. struct alc_spec *spec = codec->spec;
  707. ass = codec->subsystem_id & 0xffff;
  708. if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
  709. goto do_sku;
  710. /*
  711. * 31~30 : port conetcivity
  712. * 29~21 : reserve
  713. * 20 : PCBEEP input
  714. * 19~16 : Check sum (15:1)
  715. * 15~1 : Custom
  716. * 0 : override
  717. */
  718. nid = 0x1d;
  719. if (codec->vendor_id == 0x10ec0260)
  720. nid = 0x17;
  721. ass = snd_hda_codec_read(codec, nid, 0,
  722. AC_VERB_GET_CONFIG_DEFAULT, 0);
  723. if (!(ass & 1) && !(ass & 0x100000))
  724. return;
  725. if ((ass >> 30) != 1) /* no physical connection */
  726. return;
  727. /* check sum */
  728. tmp = 0;
  729. for (i = 1; i < 16; i++) {
  730. if ((ass >> i) & 1)
  731. tmp++;
  732. }
  733. if (((ass >> 16) & 0xf) != tmp)
  734. return;
  735. do_sku:
  736. /*
  737. * 0 : override
  738. * 1 : Swap Jack
  739. * 2 : 0 --> Desktop, 1 --> Laptop
  740. * 3~5 : External Amplifier control
  741. * 7~6 : Reserved
  742. */
  743. tmp = (ass & 0x38) >> 3; /* external Amp control */
  744. switch (tmp) {
  745. case 1:
  746. snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
  747. break;
  748. case 3:
  749. snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
  750. break;
  751. case 7:
  752. snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
  753. break;
  754. case 5: /* set EAPD output high */
  755. switch (codec->vendor_id) {
  756. case 0x10ec0260:
  757. snd_hda_codec_write(codec, 0x0f, 0,
  758. AC_VERB_SET_EAPD_BTLENABLE, 2);
  759. snd_hda_codec_write(codec, 0x10, 0,
  760. AC_VERB_SET_EAPD_BTLENABLE, 2);
  761. break;
  762. case 0x10ec0262:
  763. case 0x10ec0267:
  764. case 0x10ec0268:
  765. case 0x10ec0269:
  766. case 0x10ec0862:
  767. case 0x10ec0662:
  768. snd_hda_codec_write(codec, 0x14, 0,
  769. AC_VERB_SET_EAPD_BTLENABLE, 2);
  770. snd_hda_codec_write(codec, 0x15, 0,
  771. AC_VERB_SET_EAPD_BTLENABLE, 2);
  772. break;
  773. }
  774. switch (codec->vendor_id) {
  775. case 0x10ec0260:
  776. snd_hda_codec_write(codec, 0x1a, 0,
  777. AC_VERB_SET_COEF_INDEX, 7);
  778. tmp = snd_hda_codec_read(codec, 0x1a, 0,
  779. AC_VERB_GET_PROC_COEF, 0);
  780. snd_hda_codec_write(codec, 0x1a, 0,
  781. AC_VERB_SET_COEF_INDEX, 7);
  782. snd_hda_codec_write(codec, 0x1a, 0,
  783. AC_VERB_SET_PROC_COEF,
  784. tmp | 0x2010);
  785. break;
  786. case 0x10ec0262:
  787. case 0x10ec0880:
  788. case 0x10ec0882:
  789. case 0x10ec0883:
  790. case 0x10ec0885:
  791. case 0x10ec0888:
  792. snd_hda_codec_write(codec, 0x20, 0,
  793. AC_VERB_SET_COEF_INDEX, 7);
  794. tmp = snd_hda_codec_read(codec, 0x20, 0,
  795. AC_VERB_GET_PROC_COEF, 0);
  796. snd_hda_codec_write(codec, 0x20, 0,
  797. AC_VERB_SET_COEF_INDEX, 7);
  798. snd_hda_codec_write(codec, 0x20, 0,
  799. AC_VERB_SET_PROC_COEF,
  800. tmp | 0x2010);
  801. break;
  802. case 0x10ec0267:
  803. case 0x10ec0268:
  804. snd_hda_codec_write(codec, 0x20, 0,
  805. AC_VERB_SET_COEF_INDEX, 7);
  806. tmp = snd_hda_codec_read(codec, 0x20, 0,
  807. AC_VERB_GET_PROC_COEF, 0);
  808. snd_hda_codec_write(codec, 0x20, 0,
  809. AC_VERB_SET_COEF_INDEX, 7);
  810. snd_hda_codec_write(codec, 0x20, 0,
  811. AC_VERB_SET_PROC_COEF,
  812. tmp | 0x3000);
  813. break;
  814. }
  815. default:
  816. break;
  817. }
  818. /* is laptop or Desktop and enable the function "Mute internal speaker
  819. * when the external headphone out jack is plugged"
  820. */
  821. if (!(ass & 0x8000))
  822. return;
  823. /*
  824. * 10~8 : Jack location
  825. * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
  826. * 14~13: Resvered
  827. * 15 : 1 --> enable the function "Mute internal speaker
  828. * when the external headphone out jack is plugged"
  829. */
  830. if (!spec->autocfg.speaker_pins[0]) {
  831. if (spec->autocfg.line_out_pins[0])
  832. spec->autocfg.speaker_pins[0] =
  833. spec->autocfg.line_out_pins[0];
  834. else
  835. return;
  836. }
  837. if (!spec->autocfg.hp_pins[0]) {
  838. tmp = (ass >> 11) & 0x3; /* HP to chassis */
  839. if (tmp == 0)
  840. spec->autocfg.hp_pins[0] = porta;
  841. else if (tmp == 1)
  842. spec->autocfg.hp_pins[0] = porte;
  843. else if (tmp == 2)
  844. spec->autocfg.hp_pins[0] = portd;
  845. else
  846. return;
  847. }
  848. snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
  849. AC_VERB_SET_UNSOLICITED_ENABLE,
  850. AC_USRSP_EN | ALC880_HP_EVENT);
  851. spec->unsol_event = alc_sku_unsol_event;
  852. spec->init_hook = alc_sku_automute;
  853. }
  854. /*
  855. * Fix-up pin default configurations
  856. */
  857. struct alc_pincfg {
  858. hda_nid_t nid;
  859. u32 val;
  860. };
  861. static void alc_fix_pincfg(struct hda_codec *codec,
  862. const struct snd_pci_quirk *quirk,
  863. const struct alc_pincfg **pinfix)
  864. {
  865. const struct alc_pincfg *cfg;
  866. quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
  867. if (!quirk)
  868. return;
  869. cfg = pinfix[quirk->value];
  870. for (; cfg->nid; cfg++) {
  871. int i;
  872. u32 val = cfg->val;
  873. for (i = 0; i < 4; i++) {
  874. snd_hda_codec_write(codec, cfg->nid, 0,
  875. AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
  876. val & 0xff);
  877. val >>= 8;
  878. }
  879. }
  880. }
  881. /*
  882. * ALC880 3-stack model
  883. *
  884. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
  885. * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
  886. * F-Mic = 0x1b, HP = 0x19
  887. */
  888. static hda_nid_t alc880_dac_nids[4] = {
  889. /* front, rear, clfe, rear_surr */
  890. 0x02, 0x05, 0x04, 0x03
  891. };
  892. static hda_nid_t alc880_adc_nids[3] = {
  893. /* ADC0-2 */
  894. 0x07, 0x08, 0x09,
  895. };
  896. /* The datasheet says the node 0x07 is connected from inputs,
  897. * but it shows zero connection in the real implementation on some devices.
  898. * Note: this is a 915GAV bug, fixed on 915GLV
  899. */
  900. static hda_nid_t alc880_adc_nids_alt[2] = {
  901. /* ADC1-2 */
  902. 0x08, 0x09,
  903. };
  904. #define ALC880_DIGOUT_NID 0x06
  905. #define ALC880_DIGIN_NID 0x0a
  906. static struct hda_input_mux alc880_capture_source = {
  907. .num_items = 4,
  908. .items = {
  909. { "Mic", 0x0 },
  910. { "Front Mic", 0x3 },
  911. { "Line", 0x2 },
  912. { "CD", 0x4 },
  913. },
  914. };
  915. /* channel source setting (2/6 channel selection for 3-stack) */
  916. /* 2ch mode */
  917. static struct hda_verb alc880_threestack_ch2_init[] = {
  918. /* set line-in to input, mute it */
  919. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  920. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  921. /* set mic-in to input vref 80%, mute it */
  922. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  923. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  924. { } /* end */
  925. };
  926. /* 6ch mode */
  927. static struct hda_verb alc880_threestack_ch6_init[] = {
  928. /* set line-in to output, unmute it */
  929. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  930. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  931. /* set mic-in to output, unmute it */
  932. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  933. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  934. { } /* end */
  935. };
  936. static struct hda_channel_mode alc880_threestack_modes[2] = {
  937. { 2, alc880_threestack_ch2_init },
  938. { 6, alc880_threestack_ch6_init },
  939. };
  940. static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
  941. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  942. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  943. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  944. HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
  945. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  946. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  947. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  948. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  949. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  950. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  951. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  952. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  953. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  954. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  955. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
  956. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
  957. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  958. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  959. HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
  960. {
  961. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  962. .name = "Channel Mode",
  963. .info = alc_ch_mode_info,
  964. .get = alc_ch_mode_get,
  965. .put = alc_ch_mode_put,
  966. },
  967. { } /* end */
  968. };
  969. /* capture mixer elements */
  970. static struct snd_kcontrol_new alc880_capture_mixer[] = {
  971. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  972. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  973. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
  974. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
  975. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
  976. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
  977. {
  978. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  979. /* The multiple "Capture Source" controls confuse alsamixer
  980. * So call somewhat different..
  981. */
  982. /* .name = "Capture Source", */
  983. .name = "Input Source",
  984. .count = 3,
  985. .info = alc_mux_enum_info,
  986. .get = alc_mux_enum_get,
  987. .put = alc_mux_enum_put,
  988. },
  989. { } /* end */
  990. };
  991. /* capture mixer elements (in case NID 0x07 not available) */
  992. static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
  993. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  994. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  995. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  996. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  997. {
  998. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  999. /* The multiple "Capture Source" controls confuse alsamixer
  1000. * So call somewhat different..
  1001. */
  1002. /* .name = "Capture Source", */
  1003. .name = "Input Source",
  1004. .count = 2,
  1005. .info = alc_mux_enum_info,
  1006. .get = alc_mux_enum_get,
  1007. .put = alc_mux_enum_put,
  1008. },
  1009. { } /* end */
  1010. };
  1011. /*
  1012. * ALC880 5-stack model
  1013. *
  1014. * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
  1015. * Side = 0x02 (0xd)
  1016. * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
  1017. * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
  1018. */
  1019. /* additional mixers to alc880_three_stack_mixer */
  1020. static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
  1021. HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1022. HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
  1023. { } /* end */
  1024. };
  1025. /* channel source setting (6/8 channel selection for 5-stack) */
  1026. /* 6ch mode */
  1027. static struct hda_verb alc880_fivestack_ch6_init[] = {
  1028. /* set line-in to input, mute it */
  1029. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  1030. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  1031. { } /* end */
  1032. };
  1033. /* 8ch mode */
  1034. static struct hda_verb alc880_fivestack_ch8_init[] = {
  1035. /* set line-in to output, unmute it */
  1036. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  1037. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  1038. { } /* end */
  1039. };
  1040. static struct hda_channel_mode alc880_fivestack_modes[2] = {
  1041. { 6, alc880_fivestack_ch6_init },
  1042. { 8, alc880_fivestack_ch8_init },
  1043. };
  1044. /*
  1045. * ALC880 6-stack model
  1046. *
  1047. * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
  1048. * Side = 0x05 (0x0f)
  1049. * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
  1050. * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
  1051. */
  1052. static hda_nid_t alc880_6st_dac_nids[4] = {
  1053. /* front, rear, clfe, rear_surr */
  1054. 0x02, 0x03, 0x04, 0x05
  1055. };
  1056. static struct hda_input_mux alc880_6stack_capture_source = {
  1057. .num_items = 4,
  1058. .items = {
  1059. { "Mic", 0x0 },
  1060. { "Front Mic", 0x1 },
  1061. { "Line", 0x2 },
  1062. { "CD", 0x4 },
  1063. },
  1064. };
  1065. /* fixed 8-channels */
  1066. static struct hda_channel_mode alc880_sixstack_modes[1] = {
  1067. { 8, NULL },
  1068. };
  1069. static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
  1070. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1071. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1072. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1073. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1074. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1075. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1076. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1077. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1078. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1079. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  1080. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1081. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1082. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1083. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1084. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1085. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1086. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1087. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1088. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1089. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1090. {
  1091. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1092. .name = "Channel Mode",
  1093. .info = alc_ch_mode_info,
  1094. .get = alc_ch_mode_get,
  1095. .put = alc_ch_mode_put,
  1096. },
  1097. { } /* end */
  1098. };
  1099. /*
  1100. * ALC880 W810 model
  1101. *
  1102. * W810 has rear IO for:
  1103. * Front (DAC 02)
  1104. * Surround (DAC 03)
  1105. * Center/LFE (DAC 04)
  1106. * Digital out (06)
  1107. *
  1108. * The system also has a pair of internal speakers, and a headphone jack.
  1109. * These are both connected to Line2 on the codec, hence to DAC 02.
  1110. *
  1111. * There is a variable resistor to control the speaker or headphone
  1112. * volume. This is a hardware-only device without a software API.
  1113. *
  1114. * Plugging headphones in will disable the internal speakers. This is
  1115. * implemented in hardware, not via the driver using jack sense. In
  1116. * a similar fashion, plugging into the rear socket marked "front" will
  1117. * disable both the speakers and headphones.
  1118. *
  1119. * For input, there's a microphone jack, and an "audio in" jack.
  1120. * These may not do anything useful with this driver yet, because I
  1121. * haven't setup any initialization verbs for these yet...
  1122. */
  1123. static hda_nid_t alc880_w810_dac_nids[3] = {
  1124. /* front, rear/surround, clfe */
  1125. 0x02, 0x03, 0x04
  1126. };
  1127. /* fixed 6 channels */
  1128. static struct hda_channel_mode alc880_w810_modes[1] = {
  1129. { 6, NULL }
  1130. };
  1131. /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
  1132. static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
  1133. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1134. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1135. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1136. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1137. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1138. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1139. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1140. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1141. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  1142. { } /* end */
  1143. };
  1144. /*
  1145. * Z710V model
  1146. *
  1147. * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
  1148. * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
  1149. * Line = 0x1a
  1150. */
  1151. static hda_nid_t alc880_z71v_dac_nids[1] = {
  1152. 0x02
  1153. };
  1154. #define ALC880_Z71V_HP_DAC 0x03
  1155. /* fixed 2 channels */
  1156. static struct hda_channel_mode alc880_2_jack_modes[1] = {
  1157. { 2, NULL }
  1158. };
  1159. static struct snd_kcontrol_new alc880_z71v_mixer[] = {
  1160. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1161. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1162. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1163. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  1164. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1165. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1166. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1167. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1168. { } /* end */
  1169. };
  1170. /*
  1171. * ALC880 F1734 model
  1172. *
  1173. * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
  1174. * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
  1175. */
  1176. static hda_nid_t alc880_f1734_dac_nids[1] = {
  1177. 0x03
  1178. };
  1179. #define ALC880_F1734_HP_DAC 0x02
  1180. static struct snd_kcontrol_new alc880_f1734_mixer[] = {
  1181. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1182. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1183. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1184. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1185. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1186. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1187. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1188. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1189. { } /* end */
  1190. };
  1191. static struct hda_input_mux alc880_f1734_capture_source = {
  1192. .num_items = 2,
  1193. .items = {
  1194. { "Mic", 0x1 },
  1195. { "CD", 0x4 },
  1196. },
  1197. };
  1198. /*
  1199. * ALC880 ASUS model
  1200. *
  1201. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  1202. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  1203. * Mic = 0x18, Line = 0x1a
  1204. */
  1205. #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
  1206. #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
  1207. static struct snd_kcontrol_new alc880_asus_mixer[] = {
  1208. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1209. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1210. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1211. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  1212. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1213. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1214. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1215. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1216. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1217. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1218. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1219. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1220. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1221. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1222. {
  1223. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1224. .name = "Channel Mode",
  1225. .info = alc_ch_mode_info,
  1226. .get = alc_ch_mode_get,
  1227. .put = alc_ch_mode_put,
  1228. },
  1229. { } /* end */
  1230. };
  1231. /*
  1232. * ALC880 ASUS W1V model
  1233. *
  1234. * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
  1235. * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
  1236. * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
  1237. */
  1238. /* additional mixers to alc880_asus_mixer */
  1239. static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
  1240. HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
  1241. HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
  1242. { } /* end */
  1243. };
  1244. /* additional mixers to alc880_asus_mixer */
  1245. static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
  1246. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1247. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1248. { } /* end */
  1249. };
  1250. /* TCL S700 */
  1251. static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
  1252. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1253. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  1254. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  1255. HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
  1256. HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
  1257. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
  1258. HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
  1259. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  1260. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  1261. {
  1262. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1263. /* The multiple "Capture Source" controls confuse alsamixer
  1264. * So call somewhat different..
  1265. */
  1266. /* .name = "Capture Source", */
  1267. .name = "Input Source",
  1268. .count = 1,
  1269. .info = alc_mux_enum_info,
  1270. .get = alc_mux_enum_get,
  1271. .put = alc_mux_enum_put,
  1272. },
  1273. { } /* end */
  1274. };
  1275. /* Uniwill */
  1276. static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
  1277. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1278. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1279. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1280. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1281. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1282. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1283. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1284. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1285. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1286. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1287. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1288. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1289. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1290. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1291. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1292. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1293. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  1294. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  1295. {
  1296. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1297. .name = "Channel Mode",
  1298. .info = alc_ch_mode_info,
  1299. .get = alc_ch_mode_get,
  1300. .put = alc_ch_mode_put,
  1301. },
  1302. { } /* end */
  1303. };
  1304. static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
  1305. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1306. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1307. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1308. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1309. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  1310. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  1311. HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1312. HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1313. HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1314. HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1315. { } /* end */
  1316. };
  1317. static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
  1318. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1319. HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
  1320. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  1321. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  1322. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1323. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1324. { } /* end */
  1325. };
  1326. /*
  1327. * virtual master controls
  1328. */
  1329. /*
  1330. * slave controls for virtual master
  1331. */
  1332. static const char *alc_slave_vols[] = {
  1333. "Front Playback Volume",
  1334. "Surround Playback Volume",
  1335. "Center Playback Volume",
  1336. "LFE Playback Volume",
  1337. "Side Playback Volume",
  1338. "Headphone Playback Volume",
  1339. "Speaker Playback Volume",
  1340. "Mono Playback Volume",
  1341. "Line-Out Playback Volume",
  1342. NULL,
  1343. };
  1344. static const char *alc_slave_sws[] = {
  1345. "Front Playback Switch",
  1346. "Surround Playback Switch",
  1347. "Center Playback Switch",
  1348. "LFE Playback Switch",
  1349. "Side Playback Switch",
  1350. "Headphone Playback Switch",
  1351. "Speaker Playback Switch",
  1352. "Mono Playback Switch",
  1353. "IEC958 Playback Switch",
  1354. NULL,
  1355. };
  1356. /*
  1357. * build control elements
  1358. */
  1359. static int alc_build_controls(struct hda_codec *codec)
  1360. {
  1361. struct alc_spec *spec = codec->spec;
  1362. int err;
  1363. int i;
  1364. for (i = 0; i < spec->num_mixers; i++) {
  1365. err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  1366. if (err < 0)
  1367. return err;
  1368. }
  1369. if (spec->multiout.dig_out_nid) {
  1370. err = snd_hda_create_spdif_out_ctls(codec,
  1371. spec->multiout.dig_out_nid);
  1372. if (err < 0)
  1373. return err;
  1374. }
  1375. if (spec->dig_in_nid) {
  1376. err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
  1377. if (err < 0)
  1378. return err;
  1379. }
  1380. /* if we have no master control, let's create it */
  1381. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
  1382. snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
  1383. HDA_OUTPUT, spec->vmaster_tlv);
  1384. err = snd_hda_add_vmaster(codec, "Master Playback Volume",
  1385. spec->vmaster_tlv, alc_slave_vols);
  1386. if (err < 0)
  1387. return err;
  1388. }
  1389. if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
  1390. err = snd_hda_add_vmaster(codec, "Master Playback Switch",
  1391. NULL, alc_slave_sws);
  1392. if (err < 0)
  1393. return err;
  1394. }
  1395. return 0;
  1396. }
  1397. /*
  1398. * initialize the codec volumes, etc
  1399. */
  1400. /*
  1401. * generic initialization of ADC, input mixers and output mixers
  1402. */
  1403. static struct hda_verb alc880_volume_init_verbs[] = {
  1404. /*
  1405. * Unmute ADC0-2 and set the default input to mic-in
  1406. */
  1407. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  1408. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1409. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  1410. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1411. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  1412. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1413. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  1414. * mixer widget
  1415. * Note: PASD motherboards uses the Line In 2 as the input for front
  1416. * panel mic (mic 2)
  1417. */
  1418. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  1419. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1420. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1421. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  1422. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  1423. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  1424. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  1425. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1426. /*
  1427. * Set up output mixers (0x0c - 0x0f)
  1428. */
  1429. /* set vol=0 to output mixers */
  1430. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1431. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1432. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1433. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  1434. /* set up input amps for analog loopback */
  1435. /* Amp Indices: DAC = 0, mixer = 1 */
  1436. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1437. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1438. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1439. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1440. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1441. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1442. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  1443. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  1444. { }
  1445. };
  1446. /*
  1447. * 3-stack pin configuration:
  1448. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  1449. */
  1450. static struct hda_verb alc880_pin_3stack_init_verbs[] = {
  1451. /*
  1452. * preset connection lists of input pins
  1453. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  1454. */
  1455. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  1456. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1457. {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
  1458. /*
  1459. * Set pin mode and muting
  1460. */
  1461. /* set front pin widgets 0x14 for output */
  1462. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1463. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1464. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1465. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1466. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1467. /* Mic2 (as headphone out) for HP output */
  1468. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1469. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1470. /* Line In pin widget for input */
  1471. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1472. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1473. /* Line2 (as front mic) pin widget for input and vref at 80% */
  1474. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1475. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1476. /* CD pin widget for input */
  1477. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1478. { }
  1479. };
  1480. /*
  1481. * 5-stack pin configuration:
  1482. * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
  1483. * line-in/side = 0x1a, f-mic = 0x1b
  1484. */
  1485. static struct hda_verb alc880_pin_5stack_init_verbs[] = {
  1486. /*
  1487. * preset connection lists of input pins
  1488. * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
  1489. */
  1490. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1491. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
  1492. /*
  1493. * Set pin mode and muting
  1494. */
  1495. /* set pin widgets 0x14-0x17 for output */
  1496. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1497. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1498. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1499. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1500. /* unmute pins for output (no gain on this amp) */
  1501. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1502. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1503. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1504. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1505. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1506. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1507. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1508. /* Mic2 (as headphone out) for HP output */
  1509. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1510. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1511. /* Line In pin widget for input */
  1512. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1513. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1514. /* Line2 (as front mic) pin widget for input and vref at 80% */
  1515. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1516. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1517. /* CD pin widget for input */
  1518. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1519. { }
  1520. };
  1521. /*
  1522. * W810 pin configuration:
  1523. * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
  1524. */
  1525. static struct hda_verb alc880_pin_w810_init_verbs[] = {
  1526. /* hphone/speaker input selector: front DAC */
  1527. {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
  1528. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1529. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1530. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1531. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1532. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1533. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1534. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1535. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1536. { }
  1537. };
  1538. /*
  1539. * Z71V pin configuration:
  1540. * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
  1541. */
  1542. static struct hda_verb alc880_pin_z71v_init_verbs[] = {
  1543. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1544. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1545. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1546. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1547. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1548. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1549. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1550. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1551. { }
  1552. };
  1553. /*
  1554. * 6-stack pin configuration:
  1555. * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
  1556. * f-mic = 0x19, line = 0x1a, HP = 0x1b
  1557. */
  1558. static struct hda_verb alc880_pin_6stack_init_verbs[] = {
  1559. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1560. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1561. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1562. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1563. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1564. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1565. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1566. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1567. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1568. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1569. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1570. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1571. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1572. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1573. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1574. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1575. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1576. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1577. { }
  1578. };
  1579. /*
  1580. * Uniwill pin configuration:
  1581. * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
  1582. * line = 0x1a
  1583. */
  1584. static struct hda_verb alc880_uniwill_init_verbs[] = {
  1585. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1586. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1587. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1588. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1589. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1590. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1591. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1592. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1593. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1594. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1595. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1596. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1597. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1598. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1599. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1600. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1601. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1602. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1603. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1604. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1605. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1606. /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
  1607. /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
  1608. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1609. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  1610. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  1611. { }
  1612. };
  1613. /*
  1614. * Uniwill P53
  1615. * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
  1616. */
  1617. static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
  1618. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1619. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1620. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1621. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1622. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1623. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1624. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1625. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1626. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1627. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1628. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1629. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  1630. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  1631. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1632. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1633. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1634. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1635. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1636. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1637. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  1638. {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
  1639. { }
  1640. };
  1641. static struct hda_verb alc880_beep_init_verbs[] = {
  1642. { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
  1643. { }
  1644. };
  1645. /* toggle speaker-output according to the hp-jack state */
  1646. static void alc880_uniwill_hp_automute(struct hda_codec *codec)
  1647. {
  1648. unsigned int present;
  1649. unsigned char bits;
  1650. present = snd_hda_codec_read(codec, 0x14, 0,
  1651. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1652. bits = present ? HDA_AMP_MUTE : 0;
  1653. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  1654. HDA_AMP_MUTE, bits);
  1655. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  1656. HDA_AMP_MUTE, bits);
  1657. }
  1658. /* auto-toggle front mic */
  1659. static void alc880_uniwill_mic_automute(struct hda_codec *codec)
  1660. {
  1661. unsigned int present;
  1662. unsigned char bits;
  1663. present = snd_hda_codec_read(codec, 0x18, 0,
  1664. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1665. bits = present ? HDA_AMP_MUTE : 0;
  1666. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
  1667. }
  1668. static void alc880_uniwill_automute(struct hda_codec *codec)
  1669. {
  1670. alc880_uniwill_hp_automute(codec);
  1671. alc880_uniwill_mic_automute(codec);
  1672. }
  1673. static void alc880_uniwill_unsol_event(struct hda_codec *codec,
  1674. unsigned int res)
  1675. {
  1676. /* Looks like the unsol event is incompatible with the standard
  1677. * definition. 4bit tag is placed at 28 bit!
  1678. */
  1679. switch (res >> 28) {
  1680. case ALC880_HP_EVENT:
  1681. alc880_uniwill_hp_automute(codec);
  1682. break;
  1683. case ALC880_MIC_EVENT:
  1684. alc880_uniwill_mic_automute(codec);
  1685. break;
  1686. }
  1687. }
  1688. static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
  1689. {
  1690. unsigned int present;
  1691. unsigned char bits;
  1692. present = snd_hda_codec_read(codec, 0x14, 0,
  1693. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1694. bits = present ? HDA_AMP_MUTE : 0;
  1695. snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
  1696. }
  1697. static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
  1698. {
  1699. unsigned int present;
  1700. present = snd_hda_codec_read(codec, 0x21, 0,
  1701. AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
  1702. present &= HDA_AMP_VOLMASK;
  1703. snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
  1704. HDA_AMP_VOLMASK, present);
  1705. snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
  1706. HDA_AMP_VOLMASK, present);
  1707. }
  1708. static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
  1709. unsigned int res)
  1710. {
  1711. /* Looks like the unsol event is incompatible with the standard
  1712. * definition. 4bit tag is placed at 28 bit!
  1713. */
  1714. if ((res >> 28) == ALC880_HP_EVENT)
  1715. alc880_uniwill_p53_hp_automute(codec);
  1716. if ((res >> 28) == ALC880_DCVOL_EVENT)
  1717. alc880_uniwill_p53_dcvol_automute(codec);
  1718. }
  1719. /*
  1720. * F1734 pin configuration:
  1721. * HP = 0x14, speaker-out = 0x15, mic = 0x18
  1722. */
  1723. static struct hda_verb alc880_pin_f1734_init_verbs[] = {
  1724. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
  1725. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
  1726. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
  1727. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
  1728. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1729. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1730. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1731. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1732. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1733. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1734. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1735. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1736. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1737. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1738. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1739. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1740. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1741. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
  1742. {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
  1743. { }
  1744. };
  1745. /*
  1746. * ASUS pin configuration:
  1747. * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
  1748. */
  1749. static struct hda_verb alc880_pin_asus_init_verbs[] = {
  1750. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
  1751. {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
  1752. {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
  1753. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
  1754. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1755. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1756. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1757. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1758. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1759. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1760. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1761. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1762. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1763. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1764. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1765. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1766. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1767. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  1768. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1769. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1770. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1771. { }
  1772. };
  1773. /* Enable GPIO mask and set output */
  1774. #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
  1775. #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
  1776. /* Clevo m520g init */
  1777. static struct hda_verb alc880_pin_clevo_init_verbs[] = {
  1778. /* headphone output */
  1779. {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
  1780. /* line-out */
  1781. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1782. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1783. /* Line-in */
  1784. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1785. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1786. /* CD */
  1787. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1788. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1789. /* Mic1 (rear panel) */
  1790. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1791. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1792. /* Mic2 (front panel) */
  1793. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1794. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1795. /* headphone */
  1796. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1797. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1798. /* change to EAPD mode */
  1799. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1800. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  1801. { }
  1802. };
  1803. static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
  1804. /* change to EAPD mode */
  1805. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1806. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  1807. /* Headphone output */
  1808. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1809. /* Front output*/
  1810. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  1811. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  1812. /* Line In pin widget for input */
  1813. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1814. /* CD pin widget for input */
  1815. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1816. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  1817. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1818. /* change to EAPD mode */
  1819. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  1820. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  1821. { }
  1822. };
  1823. /*
  1824. * LG m1 express dual
  1825. *
  1826. * Pin assignment:
  1827. * Rear Line-In/Out (blue): 0x14
  1828. * Build-in Mic-In: 0x15
  1829. * Speaker-out: 0x17
  1830. * HP-Out (green): 0x1b
  1831. * Mic-In/Out (red): 0x19
  1832. * SPDIF-Out: 0x1e
  1833. */
  1834. /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
  1835. static hda_nid_t alc880_lg_dac_nids[3] = {
  1836. 0x05, 0x02, 0x03
  1837. };
  1838. /* seems analog CD is not working */
  1839. static struct hda_input_mux alc880_lg_capture_source = {
  1840. .num_items = 3,
  1841. .items = {
  1842. { "Mic", 0x1 },
  1843. { "Line", 0x5 },
  1844. { "Internal Mic", 0x6 },
  1845. },
  1846. };
  1847. /* 2,4,6 channel modes */
  1848. static struct hda_verb alc880_lg_ch2_init[] = {
  1849. /* set line-in and mic-in to input */
  1850. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  1851. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  1852. { }
  1853. };
  1854. static struct hda_verb alc880_lg_ch4_init[] = {
  1855. /* set line-in to out and mic-in to input */
  1856. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1857. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  1858. { }
  1859. };
  1860. static struct hda_verb alc880_lg_ch6_init[] = {
  1861. /* set line-in and mic-in to output */
  1862. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1863. { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
  1864. { }
  1865. };
  1866. static struct hda_channel_mode alc880_lg_ch_modes[3] = {
  1867. { 2, alc880_lg_ch2_init },
  1868. { 4, alc880_lg_ch4_init },
  1869. { 6, alc880_lg_ch6_init },
  1870. };
  1871. static struct snd_kcontrol_new alc880_lg_mixer[] = {
  1872. HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1873. HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
  1874. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1875. HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
  1876. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  1877. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  1878. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  1879. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  1880. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  1881. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  1882. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
  1883. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
  1884. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
  1885. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
  1886. {
  1887. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1888. .name = "Channel Mode",
  1889. .info = alc_ch_mode_info,
  1890. .get = alc_ch_mode_get,
  1891. .put = alc_ch_mode_put,
  1892. },
  1893. { } /* end */
  1894. };
  1895. static struct hda_verb alc880_lg_init_verbs[] = {
  1896. /* set capture source to mic-in */
  1897. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1898. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1899. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  1900. /* mute all amp mixer inputs */
  1901. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
  1902. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  1903. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1904. /* line-in to input */
  1905. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  1906. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1907. /* built-in mic */
  1908. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1909. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1910. /* speaker-out */
  1911. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1912. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1913. /* mic-in to input */
  1914. {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
  1915. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  1916. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1917. /* HP-out */
  1918. {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
  1919. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1920. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  1921. /* jack sense */
  1922. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
  1923. { }
  1924. };
  1925. /* toggle speaker-output according to the hp-jack state */
  1926. static void alc880_lg_automute(struct hda_codec *codec)
  1927. {
  1928. unsigned int present;
  1929. unsigned char bits;
  1930. present = snd_hda_codec_read(codec, 0x1b, 0,
  1931. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  1932. bits = present ? HDA_AMP_MUTE : 0;
  1933. snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
  1934. HDA_AMP_MUTE, bits);
  1935. }
  1936. static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
  1937. {
  1938. /* Looks like the unsol event is incompatible with the standard
  1939. * definition. 4bit tag is placed at 28 bit!
  1940. */
  1941. if ((res >> 28) == 0x01)
  1942. alc880_lg_automute(codec);
  1943. }
  1944. /*
  1945. * LG LW20
  1946. *
  1947. * Pin assignment:
  1948. * Speaker-out: 0x14
  1949. * Mic-In: 0x18
  1950. * Built-in Mic-In: 0x19
  1951. * Line-In: 0x1b
  1952. * HP-Out: 0x1a
  1953. * SPDIF-Out: 0x1e
  1954. */
  1955. static struct hda_input_mux alc880_lg_lw_capture_source = {
  1956. .num_items = 3,
  1957. .items = {
  1958. { "Mic", 0x0 },
  1959. { "Internal Mic", 0x1 },
  1960. { "Line In", 0x2 },
  1961. },
  1962. };
  1963. #define alc880_lg_lw_modes alc880_threestack_modes
  1964. static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
  1965. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  1966. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  1967. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  1968. HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
  1969. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  1970. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  1971. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  1972. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  1973. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  1974. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  1975. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  1976. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  1977. HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  1978. HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  1979. {
  1980. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  1981. .name = "Channel Mode",
  1982. .info = alc_ch_mode_info,
  1983. .get = alc_ch_mode_get,
  1984. .put = alc_ch_mode_put,
  1985. },
  1986. { } /* end */
  1987. };
  1988. static struct hda_verb alc880_lg_lw_init_verbs[] = {
  1989. {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  1990. {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  1991. {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
  1992. /* set capture source to mic-in */
  1993. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1994. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1995. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  1996. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  1997. /* speaker-out */
  1998. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  1999. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2000. /* HP-out */
  2001. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  2002. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2003. /* mic-in to input */
  2004. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2005. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2006. /* built-in mic */
  2007. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2008. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2009. /* jack sense */
  2010. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
  2011. { }
  2012. };
  2013. /* toggle speaker-output according to the hp-jack state */
  2014. static void alc880_lg_lw_automute(struct hda_codec *codec)
  2015. {
  2016. unsigned int present;
  2017. unsigned char bits;
  2018. present = snd_hda_codec_read(codec, 0x1b, 0,
  2019. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  2020. bits = present ? HDA_AMP_MUTE : 0;
  2021. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  2022. HDA_AMP_MUTE, bits);
  2023. }
  2024. static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
  2025. {
  2026. /* Looks like the unsol event is incompatible with the standard
  2027. * definition. 4bit tag is placed at 28 bit!
  2028. */
  2029. if ((res >> 28) == 0x01)
  2030. alc880_lg_lw_automute(codec);
  2031. }
  2032. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2033. static struct hda_amp_list alc880_loopbacks[] = {
  2034. { 0x0b, HDA_INPUT, 0 },
  2035. { 0x0b, HDA_INPUT, 1 },
  2036. { 0x0b, HDA_INPUT, 2 },
  2037. { 0x0b, HDA_INPUT, 3 },
  2038. { 0x0b, HDA_INPUT, 4 },
  2039. { } /* end */
  2040. };
  2041. static struct hda_amp_list alc880_lg_loopbacks[] = {
  2042. { 0x0b, HDA_INPUT, 1 },
  2043. { 0x0b, HDA_INPUT, 6 },
  2044. { 0x0b, HDA_INPUT, 7 },
  2045. { } /* end */
  2046. };
  2047. #endif
  2048. /*
  2049. * Common callbacks
  2050. */
  2051. static int alc_init(struct hda_codec *codec)
  2052. {
  2053. struct alc_spec *spec = codec->spec;
  2054. unsigned int i;
  2055. for (i = 0; i < spec->num_init_verbs; i++)
  2056. snd_hda_sequence_write(codec, spec->init_verbs[i]);
  2057. if (spec->init_hook)
  2058. spec->init_hook(codec);
  2059. return 0;
  2060. }
  2061. static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
  2062. {
  2063. struct alc_spec *spec = codec->spec;
  2064. if (spec->unsol_event)
  2065. spec->unsol_event(codec, res);
  2066. }
  2067. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2068. static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
  2069. {
  2070. struct alc_spec *spec = codec->spec;
  2071. return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
  2072. }
  2073. #endif
  2074. /*
  2075. * Analog playback callbacks
  2076. */
  2077. static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
  2078. struct hda_codec *codec,
  2079. struct snd_pcm_substream *substream)
  2080. {
  2081. struct alc_spec *spec = codec->spec;
  2082. return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
  2083. }
  2084. static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  2085. struct hda_codec *codec,
  2086. unsigned int stream_tag,
  2087. unsigned int format,
  2088. struct snd_pcm_substream *substream)
  2089. {
  2090. struct alc_spec *spec = codec->spec;
  2091. return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
  2092. stream_tag, format, substream);
  2093. }
  2094. static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  2095. struct hda_codec *codec,
  2096. struct snd_pcm_substream *substream)
  2097. {
  2098. struct alc_spec *spec = codec->spec;
  2099. return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
  2100. }
  2101. /*
  2102. * Digital out
  2103. */
  2104. static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
  2105. struct hda_codec *codec,
  2106. struct snd_pcm_substream *substream)
  2107. {
  2108. struct alc_spec *spec = codec->spec;
  2109. return snd_hda_multi_out_dig_open(codec, &spec->multiout);
  2110. }
  2111. static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  2112. struct hda_codec *codec,
  2113. unsigned int stream_tag,
  2114. unsigned int format,
  2115. struct snd_pcm_substream *substream)
  2116. {
  2117. struct alc_spec *spec = codec->spec;
  2118. return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
  2119. stream_tag, format, substream);
  2120. }
  2121. static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
  2122. struct hda_codec *codec,
  2123. struct snd_pcm_substream *substream)
  2124. {
  2125. struct alc_spec *spec = codec->spec;
  2126. return snd_hda_multi_out_dig_close(codec, &spec->multiout);
  2127. }
  2128. /*
  2129. * Analog capture
  2130. */
  2131. static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
  2132. struct hda_codec *codec,
  2133. unsigned int stream_tag,
  2134. unsigned int format,
  2135. struct snd_pcm_substream *substream)
  2136. {
  2137. struct alc_spec *spec = codec->spec;
  2138. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
  2139. stream_tag, 0, format);
  2140. return 0;
  2141. }
  2142. static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
  2143. struct hda_codec *codec,
  2144. struct snd_pcm_substream *substream)
  2145. {
  2146. struct alc_spec *spec = codec->spec;
  2147. snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
  2148. 0, 0, 0);
  2149. return 0;
  2150. }
  2151. /*
  2152. */
  2153. static struct hda_pcm_stream alc880_pcm_analog_playback = {
  2154. .substreams = 1,
  2155. .channels_min = 2,
  2156. .channels_max = 8,
  2157. /* NID is set in alc_build_pcms */
  2158. .ops = {
  2159. .open = alc880_playback_pcm_open,
  2160. .prepare = alc880_playback_pcm_prepare,
  2161. .cleanup = alc880_playback_pcm_cleanup
  2162. },
  2163. };
  2164. static struct hda_pcm_stream alc880_pcm_analog_capture = {
  2165. .substreams = 1,
  2166. .channels_min = 2,
  2167. .channels_max = 2,
  2168. /* NID is set in alc_build_pcms */
  2169. };
  2170. static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
  2171. .substreams = 1,
  2172. .channels_min = 2,
  2173. .channels_max = 2,
  2174. /* NID is set in alc_build_pcms */
  2175. };
  2176. static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
  2177. .substreams = 2, /* can be overridden */
  2178. .channels_min = 2,
  2179. .channels_max = 2,
  2180. /* NID is set in alc_build_pcms */
  2181. .ops = {
  2182. .prepare = alc880_alt_capture_pcm_prepare,
  2183. .cleanup = alc880_alt_capture_pcm_cleanup
  2184. },
  2185. };
  2186. static struct hda_pcm_stream alc880_pcm_digital_playback = {
  2187. .substreams = 1,
  2188. .channels_min = 2,
  2189. .channels_max = 2,
  2190. /* NID is set in alc_build_pcms */
  2191. .ops = {
  2192. .open = alc880_dig_playback_pcm_open,
  2193. .close = alc880_dig_playback_pcm_close,
  2194. .prepare = alc880_dig_playback_pcm_prepare
  2195. },
  2196. };
  2197. static struct hda_pcm_stream alc880_pcm_digital_capture = {
  2198. .substreams = 1,
  2199. .channels_min = 2,
  2200. .channels_max = 2,
  2201. /* NID is set in alc_build_pcms */
  2202. };
  2203. /* Used by alc_build_pcms to flag that a PCM has no playback stream */
  2204. static struct hda_pcm_stream alc_pcm_null_stream = {
  2205. .substreams = 0,
  2206. .channels_min = 0,
  2207. .channels_max = 0,
  2208. };
  2209. static int alc_build_pcms(struct hda_codec *codec)
  2210. {
  2211. struct alc_spec *spec = codec->spec;
  2212. struct hda_pcm *info = spec->pcm_rec;
  2213. int i;
  2214. codec->num_pcms = 1;
  2215. codec->pcm_info = info;
  2216. info->name = spec->stream_name_analog;
  2217. if (spec->stream_analog_playback) {
  2218. snd_assert(spec->multiout.dac_nids, return -EINVAL);
  2219. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
  2220. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
  2221. }
  2222. if (spec->stream_analog_capture) {
  2223. snd_assert(spec->adc_nids, return -EINVAL);
  2224. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
  2225. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
  2226. }
  2227. if (spec->channel_mode) {
  2228. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
  2229. for (i = 0; i < spec->num_channel_mode; i++) {
  2230. if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
  2231. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
  2232. }
  2233. }
  2234. }
  2235. /* SPDIF for stream index #1 */
  2236. if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
  2237. codec->num_pcms = 2;
  2238. info = spec->pcm_rec + 1;
  2239. info->name = spec->stream_name_digital;
  2240. info->pcm_type = HDA_PCM_TYPE_SPDIF;
  2241. if (spec->multiout.dig_out_nid &&
  2242. spec->stream_digital_playback) {
  2243. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
  2244. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
  2245. }
  2246. if (spec->dig_in_nid &&
  2247. spec->stream_digital_capture) {
  2248. info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
  2249. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
  2250. }
  2251. }
  2252. /* If the use of more than one ADC is requested for the current
  2253. * model, configure a second analog capture-only PCM.
  2254. */
  2255. /* Additional Analaog capture for index #2 */
  2256. if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
  2257. (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
  2258. codec->num_pcms = 3;
  2259. info = spec->pcm_rec + 2;
  2260. info->name = spec->stream_name_analog;
  2261. if (spec->alt_dac_nid) {
  2262. info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
  2263. *spec->stream_analog_alt_playback;
  2264. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
  2265. spec->alt_dac_nid;
  2266. } else {
  2267. info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
  2268. alc_pcm_null_stream;
  2269. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
  2270. }
  2271. if (spec->num_adc_nids > 1) {
  2272. info->stream[SNDRV_PCM_STREAM_CAPTURE] =
  2273. *spec->stream_analog_alt_capture;
  2274. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
  2275. spec->adc_nids[1];
  2276. info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
  2277. spec->num_adc_nids - 1;
  2278. } else {
  2279. info->stream[SNDRV_PCM_STREAM_CAPTURE] =
  2280. alc_pcm_null_stream;
  2281. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
  2282. }
  2283. }
  2284. return 0;
  2285. }
  2286. static void alc_free(struct hda_codec *codec)
  2287. {
  2288. struct alc_spec *spec = codec->spec;
  2289. unsigned int i;
  2290. if (!spec)
  2291. return;
  2292. if (spec->kctl_alloc) {
  2293. for (i = 0; i < spec->num_kctl_used; i++)
  2294. kfree(spec->kctl_alloc[i].name);
  2295. kfree(spec->kctl_alloc);
  2296. }
  2297. kfree(spec);
  2298. }
  2299. /*
  2300. */
  2301. static struct hda_codec_ops alc_patch_ops = {
  2302. .build_controls = alc_build_controls,
  2303. .build_pcms = alc_build_pcms,
  2304. .init = alc_init,
  2305. .free = alc_free,
  2306. .unsol_event = alc_unsol_event,
  2307. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2308. .check_power_status = alc_check_power_status,
  2309. #endif
  2310. };
  2311. /*
  2312. * Test configuration for debugging
  2313. *
  2314. * Almost all inputs/outputs are enabled. I/O pins can be configured via
  2315. * enum controls.
  2316. */
  2317. #ifdef CONFIG_SND_DEBUG
  2318. static hda_nid_t alc880_test_dac_nids[4] = {
  2319. 0x02, 0x03, 0x04, 0x05
  2320. };
  2321. static struct hda_input_mux alc880_test_capture_source = {
  2322. .num_items = 7,
  2323. .items = {
  2324. { "In-1", 0x0 },
  2325. { "In-2", 0x1 },
  2326. { "In-3", 0x2 },
  2327. { "In-4", 0x3 },
  2328. { "CD", 0x4 },
  2329. { "Front", 0x5 },
  2330. { "Surround", 0x6 },
  2331. },
  2332. };
  2333. static struct hda_channel_mode alc880_test_modes[4] = {
  2334. { 2, NULL },
  2335. { 4, NULL },
  2336. { 6, NULL },
  2337. { 8, NULL },
  2338. };
  2339. static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
  2340. struct snd_ctl_elem_info *uinfo)
  2341. {
  2342. static char *texts[] = {
  2343. "N/A", "Line Out", "HP Out",
  2344. "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
  2345. };
  2346. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  2347. uinfo->count = 1;
  2348. uinfo->value.enumerated.items = 8;
  2349. if (uinfo->value.enumerated.item >= 8)
  2350. uinfo->value.enumerated.item = 7;
  2351. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  2352. return 0;
  2353. }
  2354. static int alc_test_pin_ctl_get(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 pin_ctl, item = 0;
  2360. pin_ctl = snd_hda_codec_read(codec, nid, 0,
  2361. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  2362. if (pin_ctl & AC_PINCTL_OUT_EN) {
  2363. if (pin_ctl & AC_PINCTL_HP_EN)
  2364. item = 2;
  2365. else
  2366. item = 1;
  2367. } else if (pin_ctl & AC_PINCTL_IN_EN) {
  2368. switch (pin_ctl & AC_PINCTL_VREFEN) {
  2369. case AC_PINCTL_VREF_HIZ: item = 3; break;
  2370. case AC_PINCTL_VREF_50: item = 4; break;
  2371. case AC_PINCTL_VREF_GRD: item = 5; break;
  2372. case AC_PINCTL_VREF_80: item = 6; break;
  2373. case AC_PINCTL_VREF_100: item = 7; break;
  2374. }
  2375. }
  2376. ucontrol->value.enumerated.item[0] = item;
  2377. return 0;
  2378. }
  2379. static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
  2380. struct snd_ctl_elem_value *ucontrol)
  2381. {
  2382. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2383. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2384. static unsigned int ctls[] = {
  2385. 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
  2386. AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
  2387. AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
  2388. AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
  2389. AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
  2390. AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
  2391. };
  2392. unsigned int old_ctl, new_ctl;
  2393. old_ctl = snd_hda_codec_read(codec, nid, 0,
  2394. AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  2395. new_ctl = ctls[ucontrol->value.enumerated.item[0]];
  2396. if (old_ctl != new_ctl) {
  2397. int val;
  2398. snd_hda_codec_write_cache(codec, nid, 0,
  2399. AC_VERB_SET_PIN_WIDGET_CONTROL,
  2400. new_ctl);
  2401. val = ucontrol->value.enumerated.item[0] >= 3 ?
  2402. HDA_AMP_MUTE : 0;
  2403. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  2404. HDA_AMP_MUTE, val);
  2405. return 1;
  2406. }
  2407. return 0;
  2408. }
  2409. static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
  2410. struct snd_ctl_elem_info *uinfo)
  2411. {
  2412. static char *texts[] = {
  2413. "Front", "Surround", "CLFE", "Side"
  2414. };
  2415. uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  2416. uinfo->count = 1;
  2417. uinfo->value.enumerated.items = 4;
  2418. if (uinfo->value.enumerated.item >= 4)
  2419. uinfo->value.enumerated.item = 3;
  2420. strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  2421. return 0;
  2422. }
  2423. static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
  2424. struct snd_ctl_elem_value *ucontrol)
  2425. {
  2426. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2427. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2428. unsigned int sel;
  2429. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
  2430. ucontrol->value.enumerated.item[0] = sel & 3;
  2431. return 0;
  2432. }
  2433. static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
  2434. struct snd_ctl_elem_value *ucontrol)
  2435. {
  2436. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  2437. hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
  2438. unsigned int sel;
  2439. sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
  2440. if (ucontrol->value.enumerated.item[0] != sel) {
  2441. sel = ucontrol->value.enumerated.item[0] & 3;
  2442. snd_hda_codec_write_cache(codec, nid, 0,
  2443. AC_VERB_SET_CONNECT_SEL, sel);
  2444. return 1;
  2445. }
  2446. return 0;
  2447. }
  2448. #define PIN_CTL_TEST(xname,nid) { \
  2449. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  2450. .name = xname, \
  2451. .info = alc_test_pin_ctl_info, \
  2452. .get = alc_test_pin_ctl_get, \
  2453. .put = alc_test_pin_ctl_put, \
  2454. .private_value = nid \
  2455. }
  2456. #define PIN_SRC_TEST(xname,nid) { \
  2457. .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  2458. .name = xname, \
  2459. .info = alc_test_pin_src_info, \
  2460. .get = alc_test_pin_src_get, \
  2461. .put = alc_test_pin_src_put, \
  2462. .private_value = nid \
  2463. }
  2464. static struct snd_kcontrol_new alc880_test_mixer[] = {
  2465. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  2466. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  2467. HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  2468. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  2469. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  2470. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  2471. HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
  2472. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  2473. PIN_CTL_TEST("Front Pin Mode", 0x14),
  2474. PIN_CTL_TEST("Surround Pin Mode", 0x15),
  2475. PIN_CTL_TEST("CLFE Pin Mode", 0x16),
  2476. PIN_CTL_TEST("Side Pin Mode", 0x17),
  2477. PIN_CTL_TEST("In-1 Pin Mode", 0x18),
  2478. PIN_CTL_TEST("In-2 Pin Mode", 0x19),
  2479. PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
  2480. PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
  2481. PIN_SRC_TEST("In-1 Pin Source", 0x18),
  2482. PIN_SRC_TEST("In-2 Pin Source", 0x19),
  2483. PIN_SRC_TEST("In-3 Pin Source", 0x1a),
  2484. PIN_SRC_TEST("In-4 Pin Source", 0x1b),
  2485. HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
  2486. HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
  2487. HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
  2488. HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
  2489. HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
  2490. HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
  2491. HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
  2492. HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
  2493. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
  2494. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
  2495. {
  2496. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  2497. .name = "Channel Mode",
  2498. .info = alc_ch_mode_info,
  2499. .get = alc_ch_mode_get,
  2500. .put = alc_ch_mode_put,
  2501. },
  2502. { } /* end */
  2503. };
  2504. static struct hda_verb alc880_test_init_verbs[] = {
  2505. /* Unmute inputs of 0x0c - 0x0f */
  2506. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2507. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2508. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2509. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2510. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2511. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2512. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  2513. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  2514. /* Vol output for 0x0c-0x0f */
  2515. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2516. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2517. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2518. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  2519. /* Set output pins 0x14-0x17 */
  2520. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2521. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2522. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2523. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  2524. /* Unmute output pins 0x14-0x17 */
  2525. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2526. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2527. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2528. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  2529. /* Set input pins 0x18-0x1c */
  2530. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2531. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  2532. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2533. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2534. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  2535. /* Mute input pins 0x18-0x1b */
  2536. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2537. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2538. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2539. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  2540. /* ADC set up */
  2541. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2542. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  2543. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2544. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  2545. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2546. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  2547. /* Analog input/passthru */
  2548. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  2549. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  2550. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  2551. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  2552. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  2553. { }
  2554. };
  2555. #endif
  2556. /*
  2557. */
  2558. static const char *alc880_models[ALC880_MODEL_LAST] = {
  2559. [ALC880_3ST] = "3stack",
  2560. [ALC880_TCL_S700] = "tcl",
  2561. [ALC880_3ST_DIG] = "3stack-digout",
  2562. [ALC880_CLEVO] = "clevo",
  2563. [ALC880_5ST] = "5stack",
  2564. [ALC880_5ST_DIG] = "5stack-digout",
  2565. [ALC880_W810] = "w810",
  2566. [ALC880_Z71V] = "z71v",
  2567. [ALC880_6ST] = "6stack",
  2568. [ALC880_6ST_DIG] = "6stack-digout",
  2569. [ALC880_ASUS] = "asus",
  2570. [ALC880_ASUS_W1V] = "asus-w1v",
  2571. [ALC880_ASUS_DIG] = "asus-dig",
  2572. [ALC880_ASUS_DIG2] = "asus-dig2",
  2573. [ALC880_UNIWILL_DIG] = "uniwill",
  2574. [ALC880_UNIWILL_P53] = "uniwill-p53",
  2575. [ALC880_FUJITSU] = "fujitsu",
  2576. [ALC880_F1734] = "F1734",
  2577. [ALC880_LG] = "lg",
  2578. [ALC880_LG_LW] = "lg-lw",
  2579. #ifdef CONFIG_SND_DEBUG
  2580. [ALC880_TEST] = "test",
  2581. #endif
  2582. [ALC880_AUTO] = "auto",
  2583. };
  2584. static struct snd_pci_quirk alc880_cfg_tbl[] = {
  2585. SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
  2586. SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
  2587. SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
  2588. SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
  2589. SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
  2590. SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
  2591. SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
  2592. SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
  2593. SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
  2594. SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
  2595. SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
  2596. SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
  2597. SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
  2598. SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
  2599. SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
  2600. SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
  2601. SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
  2602. SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
  2603. /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
  2604. SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
  2605. SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
  2606. SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
  2607. SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
  2608. SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
  2609. SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
  2610. SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
  2611. SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
  2612. SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
  2613. SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
  2614. SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
  2615. SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
  2616. SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
  2617. SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
  2618. SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
  2619. SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
  2620. SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
  2621. SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
  2622. SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
  2623. SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
  2624. SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
  2625. SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
  2626. SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
  2627. SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
  2628. SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
  2629. SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
  2630. SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
  2631. SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
  2632. SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
  2633. SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
  2634. SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
  2635. SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
  2636. SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
  2637. SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
  2638. SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
  2639. SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
  2640. SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
  2641. SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
  2642. SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
  2643. SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
  2644. SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
  2645. SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
  2646. SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
  2647. SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
  2648. SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
  2649. SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
  2650. SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
  2651. SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
  2652. SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
  2653. SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
  2654. {}
  2655. };
  2656. /*
  2657. * ALC880 codec presets
  2658. */
  2659. static struct alc_config_preset alc880_presets[] = {
  2660. [ALC880_3ST] = {
  2661. .mixers = { alc880_three_stack_mixer },
  2662. .init_verbs = { alc880_volume_init_verbs,
  2663. alc880_pin_3stack_init_verbs },
  2664. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2665. .dac_nids = alc880_dac_nids,
  2666. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2667. .channel_mode = alc880_threestack_modes,
  2668. .need_dac_fix = 1,
  2669. .input_mux = &alc880_capture_source,
  2670. },
  2671. [ALC880_3ST_DIG] = {
  2672. .mixers = { alc880_three_stack_mixer },
  2673. .init_verbs = { alc880_volume_init_verbs,
  2674. alc880_pin_3stack_init_verbs },
  2675. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2676. .dac_nids = alc880_dac_nids,
  2677. .dig_out_nid = ALC880_DIGOUT_NID,
  2678. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2679. .channel_mode = alc880_threestack_modes,
  2680. .need_dac_fix = 1,
  2681. .input_mux = &alc880_capture_source,
  2682. },
  2683. [ALC880_TCL_S700] = {
  2684. .mixers = { alc880_tcl_s700_mixer },
  2685. .init_verbs = { alc880_volume_init_verbs,
  2686. alc880_pin_tcl_S700_init_verbs,
  2687. alc880_gpio2_init_verbs },
  2688. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2689. .dac_nids = alc880_dac_nids,
  2690. .hp_nid = 0x03,
  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_5ST] = {
  2696. .mixers = { alc880_three_stack_mixer,
  2697. alc880_five_stack_mixer},
  2698. .init_verbs = { alc880_volume_init_verbs,
  2699. alc880_pin_5stack_init_verbs },
  2700. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2701. .dac_nids = alc880_dac_nids,
  2702. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  2703. .channel_mode = alc880_fivestack_modes,
  2704. .input_mux = &alc880_capture_source,
  2705. },
  2706. [ALC880_5ST_DIG] = {
  2707. .mixers = { alc880_three_stack_mixer,
  2708. alc880_five_stack_mixer },
  2709. .init_verbs = { alc880_volume_init_verbs,
  2710. alc880_pin_5stack_init_verbs },
  2711. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2712. .dac_nids = alc880_dac_nids,
  2713. .dig_out_nid = ALC880_DIGOUT_NID,
  2714. .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
  2715. .channel_mode = alc880_fivestack_modes,
  2716. .input_mux = &alc880_capture_source,
  2717. },
  2718. [ALC880_6ST] = {
  2719. .mixers = { alc880_six_stack_mixer },
  2720. .init_verbs = { alc880_volume_init_verbs,
  2721. alc880_pin_6stack_init_verbs },
  2722. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  2723. .dac_nids = alc880_6st_dac_nids,
  2724. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  2725. .channel_mode = alc880_sixstack_modes,
  2726. .input_mux = &alc880_6stack_capture_source,
  2727. },
  2728. [ALC880_6ST_DIG] = {
  2729. .mixers = { alc880_six_stack_mixer },
  2730. .init_verbs = { alc880_volume_init_verbs,
  2731. alc880_pin_6stack_init_verbs },
  2732. .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
  2733. .dac_nids = alc880_6st_dac_nids,
  2734. .dig_out_nid = ALC880_DIGOUT_NID,
  2735. .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
  2736. .channel_mode = alc880_sixstack_modes,
  2737. .input_mux = &alc880_6stack_capture_source,
  2738. },
  2739. [ALC880_W810] = {
  2740. .mixers = { alc880_w810_base_mixer },
  2741. .init_verbs = { alc880_volume_init_verbs,
  2742. alc880_pin_w810_init_verbs,
  2743. alc880_gpio2_init_verbs },
  2744. .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
  2745. .dac_nids = alc880_w810_dac_nids,
  2746. .dig_out_nid = ALC880_DIGOUT_NID,
  2747. .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
  2748. .channel_mode = alc880_w810_modes,
  2749. .input_mux = &alc880_capture_source,
  2750. },
  2751. [ALC880_Z71V] = {
  2752. .mixers = { alc880_z71v_mixer },
  2753. .init_verbs = { alc880_volume_init_verbs,
  2754. alc880_pin_z71v_init_verbs },
  2755. .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
  2756. .dac_nids = alc880_z71v_dac_nids,
  2757. .dig_out_nid = ALC880_DIGOUT_NID,
  2758. .hp_nid = 0x03,
  2759. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2760. .channel_mode = alc880_2_jack_modes,
  2761. .input_mux = &alc880_capture_source,
  2762. },
  2763. [ALC880_F1734] = {
  2764. .mixers = { alc880_f1734_mixer },
  2765. .init_verbs = { alc880_volume_init_verbs,
  2766. alc880_pin_f1734_init_verbs },
  2767. .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
  2768. .dac_nids = alc880_f1734_dac_nids,
  2769. .hp_nid = 0x02,
  2770. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2771. .channel_mode = alc880_2_jack_modes,
  2772. .input_mux = &alc880_f1734_capture_source,
  2773. .unsol_event = alc880_uniwill_p53_unsol_event,
  2774. .init_hook = alc880_uniwill_p53_hp_automute,
  2775. },
  2776. [ALC880_ASUS] = {
  2777. .mixers = { alc880_asus_mixer },
  2778. .init_verbs = { alc880_volume_init_verbs,
  2779. alc880_pin_asus_init_verbs,
  2780. alc880_gpio1_init_verbs },
  2781. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2782. .dac_nids = alc880_asus_dac_nids,
  2783. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2784. .channel_mode = alc880_asus_modes,
  2785. .need_dac_fix = 1,
  2786. .input_mux = &alc880_capture_source,
  2787. },
  2788. [ALC880_ASUS_DIG] = {
  2789. .mixers = { alc880_asus_mixer },
  2790. .init_verbs = { alc880_volume_init_verbs,
  2791. alc880_pin_asus_init_verbs,
  2792. alc880_gpio1_init_verbs },
  2793. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2794. .dac_nids = alc880_asus_dac_nids,
  2795. .dig_out_nid = ALC880_DIGOUT_NID,
  2796. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2797. .channel_mode = alc880_asus_modes,
  2798. .need_dac_fix = 1,
  2799. .input_mux = &alc880_capture_source,
  2800. },
  2801. [ALC880_ASUS_DIG2] = {
  2802. .mixers = { alc880_asus_mixer },
  2803. .init_verbs = { alc880_volume_init_verbs,
  2804. alc880_pin_asus_init_verbs,
  2805. alc880_gpio2_init_verbs }, /* use GPIO2 */
  2806. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2807. .dac_nids = alc880_asus_dac_nids,
  2808. .dig_out_nid = ALC880_DIGOUT_NID,
  2809. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2810. .channel_mode = alc880_asus_modes,
  2811. .need_dac_fix = 1,
  2812. .input_mux = &alc880_capture_source,
  2813. },
  2814. [ALC880_ASUS_W1V] = {
  2815. .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
  2816. .init_verbs = { alc880_volume_init_verbs,
  2817. alc880_pin_asus_init_verbs,
  2818. alc880_gpio1_init_verbs },
  2819. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2820. .dac_nids = alc880_asus_dac_nids,
  2821. .dig_out_nid = ALC880_DIGOUT_NID,
  2822. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2823. .channel_mode = alc880_asus_modes,
  2824. .need_dac_fix = 1,
  2825. .input_mux = &alc880_capture_source,
  2826. },
  2827. [ALC880_UNIWILL_DIG] = {
  2828. .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
  2829. .init_verbs = { alc880_volume_init_verbs,
  2830. alc880_pin_asus_init_verbs },
  2831. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2832. .dac_nids = alc880_asus_dac_nids,
  2833. .dig_out_nid = ALC880_DIGOUT_NID,
  2834. .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
  2835. .channel_mode = alc880_asus_modes,
  2836. .need_dac_fix = 1,
  2837. .input_mux = &alc880_capture_source,
  2838. },
  2839. [ALC880_UNIWILL] = {
  2840. .mixers = { alc880_uniwill_mixer },
  2841. .init_verbs = { alc880_volume_init_verbs,
  2842. alc880_uniwill_init_verbs },
  2843. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2844. .dac_nids = alc880_asus_dac_nids,
  2845. .dig_out_nid = ALC880_DIGOUT_NID,
  2846. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2847. .channel_mode = alc880_threestack_modes,
  2848. .need_dac_fix = 1,
  2849. .input_mux = &alc880_capture_source,
  2850. .unsol_event = alc880_uniwill_unsol_event,
  2851. .init_hook = alc880_uniwill_automute,
  2852. },
  2853. [ALC880_UNIWILL_P53] = {
  2854. .mixers = { alc880_uniwill_p53_mixer },
  2855. .init_verbs = { alc880_volume_init_verbs,
  2856. alc880_uniwill_p53_init_verbs },
  2857. .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
  2858. .dac_nids = alc880_asus_dac_nids,
  2859. .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
  2860. .channel_mode = alc880_threestack_modes,
  2861. .input_mux = &alc880_capture_source,
  2862. .unsol_event = alc880_uniwill_p53_unsol_event,
  2863. .init_hook = alc880_uniwill_p53_hp_automute,
  2864. },
  2865. [ALC880_FUJITSU] = {
  2866. .mixers = { alc880_fujitsu_mixer,
  2867. alc880_pcbeep_mixer, },
  2868. .init_verbs = { alc880_volume_init_verbs,
  2869. alc880_uniwill_p53_init_verbs,
  2870. alc880_beep_init_verbs },
  2871. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2872. .dac_nids = alc880_dac_nids,
  2873. .dig_out_nid = ALC880_DIGOUT_NID,
  2874. .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
  2875. .channel_mode = alc880_2_jack_modes,
  2876. .input_mux = &alc880_capture_source,
  2877. .unsol_event = alc880_uniwill_p53_unsol_event,
  2878. .init_hook = alc880_uniwill_p53_hp_automute,
  2879. },
  2880. [ALC880_CLEVO] = {
  2881. .mixers = { alc880_three_stack_mixer },
  2882. .init_verbs = { alc880_volume_init_verbs,
  2883. alc880_pin_clevo_init_verbs },
  2884. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2885. .dac_nids = alc880_dac_nids,
  2886. .hp_nid = 0x03,
  2887. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  2888. .channel_mode = alc880_threestack_modes,
  2889. .need_dac_fix = 1,
  2890. .input_mux = &alc880_capture_source,
  2891. },
  2892. [ALC880_LG] = {
  2893. .mixers = { alc880_lg_mixer },
  2894. .init_verbs = { alc880_volume_init_verbs,
  2895. alc880_lg_init_verbs },
  2896. .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
  2897. .dac_nids = alc880_lg_dac_nids,
  2898. .dig_out_nid = ALC880_DIGOUT_NID,
  2899. .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
  2900. .channel_mode = alc880_lg_ch_modes,
  2901. .need_dac_fix = 1,
  2902. .input_mux = &alc880_lg_capture_source,
  2903. .unsol_event = alc880_lg_unsol_event,
  2904. .init_hook = alc880_lg_automute,
  2905. #ifdef CONFIG_SND_HDA_POWER_SAVE
  2906. .loopbacks = alc880_lg_loopbacks,
  2907. #endif
  2908. },
  2909. [ALC880_LG_LW] = {
  2910. .mixers = { alc880_lg_lw_mixer },
  2911. .init_verbs = { alc880_volume_init_verbs,
  2912. alc880_lg_lw_init_verbs },
  2913. .num_dacs = ARRAY_SIZE(alc880_dac_nids),
  2914. .dac_nids = alc880_dac_nids,
  2915. .dig_out_nid = ALC880_DIGOUT_NID,
  2916. .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
  2917. .channel_mode = alc880_lg_lw_modes,
  2918. .input_mux = &alc880_lg_lw_capture_source,
  2919. .unsol_event = alc880_lg_lw_unsol_event,
  2920. .init_hook = alc880_lg_lw_automute,
  2921. },
  2922. #ifdef CONFIG_SND_DEBUG
  2923. [ALC880_TEST] = {
  2924. .mixers = { alc880_test_mixer },
  2925. .init_verbs = { alc880_test_init_verbs },
  2926. .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
  2927. .dac_nids = alc880_test_dac_nids,
  2928. .dig_out_nid = ALC880_DIGOUT_NID,
  2929. .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
  2930. .channel_mode = alc880_test_modes,
  2931. .input_mux = &alc880_test_capture_source,
  2932. },
  2933. #endif
  2934. };
  2935. /*
  2936. * Automatic parse of I/O pins from the BIOS configuration
  2937. */
  2938. #define NUM_CONTROL_ALLOC 32
  2939. #define NUM_VERB_ALLOC 32
  2940. enum {
  2941. ALC_CTL_WIDGET_VOL,
  2942. ALC_CTL_WIDGET_MUTE,
  2943. ALC_CTL_BIND_MUTE,
  2944. };
  2945. static struct snd_kcontrol_new alc880_control_templates[] = {
  2946. HDA_CODEC_VOLUME(NULL, 0, 0, 0),
  2947. HDA_CODEC_MUTE(NULL, 0, 0, 0),
  2948. HDA_BIND_MUTE(NULL, 0, 0, 0),
  2949. };
  2950. /* add dynamic controls */
  2951. static int add_control(struct alc_spec *spec, int type, const char *name,
  2952. unsigned long val)
  2953. {
  2954. struct snd_kcontrol_new *knew;
  2955. if (spec->num_kctl_used >= spec->num_kctl_alloc) {
  2956. int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
  2957. /* array + terminator */
  2958. knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
  2959. if (!knew)
  2960. return -ENOMEM;
  2961. if (spec->kctl_alloc) {
  2962. memcpy(knew, spec->kctl_alloc,
  2963. sizeof(*knew) * spec->num_kctl_alloc);
  2964. kfree(spec->kctl_alloc);
  2965. }
  2966. spec->kctl_alloc = knew;
  2967. spec->num_kctl_alloc = num;
  2968. }
  2969. knew = &spec->kctl_alloc[spec->num_kctl_used];
  2970. *knew = alc880_control_templates[type];
  2971. knew->name = kstrdup(name, GFP_KERNEL);
  2972. if (!knew->name)
  2973. return -ENOMEM;
  2974. knew->private_value = val;
  2975. spec->num_kctl_used++;
  2976. return 0;
  2977. }
  2978. #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
  2979. #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
  2980. #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
  2981. #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
  2982. #define alc880_is_input_pin(nid) ((nid) >= 0x18)
  2983. #define alc880_input_pin_idx(nid) ((nid) - 0x18)
  2984. #define alc880_idx_to_dac(nid) ((nid) + 0x02)
  2985. #define alc880_dac_to_idx(nid) ((nid) - 0x02)
  2986. #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
  2987. #define alc880_idx_to_selector(nid) ((nid) + 0x10)
  2988. #define ALC880_PIN_CD_NID 0x1c
  2989. /* fill in the dac_nids table from the parsed pin configuration */
  2990. static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
  2991. const struct auto_pin_cfg *cfg)
  2992. {
  2993. hda_nid_t nid;
  2994. int assigned[4];
  2995. int i, j;
  2996. memset(assigned, 0, sizeof(assigned));
  2997. spec->multiout.dac_nids = spec->private_dac_nids;
  2998. /* check the pins hardwired to audio widget */
  2999. for (i = 0; i < cfg->line_outs; i++) {
  3000. nid = cfg->line_out_pins[i];
  3001. if (alc880_is_fixed_pin(nid)) {
  3002. int idx = alc880_fixed_pin_idx(nid);
  3003. spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
  3004. assigned[idx] = 1;
  3005. }
  3006. }
  3007. /* left pins can be connect to any audio widget */
  3008. for (i = 0; i < cfg->line_outs; i++) {
  3009. nid = cfg->line_out_pins[i];
  3010. if (alc880_is_fixed_pin(nid))
  3011. continue;
  3012. /* search for an empty channel */
  3013. for (j = 0; j < cfg->line_outs; j++) {
  3014. if (!assigned[j]) {
  3015. spec->multiout.dac_nids[i] =
  3016. alc880_idx_to_dac(j);
  3017. assigned[j] = 1;
  3018. break;
  3019. }
  3020. }
  3021. }
  3022. spec->multiout.num_dacs = cfg->line_outs;
  3023. return 0;
  3024. }
  3025. /* add playback controls from the parsed DAC table */
  3026. static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
  3027. const struct auto_pin_cfg *cfg)
  3028. {
  3029. char name[32];
  3030. static const char *chname[4] = {
  3031. "Front", "Surround", NULL /*CLFE*/, "Side"
  3032. };
  3033. hda_nid_t nid;
  3034. int i, err;
  3035. for (i = 0; i < cfg->line_outs; i++) {
  3036. if (!spec->multiout.dac_nids[i])
  3037. continue;
  3038. nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
  3039. if (i == 2) {
  3040. /* Center/LFE */
  3041. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  3042. "Center Playback Volume",
  3043. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  3044. HDA_OUTPUT));
  3045. if (err < 0)
  3046. return err;
  3047. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  3048. "LFE Playback Volume",
  3049. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  3050. HDA_OUTPUT));
  3051. if (err < 0)
  3052. return err;
  3053. err = add_control(spec, ALC_CTL_BIND_MUTE,
  3054. "Center Playback Switch",
  3055. HDA_COMPOSE_AMP_VAL(nid, 1, 2,
  3056. HDA_INPUT));
  3057. if (err < 0)
  3058. return err;
  3059. err = add_control(spec, ALC_CTL_BIND_MUTE,
  3060. "LFE Playback Switch",
  3061. HDA_COMPOSE_AMP_VAL(nid, 2, 2,
  3062. HDA_INPUT));
  3063. if (err < 0)
  3064. return err;
  3065. } else {
  3066. sprintf(name, "%s Playback Volume", chname[i]);
  3067. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  3068. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  3069. HDA_OUTPUT));
  3070. if (err < 0)
  3071. return err;
  3072. sprintf(name, "%s Playback Switch", chname[i]);
  3073. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  3074. HDA_COMPOSE_AMP_VAL(nid, 3, 2,
  3075. HDA_INPUT));
  3076. if (err < 0)
  3077. return err;
  3078. }
  3079. }
  3080. return 0;
  3081. }
  3082. /* add playback controls for speaker and HP outputs */
  3083. static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
  3084. const char *pfx)
  3085. {
  3086. hda_nid_t nid;
  3087. int err;
  3088. char name[32];
  3089. if (!pin)
  3090. return 0;
  3091. if (alc880_is_fixed_pin(pin)) {
  3092. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  3093. /* specify the DAC as the extra output */
  3094. if (!spec->multiout.hp_nid)
  3095. spec->multiout.hp_nid = nid;
  3096. else
  3097. spec->multiout.extra_out_nid[0] = nid;
  3098. /* control HP volume/switch on the output mixer amp */
  3099. nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
  3100. sprintf(name, "%s Playback Volume", pfx);
  3101. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  3102. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  3103. if (err < 0)
  3104. return err;
  3105. sprintf(name, "%s Playback Switch", pfx);
  3106. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  3107. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
  3108. if (err < 0)
  3109. return err;
  3110. } else if (alc880_is_multi_pin(pin)) {
  3111. /* set manual connection */
  3112. /* we have only a switch on HP-out PIN */
  3113. sprintf(name, "%s Playback Switch", pfx);
  3114. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  3115. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  3116. if (err < 0)
  3117. return err;
  3118. }
  3119. return 0;
  3120. }
  3121. /* create input playback/capture controls for the given pin */
  3122. static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
  3123. const char *ctlname,
  3124. int idx, hda_nid_t mix_nid)
  3125. {
  3126. char name[32];
  3127. int err;
  3128. sprintf(name, "%s Playback Volume", ctlname);
  3129. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  3130. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  3131. if (err < 0)
  3132. return err;
  3133. sprintf(name, "%s Playback Switch", ctlname);
  3134. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  3135. HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
  3136. if (err < 0)
  3137. return err;
  3138. return 0;
  3139. }
  3140. /* create playback/capture controls for input pins */
  3141. static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
  3142. const struct auto_pin_cfg *cfg)
  3143. {
  3144. struct hda_input_mux *imux = &spec->private_imux;
  3145. int i, err, idx;
  3146. for (i = 0; i < AUTO_PIN_LAST; i++) {
  3147. if (alc880_is_input_pin(cfg->input_pins[i])) {
  3148. idx = alc880_input_pin_idx(cfg->input_pins[i]);
  3149. err = new_analog_input(spec, cfg->input_pins[i],
  3150. auto_pin_cfg_labels[i],
  3151. idx, 0x0b);
  3152. if (err < 0)
  3153. return err;
  3154. imux->items[imux->num_items].label =
  3155. auto_pin_cfg_labels[i];
  3156. imux->items[imux->num_items].index =
  3157. alc880_input_pin_idx(cfg->input_pins[i]);
  3158. imux->num_items++;
  3159. }
  3160. }
  3161. return 0;
  3162. }
  3163. static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
  3164. unsigned int pin_type)
  3165. {
  3166. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  3167. pin_type);
  3168. /* unmute pin */
  3169. snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 0xff, 0x00);
  3170. }
  3171. static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
  3172. hda_nid_t nid, int pin_type,
  3173. int dac_idx)
  3174. {
  3175. alc_set_pin_output(codec, nid, pin_type);
  3176. /* need the manual connection? */
  3177. if (alc880_is_multi_pin(nid)) {
  3178. struct alc_spec *spec = codec->spec;
  3179. int idx = alc880_multi_pin_idx(nid);
  3180. snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
  3181. AC_VERB_SET_CONNECT_SEL,
  3182. alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
  3183. }
  3184. }
  3185. static int get_pin_type(int line_out_type)
  3186. {
  3187. if (line_out_type == AUTO_PIN_HP_OUT)
  3188. return PIN_HP;
  3189. else
  3190. return PIN_OUT;
  3191. }
  3192. static void alc880_auto_init_multi_out(struct hda_codec *codec)
  3193. {
  3194. struct alc_spec *spec = codec->spec;
  3195. int i;
  3196. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  3197. for (i = 0; i < spec->autocfg.line_outs; i++) {
  3198. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  3199. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  3200. alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
  3201. }
  3202. }
  3203. static void alc880_auto_init_extra_out(struct hda_codec *codec)
  3204. {
  3205. struct alc_spec *spec = codec->spec;
  3206. hda_nid_t pin;
  3207. pin = spec->autocfg.speaker_pins[0];
  3208. if (pin) /* connect to front */
  3209. alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  3210. pin = spec->autocfg.hp_pins[0];
  3211. if (pin) /* connect to front */
  3212. alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  3213. }
  3214. static void alc880_auto_init_analog_input(struct hda_codec *codec)
  3215. {
  3216. struct alc_spec *spec = codec->spec;
  3217. int i;
  3218. for (i = 0; i < AUTO_PIN_LAST; i++) {
  3219. hda_nid_t nid = spec->autocfg.input_pins[i];
  3220. if (alc880_is_input_pin(nid)) {
  3221. snd_hda_codec_write(codec, nid, 0,
  3222. AC_VERB_SET_PIN_WIDGET_CONTROL,
  3223. i <= AUTO_PIN_FRONT_MIC ?
  3224. PIN_VREF80 : PIN_IN);
  3225. if (nid != ALC880_PIN_CD_NID)
  3226. snd_hda_codec_write(codec, nid, 0,
  3227. AC_VERB_SET_AMP_GAIN_MUTE,
  3228. AMP_OUT_MUTE);
  3229. }
  3230. }
  3231. }
  3232. /* parse the BIOS configuration and set up the alc_spec */
  3233. /* return 1 if successful, 0 if the proper config is not found,
  3234. * or a negative error code
  3235. */
  3236. static int alc880_parse_auto_config(struct hda_codec *codec)
  3237. {
  3238. struct alc_spec *spec = codec->spec;
  3239. int err;
  3240. static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
  3241. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  3242. alc880_ignore);
  3243. if (err < 0)
  3244. return err;
  3245. if (!spec->autocfg.line_outs)
  3246. return 0; /* can't find valid BIOS pin config */
  3247. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  3248. if (err < 0)
  3249. return err;
  3250. err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
  3251. if (err < 0)
  3252. return err;
  3253. err = alc880_auto_create_extra_out(spec,
  3254. spec->autocfg.speaker_pins[0],
  3255. "Speaker");
  3256. if (err < 0)
  3257. return err;
  3258. err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
  3259. "Headphone");
  3260. if (err < 0)
  3261. return err;
  3262. err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
  3263. if (err < 0)
  3264. return err;
  3265. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  3266. if (spec->autocfg.dig_out_pin)
  3267. spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
  3268. if (spec->autocfg.dig_in_pin)
  3269. spec->dig_in_nid = ALC880_DIGIN_NID;
  3270. if (spec->kctl_alloc)
  3271. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  3272. spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
  3273. spec->num_mux_defs = 1;
  3274. spec->input_mux = &spec->private_imux;
  3275. return 1;
  3276. }
  3277. /* additional initialization for auto-configuration model */
  3278. static void alc880_auto_init(struct hda_codec *codec)
  3279. {
  3280. struct alc_spec *spec = codec->spec;
  3281. alc880_auto_init_multi_out(codec);
  3282. alc880_auto_init_extra_out(codec);
  3283. alc880_auto_init_analog_input(codec);
  3284. if (spec->unsol_event)
  3285. alc_sku_automute(codec);
  3286. }
  3287. /*
  3288. * OK, here we have finally the patch for ALC880
  3289. */
  3290. static int patch_alc880(struct hda_codec *codec)
  3291. {
  3292. struct alc_spec *spec;
  3293. int board_config;
  3294. int err;
  3295. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  3296. if (spec == NULL)
  3297. return -ENOMEM;
  3298. codec->spec = spec;
  3299. board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
  3300. alc880_models,
  3301. alc880_cfg_tbl);
  3302. if (board_config < 0) {
  3303. printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
  3304. "trying auto-probe from BIOS...\n");
  3305. board_config = ALC880_AUTO;
  3306. }
  3307. if (board_config == ALC880_AUTO) {
  3308. /* automatic parse from the BIOS config */
  3309. err = alc880_parse_auto_config(codec);
  3310. if (err < 0) {
  3311. alc_free(codec);
  3312. return err;
  3313. } else if (!err) {
  3314. printk(KERN_INFO
  3315. "hda_codec: Cannot set up configuration "
  3316. "from BIOS. Using 3-stack mode...\n");
  3317. board_config = ALC880_3ST;
  3318. }
  3319. }
  3320. if (board_config != ALC880_AUTO)
  3321. setup_preset(spec, &alc880_presets[board_config]);
  3322. spec->stream_name_analog = "ALC880 Analog";
  3323. spec->stream_analog_playback = &alc880_pcm_analog_playback;
  3324. spec->stream_analog_capture = &alc880_pcm_analog_capture;
  3325. spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
  3326. spec->stream_name_digital = "ALC880 Digital";
  3327. spec->stream_digital_playback = &alc880_pcm_digital_playback;
  3328. spec->stream_digital_capture = &alc880_pcm_digital_capture;
  3329. if (!spec->adc_nids && spec->input_mux) {
  3330. /* check whether NID 0x07 is valid */
  3331. unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
  3332. /* get type */
  3333. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  3334. if (wcap != AC_WID_AUD_IN) {
  3335. spec->adc_nids = alc880_adc_nids_alt;
  3336. spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
  3337. spec->mixers[spec->num_mixers] =
  3338. alc880_capture_alt_mixer;
  3339. spec->num_mixers++;
  3340. } else {
  3341. spec->adc_nids = alc880_adc_nids;
  3342. spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
  3343. spec->mixers[spec->num_mixers] = alc880_capture_mixer;
  3344. spec->num_mixers++;
  3345. }
  3346. }
  3347. spec->vmaster_nid = 0x0c;
  3348. codec->patch_ops = alc_patch_ops;
  3349. if (board_config == ALC880_AUTO)
  3350. spec->init_hook = alc880_auto_init;
  3351. #ifdef CONFIG_SND_HDA_POWER_SAVE
  3352. if (!spec->loopback.amplist)
  3353. spec->loopback.amplist = alc880_loopbacks;
  3354. #endif
  3355. return 0;
  3356. }
  3357. /*
  3358. * ALC260 support
  3359. */
  3360. static hda_nid_t alc260_dac_nids[1] = {
  3361. /* front */
  3362. 0x02,
  3363. };
  3364. static hda_nid_t alc260_adc_nids[1] = {
  3365. /* ADC0 */
  3366. 0x04,
  3367. };
  3368. static hda_nid_t alc260_adc_nids_alt[1] = {
  3369. /* ADC1 */
  3370. 0x05,
  3371. };
  3372. static hda_nid_t alc260_hp_adc_nids[2] = {
  3373. /* ADC1, 0 */
  3374. 0x05, 0x04
  3375. };
  3376. /* NIDs used when simultaneous access to both ADCs makes sense. Note that
  3377. * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
  3378. */
  3379. static hda_nid_t alc260_dual_adc_nids[2] = {
  3380. /* ADC0, ADC1 */
  3381. 0x04, 0x05
  3382. };
  3383. #define ALC260_DIGOUT_NID 0x03
  3384. #define ALC260_DIGIN_NID 0x06
  3385. static struct hda_input_mux alc260_capture_source = {
  3386. .num_items = 4,
  3387. .items = {
  3388. { "Mic", 0x0 },
  3389. { "Front Mic", 0x1 },
  3390. { "Line", 0x2 },
  3391. { "CD", 0x4 },
  3392. },
  3393. };
  3394. /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
  3395. * headphone jack and the internal CD lines since these are the only pins at
  3396. * which audio can appear. For flexibility, also allow the option of
  3397. * recording the mixer output on the second ADC (ADC0 doesn't have a
  3398. * connection to the mixer output).
  3399. */
  3400. static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
  3401. {
  3402. .num_items = 3,
  3403. .items = {
  3404. { "Mic/Line", 0x0 },
  3405. { "CD", 0x4 },
  3406. { "Headphone", 0x2 },
  3407. },
  3408. },
  3409. {
  3410. .num_items = 4,
  3411. .items = {
  3412. { "Mic/Line", 0x0 },
  3413. { "CD", 0x4 },
  3414. { "Headphone", 0x2 },
  3415. { "Mixer", 0x5 },
  3416. },
  3417. },
  3418. };
  3419. /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
  3420. * the Fujitsu S702x, but jacks are marked differently.
  3421. */
  3422. static struct hda_input_mux alc260_acer_capture_sources[2] = {
  3423. {
  3424. .num_items = 4,
  3425. .items = {
  3426. { "Mic", 0x0 },
  3427. { "Line", 0x2 },
  3428. { "CD", 0x4 },
  3429. { "Headphone", 0x5 },
  3430. },
  3431. },
  3432. {
  3433. .num_items = 5,
  3434. .items = {
  3435. { "Mic", 0x0 },
  3436. { "Line", 0x2 },
  3437. { "CD", 0x4 },
  3438. { "Headphone", 0x6 },
  3439. { "Mixer", 0x5 },
  3440. },
  3441. },
  3442. };
  3443. /*
  3444. * This is just place-holder, so there's something for alc_build_pcms to look
  3445. * at when it calculates the maximum number of channels. ALC260 has no mixer
  3446. * element which allows changing the channel mode, so the verb list is
  3447. * never used.
  3448. */
  3449. static struct hda_channel_mode alc260_modes[1] = {
  3450. { 2, NULL },
  3451. };
  3452. /* Mixer combinations
  3453. *
  3454. * basic: base_output + input + pc_beep + capture
  3455. * HP: base_output + input + capture_alt
  3456. * HP_3013: hp_3013 + input + capture
  3457. * fujitsu: fujitsu + capture
  3458. * acer: acer + capture
  3459. */
  3460. static struct snd_kcontrol_new alc260_base_output_mixer[] = {
  3461. HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3462. HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
  3463. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3464. HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
  3465. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  3466. HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
  3467. { } /* end */
  3468. };
  3469. static struct snd_kcontrol_new alc260_input_mixer[] = {
  3470. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3471. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3472. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3473. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3474. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3475. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3476. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
  3477. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
  3478. { } /* end */
  3479. };
  3480. static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
  3481. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
  3482. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
  3483. { } /* end */
  3484. };
  3485. /* update HP, line and mono out pins according to the master switch */
  3486. static void alc260_hp_master_update(struct hda_codec *codec,
  3487. hda_nid_t hp, hda_nid_t line,
  3488. hda_nid_t mono)
  3489. {
  3490. struct alc_spec *spec = codec->spec;
  3491. unsigned int val = spec->master_sw ? PIN_HP : 0;
  3492. /* change HP and line-out pins */
  3493. snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  3494. val);
  3495. snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  3496. val);
  3497. /* mono (speaker) depending on the HP jack sense */
  3498. val = (val && !spec->jack_present) ? PIN_OUT : 0;
  3499. snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  3500. val);
  3501. }
  3502. static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
  3503. struct snd_ctl_elem_value *ucontrol)
  3504. {
  3505. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  3506. struct alc_spec *spec = codec->spec;
  3507. *ucontrol->value.integer.value = spec->master_sw;
  3508. return 0;
  3509. }
  3510. static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
  3511. struct snd_ctl_elem_value *ucontrol)
  3512. {
  3513. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  3514. struct alc_spec *spec = codec->spec;
  3515. int val = !!*ucontrol->value.integer.value;
  3516. hda_nid_t hp, line, mono;
  3517. if (val == spec->master_sw)
  3518. return 0;
  3519. spec->master_sw = val;
  3520. hp = (kcontrol->private_value >> 16) & 0xff;
  3521. line = (kcontrol->private_value >> 8) & 0xff;
  3522. mono = kcontrol->private_value & 0xff;
  3523. alc260_hp_master_update(codec, hp, line, mono);
  3524. return 1;
  3525. }
  3526. static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
  3527. {
  3528. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3529. .name = "Master Playback Switch",
  3530. .info = snd_ctl_boolean_mono_info,
  3531. .get = alc260_hp_master_sw_get,
  3532. .put = alc260_hp_master_sw_put,
  3533. .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
  3534. },
  3535. HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3536. HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
  3537. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3538. HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
  3539. HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
  3540. HDA_OUTPUT),
  3541. HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
  3542. { } /* end */
  3543. };
  3544. static struct hda_verb alc260_hp_unsol_verbs[] = {
  3545. {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  3546. {},
  3547. };
  3548. static void alc260_hp_automute(struct hda_codec *codec)
  3549. {
  3550. struct alc_spec *spec = codec->spec;
  3551. unsigned int present;
  3552. present = snd_hda_codec_read(codec, 0x10, 0,
  3553. AC_VERB_GET_PIN_SENSE, 0);
  3554. spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
  3555. alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
  3556. }
  3557. static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
  3558. {
  3559. if ((res >> 26) == ALC880_HP_EVENT)
  3560. alc260_hp_automute(codec);
  3561. }
  3562. static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
  3563. {
  3564. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3565. .name = "Master Playback Switch",
  3566. .info = snd_ctl_boolean_mono_info,
  3567. .get = alc260_hp_master_sw_get,
  3568. .put = alc260_hp_master_sw_put,
  3569. .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
  3570. },
  3571. HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3572. HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
  3573. HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
  3574. HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
  3575. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3576. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  3577. HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  3578. HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
  3579. { } /* end */
  3580. };
  3581. static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
  3582. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  3583. {},
  3584. };
  3585. static void alc260_hp_3013_automute(struct hda_codec *codec)
  3586. {
  3587. struct alc_spec *spec = codec->spec;
  3588. unsigned int present;
  3589. present = snd_hda_codec_read(codec, 0x15, 0,
  3590. AC_VERB_GET_PIN_SENSE, 0);
  3591. spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
  3592. alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
  3593. }
  3594. static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
  3595. unsigned int res)
  3596. {
  3597. if ((res >> 26) == ALC880_HP_EVENT)
  3598. alc260_hp_3013_automute(codec);
  3599. }
  3600. /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
  3601. * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
  3602. */
  3603. static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
  3604. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3605. HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
  3606. ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3607. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3608. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3609. HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
  3610. HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
  3611. ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3612. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3613. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3614. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  3615. HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
  3616. { } /* end */
  3617. };
  3618. /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
  3619. * versions of the ALC260 don't act on requests to enable mic bias from NID
  3620. * 0x0f (used to drive the headphone jack in these laptops). The ALC260
  3621. * datasheet doesn't mention this restriction. At this stage it's not clear
  3622. * whether this behaviour is intentional or is a hardware bug in chip
  3623. * revisions available in early 2006. Therefore for now allow the
  3624. * "Headphone Jack Mode" control to span all choices, but if it turns out
  3625. * that the lack of mic bias for this NID is intentional we could change the
  3626. * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
  3627. *
  3628. * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
  3629. * don't appear to make the mic bias available from the "line" jack, even
  3630. * though the NID used for this jack (0x14) can supply it. The theory is
  3631. * that perhaps Acer have included blocking capacitors between the ALC260
  3632. * and the output jack. If this turns out to be the case for all such
  3633. * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
  3634. * to ALC_PIN_DIR_INOUT_NOMICBIAS.
  3635. *
  3636. * The C20x Tablet series have a mono internal speaker which is controlled
  3637. * via the chip's Mono sum widget and pin complex, so include the necessary
  3638. * controls for such models. On models without a "mono speaker" the control
  3639. * won't do anything.
  3640. */
  3641. static struct snd_kcontrol_new alc260_acer_mixer[] = {
  3642. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3643. HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
  3644. ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
  3645. HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
  3646. HDA_OUTPUT),
  3647. HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
  3648. HDA_INPUT),
  3649. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3650. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3651. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3652. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3653. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3654. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3655. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3656. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3657. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3658. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3659. { } /* end */
  3660. };
  3661. /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
  3662. * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
  3663. */
  3664. static struct snd_kcontrol_new alc260_will_mixer[] = {
  3665. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3666. HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
  3667. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3668. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3669. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3670. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3671. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3672. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3673. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  3674. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  3675. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  3676. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  3677. { } /* end */
  3678. };
  3679. /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
  3680. * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
  3681. */
  3682. static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
  3683. HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  3684. HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
  3685. HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
  3686. HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
  3687. ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
  3688. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
  3689. HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
  3690. HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
  3691. HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
  3692. ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
  3693. { } /* end */
  3694. };
  3695. /* capture mixer elements */
  3696. static struct snd_kcontrol_new alc260_capture_mixer[] = {
  3697. HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
  3698. HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
  3699. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
  3700. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
  3701. {
  3702. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3703. /* The multiple "Capture Source" controls confuse alsamixer
  3704. * So call somewhat different..
  3705. */
  3706. /* .name = "Capture Source", */
  3707. .name = "Input Source",
  3708. .count = 2,
  3709. .info = alc_mux_enum_info,
  3710. .get = alc_mux_enum_get,
  3711. .put = alc_mux_enum_put,
  3712. },
  3713. { } /* end */
  3714. };
  3715. static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
  3716. HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
  3717. HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
  3718. {
  3719. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  3720. /* The multiple "Capture Source" controls confuse alsamixer
  3721. * So call somewhat different..
  3722. */
  3723. /* .name = "Capture Source", */
  3724. .name = "Input Source",
  3725. .count = 1,
  3726. .info = alc_mux_enum_info,
  3727. .get = alc_mux_enum_get,
  3728. .put = alc_mux_enum_put,
  3729. },
  3730. { } /* end */
  3731. };
  3732. /*
  3733. * initialization verbs
  3734. */
  3735. static struct hda_verb alc260_init_verbs[] = {
  3736. /* Line In pin widget for input */
  3737. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3738. /* CD pin widget for input */
  3739. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3740. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3741. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3742. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3743. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  3744. /* LINE-2 is used for line-out in rear */
  3745. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3746. /* select line-out */
  3747. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
  3748. /* LINE-OUT pin */
  3749. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3750. /* enable HP */
  3751. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3752. /* enable Mono */
  3753. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3754. /* mute capture amp left and right */
  3755. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3756. /* set connection select to line in (default select for this ADC) */
  3757. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3758. /* mute capture amp left and right */
  3759. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3760. /* set connection select to line in (default select for this ADC) */
  3761. {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
  3762. /* set vol=0 Line-Out mixer amp left and right */
  3763. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3764. /* unmute pin widget amp left and right (no gain on this amp) */
  3765. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3766. /* set vol=0 HP mixer amp left and right */
  3767. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3768. /* unmute pin widget amp left and right (no gain on this amp) */
  3769. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3770. /* set vol=0 Mono mixer amp left and right */
  3771. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3772. /* unmute pin widget amp left and right (no gain on this amp) */
  3773. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3774. /* unmute LINE-2 out pin */
  3775. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3776. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3777. * Line In 2 = 0x03
  3778. */
  3779. /* mute analog inputs */
  3780. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3781. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3782. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3783. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3784. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3785. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3786. /* mute Front out path */
  3787. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3788. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3789. /* mute Headphone out path */
  3790. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3791. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3792. /* mute Mono out path */
  3793. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3794. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3795. { }
  3796. };
  3797. #if 0 /* should be identical with alc260_init_verbs? */
  3798. static struct hda_verb alc260_hp_init_verbs[] = {
  3799. /* Headphone and output */
  3800. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  3801. /* mono output */
  3802. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3803. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3804. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3805. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3806. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3807. /* Line In pin widget for input */
  3808. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3809. /* Line-2 pin widget for output */
  3810. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3811. /* CD pin widget for input */
  3812. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3813. /* unmute amp left and right */
  3814. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
  3815. /* set connection select to line in (default select for this ADC) */
  3816. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3817. /* unmute Line-Out mixer amp left and right (volume = 0) */
  3818. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3819. /* mute pin widget amp left and right (no gain on this amp) */
  3820. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3821. /* unmute HP mixer amp left and right (volume = 0) */
  3822. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3823. /* mute pin widget amp left and right (no gain on this amp) */
  3824. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3825. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3826. * Line In 2 = 0x03
  3827. */
  3828. /* mute analog inputs */
  3829. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3830. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3831. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3832. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3833. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3834. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3835. /* Unmute Front out path */
  3836. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3837. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3838. /* Unmute Headphone out path */
  3839. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3840. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3841. /* Unmute Mono out path */
  3842. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3843. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3844. { }
  3845. };
  3846. #endif
  3847. static struct hda_verb alc260_hp_3013_init_verbs[] = {
  3848. /* Line out and output */
  3849. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3850. /* mono output */
  3851. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  3852. /* Mic1 (rear panel) pin widget for input and vref at 80% */
  3853. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3854. /* Mic2 (front panel) pin widget for input and vref at 80% */
  3855. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  3856. /* Line In pin widget for input */
  3857. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3858. /* Headphone pin widget for output */
  3859. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  3860. /* CD pin widget for input */
  3861. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  3862. /* unmute amp left and right */
  3863. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
  3864. /* set connection select to line in (default select for this ADC) */
  3865. {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
  3866. /* unmute Line-Out mixer amp left and right (volume = 0) */
  3867. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3868. /* mute pin widget amp left and right (no gain on this amp) */
  3869. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3870. /* unmute HP mixer amp left and right (volume = 0) */
  3871. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
  3872. /* mute pin widget amp left and right (no gain on this amp) */
  3873. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  3874. /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
  3875. * Line In 2 = 0x03
  3876. */
  3877. /* mute analog inputs */
  3878. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3879. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3880. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  3881. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  3882. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  3883. /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
  3884. /* Unmute Front out path */
  3885. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3886. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3887. /* Unmute Headphone out path */
  3888. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3889. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3890. /* Unmute Mono out path */
  3891. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  3892. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  3893. { }
  3894. };
  3895. /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
  3896. * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
  3897. * audio = 0x16, internal speaker = 0x10.
  3898. */
  3899. static struct hda_verb alc260_fujitsu_init_verbs[] = {
  3900. /* Disable all GPIOs */
  3901. {0x01, AC_VERB_SET_GPIO_MASK, 0},
  3902. /* Internal speaker is connected to headphone pin */
  3903. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3904. /* Headphone/Line-out jack connects to Line1 pin; make it an output */
  3905. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  3906. /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
  3907. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3908. /* Ensure all other unused pins are disabled and muted. */
  3909. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3910. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3911. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3912. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3913. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3914. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3915. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3916. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3917. /* Disable digital (SPDIF) pins */
  3918. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3919. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3920. /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
  3921. * when acting as an output.
  3922. */
  3923. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  3924. /* Start with output sum widgets muted and their output gains at min */
  3925. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3926. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3927. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3928. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3929. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3930. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3931. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3932. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  3933. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  3934. /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
  3935. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3936. /* Unmute Line1 pin widget output buffer since it starts as an output.
  3937. * If the pin mode is changed by the user the pin mode control will
  3938. * take care of enabling the pin's input/output buffers as needed.
  3939. * Therefore there's no need to enable the input buffer at this
  3940. * stage.
  3941. */
  3942. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  3943. /* Unmute input buffer of pin widget used for Line-in (no equiv
  3944. * mixer ctrl)
  3945. */
  3946. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  3947. /* Mute capture amp left and right */
  3948. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3949. /* Set ADC connection select to match default mixer setting - line
  3950. * in (on mic1 pin)
  3951. */
  3952. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  3953. /* Do the same for the second ADC: mute capture input amp and
  3954. * set ADC connection to line in (on mic1 pin)
  3955. */
  3956. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3957. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  3958. /* Mute all inputs to mixer widget (even unconnected ones) */
  3959. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  3960. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  3961. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  3962. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  3963. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  3964. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  3965. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  3966. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  3967. { }
  3968. };
  3969. /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
  3970. * similar laptops (adapted from Fujitsu init verbs).
  3971. */
  3972. static struct hda_verb alc260_acer_init_verbs[] = {
  3973. /* On TravelMate laptops, GPIO 0 enables the internal speaker and
  3974. * the headphone jack. Turn this on and rely on the standard mute
  3975. * methods whenever the user wants to turn these outputs off.
  3976. */
  3977. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  3978. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  3979. {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
  3980. /* Internal speaker/Headphone jack is connected to Line-out pin */
  3981. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3982. /* Internal microphone/Mic jack is connected to Mic1 pin */
  3983. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  3984. /* Line In jack is connected to Line1 pin */
  3985. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  3986. /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
  3987. {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  3988. /* Ensure all other unused pins are disabled and muted. */
  3989. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3990. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3991. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3992. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3993. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
  3994. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  3995. /* Disable digital (SPDIF) pins */
  3996. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3997. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  3998. /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
  3999. * bus when acting as outputs.
  4000. */
  4001. {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
  4002. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  4003. /* Start with output sum widgets muted and their output gains at min */
  4004. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4005. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4006. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4007. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4008. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4009. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4010. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4011. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4012. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4013. /* Unmute Line-out pin widget amp left and right
  4014. * (no equiv mixer ctrl)
  4015. */
  4016. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4017. /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
  4018. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4019. /* Unmute Mic1 and Line1 pin widget input buffers since they start as
  4020. * inputs. If the pin mode is changed by the user the pin mode control
  4021. * will take care of enabling the pin's input/output buffers as needed.
  4022. * Therefore there's no need to enable the input buffer at this
  4023. * stage.
  4024. */
  4025. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4026. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4027. /* Mute capture amp left and right */
  4028. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4029. /* Set ADC connection select to match default mixer setting - mic
  4030. * (on mic1 pin)
  4031. */
  4032. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  4033. /* Do similar with the second ADC: mute capture input amp and
  4034. * set ADC connection to mic to match ALSA's default state.
  4035. */
  4036. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4037. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  4038. /* Mute all inputs to mixer widget (even unconnected ones) */
  4039. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  4040. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  4041. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  4042. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  4043. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  4044. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  4045. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  4046. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  4047. { }
  4048. };
  4049. static struct hda_verb alc260_will_verbs[] = {
  4050. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  4051. {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
  4052. {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
  4053. {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  4054. {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
  4055. {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
  4056. {}
  4057. };
  4058. static struct hda_verb alc260_replacer_672v_verbs[] = {
  4059. {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
  4060. {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
  4061. {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
  4062. {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  4063. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  4064. {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
  4065. {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  4066. {}
  4067. };
  4068. /* toggle speaker-output according to the hp-jack state */
  4069. static void alc260_replacer_672v_automute(struct hda_codec *codec)
  4070. {
  4071. unsigned int present;
  4072. /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
  4073. present = snd_hda_codec_read(codec, 0x0f, 0,
  4074. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  4075. if (present) {
  4076. snd_hda_codec_write_cache(codec, 0x01, 0,
  4077. AC_VERB_SET_GPIO_DATA, 1);
  4078. snd_hda_codec_write_cache(codec, 0x0f, 0,
  4079. AC_VERB_SET_PIN_WIDGET_CONTROL,
  4080. PIN_HP);
  4081. } else {
  4082. snd_hda_codec_write_cache(codec, 0x01, 0,
  4083. AC_VERB_SET_GPIO_DATA, 0);
  4084. snd_hda_codec_write_cache(codec, 0x0f, 0,
  4085. AC_VERB_SET_PIN_WIDGET_CONTROL,
  4086. PIN_OUT);
  4087. }
  4088. }
  4089. static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
  4090. unsigned int res)
  4091. {
  4092. if ((res >> 26) == ALC880_HP_EVENT)
  4093. alc260_replacer_672v_automute(codec);
  4094. }
  4095. /* Test configuration for debugging, modelled after the ALC880 test
  4096. * configuration.
  4097. */
  4098. #ifdef CONFIG_SND_DEBUG
  4099. static hda_nid_t alc260_test_dac_nids[1] = {
  4100. 0x02,
  4101. };
  4102. static hda_nid_t alc260_test_adc_nids[2] = {
  4103. 0x04, 0x05,
  4104. };
  4105. /* For testing the ALC260, each input MUX needs its own definition since
  4106. * the signal assignments are different. This assumes that the first ADC
  4107. * is NID 0x04.
  4108. */
  4109. static struct hda_input_mux alc260_test_capture_sources[2] = {
  4110. {
  4111. .num_items = 7,
  4112. .items = {
  4113. { "MIC1 pin", 0x0 },
  4114. { "MIC2 pin", 0x1 },
  4115. { "LINE1 pin", 0x2 },
  4116. { "LINE2 pin", 0x3 },
  4117. { "CD pin", 0x4 },
  4118. { "LINE-OUT pin", 0x5 },
  4119. { "HP-OUT pin", 0x6 },
  4120. },
  4121. },
  4122. {
  4123. .num_items = 8,
  4124. .items = {
  4125. { "MIC1 pin", 0x0 },
  4126. { "MIC2 pin", 0x1 },
  4127. { "LINE1 pin", 0x2 },
  4128. { "LINE2 pin", 0x3 },
  4129. { "CD pin", 0x4 },
  4130. { "Mixer", 0x5 },
  4131. { "LINE-OUT pin", 0x6 },
  4132. { "HP-OUT pin", 0x7 },
  4133. },
  4134. },
  4135. };
  4136. static struct snd_kcontrol_new alc260_test_mixer[] = {
  4137. /* Output driver widgets */
  4138. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
  4139. HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
  4140. HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
  4141. HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
  4142. HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
  4143. HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
  4144. /* Modes for retasking pin widgets
  4145. * Note: the ALC260 doesn't seem to act on requests to enable mic
  4146. * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
  4147. * mention this restriction. At this stage it's not clear whether
  4148. * this behaviour is intentional or is a hardware bug in chip
  4149. * revisions available at least up until early 2006. Therefore for
  4150. * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
  4151. * choices, but if it turns out that the lack of mic bias for these
  4152. * NIDs is intentional we could change their modes from
  4153. * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
  4154. */
  4155. ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
  4156. ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
  4157. ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
  4158. ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
  4159. ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
  4160. ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
  4161. /* Loopback mixer controls */
  4162. HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
  4163. HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
  4164. HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
  4165. HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
  4166. HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
  4167. HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
  4168. HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
  4169. HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
  4170. HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
  4171. HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
  4172. HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
  4173. HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
  4174. HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
  4175. HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
  4176. HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
  4177. HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
  4178. /* Controls for GPIO pins, assuming they are configured as outputs */
  4179. ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
  4180. ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
  4181. ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
  4182. ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
  4183. /* Switches to allow the digital IO pins to be enabled. The datasheet
  4184. * is ambigious as to which NID is which; testing on laptops which
  4185. * make this output available should provide clarification.
  4186. */
  4187. ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
  4188. ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
  4189. /* A switch allowing EAPD to be enabled. Some laptops seem to use
  4190. * this output to turn on an external amplifier.
  4191. */
  4192. ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
  4193. ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
  4194. { } /* end */
  4195. };
  4196. static struct hda_verb alc260_test_init_verbs[] = {
  4197. /* Enable all GPIOs as outputs with an initial value of 0 */
  4198. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
  4199. {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
  4200. {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
  4201. /* Enable retasking pins as output, initially without power amp */
  4202. {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4203. {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4204. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4205. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4206. {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4207. {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4208. /* Disable digital (SPDIF) pins initially, but users can enable
  4209. * them via a mixer switch. In the case of SPDIF-out, this initverb
  4210. * payload also sets the generation to 0, output to be in "consumer"
  4211. * PCM format, copyright asserted, no pre-emphasis and no validity
  4212. * control.
  4213. */
  4214. {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
  4215. {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
  4216. /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
  4217. * OUT1 sum bus when acting as an output.
  4218. */
  4219. {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
  4220. {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
  4221. {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
  4222. {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
  4223. /* Start with output sum widgets muted and their output gains at min */
  4224. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4225. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4226. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4227. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4228. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4229. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4230. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4231. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4232. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4233. /* Unmute retasking pin widget output buffers since the default
  4234. * state appears to be output. As the pin mode is changed by the
  4235. * user the pin mode control will take care of enabling the pin's
  4236. * input/output buffers as needed.
  4237. */
  4238. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4239. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4240. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4241. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4242. {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4243. {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4244. /* Also unmute the mono-out pin widget */
  4245. {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4246. /* Mute capture amp left and right */
  4247. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4248. /* Set ADC connection select to match default mixer setting (mic1
  4249. * pin)
  4250. */
  4251. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  4252. /* Do the same for the second ADC: mute capture input amp and
  4253. * set ADC connection to mic1 pin
  4254. */
  4255. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4256. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  4257. /* Mute all inputs to mixer widget (even unconnected ones) */
  4258. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
  4259. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
  4260. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
  4261. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
  4262. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
  4263. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
  4264. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
  4265. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
  4266. { }
  4267. };
  4268. #endif
  4269. #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
  4270. #define alc260_pcm_analog_capture alc880_pcm_analog_capture
  4271. #define alc260_pcm_digital_playback alc880_pcm_digital_playback
  4272. #define alc260_pcm_digital_capture alc880_pcm_digital_capture
  4273. /*
  4274. * for BIOS auto-configuration
  4275. */
  4276. static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
  4277. const char *pfx)
  4278. {
  4279. hda_nid_t nid_vol;
  4280. unsigned long vol_val, sw_val;
  4281. char name[32];
  4282. int err;
  4283. if (nid >= 0x0f && nid < 0x11) {
  4284. nid_vol = nid - 0x7;
  4285. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
  4286. sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
  4287. } else if (nid == 0x11) {
  4288. nid_vol = nid - 0x7;
  4289. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
  4290. sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
  4291. } else if (nid >= 0x12 && nid <= 0x15) {
  4292. nid_vol = 0x08;
  4293. vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
  4294. sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
  4295. } else
  4296. return 0; /* N/A */
  4297. snprintf(name, sizeof(name), "%s Playback Volume", pfx);
  4298. err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
  4299. if (err < 0)
  4300. return err;
  4301. snprintf(name, sizeof(name), "%s Playback Switch", pfx);
  4302. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
  4303. if (err < 0)
  4304. return err;
  4305. return 1;
  4306. }
  4307. /* add playback controls from the parsed DAC table */
  4308. static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
  4309. const struct auto_pin_cfg *cfg)
  4310. {
  4311. hda_nid_t nid;
  4312. int err;
  4313. spec->multiout.num_dacs = 1;
  4314. spec->multiout.dac_nids = spec->private_dac_nids;
  4315. spec->multiout.dac_nids[0] = 0x02;
  4316. nid = cfg->line_out_pins[0];
  4317. if (nid) {
  4318. err = alc260_add_playback_controls(spec, nid, "Front");
  4319. if (err < 0)
  4320. return err;
  4321. }
  4322. nid = cfg->speaker_pins[0];
  4323. if (nid) {
  4324. err = alc260_add_playback_controls(spec, nid, "Speaker");
  4325. if (err < 0)
  4326. return err;
  4327. }
  4328. nid = cfg->hp_pins[0];
  4329. if (nid) {
  4330. err = alc260_add_playback_controls(spec, nid, "Headphone");
  4331. if (err < 0)
  4332. return err;
  4333. }
  4334. return 0;
  4335. }
  4336. /* create playback/capture controls for input pins */
  4337. static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
  4338. const struct auto_pin_cfg *cfg)
  4339. {
  4340. struct hda_input_mux *imux = &spec->private_imux;
  4341. int i, err, idx;
  4342. for (i = 0; i < AUTO_PIN_LAST; i++) {
  4343. if (cfg->input_pins[i] >= 0x12) {
  4344. idx = cfg->input_pins[i] - 0x12;
  4345. err = new_analog_input(spec, cfg->input_pins[i],
  4346. auto_pin_cfg_labels[i], idx,
  4347. 0x07);
  4348. if (err < 0)
  4349. return err;
  4350. imux->items[imux->num_items].label =
  4351. auto_pin_cfg_labels[i];
  4352. imux->items[imux->num_items].index = idx;
  4353. imux->num_items++;
  4354. }
  4355. if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
  4356. idx = cfg->input_pins[i] - 0x09;
  4357. err = new_analog_input(spec, cfg->input_pins[i],
  4358. auto_pin_cfg_labels[i], idx,
  4359. 0x07);
  4360. if (err < 0)
  4361. return err;
  4362. imux->items[imux->num_items].label =
  4363. auto_pin_cfg_labels[i];
  4364. imux->items[imux->num_items].index = idx;
  4365. imux->num_items++;
  4366. }
  4367. }
  4368. return 0;
  4369. }
  4370. static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
  4371. hda_nid_t nid, int pin_type,
  4372. int sel_idx)
  4373. {
  4374. alc_set_pin_output(codec, nid, pin_type);
  4375. /* need the manual connection? */
  4376. if (nid >= 0x12) {
  4377. int idx = nid - 0x12;
  4378. snd_hda_codec_write(codec, idx + 0x0b, 0,
  4379. AC_VERB_SET_CONNECT_SEL, sel_idx);
  4380. }
  4381. }
  4382. static void alc260_auto_init_multi_out(struct hda_codec *codec)
  4383. {
  4384. struct alc_spec *spec = codec->spec;
  4385. hda_nid_t nid;
  4386. alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
  4387. nid = spec->autocfg.line_out_pins[0];
  4388. if (nid) {
  4389. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  4390. alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
  4391. }
  4392. nid = spec->autocfg.speaker_pins[0];
  4393. if (nid)
  4394. alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
  4395. nid = spec->autocfg.hp_pins[0];
  4396. if (nid)
  4397. alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
  4398. }
  4399. #define ALC260_PIN_CD_NID 0x16
  4400. static void alc260_auto_init_analog_input(struct hda_codec *codec)
  4401. {
  4402. struct alc_spec *spec = codec->spec;
  4403. int i;
  4404. for (i = 0; i < AUTO_PIN_LAST; i++) {
  4405. hda_nid_t nid = spec->autocfg.input_pins[i];
  4406. if (nid >= 0x12) {
  4407. snd_hda_codec_write(codec, nid, 0,
  4408. AC_VERB_SET_PIN_WIDGET_CONTROL,
  4409. i <= AUTO_PIN_FRONT_MIC ?
  4410. PIN_VREF80 : PIN_IN);
  4411. if (nid != ALC260_PIN_CD_NID)
  4412. snd_hda_codec_write(codec, nid, 0,
  4413. AC_VERB_SET_AMP_GAIN_MUTE,
  4414. AMP_OUT_MUTE);
  4415. }
  4416. }
  4417. }
  4418. /*
  4419. * generic initialization of ADC, input mixers and output mixers
  4420. */
  4421. static struct hda_verb alc260_volume_init_verbs[] = {
  4422. /*
  4423. * Unmute ADC0-1 and set the default input to mic-in
  4424. */
  4425. {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
  4426. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4427. {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
  4428. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4429. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  4430. * mixer widget
  4431. * Note: PASD motherboards uses the Line In 2 as the input for
  4432. * front panel mic (mic 2)
  4433. */
  4434. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  4435. /* mute analog inputs */
  4436. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4437. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4438. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  4439. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  4440. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  4441. /*
  4442. * Set up output mixers (0x08 - 0x0a)
  4443. */
  4444. /* set vol=0 to output mixers */
  4445. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4446. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4447. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4448. /* set up input amps for analog loopback */
  4449. /* Amp Indices: DAC = 0, mixer = 1 */
  4450. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4451. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4452. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4453. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4454. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4455. {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4456. { }
  4457. };
  4458. static int alc260_parse_auto_config(struct hda_codec *codec)
  4459. {
  4460. struct alc_spec *spec = codec->spec;
  4461. unsigned int wcap;
  4462. int err;
  4463. static hda_nid_t alc260_ignore[] = { 0x17, 0 };
  4464. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  4465. alc260_ignore);
  4466. if (err < 0)
  4467. return err;
  4468. err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
  4469. if (err < 0)
  4470. return err;
  4471. if (!spec->kctl_alloc)
  4472. return 0; /* can't find valid BIOS pin config */
  4473. err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
  4474. if (err < 0)
  4475. return err;
  4476. spec->multiout.max_channels = 2;
  4477. if (spec->autocfg.dig_out_pin)
  4478. spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
  4479. if (spec->kctl_alloc)
  4480. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  4481. spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
  4482. spec->num_mux_defs = 1;
  4483. spec->input_mux = &spec->private_imux;
  4484. /* check whether NID 0x04 is valid */
  4485. wcap = get_wcaps(codec, 0x04);
  4486. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
  4487. if (wcap != AC_WID_AUD_IN) {
  4488. spec->adc_nids = alc260_adc_nids_alt;
  4489. spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
  4490. spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
  4491. } else {
  4492. spec->adc_nids = alc260_adc_nids;
  4493. spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
  4494. spec->mixers[spec->num_mixers] = alc260_capture_mixer;
  4495. }
  4496. spec->num_mixers++;
  4497. return 1;
  4498. }
  4499. /* additional initialization for auto-configuration model */
  4500. static void alc260_auto_init(struct hda_codec *codec)
  4501. {
  4502. struct alc_spec *spec = codec->spec;
  4503. alc260_auto_init_multi_out(codec);
  4504. alc260_auto_init_analog_input(codec);
  4505. if (spec->unsol_event)
  4506. alc_sku_automute(codec);
  4507. }
  4508. #ifdef CONFIG_SND_HDA_POWER_SAVE
  4509. static struct hda_amp_list alc260_loopbacks[] = {
  4510. { 0x07, HDA_INPUT, 0 },
  4511. { 0x07, HDA_INPUT, 1 },
  4512. { 0x07, HDA_INPUT, 2 },
  4513. { 0x07, HDA_INPUT, 3 },
  4514. { 0x07, HDA_INPUT, 4 },
  4515. { } /* end */
  4516. };
  4517. #endif
  4518. /*
  4519. * ALC260 configurations
  4520. */
  4521. static const char *alc260_models[ALC260_MODEL_LAST] = {
  4522. [ALC260_BASIC] = "basic",
  4523. [ALC260_HP] = "hp",
  4524. [ALC260_HP_3013] = "hp-3013",
  4525. [ALC260_FUJITSU_S702X] = "fujitsu",
  4526. [ALC260_ACER] = "acer",
  4527. [ALC260_WILL] = "will",
  4528. [ALC260_REPLACER_672V] = "replacer",
  4529. #ifdef CONFIG_SND_DEBUG
  4530. [ALC260_TEST] = "test",
  4531. #endif
  4532. [ALC260_AUTO] = "auto",
  4533. };
  4534. static struct snd_pci_quirk alc260_cfg_tbl[] = {
  4535. SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
  4536. SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
  4537. SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
  4538. SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
  4539. SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
  4540. SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
  4541. SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
  4542. SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
  4543. SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
  4544. SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
  4545. SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
  4546. SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
  4547. SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
  4548. SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
  4549. SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
  4550. SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
  4551. SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
  4552. SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
  4553. {}
  4554. };
  4555. static struct alc_config_preset alc260_presets[] = {
  4556. [ALC260_BASIC] = {
  4557. .mixers = { alc260_base_output_mixer,
  4558. alc260_input_mixer,
  4559. alc260_pc_beep_mixer,
  4560. alc260_capture_mixer },
  4561. .init_verbs = { alc260_init_verbs },
  4562. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4563. .dac_nids = alc260_dac_nids,
  4564. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4565. .adc_nids = alc260_adc_nids,
  4566. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4567. .channel_mode = alc260_modes,
  4568. .input_mux = &alc260_capture_source,
  4569. },
  4570. [ALC260_HP] = {
  4571. .mixers = { alc260_hp_output_mixer,
  4572. alc260_input_mixer,
  4573. alc260_capture_alt_mixer },
  4574. .init_verbs = { alc260_init_verbs,
  4575. alc260_hp_unsol_verbs },
  4576. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4577. .dac_nids = alc260_dac_nids,
  4578. .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
  4579. .adc_nids = alc260_hp_adc_nids,
  4580. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4581. .channel_mode = alc260_modes,
  4582. .input_mux = &alc260_capture_source,
  4583. .unsol_event = alc260_hp_unsol_event,
  4584. .init_hook = alc260_hp_automute,
  4585. },
  4586. [ALC260_HP_3013] = {
  4587. .mixers = { alc260_hp_3013_mixer,
  4588. alc260_input_mixer,
  4589. alc260_capture_alt_mixer },
  4590. .init_verbs = { alc260_hp_3013_init_verbs,
  4591. alc260_hp_3013_unsol_verbs },
  4592. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4593. .dac_nids = alc260_dac_nids,
  4594. .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
  4595. .adc_nids = alc260_hp_adc_nids,
  4596. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4597. .channel_mode = alc260_modes,
  4598. .input_mux = &alc260_capture_source,
  4599. .unsol_event = alc260_hp_3013_unsol_event,
  4600. .init_hook = alc260_hp_3013_automute,
  4601. },
  4602. [ALC260_FUJITSU_S702X] = {
  4603. .mixers = { alc260_fujitsu_mixer,
  4604. alc260_capture_mixer },
  4605. .init_verbs = { alc260_fujitsu_init_verbs },
  4606. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4607. .dac_nids = alc260_dac_nids,
  4608. .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
  4609. .adc_nids = alc260_dual_adc_nids,
  4610. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4611. .channel_mode = alc260_modes,
  4612. .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
  4613. .input_mux = alc260_fujitsu_capture_sources,
  4614. },
  4615. [ALC260_ACER] = {
  4616. .mixers = { alc260_acer_mixer,
  4617. alc260_capture_mixer },
  4618. .init_verbs = { alc260_acer_init_verbs },
  4619. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4620. .dac_nids = alc260_dac_nids,
  4621. .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
  4622. .adc_nids = alc260_dual_adc_nids,
  4623. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4624. .channel_mode = alc260_modes,
  4625. .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
  4626. .input_mux = alc260_acer_capture_sources,
  4627. },
  4628. [ALC260_WILL] = {
  4629. .mixers = { alc260_will_mixer,
  4630. alc260_capture_mixer },
  4631. .init_verbs = { alc260_init_verbs, alc260_will_verbs },
  4632. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4633. .dac_nids = alc260_dac_nids,
  4634. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4635. .adc_nids = alc260_adc_nids,
  4636. .dig_out_nid = ALC260_DIGOUT_NID,
  4637. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4638. .channel_mode = alc260_modes,
  4639. .input_mux = &alc260_capture_source,
  4640. },
  4641. [ALC260_REPLACER_672V] = {
  4642. .mixers = { alc260_replacer_672v_mixer,
  4643. alc260_capture_mixer },
  4644. .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
  4645. .num_dacs = ARRAY_SIZE(alc260_dac_nids),
  4646. .dac_nids = alc260_dac_nids,
  4647. .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
  4648. .adc_nids = alc260_adc_nids,
  4649. .dig_out_nid = ALC260_DIGOUT_NID,
  4650. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4651. .channel_mode = alc260_modes,
  4652. .input_mux = &alc260_capture_source,
  4653. .unsol_event = alc260_replacer_672v_unsol_event,
  4654. .init_hook = alc260_replacer_672v_automute,
  4655. },
  4656. #ifdef CONFIG_SND_DEBUG
  4657. [ALC260_TEST] = {
  4658. .mixers = { alc260_test_mixer,
  4659. alc260_capture_mixer },
  4660. .init_verbs = { alc260_test_init_verbs },
  4661. .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
  4662. .dac_nids = alc260_test_dac_nids,
  4663. .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
  4664. .adc_nids = alc260_test_adc_nids,
  4665. .num_channel_mode = ARRAY_SIZE(alc260_modes),
  4666. .channel_mode = alc260_modes,
  4667. .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
  4668. .input_mux = alc260_test_capture_sources,
  4669. },
  4670. #endif
  4671. };
  4672. static int patch_alc260(struct hda_codec *codec)
  4673. {
  4674. struct alc_spec *spec;
  4675. int err, board_config;
  4676. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  4677. if (spec == NULL)
  4678. return -ENOMEM;
  4679. codec->spec = spec;
  4680. board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
  4681. alc260_models,
  4682. alc260_cfg_tbl);
  4683. if (board_config < 0) {
  4684. snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
  4685. "trying auto-probe from BIOS...\n");
  4686. board_config = ALC260_AUTO;
  4687. }
  4688. if (board_config == ALC260_AUTO) {
  4689. /* automatic parse from the BIOS config */
  4690. err = alc260_parse_auto_config(codec);
  4691. if (err < 0) {
  4692. alc_free(codec);
  4693. return err;
  4694. } else if (!err) {
  4695. printk(KERN_INFO
  4696. "hda_codec: Cannot set up configuration "
  4697. "from BIOS. Using base mode...\n");
  4698. board_config = ALC260_BASIC;
  4699. }
  4700. }
  4701. if (board_config != ALC260_AUTO)
  4702. setup_preset(spec, &alc260_presets[board_config]);
  4703. spec->stream_name_analog = "ALC260 Analog";
  4704. spec->stream_analog_playback = &alc260_pcm_analog_playback;
  4705. spec->stream_analog_capture = &alc260_pcm_analog_capture;
  4706. spec->stream_name_digital = "ALC260 Digital";
  4707. spec->stream_digital_playback = &alc260_pcm_digital_playback;
  4708. spec->stream_digital_capture = &alc260_pcm_digital_capture;
  4709. spec->vmaster_nid = 0x08;
  4710. codec->patch_ops = alc_patch_ops;
  4711. if (board_config == ALC260_AUTO)
  4712. spec->init_hook = alc260_auto_init;
  4713. #ifdef CONFIG_SND_HDA_POWER_SAVE
  4714. if (!spec->loopback.amplist)
  4715. spec->loopback.amplist = alc260_loopbacks;
  4716. #endif
  4717. return 0;
  4718. }
  4719. /*
  4720. * ALC882 support
  4721. *
  4722. * ALC882 is almost identical with ALC880 but has cleaner and more flexible
  4723. * configuration. Each pin widget can choose any input DACs and a mixer.
  4724. * Each ADC is connected from a mixer of all inputs. This makes possible
  4725. * 6-channel independent captures.
  4726. *
  4727. * In addition, an independent DAC for the multi-playback (not used in this
  4728. * driver yet).
  4729. */
  4730. #define ALC882_DIGOUT_NID 0x06
  4731. #define ALC882_DIGIN_NID 0x0a
  4732. static struct hda_channel_mode alc882_ch_modes[1] = {
  4733. { 8, NULL }
  4734. };
  4735. static hda_nid_t alc882_dac_nids[4] = {
  4736. /* front, rear, clfe, rear_surr */
  4737. 0x02, 0x03, 0x04, 0x05
  4738. };
  4739. /* identical with ALC880 */
  4740. #define alc882_adc_nids alc880_adc_nids
  4741. #define alc882_adc_nids_alt alc880_adc_nids_alt
  4742. static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
  4743. static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
  4744. /* input MUX */
  4745. /* FIXME: should be a matrix-type input source selection */
  4746. static struct hda_input_mux alc882_capture_source = {
  4747. .num_items = 4,
  4748. .items = {
  4749. { "Mic", 0x0 },
  4750. { "Front Mic", 0x1 },
  4751. { "Line", 0x2 },
  4752. { "CD", 0x4 },
  4753. },
  4754. };
  4755. #define alc882_mux_enum_info alc_mux_enum_info
  4756. #define alc882_mux_enum_get alc_mux_enum_get
  4757. static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
  4758. struct snd_ctl_elem_value *ucontrol)
  4759. {
  4760. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  4761. struct alc_spec *spec = codec->spec;
  4762. const struct hda_input_mux *imux = spec->input_mux;
  4763. unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  4764. hda_nid_t nid = spec->capsrc_nids[adc_idx];
  4765. unsigned int *cur_val = &spec->cur_mux[adc_idx];
  4766. unsigned int i, idx;
  4767. idx = ucontrol->value.enumerated.item[0];
  4768. if (idx >= imux->num_items)
  4769. idx = imux->num_items - 1;
  4770. if (*cur_val == idx)
  4771. return 0;
  4772. for (i = 0; i < imux->num_items; i++) {
  4773. unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
  4774. snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
  4775. imux->items[i].index,
  4776. HDA_AMP_MUTE, v);
  4777. }
  4778. *cur_val = idx;
  4779. return 1;
  4780. }
  4781. /*
  4782. * 2ch mode
  4783. */
  4784. static struct hda_verb alc882_3ST_ch2_init[] = {
  4785. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  4786. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  4787. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  4788. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  4789. { } /* end */
  4790. };
  4791. /*
  4792. * 6ch mode
  4793. */
  4794. static struct hda_verb alc882_3ST_ch6_init[] = {
  4795. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4796. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  4797. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  4798. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4799. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  4800. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  4801. { } /* end */
  4802. };
  4803. static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
  4804. { 2, alc882_3ST_ch2_init },
  4805. { 6, alc882_3ST_ch6_init },
  4806. };
  4807. /*
  4808. * 6ch mode
  4809. */
  4810. static struct hda_verb alc882_sixstack_ch6_init[] = {
  4811. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  4812. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4813. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4814. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4815. { } /* end */
  4816. };
  4817. /*
  4818. * 8ch mode
  4819. */
  4820. static struct hda_verb alc882_sixstack_ch8_init[] = {
  4821. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4822. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4823. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4824. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4825. { } /* end */
  4826. };
  4827. static struct hda_channel_mode alc882_sixstack_modes[2] = {
  4828. { 6, alc882_sixstack_ch6_init },
  4829. { 8, alc882_sixstack_ch8_init },
  4830. };
  4831. /*
  4832. * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
  4833. */
  4834. /*
  4835. * 2ch mode
  4836. */
  4837. static struct hda_verb alc885_mbp_ch2_init[] = {
  4838. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  4839. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4840. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4841. { } /* end */
  4842. };
  4843. /*
  4844. * 6ch mode
  4845. */
  4846. static struct hda_verb alc885_mbp_ch6_init[] = {
  4847. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  4848. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4849. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  4850. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  4851. { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  4852. { } /* end */
  4853. };
  4854. static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
  4855. { 2, alc885_mbp_ch2_init },
  4856. { 6, alc885_mbp_ch6_init },
  4857. };
  4858. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  4859. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  4860. */
  4861. static struct snd_kcontrol_new alc882_base_mixer[] = {
  4862. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4863. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4864. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  4865. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  4866. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  4867. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  4868. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  4869. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  4870. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  4871. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  4872. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  4873. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4874. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4875. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4876. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4877. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4878. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4879. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4880. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  4881. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  4882. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  4883. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4884. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4885. { } /* end */
  4886. };
  4887. static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
  4888. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
  4889. HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
  4890. HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
  4891. HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
  4892. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4893. HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4894. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
  4895. HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
  4896. HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
  4897. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
  4898. { } /* end */
  4899. };
  4900. static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
  4901. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4902. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4903. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4904. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4905. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4906. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4907. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4908. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4909. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4910. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4911. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4912. { } /* end */
  4913. };
  4914. static struct snd_kcontrol_new alc882_targa_mixer[] = {
  4915. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4916. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4917. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  4918. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4919. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4920. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4921. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4922. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4923. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4924. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4925. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  4926. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  4927. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  4928. { } /* end */
  4929. };
  4930. /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
  4931. * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
  4932. */
  4933. static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
  4934. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4935. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  4936. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  4937. HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  4938. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4939. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4940. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4941. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4942. HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
  4943. HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
  4944. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4945. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4946. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4947. { } /* end */
  4948. };
  4949. static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
  4950. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  4951. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  4952. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  4953. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  4954. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  4955. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  4956. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  4957. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  4958. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  4959. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  4960. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  4961. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  4962. { } /* end */
  4963. };
  4964. static struct snd_kcontrol_new alc882_chmode_mixer[] = {
  4965. {
  4966. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  4967. .name = "Channel Mode",
  4968. .info = alc_ch_mode_info,
  4969. .get = alc_ch_mode_get,
  4970. .put = alc_ch_mode_put,
  4971. },
  4972. { } /* end */
  4973. };
  4974. static struct hda_verb alc882_init_verbs[] = {
  4975. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  4976. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4977. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4978. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4979. /* Rear mixer */
  4980. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4981. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4982. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4983. /* CLFE mixer */
  4984. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4985. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4986. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4987. /* Side mixer */
  4988. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  4989. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  4990. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  4991. /* Front Pin: output 0 (0x0c) */
  4992. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4993. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4994. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  4995. /* Rear Pin: output 1 (0x0d) */
  4996. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  4997. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  4998. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  4999. /* CLFE Pin: output 2 (0x0e) */
  5000. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5001. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5002. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  5003. /* Side Pin: output 3 (0x0f) */
  5004. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5005. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5006. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  5007. /* Mic (rear) pin: input vref at 80% */
  5008. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5009. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5010. /* Front Mic pin: input vref at 80% */
  5011. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5012. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5013. /* Line In pin: input */
  5014. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  5015. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5016. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  5017. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5018. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5019. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  5020. /* CD pin widget for input */
  5021. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  5022. /* FIXME: use matrix-type input source selection */
  5023. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  5024. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  5025. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5026. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5027. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5028. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5029. /* Input mixer2 */
  5030. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5031. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5032. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5033. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5034. /* Input mixer3 */
  5035. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5036. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5037. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5038. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5039. /* ADC1: mute amp left and right */
  5040. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5041. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  5042. /* ADC2: mute amp left and right */
  5043. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5044. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  5045. /* ADC3: mute amp left and right */
  5046. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5047. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  5048. { }
  5049. };
  5050. static struct hda_verb alc882_eapd_verbs[] = {
  5051. /* change to EAPD mode */
  5052. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  5053. {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
  5054. { }
  5055. };
  5056. /* Mac Pro test */
  5057. static struct snd_kcontrol_new alc882_macpro_mixer[] = {
  5058. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5059. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5060. HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
  5061. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
  5062. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
  5063. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5064. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5065. { } /* end */
  5066. };
  5067. static struct hda_verb alc882_macpro_init_verbs[] = {
  5068. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  5069. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5070. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5071. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  5072. /* Front Pin: output 0 (0x0c) */
  5073. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5074. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5075. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  5076. /* Front Mic pin: input vref at 80% */
  5077. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5078. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5079. /* Speaker: output */
  5080. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5081. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5082. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
  5083. /* Headphone output (output 0 - 0x0c) */
  5084. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5085. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5086. {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
  5087. /* FIXME: use matrix-type input source selection */
  5088. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  5089. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  5090. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5091. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5092. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5093. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5094. /* Input mixer2 */
  5095. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5096. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5097. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5098. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5099. /* Input mixer3 */
  5100. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5101. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5102. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5103. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5104. /* ADC1: mute amp left and right */
  5105. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5106. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  5107. /* ADC2: mute amp left and right */
  5108. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5109. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  5110. /* ADC3: mute amp left and right */
  5111. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5112. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  5113. { }
  5114. };
  5115. /* Macbook Pro rev3 */
  5116. static struct hda_verb alc885_mbp3_init_verbs[] = {
  5117. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  5118. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5119. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5120. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  5121. /* Rear mixer */
  5122. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5123. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5124. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  5125. /* Front Pin: output 0 (0x0c) */
  5126. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5127. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5128. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  5129. /* HP Pin: output 0 (0x0d) */
  5130. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
  5131. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5132. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  5133. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  5134. /* Mic (rear) pin: input vref at 80% */
  5135. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5136. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5137. /* Front Mic pin: input vref at 80% */
  5138. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5139. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5140. /* Line In pin: use output 1 when in LineOut mode */
  5141. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  5142. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5143. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
  5144. /* FIXME: use matrix-type input source selection */
  5145. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  5146. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  5147. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5148. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5149. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5150. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5151. /* Input mixer2 */
  5152. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5153. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5154. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5155. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5156. /* Input mixer3 */
  5157. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5158. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5159. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5160. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5161. /* ADC1: mute amp left and right */
  5162. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5163. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  5164. /* ADC2: mute amp left and right */
  5165. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5166. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  5167. /* ADC3: mute amp left and right */
  5168. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5169. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  5170. { }
  5171. };
  5172. /* iMac 24 mixer. */
  5173. static struct snd_kcontrol_new alc885_imac24_mixer[] = {
  5174. HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
  5175. HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
  5176. { } /* end */
  5177. };
  5178. /* iMac 24 init verbs. */
  5179. static struct hda_verb alc885_imac24_init_verbs[] = {
  5180. /* Internal speakers: output 0 (0x0c) */
  5181. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5182. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5183. {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
  5184. /* Internal speakers: output 0 (0x0c) */
  5185. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5186. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5187. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
  5188. /* Headphone: output 0 (0x0c) */
  5189. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5190. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  5191. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  5192. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  5193. /* Front Mic: input vref at 80% */
  5194. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  5195. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  5196. { }
  5197. };
  5198. /* Toggle speaker-output according to the hp-jack state */
  5199. static void alc885_imac24_automute(struct hda_codec *codec)
  5200. {
  5201. unsigned int present;
  5202. present = snd_hda_codec_read(codec, 0x14, 0,
  5203. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5204. snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
  5205. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5206. snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
  5207. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5208. }
  5209. /* Processes unsolicited events. */
  5210. static void alc885_imac24_unsol_event(struct hda_codec *codec,
  5211. unsigned int res)
  5212. {
  5213. /* Headphone insertion or removal. */
  5214. if ((res >> 26) == ALC880_HP_EVENT)
  5215. alc885_imac24_automute(codec);
  5216. }
  5217. static void alc885_mbp3_automute(struct hda_codec *codec)
  5218. {
  5219. unsigned int present;
  5220. present = snd_hda_codec_read(codec, 0x15, 0,
  5221. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5222. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  5223. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5224. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  5225. HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
  5226. }
  5227. static void alc885_mbp3_unsol_event(struct hda_codec *codec,
  5228. unsigned int res)
  5229. {
  5230. /* Headphone insertion or removal. */
  5231. if ((res >> 26) == ALC880_HP_EVENT)
  5232. alc885_mbp3_automute(codec);
  5233. }
  5234. static struct hda_verb alc882_targa_verbs[] = {
  5235. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5236. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5237. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5238. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5239. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5240. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5241. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5242. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  5243. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  5244. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  5245. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  5246. { } /* end */
  5247. };
  5248. /* toggle speaker-output according to the hp-jack state */
  5249. static void alc882_targa_automute(struct hda_codec *codec)
  5250. {
  5251. unsigned int present;
  5252. present = snd_hda_codec_read(codec, 0x14, 0,
  5253. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  5254. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  5255. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  5256. snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
  5257. present ? 1 : 3);
  5258. }
  5259. static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
  5260. {
  5261. /* Looks like the unsol event is incompatible with the standard
  5262. * definition. 4bit tag is placed at 26 bit!
  5263. */
  5264. if (((res >> 26) == ALC880_HP_EVENT)) {
  5265. alc882_targa_automute(codec);
  5266. }
  5267. }
  5268. static struct hda_verb alc882_asus_a7j_verbs[] = {
  5269. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5270. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5271. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5272. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5273. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5274. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5275. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5276. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5277. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5278. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5279. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5280. { } /* end */
  5281. };
  5282. static struct hda_verb alc882_asus_a7m_verbs[] = {
  5283. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5284. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5285. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  5286. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5287. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  5288. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5289. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5290. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
  5291. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  5292. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  5293. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  5294. { } /* end */
  5295. };
  5296. static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
  5297. {
  5298. unsigned int gpiostate, gpiomask, gpiodir;
  5299. gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
  5300. AC_VERB_GET_GPIO_DATA, 0);
  5301. if (!muted)
  5302. gpiostate |= (1 << pin);
  5303. else
  5304. gpiostate &= ~(1 << pin);
  5305. gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
  5306. AC_VERB_GET_GPIO_MASK, 0);
  5307. gpiomask |= (1 << pin);
  5308. gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
  5309. AC_VERB_GET_GPIO_DIRECTION, 0);
  5310. gpiodir |= (1 << pin);
  5311. snd_hda_codec_write(codec, codec->afg, 0,
  5312. AC_VERB_SET_GPIO_MASK, gpiomask);
  5313. snd_hda_codec_write(codec, codec->afg, 0,
  5314. AC_VERB_SET_GPIO_DIRECTION, gpiodir);
  5315. msleep(1);
  5316. snd_hda_codec_write(codec, codec->afg, 0,
  5317. AC_VERB_SET_GPIO_DATA, gpiostate);
  5318. }
  5319. /* set up GPIO at initialization */
  5320. static void alc885_macpro_init_hook(struct hda_codec *codec)
  5321. {
  5322. alc882_gpio_mute(codec, 0, 0);
  5323. alc882_gpio_mute(codec, 1, 0);
  5324. }
  5325. /* set up GPIO and update auto-muting at initialization */
  5326. static void alc885_imac24_init_hook(struct hda_codec *codec)
  5327. {
  5328. alc885_macpro_init_hook(codec);
  5329. alc885_imac24_automute(codec);
  5330. }
  5331. /*
  5332. * generic initialization of ADC, input mixers and output mixers
  5333. */
  5334. static struct hda_verb alc882_auto_init_verbs[] = {
  5335. /*
  5336. * Unmute ADC0-2 and set the default input to mic-in
  5337. */
  5338. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  5339. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5340. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  5341. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5342. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  5343. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5344. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  5345. * mixer widget
  5346. * Note: PASD motherboards uses the Line In 2 as the input for
  5347. * front panel mic (mic 2)
  5348. */
  5349. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  5350. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  5351. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  5352. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  5353. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  5354. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  5355. /*
  5356. * Set up output mixers (0x0c - 0x0f)
  5357. */
  5358. /* set vol=0 to output mixers */
  5359. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5360. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5361. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5362. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  5363. /* set up input amps for analog loopback */
  5364. /* Amp Indices: DAC = 0, mixer = 1 */
  5365. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5366. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5367. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5368. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5369. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5370. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5371. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5372. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5373. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  5374. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  5375. /* FIXME: use matrix-type input source selection */
  5376. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  5377. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  5378. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5379. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5380. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5381. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5382. /* Input mixer2 */
  5383. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5384. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5385. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5386. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5387. /* Input mixer3 */
  5388. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  5389. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  5390. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  5391. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  5392. { }
  5393. };
  5394. /* capture mixer elements */
  5395. static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
  5396. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5397. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5398. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5399. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5400. {
  5401. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5402. /* The multiple "Capture Source" controls confuse alsamixer
  5403. * So call somewhat different..
  5404. */
  5405. /* .name = "Capture Source", */
  5406. .name = "Input Source",
  5407. .count = 2,
  5408. .info = alc882_mux_enum_info,
  5409. .get = alc882_mux_enum_get,
  5410. .put = alc882_mux_enum_put,
  5411. },
  5412. { } /* end */
  5413. };
  5414. static struct snd_kcontrol_new alc882_capture_mixer[] = {
  5415. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  5416. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  5417. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
  5418. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
  5419. HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
  5420. HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
  5421. {
  5422. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5423. /* The multiple "Capture Source" controls confuse alsamixer
  5424. * So call somewhat different..
  5425. */
  5426. /* .name = "Capture Source", */
  5427. .name = "Input Source",
  5428. .count = 3,
  5429. .info = alc882_mux_enum_info,
  5430. .get = alc882_mux_enum_get,
  5431. .put = alc882_mux_enum_put,
  5432. },
  5433. { } /* end */
  5434. };
  5435. #ifdef CONFIG_SND_HDA_POWER_SAVE
  5436. #define alc882_loopbacks alc880_loopbacks
  5437. #endif
  5438. /* pcm configuration: identiacal with ALC880 */
  5439. #define alc882_pcm_analog_playback alc880_pcm_analog_playback
  5440. #define alc882_pcm_analog_capture alc880_pcm_analog_capture
  5441. #define alc882_pcm_digital_playback alc880_pcm_digital_playback
  5442. #define alc882_pcm_digital_capture alc880_pcm_digital_capture
  5443. /*
  5444. * configuration and preset
  5445. */
  5446. static const char *alc882_models[ALC882_MODEL_LAST] = {
  5447. [ALC882_3ST_DIG] = "3stack-dig",
  5448. [ALC882_6ST_DIG] = "6stack-dig",
  5449. [ALC882_ARIMA] = "arima",
  5450. [ALC882_W2JC] = "w2jc",
  5451. [ALC882_TARGA] = "targa",
  5452. [ALC882_ASUS_A7J] = "asus-a7j",
  5453. [ALC882_ASUS_A7M] = "asus-a7m",
  5454. [ALC885_MACPRO] = "macpro",
  5455. [ALC885_MBP3] = "mbp3",
  5456. [ALC885_IMAC24] = "imac24",
  5457. [ALC882_AUTO] = "auto",
  5458. };
  5459. static struct snd_pci_quirk alc882_cfg_tbl[] = {
  5460. SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
  5461. SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
  5462. SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
  5463. SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
  5464. SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
  5465. SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
  5466. SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
  5467. SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
  5468. SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
  5469. SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
  5470. SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
  5471. SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
  5472. {}
  5473. };
  5474. static struct alc_config_preset alc882_presets[] = {
  5475. [ALC882_3ST_DIG] = {
  5476. .mixers = { alc882_base_mixer },
  5477. .init_verbs = { alc882_init_verbs },
  5478. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5479. .dac_nids = alc882_dac_nids,
  5480. .dig_out_nid = ALC882_DIGOUT_NID,
  5481. .dig_in_nid = ALC882_DIGIN_NID,
  5482. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5483. .channel_mode = alc882_ch_modes,
  5484. .need_dac_fix = 1,
  5485. .input_mux = &alc882_capture_source,
  5486. },
  5487. [ALC882_6ST_DIG] = {
  5488. .mixers = { alc882_base_mixer, alc882_chmode_mixer },
  5489. .init_verbs = { alc882_init_verbs },
  5490. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5491. .dac_nids = alc882_dac_nids,
  5492. .dig_out_nid = ALC882_DIGOUT_NID,
  5493. .dig_in_nid = ALC882_DIGIN_NID,
  5494. .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
  5495. .channel_mode = alc882_sixstack_modes,
  5496. .input_mux = &alc882_capture_source,
  5497. },
  5498. [ALC882_ARIMA] = {
  5499. .mixers = { alc882_base_mixer, alc882_chmode_mixer },
  5500. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
  5501. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5502. .dac_nids = alc882_dac_nids,
  5503. .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
  5504. .channel_mode = alc882_sixstack_modes,
  5505. .input_mux = &alc882_capture_source,
  5506. },
  5507. [ALC882_W2JC] = {
  5508. .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
  5509. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
  5510. alc880_gpio1_init_verbs },
  5511. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5512. .dac_nids = alc882_dac_nids,
  5513. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  5514. .channel_mode = alc880_threestack_modes,
  5515. .need_dac_fix = 1,
  5516. .input_mux = &alc882_capture_source,
  5517. .dig_out_nid = ALC882_DIGOUT_NID,
  5518. },
  5519. [ALC885_MBP3] = {
  5520. .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
  5521. .init_verbs = { alc885_mbp3_init_verbs,
  5522. alc880_gpio1_init_verbs },
  5523. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5524. .dac_nids = alc882_dac_nids,
  5525. .channel_mode = alc885_mbp_6ch_modes,
  5526. .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
  5527. .input_mux = &alc882_capture_source,
  5528. .dig_out_nid = ALC882_DIGOUT_NID,
  5529. .dig_in_nid = ALC882_DIGIN_NID,
  5530. .unsol_event = alc885_mbp3_unsol_event,
  5531. .init_hook = alc885_mbp3_automute,
  5532. },
  5533. [ALC885_MACPRO] = {
  5534. .mixers = { alc882_macpro_mixer },
  5535. .init_verbs = { alc882_macpro_init_verbs },
  5536. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5537. .dac_nids = alc882_dac_nids,
  5538. .dig_out_nid = ALC882_DIGOUT_NID,
  5539. .dig_in_nid = ALC882_DIGIN_NID,
  5540. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5541. .channel_mode = alc882_ch_modes,
  5542. .input_mux = &alc882_capture_source,
  5543. .init_hook = alc885_macpro_init_hook,
  5544. },
  5545. [ALC885_IMAC24] = {
  5546. .mixers = { alc885_imac24_mixer },
  5547. .init_verbs = { alc885_imac24_init_verbs },
  5548. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5549. .dac_nids = alc882_dac_nids,
  5550. .dig_out_nid = ALC882_DIGOUT_NID,
  5551. .dig_in_nid = ALC882_DIGIN_NID,
  5552. .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
  5553. .channel_mode = alc882_ch_modes,
  5554. .input_mux = &alc882_capture_source,
  5555. .unsol_event = alc885_imac24_unsol_event,
  5556. .init_hook = alc885_imac24_init_hook,
  5557. },
  5558. [ALC882_TARGA] = {
  5559. .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
  5560. alc882_capture_mixer },
  5561. .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
  5562. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5563. .dac_nids = alc882_dac_nids,
  5564. .dig_out_nid = ALC882_DIGOUT_NID,
  5565. .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
  5566. .adc_nids = alc882_adc_nids,
  5567. .capsrc_nids = alc882_capsrc_nids,
  5568. .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
  5569. .channel_mode = alc882_3ST_6ch_modes,
  5570. .need_dac_fix = 1,
  5571. .input_mux = &alc882_capture_source,
  5572. .unsol_event = alc882_targa_unsol_event,
  5573. .init_hook = alc882_targa_automute,
  5574. },
  5575. [ALC882_ASUS_A7J] = {
  5576. .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
  5577. alc882_capture_mixer },
  5578. .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
  5579. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5580. .dac_nids = alc882_dac_nids,
  5581. .dig_out_nid = ALC882_DIGOUT_NID,
  5582. .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
  5583. .adc_nids = alc882_adc_nids,
  5584. .capsrc_nids = alc882_capsrc_nids,
  5585. .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
  5586. .channel_mode = alc882_3ST_6ch_modes,
  5587. .need_dac_fix = 1,
  5588. .input_mux = &alc882_capture_source,
  5589. },
  5590. [ALC882_ASUS_A7M] = {
  5591. .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
  5592. .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
  5593. alc880_gpio1_init_verbs,
  5594. alc882_asus_a7m_verbs },
  5595. .num_dacs = ARRAY_SIZE(alc882_dac_nids),
  5596. .dac_nids = alc882_dac_nids,
  5597. .dig_out_nid = ALC882_DIGOUT_NID,
  5598. .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
  5599. .channel_mode = alc880_threestack_modes,
  5600. .need_dac_fix = 1,
  5601. .input_mux = &alc882_capture_source,
  5602. },
  5603. };
  5604. /*
  5605. * Pin config fixes
  5606. */
  5607. enum {
  5608. PINFIX_ABIT_AW9D_MAX
  5609. };
  5610. static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
  5611. { 0x15, 0x01080104 }, /* side */
  5612. { 0x16, 0x01011012 }, /* rear */
  5613. { 0x17, 0x01016011 }, /* clfe */
  5614. { }
  5615. };
  5616. static const struct alc_pincfg *alc882_pin_fixes[] = {
  5617. [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
  5618. };
  5619. static struct snd_pci_quirk alc882_pinfix_tbl[] = {
  5620. SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
  5621. {}
  5622. };
  5623. /*
  5624. * BIOS auto configuration
  5625. */
  5626. static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
  5627. hda_nid_t nid, int pin_type,
  5628. int dac_idx)
  5629. {
  5630. /* set as output */
  5631. struct alc_spec *spec = codec->spec;
  5632. int idx;
  5633. alc_set_pin_output(codec, nid, pin_type);
  5634. if (spec->multiout.dac_nids[dac_idx] == 0x25)
  5635. idx = 4;
  5636. else
  5637. idx = spec->multiout.dac_nids[dac_idx] - 2;
  5638. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
  5639. }
  5640. static void alc882_auto_init_multi_out(struct hda_codec *codec)
  5641. {
  5642. struct alc_spec *spec = codec->spec;
  5643. int i;
  5644. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  5645. for (i = 0; i <= HDA_SIDE; i++) {
  5646. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  5647. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  5648. if (nid)
  5649. alc882_auto_set_output_and_unmute(codec, nid, pin_type,
  5650. i);
  5651. }
  5652. }
  5653. static void alc882_auto_init_hp_out(struct hda_codec *codec)
  5654. {
  5655. struct alc_spec *spec = codec->spec;
  5656. hda_nid_t pin;
  5657. pin = spec->autocfg.hp_pins[0];
  5658. if (pin) /* connect to front */
  5659. /* use dac 0 */
  5660. alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  5661. pin = spec->autocfg.speaker_pins[0];
  5662. if (pin)
  5663. alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  5664. }
  5665. #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
  5666. #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
  5667. static void alc882_auto_init_analog_input(struct hda_codec *codec)
  5668. {
  5669. struct alc_spec *spec = codec->spec;
  5670. int i;
  5671. for (i = 0; i < AUTO_PIN_LAST; i++) {
  5672. hda_nid_t nid = spec->autocfg.input_pins[i];
  5673. if (alc882_is_input_pin(nid)) {
  5674. snd_hda_codec_write(codec, nid, 0,
  5675. AC_VERB_SET_PIN_WIDGET_CONTROL,
  5676. i <= AUTO_PIN_FRONT_MIC ?
  5677. PIN_VREF80 : PIN_IN);
  5678. if (nid != ALC882_PIN_CD_NID)
  5679. snd_hda_codec_write(codec, nid, 0,
  5680. AC_VERB_SET_AMP_GAIN_MUTE,
  5681. AMP_OUT_MUTE);
  5682. }
  5683. }
  5684. }
  5685. /* add mic boosts if needed */
  5686. static int alc_auto_add_mic_boost(struct hda_codec *codec)
  5687. {
  5688. struct alc_spec *spec = codec->spec;
  5689. int err;
  5690. hda_nid_t nid;
  5691. nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
  5692. if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
  5693. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  5694. "Mic Boost",
  5695. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  5696. if (err < 0)
  5697. return err;
  5698. }
  5699. nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
  5700. if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
  5701. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  5702. "Front Mic Boost",
  5703. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  5704. if (err < 0)
  5705. return err;
  5706. }
  5707. return 0;
  5708. }
  5709. /* almost identical with ALC880 parser... */
  5710. static int alc882_parse_auto_config(struct hda_codec *codec)
  5711. {
  5712. struct alc_spec *spec = codec->spec;
  5713. int err = alc880_parse_auto_config(codec);
  5714. if (err < 0)
  5715. return err;
  5716. else if (!err)
  5717. return 0; /* no config found */
  5718. err = alc_auto_add_mic_boost(codec);
  5719. if (err < 0)
  5720. return err;
  5721. /* hack - override the init verbs */
  5722. spec->init_verbs[0] = alc882_auto_init_verbs;
  5723. return 1; /* config found */
  5724. }
  5725. /* additional initialization for auto-configuration model */
  5726. static void alc882_auto_init(struct hda_codec *codec)
  5727. {
  5728. struct alc_spec *spec = codec->spec;
  5729. alc882_auto_init_multi_out(codec);
  5730. alc882_auto_init_hp_out(codec);
  5731. alc882_auto_init_analog_input(codec);
  5732. if (spec->unsol_event)
  5733. alc_sku_automute(codec);
  5734. }
  5735. static int patch_alc882(struct hda_codec *codec)
  5736. {
  5737. struct alc_spec *spec;
  5738. int err, board_config;
  5739. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  5740. if (spec == NULL)
  5741. return -ENOMEM;
  5742. codec->spec = spec;
  5743. board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
  5744. alc882_models,
  5745. alc882_cfg_tbl);
  5746. if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
  5747. /* Pick up systems that don't supply PCI SSID */
  5748. switch (codec->subsystem_id) {
  5749. case 0x106b0c00: /* Mac Pro */
  5750. board_config = ALC885_MACPRO;
  5751. break;
  5752. case 0x106b1000: /* iMac 24 */
  5753. board_config = ALC885_IMAC24;
  5754. break;
  5755. case 0x106b00a1: /* Macbook */
  5756. case 0x106b2c00: /* Macbook Pro rev3 */
  5757. board_config = ALC885_MBP3;
  5758. break;
  5759. default:
  5760. printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
  5761. "trying auto-probe from BIOS...\n");
  5762. board_config = ALC882_AUTO;
  5763. }
  5764. }
  5765. alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
  5766. if (board_config == ALC882_AUTO) {
  5767. /* automatic parse from the BIOS config */
  5768. err = alc882_parse_auto_config(codec);
  5769. if (err < 0) {
  5770. alc_free(codec);
  5771. return err;
  5772. } else if (!err) {
  5773. printk(KERN_INFO
  5774. "hda_codec: Cannot set up configuration "
  5775. "from BIOS. Using base mode...\n");
  5776. board_config = ALC882_3ST_DIG;
  5777. }
  5778. }
  5779. if (board_config != ALC882_AUTO)
  5780. setup_preset(spec, &alc882_presets[board_config]);
  5781. spec->stream_name_analog = "ALC882 Analog";
  5782. spec->stream_analog_playback = &alc882_pcm_analog_playback;
  5783. spec->stream_analog_capture = &alc882_pcm_analog_capture;
  5784. /* FIXME: setup DAC5 */
  5785. /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
  5786. spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
  5787. spec->stream_name_digital = "ALC882 Digital";
  5788. spec->stream_digital_playback = &alc882_pcm_digital_playback;
  5789. spec->stream_digital_capture = &alc882_pcm_digital_capture;
  5790. if (!spec->adc_nids && spec->input_mux) {
  5791. /* check whether NID 0x07 is valid */
  5792. unsigned int wcap = get_wcaps(codec, 0x07);
  5793. /* get type */
  5794. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  5795. if (wcap != AC_WID_AUD_IN) {
  5796. spec->adc_nids = alc882_adc_nids_alt;
  5797. spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
  5798. spec->capsrc_nids = alc882_capsrc_nids_alt;
  5799. spec->mixers[spec->num_mixers] =
  5800. alc882_capture_alt_mixer;
  5801. spec->num_mixers++;
  5802. } else {
  5803. spec->adc_nids = alc882_adc_nids;
  5804. spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
  5805. spec->capsrc_nids = alc882_capsrc_nids;
  5806. spec->mixers[spec->num_mixers] = alc882_capture_mixer;
  5807. spec->num_mixers++;
  5808. }
  5809. }
  5810. spec->vmaster_nid = 0x0c;
  5811. codec->patch_ops = alc_patch_ops;
  5812. if (board_config == ALC882_AUTO)
  5813. spec->init_hook = alc882_auto_init;
  5814. #ifdef CONFIG_SND_HDA_POWER_SAVE
  5815. if (!spec->loopback.amplist)
  5816. spec->loopback.amplist = alc882_loopbacks;
  5817. #endif
  5818. return 0;
  5819. }
  5820. /*
  5821. * ALC883 support
  5822. *
  5823. * ALC883 is almost identical with ALC880 but has cleaner and more flexible
  5824. * configuration. Each pin widget can choose any input DACs and a mixer.
  5825. * Each ADC is connected from a mixer of all inputs. This makes possible
  5826. * 6-channel independent captures.
  5827. *
  5828. * In addition, an independent DAC for the multi-playback (not used in this
  5829. * driver yet).
  5830. */
  5831. #define ALC883_DIGOUT_NID 0x06
  5832. #define ALC883_DIGIN_NID 0x0a
  5833. static hda_nid_t alc883_dac_nids[4] = {
  5834. /* front, rear, clfe, rear_surr */
  5835. 0x02, 0x04, 0x03, 0x05
  5836. };
  5837. static hda_nid_t alc883_adc_nids[2] = {
  5838. /* ADC1-2 */
  5839. 0x08, 0x09,
  5840. };
  5841. static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
  5842. /* input MUX */
  5843. /* FIXME: should be a matrix-type input source selection */
  5844. static struct hda_input_mux alc883_capture_source = {
  5845. .num_items = 4,
  5846. .items = {
  5847. { "Mic", 0x0 },
  5848. { "Front Mic", 0x1 },
  5849. { "Line", 0x2 },
  5850. { "CD", 0x4 },
  5851. },
  5852. };
  5853. static struct hda_input_mux alc883_lenovo_101e_capture_source = {
  5854. .num_items = 2,
  5855. .items = {
  5856. { "Mic", 0x1 },
  5857. { "Line", 0x2 },
  5858. },
  5859. };
  5860. static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
  5861. .num_items = 4,
  5862. .items = {
  5863. { "Mic", 0x0 },
  5864. { "iMic", 0x1 },
  5865. { "Line", 0x2 },
  5866. { "CD", 0x4 },
  5867. },
  5868. };
  5869. #define alc883_mux_enum_info alc_mux_enum_info
  5870. #define alc883_mux_enum_get alc_mux_enum_get
  5871. /* ALC883 has the ALC882-type input selection */
  5872. #define alc883_mux_enum_put alc882_mux_enum_put
  5873. /*
  5874. * 2ch mode
  5875. */
  5876. static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
  5877. { 2, NULL }
  5878. };
  5879. /*
  5880. * 2ch mode
  5881. */
  5882. static struct hda_verb alc883_3ST_ch2_init[] = {
  5883. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  5884. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5885. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  5886. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5887. { } /* end */
  5888. };
  5889. /*
  5890. * 4ch mode
  5891. */
  5892. static struct hda_verb alc883_3ST_ch4_init[] = {
  5893. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  5894. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  5895. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5896. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5897. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  5898. { } /* end */
  5899. };
  5900. /*
  5901. * 6ch mode
  5902. */
  5903. static struct hda_verb alc883_3ST_ch6_init[] = {
  5904. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5905. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5906. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  5907. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5908. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  5909. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  5910. { } /* end */
  5911. };
  5912. static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
  5913. { 2, alc883_3ST_ch2_init },
  5914. { 4, alc883_3ST_ch4_init },
  5915. { 6, alc883_3ST_ch6_init },
  5916. };
  5917. /*
  5918. * 6ch mode
  5919. */
  5920. static struct hda_verb alc883_sixstack_ch6_init[] = {
  5921. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  5922. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5923. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5924. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5925. { } /* end */
  5926. };
  5927. /*
  5928. * 8ch mode
  5929. */
  5930. static struct hda_verb alc883_sixstack_ch8_init[] = {
  5931. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5932. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5933. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5934. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  5935. { } /* end */
  5936. };
  5937. static struct hda_channel_mode alc883_sixstack_modes[2] = {
  5938. { 6, alc883_sixstack_ch6_init },
  5939. { 8, alc883_sixstack_ch8_init },
  5940. };
  5941. static struct hda_verb alc883_medion_eapd_verbs[] = {
  5942. /* eanable EAPD on medion laptop */
  5943. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  5944. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  5945. { }
  5946. };
  5947. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  5948. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  5949. */
  5950. static struct snd_kcontrol_new alc883_base_mixer[] = {
  5951. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5952. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5953. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  5954. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  5955. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5956. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5957. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5958. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5959. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  5960. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  5961. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  5962. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  5963. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  5964. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  5965. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  5966. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5967. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5968. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  5969. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  5970. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  5971. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  5972. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  5973. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  5974. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  5975. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  5976. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  5977. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  5978. {
  5979. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  5980. /* .name = "Capture Source", */
  5981. .name = "Input Source",
  5982. .count = 2,
  5983. .info = alc883_mux_enum_info,
  5984. .get = alc883_mux_enum_get,
  5985. .put = alc883_mux_enum_put,
  5986. },
  5987. { } /* end */
  5988. };
  5989. static struct snd_kcontrol_new alc883_mitac_mixer[] = {
  5990. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  5991. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  5992. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  5993. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  5994. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  5995. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  5996. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  5997. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  5998. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  5999. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6000. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6001. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6002. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6003. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6004. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6005. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6006. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6007. {
  6008. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6009. /* .name = "Capture Source", */
  6010. .name = "Input Source",
  6011. .count = 2,
  6012. .info = alc883_mux_enum_info,
  6013. .get = alc883_mux_enum_get,
  6014. .put = alc883_mux_enum_put,
  6015. },
  6016. { } /* end */
  6017. };
  6018. static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
  6019. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6020. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6021. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6022. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6023. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6024. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6025. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6026. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6027. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6028. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6029. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6030. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6031. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6032. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6033. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6034. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6035. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6036. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6037. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6038. {
  6039. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6040. /* .name = "Capture Source", */
  6041. .name = "Input Source",
  6042. .count = 2,
  6043. .info = alc883_mux_enum_info,
  6044. .get = alc883_mux_enum_get,
  6045. .put = alc883_mux_enum_put,
  6046. },
  6047. { } /* end */
  6048. };
  6049. static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
  6050. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6051. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6052. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  6053. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  6054. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  6055. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  6056. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  6057. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  6058. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6059. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6060. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6061. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6062. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6063. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6064. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6065. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6066. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6067. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6068. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6069. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6070. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6071. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6072. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6073. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6074. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6075. {
  6076. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6077. /* .name = "Capture Source", */
  6078. .name = "Input Source",
  6079. .count = 2,
  6080. .info = alc883_mux_enum_info,
  6081. .get = alc883_mux_enum_get,
  6082. .put = alc883_mux_enum_put,
  6083. },
  6084. { } /* end */
  6085. };
  6086. static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
  6087. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6088. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6089. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  6090. HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  6091. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  6092. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  6093. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
  6094. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  6095. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6096. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6097. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6098. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6099. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6100. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6101. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6102. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6103. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6104. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6105. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6106. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6107. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6108. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6109. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6110. {
  6111. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6112. /* .name = "Capture Source", */
  6113. .name = "Input Source",
  6114. .count = 1,
  6115. .info = alc883_mux_enum_info,
  6116. .get = alc883_mux_enum_get,
  6117. .put = alc883_mux_enum_put,
  6118. },
  6119. { } /* end */
  6120. };
  6121. static struct snd_kcontrol_new alc883_tagra_mixer[] = {
  6122. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6123. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6124. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6125. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  6126. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  6127. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
  6128. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  6129. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  6130. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  6131. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6132. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6133. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6134. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6135. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6136. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6137. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6138. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6139. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6140. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6141. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6142. {
  6143. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6144. /* .name = "Capture Source", */
  6145. .name = "Input Source",
  6146. .count = 2,
  6147. .info = alc883_mux_enum_info,
  6148. .get = alc883_mux_enum_get,
  6149. .put = alc883_mux_enum_put,
  6150. },
  6151. { } /* end */
  6152. };
  6153. static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
  6154. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6155. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6156. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6157. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6158. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6159. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6160. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6161. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6162. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6163. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6164. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6165. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6166. {
  6167. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6168. /* .name = "Capture Source", */
  6169. .name = "Input Source",
  6170. .count = 2,
  6171. .info = alc883_mux_enum_info,
  6172. .get = alc883_mux_enum_get,
  6173. .put = alc883_mux_enum_put,
  6174. },
  6175. { } /* end */
  6176. };
  6177. static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
  6178. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6179. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6180. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  6181. HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
  6182. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6183. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6184. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6185. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6186. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6187. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6188. {
  6189. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6190. /* .name = "Capture Source", */
  6191. .name = "Input Source",
  6192. .count = 1,
  6193. .info = alc883_mux_enum_info,
  6194. .get = alc883_mux_enum_get,
  6195. .put = alc883_mux_enum_put,
  6196. },
  6197. { } /* end */
  6198. };
  6199. static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
  6200. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6201. HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
  6202. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6203. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6204. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6205. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6206. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6207. HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6208. HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6209. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6210. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6211. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6212. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6213. {
  6214. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6215. /* .name = "Capture Source", */
  6216. .name = "Input Source",
  6217. .count = 2,
  6218. .info = alc883_mux_enum_info,
  6219. .get = alc883_mux_enum_get,
  6220. .put = alc883_mux_enum_put,
  6221. },
  6222. { } /* end */
  6223. };
  6224. static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
  6225. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6226. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6227. HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  6228. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6229. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6230. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6231. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6232. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6233. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6234. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6235. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6236. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6237. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6238. {
  6239. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6240. /* .name = "Capture Source", */
  6241. .name = "Input Source",
  6242. .count = 2,
  6243. .info = alc883_mux_enum_info,
  6244. .get = alc883_mux_enum_get,
  6245. .put = alc883_mux_enum_put,
  6246. },
  6247. { } /* end */
  6248. };
  6249. static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
  6250. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6251. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6252. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  6253. HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
  6254. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  6255. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  6256. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  6257. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  6258. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  6259. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  6260. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6261. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6262. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6263. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6264. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6265. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6266. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6267. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6268. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6269. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6270. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6271. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6272. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6273. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6274. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6275. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6276. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6277. {
  6278. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6279. /* .name = "Capture Source", */
  6280. .name = "Input Source",
  6281. .count = 2,
  6282. .info = alc883_mux_enum_info,
  6283. .get = alc883_mux_enum_get,
  6284. .put = alc883_mux_enum_put,
  6285. },
  6286. { } /* end */
  6287. };
  6288. static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
  6289. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6290. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6291. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  6292. HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
  6293. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  6294. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  6295. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  6296. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  6297. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6298. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6299. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6300. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6301. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6302. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6303. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6304. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6305. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6306. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6307. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6308. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6309. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6310. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6311. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6312. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6313. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6314. {
  6315. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6316. /* .name = "Capture Source", */
  6317. .name = "Input Source",
  6318. .count = 2,
  6319. .info = alc883_mux_enum_info,
  6320. .get = alc883_mux_enum_get,
  6321. .put = alc883_mux_enum_put,
  6322. },
  6323. { } /* end */
  6324. };
  6325. static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
  6326. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6327. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6328. HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  6329. HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
  6330. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
  6331. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
  6332. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
  6333. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
  6334. HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
  6335. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  6336. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  6337. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  6338. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  6339. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6340. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6341. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6342. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6343. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6344. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  6345. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  6346. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  6347. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  6348. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  6349. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6350. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6351. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6352. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6353. {
  6354. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6355. /* .name = "Capture Source", */
  6356. .name = "Input Source",
  6357. .count = 2,
  6358. .info = alc883_mux_enum_info,
  6359. .get = alc883_mux_enum_get,
  6360. .put = alc883_mux_enum_put,
  6361. },
  6362. { } /* end */
  6363. };
  6364. static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
  6365. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  6366. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  6367. HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  6368. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  6369. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  6370. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  6371. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  6372. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  6373. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6374. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6375. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6376. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6377. {
  6378. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6379. /* .name = "Capture Source", */
  6380. .name = "Input Source",
  6381. .count = 2,
  6382. .info = alc883_mux_enum_info,
  6383. .get = alc883_mux_enum_get,
  6384. .put = alc883_mux_enum_put,
  6385. },
  6386. { } /* end */
  6387. };
  6388. static struct snd_kcontrol_new alc883_chmode_mixer[] = {
  6389. {
  6390. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6391. .name = "Channel Mode",
  6392. .info = alc_ch_mode_info,
  6393. .get = alc_ch_mode_get,
  6394. .put = alc_ch_mode_put,
  6395. },
  6396. { } /* end */
  6397. };
  6398. static struct hda_verb alc883_init_verbs[] = {
  6399. /* ADC1: mute amp left and right */
  6400. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6401. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  6402. /* ADC2: mute amp left and right */
  6403. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6404. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  6405. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  6406. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6407. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6408. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6409. /* Rear mixer */
  6410. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6411. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6412. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6413. /* CLFE mixer */
  6414. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6415. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6416. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6417. /* Side mixer */
  6418. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6419. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6420. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6421. /* mute analog input loopbacks */
  6422. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6423. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6424. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  6425. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  6426. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  6427. /* Front Pin: output 0 (0x0c) */
  6428. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6429. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6430. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  6431. /* Rear Pin: output 1 (0x0d) */
  6432. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6433. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6434. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  6435. /* CLFE Pin: output 2 (0x0e) */
  6436. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6437. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6438. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  6439. /* Side Pin: output 3 (0x0f) */
  6440. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6441. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6442. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  6443. /* Mic (rear) pin: input vref at 80% */
  6444. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  6445. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6446. /* Front Mic pin: input vref at 80% */
  6447. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  6448. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6449. /* Line In pin: input */
  6450. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  6451. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  6452. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  6453. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6454. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6455. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  6456. /* CD pin widget for input */
  6457. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  6458. /* FIXME: use matrix-type input source selection */
  6459. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  6460. /* Input mixer2 */
  6461. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6462. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6463. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6464. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6465. /* Input mixer3 */
  6466. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6467. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6468. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6469. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6470. { }
  6471. };
  6472. /* toggle speaker-output according to the hp-jack state */
  6473. static void alc883_mitac_hp_automute(struct hda_codec *codec)
  6474. {
  6475. unsigned int present;
  6476. present = snd_hda_codec_read(codec, 0x15, 0,
  6477. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6478. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6479. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6480. snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
  6481. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6482. }
  6483. /* auto-toggle front mic */
  6484. /*
  6485. static void alc883_mitac_mic_automute(struct hda_codec *codec)
  6486. {
  6487. unsigned int present;
  6488. unsigned char bits;
  6489. present = snd_hda_codec_read(codec, 0x18, 0,
  6490. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6491. bits = present ? HDA_AMP_MUTE : 0;
  6492. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
  6493. }
  6494. */
  6495. static void alc883_mitac_automute(struct hda_codec *codec)
  6496. {
  6497. alc883_mitac_hp_automute(codec);
  6498. /* alc883_mitac_mic_automute(codec); */
  6499. }
  6500. static void alc883_mitac_unsol_event(struct hda_codec *codec,
  6501. unsigned int res)
  6502. {
  6503. switch (res >> 26) {
  6504. case ALC880_HP_EVENT:
  6505. alc883_mitac_hp_automute(codec);
  6506. break;
  6507. case ALC880_MIC_EVENT:
  6508. /* alc883_mitac_mic_automute(codec); */
  6509. break;
  6510. }
  6511. }
  6512. static struct hda_verb alc883_mitac_verbs[] = {
  6513. /* HP */
  6514. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6515. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6516. /* Subwoofer */
  6517. {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
  6518. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6519. /* enable unsolicited event */
  6520. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6521. /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
  6522. { } /* end */
  6523. };
  6524. static struct hda_verb alc883_tagra_verbs[] = {
  6525. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6526. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6527. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6528. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6529. {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
  6530. {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
  6531. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
  6532. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6533. {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  6534. {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  6535. {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  6536. { } /* end */
  6537. };
  6538. static struct hda_verb alc883_lenovo_101e_verbs[] = {
  6539. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6540. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
  6541. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
  6542. { } /* end */
  6543. };
  6544. static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
  6545. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6546. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6547. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6548. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6549. { } /* end */
  6550. };
  6551. static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
  6552. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6553. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6554. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6555. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
  6556. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6557. { } /* end */
  6558. };
  6559. static struct hda_verb alc883_haier_w66_verbs[] = {
  6560. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6561. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6562. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6563. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  6564. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6565. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6566. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6567. { } /* end */
  6568. };
  6569. static struct hda_verb alc888_6st_hp_verbs[] = {
  6570. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
  6571. {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
  6572. {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
  6573. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
  6574. { }
  6575. };
  6576. static struct hda_verb alc888_3st_hp_verbs[] = {
  6577. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
  6578. {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
  6579. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
  6580. { }
  6581. };
  6582. static struct hda_verb alc888_6st_dell_verbs[] = {
  6583. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
  6584. {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
  6585. {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
  6586. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
  6587. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6588. { }
  6589. };
  6590. static struct hda_verb alc888_3st_hp_2ch_init[] = {
  6591. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  6592. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  6593. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  6594. { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  6595. { }
  6596. };
  6597. static struct hda_verb alc888_3st_hp_6ch_init[] = {
  6598. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  6599. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  6600. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  6601. { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  6602. { }
  6603. };
  6604. static struct hda_channel_mode alc888_3st_hp_modes[2] = {
  6605. { 2, alc888_3st_hp_2ch_init },
  6606. { 6, alc888_3st_hp_6ch_init },
  6607. };
  6608. /* toggle front-jack and RCA according to the hp-jack state */
  6609. static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
  6610. {
  6611. unsigned int present;
  6612. present = snd_hda_codec_read(codec, 0x1b, 0,
  6613. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6614. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6615. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6616. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6617. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6618. }
  6619. /* toggle RCA according to the front-jack state */
  6620. static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
  6621. {
  6622. unsigned int present;
  6623. present = snd_hda_codec_read(codec, 0x14, 0,
  6624. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6625. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6626. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6627. }
  6628. static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
  6629. unsigned int res)
  6630. {
  6631. if ((res >> 26) == ALC880_HP_EVENT)
  6632. alc888_lenovo_ms7195_front_automute(codec);
  6633. if ((res >> 26) == ALC880_FRONT_EVENT)
  6634. alc888_lenovo_ms7195_rca_automute(codec);
  6635. }
  6636. static struct hda_verb alc883_medion_md2_verbs[] = {
  6637. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6638. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6639. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6640. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6641. { } /* end */
  6642. };
  6643. /* toggle speaker-output according to the hp-jack state */
  6644. static void alc883_medion_md2_automute(struct hda_codec *codec)
  6645. {
  6646. unsigned int present;
  6647. present = snd_hda_codec_read(codec, 0x14, 0,
  6648. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6649. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6650. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6651. }
  6652. static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
  6653. unsigned int res)
  6654. {
  6655. if ((res >> 26) == ALC880_HP_EVENT)
  6656. alc883_medion_md2_automute(codec);
  6657. }
  6658. /* toggle speaker-output according to the hp-jack state */
  6659. static void alc883_tagra_automute(struct hda_codec *codec)
  6660. {
  6661. unsigned int present;
  6662. unsigned char bits;
  6663. present = snd_hda_codec_read(codec, 0x14, 0,
  6664. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6665. bits = present ? HDA_AMP_MUTE : 0;
  6666. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  6667. HDA_AMP_MUTE, bits);
  6668. snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
  6669. present ? 1 : 3);
  6670. }
  6671. static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
  6672. {
  6673. if ((res >> 26) == ALC880_HP_EVENT)
  6674. alc883_tagra_automute(codec);
  6675. }
  6676. static void alc883_haier_w66_automute(struct hda_codec *codec)
  6677. {
  6678. unsigned int present;
  6679. unsigned char bits;
  6680. present = snd_hda_codec_read(codec, 0x1b, 0,
  6681. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6682. bits = present ? 0x80 : 0;
  6683. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6684. 0x80, bits);
  6685. }
  6686. static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
  6687. unsigned int res)
  6688. {
  6689. if ((res >> 26) == ALC880_HP_EVENT)
  6690. alc883_haier_w66_automute(codec);
  6691. }
  6692. static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
  6693. {
  6694. unsigned int present;
  6695. unsigned char bits;
  6696. present = snd_hda_codec_read(codec, 0x14, 0,
  6697. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6698. bits = present ? HDA_AMP_MUTE : 0;
  6699. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6700. HDA_AMP_MUTE, bits);
  6701. }
  6702. static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
  6703. {
  6704. unsigned int present;
  6705. unsigned char bits;
  6706. present = snd_hda_codec_read(codec, 0x1b, 0,
  6707. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6708. bits = present ? HDA_AMP_MUTE : 0;
  6709. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6710. HDA_AMP_MUTE, bits);
  6711. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6712. HDA_AMP_MUTE, bits);
  6713. }
  6714. static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
  6715. unsigned int res)
  6716. {
  6717. if ((res >> 26) == ALC880_HP_EVENT)
  6718. alc883_lenovo_101e_all_automute(codec);
  6719. if ((res >> 26) == ALC880_FRONT_EVENT)
  6720. alc883_lenovo_101e_ispeaker_automute(codec);
  6721. }
  6722. /* toggle speaker-output according to the hp-jack state */
  6723. static void alc883_acer_aspire_automute(struct hda_codec *codec)
  6724. {
  6725. unsigned int present;
  6726. present = snd_hda_codec_read(codec, 0x14, 0,
  6727. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6728. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6729. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6730. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  6731. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6732. }
  6733. static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
  6734. unsigned int res)
  6735. {
  6736. if ((res >> 26) == ALC880_HP_EVENT)
  6737. alc883_acer_aspire_automute(codec);
  6738. }
  6739. static struct hda_verb alc883_acer_eapd_verbs[] = {
  6740. /* HP Pin: output 0 (0x0c) */
  6741. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  6742. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  6743. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  6744. /* Front Pin: output 0 (0x0c) */
  6745. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6746. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  6747. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  6748. {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
  6749. /* eanable EAPD on medion laptop */
  6750. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  6751. {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
  6752. /* enable unsolicited event */
  6753. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  6754. { }
  6755. };
  6756. static void alc888_6st_dell_front_automute(struct hda_codec *codec)
  6757. {
  6758. unsigned int present;
  6759. present = snd_hda_codec_read(codec, 0x1b, 0,
  6760. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  6761. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  6762. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6763. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  6764. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6765. snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
  6766. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6767. snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
  6768. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  6769. }
  6770. static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
  6771. unsigned int res)
  6772. {
  6773. switch (res >> 26) {
  6774. case ALC880_HP_EVENT:
  6775. printk("hp_event\n");
  6776. alc888_6st_dell_front_automute(codec);
  6777. break;
  6778. }
  6779. }
  6780. /*
  6781. * generic initialization of ADC, input mixers and output mixers
  6782. */
  6783. static struct hda_verb alc883_auto_init_verbs[] = {
  6784. /*
  6785. * Unmute ADC0-2 and set the default input to mic-in
  6786. */
  6787. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  6788. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6789. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  6790. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6791. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  6792. * mixer widget
  6793. * Note: PASD motherboards uses the Line In 2 as the input for
  6794. * front panel mic (mic 2)
  6795. */
  6796. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  6797. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  6798. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  6799. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  6800. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  6801. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  6802. /*
  6803. * Set up output mixers (0x0c - 0x0f)
  6804. */
  6805. /* set vol=0 to output mixers */
  6806. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6807. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6808. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6809. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  6810. /* set up input amps for analog loopback */
  6811. /* Amp Indices: DAC = 0, mixer = 1 */
  6812. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6813. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6814. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6815. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6816. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6817. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6818. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6819. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6820. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6821. {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6822. /* FIXME: use matrix-type input source selection */
  6823. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  6824. /* Input mixer1 */
  6825. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6826. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6827. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6828. /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
  6829. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6830. /* Input mixer2 */
  6831. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  6832. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  6833. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  6834. /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
  6835. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  6836. { }
  6837. };
  6838. /* capture mixer elements */
  6839. static struct snd_kcontrol_new alc883_capture_mixer[] = {
  6840. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  6841. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  6842. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
  6843. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
  6844. {
  6845. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  6846. /* The multiple "Capture Source" controls confuse alsamixer
  6847. * So call somewhat different..
  6848. */
  6849. /* .name = "Capture Source", */
  6850. .name = "Input Source",
  6851. .count = 2,
  6852. .info = alc882_mux_enum_info,
  6853. .get = alc882_mux_enum_get,
  6854. .put = alc882_mux_enum_put,
  6855. },
  6856. { } /* end */
  6857. };
  6858. #ifdef CONFIG_SND_HDA_POWER_SAVE
  6859. #define alc883_loopbacks alc880_loopbacks
  6860. #endif
  6861. /* pcm configuration: identiacal with ALC880 */
  6862. #define alc883_pcm_analog_playback alc880_pcm_analog_playback
  6863. #define alc883_pcm_analog_capture alc880_pcm_analog_capture
  6864. #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
  6865. #define alc883_pcm_digital_playback alc880_pcm_digital_playback
  6866. #define alc883_pcm_digital_capture alc880_pcm_digital_capture
  6867. /*
  6868. * configuration and preset
  6869. */
  6870. static const char *alc883_models[ALC883_MODEL_LAST] = {
  6871. [ALC883_3ST_2ch_DIG] = "3stack-dig",
  6872. [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
  6873. [ALC883_3ST_6ch] = "3stack-6ch",
  6874. [ALC883_6ST_DIG] = "6stack-dig",
  6875. [ALC883_TARGA_DIG] = "targa-dig",
  6876. [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
  6877. [ALC883_ACER] = "acer",
  6878. [ALC883_ACER_ASPIRE] = "acer-aspire",
  6879. [ALC883_MEDION] = "medion",
  6880. [ALC883_MEDION_MD2] = "medion-md2",
  6881. [ALC883_LAPTOP_EAPD] = "laptop-eapd",
  6882. [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
  6883. [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
  6884. [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
  6885. [ALC883_HAIER_W66] = "haier-w66",
  6886. [ALC888_6ST_HP] = "6stack-hp",
  6887. [ALC888_3ST_HP] = "3stack-hp",
  6888. [ALC888_6ST_DELL] = "6stack-dell",
  6889. [ALC883_MITAC] = "mitac",
  6890. [ALC883_AUTO] = "auto",
  6891. };
  6892. static struct snd_pci_quirk alc883_cfg_tbl[] = {
  6893. SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
  6894. SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
  6895. SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
  6896. SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
  6897. SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
  6898. SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
  6899. SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
  6900. SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
  6901. SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
  6902. SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
  6903. SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
  6904. SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
  6905. SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
  6906. SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
  6907. SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
  6908. SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
  6909. SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
  6910. SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
  6911. SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
  6912. SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
  6913. SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
  6914. SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
  6915. SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
  6916. SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
  6917. SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
  6918. SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
  6919. SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
  6920. SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
  6921. SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
  6922. SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
  6923. SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
  6924. SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
  6925. SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
  6926. SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
  6927. SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
  6928. SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
  6929. SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
  6930. SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
  6931. SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
  6932. SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
  6933. SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6934. SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6935. SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
  6936. SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
  6937. SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
  6938. SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
  6939. SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
  6940. {}
  6941. };
  6942. static struct alc_config_preset alc883_presets[] = {
  6943. [ALC883_3ST_2ch_DIG] = {
  6944. .mixers = { alc883_3ST_2ch_mixer },
  6945. .init_verbs = { alc883_init_verbs },
  6946. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6947. .dac_nids = alc883_dac_nids,
  6948. .dig_out_nid = ALC883_DIGOUT_NID,
  6949. .dig_in_nid = ALC883_DIGIN_NID,
  6950. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  6951. .channel_mode = alc883_3ST_2ch_modes,
  6952. .input_mux = &alc883_capture_source,
  6953. },
  6954. [ALC883_3ST_6ch_DIG] = {
  6955. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  6956. .init_verbs = { alc883_init_verbs },
  6957. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6958. .dac_nids = alc883_dac_nids,
  6959. .dig_out_nid = ALC883_DIGOUT_NID,
  6960. .dig_in_nid = ALC883_DIGIN_NID,
  6961. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6962. .channel_mode = alc883_3ST_6ch_modes,
  6963. .need_dac_fix = 1,
  6964. .input_mux = &alc883_capture_source,
  6965. },
  6966. [ALC883_3ST_6ch] = {
  6967. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  6968. .init_verbs = { alc883_init_verbs },
  6969. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6970. .dac_nids = alc883_dac_nids,
  6971. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6972. .channel_mode = alc883_3ST_6ch_modes,
  6973. .need_dac_fix = 1,
  6974. .input_mux = &alc883_capture_source,
  6975. },
  6976. [ALC883_6ST_DIG] = {
  6977. .mixers = { alc883_base_mixer, alc883_chmode_mixer },
  6978. .init_verbs = { alc883_init_verbs },
  6979. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6980. .dac_nids = alc883_dac_nids,
  6981. .dig_out_nid = ALC883_DIGOUT_NID,
  6982. .dig_in_nid = ALC883_DIGIN_NID,
  6983. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  6984. .channel_mode = alc883_sixstack_modes,
  6985. .input_mux = &alc883_capture_source,
  6986. },
  6987. [ALC883_TARGA_DIG] = {
  6988. .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
  6989. .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
  6990. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  6991. .dac_nids = alc883_dac_nids,
  6992. .dig_out_nid = ALC883_DIGOUT_NID,
  6993. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  6994. .channel_mode = alc883_3ST_6ch_modes,
  6995. .need_dac_fix = 1,
  6996. .input_mux = &alc883_capture_source,
  6997. .unsol_event = alc883_tagra_unsol_event,
  6998. .init_hook = alc883_tagra_automute,
  6999. },
  7000. [ALC883_TARGA_2ch_DIG] = {
  7001. .mixers = { alc883_tagra_2ch_mixer},
  7002. .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
  7003. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7004. .dac_nids = alc883_dac_nids,
  7005. .dig_out_nid = ALC883_DIGOUT_NID,
  7006. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7007. .channel_mode = alc883_3ST_2ch_modes,
  7008. .input_mux = &alc883_capture_source,
  7009. .unsol_event = alc883_tagra_unsol_event,
  7010. .init_hook = alc883_tagra_automute,
  7011. },
  7012. [ALC883_ACER] = {
  7013. .mixers = { alc883_base_mixer },
  7014. /* On TravelMate laptops, GPIO 0 enables the internal speaker
  7015. * and the headphone jack. Turn this on and rely on the
  7016. * standard mute methods whenever the user wants to turn
  7017. * these outputs off.
  7018. */
  7019. .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
  7020. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7021. .dac_nids = alc883_dac_nids,
  7022. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7023. .channel_mode = alc883_3ST_2ch_modes,
  7024. .input_mux = &alc883_capture_source,
  7025. },
  7026. [ALC883_ACER_ASPIRE] = {
  7027. .mixers = { alc883_acer_aspire_mixer },
  7028. .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
  7029. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7030. .dac_nids = alc883_dac_nids,
  7031. .dig_out_nid = ALC883_DIGOUT_NID,
  7032. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7033. .channel_mode = alc883_3ST_2ch_modes,
  7034. .input_mux = &alc883_capture_source,
  7035. .unsol_event = alc883_acer_aspire_unsol_event,
  7036. .init_hook = alc883_acer_aspire_automute,
  7037. },
  7038. [ALC883_MEDION] = {
  7039. .mixers = { alc883_fivestack_mixer,
  7040. alc883_chmode_mixer },
  7041. .init_verbs = { alc883_init_verbs,
  7042. alc883_medion_eapd_verbs },
  7043. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7044. .dac_nids = alc883_dac_nids,
  7045. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  7046. .channel_mode = alc883_sixstack_modes,
  7047. .input_mux = &alc883_capture_source,
  7048. },
  7049. [ALC883_MEDION_MD2] = {
  7050. .mixers = { alc883_medion_md2_mixer},
  7051. .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
  7052. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7053. .dac_nids = alc883_dac_nids,
  7054. .dig_out_nid = ALC883_DIGOUT_NID,
  7055. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7056. .channel_mode = alc883_3ST_2ch_modes,
  7057. .input_mux = &alc883_capture_source,
  7058. .unsol_event = alc883_medion_md2_unsol_event,
  7059. .init_hook = alc883_medion_md2_automute,
  7060. },
  7061. [ALC883_LAPTOP_EAPD] = {
  7062. .mixers = { alc883_base_mixer },
  7063. .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
  7064. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7065. .dac_nids = alc883_dac_nids,
  7066. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7067. .channel_mode = alc883_3ST_2ch_modes,
  7068. .input_mux = &alc883_capture_source,
  7069. },
  7070. [ALC883_LENOVO_101E_2ch] = {
  7071. .mixers = { alc883_lenovo_101e_2ch_mixer},
  7072. .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
  7073. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7074. .dac_nids = alc883_dac_nids,
  7075. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7076. .channel_mode = alc883_3ST_2ch_modes,
  7077. .input_mux = &alc883_lenovo_101e_capture_source,
  7078. .unsol_event = alc883_lenovo_101e_unsol_event,
  7079. .init_hook = alc883_lenovo_101e_all_automute,
  7080. },
  7081. [ALC883_LENOVO_NB0763] = {
  7082. .mixers = { alc883_lenovo_nb0763_mixer },
  7083. .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
  7084. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7085. .dac_nids = alc883_dac_nids,
  7086. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7087. .channel_mode = alc883_3ST_2ch_modes,
  7088. .need_dac_fix = 1,
  7089. .input_mux = &alc883_lenovo_nb0763_capture_source,
  7090. .unsol_event = alc883_medion_md2_unsol_event,
  7091. .init_hook = alc883_medion_md2_automute,
  7092. },
  7093. [ALC888_LENOVO_MS7195_DIG] = {
  7094. .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
  7095. .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
  7096. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7097. .dac_nids = alc883_dac_nids,
  7098. .dig_out_nid = ALC883_DIGOUT_NID,
  7099. .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
  7100. .channel_mode = alc883_3ST_6ch_modes,
  7101. .need_dac_fix = 1,
  7102. .input_mux = &alc883_capture_source,
  7103. .unsol_event = alc883_lenovo_ms7195_unsol_event,
  7104. .init_hook = alc888_lenovo_ms7195_front_automute,
  7105. },
  7106. [ALC883_HAIER_W66] = {
  7107. .mixers = { alc883_tagra_2ch_mixer},
  7108. .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
  7109. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7110. .dac_nids = alc883_dac_nids,
  7111. .dig_out_nid = ALC883_DIGOUT_NID,
  7112. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7113. .channel_mode = alc883_3ST_2ch_modes,
  7114. .input_mux = &alc883_capture_source,
  7115. .unsol_event = alc883_haier_w66_unsol_event,
  7116. .init_hook = alc883_haier_w66_automute,
  7117. },
  7118. [ALC888_6ST_HP] = {
  7119. .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
  7120. .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
  7121. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7122. .dac_nids = alc883_dac_nids,
  7123. .dig_out_nid = ALC883_DIGOUT_NID,
  7124. .dig_in_nid = ALC883_DIGIN_NID,
  7125. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  7126. .channel_mode = alc883_sixstack_modes,
  7127. .input_mux = &alc883_capture_source,
  7128. },
  7129. [ALC888_3ST_HP] = {
  7130. .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
  7131. .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
  7132. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7133. .dac_nids = alc883_dac_nids,
  7134. .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
  7135. .channel_mode = alc888_3st_hp_modes,
  7136. .need_dac_fix = 1,
  7137. .input_mux = &alc883_capture_source,
  7138. },
  7139. [ALC888_6ST_DELL] = {
  7140. .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
  7141. .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
  7142. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7143. .dac_nids = alc883_dac_nids,
  7144. .dig_out_nid = ALC883_DIGOUT_NID,
  7145. .dig_in_nid = ALC883_DIGIN_NID,
  7146. .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
  7147. .channel_mode = alc883_sixstack_modes,
  7148. .input_mux = &alc883_capture_source,
  7149. .unsol_event = alc888_6st_dell_unsol_event,
  7150. .init_hook = alc888_6st_dell_front_automute,
  7151. },
  7152. [ALC883_MITAC] = {
  7153. .mixers = { alc883_mitac_mixer },
  7154. .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
  7155. .num_dacs = ARRAY_SIZE(alc883_dac_nids),
  7156. .dac_nids = alc883_dac_nids,
  7157. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  7158. .channel_mode = alc883_3ST_2ch_modes,
  7159. .input_mux = &alc883_capture_source,
  7160. .unsol_event = alc883_mitac_unsol_event,
  7161. .init_hook = alc883_mitac_automute,
  7162. },
  7163. };
  7164. /*
  7165. * BIOS auto configuration
  7166. */
  7167. static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
  7168. hda_nid_t nid, int pin_type,
  7169. int dac_idx)
  7170. {
  7171. /* set as output */
  7172. struct alc_spec *spec = codec->spec;
  7173. int idx;
  7174. alc_set_pin_output(codec, nid, pin_type);
  7175. if (spec->multiout.dac_nids[dac_idx] == 0x25)
  7176. idx = 4;
  7177. else
  7178. idx = spec->multiout.dac_nids[dac_idx] - 2;
  7179. snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
  7180. }
  7181. static void alc883_auto_init_multi_out(struct hda_codec *codec)
  7182. {
  7183. struct alc_spec *spec = codec->spec;
  7184. int i;
  7185. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  7186. for (i = 0; i <= HDA_SIDE; i++) {
  7187. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  7188. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  7189. if (nid)
  7190. alc883_auto_set_output_and_unmute(codec, nid, pin_type,
  7191. i);
  7192. }
  7193. }
  7194. static void alc883_auto_init_hp_out(struct hda_codec *codec)
  7195. {
  7196. struct alc_spec *spec = codec->spec;
  7197. hda_nid_t pin;
  7198. pin = spec->autocfg.hp_pins[0];
  7199. if (pin) /* connect to front */
  7200. /* use dac 0 */
  7201. alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  7202. pin = spec->autocfg.speaker_pins[0];
  7203. if (pin)
  7204. alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  7205. }
  7206. #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
  7207. #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
  7208. static void alc883_auto_init_analog_input(struct hda_codec *codec)
  7209. {
  7210. struct alc_spec *spec = codec->spec;
  7211. int i;
  7212. for (i = 0; i < AUTO_PIN_LAST; i++) {
  7213. hda_nid_t nid = spec->autocfg.input_pins[i];
  7214. if (alc883_is_input_pin(nid)) {
  7215. snd_hda_codec_write(codec, nid, 0,
  7216. AC_VERB_SET_PIN_WIDGET_CONTROL,
  7217. (i <= AUTO_PIN_FRONT_MIC ?
  7218. PIN_VREF80 : PIN_IN));
  7219. if (nid != ALC883_PIN_CD_NID)
  7220. snd_hda_codec_write(codec, nid, 0,
  7221. AC_VERB_SET_AMP_GAIN_MUTE,
  7222. AMP_OUT_MUTE);
  7223. }
  7224. }
  7225. }
  7226. /* almost identical with ALC880 parser... */
  7227. static int alc883_parse_auto_config(struct hda_codec *codec)
  7228. {
  7229. struct alc_spec *spec = codec->spec;
  7230. int err = alc880_parse_auto_config(codec);
  7231. if (err < 0)
  7232. return err;
  7233. else if (!err)
  7234. return 0; /* no config found */
  7235. err = alc_auto_add_mic_boost(codec);
  7236. if (err < 0)
  7237. return err;
  7238. /* hack - override the init verbs */
  7239. spec->init_verbs[0] = alc883_auto_init_verbs;
  7240. spec->mixers[spec->num_mixers] = alc883_capture_mixer;
  7241. spec->num_mixers++;
  7242. return 1; /* config found */
  7243. }
  7244. /* additional initialization for auto-configuration model */
  7245. static void alc883_auto_init(struct hda_codec *codec)
  7246. {
  7247. struct alc_spec *spec = codec->spec;
  7248. alc883_auto_init_multi_out(codec);
  7249. alc883_auto_init_hp_out(codec);
  7250. alc883_auto_init_analog_input(codec);
  7251. if (spec->unsol_event)
  7252. alc_sku_automute(codec);
  7253. }
  7254. static int patch_alc883(struct hda_codec *codec)
  7255. {
  7256. struct alc_spec *spec;
  7257. int err, board_config;
  7258. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  7259. if (spec == NULL)
  7260. return -ENOMEM;
  7261. codec->spec = spec;
  7262. board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
  7263. alc883_models,
  7264. alc883_cfg_tbl);
  7265. if (board_config < 0) {
  7266. printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
  7267. "trying auto-probe from BIOS...\n");
  7268. board_config = ALC883_AUTO;
  7269. }
  7270. if (board_config == ALC883_AUTO) {
  7271. /* automatic parse from the BIOS config */
  7272. err = alc883_parse_auto_config(codec);
  7273. if (err < 0) {
  7274. alc_free(codec);
  7275. return err;
  7276. } else if (!err) {
  7277. printk(KERN_INFO
  7278. "hda_codec: Cannot set up configuration "
  7279. "from BIOS. Using base mode...\n");
  7280. board_config = ALC883_3ST_2ch_DIG;
  7281. }
  7282. }
  7283. if (board_config != ALC883_AUTO)
  7284. setup_preset(spec, &alc883_presets[board_config]);
  7285. spec->stream_name_analog = "ALC883 Analog";
  7286. spec->stream_analog_playback = &alc883_pcm_analog_playback;
  7287. spec->stream_analog_capture = &alc883_pcm_analog_capture;
  7288. spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
  7289. spec->stream_name_digital = "ALC883 Digital";
  7290. spec->stream_digital_playback = &alc883_pcm_digital_playback;
  7291. spec->stream_digital_capture = &alc883_pcm_digital_capture;
  7292. spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
  7293. spec->adc_nids = alc883_adc_nids;
  7294. spec->capsrc_nids = alc883_capsrc_nids;
  7295. spec->vmaster_nid = 0x0c;
  7296. codec->patch_ops = alc_patch_ops;
  7297. if (board_config == ALC883_AUTO)
  7298. spec->init_hook = alc883_auto_init;
  7299. #ifdef CONFIG_SND_HDA_POWER_SAVE
  7300. if (!spec->loopback.amplist)
  7301. spec->loopback.amplist = alc883_loopbacks;
  7302. #endif
  7303. return 0;
  7304. }
  7305. /*
  7306. * ALC262 support
  7307. */
  7308. #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
  7309. #define ALC262_DIGIN_NID ALC880_DIGIN_NID
  7310. #define alc262_dac_nids alc260_dac_nids
  7311. #define alc262_adc_nids alc882_adc_nids
  7312. #define alc262_adc_nids_alt alc882_adc_nids_alt
  7313. #define alc262_modes alc260_modes
  7314. #define alc262_capture_source alc882_capture_source
  7315. static struct snd_kcontrol_new alc262_base_mixer[] = {
  7316. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7317. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7318. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7319. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7320. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7321. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7322. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7323. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7324. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7325. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7326. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7327. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7328. /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7329. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
  7330. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
  7331. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7332. HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
  7333. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  7334. { } /* end */
  7335. };
  7336. static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
  7337. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7338. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7339. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7340. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7341. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7342. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7343. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7344. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7345. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7346. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7347. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7348. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7349. /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7350. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
  7351. /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
  7352. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7353. { } /* end */
  7354. };
  7355. /* update HP, line and mono-out pins according to the master switch */
  7356. static void alc262_hp_master_update(struct hda_codec *codec)
  7357. {
  7358. struct alc_spec *spec = codec->spec;
  7359. int val = spec->master_sw;
  7360. /* HP & line-out */
  7361. snd_hda_codec_write_cache(codec, 0x1b, 0,
  7362. AC_VERB_SET_PIN_WIDGET_CONTROL,
  7363. val ? PIN_HP : 0);
  7364. snd_hda_codec_write_cache(codec, 0x15, 0,
  7365. AC_VERB_SET_PIN_WIDGET_CONTROL,
  7366. val ? PIN_HP : 0);
  7367. /* mono (speaker) depending on the HP jack sense */
  7368. val = val && !spec->jack_present;
  7369. snd_hda_codec_write_cache(codec, 0x16, 0,
  7370. AC_VERB_SET_PIN_WIDGET_CONTROL,
  7371. val ? PIN_OUT : 0);
  7372. }
  7373. static void alc262_hp_bpc_automute(struct hda_codec *codec)
  7374. {
  7375. struct alc_spec *spec = codec->spec;
  7376. unsigned int presence;
  7377. presence = snd_hda_codec_read(codec, 0x1b, 0,
  7378. AC_VERB_GET_PIN_SENSE, 0);
  7379. spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
  7380. alc262_hp_master_update(codec);
  7381. }
  7382. static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
  7383. {
  7384. if ((res >> 26) != ALC880_HP_EVENT)
  7385. return;
  7386. alc262_hp_bpc_automute(codec);
  7387. }
  7388. static void alc262_hp_wildwest_automute(struct hda_codec *codec)
  7389. {
  7390. struct alc_spec *spec = codec->spec;
  7391. unsigned int presence;
  7392. presence = snd_hda_codec_read(codec, 0x15, 0,
  7393. AC_VERB_GET_PIN_SENSE, 0);
  7394. spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
  7395. alc262_hp_master_update(codec);
  7396. }
  7397. static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
  7398. unsigned int res)
  7399. {
  7400. if ((res >> 26) != ALC880_HP_EVENT)
  7401. return;
  7402. alc262_hp_wildwest_automute(codec);
  7403. }
  7404. static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
  7405. struct snd_ctl_elem_value *ucontrol)
  7406. {
  7407. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7408. struct alc_spec *spec = codec->spec;
  7409. *ucontrol->value.integer.value = spec->master_sw;
  7410. return 0;
  7411. }
  7412. static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
  7413. struct snd_ctl_elem_value *ucontrol)
  7414. {
  7415. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7416. struct alc_spec *spec = codec->spec;
  7417. int val = !!*ucontrol->value.integer.value;
  7418. if (val == spec->master_sw)
  7419. return 0;
  7420. spec->master_sw = val;
  7421. alc262_hp_master_update(codec);
  7422. return 1;
  7423. }
  7424. static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
  7425. {
  7426. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7427. .name = "Master Playback Switch",
  7428. .info = snd_ctl_boolean_mono_info,
  7429. .get = alc262_hp_master_sw_get,
  7430. .put = alc262_hp_master_sw_put,
  7431. },
  7432. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7433. HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7434. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7435. HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
  7436. HDA_OUTPUT),
  7437. HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
  7438. HDA_OUTPUT),
  7439. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7440. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7441. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7442. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7443. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7444. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  7445. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7446. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7447. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7448. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7449. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7450. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
  7451. HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
  7452. HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
  7453. { } /* end */
  7454. };
  7455. static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
  7456. {
  7457. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7458. .name = "Master Playback Switch",
  7459. .info = snd_ctl_boolean_mono_info,
  7460. .get = alc262_hp_master_sw_get,
  7461. .put = alc262_hp_master_sw_put,
  7462. },
  7463. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7464. HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7465. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  7466. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7467. HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
  7468. HDA_OUTPUT),
  7469. HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
  7470. HDA_OUTPUT),
  7471. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
  7472. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
  7473. HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
  7474. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7475. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7476. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7477. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7478. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
  7479. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
  7480. { } /* end */
  7481. };
  7482. static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
  7483. HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7484. HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7485. HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
  7486. { } /* end */
  7487. };
  7488. /* mute/unmute internal speaker according to the hp jack and mute state */
  7489. static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
  7490. {
  7491. struct alc_spec *spec = codec->spec;
  7492. if (force || !spec->sense_updated) {
  7493. unsigned int present;
  7494. present = snd_hda_codec_read(codec, 0x15, 0,
  7495. AC_VERB_GET_PIN_SENSE, 0);
  7496. spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
  7497. spec->sense_updated = 1;
  7498. }
  7499. snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
  7500. spec->jack_present ? HDA_AMP_MUTE : 0);
  7501. }
  7502. static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
  7503. unsigned int res)
  7504. {
  7505. if ((res >> 26) != ALC880_HP_EVENT)
  7506. return;
  7507. alc262_hp_t5735_automute(codec, 1);
  7508. }
  7509. static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
  7510. {
  7511. alc262_hp_t5735_automute(codec, 1);
  7512. }
  7513. static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
  7514. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7515. HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7516. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
  7517. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7518. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7519. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7520. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7521. { } /* end */
  7522. };
  7523. static struct hda_verb alc262_hp_t5735_verbs[] = {
  7524. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  7525. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7526. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  7527. { }
  7528. };
  7529. static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
  7530. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7531. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  7532. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
  7533. HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
  7534. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7535. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7536. { } /* end */
  7537. };
  7538. static struct hda_verb alc262_hp_rp5700_verbs[] = {
  7539. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  7540. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  7541. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  7542. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  7543. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  7544. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  7545. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7546. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7547. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
  7548. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
  7549. {}
  7550. };
  7551. static struct hda_input_mux alc262_hp_rp5700_capture_source = {
  7552. .num_items = 1,
  7553. .items = {
  7554. { "Line", 0x1 },
  7555. },
  7556. };
  7557. /* bind hp and internal speaker mute (with plug check) */
  7558. static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
  7559. struct snd_ctl_elem_value *ucontrol)
  7560. {
  7561. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7562. long *valp = ucontrol->value.integer.value;
  7563. int change;
  7564. /* change hp mute */
  7565. change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
  7566. HDA_AMP_MUTE,
  7567. valp[0] ? 0 : HDA_AMP_MUTE);
  7568. change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
  7569. HDA_AMP_MUTE,
  7570. valp[1] ? 0 : HDA_AMP_MUTE);
  7571. if (change) {
  7572. /* change speaker according to HP jack state */
  7573. struct alc_spec *spec = codec->spec;
  7574. unsigned int mute;
  7575. if (spec->jack_present)
  7576. mute = HDA_AMP_MUTE;
  7577. else
  7578. mute = snd_hda_codec_amp_read(codec, 0x15, 0,
  7579. HDA_OUTPUT, 0);
  7580. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7581. HDA_AMP_MUTE, mute);
  7582. }
  7583. return change;
  7584. }
  7585. static struct snd_kcontrol_new alc262_sony_mixer[] = {
  7586. HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7587. {
  7588. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7589. .name = "Master Playback Switch",
  7590. .info = snd_hda_mixer_amp_switch_info,
  7591. .get = snd_hda_mixer_amp_switch_get,
  7592. .put = alc262_sony_master_sw_put,
  7593. .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
  7594. },
  7595. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7596. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7597. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7598. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7599. { } /* end */
  7600. };
  7601. static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
  7602. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7603. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7604. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7605. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7606. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7607. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7608. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7609. { } /* end */
  7610. };
  7611. #define alc262_capture_mixer alc882_capture_mixer
  7612. #define alc262_capture_alt_mixer alc882_capture_alt_mixer
  7613. /*
  7614. * generic initialization of ADC, input mixers and output mixers
  7615. */
  7616. static struct hda_verb alc262_init_verbs[] = {
  7617. /*
  7618. * Unmute ADC0-2 and set the default input to mic-in
  7619. */
  7620. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  7621. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7622. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  7623. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7624. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  7625. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7626. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  7627. * mixer widget
  7628. * Note: PASD motherboards uses the Line In 2 as the input for
  7629. * front panel mic (mic 2)
  7630. */
  7631. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  7632. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  7633. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  7634. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  7635. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  7636. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  7637. /*
  7638. * Set up output mixers (0x0c - 0x0e)
  7639. */
  7640. /* set vol=0 to output mixers */
  7641. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7642. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7643. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  7644. /* set up input amps for analog loopback */
  7645. /* Amp Indices: DAC = 0, mixer = 1 */
  7646. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7647. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7648. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7649. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7650. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  7651. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  7652. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7653. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7654. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7655. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7656. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7657. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  7658. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7659. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7660. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7661. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7662. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7663. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  7664. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  7665. /* FIXME: use matrix-type input source selection */
  7666. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  7667. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  7668. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7669. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7670. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7671. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7672. /* Input mixer2 */
  7673. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7674. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7675. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7676. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7677. /* Input mixer3 */
  7678. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  7679. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  7680. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  7681. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  7682. { }
  7683. };
  7684. static struct hda_verb alc262_hippo_unsol_verbs[] = {
  7685. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7686. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7687. {}
  7688. };
  7689. static struct hda_verb alc262_hippo1_unsol_verbs[] = {
  7690. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7691. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  7692. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
  7693. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7694. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7695. {}
  7696. };
  7697. static struct hda_verb alc262_sony_unsol_verbs[] = {
  7698. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  7699. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  7700. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
  7701. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7702. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7703. };
  7704. /* mute/unmute internal speaker according to the hp jack and mute state */
  7705. static void alc262_hippo_automute(struct hda_codec *codec)
  7706. {
  7707. struct alc_spec *spec = codec->spec;
  7708. unsigned int mute;
  7709. unsigned int present;
  7710. /* need to execute and sync at first */
  7711. snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
  7712. present = snd_hda_codec_read(codec, 0x15, 0,
  7713. AC_VERB_GET_PIN_SENSE, 0);
  7714. spec->jack_present = (present & 0x80000000) != 0;
  7715. if (spec->jack_present) {
  7716. /* mute internal speaker */
  7717. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7718. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7719. } else {
  7720. /* unmute internal speaker if necessary */
  7721. mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
  7722. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7723. HDA_AMP_MUTE, mute);
  7724. }
  7725. }
  7726. /* unsolicited event for HP jack sensing */
  7727. static void alc262_hippo_unsol_event(struct hda_codec *codec,
  7728. unsigned int res)
  7729. {
  7730. if ((res >> 26) != ALC880_HP_EVENT)
  7731. return;
  7732. alc262_hippo_automute(codec);
  7733. }
  7734. static void alc262_hippo1_automute(struct hda_codec *codec)
  7735. {
  7736. unsigned int mute;
  7737. unsigned int present;
  7738. snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
  7739. present = snd_hda_codec_read(codec, 0x1b, 0,
  7740. AC_VERB_GET_PIN_SENSE, 0);
  7741. present = (present & 0x80000000) != 0;
  7742. if (present) {
  7743. /* mute internal speaker */
  7744. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7745. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7746. } else {
  7747. /* unmute internal speaker if necessary */
  7748. mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
  7749. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7750. HDA_AMP_MUTE, mute);
  7751. }
  7752. }
  7753. /* unsolicited event for HP jack sensing */
  7754. static void alc262_hippo1_unsol_event(struct hda_codec *codec,
  7755. unsigned int res)
  7756. {
  7757. if ((res >> 26) != ALC880_HP_EVENT)
  7758. return;
  7759. alc262_hippo1_automute(codec);
  7760. }
  7761. /*
  7762. * fujitsu model
  7763. * 0x14 = headphone/spdif-out, 0x15 = internal speaker
  7764. */
  7765. #define ALC_HP_EVENT 0x37
  7766. static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
  7767. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
  7768. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7769. {}
  7770. };
  7771. static struct hda_input_mux alc262_fujitsu_capture_source = {
  7772. .num_items = 3,
  7773. .items = {
  7774. { "Mic", 0x0 },
  7775. { "Int Mic", 0x1 },
  7776. { "CD", 0x4 },
  7777. },
  7778. };
  7779. static struct hda_input_mux alc262_HP_capture_source = {
  7780. .num_items = 5,
  7781. .items = {
  7782. { "Mic", 0x0 },
  7783. { "Front Mic", 0x1 },
  7784. { "Line", 0x2 },
  7785. { "CD", 0x4 },
  7786. { "AUX IN", 0x6 },
  7787. },
  7788. };
  7789. static struct hda_input_mux alc262_HP_D7000_capture_source = {
  7790. .num_items = 4,
  7791. .items = {
  7792. { "Mic", 0x0 },
  7793. { "Front Mic", 0x2 },
  7794. { "Line", 0x1 },
  7795. { "CD", 0x4 },
  7796. },
  7797. };
  7798. /* mute/unmute internal speaker according to the hp jack and mute state */
  7799. static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
  7800. {
  7801. struct alc_spec *spec = codec->spec;
  7802. unsigned int mute;
  7803. if (force || !spec->sense_updated) {
  7804. unsigned int present;
  7805. /* need to execute and sync at first */
  7806. snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
  7807. present = snd_hda_codec_read(codec, 0x14, 0,
  7808. AC_VERB_GET_PIN_SENSE, 0);
  7809. spec->jack_present = (present & 0x80000000) != 0;
  7810. spec->sense_updated = 1;
  7811. }
  7812. if (spec->jack_present) {
  7813. /* mute internal speaker */
  7814. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  7815. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7816. } else {
  7817. /* unmute internal speaker if necessary */
  7818. mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
  7819. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  7820. HDA_AMP_MUTE, mute);
  7821. }
  7822. }
  7823. /* unsolicited event for HP jack sensing */
  7824. static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
  7825. unsigned int res)
  7826. {
  7827. if ((res >> 26) != ALC_HP_EVENT)
  7828. return;
  7829. alc262_fujitsu_automute(codec, 1);
  7830. }
  7831. /* bind volumes of both NID 0x0c and 0x0d */
  7832. static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
  7833. .ops = &snd_hda_bind_vol,
  7834. .values = {
  7835. HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
  7836. HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
  7837. 0
  7838. },
  7839. };
  7840. /* bind hp and internal speaker mute (with plug check) */
  7841. static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
  7842. struct snd_ctl_elem_value *ucontrol)
  7843. {
  7844. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  7845. long *valp = ucontrol->value.integer.value;
  7846. int change;
  7847. change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
  7848. HDA_AMP_MUTE,
  7849. valp[0] ? 0 : HDA_AMP_MUTE);
  7850. change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
  7851. HDA_AMP_MUTE,
  7852. valp[1] ? 0 : HDA_AMP_MUTE);
  7853. if (change)
  7854. alc262_fujitsu_automute(codec, 0);
  7855. return change;
  7856. }
  7857. static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
  7858. HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
  7859. {
  7860. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  7861. .name = "Master Playback Switch",
  7862. .info = snd_hda_mixer_amp_switch_info,
  7863. .get = snd_hda_mixer_amp_switch_get,
  7864. .put = alc262_fujitsu_master_sw_put,
  7865. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  7866. },
  7867. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  7868. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  7869. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  7870. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  7871. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  7872. HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
  7873. HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  7874. HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  7875. { } /* end */
  7876. };
  7877. /* additional init verbs for Benq laptops */
  7878. static struct hda_verb alc262_EAPD_verbs[] = {
  7879. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  7880. {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
  7881. {}
  7882. };
  7883. static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
  7884. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  7885. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7886. {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
  7887. {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
  7888. {}
  7889. };
  7890. /* Samsung Q1 Ultra Vista model setup */
  7891. static struct snd_kcontrol_new alc262_ultra_mixer[] = {
  7892. HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
  7893. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  7894. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  7895. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  7896. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  7897. HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
  7898. { } /* end */
  7899. };
  7900. static struct hda_verb alc262_ultra_verbs[] = {
  7901. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  7902. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  7903. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  7904. /* Mic is on Node 0x19 */
  7905. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  7906. {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
  7907. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7908. {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
  7909. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7910. {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
  7911. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  7912. {}
  7913. };
  7914. static struct hda_input_mux alc262_ultra_capture_source = {
  7915. .num_items = 1,
  7916. .items = {
  7917. { "Mic", 0x1 },
  7918. },
  7919. };
  7920. /* mute/unmute internal speaker according to the hp jack and mute state */
  7921. static void alc262_ultra_automute(struct hda_codec *codec)
  7922. {
  7923. struct alc_spec *spec = codec->spec;
  7924. unsigned int mute;
  7925. unsigned int present;
  7926. /* need to execute and sync at first */
  7927. snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
  7928. present = snd_hda_codec_read(codec, 0x15, 0,
  7929. AC_VERB_GET_PIN_SENSE, 0);
  7930. spec->jack_present = (present & 0x80000000) != 0;
  7931. if (spec->jack_present) {
  7932. /* mute internal speaker */
  7933. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7934. HDA_AMP_MUTE, HDA_AMP_MUTE);
  7935. } else {
  7936. /* unmute internal speaker if necessary */
  7937. mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
  7938. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  7939. HDA_AMP_MUTE, mute);
  7940. }
  7941. }
  7942. /* unsolicited event for HP jack sensing */
  7943. static void alc262_ultra_unsol_event(struct hda_codec *codec,
  7944. unsigned int res)
  7945. {
  7946. if ((res >> 26) != ALC880_HP_EVENT)
  7947. return;
  7948. alc262_ultra_automute(codec);
  7949. }
  7950. /* add playback controls from the parsed DAC table */
  7951. static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
  7952. const struct auto_pin_cfg *cfg)
  7953. {
  7954. hda_nid_t nid;
  7955. int err;
  7956. spec->multiout.num_dacs = 1; /* only use one dac */
  7957. spec->multiout.dac_nids = spec->private_dac_nids;
  7958. spec->multiout.dac_nids[0] = 2;
  7959. nid = cfg->line_out_pins[0];
  7960. if (nid) {
  7961. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  7962. "Front Playback Volume",
  7963. HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
  7964. if (err < 0)
  7965. return err;
  7966. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7967. "Front Playback Switch",
  7968. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  7969. if (err < 0)
  7970. return err;
  7971. }
  7972. nid = cfg->speaker_pins[0];
  7973. if (nid) {
  7974. if (nid == 0x16) {
  7975. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  7976. "Speaker Playback Volume",
  7977. HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
  7978. HDA_OUTPUT));
  7979. if (err < 0)
  7980. return err;
  7981. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7982. "Speaker Playback Switch",
  7983. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  7984. HDA_OUTPUT));
  7985. if (err < 0)
  7986. return err;
  7987. } else {
  7988. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  7989. "Speaker Playback Switch",
  7990. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  7991. HDA_OUTPUT));
  7992. if (err < 0)
  7993. return err;
  7994. }
  7995. }
  7996. nid = cfg->hp_pins[0];
  7997. if (nid) {
  7998. /* spec->multiout.hp_nid = 2; */
  7999. if (nid == 0x16) {
  8000. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  8001. "Headphone Playback Volume",
  8002. HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
  8003. HDA_OUTPUT));
  8004. if (err < 0)
  8005. return err;
  8006. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  8007. "Headphone Playback Switch",
  8008. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  8009. HDA_OUTPUT));
  8010. if (err < 0)
  8011. return err;
  8012. } else {
  8013. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  8014. "Headphone Playback Switch",
  8015. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  8016. HDA_OUTPUT));
  8017. if (err < 0)
  8018. return err;
  8019. }
  8020. }
  8021. return 0;
  8022. }
  8023. /* identical with ALC880 */
  8024. #define alc262_auto_create_analog_input_ctls \
  8025. alc880_auto_create_analog_input_ctls
  8026. /*
  8027. * generic initialization of ADC, input mixers and output mixers
  8028. */
  8029. static struct hda_verb alc262_volume_init_verbs[] = {
  8030. /*
  8031. * Unmute ADC0-2 and set the default input to mic-in
  8032. */
  8033. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  8034. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8035. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  8036. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8037. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  8038. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8039. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  8040. * mixer widget
  8041. * Note: PASD motherboards uses the Line In 2 as the input for
  8042. * front panel mic (mic 2)
  8043. */
  8044. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  8045. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  8046. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  8047. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  8048. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  8049. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  8050. /*
  8051. * Set up output mixers (0x0c - 0x0f)
  8052. */
  8053. /* set vol=0 to output mixers */
  8054. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8055. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8056. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8057. /* set up input amps for analog loopback */
  8058. /* Amp Indices: DAC = 0, mixer = 1 */
  8059. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8060. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8061. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8062. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8063. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8064. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8065. /* FIXME: use matrix-type input source selection */
  8066. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  8067. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  8068. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8069. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  8070. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  8071. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  8072. /* Input mixer2 */
  8073. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8074. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  8075. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  8076. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  8077. /* Input mixer3 */
  8078. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8079. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
  8080. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
  8081. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
  8082. { }
  8083. };
  8084. static struct hda_verb alc262_HP_BPC_init_verbs[] = {
  8085. /*
  8086. * Unmute ADC0-2 and set the default input to mic-in
  8087. */
  8088. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  8089. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8090. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  8091. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8092. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  8093. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8094. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  8095. * mixer widget
  8096. * Note: PASD motherboards uses the Line In 2 as the input for
  8097. * front panel mic (mic 2)
  8098. */
  8099. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  8100. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  8101. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  8102. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  8103. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  8104. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  8105. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  8106. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  8107. /*
  8108. * Set up output mixers (0x0c - 0x0e)
  8109. */
  8110. /* set vol=0 to output mixers */
  8111. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8112. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8113. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8114. /* set up input amps for analog loopback */
  8115. /* Amp Indices: DAC = 0, mixer = 1 */
  8116. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8117. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8118. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8119. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8120. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8121. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8122. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8123. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  8124. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  8125. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  8126. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  8127. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  8128. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  8129. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8130. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8131. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8132. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8133. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8134. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  8135. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8136. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8137. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  8138. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8139. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8140. /* FIXME: use matrix-type input source selection */
  8141. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  8142. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  8143. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8144. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  8145. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  8146. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  8147. /* Input mixer2 */
  8148. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8149. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  8150. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  8151. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  8152. /* Input mixer3 */
  8153. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8154. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  8155. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  8156. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  8157. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8158. { }
  8159. };
  8160. static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
  8161. /*
  8162. * Unmute ADC0-2 and set the default input to mic-in
  8163. */
  8164. {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
  8165. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8166. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  8167. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8168. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  8169. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8170. /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  8171. * mixer widget
  8172. * Note: PASD motherboards uses the Line In 2 as the input for front
  8173. * panel mic (mic 2)
  8174. */
  8175. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  8176. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  8177. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  8178. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  8179. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  8180. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  8181. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  8182. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
  8183. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
  8184. /*
  8185. * Set up output mixers (0x0c - 0x0e)
  8186. */
  8187. /* set vol=0 to output mixers */
  8188. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8189. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8190. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8191. /* set up input amps for analog loopback */
  8192. /* Amp Indices: DAC = 0, mixer = 1 */
  8193. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8194. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8195. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8196. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8197. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8198. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8199. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
  8200. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
  8201. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
  8202. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
  8203. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
  8204. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
  8205. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
  8206. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  8207. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  8208. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  8209. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  8210. /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
  8211. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8212. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8213. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
  8214. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8215. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
  8216. /* FIXME: use matrix-type input source selection */
  8217. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  8218. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  8219. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
  8220. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
  8221. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
  8222. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
  8223. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
  8224. /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  8225. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
  8226. /* Input mixer2 */
  8227. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8228. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  8229. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  8230. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  8231. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  8232. /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  8233. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
  8234. /* Input mixer3 */
  8235. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8236. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
  8237. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
  8238. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
  8239. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
  8240. /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
  8241. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
  8242. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8243. { }
  8244. };
  8245. #ifdef CONFIG_SND_HDA_POWER_SAVE
  8246. #define alc262_loopbacks alc880_loopbacks
  8247. #endif
  8248. /* pcm configuration: identiacal with ALC880 */
  8249. #define alc262_pcm_analog_playback alc880_pcm_analog_playback
  8250. #define alc262_pcm_analog_capture alc880_pcm_analog_capture
  8251. #define alc262_pcm_digital_playback alc880_pcm_digital_playback
  8252. #define alc262_pcm_digital_capture alc880_pcm_digital_capture
  8253. /*
  8254. * BIOS auto configuration
  8255. */
  8256. static int alc262_parse_auto_config(struct hda_codec *codec)
  8257. {
  8258. struct alc_spec *spec = codec->spec;
  8259. int err;
  8260. static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
  8261. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  8262. alc262_ignore);
  8263. if (err < 0)
  8264. return err;
  8265. if (!spec->autocfg.line_outs)
  8266. return 0; /* can't find valid BIOS pin config */
  8267. err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
  8268. if (err < 0)
  8269. return err;
  8270. err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
  8271. if (err < 0)
  8272. return err;
  8273. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  8274. if (spec->autocfg.dig_out_pin)
  8275. spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
  8276. if (spec->autocfg.dig_in_pin)
  8277. spec->dig_in_nid = ALC262_DIGIN_NID;
  8278. if (spec->kctl_alloc)
  8279. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  8280. spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
  8281. spec->num_mux_defs = 1;
  8282. spec->input_mux = &spec->private_imux;
  8283. err = alc_auto_add_mic_boost(codec);
  8284. if (err < 0)
  8285. return err;
  8286. return 1;
  8287. }
  8288. #define alc262_auto_init_multi_out alc882_auto_init_multi_out
  8289. #define alc262_auto_init_hp_out alc882_auto_init_hp_out
  8290. #define alc262_auto_init_analog_input alc882_auto_init_analog_input
  8291. /* init callback for auto-configuration model -- overriding the default init */
  8292. static void alc262_auto_init(struct hda_codec *codec)
  8293. {
  8294. struct alc_spec *spec = codec->spec;
  8295. alc262_auto_init_multi_out(codec);
  8296. alc262_auto_init_hp_out(codec);
  8297. alc262_auto_init_analog_input(codec);
  8298. if (spec->unsol_event)
  8299. alc_sku_automute(codec);
  8300. }
  8301. /*
  8302. * configuration and preset
  8303. */
  8304. static const char *alc262_models[ALC262_MODEL_LAST] = {
  8305. [ALC262_BASIC] = "basic",
  8306. [ALC262_HIPPO] = "hippo",
  8307. [ALC262_HIPPO_1] = "hippo_1",
  8308. [ALC262_FUJITSU] = "fujitsu",
  8309. [ALC262_HP_BPC] = "hp-bpc",
  8310. [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
  8311. [ALC262_HP_TC_T5735] = "hp-tc-t5735",
  8312. [ALC262_HP_RP5700] = "hp-rp5700",
  8313. [ALC262_BENQ_ED8] = "benq",
  8314. [ALC262_BENQ_T31] = "benq-t31",
  8315. [ALC262_SONY_ASSAMD] = "sony-assamd",
  8316. [ALC262_ULTRA] = "ultra",
  8317. [ALC262_AUTO] = "auto",
  8318. };
  8319. static struct snd_pci_quirk alc262_cfg_tbl[] = {
  8320. SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
  8321. SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
  8322. SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
  8323. SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
  8324. SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
  8325. SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
  8326. SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
  8327. SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
  8328. SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
  8329. SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8330. SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8331. SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8332. SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8333. SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8334. SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8335. SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
  8336. SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
  8337. SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
  8338. SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
  8339. SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
  8340. SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
  8341. ALC262_HP_TC_T5735),
  8342. SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
  8343. SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8344. SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
  8345. SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8346. SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
  8347. SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
  8348. SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
  8349. SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
  8350. SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
  8351. SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
  8352. SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
  8353. SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
  8354. {}
  8355. };
  8356. static struct alc_config_preset alc262_presets[] = {
  8357. [ALC262_BASIC] = {
  8358. .mixers = { alc262_base_mixer },
  8359. .init_verbs = { alc262_init_verbs },
  8360. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8361. .dac_nids = alc262_dac_nids,
  8362. .hp_nid = 0x03,
  8363. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8364. .channel_mode = alc262_modes,
  8365. .input_mux = &alc262_capture_source,
  8366. },
  8367. [ALC262_HIPPO] = {
  8368. .mixers = { alc262_base_mixer },
  8369. .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
  8370. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8371. .dac_nids = alc262_dac_nids,
  8372. .hp_nid = 0x03,
  8373. .dig_out_nid = ALC262_DIGOUT_NID,
  8374. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8375. .channel_mode = alc262_modes,
  8376. .input_mux = &alc262_capture_source,
  8377. .unsol_event = alc262_hippo_unsol_event,
  8378. .init_hook = alc262_hippo_automute,
  8379. },
  8380. [ALC262_HIPPO_1] = {
  8381. .mixers = { alc262_hippo1_mixer },
  8382. .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
  8383. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8384. .dac_nids = alc262_dac_nids,
  8385. .hp_nid = 0x02,
  8386. .dig_out_nid = ALC262_DIGOUT_NID,
  8387. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8388. .channel_mode = alc262_modes,
  8389. .input_mux = &alc262_capture_source,
  8390. .unsol_event = alc262_hippo1_unsol_event,
  8391. .init_hook = alc262_hippo1_automute,
  8392. },
  8393. [ALC262_FUJITSU] = {
  8394. .mixers = { alc262_fujitsu_mixer },
  8395. .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
  8396. alc262_fujitsu_unsol_verbs },
  8397. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8398. .dac_nids = alc262_dac_nids,
  8399. .hp_nid = 0x03,
  8400. .dig_out_nid = ALC262_DIGOUT_NID,
  8401. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8402. .channel_mode = alc262_modes,
  8403. .input_mux = &alc262_fujitsu_capture_source,
  8404. .unsol_event = alc262_fujitsu_unsol_event,
  8405. },
  8406. [ALC262_HP_BPC] = {
  8407. .mixers = { alc262_HP_BPC_mixer },
  8408. .init_verbs = { alc262_HP_BPC_init_verbs },
  8409. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8410. .dac_nids = alc262_dac_nids,
  8411. .hp_nid = 0x03,
  8412. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8413. .channel_mode = alc262_modes,
  8414. .input_mux = &alc262_HP_capture_source,
  8415. .unsol_event = alc262_hp_bpc_unsol_event,
  8416. .init_hook = alc262_hp_bpc_automute,
  8417. },
  8418. [ALC262_HP_BPC_D7000_WF] = {
  8419. .mixers = { alc262_HP_BPC_WildWest_mixer },
  8420. .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
  8421. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8422. .dac_nids = alc262_dac_nids,
  8423. .hp_nid = 0x03,
  8424. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8425. .channel_mode = alc262_modes,
  8426. .input_mux = &alc262_HP_D7000_capture_source,
  8427. .unsol_event = alc262_hp_wildwest_unsol_event,
  8428. .init_hook = alc262_hp_wildwest_automute,
  8429. },
  8430. [ALC262_HP_BPC_D7000_WL] = {
  8431. .mixers = { alc262_HP_BPC_WildWest_mixer,
  8432. alc262_HP_BPC_WildWest_option_mixer },
  8433. .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
  8434. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8435. .dac_nids = alc262_dac_nids,
  8436. .hp_nid = 0x03,
  8437. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8438. .channel_mode = alc262_modes,
  8439. .input_mux = &alc262_HP_D7000_capture_source,
  8440. .unsol_event = alc262_hp_wildwest_unsol_event,
  8441. .init_hook = alc262_hp_wildwest_automute,
  8442. },
  8443. [ALC262_HP_TC_T5735] = {
  8444. .mixers = { alc262_hp_t5735_mixer },
  8445. .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
  8446. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8447. .dac_nids = alc262_dac_nids,
  8448. .hp_nid = 0x03,
  8449. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8450. .channel_mode = alc262_modes,
  8451. .input_mux = &alc262_capture_source,
  8452. .unsol_event = alc262_hp_t5735_unsol_event,
  8453. .init_hook = alc262_hp_t5735_init_hook,
  8454. },
  8455. [ALC262_HP_RP5700] = {
  8456. .mixers = { alc262_hp_rp5700_mixer },
  8457. .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
  8458. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8459. .dac_nids = alc262_dac_nids,
  8460. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8461. .channel_mode = alc262_modes,
  8462. .input_mux = &alc262_hp_rp5700_capture_source,
  8463. },
  8464. [ALC262_BENQ_ED8] = {
  8465. .mixers = { alc262_base_mixer },
  8466. .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
  8467. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8468. .dac_nids = alc262_dac_nids,
  8469. .hp_nid = 0x03,
  8470. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8471. .channel_mode = alc262_modes,
  8472. .input_mux = &alc262_capture_source,
  8473. },
  8474. [ALC262_SONY_ASSAMD] = {
  8475. .mixers = { alc262_sony_mixer },
  8476. .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
  8477. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8478. .dac_nids = alc262_dac_nids,
  8479. .hp_nid = 0x02,
  8480. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8481. .channel_mode = alc262_modes,
  8482. .input_mux = &alc262_capture_source,
  8483. .unsol_event = alc262_hippo_unsol_event,
  8484. .init_hook = alc262_hippo_automute,
  8485. },
  8486. [ALC262_BENQ_T31] = {
  8487. .mixers = { alc262_benq_t31_mixer },
  8488. .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
  8489. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8490. .dac_nids = alc262_dac_nids,
  8491. .hp_nid = 0x03,
  8492. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8493. .channel_mode = alc262_modes,
  8494. .input_mux = &alc262_capture_source,
  8495. .unsol_event = alc262_hippo_unsol_event,
  8496. .init_hook = alc262_hippo_automute,
  8497. },
  8498. [ALC262_ULTRA] = {
  8499. .mixers = { alc262_ultra_mixer },
  8500. .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
  8501. .num_dacs = ARRAY_SIZE(alc262_dac_nids),
  8502. .dac_nids = alc262_dac_nids,
  8503. .hp_nid = 0x03,
  8504. .dig_out_nid = ALC262_DIGOUT_NID,
  8505. .num_channel_mode = ARRAY_SIZE(alc262_modes),
  8506. .channel_mode = alc262_modes,
  8507. .input_mux = &alc262_ultra_capture_source,
  8508. .unsol_event = alc262_ultra_unsol_event,
  8509. .init_hook = alc262_ultra_automute,
  8510. },
  8511. };
  8512. static int patch_alc262(struct hda_codec *codec)
  8513. {
  8514. struct alc_spec *spec;
  8515. int board_config;
  8516. int err;
  8517. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  8518. if (spec == NULL)
  8519. return -ENOMEM;
  8520. codec->spec = spec;
  8521. #if 0
  8522. /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
  8523. * under-run
  8524. */
  8525. {
  8526. int tmp;
  8527. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
  8528. tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
  8529. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
  8530. snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
  8531. }
  8532. #endif
  8533. board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
  8534. alc262_models,
  8535. alc262_cfg_tbl);
  8536. if (board_config < 0) {
  8537. printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
  8538. "trying auto-probe from BIOS...\n");
  8539. board_config = ALC262_AUTO;
  8540. }
  8541. if (board_config == ALC262_AUTO) {
  8542. /* automatic parse from the BIOS config */
  8543. err = alc262_parse_auto_config(codec);
  8544. if (err < 0) {
  8545. alc_free(codec);
  8546. return err;
  8547. } else if (!err) {
  8548. printk(KERN_INFO
  8549. "hda_codec: Cannot set up configuration "
  8550. "from BIOS. Using base mode...\n");
  8551. board_config = ALC262_BASIC;
  8552. }
  8553. }
  8554. if (board_config != ALC262_AUTO)
  8555. setup_preset(spec, &alc262_presets[board_config]);
  8556. spec->stream_name_analog = "ALC262 Analog";
  8557. spec->stream_analog_playback = &alc262_pcm_analog_playback;
  8558. spec->stream_analog_capture = &alc262_pcm_analog_capture;
  8559. spec->stream_name_digital = "ALC262 Digital";
  8560. spec->stream_digital_playback = &alc262_pcm_digital_playback;
  8561. spec->stream_digital_capture = &alc262_pcm_digital_capture;
  8562. if (!spec->adc_nids && spec->input_mux) {
  8563. /* check whether NID 0x07 is valid */
  8564. unsigned int wcap = get_wcaps(codec, 0x07);
  8565. /* get type */
  8566. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  8567. if (wcap != AC_WID_AUD_IN) {
  8568. spec->adc_nids = alc262_adc_nids_alt;
  8569. spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
  8570. spec->mixers[spec->num_mixers] =
  8571. alc262_capture_alt_mixer;
  8572. spec->num_mixers++;
  8573. } else {
  8574. spec->adc_nids = alc262_adc_nids;
  8575. spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
  8576. spec->mixers[spec->num_mixers] = alc262_capture_mixer;
  8577. spec->num_mixers++;
  8578. }
  8579. }
  8580. spec->vmaster_nid = 0x0c;
  8581. codec->patch_ops = alc_patch_ops;
  8582. if (board_config == ALC262_AUTO)
  8583. spec->init_hook = alc262_auto_init;
  8584. #ifdef CONFIG_SND_HDA_POWER_SAVE
  8585. if (!spec->loopback.amplist)
  8586. spec->loopback.amplist = alc262_loopbacks;
  8587. #endif
  8588. return 0;
  8589. }
  8590. /*
  8591. * ALC268 channel source setting (2 channel)
  8592. */
  8593. #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
  8594. #define alc268_modes alc260_modes
  8595. static hda_nid_t alc268_dac_nids[2] = {
  8596. /* front, hp */
  8597. 0x02, 0x03
  8598. };
  8599. static hda_nid_t alc268_adc_nids[2] = {
  8600. /* ADC0-1 */
  8601. 0x08, 0x07
  8602. };
  8603. static hda_nid_t alc268_adc_nids_alt[1] = {
  8604. /* ADC0 */
  8605. 0x08
  8606. };
  8607. static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
  8608. static struct snd_kcontrol_new alc268_base_mixer[] = {
  8609. /* output mixer control */
  8610. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  8611. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  8612. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  8613. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  8614. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8615. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  8616. HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
  8617. { }
  8618. };
  8619. static struct hda_verb alc268_eapd_verbs[] = {
  8620. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8621. {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
  8622. { }
  8623. };
  8624. /* Toshiba specific */
  8625. #define alc268_toshiba_automute alc262_hippo_automute
  8626. static struct hda_verb alc268_toshiba_verbs[] = {
  8627. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8628. { } /* end */
  8629. };
  8630. /* Acer specific */
  8631. /* bind volumes of both NID 0x02 and 0x03 */
  8632. static struct hda_bind_ctls alc268_acer_bind_master_vol = {
  8633. .ops = &snd_hda_bind_vol,
  8634. .values = {
  8635. HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
  8636. HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
  8637. 0
  8638. },
  8639. };
  8640. /* mute/unmute internal speaker according to the hp jack and mute state */
  8641. static void alc268_acer_automute(struct hda_codec *codec, int force)
  8642. {
  8643. struct alc_spec *spec = codec->spec;
  8644. unsigned int mute;
  8645. if (force || !spec->sense_updated) {
  8646. unsigned int present;
  8647. present = snd_hda_codec_read(codec, 0x14, 0,
  8648. AC_VERB_GET_PIN_SENSE, 0);
  8649. spec->jack_present = (present & 0x80000000) != 0;
  8650. spec->sense_updated = 1;
  8651. }
  8652. if (spec->jack_present)
  8653. mute = HDA_AMP_MUTE; /* mute internal speaker */
  8654. else /* unmute internal speaker if necessary */
  8655. mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
  8656. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  8657. HDA_AMP_MUTE, mute);
  8658. }
  8659. /* bind hp and internal speaker mute (with plug check) */
  8660. static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
  8661. struct snd_ctl_elem_value *ucontrol)
  8662. {
  8663. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  8664. long *valp = ucontrol->value.integer.value;
  8665. int change;
  8666. change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
  8667. HDA_AMP_MUTE,
  8668. valp[0] ? 0 : HDA_AMP_MUTE);
  8669. change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
  8670. HDA_AMP_MUTE,
  8671. valp[1] ? 0 : HDA_AMP_MUTE);
  8672. if (change)
  8673. alc268_acer_automute(codec, 0);
  8674. return change;
  8675. }
  8676. static struct snd_kcontrol_new alc268_acer_mixer[] = {
  8677. /* output mixer control */
  8678. HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
  8679. {
  8680. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8681. .name = "Master Playback Switch",
  8682. .info = snd_hda_mixer_amp_switch_info,
  8683. .get = snd_hda_mixer_amp_switch_get,
  8684. .put = alc268_acer_master_sw_put,
  8685. .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
  8686. },
  8687. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8688. HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
  8689. HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
  8690. { }
  8691. };
  8692. static struct hda_verb alc268_acer_verbs[] = {
  8693. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8694. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  8695. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8696. { }
  8697. };
  8698. /* unsolicited event for HP jack sensing */
  8699. static void alc268_toshiba_unsol_event(struct hda_codec *codec,
  8700. unsigned int res)
  8701. {
  8702. if ((res >> 26) != ALC880_HP_EVENT)
  8703. return;
  8704. alc268_toshiba_automute(codec);
  8705. }
  8706. static void alc268_acer_unsol_event(struct hda_codec *codec,
  8707. unsigned int res)
  8708. {
  8709. if ((res >> 26) != ALC880_HP_EVENT)
  8710. return;
  8711. alc268_acer_automute(codec, 1);
  8712. }
  8713. static void alc268_acer_init_hook(struct hda_codec *codec)
  8714. {
  8715. alc268_acer_automute(codec, 1);
  8716. }
  8717. static struct snd_kcontrol_new alc268_dell_mixer[] = {
  8718. /* output mixer control */
  8719. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  8720. HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  8721. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  8722. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  8723. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  8724. HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
  8725. { }
  8726. };
  8727. static struct hda_verb alc268_dell_verbs[] = {
  8728. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8729. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  8730. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
  8731. { }
  8732. };
  8733. /* mute/unmute internal speaker according to the hp jack and mute state */
  8734. static void alc268_dell_automute(struct hda_codec *codec)
  8735. {
  8736. unsigned int present;
  8737. unsigned int mute;
  8738. present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
  8739. if (present & 0x80000000)
  8740. mute = HDA_AMP_MUTE;
  8741. else
  8742. mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
  8743. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  8744. HDA_AMP_MUTE, mute);
  8745. }
  8746. static void alc268_dell_unsol_event(struct hda_codec *codec,
  8747. unsigned int res)
  8748. {
  8749. if ((res >> 26) != ALC880_HP_EVENT)
  8750. return;
  8751. alc268_dell_automute(codec);
  8752. }
  8753. #define alc268_dell_init_hook alc268_dell_automute
  8754. /*
  8755. * generic initialization of ADC, input mixers and output mixers
  8756. */
  8757. static struct hda_verb alc268_base_init_verbs[] = {
  8758. /* Unmute DAC0-1 and set vol = 0 */
  8759. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8760. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8761. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8762. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8763. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8764. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8765. /*
  8766. * Set up output mixers (0x0c - 0x0e)
  8767. */
  8768. /* set vol=0 to output mixers */
  8769. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8770. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8771. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8772. {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
  8773. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8774. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8775. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  8776. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
  8777. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
  8778. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8779. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8780. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8781. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8782. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8783. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8784. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8785. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8786. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8787. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8788. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8789. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8790. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
  8791. /* Unmute Selector 23h,24h and set the default input to mic-in */
  8792. {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
  8793. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8794. {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
  8795. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  8796. { }
  8797. };
  8798. /*
  8799. * generic initialization of ADC, input mixers and output mixers
  8800. */
  8801. static struct hda_verb alc268_volume_init_verbs[] = {
  8802. /* set output DAC */
  8803. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8804. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8805. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8806. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8807. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8808. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
  8809. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8810. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8811. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
  8812. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  8813. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8814. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  8815. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8816. {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  8817. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8818. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8819. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8820. {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  8821. /* set PCBEEP vol = 0 */
  8822. {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
  8823. { }
  8824. };
  8825. #define alc268_mux_enum_info alc_mux_enum_info
  8826. #define alc268_mux_enum_get alc_mux_enum_get
  8827. #define alc268_mux_enum_put alc_mux_enum_put
  8828. static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
  8829. HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8830. HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
  8831. {
  8832. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8833. /* The multiple "Capture Source" controls confuse alsamixer
  8834. * So call somewhat different..
  8835. */
  8836. /* .name = "Capture Source", */
  8837. .name = "Input Source",
  8838. .count = 1,
  8839. .info = alc268_mux_enum_info,
  8840. .get = alc268_mux_enum_get,
  8841. .put = alc268_mux_enum_put,
  8842. },
  8843. { } /* end */
  8844. };
  8845. static struct snd_kcontrol_new alc268_capture_mixer[] = {
  8846. HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8847. HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
  8848. HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
  8849. HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
  8850. {
  8851. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  8852. /* The multiple "Capture Source" controls confuse alsamixer
  8853. * So call somewhat different..
  8854. */
  8855. /* .name = "Capture Source", */
  8856. .name = "Input Source",
  8857. .count = 2,
  8858. .info = alc268_mux_enum_info,
  8859. .get = alc268_mux_enum_get,
  8860. .put = alc268_mux_enum_put,
  8861. },
  8862. { } /* end */
  8863. };
  8864. static struct hda_input_mux alc268_capture_source = {
  8865. .num_items = 4,
  8866. .items = {
  8867. { "Mic", 0x0 },
  8868. { "Front Mic", 0x1 },
  8869. { "Line", 0x2 },
  8870. { "CD", 0x3 },
  8871. },
  8872. };
  8873. #ifdef CONFIG_SND_DEBUG
  8874. static struct snd_kcontrol_new alc268_test_mixer[] = {
  8875. /* Volume widgets */
  8876. HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  8877. HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  8878. HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  8879. HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
  8880. HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
  8881. HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
  8882. HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
  8883. HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
  8884. HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
  8885. HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
  8886. HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
  8887. HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
  8888. HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
  8889. /* The below appears problematic on some hardwares */
  8890. /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
  8891. HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
  8892. HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
  8893. HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
  8894. HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
  8895. /* Modes for retasking pin widgets */
  8896. ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
  8897. ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
  8898. ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
  8899. ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
  8900. /* Controls for GPIO pins, assuming they are configured as outputs */
  8901. ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
  8902. ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
  8903. ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
  8904. ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
  8905. /* Switches to allow the digital SPDIF output pin to be enabled.
  8906. * The ALC268 does not have an SPDIF input.
  8907. */
  8908. ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
  8909. /* A switch allowing EAPD to be enabled. Some laptops seem to use
  8910. * this output to turn on an external amplifier.
  8911. */
  8912. ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
  8913. ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
  8914. { } /* end */
  8915. };
  8916. #endif
  8917. /* create input playback/capture controls for the given pin */
  8918. static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
  8919. const char *ctlname, int idx)
  8920. {
  8921. char name[32];
  8922. int err;
  8923. sprintf(name, "%s Playback Volume", ctlname);
  8924. if (nid == 0x14) {
  8925. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  8926. HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
  8927. HDA_OUTPUT));
  8928. if (err < 0)
  8929. return err;
  8930. } else if (nid == 0x15) {
  8931. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  8932. HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
  8933. HDA_OUTPUT));
  8934. if (err < 0)
  8935. return err;
  8936. } else
  8937. return -1;
  8938. sprintf(name, "%s Playback Switch", ctlname);
  8939. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  8940. HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
  8941. if (err < 0)
  8942. return err;
  8943. return 0;
  8944. }
  8945. /* add playback controls from the parsed DAC table */
  8946. static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
  8947. const struct auto_pin_cfg *cfg)
  8948. {
  8949. hda_nid_t nid;
  8950. int err;
  8951. spec->multiout.num_dacs = 2; /* only use one dac */
  8952. spec->multiout.dac_nids = spec->private_dac_nids;
  8953. spec->multiout.dac_nids[0] = 2;
  8954. spec->multiout.dac_nids[1] = 3;
  8955. nid = cfg->line_out_pins[0];
  8956. if (nid)
  8957. alc268_new_analog_output(spec, nid, "Front", 0);
  8958. nid = cfg->speaker_pins[0];
  8959. if (nid == 0x1d) {
  8960. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  8961. "Speaker Playback Volume",
  8962. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
  8963. if (err < 0)
  8964. return err;
  8965. }
  8966. nid = cfg->hp_pins[0];
  8967. if (nid)
  8968. alc268_new_analog_output(spec, nid, "Headphone", 0);
  8969. nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
  8970. if (nid == 0x16) {
  8971. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  8972. "Mono Playback Switch",
  8973. HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
  8974. if (err < 0)
  8975. return err;
  8976. }
  8977. return 0;
  8978. }
  8979. /* create playback/capture controls for input pins */
  8980. static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
  8981. const struct auto_pin_cfg *cfg)
  8982. {
  8983. struct hda_input_mux *imux = &spec->private_imux;
  8984. int i, idx1;
  8985. for (i = 0; i < AUTO_PIN_LAST; i++) {
  8986. switch(cfg->input_pins[i]) {
  8987. case 0x18:
  8988. idx1 = 0; /* Mic 1 */
  8989. break;
  8990. case 0x19:
  8991. idx1 = 1; /* Mic 2 */
  8992. break;
  8993. case 0x1a:
  8994. idx1 = 2; /* Line In */
  8995. break;
  8996. case 0x1c:
  8997. idx1 = 3; /* CD */
  8998. break;
  8999. default:
  9000. continue;
  9001. }
  9002. imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
  9003. imux->items[imux->num_items].index = idx1;
  9004. imux->num_items++;
  9005. }
  9006. return 0;
  9007. }
  9008. static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
  9009. {
  9010. struct alc_spec *spec = codec->spec;
  9011. hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
  9012. hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
  9013. hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
  9014. unsigned int dac_vol1, dac_vol2;
  9015. if (speaker_nid) {
  9016. snd_hda_codec_write(codec, speaker_nid, 0,
  9017. AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
  9018. snd_hda_codec_write(codec, 0x0f, 0,
  9019. AC_VERB_SET_AMP_GAIN_MUTE,
  9020. AMP_IN_UNMUTE(1));
  9021. snd_hda_codec_write(codec, 0x10, 0,
  9022. AC_VERB_SET_AMP_GAIN_MUTE,
  9023. AMP_IN_UNMUTE(1));
  9024. } else {
  9025. snd_hda_codec_write(codec, 0x0f, 0,
  9026. AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
  9027. snd_hda_codec_write(codec, 0x10, 0,
  9028. AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
  9029. }
  9030. dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
  9031. if (line_nid == 0x14)
  9032. dac_vol2 = AMP_OUT_ZERO;
  9033. else if (line_nid == 0x15)
  9034. dac_vol1 = AMP_OUT_ZERO;
  9035. if (hp_nid == 0x14)
  9036. dac_vol2 = AMP_OUT_ZERO;
  9037. else if (hp_nid == 0x15)
  9038. dac_vol1 = AMP_OUT_ZERO;
  9039. if (line_nid != 0x16 || hp_nid != 0x16 ||
  9040. spec->autocfg.line_out_pins[1] != 0x16 ||
  9041. spec->autocfg.line_out_pins[2] != 0x16)
  9042. dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
  9043. snd_hda_codec_write(codec, 0x02, 0,
  9044. AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
  9045. snd_hda_codec_write(codec, 0x03, 0,
  9046. AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
  9047. }
  9048. /* pcm configuration: identiacal with ALC880 */
  9049. #define alc268_pcm_analog_playback alc880_pcm_analog_playback
  9050. #define alc268_pcm_analog_capture alc880_pcm_analog_capture
  9051. #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
  9052. #define alc268_pcm_digital_playback alc880_pcm_digital_playback
  9053. /*
  9054. * BIOS auto configuration
  9055. */
  9056. static int alc268_parse_auto_config(struct hda_codec *codec)
  9057. {
  9058. struct alc_spec *spec = codec->spec;
  9059. int err;
  9060. static hda_nid_t alc268_ignore[] = { 0 };
  9061. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  9062. alc268_ignore);
  9063. if (err < 0)
  9064. return err;
  9065. if (!spec->autocfg.line_outs)
  9066. return 0; /* can't find valid BIOS pin config */
  9067. err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
  9068. if (err < 0)
  9069. return err;
  9070. err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
  9071. if (err < 0)
  9072. return err;
  9073. spec->multiout.max_channels = 2;
  9074. /* digital only support output */
  9075. if (spec->autocfg.dig_out_pin)
  9076. spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
  9077. if (spec->kctl_alloc)
  9078. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  9079. spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
  9080. spec->num_mux_defs = 1;
  9081. spec->input_mux = &spec->private_imux;
  9082. err = alc_auto_add_mic_boost(codec);
  9083. if (err < 0)
  9084. return err;
  9085. return 1;
  9086. }
  9087. #define alc268_auto_init_multi_out alc882_auto_init_multi_out
  9088. #define alc268_auto_init_hp_out alc882_auto_init_hp_out
  9089. #define alc268_auto_init_analog_input alc882_auto_init_analog_input
  9090. /* init callback for auto-configuration model -- overriding the default init */
  9091. static void alc268_auto_init(struct hda_codec *codec)
  9092. {
  9093. struct alc_spec *spec = codec->spec;
  9094. alc268_auto_init_multi_out(codec);
  9095. alc268_auto_init_hp_out(codec);
  9096. alc268_auto_init_mono_speaker_out(codec);
  9097. alc268_auto_init_analog_input(codec);
  9098. if (spec->unsol_event)
  9099. alc_sku_automute(codec);
  9100. }
  9101. /*
  9102. * configuration and preset
  9103. */
  9104. static const char *alc268_models[ALC268_MODEL_LAST] = {
  9105. [ALC268_3ST] = "3stack",
  9106. [ALC268_TOSHIBA] = "toshiba",
  9107. [ALC268_ACER] = "acer",
  9108. [ALC268_DELL] = "dell",
  9109. [ALC268_ZEPTO] = "zepto",
  9110. #ifdef CONFIG_SND_DEBUG
  9111. [ALC268_TEST] = "test",
  9112. #endif
  9113. [ALC268_AUTO] = "auto",
  9114. };
  9115. static struct snd_pci_quirk alc268_cfg_tbl[] = {
  9116. SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
  9117. SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
  9118. SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
  9119. SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
  9120. SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
  9121. SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
  9122. SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
  9123. SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
  9124. SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
  9125. SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
  9126. SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
  9127. {}
  9128. };
  9129. static struct alc_config_preset alc268_presets[] = {
  9130. [ALC268_3ST] = {
  9131. .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
  9132. .init_verbs = { alc268_base_init_verbs },
  9133. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9134. .dac_nids = alc268_dac_nids,
  9135. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  9136. .adc_nids = alc268_adc_nids_alt,
  9137. .capsrc_nids = alc268_capsrc_nids,
  9138. .hp_nid = 0x03,
  9139. .dig_out_nid = ALC268_DIGOUT_NID,
  9140. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9141. .channel_mode = alc268_modes,
  9142. .input_mux = &alc268_capture_source,
  9143. },
  9144. [ALC268_TOSHIBA] = {
  9145. .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
  9146. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  9147. alc268_toshiba_verbs },
  9148. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9149. .dac_nids = alc268_dac_nids,
  9150. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  9151. .adc_nids = alc268_adc_nids_alt,
  9152. .capsrc_nids = alc268_capsrc_nids,
  9153. .hp_nid = 0x03,
  9154. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9155. .channel_mode = alc268_modes,
  9156. .input_mux = &alc268_capture_source,
  9157. .unsol_event = alc268_toshiba_unsol_event,
  9158. .init_hook = alc268_toshiba_automute,
  9159. },
  9160. [ALC268_ACER] = {
  9161. .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
  9162. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  9163. alc268_acer_verbs },
  9164. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9165. .dac_nids = alc268_dac_nids,
  9166. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  9167. .adc_nids = alc268_adc_nids_alt,
  9168. .capsrc_nids = alc268_capsrc_nids,
  9169. .hp_nid = 0x02,
  9170. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9171. .channel_mode = alc268_modes,
  9172. .input_mux = &alc268_capture_source,
  9173. .unsol_event = alc268_acer_unsol_event,
  9174. .init_hook = alc268_acer_init_hook,
  9175. },
  9176. [ALC268_DELL] = {
  9177. .mixers = { alc268_dell_mixer },
  9178. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  9179. alc268_dell_verbs },
  9180. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9181. .dac_nids = alc268_dac_nids,
  9182. .hp_nid = 0x02,
  9183. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9184. .channel_mode = alc268_modes,
  9185. .unsol_event = alc268_dell_unsol_event,
  9186. .init_hook = alc268_dell_init_hook,
  9187. .input_mux = &alc268_capture_source,
  9188. },
  9189. [ALC268_ZEPTO] = {
  9190. .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
  9191. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  9192. alc268_toshiba_verbs },
  9193. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9194. .dac_nids = alc268_dac_nids,
  9195. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  9196. .adc_nids = alc268_adc_nids_alt,
  9197. .capsrc_nids = alc268_capsrc_nids,
  9198. .hp_nid = 0x03,
  9199. .dig_out_nid = ALC268_DIGOUT_NID,
  9200. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9201. .channel_mode = alc268_modes,
  9202. .input_mux = &alc268_capture_source,
  9203. .unsol_event = alc268_toshiba_unsol_event,
  9204. .init_hook = alc268_toshiba_automute
  9205. },
  9206. #ifdef CONFIG_SND_DEBUG
  9207. [ALC268_TEST] = {
  9208. .mixers = { alc268_test_mixer, alc268_capture_mixer },
  9209. .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
  9210. alc268_volume_init_verbs },
  9211. .num_dacs = ARRAY_SIZE(alc268_dac_nids),
  9212. .dac_nids = alc268_dac_nids,
  9213. .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
  9214. .adc_nids = alc268_adc_nids_alt,
  9215. .capsrc_nids = alc268_capsrc_nids,
  9216. .hp_nid = 0x03,
  9217. .dig_out_nid = ALC268_DIGOUT_NID,
  9218. .num_channel_mode = ARRAY_SIZE(alc268_modes),
  9219. .channel_mode = alc268_modes,
  9220. .input_mux = &alc268_capture_source,
  9221. },
  9222. #endif
  9223. };
  9224. static int patch_alc268(struct hda_codec *codec)
  9225. {
  9226. struct alc_spec *spec;
  9227. int board_config;
  9228. int err;
  9229. spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
  9230. if (spec == NULL)
  9231. return -ENOMEM;
  9232. codec->spec = spec;
  9233. board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
  9234. alc268_models,
  9235. alc268_cfg_tbl);
  9236. if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
  9237. printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
  9238. "trying auto-probe from BIOS...\n");
  9239. board_config = ALC268_AUTO;
  9240. }
  9241. if (board_config == ALC268_AUTO) {
  9242. /* automatic parse from the BIOS config */
  9243. err = alc268_parse_auto_config(codec);
  9244. if (err < 0) {
  9245. alc_free(codec);
  9246. return err;
  9247. } else if (!err) {
  9248. printk(KERN_INFO
  9249. "hda_codec: Cannot set up configuration "
  9250. "from BIOS. Using base mode...\n");
  9251. board_config = ALC268_3ST;
  9252. }
  9253. }
  9254. if (board_config != ALC268_AUTO)
  9255. setup_preset(spec, &alc268_presets[board_config]);
  9256. spec->stream_name_analog = "ALC268 Analog";
  9257. spec->stream_analog_playback = &alc268_pcm_analog_playback;
  9258. spec->stream_analog_capture = &alc268_pcm_analog_capture;
  9259. spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
  9260. spec->stream_name_digital = "ALC268 Digital";
  9261. spec->stream_digital_playback = &alc268_pcm_digital_playback;
  9262. if (!spec->adc_nids && spec->input_mux) {
  9263. /* check whether NID 0x07 is valid */
  9264. unsigned int wcap = get_wcaps(codec, 0x07);
  9265. /* get type */
  9266. wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  9267. if (wcap != AC_WID_AUD_IN) {
  9268. spec->adc_nids = alc268_adc_nids_alt;
  9269. spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
  9270. spec->mixers[spec->num_mixers] =
  9271. alc268_capture_alt_mixer;
  9272. spec->num_mixers++;
  9273. } else {
  9274. spec->adc_nids = alc268_adc_nids;
  9275. spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
  9276. spec->mixers[spec->num_mixers] =
  9277. alc268_capture_mixer;
  9278. spec->num_mixers++;
  9279. }
  9280. spec->capsrc_nids = alc268_capsrc_nids;
  9281. }
  9282. spec->vmaster_nid = 0x02;
  9283. codec->patch_ops = alc_patch_ops;
  9284. if (board_config == ALC268_AUTO)
  9285. spec->init_hook = alc268_auto_init;
  9286. return 0;
  9287. }
  9288. /*
  9289. * ALC269 channel source setting (2 channel)
  9290. */
  9291. #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
  9292. #define alc269_dac_nids alc260_dac_nids
  9293. static hda_nid_t alc269_adc_nids[1] = {
  9294. /* ADC1 */
  9295. 0x07,
  9296. };
  9297. #define alc269_modes alc260_modes
  9298. #define alc269_capture_source alc880_lg_lw_capture_source
  9299. static struct snd_kcontrol_new alc269_base_mixer[] = {
  9300. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  9301. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  9302. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  9303. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  9304. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  9305. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  9306. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  9307. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
  9308. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
  9309. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  9310. HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  9311. HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
  9312. { } /* end */
  9313. };
  9314. /* capture mixer elements */
  9315. static struct snd_kcontrol_new alc269_capture_mixer[] = {
  9316. HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
  9317. HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
  9318. {
  9319. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9320. /* The multiple "Capture Source" controls confuse alsamixer
  9321. * So call somewhat different..
  9322. */
  9323. /* .name = "Capture Source", */
  9324. .name = "Input Source",
  9325. .count = 1,
  9326. .info = alc_mux_enum_info,
  9327. .get = alc_mux_enum_get,
  9328. .put = alc_mux_enum_put,
  9329. },
  9330. { } /* end */
  9331. };
  9332. /*
  9333. * generic initialization of ADC, input mixers and output mixers
  9334. */
  9335. static struct hda_verb alc269_init_verbs[] = {
  9336. /*
  9337. * Unmute ADC0 and set the default input to mic-in
  9338. */
  9339. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9340. /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
  9341. * analog-loopback mixer widget
  9342. * Note: PASD motherboards uses the Line In 2 as the input for
  9343. * front panel mic (mic 2)
  9344. */
  9345. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  9346. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  9347. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  9348. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  9349. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  9350. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  9351. /*
  9352. * Set up output mixers (0x0c - 0x0e)
  9353. */
  9354. /* set vol=0 to output mixers */
  9355. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  9356. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  9357. /* set up input amps for analog loopback */
  9358. /* Amp Indices: DAC = 0, mixer = 1 */
  9359. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9360. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9361. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9362. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9363. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9364. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9365. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  9366. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  9367. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  9368. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  9369. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  9370. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  9371. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  9372. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9373. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9374. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9375. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9376. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9377. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9378. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  9379. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  9380. {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
  9381. /* FIXME: use matrix-type input source selection */
  9382. /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
  9383. /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
  9384. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9385. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  9386. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  9387. {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  9388. /* set EAPD */
  9389. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  9390. {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
  9391. { }
  9392. };
  9393. /* add playback controls from the parsed DAC table */
  9394. static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
  9395. const struct auto_pin_cfg *cfg)
  9396. {
  9397. hda_nid_t nid;
  9398. int err;
  9399. spec->multiout.num_dacs = 1; /* only use one dac */
  9400. spec->multiout.dac_nids = spec->private_dac_nids;
  9401. spec->multiout.dac_nids[0] = 2;
  9402. nid = cfg->line_out_pins[0];
  9403. if (nid) {
  9404. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  9405. "Front Playback Volume",
  9406. HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
  9407. if (err < 0)
  9408. return err;
  9409. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9410. "Front Playback Switch",
  9411. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  9412. if (err < 0)
  9413. return err;
  9414. }
  9415. nid = cfg->speaker_pins[0];
  9416. if (nid) {
  9417. if (!cfg->line_out_pins[0]) {
  9418. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  9419. "Speaker Playback Volume",
  9420. HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
  9421. HDA_OUTPUT));
  9422. if (err < 0)
  9423. return err;
  9424. }
  9425. if (nid == 0x16) {
  9426. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9427. "Speaker Playback Switch",
  9428. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  9429. HDA_OUTPUT));
  9430. if (err < 0)
  9431. return err;
  9432. } else {
  9433. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9434. "Speaker Playback Switch",
  9435. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  9436. HDA_OUTPUT));
  9437. if (err < 0)
  9438. return err;
  9439. }
  9440. }
  9441. nid = cfg->hp_pins[0];
  9442. if (nid) {
  9443. /* spec->multiout.hp_nid = 2; */
  9444. if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
  9445. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  9446. "Headphone Playback Volume",
  9447. HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
  9448. HDA_OUTPUT));
  9449. if (err < 0)
  9450. return err;
  9451. }
  9452. if (nid == 0x16) {
  9453. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9454. "Headphone Playback Switch",
  9455. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  9456. HDA_OUTPUT));
  9457. if (err < 0)
  9458. return err;
  9459. } else {
  9460. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  9461. "Headphone Playback Switch",
  9462. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  9463. HDA_OUTPUT));
  9464. if (err < 0)
  9465. return err;
  9466. }
  9467. }
  9468. return 0;
  9469. }
  9470. #define alc269_auto_create_analog_input_ctls \
  9471. alc880_auto_create_analog_input_ctls
  9472. #ifdef CONFIG_SND_HDA_POWER_SAVE
  9473. #define alc269_loopbacks alc880_loopbacks
  9474. #endif
  9475. /* pcm configuration: identiacal with ALC880 */
  9476. #define alc269_pcm_analog_playback alc880_pcm_analog_playback
  9477. #define alc269_pcm_analog_capture alc880_pcm_analog_capture
  9478. #define alc269_pcm_digital_playback alc880_pcm_digital_playback
  9479. #define alc269_pcm_digital_capture alc880_pcm_digital_capture
  9480. /*
  9481. * BIOS auto configuration
  9482. */
  9483. static int alc269_parse_auto_config(struct hda_codec *codec)
  9484. {
  9485. struct alc_spec *spec = codec->spec;
  9486. int err;
  9487. static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
  9488. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  9489. alc269_ignore);
  9490. if (err < 0)
  9491. return err;
  9492. err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
  9493. if (err < 0)
  9494. return err;
  9495. err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
  9496. if (err < 0)
  9497. return err;
  9498. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  9499. if (spec->autocfg.dig_out_pin)
  9500. spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
  9501. if (spec->kctl_alloc)
  9502. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  9503. spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
  9504. spec->num_mux_defs = 1;
  9505. spec->input_mux = &spec->private_imux;
  9506. err = alc_auto_add_mic_boost(codec);
  9507. if (err < 0)
  9508. return err;
  9509. return 1;
  9510. }
  9511. #define alc269_auto_init_multi_out alc882_auto_init_multi_out
  9512. #define alc269_auto_init_hp_out alc882_auto_init_hp_out
  9513. #define alc269_auto_init_analog_input alc882_auto_init_analog_input
  9514. /* init callback for auto-configuration model -- overriding the default init */
  9515. static void alc269_auto_init(struct hda_codec *codec)
  9516. {
  9517. struct alc_spec *spec = codec->spec;
  9518. alc269_auto_init_multi_out(codec);
  9519. alc269_auto_init_hp_out(codec);
  9520. alc269_auto_init_analog_input(codec);
  9521. if (spec->unsol_event)
  9522. alc_sku_automute(codec);
  9523. }
  9524. /*
  9525. * configuration and preset
  9526. */
  9527. static const char *alc269_models[ALC269_MODEL_LAST] = {
  9528. [ALC269_BASIC] = "basic",
  9529. };
  9530. static struct snd_pci_quirk alc269_cfg_tbl[] = {
  9531. {}
  9532. };
  9533. static struct alc_config_preset alc269_presets[] = {
  9534. [ALC269_BASIC] = {
  9535. .mixers = { alc269_base_mixer },
  9536. .init_verbs = { alc269_init_verbs },
  9537. .num_dacs = ARRAY_SIZE(alc269_dac_nids),
  9538. .dac_nids = alc269_dac_nids,
  9539. .hp_nid = 0x03,
  9540. .num_channel_mode = ARRAY_SIZE(alc269_modes),
  9541. .channel_mode = alc269_modes,
  9542. .input_mux = &alc269_capture_source,
  9543. },
  9544. };
  9545. static int patch_alc269(struct hda_codec *codec)
  9546. {
  9547. struct alc_spec *spec;
  9548. int board_config;
  9549. int err;
  9550. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  9551. if (spec == NULL)
  9552. return -ENOMEM;
  9553. codec->spec = spec;
  9554. board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
  9555. alc269_models,
  9556. alc269_cfg_tbl);
  9557. if (board_config < 0) {
  9558. printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
  9559. "trying auto-probe from BIOS...\n");
  9560. board_config = ALC269_AUTO;
  9561. }
  9562. if (board_config == ALC269_AUTO) {
  9563. /* automatic parse from the BIOS config */
  9564. err = alc269_parse_auto_config(codec);
  9565. if (err < 0) {
  9566. alc_free(codec);
  9567. return err;
  9568. } else if (!err) {
  9569. printk(KERN_INFO
  9570. "hda_codec: Cannot set up configuration "
  9571. "from BIOS. Using base mode...\n");
  9572. board_config = ALC269_BASIC;
  9573. }
  9574. }
  9575. if (board_config != ALC269_AUTO)
  9576. setup_preset(spec, &alc269_presets[board_config]);
  9577. spec->stream_name_analog = "ALC269 Analog";
  9578. spec->stream_analog_playback = &alc269_pcm_analog_playback;
  9579. spec->stream_analog_capture = &alc269_pcm_analog_capture;
  9580. spec->stream_name_digital = "ALC269 Digital";
  9581. spec->stream_digital_playback = &alc269_pcm_digital_playback;
  9582. spec->stream_digital_capture = &alc269_pcm_digital_capture;
  9583. spec->adc_nids = alc269_adc_nids;
  9584. spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
  9585. spec->mixers[spec->num_mixers] = alc269_capture_mixer;
  9586. spec->num_mixers++;
  9587. codec->patch_ops = alc_patch_ops;
  9588. if (board_config == ALC269_AUTO)
  9589. spec->init_hook = alc269_auto_init;
  9590. #ifdef CONFIG_SND_HDA_POWER_SAVE
  9591. if (!spec->loopback.amplist)
  9592. spec->loopback.amplist = alc269_loopbacks;
  9593. #endif
  9594. return 0;
  9595. }
  9596. /*
  9597. * ALC861 channel source setting (2/6 channel selection for 3-stack)
  9598. */
  9599. /*
  9600. * set the path ways for 2 channel output
  9601. * need to set the codec line out and mic 1 pin widgets to inputs
  9602. */
  9603. static struct hda_verb alc861_threestack_ch2_init[] = {
  9604. /* set pin widget 1Ah (line in) for input */
  9605. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9606. /* set pin widget 18h (mic1/2) for input, for mic also enable
  9607. * the vref
  9608. */
  9609. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9610. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
  9611. #if 0
  9612. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9613. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
  9614. #endif
  9615. { } /* end */
  9616. };
  9617. /*
  9618. * 6ch mode
  9619. * need to set the codec line out and mic 1 pin widgets to outputs
  9620. */
  9621. static struct hda_verb alc861_threestack_ch6_init[] = {
  9622. /* set pin widget 1Ah (line in) for output (Back Surround)*/
  9623. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9624. /* set pin widget 18h (mic1) for output (CLFE)*/
  9625. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9626. { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9627. { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9628. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
  9629. #if 0
  9630. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9631. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
  9632. #endif
  9633. { } /* end */
  9634. };
  9635. static struct hda_channel_mode alc861_threestack_modes[2] = {
  9636. { 2, alc861_threestack_ch2_init },
  9637. { 6, alc861_threestack_ch6_init },
  9638. };
  9639. /* Set mic1 as input and unmute the mixer */
  9640. static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
  9641. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9642. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9643. { } /* end */
  9644. };
  9645. /* Set mic1 as output and mute mixer */
  9646. static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
  9647. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9648. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9649. { } /* end */
  9650. };
  9651. static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
  9652. { 2, alc861_uniwill_m31_ch2_init },
  9653. { 4, alc861_uniwill_m31_ch4_init },
  9654. };
  9655. /* Set mic1 and line-in as input and unmute the mixer */
  9656. static struct hda_verb alc861_asus_ch2_init[] = {
  9657. /* set pin widget 1Ah (line in) for input */
  9658. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9659. /* set pin widget 18h (mic1/2) for input, for mic also enable
  9660. * the vref
  9661. */
  9662. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9663. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
  9664. #if 0
  9665. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
  9666. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
  9667. #endif
  9668. { } /* end */
  9669. };
  9670. /* Set mic1 nad line-in as output and mute mixer */
  9671. static struct hda_verb alc861_asus_ch6_init[] = {
  9672. /* set pin widget 1Ah (line in) for output (Back Surround)*/
  9673. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9674. /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
  9675. /* set pin widget 18h (mic1) for output (CLFE)*/
  9676. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9677. /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
  9678. { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9679. { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9680. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
  9681. #if 0
  9682. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
  9683. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
  9684. #endif
  9685. { } /* end */
  9686. };
  9687. static struct hda_channel_mode alc861_asus_modes[2] = {
  9688. { 2, alc861_asus_ch2_init },
  9689. { 6, alc861_asus_ch6_init },
  9690. };
  9691. /* patch-ALC861 */
  9692. static struct snd_kcontrol_new alc861_base_mixer[] = {
  9693. /* output mixer control */
  9694. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9695. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9696. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9697. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9698. HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
  9699. /*Input mixer control */
  9700. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9701. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9702. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9703. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9704. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9705. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9706. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9707. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9708. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9709. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9710. /* Capture mixer control */
  9711. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9712. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9713. {
  9714. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9715. .name = "Capture Source",
  9716. .count = 1,
  9717. .info = alc_mux_enum_info,
  9718. .get = alc_mux_enum_get,
  9719. .put = alc_mux_enum_put,
  9720. },
  9721. { } /* end */
  9722. };
  9723. static struct snd_kcontrol_new alc861_3ST_mixer[] = {
  9724. /* output mixer control */
  9725. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9726. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9727. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9728. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9729. /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
  9730. /* Input mixer control */
  9731. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9732. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9733. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9734. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9735. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9736. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9737. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9738. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9739. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9740. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9741. /* Capture mixer control */
  9742. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9743. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9744. {
  9745. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9746. .name = "Capture Source",
  9747. .count = 1,
  9748. .info = alc_mux_enum_info,
  9749. .get = alc_mux_enum_get,
  9750. .put = alc_mux_enum_put,
  9751. },
  9752. {
  9753. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9754. .name = "Channel Mode",
  9755. .info = alc_ch_mode_info,
  9756. .get = alc_ch_mode_get,
  9757. .put = alc_ch_mode_put,
  9758. .private_value = ARRAY_SIZE(alc861_threestack_modes),
  9759. },
  9760. { } /* end */
  9761. };
  9762. static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
  9763. /* output mixer control */
  9764. HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9765. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9766. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9767. /*Capture mixer control */
  9768. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9769. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9770. {
  9771. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9772. .name = "Capture Source",
  9773. .count = 1,
  9774. .info = alc_mux_enum_info,
  9775. .get = alc_mux_enum_get,
  9776. .put = alc_mux_enum_put,
  9777. },
  9778. { } /* end */
  9779. };
  9780. static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
  9781. /* output mixer control */
  9782. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9783. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9784. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9785. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9786. /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
  9787. /* Input mixer control */
  9788. /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9789. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
  9790. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9791. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9792. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9793. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9794. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9795. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9796. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9797. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
  9798. /* Capture mixer control */
  9799. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9800. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9801. {
  9802. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9803. .name = "Capture Source",
  9804. .count = 1,
  9805. .info = alc_mux_enum_info,
  9806. .get = alc_mux_enum_get,
  9807. .put = alc_mux_enum_put,
  9808. },
  9809. {
  9810. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9811. .name = "Channel Mode",
  9812. .info = alc_ch_mode_info,
  9813. .get = alc_ch_mode_get,
  9814. .put = alc_ch_mode_put,
  9815. .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
  9816. },
  9817. { } /* end */
  9818. };
  9819. static struct snd_kcontrol_new alc861_asus_mixer[] = {
  9820. /* output mixer control */
  9821. HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  9822. HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
  9823. HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
  9824. HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
  9825. HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
  9826. /* Input mixer control */
  9827. HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
  9828. HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
  9829. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9830. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9831. HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
  9832. HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
  9833. HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
  9834. HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
  9835. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
  9836. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
  9837. /* Capture mixer control */
  9838. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  9839. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  9840. {
  9841. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9842. .name = "Capture Source",
  9843. .count = 1,
  9844. .info = alc_mux_enum_info,
  9845. .get = alc_mux_enum_get,
  9846. .put = alc_mux_enum_put,
  9847. },
  9848. {
  9849. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  9850. .name = "Channel Mode",
  9851. .info = alc_ch_mode_info,
  9852. .get = alc_ch_mode_get,
  9853. .put = alc_ch_mode_put,
  9854. .private_value = ARRAY_SIZE(alc861_asus_modes),
  9855. },
  9856. { }
  9857. };
  9858. /* additional mixer */
  9859. static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
  9860. HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
  9861. HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
  9862. HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
  9863. HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
  9864. { }
  9865. };
  9866. /*
  9867. * generic initialization of ADC, input mixers and output mixers
  9868. */
  9869. static struct hda_verb alc861_base_init_verbs[] = {
  9870. /*
  9871. * Unmute ADC0 and set the default input to mic-in
  9872. */
  9873. /* port-A for surround (rear panel) */
  9874. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9875. { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9876. /* port-B for mic-in (rear panel) with vref */
  9877. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9878. /* port-C for line-in (rear panel) */
  9879. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9880. /* port-D for Front */
  9881. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9882. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9883. /* port-E for HP out (front panel) */
  9884. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  9885. /* route front PCM to HP */
  9886. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9887. /* port-F for mic-in (front panel) with vref */
  9888. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9889. /* port-G for CLFE (rear panel) */
  9890. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9891. { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9892. /* port-H for side (rear panel) */
  9893. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9894. { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9895. /* CD-in */
  9896. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9897. /* route front mic to ADC1*/
  9898. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9899. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9900. /* Unmute DAC0~3 & spdif out*/
  9901. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9902. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9903. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9904. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9905. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9906. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9907. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9908. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9909. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9910. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9911. /* Unmute Stereo Mixer 15 */
  9912. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9913. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9914. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9915. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9916. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9917. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9918. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9919. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9920. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9921. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9922. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9923. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9924. /* hp used DAC 3 (Front) */
  9925. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9926. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9927. { }
  9928. };
  9929. static struct hda_verb alc861_threestack_init_verbs[] = {
  9930. /*
  9931. * Unmute ADC0 and set the default input to mic-in
  9932. */
  9933. /* port-A for surround (rear panel) */
  9934. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9935. /* port-B for mic-in (rear panel) with vref */
  9936. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9937. /* port-C for line-in (rear panel) */
  9938. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9939. /* port-D for Front */
  9940. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9941. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9942. /* port-E for HP out (front panel) */
  9943. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
  9944. /* route front PCM to HP */
  9945. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9946. /* port-F for mic-in (front panel) with vref */
  9947. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9948. /* port-G for CLFE (rear panel) */
  9949. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9950. /* port-H for side (rear panel) */
  9951. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9952. /* CD-in */
  9953. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9954. /* route front mic to ADC1*/
  9955. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  9956. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9957. /* Unmute DAC0~3 & spdif out*/
  9958. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9959. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9960. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9961. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9962. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  9963. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  9964. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9965. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9966. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9967. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9968. /* Unmute Stereo Mixer 15 */
  9969. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9970. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9971. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9972. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  9973. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9974. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9975. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9976. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9977. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9978. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9979. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  9980. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  9981. /* hp used DAC 3 (Front) */
  9982. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  9983. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  9984. { }
  9985. };
  9986. static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
  9987. /*
  9988. * Unmute ADC0 and set the default input to mic-in
  9989. */
  9990. /* port-A for surround (rear panel) */
  9991. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  9992. /* port-B for mic-in (rear panel) with vref */
  9993. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  9994. /* port-C for line-in (rear panel) */
  9995. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  9996. /* port-D for Front */
  9997. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  9998. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  9999. /* port-E for HP out (front panel) */
  10000. /* this has to be set to VREF80 */
  10001. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  10002. /* route front PCM to HP */
  10003. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  10004. /* port-F for mic-in (front panel) with vref */
  10005. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  10006. /* port-G for CLFE (rear panel) */
  10007. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  10008. /* port-H for side (rear panel) */
  10009. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  10010. /* CD-in */
  10011. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  10012. /* route front mic to ADC1*/
  10013. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  10014. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10015. /* Unmute DAC0~3 & spdif out*/
  10016. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10017. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10018. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10019. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10020. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10021. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  10022. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10023. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10024. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10025. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10026. /* Unmute Stereo Mixer 15 */
  10027. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10028. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10029. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10030. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  10031. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10032. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10033. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10034. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10035. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10036. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10037. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10038. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10039. /* hp used DAC 3 (Front) */
  10040. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  10041. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10042. { }
  10043. };
  10044. static struct hda_verb alc861_asus_init_verbs[] = {
  10045. /*
  10046. * Unmute ADC0 and set the default input to mic-in
  10047. */
  10048. /* port-A for surround (rear panel)
  10049. * according to codec#0 this is the HP jack
  10050. */
  10051. { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
  10052. /* route front PCM to HP */
  10053. { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
  10054. /* port-B for mic-in (rear panel) with vref */
  10055. { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  10056. /* port-C for line-in (rear panel) */
  10057. { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  10058. /* port-D for Front */
  10059. { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  10060. { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
  10061. /* port-E for HP out (front panel) */
  10062. /* this has to be set to VREF80 */
  10063. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  10064. /* route front PCM to HP */
  10065. { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
  10066. /* port-F for mic-in (front panel) with vref */
  10067. { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
  10068. /* port-G for CLFE (rear panel) */
  10069. { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  10070. /* port-H for side (rear panel) */
  10071. { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
  10072. /* CD-in */
  10073. { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
  10074. /* route front mic to ADC1*/
  10075. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
  10076. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10077. /* Unmute DAC0~3 & spdif out*/
  10078. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10079. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10080. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10081. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10082. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10083. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  10084. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10085. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10086. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10087. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10088. /* Unmute Stereo Mixer 15 */
  10089. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10090. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10091. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10092. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
  10093. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10094. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10095. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10096. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10097. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10098. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10099. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10100. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10101. /* hp used DAC 3 (Front) */
  10102. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  10103. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10104. { }
  10105. };
  10106. /* additional init verbs for ASUS laptops */
  10107. static struct hda_verb alc861_asus_laptop_init_verbs[] = {
  10108. { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
  10109. { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
  10110. { }
  10111. };
  10112. /*
  10113. * generic initialization of ADC, input mixers and output mixers
  10114. */
  10115. static struct hda_verb alc861_auto_init_verbs[] = {
  10116. /*
  10117. * Unmute ADC0 and set the default input to mic-in
  10118. */
  10119. /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
  10120. {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10121. /* Unmute DAC0~3 & spdif out*/
  10122. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10123. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10124. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10125. {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10126. {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10127. /* Unmute Mixer 14 (mic) 1c (Line in)*/
  10128. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10129. {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10130. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10131. {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10132. /* Unmute Stereo Mixer 15 */
  10133. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10134. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10135. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10136. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
  10137. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10138. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10139. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10140. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10141. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10142. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10143. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10144. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10145. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10146. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10147. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10148. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  10149. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10150. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10151. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10152. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
  10153. {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
  10154. { }
  10155. };
  10156. static struct hda_verb alc861_toshiba_init_verbs[] = {
  10157. {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  10158. { }
  10159. };
  10160. /* toggle speaker-output according to the hp-jack state */
  10161. static void alc861_toshiba_automute(struct hda_codec *codec)
  10162. {
  10163. unsigned int present;
  10164. present = snd_hda_codec_read(codec, 0x0f, 0,
  10165. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10166. snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
  10167. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  10168. snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
  10169. HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
  10170. }
  10171. static void alc861_toshiba_unsol_event(struct hda_codec *codec,
  10172. unsigned int res)
  10173. {
  10174. if ((res >> 26) == ALC880_HP_EVENT)
  10175. alc861_toshiba_automute(codec);
  10176. }
  10177. /* pcm configuration: identiacal with ALC880 */
  10178. #define alc861_pcm_analog_playback alc880_pcm_analog_playback
  10179. #define alc861_pcm_analog_capture alc880_pcm_analog_capture
  10180. #define alc861_pcm_digital_playback alc880_pcm_digital_playback
  10181. #define alc861_pcm_digital_capture alc880_pcm_digital_capture
  10182. #define ALC861_DIGOUT_NID 0x07
  10183. static struct hda_channel_mode alc861_8ch_modes[1] = {
  10184. { 8, NULL }
  10185. };
  10186. static hda_nid_t alc861_dac_nids[4] = {
  10187. /* front, surround, clfe, side */
  10188. 0x03, 0x06, 0x05, 0x04
  10189. };
  10190. static hda_nid_t alc660_dac_nids[3] = {
  10191. /* front, clfe, surround */
  10192. 0x03, 0x05, 0x06
  10193. };
  10194. static hda_nid_t alc861_adc_nids[1] = {
  10195. /* ADC0-2 */
  10196. 0x08,
  10197. };
  10198. static struct hda_input_mux alc861_capture_source = {
  10199. .num_items = 5,
  10200. .items = {
  10201. { "Mic", 0x0 },
  10202. { "Front Mic", 0x3 },
  10203. { "Line", 0x1 },
  10204. { "CD", 0x4 },
  10205. { "Mixer", 0x5 },
  10206. },
  10207. };
  10208. /* fill in the dac_nids table from the parsed pin configuration */
  10209. static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
  10210. const struct auto_pin_cfg *cfg)
  10211. {
  10212. int i;
  10213. hda_nid_t nid;
  10214. spec->multiout.dac_nids = spec->private_dac_nids;
  10215. for (i = 0; i < cfg->line_outs; i++) {
  10216. nid = cfg->line_out_pins[i];
  10217. if (nid) {
  10218. if (i >= ARRAY_SIZE(alc861_dac_nids))
  10219. continue;
  10220. spec->multiout.dac_nids[i] = alc861_dac_nids[i];
  10221. }
  10222. }
  10223. spec->multiout.num_dacs = cfg->line_outs;
  10224. return 0;
  10225. }
  10226. /* add playback controls from the parsed DAC table */
  10227. static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
  10228. const struct auto_pin_cfg *cfg)
  10229. {
  10230. char name[32];
  10231. static const char *chname[4] = {
  10232. "Front", "Surround", NULL /*CLFE*/, "Side"
  10233. };
  10234. hda_nid_t nid;
  10235. int i, idx, err;
  10236. for (i = 0; i < cfg->line_outs; i++) {
  10237. nid = spec->multiout.dac_nids[i];
  10238. if (!nid)
  10239. continue;
  10240. if (nid == 0x05) {
  10241. /* Center/LFE */
  10242. err = add_control(spec, ALC_CTL_BIND_MUTE,
  10243. "Center Playback Switch",
  10244. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  10245. HDA_OUTPUT));
  10246. if (err < 0)
  10247. return err;
  10248. err = add_control(spec, ALC_CTL_BIND_MUTE,
  10249. "LFE Playback Switch",
  10250. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  10251. HDA_OUTPUT));
  10252. if (err < 0)
  10253. return err;
  10254. } else {
  10255. for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
  10256. idx++)
  10257. if (nid == alc861_dac_nids[idx])
  10258. break;
  10259. sprintf(name, "%s Playback Switch", chname[idx]);
  10260. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  10261. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  10262. HDA_OUTPUT));
  10263. if (err < 0)
  10264. return err;
  10265. }
  10266. }
  10267. return 0;
  10268. }
  10269. static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
  10270. {
  10271. int err;
  10272. hda_nid_t nid;
  10273. if (!pin)
  10274. return 0;
  10275. if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
  10276. nid = 0x03;
  10277. err = add_control(spec, ALC_CTL_WIDGET_MUTE,
  10278. "Headphone Playback Switch",
  10279. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  10280. if (err < 0)
  10281. return err;
  10282. spec->multiout.hp_nid = nid;
  10283. }
  10284. return 0;
  10285. }
  10286. /* create playback/capture controls for input pins */
  10287. static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
  10288. const struct auto_pin_cfg *cfg)
  10289. {
  10290. struct hda_input_mux *imux = &spec->private_imux;
  10291. int i, err, idx, idx1;
  10292. for (i = 0; i < AUTO_PIN_LAST; i++) {
  10293. switch (cfg->input_pins[i]) {
  10294. case 0x0c:
  10295. idx1 = 1;
  10296. idx = 2; /* Line In */
  10297. break;
  10298. case 0x0f:
  10299. idx1 = 2;
  10300. idx = 2; /* Line In */
  10301. break;
  10302. case 0x0d:
  10303. idx1 = 0;
  10304. idx = 1; /* Mic In */
  10305. break;
  10306. case 0x10:
  10307. idx1 = 3;
  10308. idx = 1; /* Mic In */
  10309. break;
  10310. case 0x11:
  10311. idx1 = 4;
  10312. idx = 0; /* CD */
  10313. break;
  10314. default:
  10315. continue;
  10316. }
  10317. err = new_analog_input(spec, cfg->input_pins[i],
  10318. auto_pin_cfg_labels[i], idx, 0x15);
  10319. if (err < 0)
  10320. return err;
  10321. imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
  10322. imux->items[imux->num_items].index = idx1;
  10323. imux->num_items++;
  10324. }
  10325. return 0;
  10326. }
  10327. static struct snd_kcontrol_new alc861_capture_mixer[] = {
  10328. HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
  10329. HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
  10330. {
  10331. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  10332. /* The multiple "Capture Source" controls confuse alsamixer
  10333. * So call somewhat different..
  10334. */
  10335. /* .name = "Capture Source", */
  10336. .name = "Input Source",
  10337. .count = 1,
  10338. .info = alc_mux_enum_info,
  10339. .get = alc_mux_enum_get,
  10340. .put = alc_mux_enum_put,
  10341. },
  10342. { } /* end */
  10343. };
  10344. static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
  10345. hda_nid_t nid,
  10346. int pin_type, int dac_idx)
  10347. {
  10348. alc_set_pin_output(codec, nid, pin_type);
  10349. }
  10350. static void alc861_auto_init_multi_out(struct hda_codec *codec)
  10351. {
  10352. struct alc_spec *spec = codec->spec;
  10353. int i;
  10354. alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
  10355. for (i = 0; i < spec->autocfg.line_outs; i++) {
  10356. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  10357. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  10358. if (nid)
  10359. alc861_auto_set_output_and_unmute(codec, nid, pin_type,
  10360. spec->multiout.dac_nids[i]);
  10361. }
  10362. }
  10363. static void alc861_auto_init_hp_out(struct hda_codec *codec)
  10364. {
  10365. struct alc_spec *spec = codec->spec;
  10366. hda_nid_t pin;
  10367. pin = spec->autocfg.hp_pins[0];
  10368. if (pin) /* connect to front */
  10369. alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
  10370. spec->multiout.dac_nids[0]);
  10371. pin = spec->autocfg.speaker_pins[0];
  10372. if (pin)
  10373. alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  10374. }
  10375. static void alc861_auto_init_analog_input(struct hda_codec *codec)
  10376. {
  10377. struct alc_spec *spec = codec->spec;
  10378. int i;
  10379. for (i = 0; i < AUTO_PIN_LAST; i++) {
  10380. hda_nid_t nid = spec->autocfg.input_pins[i];
  10381. if (nid >= 0x0c && nid <= 0x11) {
  10382. snd_hda_codec_write(codec, nid, 0,
  10383. AC_VERB_SET_PIN_WIDGET_CONTROL,
  10384. i <= AUTO_PIN_FRONT_MIC ?
  10385. PIN_VREF80 : PIN_IN);
  10386. }
  10387. }
  10388. }
  10389. /* parse the BIOS configuration and set up the alc_spec */
  10390. /* return 1 if successful, 0 if the proper config is not found,
  10391. * or a negative error code
  10392. */
  10393. static int alc861_parse_auto_config(struct hda_codec *codec)
  10394. {
  10395. struct alc_spec *spec = codec->spec;
  10396. int err;
  10397. static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
  10398. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  10399. alc861_ignore);
  10400. if (err < 0)
  10401. return err;
  10402. if (!spec->autocfg.line_outs)
  10403. return 0; /* can't find valid BIOS pin config */
  10404. err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
  10405. if (err < 0)
  10406. return err;
  10407. err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
  10408. if (err < 0)
  10409. return err;
  10410. err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
  10411. if (err < 0)
  10412. return err;
  10413. err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
  10414. if (err < 0)
  10415. return err;
  10416. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  10417. if (spec->autocfg.dig_out_pin)
  10418. spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
  10419. if (spec->kctl_alloc)
  10420. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  10421. spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
  10422. spec->num_mux_defs = 1;
  10423. spec->input_mux = &spec->private_imux;
  10424. spec->adc_nids = alc861_adc_nids;
  10425. spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
  10426. spec->mixers[spec->num_mixers] = alc861_capture_mixer;
  10427. spec->num_mixers++;
  10428. return 1;
  10429. }
  10430. /* additional initialization for auto-configuration model */
  10431. static void alc861_auto_init(struct hda_codec *codec)
  10432. {
  10433. struct alc_spec *spec = codec->spec;
  10434. alc861_auto_init_multi_out(codec);
  10435. alc861_auto_init_hp_out(codec);
  10436. alc861_auto_init_analog_input(codec);
  10437. if (spec->unsol_event)
  10438. alc_sku_automute(codec);
  10439. }
  10440. #ifdef CONFIG_SND_HDA_POWER_SAVE
  10441. static struct hda_amp_list alc861_loopbacks[] = {
  10442. { 0x15, HDA_INPUT, 0 },
  10443. { 0x15, HDA_INPUT, 1 },
  10444. { 0x15, HDA_INPUT, 2 },
  10445. { 0x15, HDA_INPUT, 3 },
  10446. { } /* end */
  10447. };
  10448. #endif
  10449. /*
  10450. * configuration and preset
  10451. */
  10452. static const char *alc861_models[ALC861_MODEL_LAST] = {
  10453. [ALC861_3ST] = "3stack",
  10454. [ALC660_3ST] = "3stack-660",
  10455. [ALC861_3ST_DIG] = "3stack-dig",
  10456. [ALC861_6ST_DIG] = "6stack-dig",
  10457. [ALC861_UNIWILL_M31] = "uniwill-m31",
  10458. [ALC861_TOSHIBA] = "toshiba",
  10459. [ALC861_ASUS] = "asus",
  10460. [ALC861_ASUS_LAPTOP] = "asus-laptop",
  10461. [ALC861_AUTO] = "auto",
  10462. };
  10463. static struct snd_pci_quirk alc861_cfg_tbl[] = {
  10464. SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
  10465. SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
  10466. SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
  10467. SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
  10468. SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
  10469. SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
  10470. SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
  10471. /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
  10472. * Any other models that need this preset?
  10473. */
  10474. /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
  10475. SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
  10476. SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
  10477. SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
  10478. SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
  10479. SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
  10480. /* FIXME: the below seems conflict */
  10481. /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
  10482. SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
  10483. SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
  10484. {}
  10485. };
  10486. static struct alc_config_preset alc861_presets[] = {
  10487. [ALC861_3ST] = {
  10488. .mixers = { alc861_3ST_mixer },
  10489. .init_verbs = { alc861_threestack_init_verbs },
  10490. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10491. .dac_nids = alc861_dac_nids,
  10492. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10493. .channel_mode = alc861_threestack_modes,
  10494. .need_dac_fix = 1,
  10495. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10496. .adc_nids = alc861_adc_nids,
  10497. .input_mux = &alc861_capture_source,
  10498. },
  10499. [ALC861_3ST_DIG] = {
  10500. .mixers = { alc861_base_mixer },
  10501. .init_verbs = { alc861_threestack_init_verbs },
  10502. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10503. .dac_nids = alc861_dac_nids,
  10504. .dig_out_nid = ALC861_DIGOUT_NID,
  10505. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10506. .channel_mode = alc861_threestack_modes,
  10507. .need_dac_fix = 1,
  10508. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10509. .adc_nids = alc861_adc_nids,
  10510. .input_mux = &alc861_capture_source,
  10511. },
  10512. [ALC861_6ST_DIG] = {
  10513. .mixers = { alc861_base_mixer },
  10514. .init_verbs = { alc861_base_init_verbs },
  10515. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10516. .dac_nids = alc861_dac_nids,
  10517. .dig_out_nid = ALC861_DIGOUT_NID,
  10518. .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
  10519. .channel_mode = alc861_8ch_modes,
  10520. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10521. .adc_nids = alc861_adc_nids,
  10522. .input_mux = &alc861_capture_source,
  10523. },
  10524. [ALC660_3ST] = {
  10525. .mixers = { alc861_3ST_mixer },
  10526. .init_verbs = { alc861_threestack_init_verbs },
  10527. .num_dacs = ARRAY_SIZE(alc660_dac_nids),
  10528. .dac_nids = alc660_dac_nids,
  10529. .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
  10530. .channel_mode = alc861_threestack_modes,
  10531. .need_dac_fix = 1,
  10532. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10533. .adc_nids = alc861_adc_nids,
  10534. .input_mux = &alc861_capture_source,
  10535. },
  10536. [ALC861_UNIWILL_M31] = {
  10537. .mixers = { alc861_uniwill_m31_mixer },
  10538. .init_verbs = { alc861_uniwill_m31_init_verbs },
  10539. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10540. .dac_nids = alc861_dac_nids,
  10541. .dig_out_nid = ALC861_DIGOUT_NID,
  10542. .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
  10543. .channel_mode = alc861_uniwill_m31_modes,
  10544. .need_dac_fix = 1,
  10545. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10546. .adc_nids = alc861_adc_nids,
  10547. .input_mux = &alc861_capture_source,
  10548. },
  10549. [ALC861_TOSHIBA] = {
  10550. .mixers = { alc861_toshiba_mixer },
  10551. .init_verbs = { alc861_base_init_verbs,
  10552. alc861_toshiba_init_verbs },
  10553. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10554. .dac_nids = alc861_dac_nids,
  10555. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  10556. .channel_mode = alc883_3ST_2ch_modes,
  10557. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10558. .adc_nids = alc861_adc_nids,
  10559. .input_mux = &alc861_capture_source,
  10560. .unsol_event = alc861_toshiba_unsol_event,
  10561. .init_hook = alc861_toshiba_automute,
  10562. },
  10563. [ALC861_ASUS] = {
  10564. .mixers = { alc861_asus_mixer },
  10565. .init_verbs = { alc861_asus_init_verbs },
  10566. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10567. .dac_nids = alc861_dac_nids,
  10568. .dig_out_nid = ALC861_DIGOUT_NID,
  10569. .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
  10570. .channel_mode = alc861_asus_modes,
  10571. .need_dac_fix = 1,
  10572. .hp_nid = 0x06,
  10573. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10574. .adc_nids = alc861_adc_nids,
  10575. .input_mux = &alc861_capture_source,
  10576. },
  10577. [ALC861_ASUS_LAPTOP] = {
  10578. .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
  10579. .init_verbs = { alc861_asus_init_verbs,
  10580. alc861_asus_laptop_init_verbs },
  10581. .num_dacs = ARRAY_SIZE(alc861_dac_nids),
  10582. .dac_nids = alc861_dac_nids,
  10583. .dig_out_nid = ALC861_DIGOUT_NID,
  10584. .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
  10585. .channel_mode = alc883_3ST_2ch_modes,
  10586. .need_dac_fix = 1,
  10587. .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
  10588. .adc_nids = alc861_adc_nids,
  10589. .input_mux = &alc861_capture_source,
  10590. },
  10591. };
  10592. static int patch_alc861(struct hda_codec *codec)
  10593. {
  10594. struct alc_spec *spec;
  10595. int board_config;
  10596. int err;
  10597. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  10598. if (spec == NULL)
  10599. return -ENOMEM;
  10600. codec->spec = spec;
  10601. board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
  10602. alc861_models,
  10603. alc861_cfg_tbl);
  10604. if (board_config < 0) {
  10605. printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
  10606. "trying auto-probe from BIOS...\n");
  10607. board_config = ALC861_AUTO;
  10608. }
  10609. if (board_config == ALC861_AUTO) {
  10610. /* automatic parse from the BIOS config */
  10611. err = alc861_parse_auto_config(codec);
  10612. if (err < 0) {
  10613. alc_free(codec);
  10614. return err;
  10615. } else if (!err) {
  10616. printk(KERN_INFO
  10617. "hda_codec: Cannot set up configuration "
  10618. "from BIOS. Using base mode...\n");
  10619. board_config = ALC861_3ST_DIG;
  10620. }
  10621. }
  10622. if (board_config != ALC861_AUTO)
  10623. setup_preset(spec, &alc861_presets[board_config]);
  10624. spec->stream_name_analog = "ALC861 Analog";
  10625. spec->stream_analog_playback = &alc861_pcm_analog_playback;
  10626. spec->stream_analog_capture = &alc861_pcm_analog_capture;
  10627. spec->stream_name_digital = "ALC861 Digital";
  10628. spec->stream_digital_playback = &alc861_pcm_digital_playback;
  10629. spec->stream_digital_capture = &alc861_pcm_digital_capture;
  10630. spec->vmaster_nid = 0x03;
  10631. codec->patch_ops = alc_patch_ops;
  10632. if (board_config == ALC861_AUTO)
  10633. spec->init_hook = alc861_auto_init;
  10634. #ifdef CONFIG_SND_HDA_POWER_SAVE
  10635. if (!spec->loopback.amplist)
  10636. spec->loopback.amplist = alc861_loopbacks;
  10637. #endif
  10638. return 0;
  10639. }
  10640. /*
  10641. * ALC861-VD support
  10642. *
  10643. * Based on ALC882
  10644. *
  10645. * In addition, an independent DAC
  10646. */
  10647. #define ALC861VD_DIGOUT_NID 0x06
  10648. static hda_nid_t alc861vd_dac_nids[4] = {
  10649. /* front, surr, clfe, side surr */
  10650. 0x02, 0x03, 0x04, 0x05
  10651. };
  10652. /* dac_nids for ALC660vd are in a different order - according to
  10653. * Realtek's driver.
  10654. * This should probably tesult in a different mixer for 6stack models
  10655. * of ALC660vd codecs, but for now there is only 3stack mixer
  10656. * - and it is the same as in 861vd.
  10657. * adc_nids in ALC660vd are (is) the same as in 861vd
  10658. */
  10659. static hda_nid_t alc660vd_dac_nids[3] = {
  10660. /* front, rear, clfe, rear_surr */
  10661. 0x02, 0x04, 0x03
  10662. };
  10663. static hda_nid_t alc861vd_adc_nids[1] = {
  10664. /* ADC0 */
  10665. 0x09,
  10666. };
  10667. static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
  10668. /* input MUX */
  10669. /* FIXME: should be a matrix-type input source selection */
  10670. static struct hda_input_mux alc861vd_capture_source = {
  10671. .num_items = 4,
  10672. .items = {
  10673. { "Mic", 0x0 },
  10674. { "Front Mic", 0x1 },
  10675. { "Line", 0x2 },
  10676. { "CD", 0x4 },
  10677. },
  10678. };
  10679. static struct hda_input_mux alc861vd_dallas_capture_source = {
  10680. .num_items = 3,
  10681. .items = {
  10682. { "Front Mic", 0x0 },
  10683. { "ATAPI Mic", 0x1 },
  10684. { "Line In", 0x5 },
  10685. },
  10686. };
  10687. static struct hda_input_mux alc861vd_hp_capture_source = {
  10688. .num_items = 2,
  10689. .items = {
  10690. { "Front Mic", 0x0 },
  10691. { "ATAPI Mic", 0x1 },
  10692. },
  10693. };
  10694. #define alc861vd_mux_enum_info alc_mux_enum_info
  10695. #define alc861vd_mux_enum_get alc_mux_enum_get
  10696. /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
  10697. #define alc861vd_mux_enum_put alc882_mux_enum_put
  10698. /*
  10699. * 2ch mode
  10700. */
  10701. static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
  10702. { 2, NULL }
  10703. };
  10704. /*
  10705. * 6ch mode
  10706. */
  10707. static struct hda_verb alc861vd_6stack_ch6_init[] = {
  10708. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  10709. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10710. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10711. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10712. { } /* end */
  10713. };
  10714. /*
  10715. * 8ch mode
  10716. */
  10717. static struct hda_verb alc861vd_6stack_ch8_init[] = {
  10718. { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10719. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10720. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10721. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  10722. { } /* end */
  10723. };
  10724. static struct hda_channel_mode alc861vd_6stack_modes[2] = {
  10725. { 6, alc861vd_6stack_ch6_init },
  10726. { 8, alc861vd_6stack_ch8_init },
  10727. };
  10728. static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
  10729. {
  10730. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  10731. .name = "Channel Mode",
  10732. .info = alc_ch_mode_info,
  10733. .get = alc_ch_mode_get,
  10734. .put = alc_ch_mode_put,
  10735. },
  10736. { } /* end */
  10737. };
  10738. static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
  10739. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  10740. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  10741. {
  10742. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  10743. /* The multiple "Capture Source" controls confuse alsamixer
  10744. * So call somewhat different..
  10745. */
  10746. /* .name = "Capture Source", */
  10747. .name = "Input Source",
  10748. .count = 1,
  10749. .info = alc861vd_mux_enum_info,
  10750. .get = alc861vd_mux_enum_get,
  10751. .put = alc861vd_mux_enum_put,
  10752. },
  10753. { } /* end */
  10754. };
  10755. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  10756. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  10757. */
  10758. static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
  10759. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10760. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10761. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10762. HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
  10763. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
  10764. HDA_OUTPUT),
  10765. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
  10766. HDA_OUTPUT),
  10767. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
  10768. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
  10769. HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
  10770. HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
  10771. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10772. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10773. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10774. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10775. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10776. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10777. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10778. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  10779. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  10780. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10781. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10782. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10783. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10784. { } /* end */
  10785. };
  10786. static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
  10787. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10788. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10789. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10790. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10791. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10792. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10793. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10794. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10795. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10796. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  10797. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  10798. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10799. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10800. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10801. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10802. { } /* end */
  10803. };
  10804. static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
  10805. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10806. /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
  10807. HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  10808. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  10809. HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
  10810. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10811. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10812. HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
  10813. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10814. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10815. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  10816. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  10817. { } /* end */
  10818. };
  10819. /* Pin assignment: Front=0x14, HP = 0x15,
  10820. * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
  10821. */
  10822. static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
  10823. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10824. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10825. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10826. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  10827. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10828. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10829. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10830. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10831. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
  10832. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
  10833. { } /* end */
  10834. };
  10835. /* Pin assignment: Speaker=0x14, Line-out = 0x15,
  10836. * Front Mic=0x18, ATAPI Mic = 0x19,
  10837. */
  10838. static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
  10839. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  10840. HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
  10841. HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  10842. HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
  10843. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  10844. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  10845. HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  10846. HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  10847. { } /* end */
  10848. };
  10849. /*
  10850. * generic initialization of ADC, input mixers and output mixers
  10851. */
  10852. static struct hda_verb alc861vd_volume_init_verbs[] = {
  10853. /*
  10854. * Unmute ADC0 and set the default input to mic-in
  10855. */
  10856. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  10857. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10858. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
  10859. * the analog-loopback mixer widget
  10860. */
  10861. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  10862. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10863. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10864. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  10865. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  10866. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  10867. /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
  10868. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10869. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10870. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  10871. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  10872. /*
  10873. * Set up output mixers (0x02 - 0x05)
  10874. */
  10875. /* set vol=0 to output mixers */
  10876. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10877. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10878. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10879. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  10880. /* set up input amps for analog loopback */
  10881. /* Amp Indices: DAC = 0, mixer = 1 */
  10882. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10883. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10884. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10885. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10886. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10887. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10888. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  10889. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  10890. { }
  10891. };
  10892. /*
  10893. * 3-stack pin configuration:
  10894. * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
  10895. */
  10896. static struct hda_verb alc861vd_3stack_init_verbs[] = {
  10897. /*
  10898. * Set pin mode and muting
  10899. */
  10900. /* set front pin widgets 0x14 for output */
  10901. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10902. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10903. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  10904. /* Mic (rear) pin: input vref at 80% */
  10905. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10906. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10907. /* Front Mic pin: input vref at 80% */
  10908. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10909. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10910. /* Line In pin: input */
  10911. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10912. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10913. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  10914. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  10915. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10916. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  10917. /* CD pin widget for input */
  10918. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10919. { }
  10920. };
  10921. /*
  10922. * 6-stack pin configuration:
  10923. */
  10924. static struct hda_verb alc861vd_6stack_init_verbs[] = {
  10925. /*
  10926. * Set pin mode and muting
  10927. */
  10928. /* set front pin widgets 0x14 for output */
  10929. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10930. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10931. {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
  10932. /* Rear Pin: output 1 (0x0d) */
  10933. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10934. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10935. {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
  10936. /* CLFE Pin: output 2 (0x0e) */
  10937. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10938. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10939. {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
  10940. /* Side Pin: output 3 (0x0f) */
  10941. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  10942. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10943. {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
  10944. /* Mic (rear) pin: input vref at 80% */
  10945. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10946. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10947. /* Front Mic pin: input vref at 80% */
  10948. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  10949. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10950. /* Line In pin: input */
  10951. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10952. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  10953. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  10954. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  10955. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  10956. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  10957. /* CD pin widget for input */
  10958. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  10959. { }
  10960. };
  10961. static struct hda_verb alc861vd_eapd_verbs[] = {
  10962. {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
  10963. { }
  10964. };
  10965. static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
  10966. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  10967. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  10968. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
  10969. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  10970. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  10971. {}
  10972. };
  10973. /* toggle speaker-output according to the hp-jack state */
  10974. static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
  10975. {
  10976. unsigned int present;
  10977. unsigned char bits;
  10978. present = snd_hda_codec_read(codec, 0x1b, 0,
  10979. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10980. bits = present ? HDA_AMP_MUTE : 0;
  10981. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  10982. HDA_AMP_MUTE, bits);
  10983. }
  10984. static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
  10985. {
  10986. unsigned int present;
  10987. unsigned char bits;
  10988. present = snd_hda_codec_read(codec, 0x18, 0,
  10989. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  10990. bits = present ? HDA_AMP_MUTE : 0;
  10991. snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
  10992. HDA_AMP_MUTE, bits);
  10993. }
  10994. static void alc861vd_lenovo_automute(struct hda_codec *codec)
  10995. {
  10996. alc861vd_lenovo_hp_automute(codec);
  10997. alc861vd_lenovo_mic_automute(codec);
  10998. }
  10999. static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
  11000. unsigned int res)
  11001. {
  11002. switch (res >> 26) {
  11003. case ALC880_HP_EVENT:
  11004. alc861vd_lenovo_hp_automute(codec);
  11005. break;
  11006. case ALC880_MIC_EVENT:
  11007. alc861vd_lenovo_mic_automute(codec);
  11008. break;
  11009. }
  11010. }
  11011. static struct hda_verb alc861vd_dallas_verbs[] = {
  11012. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11013. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11014. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11015. {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11016. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11017. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11018. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11019. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11020. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11021. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11022. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11023. {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11024. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11025. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11026. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11027. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11028. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11029. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11030. {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11031. {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11032. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  11033. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11034. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
  11035. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11036. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11037. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11038. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11039. {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11040. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11041. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  11042. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  11043. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  11044. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11045. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  11046. {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  11047. { } /* end */
  11048. };
  11049. /* toggle speaker-output according to the hp-jack state */
  11050. static void alc861vd_dallas_automute(struct hda_codec *codec)
  11051. {
  11052. unsigned int present;
  11053. present = snd_hda_codec_read(codec, 0x15, 0,
  11054. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11055. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  11056. HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  11057. }
  11058. static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
  11059. {
  11060. if ((res >> 26) == ALC880_HP_EVENT)
  11061. alc861vd_dallas_automute(codec);
  11062. }
  11063. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11064. #define alc861vd_loopbacks alc880_loopbacks
  11065. #endif
  11066. /* pcm configuration: identiacal with ALC880 */
  11067. #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
  11068. #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
  11069. #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
  11070. #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
  11071. /*
  11072. * configuration and preset
  11073. */
  11074. static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
  11075. [ALC660VD_3ST] = "3stack-660",
  11076. [ALC660VD_3ST_DIG] = "3stack-660-digout",
  11077. [ALC861VD_3ST] = "3stack",
  11078. [ALC861VD_3ST_DIG] = "3stack-digout",
  11079. [ALC861VD_6ST_DIG] = "6stack-digout",
  11080. [ALC861VD_LENOVO] = "lenovo",
  11081. [ALC861VD_DALLAS] = "dallas",
  11082. [ALC861VD_HP] = "hp",
  11083. [ALC861VD_AUTO] = "auto",
  11084. };
  11085. static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
  11086. SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
  11087. SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
  11088. SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
  11089. SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
  11090. SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
  11091. SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
  11092. SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
  11093. /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
  11094. SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
  11095. SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
  11096. SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
  11097. SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
  11098. SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
  11099. SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
  11100. {}
  11101. };
  11102. static struct alc_config_preset alc861vd_presets[] = {
  11103. [ALC660VD_3ST] = {
  11104. .mixers = { alc861vd_3st_mixer },
  11105. .init_verbs = { alc861vd_volume_init_verbs,
  11106. alc861vd_3stack_init_verbs },
  11107. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  11108. .dac_nids = alc660vd_dac_nids,
  11109. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11110. .channel_mode = alc861vd_3stack_2ch_modes,
  11111. .input_mux = &alc861vd_capture_source,
  11112. },
  11113. [ALC660VD_3ST_DIG] = {
  11114. .mixers = { alc861vd_3st_mixer },
  11115. .init_verbs = { alc861vd_volume_init_verbs,
  11116. alc861vd_3stack_init_verbs },
  11117. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  11118. .dac_nids = alc660vd_dac_nids,
  11119. .dig_out_nid = ALC861VD_DIGOUT_NID,
  11120. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11121. .channel_mode = alc861vd_3stack_2ch_modes,
  11122. .input_mux = &alc861vd_capture_source,
  11123. },
  11124. [ALC861VD_3ST] = {
  11125. .mixers = { alc861vd_3st_mixer },
  11126. .init_verbs = { alc861vd_volume_init_verbs,
  11127. alc861vd_3stack_init_verbs },
  11128. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  11129. .dac_nids = alc861vd_dac_nids,
  11130. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11131. .channel_mode = alc861vd_3stack_2ch_modes,
  11132. .input_mux = &alc861vd_capture_source,
  11133. },
  11134. [ALC861VD_3ST_DIG] = {
  11135. .mixers = { alc861vd_3st_mixer },
  11136. .init_verbs = { alc861vd_volume_init_verbs,
  11137. alc861vd_3stack_init_verbs },
  11138. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  11139. .dac_nids = alc861vd_dac_nids,
  11140. .dig_out_nid = ALC861VD_DIGOUT_NID,
  11141. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11142. .channel_mode = alc861vd_3stack_2ch_modes,
  11143. .input_mux = &alc861vd_capture_source,
  11144. },
  11145. [ALC861VD_6ST_DIG] = {
  11146. .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
  11147. .init_verbs = { alc861vd_volume_init_verbs,
  11148. alc861vd_6stack_init_verbs },
  11149. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  11150. .dac_nids = alc861vd_dac_nids,
  11151. .dig_out_nid = ALC861VD_DIGOUT_NID,
  11152. .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
  11153. .channel_mode = alc861vd_6stack_modes,
  11154. .input_mux = &alc861vd_capture_source,
  11155. },
  11156. [ALC861VD_LENOVO] = {
  11157. .mixers = { alc861vd_lenovo_mixer },
  11158. .init_verbs = { alc861vd_volume_init_verbs,
  11159. alc861vd_3stack_init_verbs,
  11160. alc861vd_eapd_verbs,
  11161. alc861vd_lenovo_unsol_verbs },
  11162. .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
  11163. .dac_nids = alc660vd_dac_nids,
  11164. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11165. .channel_mode = alc861vd_3stack_2ch_modes,
  11166. .input_mux = &alc861vd_capture_source,
  11167. .unsol_event = alc861vd_lenovo_unsol_event,
  11168. .init_hook = alc861vd_lenovo_automute,
  11169. },
  11170. [ALC861VD_DALLAS] = {
  11171. .mixers = { alc861vd_dallas_mixer },
  11172. .init_verbs = { alc861vd_dallas_verbs },
  11173. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  11174. .dac_nids = alc861vd_dac_nids,
  11175. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11176. .channel_mode = alc861vd_3stack_2ch_modes,
  11177. .input_mux = &alc861vd_dallas_capture_source,
  11178. .unsol_event = alc861vd_dallas_unsol_event,
  11179. .init_hook = alc861vd_dallas_automute,
  11180. },
  11181. [ALC861VD_HP] = {
  11182. .mixers = { alc861vd_hp_mixer },
  11183. .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
  11184. .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
  11185. .dac_nids = alc861vd_dac_nids,
  11186. .dig_out_nid = ALC861VD_DIGOUT_NID,
  11187. .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
  11188. .channel_mode = alc861vd_3stack_2ch_modes,
  11189. .input_mux = &alc861vd_hp_capture_source,
  11190. .unsol_event = alc861vd_dallas_unsol_event,
  11191. .init_hook = alc861vd_dallas_automute,
  11192. },
  11193. };
  11194. /*
  11195. * BIOS auto configuration
  11196. */
  11197. static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
  11198. hda_nid_t nid, int pin_type, int dac_idx)
  11199. {
  11200. alc_set_pin_output(codec, nid, pin_type);
  11201. }
  11202. static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
  11203. {
  11204. struct alc_spec *spec = codec->spec;
  11205. int i;
  11206. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  11207. for (i = 0; i <= HDA_SIDE; i++) {
  11208. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  11209. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  11210. if (nid)
  11211. alc861vd_auto_set_output_and_unmute(codec, nid,
  11212. pin_type, i);
  11213. }
  11214. }
  11215. static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
  11216. {
  11217. struct alc_spec *spec = codec->spec;
  11218. hda_nid_t pin;
  11219. pin = spec->autocfg.hp_pins[0];
  11220. if (pin) /* connect to front and use dac 0 */
  11221. alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  11222. pin = spec->autocfg.speaker_pins[0];
  11223. if (pin)
  11224. alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  11225. }
  11226. #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
  11227. #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
  11228. static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
  11229. {
  11230. struct alc_spec *spec = codec->spec;
  11231. int i;
  11232. for (i = 0; i < AUTO_PIN_LAST; i++) {
  11233. hda_nid_t nid = spec->autocfg.input_pins[i];
  11234. if (alc861vd_is_input_pin(nid)) {
  11235. snd_hda_codec_write(codec, nid, 0,
  11236. AC_VERB_SET_PIN_WIDGET_CONTROL,
  11237. i <= AUTO_PIN_FRONT_MIC ?
  11238. PIN_VREF80 : PIN_IN);
  11239. if (nid != ALC861VD_PIN_CD_NID)
  11240. snd_hda_codec_write(codec, nid, 0,
  11241. AC_VERB_SET_AMP_GAIN_MUTE,
  11242. AMP_OUT_MUTE);
  11243. }
  11244. }
  11245. }
  11246. #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
  11247. #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
  11248. /* add playback controls from the parsed DAC table */
  11249. /* Based on ALC880 version. But ALC861VD has separate,
  11250. * different NIDs for mute/unmute switch and volume control */
  11251. static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
  11252. const struct auto_pin_cfg *cfg)
  11253. {
  11254. char name[32];
  11255. static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
  11256. hda_nid_t nid_v, nid_s;
  11257. int i, err;
  11258. for (i = 0; i < cfg->line_outs; i++) {
  11259. if (!spec->multiout.dac_nids[i])
  11260. continue;
  11261. nid_v = alc861vd_idx_to_mixer_vol(
  11262. alc880_dac_to_idx(
  11263. spec->multiout.dac_nids[i]));
  11264. nid_s = alc861vd_idx_to_mixer_switch(
  11265. alc880_dac_to_idx(
  11266. spec->multiout.dac_nids[i]));
  11267. if (i == 2) {
  11268. /* Center/LFE */
  11269. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  11270. "Center Playback Volume",
  11271. HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
  11272. HDA_OUTPUT));
  11273. if (err < 0)
  11274. return err;
  11275. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  11276. "LFE Playback Volume",
  11277. HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
  11278. HDA_OUTPUT));
  11279. if (err < 0)
  11280. return err;
  11281. err = add_control(spec, ALC_CTL_BIND_MUTE,
  11282. "Center Playback Switch",
  11283. HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
  11284. HDA_INPUT));
  11285. if (err < 0)
  11286. return err;
  11287. err = add_control(spec, ALC_CTL_BIND_MUTE,
  11288. "LFE Playback Switch",
  11289. HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
  11290. HDA_INPUT));
  11291. if (err < 0)
  11292. return err;
  11293. } else {
  11294. sprintf(name, "%s Playback Volume", chname[i]);
  11295. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  11296. HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
  11297. HDA_OUTPUT));
  11298. if (err < 0)
  11299. return err;
  11300. sprintf(name, "%s Playback Switch", chname[i]);
  11301. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  11302. HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
  11303. HDA_INPUT));
  11304. if (err < 0)
  11305. return err;
  11306. }
  11307. }
  11308. return 0;
  11309. }
  11310. /* add playback controls for speaker and HP outputs */
  11311. /* Based on ALC880 version. But ALC861VD has separate,
  11312. * different NIDs for mute/unmute switch and volume control */
  11313. static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
  11314. hda_nid_t pin, const char *pfx)
  11315. {
  11316. hda_nid_t nid_v, nid_s;
  11317. int err;
  11318. char name[32];
  11319. if (!pin)
  11320. return 0;
  11321. if (alc880_is_fixed_pin(pin)) {
  11322. nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  11323. /* specify the DAC as the extra output */
  11324. if (!spec->multiout.hp_nid)
  11325. spec->multiout.hp_nid = nid_v;
  11326. else
  11327. spec->multiout.extra_out_nid[0] = nid_v;
  11328. /* control HP volume/switch on the output mixer amp */
  11329. nid_v = alc861vd_idx_to_mixer_vol(
  11330. alc880_fixed_pin_idx(pin));
  11331. nid_s = alc861vd_idx_to_mixer_switch(
  11332. alc880_fixed_pin_idx(pin));
  11333. sprintf(name, "%s Playback Volume", pfx);
  11334. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  11335. HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
  11336. if (err < 0)
  11337. return err;
  11338. sprintf(name, "%s Playback Switch", pfx);
  11339. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  11340. HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
  11341. if (err < 0)
  11342. return err;
  11343. } else if (alc880_is_multi_pin(pin)) {
  11344. /* set manual connection */
  11345. /* we have only a switch on HP-out PIN */
  11346. sprintf(name, "%s Playback Switch", pfx);
  11347. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  11348. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  11349. if (err < 0)
  11350. return err;
  11351. }
  11352. return 0;
  11353. }
  11354. /* parse the BIOS configuration and set up the alc_spec
  11355. * return 1 if successful, 0 if the proper config is not found,
  11356. * or a negative error code
  11357. * Based on ALC880 version - had to change it to override
  11358. * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
  11359. static int alc861vd_parse_auto_config(struct hda_codec *codec)
  11360. {
  11361. struct alc_spec *spec = codec->spec;
  11362. int err;
  11363. static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
  11364. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  11365. alc861vd_ignore);
  11366. if (err < 0)
  11367. return err;
  11368. if (!spec->autocfg.line_outs)
  11369. return 0; /* can't find valid BIOS pin config */
  11370. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  11371. if (err < 0)
  11372. return err;
  11373. err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
  11374. if (err < 0)
  11375. return err;
  11376. err = alc861vd_auto_create_extra_out(spec,
  11377. spec->autocfg.speaker_pins[0],
  11378. "Speaker");
  11379. if (err < 0)
  11380. return err;
  11381. err = alc861vd_auto_create_extra_out(spec,
  11382. spec->autocfg.hp_pins[0],
  11383. "Headphone");
  11384. if (err < 0)
  11385. return err;
  11386. err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
  11387. if (err < 0)
  11388. return err;
  11389. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  11390. if (spec->autocfg.dig_out_pin)
  11391. spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
  11392. if (spec->kctl_alloc)
  11393. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  11394. spec->init_verbs[spec->num_init_verbs++]
  11395. = alc861vd_volume_init_verbs;
  11396. spec->num_mux_defs = 1;
  11397. spec->input_mux = &spec->private_imux;
  11398. err = alc_auto_add_mic_boost(codec);
  11399. if (err < 0)
  11400. return err;
  11401. return 1;
  11402. }
  11403. /* additional initialization for auto-configuration model */
  11404. static void alc861vd_auto_init(struct hda_codec *codec)
  11405. {
  11406. struct alc_spec *spec = codec->spec;
  11407. alc861vd_auto_init_multi_out(codec);
  11408. alc861vd_auto_init_hp_out(codec);
  11409. alc861vd_auto_init_analog_input(codec);
  11410. if (spec->unsol_event)
  11411. alc_sku_automute(codec);
  11412. }
  11413. static int patch_alc861vd(struct hda_codec *codec)
  11414. {
  11415. struct alc_spec *spec;
  11416. int err, board_config;
  11417. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  11418. if (spec == NULL)
  11419. return -ENOMEM;
  11420. codec->spec = spec;
  11421. board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
  11422. alc861vd_models,
  11423. alc861vd_cfg_tbl);
  11424. if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
  11425. printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
  11426. "ALC861VD, trying auto-probe from BIOS...\n");
  11427. board_config = ALC861VD_AUTO;
  11428. }
  11429. if (board_config == ALC861VD_AUTO) {
  11430. /* automatic parse from the BIOS config */
  11431. err = alc861vd_parse_auto_config(codec);
  11432. if (err < 0) {
  11433. alc_free(codec);
  11434. return err;
  11435. } else if (!err) {
  11436. printk(KERN_INFO
  11437. "hda_codec: Cannot set up configuration "
  11438. "from BIOS. Using base mode...\n");
  11439. board_config = ALC861VD_3ST;
  11440. }
  11441. }
  11442. if (board_config != ALC861VD_AUTO)
  11443. setup_preset(spec, &alc861vd_presets[board_config]);
  11444. spec->stream_name_analog = "ALC861VD Analog";
  11445. spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
  11446. spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
  11447. spec->stream_name_digital = "ALC861VD Digital";
  11448. spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
  11449. spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
  11450. spec->adc_nids = alc861vd_adc_nids;
  11451. spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
  11452. spec->capsrc_nids = alc861vd_capsrc_nids;
  11453. spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
  11454. spec->num_mixers++;
  11455. spec->vmaster_nid = 0x02;
  11456. codec->patch_ops = alc_patch_ops;
  11457. if (board_config == ALC861VD_AUTO)
  11458. spec->init_hook = alc861vd_auto_init;
  11459. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11460. if (!spec->loopback.amplist)
  11461. spec->loopback.amplist = alc861vd_loopbacks;
  11462. #endif
  11463. return 0;
  11464. }
  11465. /*
  11466. * ALC662 support
  11467. *
  11468. * ALC662 is almost identical with ALC880 but has cleaner and more flexible
  11469. * configuration. Each pin widget can choose any input DACs and a mixer.
  11470. * Each ADC is connected from a mixer of all inputs. This makes possible
  11471. * 6-channel independent captures.
  11472. *
  11473. * In addition, an independent DAC for the multi-playback (not used in this
  11474. * driver yet).
  11475. */
  11476. #define ALC662_DIGOUT_NID 0x06
  11477. #define ALC662_DIGIN_NID 0x0a
  11478. static hda_nid_t alc662_dac_nids[4] = {
  11479. /* front, rear, clfe, rear_surr */
  11480. 0x02, 0x03, 0x04
  11481. };
  11482. static hda_nid_t alc662_adc_nids[1] = {
  11483. /* ADC1-2 */
  11484. 0x09,
  11485. };
  11486. static hda_nid_t alc662_capsrc_nids[1] = { 0x23 };
  11487. /* input MUX */
  11488. /* FIXME: should be a matrix-type input source selection */
  11489. static struct hda_input_mux alc662_capture_source = {
  11490. .num_items = 4,
  11491. .items = {
  11492. { "Mic", 0x0 },
  11493. { "Front Mic", 0x1 },
  11494. { "Line", 0x2 },
  11495. { "CD", 0x4 },
  11496. },
  11497. };
  11498. static struct hda_input_mux alc662_lenovo_101e_capture_source = {
  11499. .num_items = 2,
  11500. .items = {
  11501. { "Mic", 0x1 },
  11502. { "Line", 0x2 },
  11503. },
  11504. };
  11505. static struct hda_input_mux alc662_eeepc_capture_source = {
  11506. .num_items = 2,
  11507. .items = {
  11508. { "i-Mic", 0x1 },
  11509. { "e-Mic", 0x0 },
  11510. },
  11511. };
  11512. #define alc662_mux_enum_info alc_mux_enum_info
  11513. #define alc662_mux_enum_get alc_mux_enum_get
  11514. #define alc662_mux_enum_put alc882_mux_enum_put
  11515. /*
  11516. * 2ch mode
  11517. */
  11518. static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
  11519. { 2, NULL }
  11520. };
  11521. /*
  11522. * 2ch mode
  11523. */
  11524. static struct hda_verb alc662_3ST_ch2_init[] = {
  11525. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
  11526. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  11527. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
  11528. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
  11529. { } /* end */
  11530. };
  11531. /*
  11532. * 6ch mode
  11533. */
  11534. static struct hda_verb alc662_3ST_ch6_init[] = {
  11535. { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11536. { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  11537. { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
  11538. { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11539. { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
  11540. { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
  11541. { } /* end */
  11542. };
  11543. static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
  11544. { 2, alc662_3ST_ch2_init },
  11545. { 6, alc662_3ST_ch6_init },
  11546. };
  11547. /*
  11548. * 2ch mode
  11549. */
  11550. static struct hda_verb alc662_sixstack_ch6_init[] = {
  11551. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  11552. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
  11553. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11554. { } /* end */
  11555. };
  11556. /*
  11557. * 6ch mode
  11558. */
  11559. static struct hda_verb alc662_sixstack_ch8_init[] = {
  11560. { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11561. { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11562. { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
  11563. { } /* end */
  11564. };
  11565. static struct hda_channel_mode alc662_5stack_modes[2] = {
  11566. { 2, alc662_sixstack_ch6_init },
  11567. { 6, alc662_sixstack_ch8_init },
  11568. };
  11569. /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  11570. * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  11571. */
  11572. static struct snd_kcontrol_new alc662_base_mixer[] = {
  11573. /* output mixer control */
  11574. HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
  11575. HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
  11576. HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
  11577. HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
  11578. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  11579. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  11580. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
  11581. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
  11582. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11583. /*Input mixer control */
  11584. HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
  11585. HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
  11586. HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
  11587. HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
  11588. HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
  11589. HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
  11590. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
  11591. HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
  11592. { } /* end */
  11593. };
  11594. static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
  11595. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11596. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11597. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11598. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  11599. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  11600. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11601. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11602. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11603. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11604. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11605. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11606. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  11607. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  11608. { } /* end */
  11609. };
  11610. static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
  11611. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11612. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11613. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  11614. HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
  11615. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  11616. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  11617. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
  11618. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
  11619. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11620. HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
  11621. HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
  11622. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11623. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11624. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11625. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11626. HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11627. HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11628. HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
  11629. HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
  11630. { } /* end */
  11631. };
  11632. static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
  11633. HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11634. HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
  11635. HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  11636. HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
  11637. HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11638. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11639. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11640. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11641. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11642. { } /* end */
  11643. };
  11644. static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
  11645. HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  11646. HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11647. HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11648. HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
  11649. HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11650. HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11651. HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
  11652. HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
  11653. HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
  11654. { } /* end */
  11655. };
  11656. static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
  11657. HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
  11658. HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
  11659. HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
  11660. HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
  11661. HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
  11662. HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
  11663. HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
  11664. HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
  11665. HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
  11666. HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
  11667. HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
  11668. HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
  11669. HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
  11670. HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
  11671. { } /* end */
  11672. };
  11673. static struct snd_kcontrol_new alc662_chmode_mixer[] = {
  11674. {
  11675. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  11676. .name = "Channel Mode",
  11677. .info = alc_ch_mode_info,
  11678. .get = alc_ch_mode_get,
  11679. .put = alc_ch_mode_put,
  11680. },
  11681. { } /* end */
  11682. };
  11683. static struct hda_verb alc662_init_verbs[] = {
  11684. /* ADC: mute amp left and right */
  11685. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11686. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  11687. /* Front mixer: unmute input/output amp left and right (volume = 0) */
  11688. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11689. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11690. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  11691. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  11692. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  11693. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11694. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11695. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11696. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11697. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11698. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11699. /* Front Pin: output 0 (0x0c) */
  11700. {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11701. {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11702. /* Rear Pin: output 1 (0x0d) */
  11703. {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11704. {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11705. /* CLFE Pin: output 2 (0x0e) */
  11706. {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11707. {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11708. /* Mic (rear) pin: input vref at 80% */
  11709. {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  11710. {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11711. /* Front Mic pin: input vref at 80% */
  11712. {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
  11713. {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11714. /* Line In pin: input */
  11715. {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11716. {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
  11717. /* Line-2 In: Headphone output (output 0 - 0x0c) */
  11718. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
  11719. {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
  11720. {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
  11721. /* CD pin widget for input */
  11722. {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
  11723. /* FIXME: use matrix-type input source selection */
  11724. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  11725. /* Input mixer */
  11726. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11727. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11728. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  11729. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  11730. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11731. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11732. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
  11733. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
  11734. { }
  11735. };
  11736. static struct hda_verb alc662_sue_init_verbs[] = {
  11737. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
  11738. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
  11739. {}
  11740. };
  11741. static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
  11742. {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
  11743. {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  11744. {}
  11745. };
  11746. /* Set Unsolicited Event*/
  11747. static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
  11748. {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
  11749. {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
  11750. {}
  11751. };
  11752. /*
  11753. * generic initialization of ADC, input mixers and output mixers
  11754. */
  11755. static struct hda_verb alc662_auto_init_verbs[] = {
  11756. /*
  11757. * Unmute ADC and set the default input to mic-in
  11758. */
  11759. {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
  11760. {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11761. /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
  11762. * mixer widget
  11763. * Note: PASD motherboards uses the Line In 2 as the input for front
  11764. * panel mic (mic 2)
  11765. */
  11766. /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
  11767. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
  11768. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
  11769. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
  11770. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
  11771. {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
  11772. /*
  11773. * Set up output mixers (0x0c - 0x0f)
  11774. */
  11775. /* set vol=0 to output mixers */
  11776. {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11777. {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11778. {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
  11779. /* set up input amps for analog loopback */
  11780. /* Amp Indices: DAC = 0, mixer = 1 */
  11781. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11782. {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11783. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11784. {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11785. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11786. {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
  11787. /* FIXME: use matrix-type input source selection */
  11788. /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
  11789. /* Input mixer */
  11790. {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11791. {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
  11792. { }
  11793. };
  11794. /* capture mixer elements */
  11795. static struct snd_kcontrol_new alc662_capture_mixer[] = {
  11796. HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
  11797. HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
  11798. {
  11799. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  11800. /* The multiple "Capture Source" controls confuse alsamixer
  11801. * So call somewhat different..
  11802. */
  11803. /* .name = "Capture Source", */
  11804. .name = "Input Source",
  11805. .count = 1,
  11806. .info = alc662_mux_enum_info,
  11807. .get = alc662_mux_enum_get,
  11808. .put = alc662_mux_enum_put,
  11809. },
  11810. { } /* end */
  11811. };
  11812. static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
  11813. {
  11814. unsigned int present;
  11815. unsigned char bits;
  11816. present = snd_hda_codec_read(codec, 0x14, 0,
  11817. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11818. bits = present ? HDA_AMP_MUTE : 0;
  11819. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  11820. HDA_AMP_MUTE, bits);
  11821. }
  11822. static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
  11823. {
  11824. unsigned int present;
  11825. unsigned char bits;
  11826. present = snd_hda_codec_read(codec, 0x1b, 0,
  11827. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11828. bits = present ? HDA_AMP_MUTE : 0;
  11829. snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
  11830. HDA_AMP_MUTE, bits);
  11831. snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
  11832. HDA_AMP_MUTE, bits);
  11833. }
  11834. static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
  11835. unsigned int res)
  11836. {
  11837. if ((res >> 26) == ALC880_HP_EVENT)
  11838. alc662_lenovo_101e_all_automute(codec);
  11839. if ((res >> 26) == ALC880_FRONT_EVENT)
  11840. alc662_lenovo_101e_ispeaker_automute(codec);
  11841. }
  11842. static void alc662_eeepc_mic_automute(struct hda_codec *codec)
  11843. {
  11844. unsigned int present;
  11845. present = snd_hda_codec_read(codec, 0x18, 0,
  11846. AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  11847. snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11848. 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
  11849. snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11850. 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
  11851. snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11852. 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
  11853. snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  11854. 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
  11855. }
  11856. /* unsolicited event for HP jack sensing */
  11857. static void alc662_eeepc_unsol_event(struct hda_codec *codec,
  11858. unsigned int res)
  11859. {
  11860. if ((res >> 26) == ALC880_HP_EVENT)
  11861. alc262_hippo1_automute( codec );
  11862. if ((res >> 26) == ALC880_MIC_EVENT)
  11863. alc662_eeepc_mic_automute(codec);
  11864. }
  11865. static void alc662_eeepc_inithook(struct hda_codec *codec)
  11866. {
  11867. alc262_hippo1_automute( codec );
  11868. alc662_eeepc_mic_automute(codec);
  11869. }
  11870. static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
  11871. {
  11872. unsigned int mute;
  11873. unsigned int present;
  11874. snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
  11875. present = snd_hda_codec_read(codec, 0x14, 0,
  11876. AC_VERB_GET_PIN_SENSE, 0);
  11877. present = (present & 0x80000000) != 0;
  11878. if (present) {
  11879. /* mute internal speaker */
  11880. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  11881. HDA_AMP_MUTE, HDA_AMP_MUTE);
  11882. } else {
  11883. /* unmute internal speaker if necessary */
  11884. mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
  11885. snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
  11886. HDA_AMP_MUTE, mute);
  11887. }
  11888. }
  11889. /* unsolicited event for HP jack sensing */
  11890. static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
  11891. unsigned int res)
  11892. {
  11893. if ((res >> 26) == ALC880_HP_EVENT)
  11894. alc662_eeepc_ep20_automute(codec);
  11895. }
  11896. static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
  11897. {
  11898. alc662_eeepc_ep20_automute(codec);
  11899. }
  11900. #ifdef CONFIG_SND_HDA_POWER_SAVE
  11901. #define alc662_loopbacks alc880_loopbacks
  11902. #endif
  11903. /* pcm configuration: identiacal with ALC880 */
  11904. #define alc662_pcm_analog_playback alc880_pcm_analog_playback
  11905. #define alc662_pcm_analog_capture alc880_pcm_analog_capture
  11906. #define alc662_pcm_digital_playback alc880_pcm_digital_playback
  11907. #define alc662_pcm_digital_capture alc880_pcm_digital_capture
  11908. /*
  11909. * configuration and preset
  11910. */
  11911. static const char *alc662_models[ALC662_MODEL_LAST] = {
  11912. [ALC662_3ST_2ch_DIG] = "3stack-dig",
  11913. [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
  11914. [ALC662_3ST_6ch] = "3stack-6ch",
  11915. [ALC662_5ST_DIG] = "6stack-dig",
  11916. [ALC662_LENOVO_101E] = "lenovo-101e",
  11917. [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
  11918. [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
  11919. [ALC662_AUTO] = "auto",
  11920. };
  11921. static struct snd_pci_quirk alc662_cfg_tbl[] = {
  11922. SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
  11923. SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
  11924. SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
  11925. {}
  11926. };
  11927. static struct alc_config_preset alc662_presets[] = {
  11928. [ALC662_3ST_2ch_DIG] = {
  11929. .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
  11930. .init_verbs = { alc662_init_verbs },
  11931. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11932. .dac_nids = alc662_dac_nids,
  11933. .dig_out_nid = ALC662_DIGOUT_NID,
  11934. .dig_in_nid = ALC662_DIGIN_NID,
  11935. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11936. .channel_mode = alc662_3ST_2ch_modes,
  11937. .input_mux = &alc662_capture_source,
  11938. },
  11939. [ALC662_3ST_6ch_DIG] = {
  11940. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
  11941. alc662_capture_mixer },
  11942. .init_verbs = { alc662_init_verbs },
  11943. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11944. .dac_nids = alc662_dac_nids,
  11945. .dig_out_nid = ALC662_DIGOUT_NID,
  11946. .dig_in_nid = ALC662_DIGIN_NID,
  11947. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  11948. .channel_mode = alc662_3ST_6ch_modes,
  11949. .need_dac_fix = 1,
  11950. .input_mux = &alc662_capture_source,
  11951. },
  11952. [ALC662_3ST_6ch] = {
  11953. .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
  11954. alc662_capture_mixer },
  11955. .init_verbs = { alc662_init_verbs },
  11956. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11957. .dac_nids = alc662_dac_nids,
  11958. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  11959. .channel_mode = alc662_3ST_6ch_modes,
  11960. .need_dac_fix = 1,
  11961. .input_mux = &alc662_capture_source,
  11962. },
  11963. [ALC662_5ST_DIG] = {
  11964. .mixers = { alc662_base_mixer, alc662_chmode_mixer,
  11965. alc662_capture_mixer },
  11966. .init_verbs = { alc662_init_verbs },
  11967. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11968. .dac_nids = alc662_dac_nids,
  11969. .dig_out_nid = ALC662_DIGOUT_NID,
  11970. .dig_in_nid = ALC662_DIGIN_NID,
  11971. .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
  11972. .channel_mode = alc662_5stack_modes,
  11973. .input_mux = &alc662_capture_source,
  11974. },
  11975. [ALC662_LENOVO_101E] = {
  11976. .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
  11977. .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
  11978. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11979. .dac_nids = alc662_dac_nids,
  11980. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11981. .channel_mode = alc662_3ST_2ch_modes,
  11982. .input_mux = &alc662_lenovo_101e_capture_source,
  11983. .unsol_event = alc662_lenovo_101e_unsol_event,
  11984. .init_hook = alc662_lenovo_101e_all_automute,
  11985. },
  11986. [ALC662_ASUS_EEEPC_P701] = {
  11987. .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
  11988. .init_verbs = { alc662_init_verbs,
  11989. alc662_eeepc_sue_init_verbs },
  11990. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  11991. .dac_nids = alc662_dac_nids,
  11992. .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
  11993. .channel_mode = alc662_3ST_2ch_modes,
  11994. .input_mux = &alc662_eeepc_capture_source,
  11995. .unsol_event = alc662_eeepc_unsol_event,
  11996. .init_hook = alc662_eeepc_inithook,
  11997. },
  11998. [ALC662_ASUS_EEEPC_EP20] = {
  11999. .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
  12000. alc662_chmode_mixer },
  12001. .init_verbs = { alc662_init_verbs,
  12002. alc662_eeepc_ep20_sue_init_verbs },
  12003. .num_dacs = ARRAY_SIZE(alc662_dac_nids),
  12004. .dac_nids = alc662_dac_nids,
  12005. .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
  12006. .channel_mode = alc662_3ST_6ch_modes,
  12007. .input_mux = &alc662_lenovo_101e_capture_source,
  12008. .unsol_event = alc662_eeepc_ep20_unsol_event,
  12009. .init_hook = alc662_eeepc_ep20_inithook,
  12010. },
  12011. };
  12012. /*
  12013. * BIOS auto configuration
  12014. */
  12015. /* add playback controls from the parsed DAC table */
  12016. static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
  12017. const struct auto_pin_cfg *cfg)
  12018. {
  12019. char name[32];
  12020. static const char *chname[4] = {
  12021. "Front", "Surround", NULL /*CLFE*/, "Side"
  12022. };
  12023. hda_nid_t nid;
  12024. int i, err;
  12025. for (i = 0; i < cfg->line_outs; i++) {
  12026. if (!spec->multiout.dac_nids[i])
  12027. continue;
  12028. nid = alc880_idx_to_dac(i);
  12029. if (i == 2) {
  12030. /* Center/LFE */
  12031. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  12032. "Center Playback Volume",
  12033. HDA_COMPOSE_AMP_VAL(nid, 1, 0,
  12034. HDA_OUTPUT));
  12035. if (err < 0)
  12036. return err;
  12037. err = add_control(spec, ALC_CTL_WIDGET_VOL,
  12038. "LFE Playback Volume",
  12039. HDA_COMPOSE_AMP_VAL(nid, 2, 0,
  12040. HDA_OUTPUT));
  12041. if (err < 0)
  12042. return err;
  12043. err = add_control(spec, ALC_CTL_BIND_MUTE,
  12044. "Center Playback Switch",
  12045. HDA_COMPOSE_AMP_VAL(nid, 1, 2,
  12046. HDA_INPUT));
  12047. if (err < 0)
  12048. return err;
  12049. err = add_control(spec, ALC_CTL_BIND_MUTE,
  12050. "LFE Playback Switch",
  12051. HDA_COMPOSE_AMP_VAL(nid, 2, 2,
  12052. HDA_INPUT));
  12053. if (err < 0)
  12054. return err;
  12055. } else {
  12056. sprintf(name, "%s Playback Volume", chname[i]);
  12057. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  12058. HDA_COMPOSE_AMP_VAL(nid, 3, 0,
  12059. HDA_OUTPUT));
  12060. if (err < 0)
  12061. return err;
  12062. sprintf(name, "%s Playback Switch", chname[i]);
  12063. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  12064. HDA_COMPOSE_AMP_VAL(nid, 3, 2,
  12065. HDA_INPUT));
  12066. if (err < 0)
  12067. return err;
  12068. }
  12069. }
  12070. return 0;
  12071. }
  12072. /* add playback controls for speaker and HP outputs */
  12073. static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
  12074. const char *pfx)
  12075. {
  12076. hda_nid_t nid;
  12077. int err;
  12078. char name[32];
  12079. if (!pin)
  12080. return 0;
  12081. if (alc880_is_fixed_pin(pin)) {
  12082. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  12083. /* printk("DAC nid=%x\n",nid); */
  12084. /* specify the DAC as the extra output */
  12085. if (!spec->multiout.hp_nid)
  12086. spec->multiout.hp_nid = nid;
  12087. else
  12088. spec->multiout.extra_out_nid[0] = nid;
  12089. /* control HP volume/switch on the output mixer amp */
  12090. nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
  12091. sprintf(name, "%s Playback Volume", pfx);
  12092. err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
  12093. HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
  12094. if (err < 0)
  12095. return err;
  12096. sprintf(name, "%s Playback Switch", pfx);
  12097. err = add_control(spec, ALC_CTL_BIND_MUTE, name,
  12098. HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
  12099. if (err < 0)
  12100. return err;
  12101. } else if (alc880_is_multi_pin(pin)) {
  12102. /* set manual connection */
  12103. /* we have only a switch on HP-out PIN */
  12104. sprintf(name, "%s Playback Switch", pfx);
  12105. err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
  12106. HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
  12107. if (err < 0)
  12108. return err;
  12109. }
  12110. return 0;
  12111. }
  12112. /* create playback/capture controls for input pins */
  12113. static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
  12114. const struct auto_pin_cfg *cfg)
  12115. {
  12116. struct hda_input_mux *imux = &spec->private_imux;
  12117. int i, err, idx;
  12118. for (i = 0; i < AUTO_PIN_LAST; i++) {
  12119. if (alc880_is_input_pin(cfg->input_pins[i])) {
  12120. idx = alc880_input_pin_idx(cfg->input_pins[i]);
  12121. err = new_analog_input(spec, cfg->input_pins[i],
  12122. auto_pin_cfg_labels[i],
  12123. idx, 0x0b);
  12124. if (err < 0)
  12125. return err;
  12126. imux->items[imux->num_items].label =
  12127. auto_pin_cfg_labels[i];
  12128. imux->items[imux->num_items].index =
  12129. alc880_input_pin_idx(cfg->input_pins[i]);
  12130. imux->num_items++;
  12131. }
  12132. }
  12133. return 0;
  12134. }
  12135. static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
  12136. hda_nid_t nid, int pin_type,
  12137. int dac_idx)
  12138. {
  12139. alc_set_pin_output(codec, nid, pin_type);
  12140. /* need the manual connection? */
  12141. if (alc880_is_multi_pin(nid)) {
  12142. struct alc_spec *spec = codec->spec;
  12143. int idx = alc880_multi_pin_idx(nid);
  12144. snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
  12145. AC_VERB_SET_CONNECT_SEL,
  12146. alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
  12147. }
  12148. }
  12149. static void alc662_auto_init_multi_out(struct hda_codec *codec)
  12150. {
  12151. struct alc_spec *spec = codec->spec;
  12152. int i;
  12153. alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
  12154. for (i = 0; i <= HDA_SIDE; i++) {
  12155. hda_nid_t nid = spec->autocfg.line_out_pins[i];
  12156. int pin_type = get_pin_type(spec->autocfg.line_out_type);
  12157. if (nid)
  12158. alc662_auto_set_output_and_unmute(codec, nid, pin_type,
  12159. i);
  12160. }
  12161. }
  12162. static void alc662_auto_init_hp_out(struct hda_codec *codec)
  12163. {
  12164. struct alc_spec *spec = codec->spec;
  12165. hda_nid_t pin;
  12166. pin = spec->autocfg.hp_pins[0];
  12167. if (pin) /* connect to front */
  12168. /* use dac 0 */
  12169. alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
  12170. pin = spec->autocfg.speaker_pins[0];
  12171. if (pin)
  12172. alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
  12173. }
  12174. #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
  12175. #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
  12176. static void alc662_auto_init_analog_input(struct hda_codec *codec)
  12177. {
  12178. struct alc_spec *spec = codec->spec;
  12179. int i;
  12180. for (i = 0; i < AUTO_PIN_LAST; i++) {
  12181. hda_nid_t nid = spec->autocfg.input_pins[i];
  12182. if (alc662_is_input_pin(nid)) {
  12183. snd_hda_codec_write(codec, nid, 0,
  12184. AC_VERB_SET_PIN_WIDGET_CONTROL,
  12185. (i <= AUTO_PIN_FRONT_MIC ?
  12186. PIN_VREF80 : PIN_IN));
  12187. if (nid != ALC662_PIN_CD_NID)
  12188. snd_hda_codec_write(codec, nid, 0,
  12189. AC_VERB_SET_AMP_GAIN_MUTE,
  12190. AMP_OUT_MUTE);
  12191. }
  12192. }
  12193. }
  12194. static int alc662_parse_auto_config(struct hda_codec *codec)
  12195. {
  12196. struct alc_spec *spec = codec->spec;
  12197. int err;
  12198. static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
  12199. err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
  12200. alc662_ignore);
  12201. if (err < 0)
  12202. return err;
  12203. if (!spec->autocfg.line_outs)
  12204. return 0; /* can't find valid BIOS pin config */
  12205. err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
  12206. if (err < 0)
  12207. return err;
  12208. err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
  12209. if (err < 0)
  12210. return err;
  12211. err = alc662_auto_create_extra_out(spec,
  12212. spec->autocfg.speaker_pins[0],
  12213. "Speaker");
  12214. if (err < 0)
  12215. return err;
  12216. err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
  12217. "Headphone");
  12218. if (err < 0)
  12219. return err;
  12220. err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
  12221. if (err < 0)
  12222. return err;
  12223. spec->multiout.max_channels = spec->multiout.num_dacs * 2;
  12224. if (spec->autocfg.dig_out_pin)
  12225. spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
  12226. if (spec->kctl_alloc)
  12227. spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
  12228. spec->num_mux_defs = 1;
  12229. spec->input_mux = &spec->private_imux;
  12230. spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
  12231. spec->mixers[spec->num_mixers] = alc662_capture_mixer;
  12232. spec->num_mixers++;
  12233. return 1;
  12234. }
  12235. /* additional initialization for auto-configuration model */
  12236. static void alc662_auto_init(struct hda_codec *codec)
  12237. {
  12238. struct alc_spec *spec = codec->spec;
  12239. alc662_auto_init_multi_out(codec);
  12240. alc662_auto_init_hp_out(codec);
  12241. alc662_auto_init_analog_input(codec);
  12242. if (spec->unsol_event)
  12243. alc_sku_automute(codec);
  12244. }
  12245. static int patch_alc662(struct hda_codec *codec)
  12246. {
  12247. struct alc_spec *spec;
  12248. int err, board_config;
  12249. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  12250. if (!spec)
  12251. return -ENOMEM;
  12252. codec->spec = spec;
  12253. board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
  12254. alc662_models,
  12255. alc662_cfg_tbl);
  12256. if (board_config < 0) {
  12257. printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
  12258. "trying auto-probe from BIOS...\n");
  12259. board_config = ALC662_AUTO;
  12260. }
  12261. if (board_config == ALC662_AUTO) {
  12262. /* automatic parse from the BIOS config */
  12263. err = alc662_parse_auto_config(codec);
  12264. if (err < 0) {
  12265. alc_free(codec);
  12266. return err;
  12267. } else if (!err) {
  12268. printk(KERN_INFO
  12269. "hda_codec: Cannot set up configuration "
  12270. "from BIOS. Using base mode...\n");
  12271. board_config = ALC662_3ST_2ch_DIG;
  12272. }
  12273. }
  12274. if (board_config != ALC662_AUTO)
  12275. setup_preset(spec, &alc662_presets[board_config]);
  12276. spec->stream_name_analog = "ALC662 Analog";
  12277. spec->stream_analog_playback = &alc662_pcm_analog_playback;
  12278. spec->stream_analog_capture = &alc662_pcm_analog_capture;
  12279. spec->stream_name_digital = "ALC662 Digital";
  12280. spec->stream_digital_playback = &alc662_pcm_digital_playback;
  12281. spec->stream_digital_capture = &alc662_pcm_digital_capture;
  12282. spec->adc_nids = alc662_adc_nids;
  12283. spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
  12284. spec->capsrc_nids = alc662_capsrc_nids;
  12285. spec->vmaster_nid = 0x02;
  12286. codec->patch_ops = alc_patch_ops;
  12287. if (board_config == ALC662_AUTO)
  12288. spec->init_hook = alc662_auto_init;
  12289. #ifdef CONFIG_SND_HDA_POWER_SAVE
  12290. if (!spec->loopback.amplist)
  12291. spec->loopback.amplist = alc662_loopbacks;
  12292. #endif
  12293. return 0;
  12294. }
  12295. /*
  12296. * patch entries
  12297. */
  12298. struct hda_codec_preset snd_hda_preset_realtek[] = {
  12299. { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
  12300. { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
  12301. { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
  12302. { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
  12303. { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
  12304. { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
  12305. .patch = patch_alc861 },
  12306. { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
  12307. { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
  12308. { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
  12309. { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
  12310. .patch = patch_alc883 },
  12311. { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
  12312. .patch = patch_alc662 },
  12313. { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
  12314. { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
  12315. { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
  12316. { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
  12317. { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
  12318. { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
  12319. {} /* terminator */
  12320. };