wcd9335.c 158 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
  3. // Copyright (c) 2017-2018, Linaro Limited
  4. #include <linux/module.h>
  5. #include <linux/init.h>
  6. #include <linux/platform_device.h>
  7. #include <linux/device.h>
  8. #include <linux/wait.h>
  9. #include <linux/bitops.h>
  10. #include <linux/regulator/consumer.h>
  11. #include <linux/clk.h>
  12. #include <linux/delay.h>
  13. #include <linux/kernel.h>
  14. #include <linux/slimbus.h>
  15. #include <sound/soc.h>
  16. #include <sound/pcm_params.h>
  17. #include <sound/soc-dapm.h>
  18. #include <linux/of_gpio.h>
  19. #include <linux/of.h>
  20. #include <linux/of_irq.h>
  21. #include <sound/tlv.h>
  22. #include <sound/info.h>
  23. #include "wcd9335.h"
  24. #include "wcd-clsh-v2.h"
  25. #include <dt-bindings/sound/qcom,wcd9335.h>
  26. #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
  27. SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
  28. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
  29. /* Fractional Rates */
  30. #define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100)
  31. #define WCD9335_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
  32. SNDRV_PCM_FMTBIT_S24_LE)
  33. /* slave port water mark level
  34. * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
  35. */
  36. #define SLAVE_PORT_WATER_MARK_6BYTES 0
  37. #define SLAVE_PORT_WATER_MARK_9BYTES 1
  38. #define SLAVE_PORT_WATER_MARK_12BYTES 2
  39. #define SLAVE_PORT_WATER_MARK_15BYTES 3
  40. #define SLAVE_PORT_WATER_MARK_SHIFT 1
  41. #define SLAVE_PORT_ENABLE 1
  42. #define SLAVE_PORT_DISABLE 0
  43. #define WCD9335_SLIM_WATER_MARK_VAL \
  44. ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \
  45. (SLAVE_PORT_ENABLE))
  46. #define WCD9335_SLIM_NUM_PORT_REG 3
  47. #define WCD9335_SLIM_PGD_PORT_INT_TX_EN0 (WCD9335_SLIM_PGD_PORT_INT_EN0 + 2)
  48. #define WCD9335_MCLK_CLK_12P288MHZ 12288000
  49. #define WCD9335_MCLK_CLK_9P6MHZ 9600000
  50. #define WCD9335_SLIM_CLOSE_TIMEOUT 1000
  51. #define WCD9335_SLIM_IRQ_OVERFLOW (1 << 0)
  52. #define WCD9335_SLIM_IRQ_UNDERFLOW (1 << 1)
  53. #define WCD9335_SLIM_IRQ_PORT_CLOSED (1 << 2)
  54. #define WCD9335_NUM_INTERPOLATORS 9
  55. #define WCD9335_RX_START 16
  56. #define WCD9335_SLIM_CH_START 128
  57. #define WCD9335_MAX_MICBIAS 4
  58. #define WCD9335_MAX_VALID_ADC_MUX 13
  59. #define WCD9335_INVALID_ADC_MUX 9
  60. #define TX_HPF_CUT_OFF_FREQ_MASK 0x60
  61. #define CF_MIN_3DB_4HZ 0x0
  62. #define CF_MIN_3DB_75HZ 0x1
  63. #define CF_MIN_3DB_150HZ 0x2
  64. #define WCD9335_DMIC_CLK_DIV_2 0x0
  65. #define WCD9335_DMIC_CLK_DIV_3 0x1
  66. #define WCD9335_DMIC_CLK_DIV_4 0x2
  67. #define WCD9335_DMIC_CLK_DIV_6 0x3
  68. #define WCD9335_DMIC_CLK_DIV_8 0x4
  69. #define WCD9335_DMIC_CLK_DIV_16 0x5
  70. #define WCD9335_DMIC_CLK_DRIVE_DEFAULT 0x02
  71. #define WCD9335_AMIC_PWR_LEVEL_LP 0
  72. #define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1
  73. #define WCD9335_AMIC_PWR_LEVEL_HP 2
  74. #define WCD9335_AMIC_PWR_LVL_MASK 0x60
  75. #define WCD9335_AMIC_PWR_LVL_SHIFT 0x5
  76. #define WCD9335_DEC_PWR_LVL_MASK 0x06
  77. #define WCD9335_DEC_PWR_LVL_LP 0x02
  78. #define WCD9335_DEC_PWR_LVL_HP 0x04
  79. #define WCD9335_DEC_PWR_LVL_DF 0x00
  80. #define WCD9335_SLIM_RX_CH(p) \
  81. {.port = p + WCD9335_RX_START, .shift = p,}
  82. #define WCD9335_SLIM_TX_CH(p) \
  83. {.port = p, .shift = p,}
  84. /* vout step value */
  85. #define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25)
  86. #define WCD9335_INTERPOLATOR_PATH(id) \
  87. {"RX INT" #id "_1 MIX1 INP0", "RX0", "SLIM RX0"}, \
  88. {"RX INT" #id "_1 MIX1 INP0", "RX1", "SLIM RX1"}, \
  89. {"RX INT" #id "_1 MIX1 INP0", "RX2", "SLIM RX2"}, \
  90. {"RX INT" #id "_1 MIX1 INP0", "RX3", "SLIM RX3"}, \
  91. {"RX INT" #id "_1 MIX1 INP0", "RX4", "SLIM RX4"}, \
  92. {"RX INT" #id "_1 MIX1 INP0", "RX5", "SLIM RX5"}, \
  93. {"RX INT" #id "_1 MIX1 INP0", "RX6", "SLIM RX6"}, \
  94. {"RX INT" #id "_1 MIX1 INP0", "RX7", "SLIM RX7"}, \
  95. {"RX INT" #id "_1 MIX1 INP1", "RX0", "SLIM RX0"}, \
  96. {"RX INT" #id "_1 MIX1 INP1", "RX1", "SLIM RX1"}, \
  97. {"RX INT" #id "_1 MIX1 INP1", "RX2", "SLIM RX2"}, \
  98. {"RX INT" #id "_1 MIX1 INP1", "RX3", "SLIM RX3"}, \
  99. {"RX INT" #id "_1 MIX1 INP1", "RX4", "SLIM RX4"}, \
  100. {"RX INT" #id "_1 MIX1 INP1", "RX5", "SLIM RX5"}, \
  101. {"RX INT" #id "_1 MIX1 INP1", "RX6", "SLIM RX6"}, \
  102. {"RX INT" #id "_1 MIX1 INP1", "RX7", "SLIM RX7"}, \
  103. {"RX INT" #id "_1 MIX1 INP2", "RX0", "SLIM RX0"}, \
  104. {"RX INT" #id "_1 MIX1 INP2", "RX1", "SLIM RX1"}, \
  105. {"RX INT" #id "_1 MIX1 INP2", "RX2", "SLIM RX2"}, \
  106. {"RX INT" #id "_1 MIX1 INP2", "RX3", "SLIM RX3"}, \
  107. {"RX INT" #id "_1 MIX1 INP2", "RX4", "SLIM RX4"}, \
  108. {"RX INT" #id "_1 MIX1 INP2", "RX5", "SLIM RX5"}, \
  109. {"RX INT" #id "_1 MIX1 INP2", "RX6", "SLIM RX6"}, \
  110. {"RX INT" #id "_1 MIX1 INP2", "RX7", "SLIM RX7"}, \
  111. {"RX INT" #id "_2 MUX", "RX0", "SLIM RX0"}, \
  112. {"RX INT" #id "_2 MUX", "RX1", "SLIM RX1"}, \
  113. {"RX INT" #id "_2 MUX", "RX2", "SLIM RX2"}, \
  114. {"RX INT" #id "_2 MUX", "RX3", "SLIM RX3"}, \
  115. {"RX INT" #id "_2 MUX", "RX4", "SLIM RX4"}, \
  116. {"RX INT" #id "_2 MUX", "RX5", "SLIM RX5"}, \
  117. {"RX INT" #id "_2 MUX", "RX6", "SLIM RX6"}, \
  118. {"RX INT" #id "_2 MUX", "RX7", "SLIM RX7"}, \
  119. {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP0"}, \
  120. {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP1"}, \
  121. {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP2"}, \
  122. {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_2 MUX"}, \
  123. {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_1 MIX1"}, \
  124. {"RX INT" #id " MIX2", NULL, "RX INT" #id " SEC MIX"}, \
  125. {"RX INT" #id " INTERP", NULL, "RX INT" #id " MIX2"}
  126. #define WCD9335_ADC_MUX_PATH(id) \
  127. {"AIF1_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
  128. {"AIF2_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
  129. {"AIF3_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \
  130. {"SLIM TX" #id " MUX", "DEC" #id, "ADC MUX" #id}, \
  131. {"ADC MUX" #id, "DMIC", "DMIC MUX" #id}, \
  132. {"ADC MUX" #id, "AMIC", "AMIC MUX" #id}, \
  133. {"DMIC MUX" #id, "DMIC0", "DMIC0"}, \
  134. {"DMIC MUX" #id, "DMIC1", "DMIC1"}, \
  135. {"DMIC MUX" #id, "DMIC2", "DMIC2"}, \
  136. {"DMIC MUX" #id, "DMIC3", "DMIC3"}, \
  137. {"DMIC MUX" #id, "DMIC4", "DMIC4"}, \
  138. {"DMIC MUX" #id, "DMIC5", "DMIC5"}, \
  139. {"AMIC MUX" #id, "ADC1", "ADC1"}, \
  140. {"AMIC MUX" #id, "ADC2", "ADC2"}, \
  141. {"AMIC MUX" #id, "ADC3", "ADC3"}, \
  142. {"AMIC MUX" #id, "ADC4", "ADC4"}, \
  143. {"AMIC MUX" #id, "ADC5", "ADC5"}, \
  144. {"AMIC MUX" #id, "ADC6", "ADC6"}
  145. enum {
  146. WCD9335_RX0 = 0,
  147. WCD9335_RX1,
  148. WCD9335_RX2,
  149. WCD9335_RX3,
  150. WCD9335_RX4,
  151. WCD9335_RX5,
  152. WCD9335_RX6,
  153. WCD9335_RX7,
  154. WCD9335_RX8,
  155. WCD9335_RX9,
  156. WCD9335_RX10,
  157. WCD9335_RX11,
  158. WCD9335_RX12,
  159. WCD9335_RX_MAX,
  160. };
  161. enum {
  162. WCD9335_TX0 = 0,
  163. WCD9335_TX1,
  164. WCD9335_TX2,
  165. WCD9335_TX3,
  166. WCD9335_TX4,
  167. WCD9335_TX5,
  168. WCD9335_TX6,
  169. WCD9335_TX7,
  170. WCD9335_TX8,
  171. WCD9335_TX9,
  172. WCD9335_TX10,
  173. WCD9335_TX11,
  174. WCD9335_TX12,
  175. WCD9335_TX13,
  176. WCD9335_TX14,
  177. WCD9335_TX15,
  178. WCD9335_TX_MAX,
  179. };
  180. enum {
  181. SIDO_SOURCE_INTERNAL = 0,
  182. SIDO_SOURCE_RCO_BG,
  183. };
  184. enum wcd9335_sido_voltage {
  185. SIDO_VOLTAGE_SVS_MV = 950,
  186. SIDO_VOLTAGE_NOMINAL_MV = 1100,
  187. };
  188. enum {
  189. COMPANDER_1, /* HPH_L */
  190. COMPANDER_2, /* HPH_R */
  191. COMPANDER_3, /* LO1_DIFF */
  192. COMPANDER_4, /* LO2_DIFF */
  193. COMPANDER_5, /* LO3_SE */
  194. COMPANDER_6, /* LO4_SE */
  195. COMPANDER_7, /* SWR SPK CH1 */
  196. COMPANDER_8, /* SWR SPK CH2 */
  197. COMPANDER_MAX,
  198. };
  199. enum {
  200. INTn_2_INP_SEL_ZERO = 0,
  201. INTn_2_INP_SEL_RX0,
  202. INTn_2_INP_SEL_RX1,
  203. INTn_2_INP_SEL_RX2,
  204. INTn_2_INP_SEL_RX3,
  205. INTn_2_INP_SEL_RX4,
  206. INTn_2_INP_SEL_RX5,
  207. INTn_2_INP_SEL_RX6,
  208. INTn_2_INP_SEL_RX7,
  209. INTn_2_INP_SEL_PROXIMITY,
  210. };
  211. enum {
  212. INTn_1_MIX_INP_SEL_ZERO = 0,
  213. INTn_1_MIX_INP_SEL_DEC0,
  214. INTn_1_MIX_INP_SEL_DEC1,
  215. INTn_1_MIX_INP_SEL_IIR0,
  216. INTn_1_MIX_INP_SEL_IIR1,
  217. INTn_1_MIX_INP_SEL_RX0,
  218. INTn_1_MIX_INP_SEL_RX1,
  219. INTn_1_MIX_INP_SEL_RX2,
  220. INTn_1_MIX_INP_SEL_RX3,
  221. INTn_1_MIX_INP_SEL_RX4,
  222. INTn_1_MIX_INP_SEL_RX5,
  223. INTn_1_MIX_INP_SEL_RX6,
  224. INTn_1_MIX_INP_SEL_RX7,
  225. };
  226. enum {
  227. INTERP_EAR = 0,
  228. INTERP_HPHL,
  229. INTERP_HPHR,
  230. INTERP_LO1,
  231. INTERP_LO2,
  232. INTERP_LO3,
  233. INTERP_LO4,
  234. INTERP_SPKR1,
  235. INTERP_SPKR2,
  236. };
  237. enum wcd_clock_type {
  238. WCD_CLK_OFF,
  239. WCD_CLK_RCO,
  240. WCD_CLK_MCLK,
  241. };
  242. enum {
  243. MIC_BIAS_1 = 1,
  244. MIC_BIAS_2,
  245. MIC_BIAS_3,
  246. MIC_BIAS_4
  247. };
  248. enum {
  249. MICB_PULLUP_ENABLE,
  250. MICB_PULLUP_DISABLE,
  251. MICB_ENABLE,
  252. MICB_DISABLE,
  253. };
  254. struct wcd9335_slim_ch {
  255. u32 ch_num;
  256. u16 port;
  257. u16 shift;
  258. struct list_head list;
  259. };
  260. struct wcd_slim_codec_dai_data {
  261. struct list_head slim_ch_list;
  262. struct slim_stream_config sconfig;
  263. struct slim_stream_runtime *sruntime;
  264. };
  265. struct wcd9335_codec {
  266. struct device *dev;
  267. struct clk *mclk;
  268. struct clk *native_clk;
  269. u32 mclk_rate;
  270. u8 version;
  271. struct slim_device *slim;
  272. struct slim_device *slim_ifc_dev;
  273. struct regmap *regmap;
  274. struct regmap *if_regmap;
  275. struct regmap_irq_chip_data *irq_data;
  276. struct wcd9335_slim_ch rx_chs[WCD9335_RX_MAX];
  277. struct wcd9335_slim_ch tx_chs[WCD9335_TX_MAX];
  278. u32 num_rx_port;
  279. u32 num_tx_port;
  280. int sido_input_src;
  281. enum wcd9335_sido_voltage sido_voltage;
  282. struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS];
  283. struct snd_soc_component *component;
  284. int master_bias_users;
  285. int clk_mclk_users;
  286. int clk_rco_users;
  287. int sido_ccl_cnt;
  288. enum wcd_clock_type clk_type;
  289. struct wcd_clsh_ctrl *clsh_ctrl;
  290. u32 hph_mode;
  291. int prim_int_users[WCD9335_NUM_INTERPOLATORS];
  292. int comp_enabled[COMPANDER_MAX];
  293. int intr1;
  294. int reset_gpio;
  295. struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
  296. unsigned int rx_port_value[WCD9335_RX_MAX];
  297. unsigned int tx_port_value[WCD9335_TX_MAX];
  298. int hph_l_gain;
  299. int hph_r_gain;
  300. u32 rx_bias_count;
  301. /*TX*/
  302. int micb_ref[WCD9335_MAX_MICBIAS];
  303. int pullup_ref[WCD9335_MAX_MICBIAS];
  304. int dmic_0_1_clk_cnt;
  305. int dmic_2_3_clk_cnt;
  306. int dmic_4_5_clk_cnt;
  307. int dmic_sample_rate;
  308. int mad_dmic_sample_rate;
  309. int native_clk_users;
  310. };
  311. struct wcd9335_irq {
  312. int irq;
  313. irqreturn_t (*handler)(int irq, void *data);
  314. char *name;
  315. };
  316. static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = {
  317. WCD9335_SLIM_TX_CH(0),
  318. WCD9335_SLIM_TX_CH(1),
  319. WCD9335_SLIM_TX_CH(2),
  320. WCD9335_SLIM_TX_CH(3),
  321. WCD9335_SLIM_TX_CH(4),
  322. WCD9335_SLIM_TX_CH(5),
  323. WCD9335_SLIM_TX_CH(6),
  324. WCD9335_SLIM_TX_CH(7),
  325. WCD9335_SLIM_TX_CH(8),
  326. WCD9335_SLIM_TX_CH(9),
  327. WCD9335_SLIM_TX_CH(10),
  328. WCD9335_SLIM_TX_CH(11),
  329. WCD9335_SLIM_TX_CH(12),
  330. WCD9335_SLIM_TX_CH(13),
  331. WCD9335_SLIM_TX_CH(14),
  332. WCD9335_SLIM_TX_CH(15),
  333. };
  334. static const struct wcd9335_slim_ch wcd9335_rx_chs[WCD9335_RX_MAX] = {
  335. WCD9335_SLIM_RX_CH(0), /* 16 */
  336. WCD9335_SLIM_RX_CH(1), /* 17 */
  337. WCD9335_SLIM_RX_CH(2),
  338. WCD9335_SLIM_RX_CH(3),
  339. WCD9335_SLIM_RX_CH(4),
  340. WCD9335_SLIM_RX_CH(5),
  341. WCD9335_SLIM_RX_CH(6),
  342. WCD9335_SLIM_RX_CH(7),
  343. WCD9335_SLIM_RX_CH(8),
  344. WCD9335_SLIM_RX_CH(9),
  345. WCD9335_SLIM_RX_CH(10),
  346. WCD9335_SLIM_RX_CH(11),
  347. WCD9335_SLIM_RX_CH(12),
  348. };
  349. struct interp_sample_rate {
  350. int rate;
  351. int rate_val;
  352. };
  353. static struct interp_sample_rate int_mix_rate_val[] = {
  354. {48000, 0x4}, /* 48K */
  355. {96000, 0x5}, /* 96K */
  356. {192000, 0x6}, /* 192K */
  357. };
  358. static struct interp_sample_rate int_prim_rate_val[] = {
  359. {8000, 0x0}, /* 8K */
  360. {16000, 0x1}, /* 16K */
  361. {24000, -EINVAL},/* 24K */
  362. {32000, 0x3}, /* 32K */
  363. {48000, 0x4}, /* 48K */
  364. {96000, 0x5}, /* 96K */
  365. {192000, 0x6}, /* 192K */
  366. {384000, 0x7}, /* 384K */
  367. {44100, 0x8}, /* 44.1K */
  368. };
  369. struct wcd9335_reg_mask_val {
  370. u16 reg;
  371. u8 mask;
  372. u8 val;
  373. };
  374. static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = {
  375. /* Rbuckfly/R_EAR(32) */
  376. {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00},
  377. {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60},
  378. {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00},
  379. {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
  380. {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
  381. {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
  382. {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
  383. {WCD9335_ANA_LO_1_2, 0x3C, 0X3C},
  384. {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00},
  385. {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40},
  386. {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03},
  387. {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02},
  388. {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01},
  389. {WCD9335_EAR_CMBUFF, 0x08, 0x00},
  390. {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
  391. {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
  392. {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
  393. {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
  394. {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80},
  395. {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
  396. {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
  397. {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
  398. {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
  399. {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
  400. {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
  401. {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
  402. {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
  403. {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
  404. {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
  405. {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
  406. {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
  407. {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
  408. {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
  409. {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
  410. {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
  411. {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
  412. {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
  413. {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
  414. {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
  415. {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
  416. {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08},
  417. {WCD9335_RCO_CTRL_2, 0x0F, 0x08},
  418. {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
  419. {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
  420. {WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
  421. {WCD9335_HPH_L_TEST, 0x01, 0x01},
  422. {WCD9335_HPH_R_TEST, 0x01, 0x01},
  423. {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
  424. {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
  425. {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
  426. {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
  427. {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
  428. {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
  429. {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
  430. {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
  431. {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
  432. {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
  433. };
  434. /* Cutoff frequency for high pass filter */
  435. static const char * const cf_text[] = {
  436. "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
  437. };
  438. static const char * const rx_cf_text[] = {
  439. "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
  440. "CF_NEG_3DB_0P48HZ"
  441. };
  442. static const char * const rx_int0_7_mix_mux_text[] = {
  443. "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
  444. "RX6", "RX7", "PROXIMITY"
  445. };
  446. static const char * const rx_int_mix_mux_text[] = {
  447. "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
  448. "RX6", "RX7"
  449. };
  450. static const char * const rx_prim_mix_text[] = {
  451. "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
  452. "RX3", "RX4", "RX5", "RX6", "RX7"
  453. };
  454. static const char * const rx_int_dem_inp_mux_text[] = {
  455. "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
  456. };
  457. static const char * const rx_int0_interp_mux_text[] = {
  458. "ZERO", "RX INT0 MIX2",
  459. };
  460. static const char * const rx_int1_interp_mux_text[] = {
  461. "ZERO", "RX INT1 MIX2",
  462. };
  463. static const char * const rx_int2_interp_mux_text[] = {
  464. "ZERO", "RX INT2 MIX2",
  465. };
  466. static const char * const rx_int3_interp_mux_text[] = {
  467. "ZERO", "RX INT3 MIX2",
  468. };
  469. static const char * const rx_int4_interp_mux_text[] = {
  470. "ZERO", "RX INT4 MIX2",
  471. };
  472. static const char * const rx_int5_interp_mux_text[] = {
  473. "ZERO", "RX INT5 MIX2",
  474. };
  475. static const char * const rx_int6_interp_mux_text[] = {
  476. "ZERO", "RX INT6 MIX2",
  477. };
  478. static const char * const rx_int7_interp_mux_text[] = {
  479. "ZERO", "RX INT7 MIX2",
  480. };
  481. static const char * const rx_int8_interp_mux_text[] = {
  482. "ZERO", "RX INT8 SEC MIX"
  483. };
  484. static const char * const rx_hph_mode_mux_text[] = {
  485. "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB",
  486. "Class-H Hi-Fi Low Power"
  487. };
  488. static const char *const slim_rx_mux_text[] = {
  489. "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB",
  490. };
  491. static const char * const adc_mux_text[] = {
  492. "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2"
  493. };
  494. static const char * const dmic_mux_text[] = {
  495. "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
  496. "SMIC0", "SMIC1", "SMIC2", "SMIC3"
  497. };
  498. static const char * const dmic_mux_alt_text[] = {
  499. "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
  500. };
  501. static const char * const amic_mux_text[] = {
  502. "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6"
  503. };
  504. static const char * const sb_tx0_mux_text[] = {
  505. "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
  506. };
  507. static const char * const sb_tx1_mux_text[] = {
  508. "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
  509. };
  510. static const char * const sb_tx2_mux_text[] = {
  511. "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
  512. };
  513. static const char * const sb_tx3_mux_text[] = {
  514. "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
  515. };
  516. static const char * const sb_tx4_mux_text[] = {
  517. "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
  518. };
  519. static const char * const sb_tx5_mux_text[] = {
  520. "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
  521. };
  522. static const char * const sb_tx6_mux_text[] = {
  523. "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
  524. };
  525. static const char * const sb_tx7_mux_text[] = {
  526. "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
  527. };
  528. static const char * const sb_tx8_mux_text[] = {
  529. "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
  530. };
  531. static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
  532. static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
  533. static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
  534. static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0);
  535. static const struct soc_enum cf_dec0_enum =
  536. SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text);
  537. static const struct soc_enum cf_dec1_enum =
  538. SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text);
  539. static const struct soc_enum cf_dec2_enum =
  540. SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text);
  541. static const struct soc_enum cf_dec3_enum =
  542. SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text);
  543. static const struct soc_enum cf_dec4_enum =
  544. SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text);
  545. static const struct soc_enum cf_dec5_enum =
  546. SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text);
  547. static const struct soc_enum cf_dec6_enum =
  548. SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text);
  549. static const struct soc_enum cf_dec7_enum =
  550. SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text);
  551. static const struct soc_enum cf_dec8_enum =
  552. SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text);
  553. static const struct soc_enum cf_int0_1_enum =
  554. SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
  555. static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
  556. rx_cf_text);
  557. static const struct soc_enum cf_int1_1_enum =
  558. SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
  559. static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
  560. rx_cf_text);
  561. static const struct soc_enum cf_int2_1_enum =
  562. SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
  563. static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
  564. rx_cf_text);
  565. static const struct soc_enum cf_int3_1_enum =
  566. SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
  567. static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
  568. rx_cf_text);
  569. static const struct soc_enum cf_int4_1_enum =
  570. SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
  571. static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
  572. rx_cf_text);
  573. static const struct soc_enum cf_int5_1_enum =
  574. SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
  575. static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
  576. rx_cf_text);
  577. static const struct soc_enum cf_int6_1_enum =
  578. SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
  579. static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
  580. rx_cf_text);
  581. static const struct soc_enum cf_int7_1_enum =
  582. SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
  583. static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
  584. rx_cf_text);
  585. static const struct soc_enum cf_int8_1_enum =
  586. SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
  587. static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
  588. rx_cf_text);
  589. static const struct soc_enum rx_hph_mode_mux_enum =
  590. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
  591. rx_hph_mode_mux_text);
  592. static const struct soc_enum slim_rx_mux_enum =
  593. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text);
  594. static const struct soc_enum rx_int0_2_mux_chain_enum =
  595. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10,
  596. rx_int0_7_mix_mux_text);
  597. static const struct soc_enum rx_int1_2_mux_chain_enum =
  598. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9,
  599. rx_int_mix_mux_text);
  600. static const struct soc_enum rx_int2_2_mux_chain_enum =
  601. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9,
  602. rx_int_mix_mux_text);
  603. static const struct soc_enum rx_int3_2_mux_chain_enum =
  604. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9,
  605. rx_int_mix_mux_text);
  606. static const struct soc_enum rx_int4_2_mux_chain_enum =
  607. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9,
  608. rx_int_mix_mux_text);
  609. static const struct soc_enum rx_int5_2_mux_chain_enum =
  610. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9,
  611. rx_int_mix_mux_text);
  612. static const struct soc_enum rx_int6_2_mux_chain_enum =
  613. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9,
  614. rx_int_mix_mux_text);
  615. static const struct soc_enum rx_int7_2_mux_chain_enum =
  616. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10,
  617. rx_int0_7_mix_mux_text);
  618. static const struct soc_enum rx_int8_2_mux_chain_enum =
  619. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9,
  620. rx_int_mix_mux_text);
  621. static const struct soc_enum rx_int0_1_mix_inp0_chain_enum =
  622. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13,
  623. rx_prim_mix_text);
  624. static const struct soc_enum rx_int0_1_mix_inp1_chain_enum =
  625. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13,
  626. rx_prim_mix_text);
  627. static const struct soc_enum rx_int0_1_mix_inp2_chain_enum =
  628. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13,
  629. rx_prim_mix_text);
  630. static const struct soc_enum rx_int1_1_mix_inp0_chain_enum =
  631. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13,
  632. rx_prim_mix_text);
  633. static const struct soc_enum rx_int1_1_mix_inp1_chain_enum =
  634. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13,
  635. rx_prim_mix_text);
  636. static const struct soc_enum rx_int1_1_mix_inp2_chain_enum =
  637. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13,
  638. rx_prim_mix_text);
  639. static const struct soc_enum rx_int2_1_mix_inp0_chain_enum =
  640. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13,
  641. rx_prim_mix_text);
  642. static const struct soc_enum rx_int2_1_mix_inp1_chain_enum =
  643. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13,
  644. rx_prim_mix_text);
  645. static const struct soc_enum rx_int2_1_mix_inp2_chain_enum =
  646. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13,
  647. rx_prim_mix_text);
  648. static const struct soc_enum rx_int3_1_mix_inp0_chain_enum =
  649. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13,
  650. rx_prim_mix_text);
  651. static const struct soc_enum rx_int3_1_mix_inp1_chain_enum =
  652. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13,
  653. rx_prim_mix_text);
  654. static const struct soc_enum rx_int3_1_mix_inp2_chain_enum =
  655. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13,
  656. rx_prim_mix_text);
  657. static const struct soc_enum rx_int4_1_mix_inp0_chain_enum =
  658. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13,
  659. rx_prim_mix_text);
  660. static const struct soc_enum rx_int4_1_mix_inp1_chain_enum =
  661. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13,
  662. rx_prim_mix_text);
  663. static const struct soc_enum rx_int4_1_mix_inp2_chain_enum =
  664. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13,
  665. rx_prim_mix_text);
  666. static const struct soc_enum rx_int5_1_mix_inp0_chain_enum =
  667. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13,
  668. rx_prim_mix_text);
  669. static const struct soc_enum rx_int5_1_mix_inp1_chain_enum =
  670. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13,
  671. rx_prim_mix_text);
  672. static const struct soc_enum rx_int5_1_mix_inp2_chain_enum =
  673. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13,
  674. rx_prim_mix_text);
  675. static const struct soc_enum rx_int6_1_mix_inp0_chain_enum =
  676. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13,
  677. rx_prim_mix_text);
  678. static const struct soc_enum rx_int6_1_mix_inp1_chain_enum =
  679. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13,
  680. rx_prim_mix_text);
  681. static const struct soc_enum rx_int6_1_mix_inp2_chain_enum =
  682. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13,
  683. rx_prim_mix_text);
  684. static const struct soc_enum rx_int7_1_mix_inp0_chain_enum =
  685. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13,
  686. rx_prim_mix_text);
  687. static const struct soc_enum rx_int7_1_mix_inp1_chain_enum =
  688. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13,
  689. rx_prim_mix_text);
  690. static const struct soc_enum rx_int7_1_mix_inp2_chain_enum =
  691. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13,
  692. rx_prim_mix_text);
  693. static const struct soc_enum rx_int8_1_mix_inp0_chain_enum =
  694. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13,
  695. rx_prim_mix_text);
  696. static const struct soc_enum rx_int8_1_mix_inp1_chain_enum =
  697. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13,
  698. rx_prim_mix_text);
  699. static const struct soc_enum rx_int8_1_mix_inp2_chain_enum =
  700. SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13,
  701. rx_prim_mix_text);
  702. static const struct soc_enum rx_int0_dem_inp_mux_enum =
  703. SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0,
  704. ARRAY_SIZE(rx_int_dem_inp_mux_text),
  705. rx_int_dem_inp_mux_text);
  706. static const struct soc_enum rx_int1_dem_inp_mux_enum =
  707. SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0,
  708. ARRAY_SIZE(rx_int_dem_inp_mux_text),
  709. rx_int_dem_inp_mux_text);
  710. static const struct soc_enum rx_int2_dem_inp_mux_enum =
  711. SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0,
  712. ARRAY_SIZE(rx_int_dem_inp_mux_text),
  713. rx_int_dem_inp_mux_text);
  714. static const struct soc_enum rx_int0_interp_mux_enum =
  715. SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2,
  716. rx_int0_interp_mux_text);
  717. static const struct soc_enum rx_int1_interp_mux_enum =
  718. SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2,
  719. rx_int1_interp_mux_text);
  720. static const struct soc_enum rx_int2_interp_mux_enum =
  721. SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2,
  722. rx_int2_interp_mux_text);
  723. static const struct soc_enum rx_int3_interp_mux_enum =
  724. SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2,
  725. rx_int3_interp_mux_text);
  726. static const struct soc_enum rx_int4_interp_mux_enum =
  727. SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2,
  728. rx_int4_interp_mux_text);
  729. static const struct soc_enum rx_int5_interp_mux_enum =
  730. SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2,
  731. rx_int5_interp_mux_text);
  732. static const struct soc_enum rx_int6_interp_mux_enum =
  733. SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2,
  734. rx_int6_interp_mux_text);
  735. static const struct soc_enum rx_int7_interp_mux_enum =
  736. SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2,
  737. rx_int7_interp_mux_text);
  738. static const struct soc_enum rx_int8_interp_mux_enum =
  739. SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2,
  740. rx_int8_interp_mux_text);
  741. static const struct soc_enum tx_adc_mux0_chain_enum =
  742. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4,
  743. adc_mux_text);
  744. static const struct soc_enum tx_adc_mux1_chain_enum =
  745. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4,
  746. adc_mux_text);
  747. static const struct soc_enum tx_adc_mux2_chain_enum =
  748. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4,
  749. adc_mux_text);
  750. static const struct soc_enum tx_adc_mux3_chain_enum =
  751. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4,
  752. adc_mux_text);
  753. static const struct soc_enum tx_adc_mux4_chain_enum =
  754. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4,
  755. adc_mux_text);
  756. static const struct soc_enum tx_adc_mux5_chain_enum =
  757. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4,
  758. adc_mux_text);
  759. static const struct soc_enum tx_adc_mux6_chain_enum =
  760. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4,
  761. adc_mux_text);
  762. static const struct soc_enum tx_adc_mux7_chain_enum =
  763. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4,
  764. adc_mux_text);
  765. static const struct soc_enum tx_adc_mux8_chain_enum =
  766. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4,
  767. adc_mux_text);
  768. static const struct soc_enum tx_dmic_mux0_enum =
  769. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11,
  770. dmic_mux_text);
  771. static const struct soc_enum tx_dmic_mux1_enum =
  772. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11,
  773. dmic_mux_text);
  774. static const struct soc_enum tx_dmic_mux2_enum =
  775. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11,
  776. dmic_mux_text);
  777. static const struct soc_enum tx_dmic_mux3_enum =
  778. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11,
  779. dmic_mux_text);
  780. static const struct soc_enum tx_dmic_mux4_enum =
  781. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7,
  782. dmic_mux_alt_text);
  783. static const struct soc_enum tx_dmic_mux5_enum =
  784. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7,
  785. dmic_mux_alt_text);
  786. static const struct soc_enum tx_dmic_mux6_enum =
  787. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7,
  788. dmic_mux_alt_text);
  789. static const struct soc_enum tx_dmic_mux7_enum =
  790. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7,
  791. dmic_mux_alt_text);
  792. static const struct soc_enum tx_dmic_mux8_enum =
  793. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7,
  794. dmic_mux_alt_text);
  795. static const struct soc_enum tx_amic_mux0_enum =
  796. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7,
  797. amic_mux_text);
  798. static const struct soc_enum tx_amic_mux1_enum =
  799. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7,
  800. amic_mux_text);
  801. static const struct soc_enum tx_amic_mux2_enum =
  802. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7,
  803. amic_mux_text);
  804. static const struct soc_enum tx_amic_mux3_enum =
  805. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7,
  806. amic_mux_text);
  807. static const struct soc_enum tx_amic_mux4_enum =
  808. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7,
  809. amic_mux_text);
  810. static const struct soc_enum tx_amic_mux5_enum =
  811. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7,
  812. amic_mux_text);
  813. static const struct soc_enum tx_amic_mux6_enum =
  814. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7,
  815. amic_mux_text);
  816. static const struct soc_enum tx_amic_mux7_enum =
  817. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7,
  818. amic_mux_text);
  819. static const struct soc_enum tx_amic_mux8_enum =
  820. SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7,
  821. amic_mux_text);
  822. static const struct soc_enum sb_tx0_mux_enum =
  823. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4,
  824. sb_tx0_mux_text);
  825. static const struct soc_enum sb_tx1_mux_enum =
  826. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4,
  827. sb_tx1_mux_text);
  828. static const struct soc_enum sb_tx2_mux_enum =
  829. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4,
  830. sb_tx2_mux_text);
  831. static const struct soc_enum sb_tx3_mux_enum =
  832. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4,
  833. sb_tx3_mux_text);
  834. static const struct soc_enum sb_tx4_mux_enum =
  835. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4,
  836. sb_tx4_mux_text);
  837. static const struct soc_enum sb_tx5_mux_enum =
  838. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4,
  839. sb_tx5_mux_text);
  840. static const struct soc_enum sb_tx6_mux_enum =
  841. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4,
  842. sb_tx6_mux_text);
  843. static const struct soc_enum sb_tx7_mux_enum =
  844. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4,
  845. sb_tx7_mux_text);
  846. static const struct soc_enum sb_tx8_mux_enum =
  847. SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4,
  848. sb_tx8_mux_text);
  849. static const struct snd_kcontrol_new rx_int0_2_mux =
  850. SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum);
  851. static const struct snd_kcontrol_new rx_int1_2_mux =
  852. SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum);
  853. static const struct snd_kcontrol_new rx_int2_2_mux =
  854. SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum);
  855. static const struct snd_kcontrol_new rx_int3_2_mux =
  856. SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum);
  857. static const struct snd_kcontrol_new rx_int4_2_mux =
  858. SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum);
  859. static const struct snd_kcontrol_new rx_int5_2_mux =
  860. SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum);
  861. static const struct snd_kcontrol_new rx_int6_2_mux =
  862. SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum);
  863. static const struct snd_kcontrol_new rx_int7_2_mux =
  864. SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum);
  865. static const struct snd_kcontrol_new rx_int8_2_mux =
  866. SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum);
  867. static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux =
  868. SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum);
  869. static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux =
  870. SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum);
  871. static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux =
  872. SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum);
  873. static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux =
  874. SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum);
  875. static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux =
  876. SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum);
  877. static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux =
  878. SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum);
  879. static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux =
  880. SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum);
  881. static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux =
  882. SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum);
  883. static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux =
  884. SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum);
  885. static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux =
  886. SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum);
  887. static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux =
  888. SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum);
  889. static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux =
  890. SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum);
  891. static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux =
  892. SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum);
  893. static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux =
  894. SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum);
  895. static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux =
  896. SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum);
  897. static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux =
  898. SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum);
  899. static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux =
  900. SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum);
  901. static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux =
  902. SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum);
  903. static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux =
  904. SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum);
  905. static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux =
  906. SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum);
  907. static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux =
  908. SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum);
  909. static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux =
  910. SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum);
  911. static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux =
  912. SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum);
  913. static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux =
  914. SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum);
  915. static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux =
  916. SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum);
  917. static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux =
  918. SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum);
  919. static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux =
  920. SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum);
  921. static const struct snd_kcontrol_new rx_int0_interp_mux =
  922. SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum);
  923. static const struct snd_kcontrol_new rx_int1_interp_mux =
  924. SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum);
  925. static const struct snd_kcontrol_new rx_int2_interp_mux =
  926. SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum);
  927. static const struct snd_kcontrol_new rx_int3_interp_mux =
  928. SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum);
  929. static const struct snd_kcontrol_new rx_int4_interp_mux =
  930. SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum);
  931. static const struct snd_kcontrol_new rx_int5_interp_mux =
  932. SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum);
  933. static const struct snd_kcontrol_new rx_int6_interp_mux =
  934. SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum);
  935. static const struct snd_kcontrol_new rx_int7_interp_mux =
  936. SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum);
  937. static const struct snd_kcontrol_new rx_int8_interp_mux =
  938. SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum);
  939. static const struct snd_kcontrol_new tx_dmic_mux0 =
  940. SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum);
  941. static const struct snd_kcontrol_new tx_dmic_mux1 =
  942. SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum);
  943. static const struct snd_kcontrol_new tx_dmic_mux2 =
  944. SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum);
  945. static const struct snd_kcontrol_new tx_dmic_mux3 =
  946. SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum);
  947. static const struct snd_kcontrol_new tx_dmic_mux4 =
  948. SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum);
  949. static const struct snd_kcontrol_new tx_dmic_mux5 =
  950. SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum);
  951. static const struct snd_kcontrol_new tx_dmic_mux6 =
  952. SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum);
  953. static const struct snd_kcontrol_new tx_dmic_mux7 =
  954. SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum);
  955. static const struct snd_kcontrol_new tx_dmic_mux8 =
  956. SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum);
  957. static const struct snd_kcontrol_new tx_amic_mux0 =
  958. SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum);
  959. static const struct snd_kcontrol_new tx_amic_mux1 =
  960. SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum);
  961. static const struct snd_kcontrol_new tx_amic_mux2 =
  962. SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum);
  963. static const struct snd_kcontrol_new tx_amic_mux3 =
  964. SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum);
  965. static const struct snd_kcontrol_new tx_amic_mux4 =
  966. SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum);
  967. static const struct snd_kcontrol_new tx_amic_mux5 =
  968. SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum);
  969. static const struct snd_kcontrol_new tx_amic_mux6 =
  970. SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum);
  971. static const struct snd_kcontrol_new tx_amic_mux7 =
  972. SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum);
  973. static const struct snd_kcontrol_new tx_amic_mux8 =
  974. SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum);
  975. static const struct snd_kcontrol_new sb_tx0_mux =
  976. SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum);
  977. static const struct snd_kcontrol_new sb_tx1_mux =
  978. SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum);
  979. static const struct snd_kcontrol_new sb_tx2_mux =
  980. SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum);
  981. static const struct snd_kcontrol_new sb_tx3_mux =
  982. SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum);
  983. static const struct snd_kcontrol_new sb_tx4_mux =
  984. SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum);
  985. static const struct snd_kcontrol_new sb_tx5_mux =
  986. SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
  987. static const struct snd_kcontrol_new sb_tx6_mux =
  988. SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum);
  989. static const struct snd_kcontrol_new sb_tx7_mux =
  990. SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum);
  991. static const struct snd_kcontrol_new sb_tx8_mux =
  992. SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum);
  993. static int slim_rx_mux_get(struct snd_kcontrol *kc,
  994. struct snd_ctl_elem_value *ucontrol)
  995. {
  996. struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
  997. struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
  998. u32 port_id = w->shift;
  999. ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id];
  1000. return 0;
  1001. }
  1002. static int slim_rx_mux_put(struct snd_kcontrol *kc,
  1003. struct snd_ctl_elem_value *ucontrol)
  1004. {
  1005. struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
  1006. struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
  1007. struct soc_enum *e = (struct soc_enum *)kc->private_value;
  1008. struct snd_soc_dapm_update *update = NULL;
  1009. u32 port_id = w->shift;
  1010. if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0])
  1011. return 0;
  1012. wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
  1013. /* Remove channel from any list it's in before adding it to a new one */
  1014. list_del_init(&wcd->rx_chs[port_id].list);
  1015. switch (wcd->rx_port_value[port_id]) {
  1016. case 0:
  1017. /* Channel already removed from lists. Nothing to do here */
  1018. break;
  1019. case 1:
  1020. list_add_tail(&wcd->rx_chs[port_id].list,
  1021. &wcd->dai[AIF1_PB].slim_ch_list);
  1022. break;
  1023. case 2:
  1024. list_add_tail(&wcd->rx_chs[port_id].list,
  1025. &wcd->dai[AIF2_PB].slim_ch_list);
  1026. break;
  1027. case 3:
  1028. list_add_tail(&wcd->rx_chs[port_id].list,
  1029. &wcd->dai[AIF3_PB].slim_ch_list);
  1030. break;
  1031. case 4:
  1032. list_add_tail(&wcd->rx_chs[port_id].list,
  1033. &wcd->dai[AIF4_PB].slim_ch_list);
  1034. break;
  1035. default:
  1036. dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value[port_id]);
  1037. goto err;
  1038. }
  1039. snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id],
  1040. e, update);
  1041. return 0;
  1042. err:
  1043. return -EINVAL;
  1044. }
  1045. static int slim_tx_mixer_get(struct snd_kcontrol *kc,
  1046. struct snd_ctl_elem_value *ucontrol)
  1047. {
  1048. struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
  1049. struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev);
  1050. struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc);
  1051. struct soc_mixer_control *mixer =
  1052. (struct soc_mixer_control *)kc->private_value;
  1053. int dai_id = widget->shift;
  1054. int port_id = mixer->shift;
  1055. ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id] == dai_id;
  1056. return 0;
  1057. }
  1058. static int slim_tx_mixer_put(struct snd_kcontrol *kc,
  1059. struct snd_ctl_elem_value *ucontrol)
  1060. {
  1061. struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc);
  1062. struct wcd9335_codec *wcd = dev_get_drvdata(widget->dapm->dev);
  1063. struct snd_soc_dapm_update *update = NULL;
  1064. struct soc_mixer_control *mixer =
  1065. (struct soc_mixer_control *)kc->private_value;
  1066. int enable = ucontrol->value.integer.value[0];
  1067. int dai_id = widget->shift;
  1068. int port_id = mixer->shift;
  1069. switch (dai_id) {
  1070. case AIF1_CAP:
  1071. case AIF2_CAP:
  1072. case AIF3_CAP:
  1073. /* only add to the list if value not set */
  1074. if (enable && wcd->tx_port_value[port_id] != dai_id) {
  1075. wcd->tx_port_value[port_id] = dai_id;
  1076. list_add_tail(&wcd->tx_chs[port_id].list,
  1077. &wcd->dai[dai_id].slim_ch_list);
  1078. } else if (!enable && wcd->tx_port_value[port_id] == dai_id) {
  1079. wcd->tx_port_value[port_id] = -1;
  1080. list_del_init(&wcd->tx_chs[port_id].list);
  1081. }
  1082. break;
  1083. default:
  1084. dev_err(wcd->dev, "Unknown AIF %d\n", dai_id);
  1085. return -EINVAL;
  1086. }
  1087. snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update);
  1088. return 0;
  1089. }
  1090. static const struct snd_kcontrol_new slim_rx_mux[WCD9335_RX_MAX] = {
  1091. SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum,
  1092. slim_rx_mux_get, slim_rx_mux_put),
  1093. SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum,
  1094. slim_rx_mux_get, slim_rx_mux_put),
  1095. SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum,
  1096. slim_rx_mux_get, slim_rx_mux_put),
  1097. SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum,
  1098. slim_rx_mux_get, slim_rx_mux_put),
  1099. SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum,
  1100. slim_rx_mux_get, slim_rx_mux_put),
  1101. SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum,
  1102. slim_rx_mux_get, slim_rx_mux_put),
  1103. SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum,
  1104. slim_rx_mux_get, slim_rx_mux_put),
  1105. SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum,
  1106. slim_rx_mux_get, slim_rx_mux_put),
  1107. };
  1108. static const struct snd_kcontrol_new aif1_cap_mixer[] = {
  1109. SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
  1110. slim_tx_mixer_get, slim_tx_mixer_put),
  1111. SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
  1112. slim_tx_mixer_get, slim_tx_mixer_put),
  1113. SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
  1114. slim_tx_mixer_get, slim_tx_mixer_put),
  1115. SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
  1116. slim_tx_mixer_get, slim_tx_mixer_put),
  1117. SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
  1118. slim_tx_mixer_get, slim_tx_mixer_put),
  1119. SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
  1120. slim_tx_mixer_get, slim_tx_mixer_put),
  1121. SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
  1122. slim_tx_mixer_get, slim_tx_mixer_put),
  1123. SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
  1124. slim_tx_mixer_get, slim_tx_mixer_put),
  1125. SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
  1126. slim_tx_mixer_get, slim_tx_mixer_put),
  1127. SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0,
  1128. slim_tx_mixer_get, slim_tx_mixer_put),
  1129. SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0,
  1130. slim_tx_mixer_get, slim_tx_mixer_put),
  1131. SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0,
  1132. slim_tx_mixer_get, slim_tx_mixer_put),
  1133. SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0,
  1134. slim_tx_mixer_get, slim_tx_mixer_put),
  1135. };
  1136. static const struct snd_kcontrol_new aif2_cap_mixer[] = {
  1137. SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
  1138. slim_tx_mixer_get, slim_tx_mixer_put),
  1139. SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
  1140. slim_tx_mixer_get, slim_tx_mixer_put),
  1141. SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
  1142. slim_tx_mixer_get, slim_tx_mixer_put),
  1143. SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
  1144. slim_tx_mixer_get, slim_tx_mixer_put),
  1145. SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
  1146. slim_tx_mixer_get, slim_tx_mixer_put),
  1147. SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
  1148. slim_tx_mixer_get, slim_tx_mixer_put),
  1149. SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
  1150. slim_tx_mixer_get, slim_tx_mixer_put),
  1151. SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
  1152. slim_tx_mixer_get, slim_tx_mixer_put),
  1153. SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
  1154. slim_tx_mixer_get, slim_tx_mixer_put),
  1155. SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0,
  1156. slim_tx_mixer_get, slim_tx_mixer_put),
  1157. SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0,
  1158. slim_tx_mixer_get, slim_tx_mixer_put),
  1159. SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0,
  1160. slim_tx_mixer_get, slim_tx_mixer_put),
  1161. SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0,
  1162. slim_tx_mixer_get, slim_tx_mixer_put),
  1163. };
  1164. static const struct snd_kcontrol_new aif3_cap_mixer[] = {
  1165. SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0,
  1166. slim_tx_mixer_get, slim_tx_mixer_put),
  1167. SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0,
  1168. slim_tx_mixer_get, slim_tx_mixer_put),
  1169. SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0,
  1170. slim_tx_mixer_get, slim_tx_mixer_put),
  1171. SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0,
  1172. slim_tx_mixer_get, slim_tx_mixer_put),
  1173. SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0,
  1174. slim_tx_mixer_get, slim_tx_mixer_put),
  1175. SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0,
  1176. slim_tx_mixer_get, slim_tx_mixer_put),
  1177. SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0,
  1178. slim_tx_mixer_get, slim_tx_mixer_put),
  1179. SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0,
  1180. slim_tx_mixer_get, slim_tx_mixer_put),
  1181. SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0,
  1182. slim_tx_mixer_get, slim_tx_mixer_put),
  1183. };
  1184. static int wcd9335_put_dec_enum(struct snd_kcontrol *kc,
  1185. struct snd_ctl_elem_value *ucontrol)
  1186. {
  1187. struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
  1188. struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
  1189. struct soc_enum *e = (struct soc_enum *)kc->private_value;
  1190. unsigned int val, reg, sel;
  1191. val = ucontrol->value.enumerated.item[0];
  1192. switch (e->reg) {
  1193. case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
  1194. reg = WCD9335_CDC_TX0_TX_PATH_CFG0;
  1195. break;
  1196. case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
  1197. reg = WCD9335_CDC_TX1_TX_PATH_CFG0;
  1198. break;
  1199. case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
  1200. reg = WCD9335_CDC_TX2_TX_PATH_CFG0;
  1201. break;
  1202. case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
  1203. reg = WCD9335_CDC_TX3_TX_PATH_CFG0;
  1204. break;
  1205. case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
  1206. reg = WCD9335_CDC_TX4_TX_PATH_CFG0;
  1207. break;
  1208. case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
  1209. reg = WCD9335_CDC_TX5_TX_PATH_CFG0;
  1210. break;
  1211. case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
  1212. reg = WCD9335_CDC_TX6_TX_PATH_CFG0;
  1213. break;
  1214. case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
  1215. reg = WCD9335_CDC_TX7_TX_PATH_CFG0;
  1216. break;
  1217. case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0:
  1218. reg = WCD9335_CDC_TX8_TX_PATH_CFG0;
  1219. break;
  1220. default:
  1221. return -EINVAL;
  1222. }
  1223. /* AMIC: 0, DMIC: 1 */
  1224. sel = val ? WCD9335_CDC_TX_ADC_AMIC_SEL : WCD9335_CDC_TX_ADC_DMIC_SEL;
  1225. snd_soc_component_update_bits(component, reg,
  1226. WCD9335_CDC_TX_ADC_AMIC_DMIC_SEL_MASK,
  1227. sel);
  1228. return snd_soc_dapm_put_enum_double(kc, ucontrol);
  1229. }
  1230. static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc,
  1231. struct snd_ctl_elem_value *ucontrol)
  1232. {
  1233. struct soc_enum *e = (struct soc_enum *)kc->private_value;
  1234. struct snd_soc_component *component;
  1235. int reg, val;
  1236. component = snd_soc_dapm_kcontrol_component(kc);
  1237. val = ucontrol->value.enumerated.item[0];
  1238. if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0)
  1239. reg = WCD9335_CDC_RX0_RX_PATH_CFG0;
  1240. else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0)
  1241. reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
  1242. else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0)
  1243. reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
  1244. else
  1245. return -EINVAL;
  1246. /* Set Look Ahead Delay */
  1247. snd_soc_component_update_bits(component, reg,
  1248. WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN_MASK,
  1249. val ? WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN : 0);
  1250. /* Set DEM INP Select */
  1251. return snd_soc_dapm_put_enum_double(kc, ucontrol);
  1252. }
  1253. static const struct snd_kcontrol_new rx_int0_dem_inp_mux =
  1254. SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum,
  1255. snd_soc_dapm_get_enum_double,
  1256. wcd9335_int_dem_inp_mux_put);
  1257. static const struct snd_kcontrol_new rx_int1_dem_inp_mux =
  1258. SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum,
  1259. snd_soc_dapm_get_enum_double,
  1260. wcd9335_int_dem_inp_mux_put);
  1261. static const struct snd_kcontrol_new rx_int2_dem_inp_mux =
  1262. SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum,
  1263. snd_soc_dapm_get_enum_double,
  1264. wcd9335_int_dem_inp_mux_put);
  1265. static const struct snd_kcontrol_new tx_adc_mux0 =
  1266. SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum,
  1267. snd_soc_dapm_get_enum_double,
  1268. wcd9335_put_dec_enum);
  1269. static const struct snd_kcontrol_new tx_adc_mux1 =
  1270. SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum,
  1271. snd_soc_dapm_get_enum_double,
  1272. wcd9335_put_dec_enum);
  1273. static const struct snd_kcontrol_new tx_adc_mux2 =
  1274. SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum,
  1275. snd_soc_dapm_get_enum_double,
  1276. wcd9335_put_dec_enum);
  1277. static const struct snd_kcontrol_new tx_adc_mux3 =
  1278. SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum,
  1279. snd_soc_dapm_get_enum_double,
  1280. wcd9335_put_dec_enum);
  1281. static const struct snd_kcontrol_new tx_adc_mux4 =
  1282. SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum,
  1283. snd_soc_dapm_get_enum_double,
  1284. wcd9335_put_dec_enum);
  1285. static const struct snd_kcontrol_new tx_adc_mux5 =
  1286. SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum,
  1287. snd_soc_dapm_get_enum_double,
  1288. wcd9335_put_dec_enum);
  1289. static const struct snd_kcontrol_new tx_adc_mux6 =
  1290. SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum,
  1291. snd_soc_dapm_get_enum_double,
  1292. wcd9335_put_dec_enum);
  1293. static const struct snd_kcontrol_new tx_adc_mux7 =
  1294. SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum,
  1295. snd_soc_dapm_get_enum_double,
  1296. wcd9335_put_dec_enum);
  1297. static const struct snd_kcontrol_new tx_adc_mux8 =
  1298. SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum,
  1299. snd_soc_dapm_get_enum_double,
  1300. wcd9335_put_dec_enum);
  1301. static int wcd9335_set_mix_interpolator_rate(struct snd_soc_dai *dai,
  1302. int rate_val,
  1303. u32 rate)
  1304. {
  1305. struct snd_soc_component *component = dai->component;
  1306. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  1307. struct wcd9335_slim_ch *ch;
  1308. int val, j;
  1309. list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
  1310. for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
  1311. val = snd_soc_component_read(component,
  1312. WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)) &
  1313. WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
  1314. if (val == (ch->shift + INTn_2_INP_SEL_RX0))
  1315. snd_soc_component_update_bits(component,
  1316. WCD9335_CDC_RX_PATH_MIX_CTL(j),
  1317. WCD9335_CDC_MIX_PCM_RATE_MASK,
  1318. rate_val);
  1319. }
  1320. }
  1321. return 0;
  1322. }
  1323. static int wcd9335_set_prim_interpolator_rate(struct snd_soc_dai *dai,
  1324. u8 rate_val,
  1325. u32 rate)
  1326. {
  1327. struct snd_soc_component *comp = dai->component;
  1328. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  1329. struct wcd9335_slim_ch *ch;
  1330. u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel;
  1331. int inp, j;
  1332. list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
  1333. inp = ch->shift + INTn_1_MIX_INP_SEL_RX0;
  1334. /*
  1335. * Loop through all interpolator MUX inputs and find out
  1336. * to which interpolator input, the slim rx port
  1337. * is connected
  1338. */
  1339. for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) {
  1340. cfg0 = snd_soc_component_read(comp,
  1341. WCD9335_CDC_RX_INP_MUX_RX_INT_CFG0(j));
  1342. cfg1 = snd_soc_component_read(comp,
  1343. WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j));
  1344. inp0_sel = cfg0 &
  1345. WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
  1346. inp1_sel = (cfg0 >> 4) &
  1347. WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
  1348. inp2_sel = (cfg1 >> 4) &
  1349. WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK;
  1350. if ((inp0_sel == inp) || (inp1_sel == inp) ||
  1351. (inp2_sel == inp)) {
  1352. /* rate is in Hz */
  1353. if ((j == 0) && (rate == 44100))
  1354. dev_info(wcd->dev,
  1355. "Cannot set 44.1KHz on INT0\n");
  1356. else
  1357. snd_soc_component_update_bits(comp,
  1358. WCD9335_CDC_RX_PATH_CTL(j),
  1359. WCD9335_CDC_MIX_PCM_RATE_MASK,
  1360. rate_val);
  1361. }
  1362. }
  1363. }
  1364. return 0;
  1365. }
  1366. static int wcd9335_set_interpolator_rate(struct snd_soc_dai *dai, u32 rate)
  1367. {
  1368. int i;
  1369. /* set mixing path rate */
  1370. for (i = 0; i < ARRAY_SIZE(int_mix_rate_val); i++) {
  1371. if (rate == int_mix_rate_val[i].rate) {
  1372. wcd9335_set_mix_interpolator_rate(dai,
  1373. int_mix_rate_val[i].rate_val, rate);
  1374. break;
  1375. }
  1376. }
  1377. /* set primary path sample rate */
  1378. for (i = 0; i < ARRAY_SIZE(int_prim_rate_val); i++) {
  1379. if (rate == int_prim_rate_val[i].rate) {
  1380. wcd9335_set_prim_interpolator_rate(dai,
  1381. int_prim_rate_val[i].rate_val, rate);
  1382. break;
  1383. }
  1384. }
  1385. return 0;
  1386. }
  1387. static int wcd9335_slim_set_hw_params(struct wcd9335_codec *wcd,
  1388. struct wcd_slim_codec_dai_data *dai_data,
  1389. int direction)
  1390. {
  1391. struct list_head *slim_ch_list = &dai_data->slim_ch_list;
  1392. struct slim_stream_config *cfg = &dai_data->sconfig;
  1393. struct wcd9335_slim_ch *ch;
  1394. u16 payload = 0;
  1395. int ret, i;
  1396. cfg->ch_count = 0;
  1397. cfg->direction = direction;
  1398. cfg->port_mask = 0;
  1399. /* Configure slave interface device */
  1400. list_for_each_entry(ch, slim_ch_list, list) {
  1401. cfg->ch_count++;
  1402. payload |= 1 << ch->shift;
  1403. cfg->port_mask |= BIT(ch->port);
  1404. }
  1405. cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL);
  1406. if (!cfg->chs)
  1407. return -ENOMEM;
  1408. i = 0;
  1409. list_for_each_entry(ch, slim_ch_list, list) {
  1410. cfg->chs[i++] = ch->ch_num;
  1411. if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
  1412. /* write to interface device */
  1413. ret = regmap_write(wcd->if_regmap,
  1414. WCD9335_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port),
  1415. payload);
  1416. if (ret < 0)
  1417. goto err;
  1418. /* configure the slave port for water mark and enable*/
  1419. ret = regmap_write(wcd->if_regmap,
  1420. WCD9335_SLIM_PGD_RX_PORT_CFG(ch->port),
  1421. WCD9335_SLIM_WATER_MARK_VAL);
  1422. if (ret < 0)
  1423. goto err;
  1424. } else {
  1425. ret = regmap_write(wcd->if_regmap,
  1426. WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port),
  1427. payload & 0x00FF);
  1428. if (ret < 0)
  1429. goto err;
  1430. /* ports 8,9 */
  1431. ret = regmap_write(wcd->if_regmap,
  1432. WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port),
  1433. (payload & 0xFF00)>>8);
  1434. if (ret < 0)
  1435. goto err;
  1436. /* configure the slave port for water mark and enable*/
  1437. ret = regmap_write(wcd->if_regmap,
  1438. WCD9335_SLIM_PGD_TX_PORT_CFG(ch->port),
  1439. WCD9335_SLIM_WATER_MARK_VAL);
  1440. if (ret < 0)
  1441. goto err;
  1442. }
  1443. }
  1444. dai_data->sruntime = slim_stream_allocate(wcd->slim, "WCD9335-SLIM");
  1445. return 0;
  1446. err:
  1447. dev_err(wcd->dev, "Error Setting slim hw params\n");
  1448. kfree(cfg->chs);
  1449. cfg->chs = NULL;
  1450. return ret;
  1451. }
  1452. static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai,
  1453. u8 rate_val, u32 rate)
  1454. {
  1455. struct snd_soc_component *comp = dai->component;
  1456. struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
  1457. u8 shift = 0, shift_val = 0, tx_mux_sel;
  1458. struct wcd9335_slim_ch *ch;
  1459. int tx_port, tx_port_reg;
  1460. int decimator = -1;
  1461. list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) {
  1462. tx_port = ch->port;
  1463. if ((tx_port == 12) || (tx_port >= 14)) {
  1464. dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n",
  1465. tx_port, dai->id);
  1466. return -EINVAL;
  1467. }
  1468. /* Find the SB TX MUX input - which decimator is connected */
  1469. if (tx_port < 4) {
  1470. tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0;
  1471. shift = (tx_port << 1);
  1472. shift_val = 0x03;
  1473. } else if (tx_port < 8) {
  1474. tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1;
  1475. shift = ((tx_port - 4) << 1);
  1476. shift_val = 0x03;
  1477. } else if (tx_port < 11) {
  1478. tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2;
  1479. shift = ((tx_port - 8) << 1);
  1480. shift_val = 0x03;
  1481. } else if (tx_port == 11) {
  1482. tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
  1483. shift = 0;
  1484. shift_val = 0x0F;
  1485. } else /* (tx_port == 13) */ {
  1486. tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3;
  1487. shift = 4;
  1488. shift_val = 0x03;
  1489. }
  1490. tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) &
  1491. (shift_val << shift);
  1492. tx_mux_sel = tx_mux_sel >> shift;
  1493. if (tx_port <= 8) {
  1494. if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
  1495. decimator = tx_port;
  1496. } else if (tx_port <= 10) {
  1497. if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
  1498. decimator = ((tx_port == 9) ? 7 : 6);
  1499. } else if (tx_port == 11) {
  1500. if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
  1501. decimator = tx_mux_sel - 1;
  1502. } else if (tx_port == 13) {
  1503. if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
  1504. decimator = 5;
  1505. }
  1506. if (decimator >= 0) {
  1507. snd_soc_component_update_bits(comp,
  1508. WCD9335_CDC_TX_PATH_CTL(decimator),
  1509. WCD9335_CDC_TX_PATH_CTL_PCM_RATE_MASK,
  1510. rate_val);
  1511. } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
  1512. /* Check if the TX Mux input is RX MIX TXn */
  1513. dev_err(wcd->dev, "RX_MIX_TX%u going to SLIM TX%u\n",
  1514. tx_port, tx_port);
  1515. } else {
  1516. dev_err(wcd->dev, "ERROR: Invalid decimator: %d\n",
  1517. decimator);
  1518. return -EINVAL;
  1519. }
  1520. }
  1521. return 0;
  1522. }
  1523. static int wcd9335_hw_params(struct snd_pcm_substream *substream,
  1524. struct snd_pcm_hw_params *params,
  1525. struct snd_soc_dai *dai)
  1526. {
  1527. struct wcd9335_codec *wcd;
  1528. int ret, tx_fs_rate = 0;
  1529. wcd = snd_soc_component_get_drvdata(dai->component);
  1530. switch (substream->stream) {
  1531. case SNDRV_PCM_STREAM_PLAYBACK:
  1532. ret = wcd9335_set_interpolator_rate(dai, params_rate(params));
  1533. if (ret) {
  1534. dev_err(wcd->dev, "cannot set sample rate: %u\n",
  1535. params_rate(params));
  1536. return ret;
  1537. }
  1538. switch (params_width(params)) {
  1539. case 16 ... 24:
  1540. wcd->dai[dai->id].sconfig.bps = params_width(params);
  1541. break;
  1542. default:
  1543. dev_err(wcd->dev, "%s: Invalid format 0x%x\n",
  1544. __func__, params_width(params));
  1545. return -EINVAL;
  1546. }
  1547. break;
  1548. case SNDRV_PCM_STREAM_CAPTURE:
  1549. switch (params_rate(params)) {
  1550. case 8000:
  1551. tx_fs_rate = 0;
  1552. break;
  1553. case 16000:
  1554. tx_fs_rate = 1;
  1555. break;
  1556. case 32000:
  1557. tx_fs_rate = 3;
  1558. break;
  1559. case 48000:
  1560. tx_fs_rate = 4;
  1561. break;
  1562. case 96000:
  1563. tx_fs_rate = 5;
  1564. break;
  1565. case 192000:
  1566. tx_fs_rate = 6;
  1567. break;
  1568. case 384000:
  1569. tx_fs_rate = 7;
  1570. break;
  1571. default:
  1572. dev_err(wcd->dev, "%s: Invalid TX sample rate: %d\n",
  1573. __func__, params_rate(params));
  1574. return -EINVAL;
  1575. }
  1576. ret = wcd9335_set_decimator_rate(dai, tx_fs_rate,
  1577. params_rate(params));
  1578. if (ret < 0) {
  1579. dev_err(wcd->dev, "Cannot set TX Decimator rate\n");
  1580. return ret;
  1581. }
  1582. switch (params_width(params)) {
  1583. case 16 ... 32:
  1584. wcd->dai[dai->id].sconfig.bps = params_width(params);
  1585. break;
  1586. default:
  1587. dev_err(wcd->dev, "%s: Invalid format 0x%x\n",
  1588. __func__, params_width(params));
  1589. return -EINVAL;
  1590. }
  1591. break;
  1592. default:
  1593. dev_err(wcd->dev, "Invalid stream type %d\n",
  1594. substream->stream);
  1595. return -EINVAL;
  1596. }
  1597. wcd->dai[dai->id].sconfig.rate = params_rate(params);
  1598. wcd9335_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream);
  1599. return 0;
  1600. }
  1601. static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
  1602. struct snd_soc_dai *dai)
  1603. {
  1604. struct wcd_slim_codec_dai_data *dai_data;
  1605. struct wcd9335_codec *wcd;
  1606. struct slim_stream_config *cfg;
  1607. wcd = snd_soc_component_get_drvdata(dai->component);
  1608. dai_data = &wcd->dai[dai->id];
  1609. switch (cmd) {
  1610. case SNDRV_PCM_TRIGGER_START:
  1611. case SNDRV_PCM_TRIGGER_RESUME:
  1612. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  1613. cfg = &dai_data->sconfig;
  1614. slim_stream_prepare(dai_data->sruntime, cfg);
  1615. slim_stream_enable(dai_data->sruntime);
  1616. break;
  1617. case SNDRV_PCM_TRIGGER_STOP:
  1618. case SNDRV_PCM_TRIGGER_SUSPEND:
  1619. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  1620. slim_stream_disable(dai_data->sruntime);
  1621. slim_stream_unprepare(dai_data->sruntime);
  1622. break;
  1623. default:
  1624. break;
  1625. }
  1626. return 0;
  1627. }
  1628. static int wcd9335_set_channel_map(struct snd_soc_dai *dai,
  1629. unsigned int tx_num, unsigned int *tx_slot,
  1630. unsigned int rx_num, unsigned int *rx_slot)
  1631. {
  1632. struct wcd9335_codec *wcd;
  1633. int i;
  1634. wcd = snd_soc_component_get_drvdata(dai->component);
  1635. if (!tx_slot || !rx_slot) {
  1636. dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n",
  1637. tx_slot, rx_slot);
  1638. return -EINVAL;
  1639. }
  1640. wcd->num_rx_port = rx_num;
  1641. for (i = 0; i < rx_num; i++) {
  1642. wcd->rx_chs[i].ch_num = rx_slot[i];
  1643. INIT_LIST_HEAD(&wcd->rx_chs[i].list);
  1644. }
  1645. wcd->num_tx_port = tx_num;
  1646. for (i = 0; i < tx_num; i++) {
  1647. wcd->tx_chs[i].ch_num = tx_slot[i];
  1648. INIT_LIST_HEAD(&wcd->tx_chs[i].list);
  1649. }
  1650. return 0;
  1651. }
  1652. static int wcd9335_get_channel_map(struct snd_soc_dai *dai,
  1653. unsigned int *tx_num, unsigned int *tx_slot,
  1654. unsigned int *rx_num, unsigned int *rx_slot)
  1655. {
  1656. struct wcd9335_slim_ch *ch;
  1657. struct wcd9335_codec *wcd;
  1658. int i = 0;
  1659. wcd = snd_soc_component_get_drvdata(dai->component);
  1660. switch (dai->id) {
  1661. case AIF1_PB:
  1662. case AIF2_PB:
  1663. case AIF3_PB:
  1664. case AIF4_PB:
  1665. if (!rx_slot || !rx_num) {
  1666. dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n",
  1667. rx_slot, rx_num);
  1668. return -EINVAL;
  1669. }
  1670. list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
  1671. rx_slot[i++] = ch->ch_num;
  1672. *rx_num = i;
  1673. break;
  1674. case AIF1_CAP:
  1675. case AIF2_CAP:
  1676. case AIF3_CAP:
  1677. if (!tx_slot || !tx_num) {
  1678. dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n",
  1679. tx_slot, tx_num);
  1680. return -EINVAL;
  1681. }
  1682. list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list)
  1683. tx_slot[i++] = ch->ch_num;
  1684. *tx_num = i;
  1685. break;
  1686. default:
  1687. dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id);
  1688. break;
  1689. }
  1690. return 0;
  1691. }
  1692. static const struct snd_soc_dai_ops wcd9335_dai_ops = {
  1693. .hw_params = wcd9335_hw_params,
  1694. .trigger = wcd9335_trigger,
  1695. .set_channel_map = wcd9335_set_channel_map,
  1696. .get_channel_map = wcd9335_get_channel_map,
  1697. };
  1698. static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
  1699. [0] = {
  1700. .name = "wcd9335_rx1",
  1701. .id = AIF1_PB,
  1702. .playback = {
  1703. .stream_name = "AIF1 Playback",
  1704. .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
  1705. SNDRV_PCM_RATE_384000,
  1706. .formats = WCD9335_FORMATS_S16_S24_LE,
  1707. .rate_max = 384000,
  1708. .rate_min = 8000,
  1709. .channels_min = 1,
  1710. .channels_max = 2,
  1711. },
  1712. .ops = &wcd9335_dai_ops,
  1713. },
  1714. [1] = {
  1715. .name = "wcd9335_tx1",
  1716. .id = AIF1_CAP,
  1717. .capture = {
  1718. .stream_name = "AIF1 Capture",
  1719. .rates = WCD9335_RATES_MASK,
  1720. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  1721. .rate_min = 8000,
  1722. .rate_max = 192000,
  1723. .channels_min = 1,
  1724. .channels_max = 4,
  1725. },
  1726. .ops = &wcd9335_dai_ops,
  1727. },
  1728. [2] = {
  1729. .name = "wcd9335_rx2",
  1730. .id = AIF2_PB,
  1731. .playback = {
  1732. .stream_name = "AIF2 Playback",
  1733. .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
  1734. SNDRV_PCM_RATE_384000,
  1735. .formats = WCD9335_FORMATS_S16_S24_LE,
  1736. .rate_min = 8000,
  1737. .rate_max = 384000,
  1738. .channels_min = 1,
  1739. .channels_max = 2,
  1740. },
  1741. .ops = &wcd9335_dai_ops,
  1742. },
  1743. [3] = {
  1744. .name = "wcd9335_tx2",
  1745. .id = AIF2_CAP,
  1746. .capture = {
  1747. .stream_name = "AIF2 Capture",
  1748. .rates = WCD9335_RATES_MASK,
  1749. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  1750. .rate_min = 8000,
  1751. .rate_max = 192000,
  1752. .channels_min = 1,
  1753. .channels_max = 4,
  1754. },
  1755. .ops = &wcd9335_dai_ops,
  1756. },
  1757. [4] = {
  1758. .name = "wcd9335_rx3",
  1759. .id = AIF3_PB,
  1760. .playback = {
  1761. .stream_name = "AIF3 Playback",
  1762. .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
  1763. SNDRV_PCM_RATE_384000,
  1764. .formats = WCD9335_FORMATS_S16_S24_LE,
  1765. .rate_min = 8000,
  1766. .rate_max = 384000,
  1767. .channels_min = 1,
  1768. .channels_max = 2,
  1769. },
  1770. .ops = &wcd9335_dai_ops,
  1771. },
  1772. [5] = {
  1773. .name = "wcd9335_tx3",
  1774. .id = AIF3_CAP,
  1775. .capture = {
  1776. .stream_name = "AIF3 Capture",
  1777. .rates = WCD9335_RATES_MASK,
  1778. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  1779. .rate_min = 8000,
  1780. .rate_max = 192000,
  1781. .channels_min = 1,
  1782. .channels_max = 4,
  1783. },
  1784. .ops = &wcd9335_dai_ops,
  1785. },
  1786. [6] = {
  1787. .name = "wcd9335_rx4",
  1788. .id = AIF4_PB,
  1789. .playback = {
  1790. .stream_name = "AIF4 Playback",
  1791. .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
  1792. SNDRV_PCM_RATE_384000,
  1793. .formats = WCD9335_FORMATS_S16_S24_LE,
  1794. .rate_min = 8000,
  1795. .rate_max = 384000,
  1796. .channels_min = 1,
  1797. .channels_max = 2,
  1798. },
  1799. .ops = &wcd9335_dai_ops,
  1800. },
  1801. };
  1802. static int wcd9335_get_compander(struct snd_kcontrol *kc,
  1803. struct snd_ctl_elem_value *ucontrol)
  1804. {
  1805. struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
  1806. int comp = ((struct soc_mixer_control *)kc->private_value)->shift;
  1807. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  1808. ucontrol->value.integer.value[0] = wcd->comp_enabled[comp];
  1809. return 0;
  1810. }
  1811. static int wcd9335_set_compander(struct snd_kcontrol *kc,
  1812. struct snd_ctl_elem_value *ucontrol)
  1813. {
  1814. struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
  1815. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  1816. int comp = ((struct soc_mixer_control *) kc->private_value)->shift;
  1817. int value = ucontrol->value.integer.value[0];
  1818. int sel;
  1819. wcd->comp_enabled[comp] = value;
  1820. sel = value ? WCD9335_HPH_GAIN_SRC_SEL_COMPANDER :
  1821. WCD9335_HPH_GAIN_SRC_SEL_REGISTER;
  1822. /* Any specific register configuration for compander */
  1823. switch (comp) {
  1824. case COMPANDER_1:
  1825. /* Set Gain Source Select based on compander enable/disable */
  1826. snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
  1827. WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
  1828. break;
  1829. case COMPANDER_2:
  1830. snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
  1831. WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
  1832. break;
  1833. case COMPANDER_5:
  1834. snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN,
  1835. WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
  1836. break;
  1837. case COMPANDER_6:
  1838. snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN,
  1839. WCD9335_HPH_GAIN_SRC_SEL_MASK, sel);
  1840. break;
  1841. default:
  1842. break;
  1843. }
  1844. return 0;
  1845. }
  1846. static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc,
  1847. struct snd_ctl_elem_value *ucontrol)
  1848. {
  1849. struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
  1850. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  1851. ucontrol->value.enumerated.item[0] = wcd->hph_mode;
  1852. return 0;
  1853. }
  1854. static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
  1855. struct snd_ctl_elem_value *ucontrol)
  1856. {
  1857. struct snd_soc_component *component = snd_soc_kcontrol_component(kc);
  1858. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  1859. u32 mode_val;
  1860. mode_val = ucontrol->value.enumerated.item[0];
  1861. if (mode_val == 0) {
  1862. dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n");
  1863. mode_val = CLS_H_HIFI;
  1864. }
  1865. wcd->hph_mode = mode_val;
  1866. return 0;
  1867. }
  1868. static const struct snd_kcontrol_new wcd9335_snd_controls[] = {
  1869. /* -84dB min - 40dB max */
  1870. SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
  1871. -84, 40, digital_gain),
  1872. SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
  1873. -84, 40, digital_gain),
  1874. SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
  1875. -84, 40, digital_gain),
  1876. SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
  1877. -84, 40, digital_gain),
  1878. SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
  1879. -84, 40, digital_gain),
  1880. SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
  1881. -84, 40, digital_gain),
  1882. SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
  1883. -84, 40, digital_gain),
  1884. SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
  1885. -84, 40, digital_gain),
  1886. SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
  1887. -84, 40, digital_gain),
  1888. SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
  1889. -84, 40, digital_gain),
  1890. SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
  1891. -84, 40, digital_gain),
  1892. SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
  1893. -84, 40, digital_gain),
  1894. SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
  1895. -84, 40, digital_gain),
  1896. SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
  1897. -84, 40, digital_gain),
  1898. SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
  1899. -84, 40, digital_gain),
  1900. SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
  1901. -84, 40, digital_gain),
  1902. SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
  1903. -84, 40, digital_gain),
  1904. SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
  1905. -84, 40, digital_gain),
  1906. SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
  1907. SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
  1908. SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
  1909. SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
  1910. SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
  1911. SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
  1912. SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
  1913. SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
  1914. SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
  1915. SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
  1916. SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
  1917. SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
  1918. SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
  1919. SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
  1920. SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
  1921. SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
  1922. SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
  1923. SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
  1924. SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
  1925. wcd9335_get_compander, wcd9335_set_compander),
  1926. SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
  1927. wcd9335_get_compander, wcd9335_set_compander),
  1928. SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0,
  1929. wcd9335_get_compander, wcd9335_set_compander),
  1930. SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0,
  1931. wcd9335_get_compander, wcd9335_set_compander),
  1932. SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0,
  1933. wcd9335_get_compander, wcd9335_set_compander),
  1934. SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0,
  1935. wcd9335_get_compander, wcd9335_set_compander),
  1936. SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
  1937. wcd9335_get_compander, wcd9335_set_compander),
  1938. SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
  1939. wcd9335_get_compander, wcd9335_set_compander),
  1940. SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
  1941. wcd9335_rx_hph_mode_get, wcd9335_rx_hph_mode_put),
  1942. /* Gain Controls */
  1943. SOC_SINGLE_TLV("EAR PA Volume", WCD9335_ANA_EAR, 4, 4, 1,
  1944. ear_pa_gain),
  1945. SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1,
  1946. line_gain),
  1947. SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
  1948. line_gain),
  1949. SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
  1950. 3, 16, 1, line_gain),
  1951. SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
  1952. 3, 16, 1, line_gain),
  1953. SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
  1954. line_gain),
  1955. SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
  1956. line_gain),
  1957. SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
  1958. analog_gain),
  1959. SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0,
  1960. analog_gain),
  1961. SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0,
  1962. analog_gain),
  1963. SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0,
  1964. analog_gain),
  1965. SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0,
  1966. analog_gain),
  1967. SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0,
  1968. analog_gain),
  1969. SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
  1970. SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
  1971. SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
  1972. SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
  1973. SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
  1974. SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
  1975. SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
  1976. SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
  1977. SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
  1978. };
  1979. static const struct snd_soc_dapm_route wcd9335_audio_map[] = {
  1980. {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
  1981. {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
  1982. {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
  1983. {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
  1984. {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
  1985. {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
  1986. {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
  1987. {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
  1988. {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
  1989. {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
  1990. {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
  1991. {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
  1992. {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
  1993. {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
  1994. {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
  1995. {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
  1996. {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
  1997. {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
  1998. {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
  1999. {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
  2000. {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
  2001. {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
  2002. {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
  2003. {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
  2004. {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
  2005. {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
  2006. {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
  2007. {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
  2008. {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
  2009. {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
  2010. {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
  2011. {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
  2012. {"SLIM RX0", NULL, "SLIM RX0 MUX"},
  2013. {"SLIM RX1", NULL, "SLIM RX1 MUX"},
  2014. {"SLIM RX2", NULL, "SLIM RX2 MUX"},
  2015. {"SLIM RX3", NULL, "SLIM RX3 MUX"},
  2016. {"SLIM RX4", NULL, "SLIM RX4 MUX"},
  2017. {"SLIM RX5", NULL, "SLIM RX5 MUX"},
  2018. {"SLIM RX6", NULL, "SLIM RX6 MUX"},
  2019. {"SLIM RX7", NULL, "SLIM RX7 MUX"},
  2020. WCD9335_INTERPOLATOR_PATH(0),
  2021. WCD9335_INTERPOLATOR_PATH(1),
  2022. WCD9335_INTERPOLATOR_PATH(2),
  2023. WCD9335_INTERPOLATOR_PATH(3),
  2024. WCD9335_INTERPOLATOR_PATH(4),
  2025. WCD9335_INTERPOLATOR_PATH(5),
  2026. WCD9335_INTERPOLATOR_PATH(6),
  2027. WCD9335_INTERPOLATOR_PATH(7),
  2028. WCD9335_INTERPOLATOR_PATH(8),
  2029. /* EAR PA */
  2030. {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"},
  2031. {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
  2032. {"RX INT0 DAC", NULL, "RX_BIAS"},
  2033. {"EAR PA", NULL, "RX INT0 DAC"},
  2034. {"EAR", NULL, "EAR PA"},
  2035. /* HPHL */
  2036. {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"},
  2037. {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"},
  2038. {"RX INT1 DAC", NULL, "RX_BIAS"},
  2039. {"HPHL PA", NULL, "RX INT1 DAC"},
  2040. {"HPHL", NULL, "HPHL PA"},
  2041. /* HPHR */
  2042. {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"},
  2043. {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"},
  2044. {"RX INT2 DAC", NULL, "RX_BIAS"},
  2045. {"HPHR PA", NULL, "RX INT2 DAC"},
  2046. {"HPHR", NULL, "HPHR PA"},
  2047. /* LINEOUT1 */
  2048. {"RX INT3 DAC", NULL, "RX INT3 INTERP"},
  2049. {"RX INT3 DAC", NULL, "RX_BIAS"},
  2050. {"LINEOUT1 PA", NULL, "RX INT3 DAC"},
  2051. {"LINEOUT1", NULL, "LINEOUT1 PA"},
  2052. /* LINEOUT2 */
  2053. {"RX INT4 DAC", NULL, "RX INT4 INTERP"},
  2054. {"RX INT4 DAC", NULL, "RX_BIAS"},
  2055. {"LINEOUT2 PA", NULL, "RX INT4 DAC"},
  2056. {"LINEOUT2", NULL, "LINEOUT2 PA"},
  2057. /* LINEOUT3 */
  2058. {"RX INT5 DAC", NULL, "RX INT5 INTERP"},
  2059. {"RX INT5 DAC", NULL, "RX_BIAS"},
  2060. {"LINEOUT3 PA", NULL, "RX INT5 DAC"},
  2061. {"LINEOUT3", NULL, "LINEOUT3 PA"},
  2062. /* LINEOUT4 */
  2063. {"RX INT6 DAC", NULL, "RX INT6 INTERP"},
  2064. {"RX INT6 DAC", NULL, "RX_BIAS"},
  2065. {"LINEOUT4 PA", NULL, "RX INT6 DAC"},
  2066. {"LINEOUT4", NULL, "LINEOUT4 PA"},
  2067. /* SLIMBUS Connections */
  2068. {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
  2069. {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
  2070. {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
  2071. /* ADC Mux */
  2072. WCD9335_ADC_MUX_PATH(0),
  2073. WCD9335_ADC_MUX_PATH(1),
  2074. WCD9335_ADC_MUX_PATH(2),
  2075. WCD9335_ADC_MUX_PATH(3),
  2076. WCD9335_ADC_MUX_PATH(4),
  2077. WCD9335_ADC_MUX_PATH(5),
  2078. WCD9335_ADC_MUX_PATH(6),
  2079. WCD9335_ADC_MUX_PATH(7),
  2080. WCD9335_ADC_MUX_PATH(8),
  2081. /* ADC Connections */
  2082. {"ADC1", NULL, "AMIC1"},
  2083. {"ADC2", NULL, "AMIC2"},
  2084. {"ADC3", NULL, "AMIC3"},
  2085. {"ADC4", NULL, "AMIC4"},
  2086. {"ADC5", NULL, "AMIC5"},
  2087. {"ADC6", NULL, "AMIC6"},
  2088. };
  2089. static int wcd9335_micbias_control(struct snd_soc_component *component,
  2090. int micb_num, int req, bool is_dapm)
  2091. {
  2092. struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(component);
  2093. int micb_index = micb_num - 1;
  2094. u16 micb_reg;
  2095. if ((micb_index < 0) || (micb_index > WCD9335_MAX_MICBIAS - 1)) {
  2096. dev_err(wcd->dev, "Invalid micbias index, micb_ind:%d\n",
  2097. micb_index);
  2098. return -EINVAL;
  2099. }
  2100. switch (micb_num) {
  2101. case MIC_BIAS_1:
  2102. micb_reg = WCD9335_ANA_MICB1;
  2103. break;
  2104. case MIC_BIAS_2:
  2105. micb_reg = WCD9335_ANA_MICB2;
  2106. break;
  2107. case MIC_BIAS_3:
  2108. micb_reg = WCD9335_ANA_MICB3;
  2109. break;
  2110. case MIC_BIAS_4:
  2111. micb_reg = WCD9335_ANA_MICB4;
  2112. break;
  2113. default:
  2114. dev_err(component->dev, "%s: Invalid micbias number: %d\n",
  2115. __func__, micb_num);
  2116. return -EINVAL;
  2117. }
  2118. switch (req) {
  2119. case MICB_PULLUP_ENABLE:
  2120. wcd->pullup_ref[micb_index]++;
  2121. if ((wcd->pullup_ref[micb_index] == 1) &&
  2122. (wcd->micb_ref[micb_index] == 0))
  2123. snd_soc_component_update_bits(component, micb_reg,
  2124. 0xC0, 0x80);
  2125. break;
  2126. case MICB_PULLUP_DISABLE:
  2127. wcd->pullup_ref[micb_index]--;
  2128. if ((wcd->pullup_ref[micb_index] == 0) &&
  2129. (wcd->micb_ref[micb_index] == 0))
  2130. snd_soc_component_update_bits(component, micb_reg,
  2131. 0xC0, 0x00);
  2132. break;
  2133. case MICB_ENABLE:
  2134. wcd->micb_ref[micb_index]++;
  2135. if (wcd->micb_ref[micb_index] == 1)
  2136. snd_soc_component_update_bits(component, micb_reg,
  2137. 0xC0, 0x40);
  2138. break;
  2139. case MICB_DISABLE:
  2140. wcd->micb_ref[micb_index]--;
  2141. if ((wcd->micb_ref[micb_index] == 0) &&
  2142. (wcd->pullup_ref[micb_index] > 0))
  2143. snd_soc_component_update_bits(component, micb_reg,
  2144. 0xC0, 0x80);
  2145. else if ((wcd->micb_ref[micb_index] == 0) &&
  2146. (wcd->pullup_ref[micb_index] == 0)) {
  2147. snd_soc_component_update_bits(component, micb_reg,
  2148. 0xC0, 0x00);
  2149. }
  2150. break;
  2151. }
  2152. return 0;
  2153. }
  2154. static int __wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w,
  2155. int event)
  2156. {
  2157. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2158. int micb_num;
  2159. if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
  2160. micb_num = MIC_BIAS_1;
  2161. else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
  2162. micb_num = MIC_BIAS_2;
  2163. else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
  2164. micb_num = MIC_BIAS_3;
  2165. else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
  2166. micb_num = MIC_BIAS_4;
  2167. else
  2168. return -EINVAL;
  2169. switch (event) {
  2170. case SND_SOC_DAPM_PRE_PMU:
  2171. /*
  2172. * MIC BIAS can also be requested by MBHC,
  2173. * so use ref count to handle micbias pullup
  2174. * and enable requests
  2175. */
  2176. wcd9335_micbias_control(comp, micb_num, MICB_ENABLE, true);
  2177. break;
  2178. case SND_SOC_DAPM_POST_PMU:
  2179. /* wait for cnp time */
  2180. usleep_range(1000, 1100);
  2181. break;
  2182. case SND_SOC_DAPM_POST_PMD:
  2183. wcd9335_micbias_control(comp, micb_num, MICB_DISABLE, true);
  2184. break;
  2185. }
  2186. return 0;
  2187. }
  2188. static int wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w,
  2189. struct snd_kcontrol *kc, int event)
  2190. {
  2191. return __wcd9335_codec_enable_micbias(w, event);
  2192. }
  2193. static void wcd9335_codec_set_tx_hold(struct snd_soc_component *comp,
  2194. u16 amic_reg, bool set)
  2195. {
  2196. u8 mask = 0x20;
  2197. u8 val;
  2198. if (amic_reg == WCD9335_ANA_AMIC1 || amic_reg == WCD9335_ANA_AMIC3 ||
  2199. amic_reg == WCD9335_ANA_AMIC5)
  2200. mask = 0x40;
  2201. val = set ? mask : 0x00;
  2202. switch (amic_reg) {
  2203. case WCD9335_ANA_AMIC1:
  2204. case WCD9335_ANA_AMIC2:
  2205. snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC2, mask,
  2206. val);
  2207. break;
  2208. case WCD9335_ANA_AMIC3:
  2209. case WCD9335_ANA_AMIC4:
  2210. snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC4, mask,
  2211. val);
  2212. break;
  2213. case WCD9335_ANA_AMIC5:
  2214. case WCD9335_ANA_AMIC6:
  2215. snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC6, mask,
  2216. val);
  2217. break;
  2218. default:
  2219. dev_err(comp->dev, "%s: invalid amic: %d\n",
  2220. __func__, amic_reg);
  2221. break;
  2222. }
  2223. }
  2224. static int wcd9335_codec_enable_adc(struct snd_soc_dapm_widget *w,
  2225. struct snd_kcontrol *kc, int event)
  2226. {
  2227. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2228. switch (event) {
  2229. case SND_SOC_DAPM_PRE_PMU:
  2230. wcd9335_codec_set_tx_hold(comp, w->reg, true);
  2231. break;
  2232. default:
  2233. break;
  2234. }
  2235. return 0;
  2236. }
  2237. static int wcd9335_codec_find_amic_input(struct snd_soc_component *comp,
  2238. int adc_mux_n)
  2239. {
  2240. int mux_sel, reg, mreg;
  2241. if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX ||
  2242. adc_mux_n == WCD9335_INVALID_ADC_MUX)
  2243. return 0;
  2244. /* Check whether adc mux input is AMIC or DMIC */
  2245. if (adc_mux_n < 4) {
  2246. reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + 2 * adc_mux_n;
  2247. mreg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + 2 * adc_mux_n;
  2248. mux_sel = snd_soc_component_read(comp, reg) & 0x3;
  2249. } else {
  2250. reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + adc_mux_n - 4;
  2251. mreg = reg;
  2252. mux_sel = snd_soc_component_read(comp, reg) >> 6;
  2253. }
  2254. if (mux_sel != WCD9335_CDC_TX_INP_MUX_SEL_AMIC)
  2255. return 0;
  2256. return snd_soc_component_read(comp, mreg) & 0x07;
  2257. }
  2258. static u16 wcd9335_codec_get_amic_pwlvl_reg(struct snd_soc_component *comp,
  2259. int amic)
  2260. {
  2261. u16 pwr_level_reg = 0;
  2262. switch (amic) {
  2263. case 1:
  2264. case 2:
  2265. pwr_level_reg = WCD9335_ANA_AMIC1;
  2266. break;
  2267. case 3:
  2268. case 4:
  2269. pwr_level_reg = WCD9335_ANA_AMIC3;
  2270. break;
  2271. case 5:
  2272. case 6:
  2273. pwr_level_reg = WCD9335_ANA_AMIC5;
  2274. break;
  2275. default:
  2276. dev_err(comp->dev, "invalid amic: %d\n", amic);
  2277. break;
  2278. }
  2279. return pwr_level_reg;
  2280. }
  2281. static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
  2282. struct snd_kcontrol *kc, int event)
  2283. {
  2284. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2285. unsigned int decimator;
  2286. char *dec_adc_mux_name = NULL;
  2287. char *widget_name = NULL;
  2288. char *wname;
  2289. int ret = 0, amic_n;
  2290. u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
  2291. u16 tx_gain_ctl_reg;
  2292. char *dec;
  2293. u8 hpf_coff_freq;
  2294. widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL);
  2295. if (!widget_name)
  2296. return -ENOMEM;
  2297. wname = widget_name;
  2298. dec_adc_mux_name = strsep(&widget_name, " ");
  2299. if (!dec_adc_mux_name) {
  2300. dev_err(comp->dev, "%s: Invalid decimator = %s\n",
  2301. __func__, w->name);
  2302. ret = -EINVAL;
  2303. goto out;
  2304. }
  2305. dec_adc_mux_name = widget_name;
  2306. dec = strpbrk(dec_adc_mux_name, "012345678");
  2307. if (!dec) {
  2308. dev_err(comp->dev, "%s: decimator index not found\n",
  2309. __func__);
  2310. ret = -EINVAL;
  2311. goto out;
  2312. }
  2313. ret = kstrtouint(dec, 10, &decimator);
  2314. if (ret < 0) {
  2315. dev_err(comp->dev, "%s: Invalid decimator = %s\n",
  2316. __func__, wname);
  2317. ret = -EINVAL;
  2318. goto out;
  2319. }
  2320. tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator;
  2321. hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
  2322. dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
  2323. tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator;
  2324. switch (event) {
  2325. case SND_SOC_DAPM_PRE_PMU:
  2326. amic_n = wcd9335_codec_find_amic_input(comp, decimator);
  2327. if (amic_n)
  2328. pwr_level_reg = wcd9335_codec_get_amic_pwlvl_reg(comp,
  2329. amic_n);
  2330. if (pwr_level_reg) {
  2331. switch ((snd_soc_component_read(comp, pwr_level_reg) &
  2332. WCD9335_AMIC_PWR_LVL_MASK) >>
  2333. WCD9335_AMIC_PWR_LVL_SHIFT) {
  2334. case WCD9335_AMIC_PWR_LEVEL_LP:
  2335. snd_soc_component_update_bits(comp, dec_cfg_reg,
  2336. WCD9335_DEC_PWR_LVL_MASK,
  2337. WCD9335_DEC_PWR_LVL_LP);
  2338. break;
  2339. case WCD9335_AMIC_PWR_LEVEL_HP:
  2340. snd_soc_component_update_bits(comp, dec_cfg_reg,
  2341. WCD9335_DEC_PWR_LVL_MASK,
  2342. WCD9335_DEC_PWR_LVL_HP);
  2343. break;
  2344. case WCD9335_AMIC_PWR_LEVEL_DEFAULT:
  2345. default:
  2346. snd_soc_component_update_bits(comp, dec_cfg_reg,
  2347. WCD9335_DEC_PWR_LVL_MASK,
  2348. WCD9335_DEC_PWR_LVL_DF);
  2349. break;
  2350. }
  2351. }
  2352. hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
  2353. TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
  2354. if (hpf_coff_freq != CF_MIN_3DB_150HZ)
  2355. snd_soc_component_update_bits(comp, dec_cfg_reg,
  2356. TX_HPF_CUT_OFF_FREQ_MASK,
  2357. CF_MIN_3DB_150HZ << 5);
  2358. /* Enable TX PGA Mute */
  2359. snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
  2360. 0x10, 0x10);
  2361. /* Enable APC */
  2362. snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x08);
  2363. break;
  2364. case SND_SOC_DAPM_POST_PMU:
  2365. snd_soc_component_update_bits(comp, hpf_gate_reg, 0x01, 0x00);
  2366. if (decimator == 0) {
  2367. snd_soc_component_write(comp,
  2368. WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
  2369. snd_soc_component_write(comp,
  2370. WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3);
  2371. snd_soc_component_write(comp,
  2372. WCD9335_MBHC_ZDET_RAMP_CTL, 0x83);
  2373. snd_soc_component_write(comp,
  2374. WCD9335_MBHC_ZDET_RAMP_CTL, 0x03);
  2375. }
  2376. snd_soc_component_update_bits(comp, hpf_gate_reg,
  2377. 0x01, 0x01);
  2378. snd_soc_component_update_bits(comp, tx_vol_ctl_reg,
  2379. 0x10, 0x00);
  2380. snd_soc_component_write(comp, tx_gain_ctl_reg,
  2381. snd_soc_component_read(comp, tx_gain_ctl_reg));
  2382. break;
  2383. case SND_SOC_DAPM_PRE_PMD:
  2384. hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) &
  2385. TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
  2386. snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x10);
  2387. snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x00);
  2388. if (hpf_coff_freq != CF_MIN_3DB_150HZ) {
  2389. snd_soc_component_update_bits(comp, dec_cfg_reg,
  2390. TX_HPF_CUT_OFF_FREQ_MASK,
  2391. hpf_coff_freq << 5);
  2392. }
  2393. break;
  2394. case SND_SOC_DAPM_POST_PMD:
  2395. snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x00);
  2396. break;
  2397. }
  2398. out:
  2399. kfree(wname);
  2400. return ret;
  2401. }
  2402. static u8 wcd9335_get_dmic_clk_val(struct snd_soc_component *component,
  2403. u32 mclk_rate, u32 dmic_clk_rate)
  2404. {
  2405. u32 div_factor;
  2406. u8 dmic_ctl_val;
  2407. dev_err(component->dev,
  2408. "%s: mclk_rate = %d, dmic_sample_rate = %d\n",
  2409. __func__, mclk_rate, dmic_clk_rate);
  2410. /* Default value to return in case of error */
  2411. if (mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
  2412. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
  2413. else
  2414. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
  2415. if (dmic_clk_rate == 0) {
  2416. dev_err(component->dev,
  2417. "%s: dmic_sample_rate cannot be 0\n",
  2418. __func__);
  2419. goto done;
  2420. }
  2421. div_factor = mclk_rate / dmic_clk_rate;
  2422. switch (div_factor) {
  2423. case 2:
  2424. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2;
  2425. break;
  2426. case 3:
  2427. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3;
  2428. break;
  2429. case 4:
  2430. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4;
  2431. break;
  2432. case 6:
  2433. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6;
  2434. break;
  2435. case 8:
  2436. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8;
  2437. break;
  2438. case 16:
  2439. dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16;
  2440. break;
  2441. default:
  2442. dev_err(component->dev,
  2443. "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n",
  2444. __func__, div_factor, mclk_rate, dmic_clk_rate);
  2445. break;
  2446. }
  2447. done:
  2448. return dmic_ctl_val;
  2449. }
  2450. static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w,
  2451. struct snd_kcontrol *kc, int event)
  2452. {
  2453. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2454. struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
  2455. u8 dmic_clk_en = 0x01;
  2456. u16 dmic_clk_reg;
  2457. s32 *dmic_clk_cnt;
  2458. u8 dmic_rate_val, dmic_rate_shift = 1;
  2459. unsigned int dmic;
  2460. int ret;
  2461. char *wname;
  2462. wname = strpbrk(w->name, "012345");
  2463. if (!wname) {
  2464. dev_err(comp->dev, "%s: widget not found\n", __func__);
  2465. return -EINVAL;
  2466. }
  2467. ret = kstrtouint(wname, 10, &dmic);
  2468. if (ret < 0) {
  2469. dev_err(comp->dev, "%s: Invalid DMIC line on the codec\n",
  2470. __func__);
  2471. return -EINVAL;
  2472. }
  2473. switch (dmic) {
  2474. case 0:
  2475. case 1:
  2476. dmic_clk_cnt = &(wcd->dmic_0_1_clk_cnt);
  2477. dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL;
  2478. break;
  2479. case 2:
  2480. case 3:
  2481. dmic_clk_cnt = &(wcd->dmic_2_3_clk_cnt);
  2482. dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL;
  2483. break;
  2484. case 4:
  2485. case 5:
  2486. dmic_clk_cnt = &(wcd->dmic_4_5_clk_cnt);
  2487. dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL;
  2488. break;
  2489. default:
  2490. dev_err(comp->dev, "%s: Invalid DMIC Selection\n",
  2491. __func__);
  2492. return -EINVAL;
  2493. }
  2494. switch (event) {
  2495. case SND_SOC_DAPM_PRE_PMU:
  2496. dmic_rate_val =
  2497. wcd9335_get_dmic_clk_val(comp,
  2498. wcd->mclk_rate,
  2499. wcd->dmic_sample_rate);
  2500. (*dmic_clk_cnt)++;
  2501. if (*dmic_clk_cnt == 1) {
  2502. snd_soc_component_update_bits(comp, dmic_clk_reg,
  2503. 0x07 << dmic_rate_shift,
  2504. dmic_rate_val << dmic_rate_shift);
  2505. snd_soc_component_update_bits(comp, dmic_clk_reg,
  2506. dmic_clk_en, dmic_clk_en);
  2507. }
  2508. break;
  2509. case SND_SOC_DAPM_POST_PMD:
  2510. dmic_rate_val =
  2511. wcd9335_get_dmic_clk_val(comp,
  2512. wcd->mclk_rate,
  2513. wcd->mad_dmic_sample_rate);
  2514. (*dmic_clk_cnt)--;
  2515. if (*dmic_clk_cnt == 0) {
  2516. snd_soc_component_update_bits(comp, dmic_clk_reg,
  2517. dmic_clk_en, 0);
  2518. snd_soc_component_update_bits(comp, dmic_clk_reg,
  2519. 0x07 << dmic_rate_shift,
  2520. dmic_rate_val << dmic_rate_shift);
  2521. }
  2522. break;
  2523. }
  2524. return 0;
  2525. }
  2526. static void wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai,
  2527. struct snd_soc_component *component)
  2528. {
  2529. int port_num = 0;
  2530. unsigned short reg = 0;
  2531. unsigned int val = 0;
  2532. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  2533. struct wcd9335_slim_ch *ch;
  2534. list_for_each_entry(ch, &dai->slim_ch_list, list) {
  2535. if (ch->port >= WCD9335_RX_START) {
  2536. port_num = ch->port - WCD9335_RX_START;
  2537. reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
  2538. } else {
  2539. port_num = ch->port;
  2540. reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
  2541. }
  2542. regmap_read(wcd->if_regmap, reg, &val);
  2543. if (!(val & BIT(port_num % 8)))
  2544. regmap_write(wcd->if_regmap, reg,
  2545. val | BIT(port_num % 8));
  2546. }
  2547. }
  2548. static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w,
  2549. struct snd_kcontrol *kc,
  2550. int event)
  2551. {
  2552. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2553. struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
  2554. struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift];
  2555. switch (event) {
  2556. case SND_SOC_DAPM_POST_PMU:
  2557. wcd9335_codec_enable_int_port(dai, comp);
  2558. break;
  2559. case SND_SOC_DAPM_POST_PMD:
  2560. kfree(dai->sconfig.chs);
  2561. break;
  2562. }
  2563. return 0;
  2564. }
  2565. static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
  2566. struct snd_kcontrol *kc, int event)
  2567. {
  2568. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2569. u16 gain_reg;
  2570. int offset_val = 0;
  2571. int val = 0;
  2572. switch (w->reg) {
  2573. case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
  2574. gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL;
  2575. break;
  2576. case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
  2577. gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL;
  2578. break;
  2579. case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
  2580. gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL;
  2581. break;
  2582. case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
  2583. gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL;
  2584. break;
  2585. case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
  2586. gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL;
  2587. break;
  2588. case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
  2589. gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL;
  2590. break;
  2591. case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
  2592. gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL;
  2593. break;
  2594. case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
  2595. gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL;
  2596. break;
  2597. case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
  2598. gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL;
  2599. break;
  2600. default:
  2601. dev_err(comp->dev, "%s: No gain register avail for %s\n",
  2602. __func__, w->name);
  2603. return 0;
  2604. }
  2605. switch (event) {
  2606. case SND_SOC_DAPM_POST_PMU:
  2607. val = snd_soc_component_read(comp, gain_reg);
  2608. val += offset_val;
  2609. snd_soc_component_write(comp, gain_reg, val);
  2610. break;
  2611. case SND_SOC_DAPM_POST_PMD:
  2612. break;
  2613. }
  2614. return 0;
  2615. }
  2616. static u16 wcd9335_interp_get_primary_reg(u16 reg, u16 *ind)
  2617. {
  2618. u16 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
  2619. switch (reg) {
  2620. case WCD9335_CDC_RX0_RX_PATH_CTL:
  2621. case WCD9335_CDC_RX0_RX_PATH_MIX_CTL:
  2622. prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL;
  2623. *ind = 0;
  2624. break;
  2625. case WCD9335_CDC_RX1_RX_PATH_CTL:
  2626. case WCD9335_CDC_RX1_RX_PATH_MIX_CTL:
  2627. prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL;
  2628. *ind = 1;
  2629. break;
  2630. case WCD9335_CDC_RX2_RX_PATH_CTL:
  2631. case WCD9335_CDC_RX2_RX_PATH_MIX_CTL:
  2632. prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL;
  2633. *ind = 2;
  2634. break;
  2635. case WCD9335_CDC_RX3_RX_PATH_CTL:
  2636. case WCD9335_CDC_RX3_RX_PATH_MIX_CTL:
  2637. prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
  2638. *ind = 3;
  2639. break;
  2640. case WCD9335_CDC_RX4_RX_PATH_CTL:
  2641. case WCD9335_CDC_RX4_RX_PATH_MIX_CTL:
  2642. prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
  2643. *ind = 4;
  2644. break;
  2645. case WCD9335_CDC_RX5_RX_PATH_CTL:
  2646. case WCD9335_CDC_RX5_RX_PATH_MIX_CTL:
  2647. prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
  2648. *ind = 5;
  2649. break;
  2650. case WCD9335_CDC_RX6_RX_PATH_CTL:
  2651. case WCD9335_CDC_RX6_RX_PATH_MIX_CTL:
  2652. prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
  2653. *ind = 6;
  2654. break;
  2655. case WCD9335_CDC_RX7_RX_PATH_CTL:
  2656. case WCD9335_CDC_RX7_RX_PATH_MIX_CTL:
  2657. prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL;
  2658. *ind = 7;
  2659. break;
  2660. case WCD9335_CDC_RX8_RX_PATH_CTL:
  2661. case WCD9335_CDC_RX8_RX_PATH_MIX_CTL:
  2662. prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL;
  2663. *ind = 8;
  2664. break;
  2665. }
  2666. return prim_int_reg;
  2667. }
  2668. static void wcd9335_codec_hd2_control(struct snd_soc_component *component,
  2669. u16 prim_int_reg, int event)
  2670. {
  2671. u16 hd2_scale_reg;
  2672. u16 hd2_enable_reg = 0;
  2673. if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
  2674. hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
  2675. hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
  2676. }
  2677. if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
  2678. hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
  2679. hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
  2680. }
  2681. if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
  2682. snd_soc_component_update_bits(component, hd2_scale_reg,
  2683. WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
  2684. WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P2500);
  2685. snd_soc_component_update_bits(component, hd2_scale_reg,
  2686. WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
  2687. WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_2);
  2688. snd_soc_component_update_bits(component, hd2_enable_reg,
  2689. WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
  2690. WCD9335_CDC_RX_PATH_CFG_HD2_ENABLE);
  2691. }
  2692. if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
  2693. snd_soc_component_update_bits(component, hd2_enable_reg,
  2694. WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK,
  2695. WCD9335_CDC_RX_PATH_CFG_HD2_DISABLE);
  2696. snd_soc_component_update_bits(component, hd2_scale_reg,
  2697. WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK,
  2698. WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_1);
  2699. snd_soc_component_update_bits(component, hd2_scale_reg,
  2700. WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK,
  2701. WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000);
  2702. }
  2703. }
  2704. static int wcd9335_codec_enable_prim_interpolator(
  2705. struct snd_soc_component *comp,
  2706. u16 reg, int event)
  2707. {
  2708. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  2709. u16 ind = 0;
  2710. int prim_int_reg = wcd9335_interp_get_primary_reg(reg, &ind);
  2711. switch (event) {
  2712. case SND_SOC_DAPM_PRE_PMU:
  2713. wcd->prim_int_users[ind]++;
  2714. if (wcd->prim_int_users[ind] == 1) {
  2715. snd_soc_component_update_bits(comp, prim_int_reg,
  2716. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  2717. WCD9335_CDC_RX_PGA_MUTE_ENABLE);
  2718. wcd9335_codec_hd2_control(comp, prim_int_reg, event);
  2719. snd_soc_component_update_bits(comp, prim_int_reg,
  2720. WCD9335_CDC_RX_CLK_EN_MASK,
  2721. WCD9335_CDC_RX_CLK_ENABLE);
  2722. }
  2723. if ((reg != prim_int_reg) &&
  2724. ((snd_soc_component_read(comp, prim_int_reg)) &
  2725. WCD9335_CDC_RX_PGA_MUTE_EN_MASK))
  2726. snd_soc_component_update_bits(comp, reg,
  2727. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  2728. WCD9335_CDC_RX_PGA_MUTE_ENABLE);
  2729. break;
  2730. case SND_SOC_DAPM_POST_PMD:
  2731. wcd->prim_int_users[ind]--;
  2732. if (wcd->prim_int_users[ind] == 0) {
  2733. snd_soc_component_update_bits(comp, prim_int_reg,
  2734. WCD9335_CDC_RX_CLK_EN_MASK,
  2735. WCD9335_CDC_RX_CLK_DISABLE);
  2736. snd_soc_component_update_bits(comp, prim_int_reg,
  2737. WCD9335_CDC_RX_RESET_MASK,
  2738. WCD9335_CDC_RX_RESET_ENABLE);
  2739. snd_soc_component_update_bits(comp, prim_int_reg,
  2740. WCD9335_CDC_RX_RESET_MASK,
  2741. WCD9335_CDC_RX_RESET_DISABLE);
  2742. wcd9335_codec_hd2_control(comp, prim_int_reg, event);
  2743. }
  2744. break;
  2745. }
  2746. return 0;
  2747. }
  2748. static int wcd9335_config_compander(struct snd_soc_component *component,
  2749. int interp_n, int event)
  2750. {
  2751. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  2752. int comp;
  2753. u16 comp_ctl0_reg, rx_path_cfg0_reg;
  2754. /* EAR does not have compander */
  2755. if (!interp_n)
  2756. return 0;
  2757. comp = interp_n - 1;
  2758. if (!wcd->comp_enabled[comp])
  2759. return 0;
  2760. comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL(comp);
  2761. rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG(comp);
  2762. if (SND_SOC_DAPM_EVENT_ON(event)) {
  2763. /* Enable Compander Clock */
  2764. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2765. WCD9335_CDC_COMPANDER_CLK_EN_MASK,
  2766. WCD9335_CDC_COMPANDER_CLK_ENABLE);
  2767. /* Reset comander */
  2768. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2769. WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
  2770. WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
  2771. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2772. WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
  2773. WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
  2774. /* Enables DRE in this path */
  2775. snd_soc_component_update_bits(component, rx_path_cfg0_reg,
  2776. WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
  2777. WCD9335_CDC_RX_PATH_CFG_CMP_ENABLE);
  2778. }
  2779. if (SND_SOC_DAPM_EVENT_OFF(event)) {
  2780. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2781. WCD9335_CDC_COMPANDER_HALT_MASK,
  2782. WCD9335_CDC_COMPANDER_HALT);
  2783. snd_soc_component_update_bits(component, rx_path_cfg0_reg,
  2784. WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK,
  2785. WCD9335_CDC_RX_PATH_CFG_CMP_DISABLE);
  2786. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2787. WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
  2788. WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE);
  2789. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2790. WCD9335_CDC_COMPANDER_SOFT_RST_MASK,
  2791. WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE);
  2792. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2793. WCD9335_CDC_COMPANDER_CLK_EN_MASK,
  2794. WCD9335_CDC_COMPANDER_CLK_DISABLE);
  2795. snd_soc_component_update_bits(component, comp_ctl0_reg,
  2796. WCD9335_CDC_COMPANDER_HALT_MASK,
  2797. WCD9335_CDC_COMPANDER_NOHALT);
  2798. }
  2799. return 0;
  2800. }
  2801. static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
  2802. struct snd_kcontrol *kc, int event)
  2803. {
  2804. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  2805. u16 gain_reg;
  2806. u16 reg;
  2807. int val;
  2808. int offset_val = 0;
  2809. if (!(strcmp(w->name, "RX INT0 INTERP"))) {
  2810. reg = WCD9335_CDC_RX0_RX_PATH_CTL;
  2811. gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL;
  2812. } else if (!(strcmp(w->name, "RX INT1 INTERP"))) {
  2813. reg = WCD9335_CDC_RX1_RX_PATH_CTL;
  2814. gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL;
  2815. } else if (!(strcmp(w->name, "RX INT2 INTERP"))) {
  2816. reg = WCD9335_CDC_RX2_RX_PATH_CTL;
  2817. gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL;
  2818. } else if (!(strcmp(w->name, "RX INT3 INTERP"))) {
  2819. reg = WCD9335_CDC_RX3_RX_PATH_CTL;
  2820. gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL;
  2821. } else if (!(strcmp(w->name, "RX INT4 INTERP"))) {
  2822. reg = WCD9335_CDC_RX4_RX_PATH_CTL;
  2823. gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL;
  2824. } else if (!(strcmp(w->name, "RX INT5 INTERP"))) {
  2825. reg = WCD9335_CDC_RX5_RX_PATH_CTL;
  2826. gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL;
  2827. } else if (!(strcmp(w->name, "RX INT6 INTERP"))) {
  2828. reg = WCD9335_CDC_RX6_RX_PATH_CTL;
  2829. gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL;
  2830. } else if (!(strcmp(w->name, "RX INT7 INTERP"))) {
  2831. reg = WCD9335_CDC_RX7_RX_PATH_CTL;
  2832. gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL;
  2833. } else if (!(strcmp(w->name, "RX INT8 INTERP"))) {
  2834. reg = WCD9335_CDC_RX8_RX_PATH_CTL;
  2835. gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL;
  2836. } else {
  2837. dev_err(comp->dev, "%s: Interpolator reg not found\n",
  2838. __func__);
  2839. return -EINVAL;
  2840. }
  2841. switch (event) {
  2842. case SND_SOC_DAPM_PRE_PMU:
  2843. /* Reset if needed */
  2844. wcd9335_codec_enable_prim_interpolator(comp, reg, event);
  2845. break;
  2846. case SND_SOC_DAPM_POST_PMU:
  2847. wcd9335_config_compander(comp, w->shift, event);
  2848. val = snd_soc_component_read(comp, gain_reg);
  2849. val += offset_val;
  2850. snd_soc_component_write(comp, gain_reg, val);
  2851. break;
  2852. case SND_SOC_DAPM_POST_PMD:
  2853. wcd9335_config_compander(comp, w->shift, event);
  2854. wcd9335_codec_enable_prim_interpolator(comp, reg, event);
  2855. break;
  2856. }
  2857. return 0;
  2858. }
  2859. static void wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component *component,
  2860. u8 gain)
  2861. {
  2862. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  2863. u8 hph_l_en, hph_r_en;
  2864. u8 l_val, r_val;
  2865. u8 hph_pa_status;
  2866. bool is_hphl_pa, is_hphr_pa;
  2867. hph_pa_status = snd_soc_component_read(component, WCD9335_ANA_HPH);
  2868. is_hphl_pa = hph_pa_status >> 7;
  2869. is_hphr_pa = (hph_pa_status & 0x40) >> 6;
  2870. hph_l_en = snd_soc_component_read(component, WCD9335_HPH_L_EN);
  2871. hph_r_en = snd_soc_component_read(component, WCD9335_HPH_R_EN);
  2872. l_val = (hph_l_en & 0xC0) | 0x20 | gain;
  2873. r_val = (hph_r_en & 0xC0) | 0x20 | gain;
  2874. /*
  2875. * Set HPH_L & HPH_R gain source selection to REGISTER
  2876. * for better click and pop only if corresponding PAs are
  2877. * not enabled. Also cache the values of the HPHL/R
  2878. * PA gains to be applied after PAs are enabled
  2879. */
  2880. if ((l_val != hph_l_en) && !is_hphl_pa) {
  2881. snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val);
  2882. wcd->hph_l_gain = hph_l_en & 0x1F;
  2883. }
  2884. if ((r_val != hph_r_en) && !is_hphr_pa) {
  2885. snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val);
  2886. wcd->hph_r_gain = hph_r_en & 0x1F;
  2887. }
  2888. }
  2889. static void wcd9335_codec_hph_lohifi_config(struct snd_soc_component *comp,
  2890. int event)
  2891. {
  2892. if (SND_SOC_DAPM_EVENT_ON(event)) {
  2893. snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
  2894. WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
  2895. 0x06);
  2896. snd_soc_component_update_bits(comp,
  2897. WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
  2898. 0xF0, 0x40);
  2899. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  2900. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  2901. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
  2902. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2903. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2904. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
  2905. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
  2906. WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
  2907. 0x0C);
  2908. wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
  2909. }
  2910. if (SND_SOC_DAPM_EVENT_OFF(event)) {
  2911. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2912. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2913. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
  2914. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  2915. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  2916. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
  2917. snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
  2918. 0x8A);
  2919. snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA,
  2920. WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK,
  2921. 0x0A);
  2922. }
  2923. }
  2924. static void wcd9335_codec_hph_lp_config(struct snd_soc_component *comp,
  2925. int event)
  2926. {
  2927. if (SND_SOC_DAPM_EVENT_ON(event)) {
  2928. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
  2929. WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
  2930. 0x0C);
  2931. wcd9335_codec_hph_mode_gain_opt(comp, 0x10);
  2932. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  2933. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  2934. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
  2935. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2936. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2937. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
  2938. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2939. WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
  2940. WCD9335_HPH_PA_CTL2_FORCE_PSRREH_ENABLE);
  2941. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2942. WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
  2943. WCD9335_HPH_PA_CTL2_HPH_PSRR_ENABLE);
  2944. snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
  2945. WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_MASK,
  2946. WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_V_N1P60);
  2947. snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL,
  2948. WCD9335_HPH_RDAC_1P65_LD_OUTCTL_MASK,
  2949. WCD9335_HPH_RDAC_1P65_LD_OUTCTL_V_N1P60);
  2950. snd_soc_component_update_bits(comp,
  2951. WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01);
  2952. snd_soc_component_update_bits(comp,
  2953. WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10);
  2954. }
  2955. if (SND_SOC_DAPM_EVENT_OFF(event)) {
  2956. snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDAC_LDO,
  2957. 0x88);
  2958. snd_soc_component_write(comp, WCD9335_HPH_RDAC_LDO_CTL,
  2959. 0x33);
  2960. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2961. WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK,
  2962. WCD9335_HPH_PA_CTL2_HPH_PSRR_DISABLE);
  2963. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2964. WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK,
  2965. WCD9335_HPH_PA_CTL2_FORCE_PSRREH_DISABLE);
  2966. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2967. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2968. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
  2969. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  2970. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  2971. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
  2972. snd_soc_component_update_bits(comp, WCD9335_HPH_R_EN,
  2973. WCD9335_HPH_CONST_SEL_L_MASK,
  2974. WCD9335_HPH_CONST_SEL_L_HQ_PATH);
  2975. snd_soc_component_update_bits(comp, WCD9335_HPH_L_EN,
  2976. WCD9335_HPH_CONST_SEL_L_MASK,
  2977. WCD9335_HPH_CONST_SEL_L_HQ_PATH);
  2978. }
  2979. }
  2980. static void wcd9335_codec_hph_hifi_config(struct snd_soc_component *comp,
  2981. int event)
  2982. {
  2983. if (SND_SOC_DAPM_EVENT_ON(event)) {
  2984. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  2985. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  2986. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000);
  2987. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2988. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2989. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE);
  2990. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1,
  2991. WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
  2992. 0x0C);
  2993. wcd9335_codec_hph_mode_gain_opt(comp, 0x11);
  2994. }
  2995. if (SND_SOC_DAPM_EVENT_OFF(event)) {
  2996. snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2,
  2997. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK,
  2998. WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE);
  2999. snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL,
  3000. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK,
  3001. WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500);
  3002. }
  3003. }
  3004. static void wcd9335_codec_hph_mode_config(struct snd_soc_component *component,
  3005. int event, int mode)
  3006. {
  3007. switch (mode) {
  3008. case CLS_H_LP:
  3009. wcd9335_codec_hph_lp_config(component, event);
  3010. break;
  3011. case CLS_H_LOHIFI:
  3012. wcd9335_codec_hph_lohifi_config(component, event);
  3013. break;
  3014. case CLS_H_HIFI:
  3015. wcd9335_codec_hph_hifi_config(component, event);
  3016. break;
  3017. }
  3018. }
  3019. static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
  3020. struct snd_kcontrol *kc,
  3021. int event)
  3022. {
  3023. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3024. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3025. int hph_mode = wcd->hph_mode;
  3026. u8 dem_inp;
  3027. switch (event) {
  3028. case SND_SOC_DAPM_PRE_PMU:
  3029. /* Read DEM INP Select */
  3030. dem_inp = snd_soc_component_read(comp,
  3031. WCD9335_CDC_RX1_RX_PATH_SEC0) & 0x03;
  3032. if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
  3033. (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
  3034. dev_err(comp->dev, "Incorrect DEM Input\n");
  3035. return -EINVAL;
  3036. }
  3037. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
  3038. WCD_CLSH_STATE_HPHL,
  3039. ((hph_mode == CLS_H_LOHIFI) ?
  3040. CLS_H_HIFI : hph_mode));
  3041. wcd9335_codec_hph_mode_config(comp, event, hph_mode);
  3042. break;
  3043. case SND_SOC_DAPM_POST_PMU:
  3044. usleep_range(1000, 1100);
  3045. break;
  3046. case SND_SOC_DAPM_PRE_PMD:
  3047. break;
  3048. case SND_SOC_DAPM_POST_PMD:
  3049. /* 1000us required as per HW requirement */
  3050. usleep_range(1000, 1100);
  3051. if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
  3052. WCD_CLSH_STATE_HPHR))
  3053. wcd9335_codec_hph_mode_config(comp, event, hph_mode);
  3054. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
  3055. WCD_CLSH_STATE_HPHL,
  3056. ((hph_mode == CLS_H_LOHIFI) ?
  3057. CLS_H_HIFI : hph_mode));
  3058. break;
  3059. }
  3060. return 0;
  3061. }
  3062. static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
  3063. struct snd_kcontrol *kc, int event)
  3064. {
  3065. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3066. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3067. switch (event) {
  3068. case SND_SOC_DAPM_PRE_PMU:
  3069. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
  3070. WCD_CLSH_STATE_LO, CLS_AB);
  3071. break;
  3072. case SND_SOC_DAPM_POST_PMD:
  3073. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
  3074. WCD_CLSH_STATE_LO, CLS_AB);
  3075. break;
  3076. }
  3077. return 0;
  3078. }
  3079. static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
  3080. struct snd_kcontrol *kc, int event)
  3081. {
  3082. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3083. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3084. switch (event) {
  3085. case SND_SOC_DAPM_PRE_PMU:
  3086. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC,
  3087. WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
  3088. break;
  3089. case SND_SOC_DAPM_POST_PMD:
  3090. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
  3091. WCD_CLSH_STATE_EAR, CLS_H_NORMAL);
  3092. break;
  3093. }
  3094. return 0;
  3095. }
  3096. static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd,
  3097. int mode, int event)
  3098. {
  3099. u8 scale_val = 0;
  3100. switch (event) {
  3101. case SND_SOC_DAPM_POST_PMU:
  3102. switch (mode) {
  3103. case CLS_H_HIFI:
  3104. scale_val = 0x3;
  3105. break;
  3106. case CLS_H_LOHIFI:
  3107. scale_val = 0x1;
  3108. break;
  3109. }
  3110. break;
  3111. case SND_SOC_DAPM_PRE_PMD:
  3112. scale_val = 0x6;
  3113. break;
  3114. }
  3115. if (scale_val)
  3116. snd_soc_component_update_bits(wcd->component,
  3117. WCD9335_HPH_PA_CTL1,
  3118. WCD9335_HPH_PA_GM3_IB_SCALE_MASK,
  3119. scale_val << 1);
  3120. if (SND_SOC_DAPM_EVENT_ON(event)) {
  3121. if (wcd->comp_enabled[COMPANDER_1] ||
  3122. wcd->comp_enabled[COMPANDER_2]) {
  3123. /* GAIN Source Selection */
  3124. snd_soc_component_update_bits(wcd->component,
  3125. WCD9335_HPH_L_EN,
  3126. WCD9335_HPH_GAIN_SRC_SEL_MASK,
  3127. WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
  3128. snd_soc_component_update_bits(wcd->component,
  3129. WCD9335_HPH_R_EN,
  3130. WCD9335_HPH_GAIN_SRC_SEL_MASK,
  3131. WCD9335_HPH_GAIN_SRC_SEL_COMPANDER);
  3132. snd_soc_component_update_bits(wcd->component,
  3133. WCD9335_HPH_AUTO_CHOP,
  3134. WCD9335_HPH_AUTO_CHOP_MASK,
  3135. WCD9335_HPH_AUTO_CHOP_FORCE_ENABLE);
  3136. }
  3137. snd_soc_component_update_bits(wcd->component,
  3138. WCD9335_HPH_L_EN,
  3139. WCD9335_HPH_PA_GAIN_MASK,
  3140. wcd->hph_l_gain);
  3141. snd_soc_component_update_bits(wcd->component,
  3142. WCD9335_HPH_R_EN,
  3143. WCD9335_HPH_PA_GAIN_MASK,
  3144. wcd->hph_r_gain);
  3145. }
  3146. if (SND_SOC_DAPM_EVENT_OFF(event))
  3147. snd_soc_component_update_bits(wcd->component,
  3148. WCD9335_HPH_AUTO_CHOP,
  3149. WCD9335_HPH_AUTO_CHOP_MASK,
  3150. WCD9335_HPH_AUTO_CHOP_ENABLE_BY_CMPDR_GAIN);
  3151. }
  3152. static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
  3153. struct snd_kcontrol *kc,
  3154. int event)
  3155. {
  3156. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3157. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3158. int hph_mode = wcd->hph_mode;
  3159. u8 dem_inp;
  3160. switch (event) {
  3161. case SND_SOC_DAPM_PRE_PMU:
  3162. /* Read DEM INP Select */
  3163. dem_inp = snd_soc_component_read(comp,
  3164. WCD9335_CDC_RX2_RX_PATH_SEC0) &
  3165. WCD9335_CDC_RX_PATH_DEM_INP_SEL_MASK;
  3166. if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
  3167. (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
  3168. dev_err(comp->dev, "DEM Input not set correctly, hph_mode: %d\n",
  3169. hph_mode);
  3170. return -EINVAL;
  3171. }
  3172. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl,
  3173. WCD_CLSH_EVENT_PRE_DAC,
  3174. WCD_CLSH_STATE_HPHR,
  3175. ((hph_mode == CLS_H_LOHIFI) ?
  3176. CLS_H_HIFI : hph_mode));
  3177. wcd9335_codec_hph_mode_config(comp, event, hph_mode);
  3178. break;
  3179. case SND_SOC_DAPM_POST_PMD:
  3180. /* 1000us required as per HW requirement */
  3181. usleep_range(1000, 1100);
  3182. if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) &
  3183. WCD_CLSH_STATE_HPHL))
  3184. wcd9335_codec_hph_mode_config(comp, event, hph_mode);
  3185. wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA,
  3186. WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ?
  3187. CLS_H_HIFI : hph_mode));
  3188. break;
  3189. }
  3190. return 0;
  3191. }
  3192. static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
  3193. struct snd_kcontrol *kc,
  3194. int event)
  3195. {
  3196. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3197. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3198. int hph_mode = wcd->hph_mode;
  3199. switch (event) {
  3200. case SND_SOC_DAPM_PRE_PMU:
  3201. break;
  3202. case SND_SOC_DAPM_POST_PMU:
  3203. /*
  3204. * 7ms sleep is required after PA is enabled as per
  3205. * HW requirement
  3206. */
  3207. usleep_range(7000, 7100);
  3208. wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
  3209. snd_soc_component_update_bits(comp,
  3210. WCD9335_CDC_RX1_RX_PATH_CTL,
  3211. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3212. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3213. /* Remove mix path mute if it is enabled */
  3214. if ((snd_soc_component_read(comp,
  3215. WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) &
  3216. WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
  3217. snd_soc_component_update_bits(comp,
  3218. WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
  3219. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3220. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3221. break;
  3222. case SND_SOC_DAPM_PRE_PMD:
  3223. wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
  3224. break;
  3225. case SND_SOC_DAPM_POST_PMD:
  3226. /* 5ms sleep is required after PA is disabled as per
  3227. * HW requirement
  3228. */
  3229. usleep_range(5000, 5500);
  3230. break;
  3231. }
  3232. return 0;
  3233. }
  3234. static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
  3235. struct snd_kcontrol *kc,
  3236. int event)
  3237. {
  3238. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3239. int vol_reg = 0, mix_vol_reg = 0;
  3240. if (w->reg == WCD9335_ANA_LO_1_2) {
  3241. if (w->shift == 7) {
  3242. vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL;
  3243. mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL;
  3244. } else if (w->shift == 6) {
  3245. vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL;
  3246. mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL;
  3247. }
  3248. } else if (w->reg == WCD9335_ANA_LO_3_4) {
  3249. if (w->shift == 7) {
  3250. vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL;
  3251. mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL;
  3252. } else if (w->shift == 6) {
  3253. vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL;
  3254. mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL;
  3255. }
  3256. } else {
  3257. dev_err(comp->dev, "Error enabling lineout PA\n");
  3258. return -EINVAL;
  3259. }
  3260. switch (event) {
  3261. case SND_SOC_DAPM_POST_PMU:
  3262. /* 5ms sleep is required after PA is enabled as per
  3263. * HW requirement
  3264. */
  3265. usleep_range(5000, 5500);
  3266. snd_soc_component_update_bits(comp, vol_reg,
  3267. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3268. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3269. /* Remove mix path mute if it is enabled */
  3270. if ((snd_soc_component_read(comp, mix_vol_reg)) &
  3271. WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
  3272. snd_soc_component_update_bits(comp, mix_vol_reg,
  3273. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3274. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3275. break;
  3276. case SND_SOC_DAPM_POST_PMD:
  3277. /* 5ms sleep is required after PA is disabled as per
  3278. * HW requirement
  3279. */
  3280. usleep_range(5000, 5500);
  3281. break;
  3282. }
  3283. return 0;
  3284. }
  3285. static void wcd9335_codec_init_flyback(struct snd_soc_component *component)
  3286. {
  3287. snd_soc_component_update_bits(component, WCD9335_HPH_L_EN,
  3288. WCD9335_HPH_CONST_SEL_L_MASK,
  3289. WCD9335_HPH_CONST_SEL_L_BYPASS);
  3290. snd_soc_component_update_bits(component, WCD9335_HPH_R_EN,
  3291. WCD9335_HPH_CONST_SEL_L_MASK,
  3292. WCD9335_HPH_CONST_SEL_L_BYPASS);
  3293. snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
  3294. WCD9335_RX_BIAS_FLYB_VPOS_5_UA_MASK,
  3295. WCD9335_RX_BIAS_FLYB_I_0P0_UA);
  3296. snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF,
  3297. WCD9335_RX_BIAS_FLYB_VNEG_5_UA_MASK,
  3298. WCD9335_RX_BIAS_FLYB_I_0P0_UA);
  3299. }
  3300. static int wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
  3301. struct snd_kcontrol *kc, int event)
  3302. {
  3303. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3304. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3305. switch (event) {
  3306. case SND_SOC_DAPM_PRE_PMU:
  3307. wcd->rx_bias_count++;
  3308. if (wcd->rx_bias_count == 1) {
  3309. wcd9335_codec_init_flyback(comp);
  3310. snd_soc_component_update_bits(comp,
  3311. WCD9335_ANA_RX_SUPPLIES,
  3312. WCD9335_ANA_RX_BIAS_ENABLE_MASK,
  3313. WCD9335_ANA_RX_BIAS_ENABLE);
  3314. }
  3315. break;
  3316. case SND_SOC_DAPM_POST_PMD:
  3317. wcd->rx_bias_count--;
  3318. if (!wcd->rx_bias_count)
  3319. snd_soc_component_update_bits(comp,
  3320. WCD9335_ANA_RX_SUPPLIES,
  3321. WCD9335_ANA_RX_BIAS_ENABLE_MASK,
  3322. WCD9335_ANA_RX_BIAS_DISABLE);
  3323. break;
  3324. }
  3325. return 0;
  3326. }
  3327. static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
  3328. struct snd_kcontrol *kc, int event)
  3329. {
  3330. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3331. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  3332. int hph_mode = wcd->hph_mode;
  3333. switch (event) {
  3334. case SND_SOC_DAPM_PRE_PMU:
  3335. break;
  3336. case SND_SOC_DAPM_POST_PMU:
  3337. /*
  3338. * 7ms sleep is required after PA is enabled as per
  3339. * HW requirement
  3340. */
  3341. usleep_range(7000, 7100);
  3342. wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
  3343. snd_soc_component_update_bits(comp,
  3344. WCD9335_CDC_RX2_RX_PATH_CTL,
  3345. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3346. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3347. /* Remove mix path mute if it is enabled */
  3348. if ((snd_soc_component_read(comp,
  3349. WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) &
  3350. WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
  3351. snd_soc_component_update_bits(comp,
  3352. WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
  3353. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3354. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3355. break;
  3356. case SND_SOC_DAPM_PRE_PMD:
  3357. wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event);
  3358. break;
  3359. case SND_SOC_DAPM_POST_PMD:
  3360. /* 5ms sleep is required after PA is disabled as per
  3361. * HW requirement
  3362. */
  3363. usleep_range(5000, 5500);
  3364. break;
  3365. }
  3366. return 0;
  3367. }
  3368. static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
  3369. struct snd_kcontrol *kc, int event)
  3370. {
  3371. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3372. switch (event) {
  3373. case SND_SOC_DAPM_POST_PMU:
  3374. /* 5ms sleep is required after PA is enabled as per
  3375. * HW requirement
  3376. */
  3377. usleep_range(5000, 5500);
  3378. snd_soc_component_update_bits(comp,
  3379. WCD9335_CDC_RX0_RX_PATH_CTL,
  3380. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3381. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3382. /* Remove mix path mute if it is enabled */
  3383. if ((snd_soc_component_read(comp,
  3384. WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) &
  3385. WCD9335_CDC_RX_PGA_MUTE_EN_MASK)
  3386. snd_soc_component_update_bits(comp,
  3387. WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
  3388. WCD9335_CDC_RX_PGA_MUTE_EN_MASK,
  3389. WCD9335_CDC_RX_PGA_MUTE_DISABLE);
  3390. break;
  3391. case SND_SOC_DAPM_POST_PMD:
  3392. /* 5ms sleep is required after PA is disabled as per
  3393. * HW requirement
  3394. */
  3395. usleep_range(5000, 5500);
  3396. break;
  3397. }
  3398. return 0;
  3399. }
  3400. static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
  3401. {
  3402. struct wcd9335_codec *wcd = data;
  3403. unsigned long status = 0;
  3404. int i, j, port_id;
  3405. unsigned int val, int_val = 0;
  3406. irqreturn_t ret = IRQ_NONE;
  3407. bool tx;
  3408. unsigned short reg = 0;
  3409. for (i = WCD9335_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
  3410. i <= WCD9335_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
  3411. regmap_read(wcd->if_regmap, i, &val);
  3412. status |= ((u32)val << (8 * j));
  3413. }
  3414. for_each_set_bit(j, &status, 32) {
  3415. tx = (j >= 16);
  3416. port_id = (tx ? j - 16 : j);
  3417. regmap_read(wcd->if_regmap,
  3418. WCD9335_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val);
  3419. if (val) {
  3420. if (!tx)
  3421. reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
  3422. (port_id / 8);
  3423. else
  3424. reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
  3425. (port_id / 8);
  3426. regmap_read(
  3427. wcd->if_regmap, reg, &int_val);
  3428. /*
  3429. * Ignore interrupts for ports for which the
  3430. * interrupts are not specifically enabled.
  3431. */
  3432. if (!(int_val & (1 << (port_id % 8))))
  3433. continue;
  3434. }
  3435. if (val & WCD9335_SLIM_IRQ_OVERFLOW)
  3436. dev_err_ratelimited(wcd->dev,
  3437. "%s: overflow error on %s port %d, value %x\n",
  3438. __func__, (tx ? "TX" : "RX"), port_id, val);
  3439. if (val & WCD9335_SLIM_IRQ_UNDERFLOW)
  3440. dev_err_ratelimited(wcd->dev,
  3441. "%s: underflow error on %s port %d, value %x\n",
  3442. __func__, (tx ? "TX" : "RX"), port_id, val);
  3443. if ((val & WCD9335_SLIM_IRQ_OVERFLOW) ||
  3444. (val & WCD9335_SLIM_IRQ_UNDERFLOW)) {
  3445. if (!tx)
  3446. reg = WCD9335_SLIM_PGD_PORT_INT_EN0 +
  3447. (port_id / 8);
  3448. else
  3449. reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 +
  3450. (port_id / 8);
  3451. regmap_read(
  3452. wcd->if_regmap, reg, &int_val);
  3453. if (int_val & (1 << (port_id % 8))) {
  3454. int_val = int_val ^ (1 << (port_id % 8));
  3455. regmap_write(wcd->if_regmap,
  3456. reg, int_val);
  3457. }
  3458. }
  3459. regmap_write(wcd->if_regmap,
  3460. WCD9335_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8),
  3461. BIT(j % 8));
  3462. ret = IRQ_HANDLED;
  3463. }
  3464. return ret;
  3465. }
  3466. static struct wcd9335_irq wcd9335_irqs[] = {
  3467. {
  3468. .irq = WCD9335_IRQ_SLIMBUS,
  3469. .handler = wcd9335_slimbus_irq,
  3470. .name = "SLIM Slave",
  3471. },
  3472. };
  3473. static int wcd9335_setup_irqs(struct wcd9335_codec *wcd)
  3474. {
  3475. int irq, ret, i;
  3476. for (i = 0; i < ARRAY_SIZE(wcd9335_irqs); i++) {
  3477. irq = regmap_irq_get_virq(wcd->irq_data, wcd9335_irqs[i].irq);
  3478. if (irq < 0) {
  3479. dev_err(wcd->dev, "Failed to get %s\n",
  3480. wcd9335_irqs[i].name);
  3481. return irq;
  3482. }
  3483. ret = devm_request_threaded_irq(wcd->dev, irq, NULL,
  3484. wcd9335_irqs[i].handler,
  3485. IRQF_TRIGGER_RISING |
  3486. IRQF_ONESHOT,
  3487. wcd9335_irqs[i].name, wcd);
  3488. if (ret) {
  3489. dev_err(wcd->dev, "Failed to request %s\n",
  3490. wcd9335_irqs[i].name);
  3491. return ret;
  3492. }
  3493. }
  3494. /* enable interrupts on all slave ports */
  3495. for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++)
  3496. regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i,
  3497. 0xFF);
  3498. return ret;
  3499. }
  3500. static void wcd9335_teardown_irqs(struct wcd9335_codec *wcd)
  3501. {
  3502. int i;
  3503. /* disable interrupts on all slave ports */
  3504. for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++)
  3505. regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i,
  3506. 0x00);
  3507. }
  3508. static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd,
  3509. bool ccl_flag)
  3510. {
  3511. struct snd_soc_component *comp = wcd->component;
  3512. if (ccl_flag) {
  3513. if (++wcd->sido_ccl_cnt == 1)
  3514. snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
  3515. WCD9335_SIDO_SIDO_CCL_DEF_VALUE);
  3516. } else {
  3517. if (wcd->sido_ccl_cnt == 0) {
  3518. dev_err(wcd->dev, "sido_ccl already disabled\n");
  3519. return;
  3520. }
  3521. if (--wcd->sido_ccl_cnt == 0)
  3522. snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10,
  3523. WCD9335_SIDO_SIDO_CCL_10_ICHARG_PWR_SEL_C320FF);
  3524. }
  3525. }
  3526. static int wcd9335_enable_master_bias(struct wcd9335_codec *wcd)
  3527. {
  3528. wcd->master_bias_users++;
  3529. if (wcd->master_bias_users == 1) {
  3530. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3531. WCD9335_ANA_BIAS_EN_MASK,
  3532. WCD9335_ANA_BIAS_ENABLE);
  3533. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3534. WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
  3535. WCD9335_ANA_BIAS_PRECHRG_ENABLE);
  3536. /*
  3537. * 1ms delay is required after pre-charge is enabled
  3538. * as per HW requirement
  3539. */
  3540. usleep_range(1000, 1100);
  3541. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3542. WCD9335_ANA_BIAS_PRECHRG_EN_MASK,
  3543. WCD9335_ANA_BIAS_PRECHRG_DISABLE);
  3544. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3545. WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
  3546. WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
  3547. }
  3548. return 0;
  3549. }
  3550. static int wcd9335_enable_mclk(struct wcd9335_codec *wcd)
  3551. {
  3552. /* Enable mclk requires master bias to be enabled first */
  3553. if (wcd->master_bias_users <= 0)
  3554. return -EINVAL;
  3555. if (((wcd->clk_mclk_users == 0) && (wcd->clk_type == WCD_CLK_MCLK)) ||
  3556. ((wcd->clk_mclk_users > 0) && (wcd->clk_type != WCD_CLK_MCLK))) {
  3557. dev_err(wcd->dev, "Error enabling MCLK, clk_type: %d\n",
  3558. wcd->clk_type);
  3559. return -EINVAL;
  3560. }
  3561. if (++wcd->clk_mclk_users == 1) {
  3562. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3563. WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
  3564. WCD9335_ANA_CLK_EXT_CLKBUF_ENABLE);
  3565. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3566. WCD9335_ANA_CLK_MCLK_SRC_MASK,
  3567. WCD9335_ANA_CLK_MCLK_SRC_EXTERNAL);
  3568. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3569. WCD9335_ANA_CLK_MCLK_EN_MASK,
  3570. WCD9335_ANA_CLK_MCLK_ENABLE);
  3571. regmap_update_bits(wcd->regmap,
  3572. WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
  3573. WCD9335_CDC_CLK_RST_CTRL_FS_CNT_EN_MASK,
  3574. WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE);
  3575. regmap_update_bits(wcd->regmap,
  3576. WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
  3577. WCD9335_CDC_CLK_RST_CTRL_MCLK_EN_MASK,
  3578. WCD9335_CDC_CLK_RST_CTRL_MCLK_ENABLE);
  3579. /*
  3580. * 10us sleep is required after clock is enabled
  3581. * as per HW requirement
  3582. */
  3583. usleep_range(10, 15);
  3584. }
  3585. wcd->clk_type = WCD_CLK_MCLK;
  3586. return 0;
  3587. }
  3588. static int wcd9335_disable_mclk(struct wcd9335_codec *wcd)
  3589. {
  3590. if (wcd->clk_mclk_users <= 0)
  3591. return -EINVAL;
  3592. if (--wcd->clk_mclk_users == 0) {
  3593. if (wcd->clk_rco_users > 0) {
  3594. /* MCLK to RCO switch */
  3595. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3596. WCD9335_ANA_CLK_MCLK_SRC_MASK,
  3597. WCD9335_ANA_CLK_MCLK_SRC_RCO);
  3598. wcd->clk_type = WCD_CLK_RCO;
  3599. } else {
  3600. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3601. WCD9335_ANA_CLK_MCLK_EN_MASK,
  3602. WCD9335_ANA_CLK_MCLK_DISABLE);
  3603. wcd->clk_type = WCD_CLK_OFF;
  3604. }
  3605. regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP,
  3606. WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK,
  3607. WCD9335_ANA_CLK_EXT_CLKBUF_DISABLE);
  3608. }
  3609. return 0;
  3610. }
  3611. static int wcd9335_disable_master_bias(struct wcd9335_codec *wcd)
  3612. {
  3613. if (wcd->master_bias_users <= 0)
  3614. return -EINVAL;
  3615. wcd->master_bias_users--;
  3616. if (wcd->master_bias_users == 0) {
  3617. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3618. WCD9335_ANA_BIAS_EN_MASK,
  3619. WCD9335_ANA_BIAS_DISABLE);
  3620. regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS,
  3621. WCD9335_ANA_BIAS_PRECHRG_CTL_MODE,
  3622. WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL);
  3623. }
  3624. return 0;
  3625. }
  3626. static int wcd9335_cdc_req_mclk_enable(struct wcd9335_codec *wcd,
  3627. bool enable)
  3628. {
  3629. int ret = 0;
  3630. if (enable) {
  3631. wcd9335_cdc_sido_ccl_enable(wcd, true);
  3632. ret = clk_prepare_enable(wcd->mclk);
  3633. if (ret) {
  3634. dev_err(wcd->dev, "%s: ext clk enable failed\n",
  3635. __func__);
  3636. goto err;
  3637. }
  3638. /* get BG */
  3639. wcd9335_enable_master_bias(wcd);
  3640. /* get MCLK */
  3641. wcd9335_enable_mclk(wcd);
  3642. } else {
  3643. /* put MCLK */
  3644. wcd9335_disable_mclk(wcd);
  3645. /* put BG */
  3646. wcd9335_disable_master_bias(wcd);
  3647. clk_disable_unprepare(wcd->mclk);
  3648. wcd9335_cdc_sido_ccl_enable(wcd, false);
  3649. }
  3650. err:
  3651. return ret;
  3652. }
  3653. static void wcd9335_codec_apply_sido_voltage(struct wcd9335_codec *wcd,
  3654. enum wcd9335_sido_voltage req_mv)
  3655. {
  3656. struct snd_soc_component *comp = wcd->component;
  3657. int vout_d_val;
  3658. if (req_mv == wcd->sido_voltage)
  3659. return;
  3660. /* compute the vout_d step value */
  3661. vout_d_val = WCD9335_CALCULATE_VOUT_D(req_mv) &
  3662. WCD9335_ANA_BUCK_VOUT_MASK;
  3663. snd_soc_component_write(comp, WCD9335_ANA_BUCK_VOUT_D, vout_d_val);
  3664. snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
  3665. WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
  3666. WCD9335_ANA_BUCK_CTL_RAMP_START_ENABLE);
  3667. /* 1 msec sleep required after SIDO Vout_D voltage change */
  3668. usleep_range(1000, 1100);
  3669. wcd->sido_voltage = req_mv;
  3670. snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL,
  3671. WCD9335_ANA_BUCK_CTL_RAMP_START_MASK,
  3672. WCD9335_ANA_BUCK_CTL_RAMP_START_DISABLE);
  3673. }
  3674. static int wcd9335_codec_update_sido_voltage(struct wcd9335_codec *wcd,
  3675. enum wcd9335_sido_voltage req_mv)
  3676. {
  3677. int ret = 0;
  3678. /* enable mclk before setting SIDO voltage */
  3679. ret = wcd9335_cdc_req_mclk_enable(wcd, true);
  3680. if (ret) {
  3681. dev_err(wcd->dev, "Ext clk enable failed\n");
  3682. goto err;
  3683. }
  3684. wcd9335_codec_apply_sido_voltage(wcd, req_mv);
  3685. wcd9335_cdc_req_mclk_enable(wcd, false);
  3686. err:
  3687. return ret;
  3688. }
  3689. static int _wcd9335_codec_enable_mclk(struct snd_soc_component *component,
  3690. int enable)
  3691. {
  3692. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  3693. int ret;
  3694. if (enable) {
  3695. ret = wcd9335_cdc_req_mclk_enable(wcd, true);
  3696. if (ret)
  3697. return ret;
  3698. wcd9335_codec_apply_sido_voltage(wcd,
  3699. SIDO_VOLTAGE_NOMINAL_MV);
  3700. } else {
  3701. wcd9335_codec_update_sido_voltage(wcd,
  3702. wcd->sido_voltage);
  3703. wcd9335_cdc_req_mclk_enable(wcd, false);
  3704. }
  3705. return 0;
  3706. }
  3707. static int wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget *w,
  3708. struct snd_kcontrol *kc, int event)
  3709. {
  3710. struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
  3711. switch (event) {
  3712. case SND_SOC_DAPM_PRE_PMU:
  3713. return _wcd9335_codec_enable_mclk(comp, true);
  3714. case SND_SOC_DAPM_POST_PMD:
  3715. return _wcd9335_codec_enable_mclk(comp, false);
  3716. }
  3717. return 0;
  3718. }
  3719. static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = {
  3720. /* TODO SPK1 & SPK2 OUT*/
  3721. SND_SOC_DAPM_OUTPUT("EAR"),
  3722. SND_SOC_DAPM_OUTPUT("HPHL"),
  3723. SND_SOC_DAPM_OUTPUT("HPHR"),
  3724. SND_SOC_DAPM_OUTPUT("LINEOUT1"),
  3725. SND_SOC_DAPM_OUTPUT("LINEOUT2"),
  3726. SND_SOC_DAPM_OUTPUT("LINEOUT3"),
  3727. SND_SOC_DAPM_OUTPUT("LINEOUT4"),
  3728. SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
  3729. AIF1_PB, 0, wcd9335_codec_enable_slim,
  3730. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3731. SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
  3732. AIF2_PB, 0, wcd9335_codec_enable_slim,
  3733. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3734. SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
  3735. AIF3_PB, 0, wcd9335_codec_enable_slim,
  3736. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3737. SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
  3738. AIF4_PB, 0, wcd9335_codec_enable_slim,
  3739. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3740. SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD9335_RX0, 0,
  3741. &slim_rx_mux[WCD9335_RX0]),
  3742. SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD9335_RX1, 0,
  3743. &slim_rx_mux[WCD9335_RX1]),
  3744. SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD9335_RX2, 0,
  3745. &slim_rx_mux[WCD9335_RX2]),
  3746. SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD9335_RX3, 0,
  3747. &slim_rx_mux[WCD9335_RX3]),
  3748. SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD9335_RX4, 0,
  3749. &slim_rx_mux[WCD9335_RX4]),
  3750. SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD9335_RX5, 0,
  3751. &slim_rx_mux[WCD9335_RX5]),
  3752. SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD9335_RX6, 0,
  3753. &slim_rx_mux[WCD9335_RX6]),
  3754. SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD9335_RX7, 0,
  3755. &slim_rx_mux[WCD9335_RX7]),
  3756. SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
  3757. SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3758. SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3759. SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
  3760. SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
  3761. SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
  3762. SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
  3763. SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
  3764. SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL,
  3765. 5, 0, &rx_int0_2_mux, wcd9335_codec_enable_mix_path,
  3766. SND_SOC_DAPM_POST_PMU),
  3767. SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL,
  3768. 5, 0, &rx_int1_2_mux, wcd9335_codec_enable_mix_path,
  3769. SND_SOC_DAPM_POST_PMU),
  3770. SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL,
  3771. 5, 0, &rx_int2_2_mux, wcd9335_codec_enable_mix_path,
  3772. SND_SOC_DAPM_POST_PMU),
  3773. SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL,
  3774. 5, 0, &rx_int3_2_mux, wcd9335_codec_enable_mix_path,
  3775. SND_SOC_DAPM_POST_PMU),
  3776. SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL,
  3777. 5, 0, &rx_int4_2_mux, wcd9335_codec_enable_mix_path,
  3778. SND_SOC_DAPM_POST_PMU),
  3779. SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL,
  3780. 5, 0, &rx_int5_2_mux, wcd9335_codec_enable_mix_path,
  3781. SND_SOC_DAPM_POST_PMU),
  3782. SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL,
  3783. 5, 0, &rx_int6_2_mux, wcd9335_codec_enable_mix_path,
  3784. SND_SOC_DAPM_POST_PMU),
  3785. SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL,
  3786. 5, 0, &rx_int7_2_mux, wcd9335_codec_enable_mix_path,
  3787. SND_SOC_DAPM_POST_PMU),
  3788. SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL,
  3789. 5, 0, &rx_int8_2_mux, wcd9335_codec_enable_mix_path,
  3790. SND_SOC_DAPM_POST_PMU),
  3791. SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3792. &rx_int0_1_mix_inp0_mux),
  3793. SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3794. &rx_int0_1_mix_inp1_mux),
  3795. SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3796. &rx_int0_1_mix_inp2_mux),
  3797. SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3798. &rx_int1_1_mix_inp0_mux),
  3799. SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3800. &rx_int1_1_mix_inp1_mux),
  3801. SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3802. &rx_int1_1_mix_inp2_mux),
  3803. SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3804. &rx_int2_1_mix_inp0_mux),
  3805. SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3806. &rx_int2_1_mix_inp1_mux),
  3807. SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3808. &rx_int2_1_mix_inp2_mux),
  3809. SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3810. &rx_int3_1_mix_inp0_mux),
  3811. SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3812. &rx_int3_1_mix_inp1_mux),
  3813. SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3814. &rx_int3_1_mix_inp2_mux),
  3815. SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3816. &rx_int4_1_mix_inp0_mux),
  3817. SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3818. &rx_int4_1_mix_inp1_mux),
  3819. SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3820. &rx_int4_1_mix_inp2_mux),
  3821. SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3822. &rx_int5_1_mix_inp0_mux),
  3823. SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3824. &rx_int5_1_mix_inp1_mux),
  3825. SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3826. &rx_int5_1_mix_inp2_mux),
  3827. SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3828. &rx_int6_1_mix_inp0_mux),
  3829. SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3830. &rx_int6_1_mix_inp1_mux),
  3831. SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3832. &rx_int6_1_mix_inp2_mux),
  3833. SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3834. &rx_int7_1_mix_inp0_mux),
  3835. SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3836. &rx_int7_1_mix_inp1_mux),
  3837. SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3838. &rx_int7_1_mix_inp2_mux),
  3839. SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
  3840. &rx_int8_1_mix_inp0_mux),
  3841. SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
  3842. &rx_int8_1_mix_inp1_mux),
  3843. SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
  3844. &rx_int8_1_mix_inp2_mux),
  3845. SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3846. SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3847. SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3848. SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3849. SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3850. SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3851. SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3852. SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3853. SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3854. SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3855. SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3856. SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3857. SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3858. SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3859. SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3860. SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3861. SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
  3862. SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
  3863. SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3864. SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3865. SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3866. SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3867. SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3868. SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3869. SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3870. SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3871. SND_SOC_DAPM_MIXER("RX INT8 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
  3872. SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0,
  3873. &rx_int0_dem_inp_mux),
  3874. SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0,
  3875. &rx_int1_dem_inp_mux),
  3876. SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0,
  3877. &rx_int2_dem_inp_mux),
  3878. SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM,
  3879. INTERP_EAR, 0, &rx_int0_interp_mux,
  3880. wcd9335_codec_enable_interpolator,
  3881. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3882. SND_SOC_DAPM_POST_PMD),
  3883. SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM,
  3884. INTERP_HPHL, 0, &rx_int1_interp_mux,
  3885. wcd9335_codec_enable_interpolator,
  3886. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3887. SND_SOC_DAPM_POST_PMD),
  3888. SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM,
  3889. INTERP_HPHR, 0, &rx_int2_interp_mux,
  3890. wcd9335_codec_enable_interpolator,
  3891. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3892. SND_SOC_DAPM_POST_PMD),
  3893. SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM,
  3894. INTERP_LO1, 0, &rx_int3_interp_mux,
  3895. wcd9335_codec_enable_interpolator,
  3896. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3897. SND_SOC_DAPM_POST_PMD),
  3898. SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM,
  3899. INTERP_LO2, 0, &rx_int4_interp_mux,
  3900. wcd9335_codec_enable_interpolator,
  3901. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3902. SND_SOC_DAPM_POST_PMD),
  3903. SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM,
  3904. INTERP_LO3, 0, &rx_int5_interp_mux,
  3905. wcd9335_codec_enable_interpolator,
  3906. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3907. SND_SOC_DAPM_POST_PMD),
  3908. SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM,
  3909. INTERP_LO4, 0, &rx_int6_interp_mux,
  3910. wcd9335_codec_enable_interpolator,
  3911. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3912. SND_SOC_DAPM_POST_PMD),
  3913. SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM,
  3914. INTERP_SPKR1, 0, &rx_int7_interp_mux,
  3915. wcd9335_codec_enable_interpolator,
  3916. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3917. SND_SOC_DAPM_POST_PMD),
  3918. SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM,
  3919. INTERP_SPKR2, 0, &rx_int8_interp_mux,
  3920. wcd9335_codec_enable_interpolator,
  3921. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3922. SND_SOC_DAPM_POST_PMD),
  3923. SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
  3924. 0, 0, wcd9335_codec_ear_dac_event,
  3925. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3926. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  3927. SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH,
  3928. 5, 0, wcd9335_codec_hphl_dac_event,
  3929. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3930. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  3931. SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH,
  3932. 4, 0, wcd9335_codec_hphr_dac_event,
  3933. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3934. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  3935. SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM,
  3936. 0, 0, wcd9335_codec_lineout_dac_event,
  3937. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  3938. SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM,
  3939. 0, 0, wcd9335_codec_lineout_dac_event,
  3940. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  3941. SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM,
  3942. 0, 0, wcd9335_codec_lineout_dac_event,
  3943. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  3944. SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM,
  3945. 0, 0, wcd9335_codec_lineout_dac_event,
  3946. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  3947. SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
  3948. wcd9335_codec_enable_hphl_pa,
  3949. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3950. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  3951. SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
  3952. wcd9335_codec_enable_hphr_pa,
  3953. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  3954. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  3955. SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0,
  3956. wcd9335_codec_enable_ear_pa,
  3957. SND_SOC_DAPM_POST_PMU |
  3958. SND_SOC_DAPM_POST_PMD),
  3959. SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0,
  3960. wcd9335_codec_enable_lineout_pa,
  3961. SND_SOC_DAPM_POST_PMU |
  3962. SND_SOC_DAPM_POST_PMD),
  3963. SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0,
  3964. wcd9335_codec_enable_lineout_pa,
  3965. SND_SOC_DAPM_POST_PMU |
  3966. SND_SOC_DAPM_POST_PMD),
  3967. SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0,
  3968. wcd9335_codec_enable_lineout_pa,
  3969. SND_SOC_DAPM_POST_PMU |
  3970. SND_SOC_DAPM_POST_PMD),
  3971. SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0,
  3972. wcd9335_codec_enable_lineout_pa,
  3973. SND_SOC_DAPM_POST_PMU |
  3974. SND_SOC_DAPM_POST_PMD),
  3975. SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
  3976. wcd9335_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
  3977. SND_SOC_DAPM_POST_PMD),
  3978. SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
  3979. wcd9335_codec_enable_mclk, SND_SOC_DAPM_PRE_PMU |
  3980. SND_SOC_DAPM_POST_PMD),
  3981. /* TX */
  3982. SND_SOC_DAPM_INPUT("AMIC1"),
  3983. SND_SOC_DAPM_INPUT("AMIC2"),
  3984. SND_SOC_DAPM_INPUT("AMIC3"),
  3985. SND_SOC_DAPM_INPUT("AMIC4"),
  3986. SND_SOC_DAPM_INPUT("AMIC5"),
  3987. SND_SOC_DAPM_INPUT("AMIC6"),
  3988. SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
  3989. AIF1_CAP, 0, wcd9335_codec_enable_slim,
  3990. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3991. SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
  3992. AIF2_CAP, 0, wcd9335_codec_enable_slim,
  3993. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3994. SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
  3995. AIF3_CAP, 0, wcd9335_codec_enable_slim,
  3996. SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
  3997. SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, 0, 0,
  3998. wcd9335_codec_enable_micbias,
  3999. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4000. SND_SOC_DAPM_POST_PMD),
  4001. SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, 0, 0,
  4002. wcd9335_codec_enable_micbias,
  4003. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4004. SND_SOC_DAPM_POST_PMD),
  4005. SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, 0, 0,
  4006. wcd9335_codec_enable_micbias,
  4007. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4008. SND_SOC_DAPM_POST_PMD),
  4009. SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, 0, 0,
  4010. wcd9335_codec_enable_micbias,
  4011. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4012. SND_SOC_DAPM_POST_PMD),
  4013. SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0,
  4014. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4015. SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0,
  4016. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4017. SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0,
  4018. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4019. SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0,
  4020. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4021. SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0,
  4022. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4023. SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0,
  4024. wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
  4025. /* Digital Mic Inputs */
  4026. SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
  4027. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4028. SND_SOC_DAPM_POST_PMD),
  4029. SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
  4030. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4031. SND_SOC_DAPM_POST_PMD),
  4032. SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
  4033. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4034. SND_SOC_DAPM_POST_PMD),
  4035. SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
  4036. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4037. SND_SOC_DAPM_POST_PMD),
  4038. SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
  4039. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4040. SND_SOC_DAPM_POST_PMD),
  4041. SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
  4042. wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
  4043. SND_SOC_DAPM_POST_PMD),
  4044. SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0,
  4045. &tx_dmic_mux0),
  4046. SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0,
  4047. &tx_dmic_mux1),
  4048. SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0,
  4049. &tx_dmic_mux2),
  4050. SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0,
  4051. &tx_dmic_mux3),
  4052. SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0,
  4053. &tx_dmic_mux4),
  4054. SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0,
  4055. &tx_dmic_mux5),
  4056. SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0,
  4057. &tx_dmic_mux6),
  4058. SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0,
  4059. &tx_dmic_mux7),
  4060. SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0,
  4061. &tx_dmic_mux8),
  4062. SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0,
  4063. &tx_amic_mux0),
  4064. SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0,
  4065. &tx_amic_mux1),
  4066. SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0,
  4067. &tx_amic_mux2),
  4068. SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0,
  4069. &tx_amic_mux3),
  4070. SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0,
  4071. &tx_amic_mux4),
  4072. SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0,
  4073. &tx_amic_mux5),
  4074. SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0,
  4075. &tx_amic_mux6),
  4076. SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0,
  4077. &tx_amic_mux7),
  4078. SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0,
  4079. &tx_amic_mux8),
  4080. SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
  4081. aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
  4082. SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
  4083. aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
  4084. SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
  4085. aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
  4086. SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, WCD9335_TX0, 0,
  4087. &sb_tx0_mux),
  4088. SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, WCD9335_TX1, 0,
  4089. &sb_tx1_mux),
  4090. SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, WCD9335_TX2, 0,
  4091. &sb_tx2_mux),
  4092. SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, WCD9335_TX3, 0,
  4093. &sb_tx3_mux),
  4094. SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, WCD9335_TX4, 0,
  4095. &sb_tx4_mux),
  4096. SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, WCD9335_TX5, 0,
  4097. &sb_tx5_mux),
  4098. SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, WCD9335_TX6, 0,
  4099. &sb_tx6_mux),
  4100. SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, WCD9335_TX7, 0,
  4101. &sb_tx7_mux),
  4102. SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, WCD9335_TX8, 0,
  4103. &sb_tx8_mux),
  4104. SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0,
  4105. &tx_adc_mux0, wcd9335_codec_enable_dec,
  4106. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4107. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4108. SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0,
  4109. &tx_adc_mux1, wcd9335_codec_enable_dec,
  4110. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4111. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4112. SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0,
  4113. &tx_adc_mux2, wcd9335_codec_enable_dec,
  4114. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4115. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4116. SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0,
  4117. &tx_adc_mux3, wcd9335_codec_enable_dec,
  4118. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4119. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4120. SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0,
  4121. &tx_adc_mux4, wcd9335_codec_enable_dec,
  4122. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4123. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4124. SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0,
  4125. &tx_adc_mux5, wcd9335_codec_enable_dec,
  4126. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4127. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4128. SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0,
  4129. &tx_adc_mux6, wcd9335_codec_enable_dec,
  4130. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4131. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4132. SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0,
  4133. &tx_adc_mux7, wcd9335_codec_enable_dec,
  4134. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4135. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4136. SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0,
  4137. &tx_adc_mux8, wcd9335_codec_enable_dec,
  4138. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  4139. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  4140. };
  4141. static void wcd9335_enable_sido_buck(struct snd_soc_component *component)
  4142. {
  4143. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  4144. snd_soc_component_update_bits(component, WCD9335_ANA_RCO,
  4145. WCD9335_ANA_RCO_BG_EN_MASK,
  4146. WCD9335_ANA_RCO_BG_ENABLE);
  4147. snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
  4148. WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_MASK,
  4149. WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_EXT);
  4150. /* 100us sleep needed after IREF settings */
  4151. usleep_range(100, 110);
  4152. snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL,
  4153. WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_MASK,
  4154. WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT);
  4155. /* 100us sleep needed after VREF settings */
  4156. usleep_range(100, 110);
  4157. wcd->sido_input_src = SIDO_SOURCE_RCO_BG;
  4158. }
  4159. static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp)
  4160. {
  4161. _wcd9335_codec_enable_mclk(comp, true);
  4162. snd_soc_component_update_bits(comp,
  4163. WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
  4164. WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK,
  4165. WCD9335_CHIP_TIER_CTRL_EFUSE_ENABLE);
  4166. /*
  4167. * 5ms sleep required after enabling efuse control
  4168. * before checking the status.
  4169. */
  4170. usleep_range(5000, 5500);
  4171. if (!(snd_soc_component_read(comp,
  4172. WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) &
  4173. WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK))
  4174. WARN(1, "%s: Efuse sense is not complete\n", __func__);
  4175. wcd9335_enable_sido_buck(comp);
  4176. _wcd9335_codec_enable_mclk(comp, false);
  4177. return 0;
  4178. }
  4179. static void wcd9335_codec_init(struct snd_soc_component *component)
  4180. {
  4181. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  4182. int i;
  4183. /* ungate MCLK and set clk rate */
  4184. regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_GATE,
  4185. WCD9335_CODEC_RPM_CLK_GATE_MCLK_GATE_MASK, 0);
  4186. regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_MCLK_CFG,
  4187. WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
  4188. WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
  4189. for (i = 0; i < ARRAY_SIZE(wcd9335_codec_reg_init); i++)
  4190. snd_soc_component_update_bits(component,
  4191. wcd9335_codec_reg_init[i].reg,
  4192. wcd9335_codec_reg_init[i].mask,
  4193. wcd9335_codec_reg_init[i].val);
  4194. wcd9335_enable_efuse_sensing(component);
  4195. }
  4196. static int wcd9335_codec_probe(struct snd_soc_component *component)
  4197. {
  4198. struct wcd9335_codec *wcd = dev_get_drvdata(component->dev);
  4199. int ret;
  4200. int i;
  4201. snd_soc_component_init_regmap(component, wcd->regmap);
  4202. /* Class-H Init*/
  4203. wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, WCD9335);
  4204. if (IS_ERR(wcd->clsh_ctrl))
  4205. return PTR_ERR(wcd->clsh_ctrl);
  4206. /* Default HPH Mode to Class-H HiFi */
  4207. wcd->hph_mode = CLS_H_HIFI;
  4208. wcd->component = component;
  4209. wcd9335_codec_init(component);
  4210. for (i = 0; i < NUM_CODEC_DAIS; i++)
  4211. INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list);
  4212. ret = wcd9335_setup_irqs(wcd);
  4213. if (ret)
  4214. goto free_clsh_ctrl;
  4215. return 0;
  4216. free_clsh_ctrl:
  4217. wcd_clsh_ctrl_free(wcd->clsh_ctrl);
  4218. return ret;
  4219. }
  4220. static void wcd9335_codec_remove(struct snd_soc_component *comp)
  4221. {
  4222. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  4223. wcd_clsh_ctrl_free(wcd->clsh_ctrl);
  4224. wcd9335_teardown_irqs(wcd);
  4225. }
  4226. static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp,
  4227. int clk_id, int source,
  4228. unsigned int freq, int dir)
  4229. {
  4230. struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
  4231. wcd->mclk_rate = freq;
  4232. if (wcd->mclk_rate == WCD9335_MCLK_CLK_12P288MHZ)
  4233. snd_soc_component_update_bits(comp,
  4234. WCD9335_CODEC_RPM_CLK_MCLK_CFG,
  4235. WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
  4236. WCD9335_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ);
  4237. else if (wcd->mclk_rate == WCD9335_MCLK_CLK_9P6MHZ)
  4238. snd_soc_component_update_bits(comp,
  4239. WCD9335_CODEC_RPM_CLK_MCLK_CFG,
  4240. WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
  4241. WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
  4242. return clk_set_rate(wcd->mclk, freq);
  4243. }
  4244. static const struct snd_soc_component_driver wcd9335_component_drv = {
  4245. .probe = wcd9335_codec_probe,
  4246. .remove = wcd9335_codec_remove,
  4247. .set_sysclk = wcd9335_codec_set_sysclk,
  4248. .controls = wcd9335_snd_controls,
  4249. .num_controls = ARRAY_SIZE(wcd9335_snd_controls),
  4250. .dapm_widgets = wcd9335_dapm_widgets,
  4251. .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets),
  4252. .dapm_routes = wcd9335_audio_map,
  4253. .num_dapm_routes = ARRAY_SIZE(wcd9335_audio_map),
  4254. .endianness = 1,
  4255. };
  4256. static int wcd9335_probe(struct wcd9335_codec *wcd)
  4257. {
  4258. struct device *dev = wcd->dev;
  4259. memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs));
  4260. memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs));
  4261. wcd->sido_input_src = SIDO_SOURCE_INTERNAL;
  4262. wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV;
  4263. return devm_snd_soc_register_component(dev, &wcd9335_component_drv,
  4264. wcd9335_slim_dais,
  4265. ARRAY_SIZE(wcd9335_slim_dais));
  4266. }
  4267. static const struct regmap_range_cfg wcd9335_ranges[] = {
  4268. {
  4269. .name = "WCD9335",
  4270. .range_min = 0x0,
  4271. .range_max = WCD9335_MAX_REGISTER,
  4272. .selector_reg = WCD9335_SEL_REGISTER,
  4273. .selector_mask = 0xff,
  4274. .selector_shift = 0,
  4275. .window_start = 0x800,
  4276. .window_len = 0x100,
  4277. },
  4278. };
  4279. static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg)
  4280. {
  4281. switch (reg) {
  4282. case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3:
  4283. case WCD9335_ANA_MBHC_RESULT_3:
  4284. case WCD9335_ANA_MBHC_RESULT_2:
  4285. case WCD9335_ANA_MBHC_RESULT_1:
  4286. case WCD9335_ANA_MBHC_MECH:
  4287. case WCD9335_ANA_MBHC_ELECT:
  4288. case WCD9335_ANA_MBHC_ZDET:
  4289. case WCD9335_ANA_MICB2:
  4290. case WCD9335_ANA_RCO:
  4291. case WCD9335_ANA_BIAS:
  4292. return true;
  4293. default:
  4294. return false;
  4295. }
  4296. }
  4297. static struct regmap_config wcd9335_regmap_config = {
  4298. .reg_bits = 16,
  4299. .val_bits = 8,
  4300. .cache_type = REGCACHE_RBTREE,
  4301. .max_register = WCD9335_MAX_REGISTER,
  4302. .can_multi_write = true,
  4303. .ranges = wcd9335_ranges,
  4304. .num_ranges = ARRAY_SIZE(wcd9335_ranges),
  4305. .volatile_reg = wcd9335_is_volatile_register,
  4306. };
  4307. static const struct regmap_range_cfg wcd9335_ifc_ranges[] = {
  4308. {
  4309. .name = "WCD9335-IFC-DEV",
  4310. .range_min = 0x0,
  4311. .range_max = WCD9335_MAX_REGISTER,
  4312. .selector_reg = WCD9335_SEL_REGISTER,
  4313. .selector_mask = 0xfff,
  4314. .selector_shift = 0,
  4315. .window_start = 0x800,
  4316. .window_len = 0x400,
  4317. },
  4318. };
  4319. static struct regmap_config wcd9335_ifc_regmap_config = {
  4320. .reg_bits = 16,
  4321. .val_bits = 8,
  4322. .can_multi_write = true,
  4323. .max_register = WCD9335_MAX_REGISTER,
  4324. .ranges = wcd9335_ifc_ranges,
  4325. .num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges),
  4326. };
  4327. static const struct regmap_irq wcd9335_codec_irqs[] = {
  4328. /* INTR_REG 0 */
  4329. [WCD9335_IRQ_SLIMBUS] = {
  4330. .reg_offset = 0,
  4331. .mask = BIT(0),
  4332. .type = {
  4333. .type_reg_offset = 0,
  4334. .types_supported = IRQ_TYPE_EDGE_BOTH,
  4335. .type_reg_mask = BIT(0),
  4336. },
  4337. },
  4338. };
  4339. static const unsigned int wcd9335_config_regs[] = {
  4340. WCD9335_INTR_LEVEL0,
  4341. };
  4342. static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
  4343. .name = "wcd9335_pin1_irq",
  4344. .status_base = WCD9335_INTR_PIN1_STATUS0,
  4345. .mask_base = WCD9335_INTR_PIN1_MASK0,
  4346. .ack_base = WCD9335_INTR_PIN1_CLEAR0,
  4347. .num_regs = 4,
  4348. .irqs = wcd9335_codec_irqs,
  4349. .num_irqs = ARRAY_SIZE(wcd9335_codec_irqs),
  4350. .config_base = wcd9335_config_regs,
  4351. .num_config_bases = ARRAY_SIZE(wcd9335_config_regs),
  4352. .num_config_regs = 4,
  4353. .set_type_config = regmap_irq_set_type_config_simple,
  4354. };
  4355. static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
  4356. {
  4357. struct device *dev = wcd->dev;
  4358. struct device_node *np = dev->of_node;
  4359. int ret;
  4360. wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
  4361. if (wcd->reset_gpio < 0) {
  4362. dev_err(dev, "Reset GPIO missing from DT\n");
  4363. return wcd->reset_gpio;
  4364. }
  4365. wcd->mclk = devm_clk_get(dev, "mclk");
  4366. if (IS_ERR(wcd->mclk)) {
  4367. dev_err(dev, "mclk not found\n");
  4368. return PTR_ERR(wcd->mclk);
  4369. }
  4370. wcd->native_clk = devm_clk_get(dev, "slimbus");
  4371. if (IS_ERR(wcd->native_clk)) {
  4372. dev_err(dev, "slimbus clock not found\n");
  4373. return PTR_ERR(wcd->native_clk);
  4374. }
  4375. wcd->supplies[0].supply = "vdd-buck";
  4376. wcd->supplies[1].supply = "vdd-buck-sido";
  4377. wcd->supplies[2].supply = "vdd-tx";
  4378. wcd->supplies[3].supply = "vdd-rx";
  4379. wcd->supplies[4].supply = "vdd-io";
  4380. ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
  4381. if (ret) {
  4382. dev_err(dev, "Failed to get supplies: err = %d\n", ret);
  4383. return ret;
  4384. }
  4385. return 0;
  4386. }
  4387. static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
  4388. {
  4389. struct device *dev = wcd->dev;
  4390. int ret;
  4391. ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
  4392. if (ret) {
  4393. dev_err(dev, "Failed to get supplies: err = %d\n", ret);
  4394. return ret;
  4395. }
  4396. /*
  4397. * For WCD9335, it takes about 600us for the Vout_A and
  4398. * Vout_D to be ready after BUCK_SIDO is powered up.
  4399. * SYS_RST_N shouldn't be pulled high during this time
  4400. * Toggle the reset line to make sure the reset pulse is
  4401. * correctly applied
  4402. */
  4403. usleep_range(600, 650);
  4404. gpio_direction_output(wcd->reset_gpio, 0);
  4405. msleep(20);
  4406. gpio_set_value(wcd->reset_gpio, 1);
  4407. msleep(20);
  4408. return 0;
  4409. }
  4410. static int wcd9335_bring_up(struct wcd9335_codec *wcd)
  4411. {
  4412. struct regmap *rm = wcd->regmap;
  4413. int val, byte0;
  4414. regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
  4415. regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
  4416. if ((val < 0) || (byte0 < 0)) {
  4417. dev_err(wcd->dev, "WCD9335 CODEC version detection fail!\n");
  4418. return -EINVAL;
  4419. }
  4420. if (byte0 == 0x1) {
  4421. dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n");
  4422. wcd->version = WCD9335_VERSION_2_0;
  4423. regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01);
  4424. regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00);
  4425. regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
  4426. regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
  4427. regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
  4428. regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
  4429. regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
  4430. regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3);
  4431. } else {
  4432. dev_err(wcd->dev, "WCD9335 CODEC version not supported\n");
  4433. return -EINVAL;
  4434. }
  4435. return 0;
  4436. }
  4437. static int wcd9335_irq_init(struct wcd9335_codec *wcd)
  4438. {
  4439. int ret;
  4440. /*
  4441. * INTR1 consists of all possible interrupt sources Ear OCP,
  4442. * HPH OCP, MBHC, MAD, VBAT, and SVA
  4443. * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA
  4444. */
  4445. wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1");
  4446. if (wcd->intr1 < 0) {
  4447. if (wcd->intr1 != -EPROBE_DEFER)
  4448. dev_err(wcd->dev, "Unable to configure IRQ\n");
  4449. return wcd->intr1;
  4450. }
  4451. ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1,
  4452. IRQF_TRIGGER_HIGH, 0,
  4453. &wcd9335_regmap_irq1_chip, &wcd->irq_data);
  4454. if (ret)
  4455. dev_err(wcd->dev, "Failed to register IRQ chip: %d\n", ret);
  4456. return ret;
  4457. }
  4458. static int wcd9335_slim_probe(struct slim_device *slim)
  4459. {
  4460. struct device *dev = &slim->dev;
  4461. struct wcd9335_codec *wcd;
  4462. int ret;
  4463. wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
  4464. if (!wcd)
  4465. return -ENOMEM;
  4466. wcd->dev = dev;
  4467. ret = wcd9335_parse_dt(wcd);
  4468. if (ret) {
  4469. dev_err(dev, "Error parsing DT: %d\n", ret);
  4470. return ret;
  4471. }
  4472. ret = wcd9335_power_on_reset(wcd);
  4473. if (ret)
  4474. return ret;
  4475. dev_set_drvdata(dev, wcd);
  4476. return 0;
  4477. }
  4478. static int wcd9335_slim_status(struct slim_device *sdev,
  4479. enum slim_device_status status)
  4480. {
  4481. struct device *dev = &sdev->dev;
  4482. struct device_node *ifc_dev_np;
  4483. struct wcd9335_codec *wcd;
  4484. int ret;
  4485. wcd = dev_get_drvdata(dev);
  4486. ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0);
  4487. if (!ifc_dev_np) {
  4488. dev_err(dev, "No Interface device found\n");
  4489. return -EINVAL;
  4490. }
  4491. wcd->slim = sdev;
  4492. wcd->slim_ifc_dev = of_slim_get_device(sdev->ctrl, ifc_dev_np);
  4493. of_node_put(ifc_dev_np);
  4494. if (!wcd->slim_ifc_dev) {
  4495. dev_err(dev, "Unable to get SLIM Interface device\n");
  4496. return -EINVAL;
  4497. }
  4498. slim_get_logical_addr(wcd->slim_ifc_dev);
  4499. wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config);
  4500. if (IS_ERR(wcd->regmap)) {
  4501. dev_err(dev, "Failed to allocate slim register map\n");
  4502. return PTR_ERR(wcd->regmap);
  4503. }
  4504. wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev,
  4505. &wcd9335_ifc_regmap_config);
  4506. if (IS_ERR(wcd->if_regmap)) {
  4507. dev_err(dev, "Failed to allocate ifc register map\n");
  4508. return PTR_ERR(wcd->if_regmap);
  4509. }
  4510. ret = wcd9335_bring_up(wcd);
  4511. if (ret) {
  4512. dev_err(dev, "Failed to bringup WCD9335\n");
  4513. return ret;
  4514. }
  4515. ret = wcd9335_irq_init(wcd);
  4516. if (ret)
  4517. return ret;
  4518. wcd9335_probe(wcd);
  4519. return 0;
  4520. }
  4521. static const struct slim_device_id wcd9335_slim_id[] = {
  4522. {SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9335, 0x1, 0x0},
  4523. {}
  4524. };
  4525. MODULE_DEVICE_TABLE(slim, wcd9335_slim_id);
  4526. static struct slim_driver wcd9335_slim_driver = {
  4527. .driver = {
  4528. .name = "wcd9335-slim",
  4529. },
  4530. .probe = wcd9335_slim_probe,
  4531. .device_status = wcd9335_slim_status,
  4532. .id_table = wcd9335_slim_id,
  4533. };
  4534. module_slim_driver(wcd9335_slim_driver);
  4535. MODULE_DESCRIPTION("WCD9335 slim driver");
  4536. MODULE_LICENSE("GPL v2");
  4537. MODULE_ALIAS("slim:217:1a0:*");