madera.c 122 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. //
  3. // Cirrus Logic Madera class codecs common support
  4. //
  5. // Copyright (C) 2015-2019 Cirrus Logic, Inc. and
  6. // Cirrus Logic International Semiconductor Ltd.
  7. //
  8. #include <linux/delay.h>
  9. #include <linux/gcd.h>
  10. #include <linux/module.h>
  11. #include <linux/pm_runtime.h>
  12. #include <linux/slab.h>
  13. #include <sound/pcm.h>
  14. #include <sound/pcm_params.h>
  15. #include <sound/tlv.h>
  16. #include <linux/irqchip/irq-madera.h>
  17. #include <linux/mfd/madera/core.h>
  18. #include <linux/mfd/madera/registers.h>
  19. #include <linux/mfd/madera/pdata.h>
  20. #include <sound/madera-pdata.h>
  21. #include <dt-bindings/sound/madera.h>
  22. #include "madera.h"
  23. #define MADERA_AIF_BCLK_CTRL 0x00
  24. #define MADERA_AIF_TX_PIN_CTRL 0x01
  25. #define MADERA_AIF_RX_PIN_CTRL 0x02
  26. #define MADERA_AIF_RATE_CTRL 0x03
  27. #define MADERA_AIF_FORMAT 0x04
  28. #define MADERA_AIF_RX_BCLK_RATE 0x06
  29. #define MADERA_AIF_FRAME_CTRL_1 0x07
  30. #define MADERA_AIF_FRAME_CTRL_2 0x08
  31. #define MADERA_AIF_FRAME_CTRL_3 0x09
  32. #define MADERA_AIF_FRAME_CTRL_4 0x0A
  33. #define MADERA_AIF_FRAME_CTRL_5 0x0B
  34. #define MADERA_AIF_FRAME_CTRL_6 0x0C
  35. #define MADERA_AIF_FRAME_CTRL_7 0x0D
  36. #define MADERA_AIF_FRAME_CTRL_8 0x0E
  37. #define MADERA_AIF_FRAME_CTRL_9 0x0F
  38. #define MADERA_AIF_FRAME_CTRL_10 0x10
  39. #define MADERA_AIF_FRAME_CTRL_11 0x11
  40. #define MADERA_AIF_FRAME_CTRL_12 0x12
  41. #define MADERA_AIF_FRAME_CTRL_13 0x13
  42. #define MADERA_AIF_FRAME_CTRL_14 0x14
  43. #define MADERA_AIF_FRAME_CTRL_15 0x15
  44. #define MADERA_AIF_FRAME_CTRL_16 0x16
  45. #define MADERA_AIF_FRAME_CTRL_17 0x17
  46. #define MADERA_AIF_FRAME_CTRL_18 0x18
  47. #define MADERA_AIF_TX_ENABLES 0x19
  48. #define MADERA_AIF_RX_ENABLES 0x1A
  49. #define MADERA_AIF_FORCE_WRITE 0x1B
  50. #define MADERA_DSP_CONFIG_1_OFFS 0x00
  51. #define MADERA_DSP_CONFIG_2_OFFS 0x02
  52. #define MADERA_DSP_CLK_SEL_MASK 0x70000
  53. #define MADERA_DSP_CLK_SEL_SHIFT 16
  54. #define MADERA_DSP_RATE_MASK 0x7800
  55. #define MADERA_DSP_RATE_SHIFT 11
  56. #define MADERA_SYSCLK_6MHZ 0
  57. #define MADERA_SYSCLK_12MHZ 1
  58. #define MADERA_SYSCLK_24MHZ 2
  59. #define MADERA_SYSCLK_49MHZ 3
  60. #define MADERA_SYSCLK_98MHZ 4
  61. #define MADERA_DSPCLK_9MHZ 0
  62. #define MADERA_DSPCLK_18MHZ 1
  63. #define MADERA_DSPCLK_36MHZ 2
  64. #define MADERA_DSPCLK_73MHZ 3
  65. #define MADERA_DSPCLK_147MHZ 4
  66. #define MADERA_FLL_VCO_CORNER 141900000
  67. #define MADERA_FLL_MAX_FREF 13500000
  68. #define MADERA_FLL_MAX_N 1023
  69. #define MADERA_FLL_MIN_FOUT 90000000
  70. #define MADERA_FLL_MAX_FOUT 100000000
  71. #define MADERA_FLL_MAX_FRATIO 16
  72. #define MADERA_FLL_MAX_REFDIV 8
  73. #define MADERA_FLL_OUTDIV 3
  74. #define MADERA_FLL_VCO_MULT 3
  75. #define MADERA_FLLAO_MAX_FREF 12288000
  76. #define MADERA_FLLAO_MIN_N 4
  77. #define MADERA_FLLAO_MAX_N 1023
  78. #define MADERA_FLLAO_MAX_FBDIV 254
  79. #define MADERA_FLLHJ_INT_MAX_N 1023
  80. #define MADERA_FLLHJ_INT_MIN_N 1
  81. #define MADERA_FLLHJ_FRAC_MAX_N 255
  82. #define MADERA_FLLHJ_FRAC_MIN_N 4
  83. #define MADERA_FLLHJ_LOW_THRESH 192000
  84. #define MADERA_FLLHJ_MID_THRESH 1152000
  85. #define MADERA_FLLHJ_MAX_THRESH 13000000
  86. #define MADERA_FLLHJ_LOW_GAINS 0x23f0
  87. #define MADERA_FLLHJ_MID_GAINS 0x22f2
  88. #define MADERA_FLLHJ_HIGH_GAINS 0x21f0
  89. #define MADERA_FLL_SYNCHRONISER_OFFS 0x10
  90. #define CS47L35_FLL_SYNCHRONISER_OFFS 0xE
  91. #define MADERA_FLL_CONTROL_1_OFFS 0x1
  92. #define MADERA_FLL_CONTROL_2_OFFS 0x2
  93. #define MADERA_FLL_CONTROL_3_OFFS 0x3
  94. #define MADERA_FLL_CONTROL_4_OFFS 0x4
  95. #define MADERA_FLL_CONTROL_5_OFFS 0x5
  96. #define MADERA_FLL_CONTROL_6_OFFS 0x6
  97. #define MADERA_FLL_GAIN_OFFS 0x8
  98. #define MADERA_FLL_CONTROL_7_OFFS 0x9
  99. #define MADERA_FLL_EFS_2_OFFS 0xA
  100. #define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1
  101. #define MADERA_FLL_SYNCHRONISER_2_OFFS 0x2
  102. #define MADERA_FLL_SYNCHRONISER_3_OFFS 0x3
  103. #define MADERA_FLL_SYNCHRONISER_4_OFFS 0x4
  104. #define MADERA_FLL_SYNCHRONISER_5_OFFS 0x5
  105. #define MADERA_FLL_SYNCHRONISER_6_OFFS 0x6
  106. #define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7
  107. #define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9
  108. #define MADERA_FLL_GPIO_CLOCK_OFFS 0xA
  109. #define MADERA_FLL_CONTROL_10_OFFS 0xA
  110. #define MADERA_FLL_CONTROL_11_OFFS 0xB
  111. #define MADERA_FLL1_DIGITAL_TEST_1_OFFS 0xD
  112. #define MADERA_FLLAO_CONTROL_1_OFFS 0x1
  113. #define MADERA_FLLAO_CONTROL_2_OFFS 0x2
  114. #define MADERA_FLLAO_CONTROL_3_OFFS 0x3
  115. #define MADERA_FLLAO_CONTROL_4_OFFS 0x4
  116. #define MADERA_FLLAO_CONTROL_5_OFFS 0x5
  117. #define MADERA_FLLAO_CONTROL_6_OFFS 0x6
  118. #define MADERA_FLLAO_CONTROL_7_OFFS 0x8
  119. #define MADERA_FLLAO_CONTROL_8_OFFS 0xA
  120. #define MADERA_FLLAO_CONTROL_9_OFFS 0xB
  121. #define MADERA_FLLAO_CONTROL_10_OFFS 0xC
  122. #define MADERA_FLLAO_CONTROL_11_OFFS 0xD
  123. #define MADERA_FMT_DSP_MODE_A 0
  124. #define MADERA_FMT_DSP_MODE_B 1
  125. #define MADERA_FMT_I2S_MODE 2
  126. #define MADERA_FMT_LEFT_JUSTIFIED_MODE 3
  127. #define madera_fll_err(_fll, fmt, ...) \
  128. dev_err(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  129. #define madera_fll_warn(_fll, fmt, ...) \
  130. dev_warn(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  131. #define madera_fll_dbg(_fll, fmt, ...) \
  132. dev_dbg(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  133. #define madera_aif_err(_dai, fmt, ...) \
  134. dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  135. #define madera_aif_warn(_dai, fmt, ...) \
  136. dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  137. #define madera_aif_dbg(_dai, fmt, ...) \
  138. dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  139. static const int madera_dsp_bus_error_irqs[MADERA_MAX_ADSP] = {
  140. MADERA_IRQ_DSP1_BUS_ERR,
  141. MADERA_IRQ_DSP2_BUS_ERR,
  142. MADERA_IRQ_DSP3_BUS_ERR,
  143. MADERA_IRQ_DSP4_BUS_ERR,
  144. MADERA_IRQ_DSP5_BUS_ERR,
  145. MADERA_IRQ_DSP6_BUS_ERR,
  146. MADERA_IRQ_DSP7_BUS_ERR,
  147. };
  148. int madera_clk_ev(struct snd_soc_dapm_widget *w,
  149. struct snd_kcontrol *kcontrol, int event)
  150. {
  151. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  152. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  153. struct madera *madera = priv->madera;
  154. unsigned int val;
  155. int clk_idx;
  156. int ret;
  157. ret = regmap_read(madera->regmap, w->reg, &val);
  158. if (ret) {
  159. dev_err(madera->dev, "Failed to check clock source: %d\n", ret);
  160. return ret;
  161. }
  162. switch ((val & MADERA_SYSCLK_SRC_MASK) >> MADERA_SYSCLK_SRC_SHIFT) {
  163. case MADERA_CLK_SRC_MCLK1:
  164. clk_idx = MADERA_MCLK1;
  165. break;
  166. case MADERA_CLK_SRC_MCLK2:
  167. clk_idx = MADERA_MCLK2;
  168. break;
  169. case MADERA_CLK_SRC_MCLK3:
  170. clk_idx = MADERA_MCLK3;
  171. break;
  172. default:
  173. return 0;
  174. }
  175. switch (event) {
  176. case SND_SOC_DAPM_PRE_PMU:
  177. return clk_prepare_enable(madera->mclk[clk_idx].clk);
  178. case SND_SOC_DAPM_POST_PMD:
  179. clk_disable_unprepare(madera->mclk[clk_idx].clk);
  180. return 0;
  181. default:
  182. return 0;
  183. }
  184. }
  185. EXPORT_SYMBOL_GPL(madera_clk_ev);
  186. static void madera_spin_sysclk(struct madera_priv *priv)
  187. {
  188. struct madera *madera = priv->madera;
  189. unsigned int val;
  190. int ret, i;
  191. /* Skip this if the chip is down */
  192. if (pm_runtime_suspended(madera->dev))
  193. return;
  194. /*
  195. * Just read a register a few times to ensure the internal
  196. * oscillator sends out a few clocks.
  197. */
  198. for (i = 0; i < 4; i++) {
  199. ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &val);
  200. if (ret)
  201. dev_err(madera->dev,
  202. "Failed to read sysclk spin %d: %d\n", i, ret);
  203. }
  204. udelay(300);
  205. }
  206. int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
  207. struct snd_kcontrol *kcontrol, int event)
  208. {
  209. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  210. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  211. switch (event) {
  212. case SND_SOC_DAPM_POST_PMU:
  213. case SND_SOC_DAPM_PRE_PMD:
  214. madera_spin_sysclk(priv);
  215. break;
  216. default:
  217. break;
  218. }
  219. return madera_clk_ev(w, kcontrol, event);
  220. }
  221. EXPORT_SYMBOL_GPL(madera_sysclk_ev);
  222. static int madera_check_speaker_overheat(struct madera *madera,
  223. bool *warn, bool *shutdown)
  224. {
  225. unsigned int val;
  226. int ret;
  227. ret = regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_15, &val);
  228. if (ret) {
  229. dev_err(madera->dev, "Failed to read thermal status: %d\n",
  230. ret);
  231. return ret;
  232. }
  233. *warn = val & MADERA_SPK_OVERHEAT_WARN_STS1;
  234. *shutdown = val & MADERA_SPK_OVERHEAT_STS1;
  235. return 0;
  236. }
  237. int madera_spk_ev(struct snd_soc_dapm_widget *w,
  238. struct snd_kcontrol *kcontrol, int event)
  239. {
  240. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  241. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  242. struct madera *madera = priv->madera;
  243. bool warn, shutdown;
  244. int ret;
  245. switch (event) {
  246. case SND_SOC_DAPM_POST_PMU:
  247. ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
  248. if (ret)
  249. return ret;
  250. if (shutdown) {
  251. dev_crit(madera->dev,
  252. "Speaker not enabled due to temperature\n");
  253. return -EBUSY;
  254. }
  255. regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
  256. 1 << w->shift, 1 << w->shift);
  257. break;
  258. case SND_SOC_DAPM_PRE_PMD:
  259. regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
  260. 1 << w->shift, 0);
  261. break;
  262. default:
  263. break;
  264. }
  265. return 0;
  266. }
  267. EXPORT_SYMBOL_GPL(madera_spk_ev);
  268. static irqreturn_t madera_thermal_warn(int irq, void *data)
  269. {
  270. struct madera *madera = data;
  271. bool warn, shutdown;
  272. int ret;
  273. ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
  274. if (ret || shutdown) { /* for safety attempt to shutdown on error */
  275. dev_crit(madera->dev, "Thermal shutdown\n");
  276. ret = regmap_update_bits(madera->regmap,
  277. MADERA_OUTPUT_ENABLES_1,
  278. MADERA_OUT4L_ENA |
  279. MADERA_OUT4R_ENA, 0);
  280. if (ret != 0)
  281. dev_crit(madera->dev,
  282. "Failed to disable speaker outputs: %d\n",
  283. ret);
  284. } else if (warn) {
  285. dev_alert(madera->dev, "Thermal warning\n");
  286. } else {
  287. dev_info(madera->dev, "Spurious thermal warning\n");
  288. return IRQ_NONE;
  289. }
  290. return IRQ_HANDLED;
  291. }
  292. int madera_init_overheat(struct madera_priv *priv)
  293. {
  294. struct madera *madera = priv->madera;
  295. struct device *dev = madera->dev;
  296. int ret;
  297. ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN,
  298. "Thermal warning", madera_thermal_warn,
  299. madera);
  300. if (ret)
  301. dev_err(dev, "Failed to get thermal warning IRQ: %d\n", ret);
  302. ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT,
  303. "Thermal shutdown", madera_thermal_warn,
  304. madera);
  305. if (ret)
  306. dev_err(dev, "Failed to get thermal shutdown IRQ: %d\n", ret);
  307. return 0;
  308. }
  309. EXPORT_SYMBOL_GPL(madera_init_overheat);
  310. int madera_free_overheat(struct madera_priv *priv)
  311. {
  312. struct madera *madera = priv->madera;
  313. madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN, madera);
  314. madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT, madera);
  315. return 0;
  316. }
  317. EXPORT_SYMBOL_GPL(madera_free_overheat);
  318. static int madera_get_variable_u32_array(struct device *dev,
  319. const char *propname,
  320. u32 *dest, int n_max,
  321. int multiple)
  322. {
  323. int n, ret;
  324. n = device_property_count_u32(dev, propname);
  325. if (n < 0) {
  326. if (n == -EINVAL)
  327. return 0; /* missing, ignore */
  328. dev_warn(dev, "%s malformed (%d)\n", propname, n);
  329. return n;
  330. } else if ((n % multiple) != 0) {
  331. dev_warn(dev, "%s not a multiple of %d entries\n",
  332. propname, multiple);
  333. return -EINVAL;
  334. }
  335. if (n > n_max)
  336. n = n_max;
  337. ret = device_property_read_u32_array(dev, propname, dest, n);
  338. if (ret < 0)
  339. return ret;
  340. return n;
  341. }
  342. static void madera_prop_get_inmode(struct madera_priv *priv)
  343. {
  344. struct madera *madera = priv->madera;
  345. struct madera_codec_pdata *pdata = &madera->pdata.codec;
  346. u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS];
  347. int n, i, in_idx, ch_idx;
  348. BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode) != MADERA_MAX_INPUT);
  349. BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode[0]) != MADERA_MAX_MUXED_CHANNELS);
  350. n = madera_get_variable_u32_array(madera->dev, "cirrus,inmode",
  351. tmp, ARRAY_SIZE(tmp),
  352. MADERA_MAX_MUXED_CHANNELS);
  353. if (n < 0)
  354. return;
  355. in_idx = 0;
  356. ch_idx = 0;
  357. for (i = 0; i < n; ++i) {
  358. pdata->inmode[in_idx][ch_idx] = tmp[i];
  359. if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) {
  360. ch_idx = 0;
  361. ++in_idx;
  362. }
  363. }
  364. }
  365. static void madera_prop_get_pdata(struct madera_priv *priv)
  366. {
  367. struct madera *madera = priv->madera;
  368. struct madera_codec_pdata *pdata = &madera->pdata.codec;
  369. u32 out_mono[ARRAY_SIZE(pdata->out_mono)];
  370. int i, n;
  371. madera_prop_get_inmode(priv);
  372. n = madera_get_variable_u32_array(madera->dev, "cirrus,out-mono",
  373. out_mono, ARRAY_SIZE(out_mono), 1);
  374. if (n > 0)
  375. for (i = 0; i < n; ++i)
  376. pdata->out_mono[i] = !!out_mono[i];
  377. madera_get_variable_u32_array(madera->dev,
  378. "cirrus,max-channels-clocked",
  379. pdata->max_channels_clocked,
  380. ARRAY_SIZE(pdata->max_channels_clocked),
  381. 1);
  382. madera_get_variable_u32_array(madera->dev, "cirrus,pdm-fmt",
  383. pdata->pdm_fmt,
  384. ARRAY_SIZE(pdata->pdm_fmt), 1);
  385. madera_get_variable_u32_array(madera->dev, "cirrus,pdm-mute",
  386. pdata->pdm_mute,
  387. ARRAY_SIZE(pdata->pdm_mute), 1);
  388. madera_get_variable_u32_array(madera->dev, "cirrus,dmic-ref",
  389. pdata->dmic_ref,
  390. ARRAY_SIZE(pdata->dmic_ref), 1);
  391. }
  392. int madera_core_init(struct madera_priv *priv)
  393. {
  394. int i;
  395. /* trap undersized array initializers */
  396. BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]);
  397. BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]);
  398. if (!dev_get_platdata(priv->madera->dev))
  399. madera_prop_get_pdata(priv);
  400. mutex_init(&priv->rate_lock);
  401. for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++)
  402. priv->madera->out_clamp[i] = true;
  403. return 0;
  404. }
  405. EXPORT_SYMBOL_GPL(madera_core_init);
  406. int madera_core_free(struct madera_priv *priv)
  407. {
  408. mutex_destroy(&priv->rate_lock);
  409. return 0;
  410. }
  411. EXPORT_SYMBOL_GPL(madera_core_free);
  412. static void madera_debug_dump_domain_groups(const struct madera_priv *priv)
  413. {
  414. struct madera *madera = priv->madera;
  415. int i;
  416. for (i = 0; i < ARRAY_SIZE(priv->domain_group_ref); ++i)
  417. dev_dbg(madera->dev, "domain_grp_ref[%d]=%d\n", i,
  418. priv->domain_group_ref[i]);
  419. }
  420. int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
  421. struct snd_kcontrol *kcontrol,
  422. int event)
  423. {
  424. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  425. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  426. int dom_grp = w->shift;
  427. if (dom_grp >= ARRAY_SIZE(priv->domain_group_ref)) {
  428. WARN(true, "%s dom_grp exceeds array size\n", __func__);
  429. return -EINVAL;
  430. }
  431. /*
  432. * We can't rely on the DAPM mutex for locking because we need a lock
  433. * that can safely be called in hw_params
  434. */
  435. mutex_lock(&priv->rate_lock);
  436. switch (event) {
  437. case SND_SOC_DAPM_PRE_PMU:
  438. dev_dbg(priv->madera->dev, "Inc ref on domain group %d\n",
  439. dom_grp);
  440. ++priv->domain_group_ref[dom_grp];
  441. break;
  442. case SND_SOC_DAPM_POST_PMD:
  443. dev_dbg(priv->madera->dev, "Dec ref on domain group %d\n",
  444. dom_grp);
  445. --priv->domain_group_ref[dom_grp];
  446. break;
  447. default:
  448. break;
  449. }
  450. madera_debug_dump_domain_groups(priv);
  451. mutex_unlock(&priv->rate_lock);
  452. return 0;
  453. }
  454. EXPORT_SYMBOL_GPL(madera_domain_clk_ev);
  455. int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
  456. struct snd_ctl_elem_value *ucontrol)
  457. {
  458. struct snd_soc_component *component =
  459. snd_soc_dapm_kcontrol_component(kcontrol);
  460. struct snd_soc_dapm_context *dapm =
  461. snd_soc_dapm_kcontrol_dapm(kcontrol);
  462. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  463. struct madera *madera = priv->madera;
  464. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  465. unsigned int ep_sel, mux, change;
  466. bool out_mono;
  467. int ret;
  468. if (ucontrol->value.enumerated.item[0] > e->items - 1)
  469. return -EINVAL;
  470. mux = ucontrol->value.enumerated.item[0];
  471. snd_soc_dapm_mutex_lock(dapm);
  472. ep_sel = mux << MADERA_EP_SEL_SHIFT;
  473. change = snd_soc_component_test_bits(component, MADERA_OUTPUT_ENABLES_1,
  474. MADERA_EP_SEL_MASK,
  475. ep_sel);
  476. if (!change)
  477. goto end;
  478. /* EP_SEL should not be modified while HP or EP driver is enabled */
  479. ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
  480. MADERA_OUT1L_ENA | MADERA_OUT1R_ENA, 0);
  481. if (ret)
  482. dev_warn(madera->dev, "Failed to disable outputs: %d\n", ret);
  483. usleep_range(2000, 3000); /* wait for wseq to complete */
  484. /* change demux setting */
  485. ret = 0;
  486. if (madera->out_clamp[0])
  487. ret = regmap_update_bits(madera->regmap,
  488. MADERA_OUTPUT_ENABLES_1,
  489. MADERA_EP_SEL_MASK, ep_sel);
  490. if (ret) {
  491. dev_err(madera->dev, "Failed to set OUT1 demux: %d\n", ret);
  492. } else {
  493. /* apply correct setting for mono mode */
  494. if (!ep_sel && !madera->pdata.codec.out_mono[0])
  495. out_mono = false; /* stereo HP */
  496. else
  497. out_mono = true; /* EP or mono HP */
  498. ret = madera_set_output_mode(component, 1, out_mono);
  499. if (ret)
  500. dev_warn(madera->dev,
  501. "Failed to set output mode: %d\n", ret);
  502. }
  503. /*
  504. * if HPDET has disabled the clamp while switching to HPOUT
  505. * OUT1 should remain disabled
  506. */
  507. if (ep_sel ||
  508. (madera->out_clamp[0] && !madera->out_shorted[0])) {
  509. ret = regmap_update_bits(madera->regmap,
  510. MADERA_OUTPUT_ENABLES_1,
  511. MADERA_OUT1L_ENA | MADERA_OUT1R_ENA,
  512. madera->hp_ena);
  513. if (ret)
  514. dev_warn(madera->dev,
  515. "Failed to restore earpiece outputs: %d\n",
  516. ret);
  517. else if (madera->hp_ena)
  518. msleep(34); /* wait for enable wseq */
  519. else
  520. usleep_range(2000, 3000); /* wait for disable wseq */
  521. }
  522. end:
  523. snd_soc_dapm_mutex_unlock(dapm);
  524. ret = snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
  525. if (ret < 0) {
  526. dev_err(madera->dev, "Failed to update demux power state: %d\n", ret);
  527. return ret;
  528. }
  529. return change;
  530. }
  531. EXPORT_SYMBOL_GPL(madera_out1_demux_put);
  532. int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
  533. struct snd_ctl_elem_value *ucontrol)
  534. {
  535. struct snd_soc_component *component =
  536. snd_soc_dapm_kcontrol_component(kcontrol);
  537. unsigned int val;
  538. val = snd_soc_component_read(component, MADERA_OUTPUT_ENABLES_1);
  539. val &= MADERA_EP_SEL_MASK;
  540. val >>= MADERA_EP_SEL_SHIFT;
  541. ucontrol->value.enumerated.item[0] = val;
  542. return 0;
  543. }
  544. EXPORT_SYMBOL_GPL(madera_out1_demux_get);
  545. static int madera_inmux_put(struct snd_kcontrol *kcontrol,
  546. struct snd_ctl_elem_value *ucontrol)
  547. {
  548. struct snd_soc_component *component =
  549. snd_soc_dapm_kcontrol_component(kcontrol);
  550. struct snd_soc_dapm_context *dapm =
  551. snd_soc_dapm_kcontrol_dapm(kcontrol);
  552. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  553. struct madera *madera = priv->madera;
  554. struct regmap *regmap = madera->regmap;
  555. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  556. unsigned int mux, val, mask;
  557. unsigned int inmode;
  558. bool changed;
  559. int ret;
  560. mux = ucontrol->value.enumerated.item[0];
  561. if (mux > 1)
  562. return -EINVAL;
  563. val = mux << e->shift_l;
  564. mask = (e->mask << e->shift_l) | MADERA_IN1L_SRC_SE_MASK;
  565. switch (e->reg) {
  566. case MADERA_ADC_DIGITAL_VOLUME_1L:
  567. inmode = madera->pdata.codec.inmode[0][2 * mux];
  568. break;
  569. case MADERA_ADC_DIGITAL_VOLUME_1R:
  570. inmode = madera->pdata.codec.inmode[0][1 + (2 * mux)];
  571. break;
  572. case MADERA_ADC_DIGITAL_VOLUME_2L:
  573. inmode = madera->pdata.codec.inmode[1][2 * mux];
  574. break;
  575. case MADERA_ADC_DIGITAL_VOLUME_2R:
  576. inmode = madera->pdata.codec.inmode[1][1 + (2 * mux)];
  577. break;
  578. default:
  579. return -EINVAL;
  580. }
  581. if (inmode & MADERA_INMODE_SE)
  582. val |= 1 << MADERA_IN1L_SRC_SE_SHIFT;
  583. dev_dbg(madera->dev, "mux=%u reg=0x%x inmode=0x%x mask=0x%x val=0x%x\n",
  584. mux, e->reg, inmode, mask, val);
  585. ret = regmap_update_bits_check(regmap, e->reg, mask, val, &changed);
  586. if (ret < 0)
  587. return ret;
  588. if (changed)
  589. return snd_soc_dapm_mux_update_power(dapm, kcontrol,
  590. mux, e, NULL);
  591. else
  592. return 0;
  593. }
  594. static const char * const madera_inmux_texts[] = {
  595. "A",
  596. "B",
  597. };
  598. static SOC_ENUM_SINGLE_DECL(madera_in1muxl_enum,
  599. MADERA_ADC_DIGITAL_VOLUME_1L,
  600. MADERA_IN1L_SRC_SHIFT,
  601. madera_inmux_texts);
  602. static SOC_ENUM_SINGLE_DECL(madera_in1muxr_enum,
  603. MADERA_ADC_DIGITAL_VOLUME_1R,
  604. MADERA_IN1R_SRC_SHIFT,
  605. madera_inmux_texts);
  606. static SOC_ENUM_SINGLE_DECL(madera_in2muxl_enum,
  607. MADERA_ADC_DIGITAL_VOLUME_2L,
  608. MADERA_IN2L_SRC_SHIFT,
  609. madera_inmux_texts);
  610. static SOC_ENUM_SINGLE_DECL(madera_in2muxr_enum,
  611. MADERA_ADC_DIGITAL_VOLUME_2R,
  612. MADERA_IN2R_SRC_SHIFT,
  613. madera_inmux_texts);
  614. const struct snd_kcontrol_new madera_inmux[] = {
  615. SOC_DAPM_ENUM_EXT("IN1L Mux", madera_in1muxl_enum,
  616. snd_soc_dapm_get_enum_double, madera_inmux_put),
  617. SOC_DAPM_ENUM_EXT("IN1R Mux", madera_in1muxr_enum,
  618. snd_soc_dapm_get_enum_double, madera_inmux_put),
  619. SOC_DAPM_ENUM_EXT("IN2L Mux", madera_in2muxl_enum,
  620. snd_soc_dapm_get_enum_double, madera_inmux_put),
  621. SOC_DAPM_ENUM_EXT("IN2R Mux", madera_in2muxr_enum,
  622. snd_soc_dapm_get_enum_double, madera_inmux_put),
  623. };
  624. EXPORT_SYMBOL_GPL(madera_inmux);
  625. static const char * const madera_dmode_texts[] = {
  626. "Analog",
  627. "Digital",
  628. };
  629. static SOC_ENUM_SINGLE_DECL(madera_in1dmode_enum,
  630. MADERA_IN1L_CONTROL,
  631. MADERA_IN1_MODE_SHIFT,
  632. madera_dmode_texts);
  633. static SOC_ENUM_SINGLE_DECL(madera_in2dmode_enum,
  634. MADERA_IN2L_CONTROL,
  635. MADERA_IN2_MODE_SHIFT,
  636. madera_dmode_texts);
  637. static SOC_ENUM_SINGLE_DECL(madera_in3dmode_enum,
  638. MADERA_IN3L_CONTROL,
  639. MADERA_IN3_MODE_SHIFT,
  640. madera_dmode_texts);
  641. const struct snd_kcontrol_new madera_inmode[] = {
  642. SOC_DAPM_ENUM("IN1 Mode", madera_in1dmode_enum),
  643. SOC_DAPM_ENUM("IN2 Mode", madera_in2dmode_enum),
  644. SOC_DAPM_ENUM("IN3 Mode", madera_in3dmode_enum),
  645. };
  646. EXPORT_SYMBOL_GPL(madera_inmode);
  647. static bool madera_can_change_grp_rate(const struct madera_priv *priv,
  648. unsigned int reg)
  649. {
  650. int count;
  651. switch (reg) {
  652. case MADERA_FX_CTRL1:
  653. count = priv->domain_group_ref[MADERA_DOM_GRP_FX];
  654. break;
  655. case MADERA_ASRC1_RATE1:
  656. case MADERA_ASRC1_RATE2:
  657. count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC1];
  658. break;
  659. case MADERA_ASRC2_RATE1:
  660. case MADERA_ASRC2_RATE2:
  661. count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC2];
  662. break;
  663. case MADERA_ISRC_1_CTRL_1:
  664. case MADERA_ISRC_1_CTRL_2:
  665. count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC1];
  666. break;
  667. case MADERA_ISRC_2_CTRL_1:
  668. case MADERA_ISRC_2_CTRL_2:
  669. count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC2];
  670. break;
  671. case MADERA_ISRC_3_CTRL_1:
  672. case MADERA_ISRC_3_CTRL_2:
  673. count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC3];
  674. break;
  675. case MADERA_ISRC_4_CTRL_1:
  676. case MADERA_ISRC_4_CTRL_2:
  677. count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC4];
  678. break;
  679. case MADERA_OUTPUT_RATE_1:
  680. count = priv->domain_group_ref[MADERA_DOM_GRP_OUT];
  681. break;
  682. case MADERA_SPD1_TX_CONTROL:
  683. count = priv->domain_group_ref[MADERA_DOM_GRP_SPD];
  684. break;
  685. case MADERA_DSP1_CONFIG_1:
  686. case MADERA_DSP1_CONFIG_2:
  687. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP1];
  688. break;
  689. case MADERA_DSP2_CONFIG_1:
  690. case MADERA_DSP2_CONFIG_2:
  691. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP2];
  692. break;
  693. case MADERA_DSP3_CONFIG_1:
  694. case MADERA_DSP3_CONFIG_2:
  695. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP3];
  696. break;
  697. case MADERA_DSP4_CONFIG_1:
  698. case MADERA_DSP4_CONFIG_2:
  699. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP4];
  700. break;
  701. case MADERA_DSP5_CONFIG_1:
  702. case MADERA_DSP5_CONFIG_2:
  703. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP5];
  704. break;
  705. case MADERA_DSP6_CONFIG_1:
  706. case MADERA_DSP6_CONFIG_2:
  707. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP6];
  708. break;
  709. case MADERA_DSP7_CONFIG_1:
  710. case MADERA_DSP7_CONFIG_2:
  711. count = priv->domain_group_ref[MADERA_DOM_GRP_DSP7];
  712. break;
  713. case MADERA_AIF1_RATE_CTRL:
  714. count = priv->domain_group_ref[MADERA_DOM_GRP_AIF1];
  715. break;
  716. case MADERA_AIF2_RATE_CTRL:
  717. count = priv->domain_group_ref[MADERA_DOM_GRP_AIF2];
  718. break;
  719. case MADERA_AIF3_RATE_CTRL:
  720. count = priv->domain_group_ref[MADERA_DOM_GRP_AIF3];
  721. break;
  722. case MADERA_AIF4_RATE_CTRL:
  723. count = priv->domain_group_ref[MADERA_DOM_GRP_AIF4];
  724. break;
  725. case MADERA_SLIMBUS_RATES_1:
  726. case MADERA_SLIMBUS_RATES_2:
  727. case MADERA_SLIMBUS_RATES_3:
  728. case MADERA_SLIMBUS_RATES_4:
  729. case MADERA_SLIMBUS_RATES_5:
  730. case MADERA_SLIMBUS_RATES_6:
  731. case MADERA_SLIMBUS_RATES_7:
  732. case MADERA_SLIMBUS_RATES_8:
  733. count = priv->domain_group_ref[MADERA_DOM_GRP_SLIMBUS];
  734. break;
  735. case MADERA_PWM_DRIVE_1:
  736. count = priv->domain_group_ref[MADERA_DOM_GRP_PWM];
  737. break;
  738. default:
  739. return false;
  740. }
  741. dev_dbg(priv->madera->dev, "Rate reg 0x%x group ref %d\n", reg, count);
  742. if (count)
  743. return false;
  744. else
  745. return true;
  746. }
  747. static int madera_adsp_rate_get(struct snd_kcontrol *kcontrol,
  748. struct snd_ctl_elem_value *ucontrol)
  749. {
  750. struct snd_soc_component *component =
  751. snd_soc_kcontrol_component(kcontrol);
  752. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  753. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  754. unsigned int cached_rate;
  755. const int adsp_num = e->shift_l;
  756. int item;
  757. mutex_lock(&priv->rate_lock);
  758. cached_rate = priv->adsp_rate_cache[adsp_num];
  759. mutex_unlock(&priv->rate_lock);
  760. item = snd_soc_enum_val_to_item(e, cached_rate);
  761. ucontrol->value.enumerated.item[0] = item;
  762. return 0;
  763. }
  764. static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol,
  765. struct snd_ctl_elem_value *ucontrol)
  766. {
  767. struct snd_soc_component *component =
  768. snd_soc_kcontrol_component(kcontrol);
  769. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  770. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  771. const int adsp_num = e->shift_l;
  772. const unsigned int item = ucontrol->value.enumerated.item[0];
  773. int ret = 0;
  774. if (item >= e->items)
  775. return -EINVAL;
  776. /*
  777. * We don't directly write the rate register here but we want to
  778. * maintain consistent behaviour that rate domains cannot be changed
  779. * while in use since this is a hardware requirement
  780. */
  781. mutex_lock(&priv->rate_lock);
  782. if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].cs_dsp.base)) {
  783. dev_warn(priv->madera->dev,
  784. "Cannot change '%s' while in use by active audio paths\n",
  785. kcontrol->id.name);
  786. ret = -EBUSY;
  787. } else if (priv->adsp_rate_cache[adsp_num] != e->values[item]) {
  788. /* Volatile register so defer until the codec is powered up */
  789. priv->adsp_rate_cache[adsp_num] = e->values[item];
  790. ret = 1;
  791. }
  792. mutex_unlock(&priv->rate_lock);
  793. return ret;
  794. }
  795. static const struct soc_enum madera_adsp_rate_enum[] = {
  796. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0, 0xf, MADERA_RATE_ENUM_SIZE,
  797. madera_rate_text, madera_rate_val),
  798. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 1, 0xf, MADERA_RATE_ENUM_SIZE,
  799. madera_rate_text, madera_rate_val),
  800. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 2, 0xf, MADERA_RATE_ENUM_SIZE,
  801. madera_rate_text, madera_rate_val),
  802. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 3, 0xf, MADERA_RATE_ENUM_SIZE,
  803. madera_rate_text, madera_rate_val),
  804. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 4, 0xf, MADERA_RATE_ENUM_SIZE,
  805. madera_rate_text, madera_rate_val),
  806. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 5, 0xf, MADERA_RATE_ENUM_SIZE,
  807. madera_rate_text, madera_rate_val),
  808. SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 6, 0xf, MADERA_RATE_ENUM_SIZE,
  809. madera_rate_text, madera_rate_val),
  810. };
  811. const struct snd_kcontrol_new madera_adsp_rate_controls[] = {
  812. SOC_ENUM_EXT("DSP1 Rate", madera_adsp_rate_enum[0],
  813. madera_adsp_rate_get, madera_adsp_rate_put),
  814. SOC_ENUM_EXT("DSP2 Rate", madera_adsp_rate_enum[1],
  815. madera_adsp_rate_get, madera_adsp_rate_put),
  816. SOC_ENUM_EXT("DSP3 Rate", madera_adsp_rate_enum[2],
  817. madera_adsp_rate_get, madera_adsp_rate_put),
  818. SOC_ENUM_EXT("DSP4 Rate", madera_adsp_rate_enum[3],
  819. madera_adsp_rate_get, madera_adsp_rate_put),
  820. SOC_ENUM_EXT("DSP5 Rate", madera_adsp_rate_enum[4],
  821. madera_adsp_rate_get, madera_adsp_rate_put),
  822. SOC_ENUM_EXT("DSP6 Rate", madera_adsp_rate_enum[5],
  823. madera_adsp_rate_get, madera_adsp_rate_put),
  824. SOC_ENUM_EXT("DSP7 Rate", madera_adsp_rate_enum[6],
  825. madera_adsp_rate_get, madera_adsp_rate_put),
  826. };
  827. EXPORT_SYMBOL_GPL(madera_adsp_rate_controls);
  828. static int madera_write_adsp_clk_setting(struct madera_priv *priv,
  829. struct wm_adsp *dsp,
  830. unsigned int freq)
  831. {
  832. unsigned int val;
  833. unsigned int mask = MADERA_DSP_RATE_MASK;
  834. int ret;
  835. val = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT;
  836. switch (priv->madera->type) {
  837. case CS47L35:
  838. case CS47L85:
  839. case WM1840:
  840. /* use legacy frequency registers */
  841. mask |= MADERA_DSP_CLK_SEL_MASK;
  842. val |= (freq << MADERA_DSP_CLK_SEL_SHIFT);
  843. break;
  844. default:
  845. /* Configure exact dsp frequency */
  846. dev_dbg(priv->madera->dev, "Set DSP frequency to 0x%x\n", freq);
  847. ret = regmap_write(dsp->cs_dsp.regmap,
  848. dsp->cs_dsp.base + MADERA_DSP_CONFIG_2_OFFS, freq);
  849. if (ret)
  850. goto err;
  851. break;
  852. }
  853. ret = regmap_update_bits(dsp->cs_dsp.regmap,
  854. dsp->cs_dsp.base + MADERA_DSP_CONFIG_1_OFFS,
  855. mask, val);
  856. if (ret)
  857. goto err;
  858. dev_dbg(priv->madera->dev, "Set DSP clocking to 0x%x\n", val);
  859. return 0;
  860. err:
  861. dev_err(dsp->cs_dsp.dev, "Failed to set DSP%d clock: %d\n", dsp->cs_dsp.num, ret);
  862. return ret;
  863. }
  864. int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
  865. unsigned int freq)
  866. {
  867. struct wm_adsp *dsp = &priv->adsp[dsp_num];
  868. struct madera *madera = priv->madera;
  869. unsigned int cur, new;
  870. int ret;
  871. /*
  872. * This is called at a higher DAPM priority than the mux widgets so
  873. * the muxes are still off at this point and it's safe to change
  874. * the rate domain control.
  875. * Also called at a lower DAPM priority than the domain group widgets
  876. * so locking the reads of adsp_rate_cache is not necessary as we know
  877. * changes are locked out by the domain_group_ref reference count.
  878. */
  879. ret = regmap_read(dsp->cs_dsp.regmap, dsp->cs_dsp.base, &cur);
  880. if (ret) {
  881. dev_err(madera->dev,
  882. "Failed to read current DSP rate: %d\n", ret);
  883. return ret;
  884. }
  885. cur &= MADERA_DSP_RATE_MASK;
  886. new = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT;
  887. if (new == cur) {
  888. dev_dbg(madera->dev, "DSP rate not changed\n");
  889. return madera_write_adsp_clk_setting(priv, dsp, freq);
  890. } else {
  891. dev_dbg(madera->dev, "DSP rate changed\n");
  892. /* The write must be guarded by a number of SYSCLK cycles */
  893. madera_spin_sysclk(priv);
  894. ret = madera_write_adsp_clk_setting(priv, dsp, freq);
  895. madera_spin_sysclk(priv);
  896. return ret;
  897. }
  898. }
  899. EXPORT_SYMBOL_GPL(madera_set_adsp_clk);
  900. int madera_rate_put(struct snd_kcontrol *kcontrol,
  901. struct snd_ctl_elem_value *ucontrol)
  902. {
  903. struct snd_soc_component *component =
  904. snd_soc_kcontrol_component(kcontrol);
  905. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  906. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  907. unsigned int item = ucontrol->value.enumerated.item[0];
  908. unsigned int val;
  909. int ret;
  910. if (item >= e->items)
  911. return -EINVAL;
  912. /*
  913. * Prevent the domain powering up while we're checking whether it's
  914. * safe to change rate domain
  915. */
  916. mutex_lock(&priv->rate_lock);
  917. val = snd_soc_component_read(component, e->reg);
  918. val >>= e->shift_l;
  919. val &= e->mask;
  920. if (snd_soc_enum_item_to_val(e, item) == val) {
  921. ret = 0;
  922. goto out;
  923. }
  924. if (!madera_can_change_grp_rate(priv, e->reg)) {
  925. dev_warn(priv->madera->dev,
  926. "Cannot change '%s' while in use by active audio paths\n",
  927. kcontrol->id.name);
  928. ret = -EBUSY;
  929. } else {
  930. /* The write must be guarded by a number of SYSCLK cycles */
  931. madera_spin_sysclk(priv);
  932. ret = snd_soc_put_enum_double(kcontrol, ucontrol);
  933. madera_spin_sysclk(priv);
  934. }
  935. out:
  936. mutex_unlock(&priv->rate_lock);
  937. return ret;
  938. }
  939. EXPORT_SYMBOL_GPL(madera_rate_put);
  940. static void madera_configure_input_mode(struct madera *madera)
  941. {
  942. unsigned int dig_mode, ana_mode_l, ana_mode_r;
  943. int max_analogue_inputs, max_dmic_sup, i;
  944. switch (madera->type) {
  945. case CS47L15:
  946. max_analogue_inputs = 1;
  947. max_dmic_sup = 2;
  948. break;
  949. case CS47L35:
  950. max_analogue_inputs = 2;
  951. max_dmic_sup = 2;
  952. break;
  953. case CS47L85:
  954. case WM1840:
  955. max_analogue_inputs = 3;
  956. max_dmic_sup = 3;
  957. break;
  958. case CS47L90:
  959. case CS47L91:
  960. max_analogue_inputs = 2;
  961. max_dmic_sup = 2;
  962. break;
  963. default:
  964. max_analogue_inputs = 2;
  965. max_dmic_sup = 4;
  966. break;
  967. }
  968. /*
  969. * Initialize input modes from the A settings. For muxed inputs the
  970. * B settings will be applied if the mux is changed
  971. */
  972. for (i = 0; i < max_dmic_sup; i++) {
  973. dev_dbg(madera->dev, "IN%d mode %u:%u:%u:%u\n", i + 1,
  974. madera->pdata.codec.inmode[i][0],
  975. madera->pdata.codec.inmode[i][1],
  976. madera->pdata.codec.inmode[i][2],
  977. madera->pdata.codec.inmode[i][3]);
  978. dig_mode = madera->pdata.codec.dmic_ref[i] <<
  979. MADERA_IN1_DMIC_SUP_SHIFT;
  980. switch (madera->pdata.codec.inmode[i][0]) {
  981. case MADERA_INMODE_DIFF:
  982. ana_mode_l = 0;
  983. break;
  984. case MADERA_INMODE_SE:
  985. ana_mode_l = 1 << MADERA_IN1L_SRC_SE_SHIFT;
  986. break;
  987. default:
  988. dev_warn(madera->dev,
  989. "IN%dAL Illegal inmode %u ignored\n",
  990. i + 1, madera->pdata.codec.inmode[i][0]);
  991. continue;
  992. }
  993. switch (madera->pdata.codec.inmode[i][1]) {
  994. case MADERA_INMODE_DIFF:
  995. ana_mode_r = 0;
  996. break;
  997. case MADERA_INMODE_SE:
  998. ana_mode_r = 1 << MADERA_IN1R_SRC_SE_SHIFT;
  999. break;
  1000. default:
  1001. dev_warn(madera->dev,
  1002. "IN%dAR Illegal inmode %u ignored\n",
  1003. i + 1, madera->pdata.codec.inmode[i][1]);
  1004. continue;
  1005. }
  1006. dev_dbg(madera->dev,
  1007. "IN%dA DMIC mode=0x%x Analogue mode=0x%x,0x%x\n",
  1008. i + 1, dig_mode, ana_mode_l, ana_mode_r);
  1009. regmap_update_bits(madera->regmap,
  1010. MADERA_IN1L_CONTROL + (i * 8),
  1011. MADERA_IN1_DMIC_SUP_MASK, dig_mode);
  1012. if (i >= max_analogue_inputs)
  1013. continue;
  1014. regmap_update_bits(madera->regmap,
  1015. MADERA_ADC_DIGITAL_VOLUME_1L + (i * 8),
  1016. MADERA_IN1L_SRC_SE_MASK, ana_mode_l);
  1017. regmap_update_bits(madera->regmap,
  1018. MADERA_ADC_DIGITAL_VOLUME_1R + (i * 8),
  1019. MADERA_IN1R_SRC_SE_MASK, ana_mode_r);
  1020. }
  1021. }
  1022. int madera_init_inputs(struct snd_soc_component *component)
  1023. {
  1024. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  1025. struct madera *madera = priv->madera;
  1026. madera_configure_input_mode(madera);
  1027. return 0;
  1028. }
  1029. EXPORT_SYMBOL_GPL(madera_init_inputs);
  1030. static const struct snd_soc_dapm_route madera_mono_routes[] = {
  1031. { "OUT1R", NULL, "OUT1L" },
  1032. { "OUT2R", NULL, "OUT2L" },
  1033. { "OUT3R", NULL, "OUT3L" },
  1034. { "OUT4R", NULL, "OUT4L" },
  1035. { "OUT5R", NULL, "OUT5L" },
  1036. { "OUT6R", NULL, "OUT6L" },
  1037. };
  1038. int madera_init_outputs(struct snd_soc_component *component,
  1039. const struct snd_soc_dapm_route *routes,
  1040. int n_mono_routes, int n_real)
  1041. {
  1042. struct snd_soc_dapm_context *dapm =
  1043. snd_soc_component_get_dapm(component);
  1044. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  1045. struct madera *madera = priv->madera;
  1046. const struct madera_codec_pdata *pdata = &madera->pdata.codec;
  1047. unsigned int val;
  1048. int i;
  1049. if (n_mono_routes > MADERA_MAX_OUTPUT) {
  1050. dev_warn(madera->dev,
  1051. "Requested %d mono outputs, using maximum allowed %d\n",
  1052. n_mono_routes, MADERA_MAX_OUTPUT);
  1053. n_mono_routes = MADERA_MAX_OUTPUT;
  1054. }
  1055. if (!routes)
  1056. routes = madera_mono_routes;
  1057. for (i = 0; i < n_mono_routes; i++) {
  1058. /* Default is 0 so noop with defaults */
  1059. if (pdata->out_mono[i]) {
  1060. val = MADERA_OUT1_MONO;
  1061. snd_soc_dapm_add_routes(dapm, &routes[i], 1);
  1062. } else {
  1063. val = 0;
  1064. }
  1065. if (i >= n_real)
  1066. continue;
  1067. regmap_update_bits(madera->regmap,
  1068. MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
  1069. MADERA_OUT1_MONO, val);
  1070. dev_dbg(madera->dev, "OUT%d mono=0x%x\n", i + 1, val);
  1071. }
  1072. for (i = 0; i < MADERA_MAX_PDM_SPK; i++) {
  1073. dev_dbg(madera->dev, "PDM%d fmt=0x%x mute=0x%x\n", i + 1,
  1074. pdata->pdm_fmt[i], pdata->pdm_mute[i]);
  1075. if (pdata->pdm_mute[i])
  1076. regmap_update_bits(madera->regmap,
  1077. MADERA_PDM_SPK1_CTRL_1 + (i * 2),
  1078. MADERA_SPK1_MUTE_ENDIAN_MASK |
  1079. MADERA_SPK1_MUTE_SEQ1_MASK,
  1080. pdata->pdm_mute[i]);
  1081. if (pdata->pdm_fmt[i])
  1082. regmap_update_bits(madera->regmap,
  1083. MADERA_PDM_SPK1_CTRL_2 + (i * 2),
  1084. MADERA_SPK1_FMT_MASK,
  1085. pdata->pdm_fmt[i]);
  1086. }
  1087. return 0;
  1088. }
  1089. EXPORT_SYMBOL_GPL(madera_init_outputs);
  1090. int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
  1091. irq_handler_t handler)
  1092. {
  1093. struct madera *madera = priv->madera;
  1094. int ret;
  1095. ret = madera_request_irq(madera,
  1096. madera_dsp_bus_error_irqs[dsp_num],
  1097. "ADSP2 bus error",
  1098. handler,
  1099. &priv->adsp[dsp_num]);
  1100. if (ret)
  1101. dev_err(madera->dev,
  1102. "Failed to request DSP Lock region IRQ: %d\n", ret);
  1103. return ret;
  1104. }
  1105. EXPORT_SYMBOL_GPL(madera_init_bus_error_irq);
  1106. void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num)
  1107. {
  1108. struct madera *madera = priv->madera;
  1109. madera_free_irq(madera,
  1110. madera_dsp_bus_error_irqs[dsp_num],
  1111. &priv->adsp[dsp_num]);
  1112. }
  1113. EXPORT_SYMBOL_GPL(madera_free_bus_error_irq);
  1114. const char * const madera_mixer_texts[] = {
  1115. "None",
  1116. "Tone Generator 1",
  1117. "Tone Generator 2",
  1118. "Haptics",
  1119. "AEC1",
  1120. "AEC2",
  1121. "Mic Mute Mixer",
  1122. "Noise Generator",
  1123. "IN1L",
  1124. "IN1R",
  1125. "IN2L",
  1126. "IN2R",
  1127. "IN3L",
  1128. "IN3R",
  1129. "IN4L",
  1130. "IN4R",
  1131. "IN5L",
  1132. "IN5R",
  1133. "IN6L",
  1134. "IN6R",
  1135. "AIF1RX1",
  1136. "AIF1RX2",
  1137. "AIF1RX3",
  1138. "AIF1RX4",
  1139. "AIF1RX5",
  1140. "AIF1RX6",
  1141. "AIF1RX7",
  1142. "AIF1RX8",
  1143. "AIF2RX1",
  1144. "AIF2RX2",
  1145. "AIF2RX3",
  1146. "AIF2RX4",
  1147. "AIF2RX5",
  1148. "AIF2RX6",
  1149. "AIF2RX7",
  1150. "AIF2RX8",
  1151. "AIF3RX1",
  1152. "AIF3RX2",
  1153. "AIF3RX3",
  1154. "AIF3RX4",
  1155. "AIF4RX1",
  1156. "AIF4RX2",
  1157. "SLIMRX1",
  1158. "SLIMRX2",
  1159. "SLIMRX3",
  1160. "SLIMRX4",
  1161. "SLIMRX5",
  1162. "SLIMRX6",
  1163. "SLIMRX7",
  1164. "SLIMRX8",
  1165. "EQ1",
  1166. "EQ2",
  1167. "EQ3",
  1168. "EQ4",
  1169. "DRC1L",
  1170. "DRC1R",
  1171. "DRC2L",
  1172. "DRC2R",
  1173. "LHPF1",
  1174. "LHPF2",
  1175. "LHPF3",
  1176. "LHPF4",
  1177. "DSP1.1",
  1178. "DSP1.2",
  1179. "DSP1.3",
  1180. "DSP1.4",
  1181. "DSP1.5",
  1182. "DSP1.6",
  1183. "DSP2.1",
  1184. "DSP2.2",
  1185. "DSP2.3",
  1186. "DSP2.4",
  1187. "DSP2.5",
  1188. "DSP2.6",
  1189. "DSP3.1",
  1190. "DSP3.2",
  1191. "DSP3.3",
  1192. "DSP3.4",
  1193. "DSP3.5",
  1194. "DSP3.6",
  1195. "DSP4.1",
  1196. "DSP4.2",
  1197. "DSP4.3",
  1198. "DSP4.4",
  1199. "DSP4.5",
  1200. "DSP4.6",
  1201. "DSP5.1",
  1202. "DSP5.2",
  1203. "DSP5.3",
  1204. "DSP5.4",
  1205. "DSP5.5",
  1206. "DSP5.6",
  1207. "DSP6.1",
  1208. "DSP6.2",
  1209. "DSP6.3",
  1210. "DSP6.4",
  1211. "DSP6.5",
  1212. "DSP6.6",
  1213. "DSP7.1",
  1214. "DSP7.2",
  1215. "DSP7.3",
  1216. "DSP7.4",
  1217. "DSP7.5",
  1218. "DSP7.6",
  1219. "ASRC1IN1L",
  1220. "ASRC1IN1R",
  1221. "ASRC1IN2L",
  1222. "ASRC1IN2R",
  1223. "ASRC2IN1L",
  1224. "ASRC2IN1R",
  1225. "ASRC2IN2L",
  1226. "ASRC2IN2R",
  1227. "ISRC1INT1",
  1228. "ISRC1INT2",
  1229. "ISRC1INT3",
  1230. "ISRC1INT4",
  1231. "ISRC1DEC1",
  1232. "ISRC1DEC2",
  1233. "ISRC1DEC3",
  1234. "ISRC1DEC4",
  1235. "ISRC2INT1",
  1236. "ISRC2INT2",
  1237. "ISRC2INT3",
  1238. "ISRC2INT4",
  1239. "ISRC2DEC1",
  1240. "ISRC2DEC2",
  1241. "ISRC2DEC3",
  1242. "ISRC2DEC4",
  1243. "ISRC3INT1",
  1244. "ISRC3INT2",
  1245. "ISRC3INT3",
  1246. "ISRC3INT4",
  1247. "ISRC3DEC1",
  1248. "ISRC3DEC2",
  1249. "ISRC3DEC3",
  1250. "ISRC3DEC4",
  1251. "ISRC4INT1",
  1252. "ISRC4INT2",
  1253. "ISRC4DEC1",
  1254. "ISRC4DEC2",
  1255. "DFC1",
  1256. "DFC2",
  1257. "DFC3",
  1258. "DFC4",
  1259. "DFC5",
  1260. "DFC6",
  1261. "DFC7",
  1262. "DFC8",
  1263. };
  1264. EXPORT_SYMBOL_GPL(madera_mixer_texts);
  1265. const unsigned int madera_mixer_values[] = {
  1266. 0x00, /* None */
  1267. 0x04, /* Tone Generator 1 */
  1268. 0x05, /* Tone Generator 2 */
  1269. 0x06, /* Haptics */
  1270. 0x08, /* AEC */
  1271. 0x09, /* AEC2 */
  1272. 0x0c, /* Noise mixer */
  1273. 0x0d, /* Comfort noise */
  1274. 0x10, /* IN1L */
  1275. 0x11,
  1276. 0x12,
  1277. 0x13,
  1278. 0x14,
  1279. 0x15,
  1280. 0x16,
  1281. 0x17,
  1282. 0x18,
  1283. 0x19,
  1284. 0x1A,
  1285. 0x1B,
  1286. 0x20, /* AIF1RX1 */
  1287. 0x21,
  1288. 0x22,
  1289. 0x23,
  1290. 0x24,
  1291. 0x25,
  1292. 0x26,
  1293. 0x27,
  1294. 0x28, /* AIF2RX1 */
  1295. 0x29,
  1296. 0x2a,
  1297. 0x2b,
  1298. 0x2c,
  1299. 0x2d,
  1300. 0x2e,
  1301. 0x2f,
  1302. 0x30, /* AIF3RX1 */
  1303. 0x31,
  1304. 0x32,
  1305. 0x33,
  1306. 0x34, /* AIF4RX1 */
  1307. 0x35,
  1308. 0x38, /* SLIMRX1 */
  1309. 0x39,
  1310. 0x3a,
  1311. 0x3b,
  1312. 0x3c,
  1313. 0x3d,
  1314. 0x3e,
  1315. 0x3f,
  1316. 0x50, /* EQ1 */
  1317. 0x51,
  1318. 0x52,
  1319. 0x53,
  1320. 0x58, /* DRC1L */
  1321. 0x59,
  1322. 0x5a,
  1323. 0x5b,
  1324. 0x60, /* LHPF1 */
  1325. 0x61,
  1326. 0x62,
  1327. 0x63,
  1328. 0x68, /* DSP1.1 */
  1329. 0x69,
  1330. 0x6a,
  1331. 0x6b,
  1332. 0x6c,
  1333. 0x6d,
  1334. 0x70, /* DSP2.1 */
  1335. 0x71,
  1336. 0x72,
  1337. 0x73,
  1338. 0x74,
  1339. 0x75,
  1340. 0x78, /* DSP3.1 */
  1341. 0x79,
  1342. 0x7a,
  1343. 0x7b,
  1344. 0x7c,
  1345. 0x7d,
  1346. 0x80, /* DSP4.1 */
  1347. 0x81,
  1348. 0x82,
  1349. 0x83,
  1350. 0x84,
  1351. 0x85,
  1352. 0x88, /* DSP5.1 */
  1353. 0x89,
  1354. 0x8a,
  1355. 0x8b,
  1356. 0x8c,
  1357. 0x8d,
  1358. 0xc0, /* DSP6.1 */
  1359. 0xc1,
  1360. 0xc2,
  1361. 0xc3,
  1362. 0xc4,
  1363. 0xc5,
  1364. 0xc8, /* DSP7.1 */
  1365. 0xc9,
  1366. 0xca,
  1367. 0xcb,
  1368. 0xcc,
  1369. 0xcd,
  1370. 0x90, /* ASRC1IN1L */
  1371. 0x91,
  1372. 0x92,
  1373. 0x93,
  1374. 0x94, /* ASRC2IN1L */
  1375. 0x95,
  1376. 0x96,
  1377. 0x97,
  1378. 0xa0, /* ISRC1INT1 */
  1379. 0xa1,
  1380. 0xa2,
  1381. 0xa3,
  1382. 0xa4, /* ISRC1DEC1 */
  1383. 0xa5,
  1384. 0xa6,
  1385. 0xa7,
  1386. 0xa8, /* ISRC2DEC1 */
  1387. 0xa9,
  1388. 0xaa,
  1389. 0xab,
  1390. 0xac, /* ISRC2INT1 */
  1391. 0xad,
  1392. 0xae,
  1393. 0xaf,
  1394. 0xb0, /* ISRC3DEC1 */
  1395. 0xb1,
  1396. 0xb2,
  1397. 0xb3,
  1398. 0xb4, /* ISRC3INT1 */
  1399. 0xb5,
  1400. 0xb6,
  1401. 0xb7,
  1402. 0xb8, /* ISRC4INT1 */
  1403. 0xb9,
  1404. 0xbc, /* ISRC4DEC1 */
  1405. 0xbd,
  1406. 0xf8, /* DFC1 */
  1407. 0xf9,
  1408. 0xfa,
  1409. 0xfb,
  1410. 0xfc,
  1411. 0xfd,
  1412. 0xfe,
  1413. 0xff, /* DFC8 */
  1414. };
  1415. EXPORT_SYMBOL_GPL(madera_mixer_values);
  1416. const DECLARE_TLV_DB_SCALE(madera_ana_tlv, 0, 100, 0);
  1417. EXPORT_SYMBOL_GPL(madera_ana_tlv);
  1418. const DECLARE_TLV_DB_SCALE(madera_eq_tlv, -1200, 100, 0);
  1419. EXPORT_SYMBOL_GPL(madera_eq_tlv);
  1420. const DECLARE_TLV_DB_SCALE(madera_digital_tlv, -6400, 50, 0);
  1421. EXPORT_SYMBOL_GPL(madera_digital_tlv);
  1422. const DECLARE_TLV_DB_SCALE(madera_noise_tlv, -13200, 600, 0);
  1423. EXPORT_SYMBOL_GPL(madera_noise_tlv);
  1424. const DECLARE_TLV_DB_SCALE(madera_ng_tlv, -12000, 600, 0);
  1425. EXPORT_SYMBOL_GPL(madera_ng_tlv);
  1426. const DECLARE_TLV_DB_SCALE(madera_mixer_tlv, -3200, 100, 0);
  1427. EXPORT_SYMBOL_GPL(madera_mixer_tlv);
  1428. const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE] = {
  1429. "SYNCCLK rate 1", "SYNCCLK rate 2", "SYNCCLK rate 3",
  1430. "ASYNCCLK rate 1", "ASYNCCLK rate 2",
  1431. };
  1432. EXPORT_SYMBOL_GPL(madera_rate_text);
  1433. const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE] = {
  1434. 0x0, 0x1, 0x2, 0x8, 0x9,
  1435. };
  1436. EXPORT_SYMBOL_GPL(madera_rate_val);
  1437. static const char * const madera_dfc_width_text[MADERA_DFC_WIDTH_ENUM_SIZE] = {
  1438. "8 bit", "16 bit", "20 bit", "24 bit", "32 bit",
  1439. };
  1440. static const unsigned int madera_dfc_width_val[MADERA_DFC_WIDTH_ENUM_SIZE] = {
  1441. 7, 15, 19, 23, 31,
  1442. };
  1443. static const char * const madera_dfc_type_text[MADERA_DFC_TYPE_ENUM_SIZE] = {
  1444. "Fixed", "Unsigned Fixed", "Single Precision Floating",
  1445. "Half Precision Floating", "Arm Alternative Floating",
  1446. };
  1447. static const unsigned int madera_dfc_type_val[MADERA_DFC_TYPE_ENUM_SIZE] = {
  1448. 0, 1, 2, 4, 5,
  1449. };
  1450. const struct soc_enum madera_dfc_width[] = {
  1451. SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
  1452. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1453. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1454. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1455. ARRAY_SIZE(madera_dfc_width_text),
  1456. madera_dfc_width_text,
  1457. madera_dfc_width_val),
  1458. SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
  1459. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1460. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1461. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1462. ARRAY_SIZE(madera_dfc_width_text),
  1463. madera_dfc_width_text,
  1464. madera_dfc_width_val),
  1465. SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
  1466. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1467. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1468. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1469. ARRAY_SIZE(madera_dfc_width_text),
  1470. madera_dfc_width_text,
  1471. madera_dfc_width_val),
  1472. SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
  1473. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1474. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1475. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1476. ARRAY_SIZE(madera_dfc_width_text),
  1477. madera_dfc_width_text,
  1478. madera_dfc_width_val),
  1479. SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
  1480. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1481. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1482. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1483. ARRAY_SIZE(madera_dfc_width_text),
  1484. madera_dfc_width_text,
  1485. madera_dfc_width_val),
  1486. SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
  1487. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1488. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1489. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1490. ARRAY_SIZE(madera_dfc_width_text),
  1491. madera_dfc_width_text,
  1492. madera_dfc_width_val),
  1493. SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
  1494. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1495. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1496. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1497. ARRAY_SIZE(madera_dfc_width_text),
  1498. madera_dfc_width_text,
  1499. madera_dfc_width_val),
  1500. SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
  1501. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1502. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1503. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1504. ARRAY_SIZE(madera_dfc_width_text),
  1505. madera_dfc_width_text,
  1506. madera_dfc_width_val),
  1507. SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
  1508. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1509. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1510. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1511. ARRAY_SIZE(madera_dfc_width_text),
  1512. madera_dfc_width_text,
  1513. madera_dfc_width_val),
  1514. SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
  1515. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1516. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1517. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1518. ARRAY_SIZE(madera_dfc_width_text),
  1519. madera_dfc_width_text,
  1520. madera_dfc_width_val),
  1521. SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
  1522. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1523. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1524. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1525. ARRAY_SIZE(madera_dfc_width_text),
  1526. madera_dfc_width_text,
  1527. madera_dfc_width_val),
  1528. SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
  1529. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1530. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1531. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1532. ARRAY_SIZE(madera_dfc_width_text),
  1533. madera_dfc_width_text,
  1534. madera_dfc_width_val),
  1535. SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
  1536. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1537. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1538. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1539. ARRAY_SIZE(madera_dfc_width_text),
  1540. madera_dfc_width_text,
  1541. madera_dfc_width_val),
  1542. SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
  1543. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1544. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1545. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1546. ARRAY_SIZE(madera_dfc_width_text),
  1547. madera_dfc_width_text,
  1548. madera_dfc_width_val),
  1549. SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
  1550. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1551. MADERA_DFC1_RX_DATA_WIDTH_MASK >>
  1552. MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
  1553. ARRAY_SIZE(madera_dfc_width_text),
  1554. madera_dfc_width_text,
  1555. madera_dfc_width_val),
  1556. SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
  1557. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1558. MADERA_DFC1_TX_DATA_WIDTH_MASK >>
  1559. MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
  1560. ARRAY_SIZE(madera_dfc_width_text),
  1561. madera_dfc_width_text,
  1562. madera_dfc_width_val),
  1563. };
  1564. EXPORT_SYMBOL_GPL(madera_dfc_width);
  1565. const struct soc_enum madera_dfc_type[] = {
  1566. SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
  1567. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1568. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1569. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1570. ARRAY_SIZE(madera_dfc_type_text),
  1571. madera_dfc_type_text,
  1572. madera_dfc_type_val),
  1573. SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
  1574. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1575. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1576. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1577. ARRAY_SIZE(madera_dfc_type_text),
  1578. madera_dfc_type_text,
  1579. madera_dfc_type_val),
  1580. SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
  1581. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1582. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1583. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1584. ARRAY_SIZE(madera_dfc_type_text),
  1585. madera_dfc_type_text,
  1586. madera_dfc_type_val),
  1587. SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
  1588. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1589. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1590. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1591. ARRAY_SIZE(madera_dfc_type_text),
  1592. madera_dfc_type_text,
  1593. madera_dfc_type_val),
  1594. SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
  1595. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1596. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1597. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1598. ARRAY_SIZE(madera_dfc_type_text),
  1599. madera_dfc_type_text,
  1600. madera_dfc_type_val),
  1601. SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
  1602. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1603. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1604. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1605. ARRAY_SIZE(madera_dfc_type_text),
  1606. madera_dfc_type_text,
  1607. madera_dfc_type_val),
  1608. SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
  1609. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1610. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1611. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1612. ARRAY_SIZE(madera_dfc_type_text),
  1613. madera_dfc_type_text,
  1614. madera_dfc_type_val),
  1615. SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
  1616. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1617. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1618. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1619. ARRAY_SIZE(madera_dfc_type_text),
  1620. madera_dfc_type_text,
  1621. madera_dfc_type_val),
  1622. SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
  1623. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1624. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1625. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1626. ARRAY_SIZE(madera_dfc_type_text),
  1627. madera_dfc_type_text,
  1628. madera_dfc_type_val),
  1629. SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
  1630. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1631. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1632. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1633. ARRAY_SIZE(madera_dfc_type_text),
  1634. madera_dfc_type_text,
  1635. madera_dfc_type_val),
  1636. SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
  1637. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1638. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1639. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1640. ARRAY_SIZE(madera_dfc_type_text),
  1641. madera_dfc_type_text,
  1642. madera_dfc_type_val),
  1643. SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
  1644. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1645. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1646. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1647. ARRAY_SIZE(madera_dfc_type_text),
  1648. madera_dfc_type_text,
  1649. madera_dfc_type_val),
  1650. SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
  1651. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1652. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1653. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1654. ARRAY_SIZE(madera_dfc_type_text),
  1655. madera_dfc_type_text,
  1656. madera_dfc_type_val),
  1657. SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
  1658. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1659. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1660. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1661. ARRAY_SIZE(madera_dfc_type_text),
  1662. madera_dfc_type_text,
  1663. madera_dfc_type_val),
  1664. SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
  1665. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1666. MADERA_DFC1_RX_DATA_TYPE_MASK >>
  1667. MADERA_DFC1_RX_DATA_TYPE_SHIFT,
  1668. ARRAY_SIZE(madera_dfc_type_text),
  1669. madera_dfc_type_text,
  1670. madera_dfc_type_val),
  1671. SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
  1672. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1673. MADERA_DFC1_TX_DATA_TYPE_MASK >>
  1674. MADERA_DFC1_TX_DATA_TYPE_SHIFT,
  1675. ARRAY_SIZE(madera_dfc_type_text),
  1676. madera_dfc_type_text,
  1677. madera_dfc_type_val),
  1678. };
  1679. EXPORT_SYMBOL_GPL(madera_dfc_type);
  1680. const struct soc_enum madera_isrc_fsh[] = {
  1681. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_1,
  1682. MADERA_ISRC1_FSH_SHIFT, 0xf,
  1683. MADERA_RATE_ENUM_SIZE,
  1684. madera_rate_text, madera_rate_val),
  1685. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_1,
  1686. MADERA_ISRC2_FSH_SHIFT, 0xf,
  1687. MADERA_RATE_ENUM_SIZE,
  1688. madera_rate_text, madera_rate_val),
  1689. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_1,
  1690. MADERA_ISRC3_FSH_SHIFT, 0xf,
  1691. MADERA_RATE_ENUM_SIZE,
  1692. madera_rate_text, madera_rate_val),
  1693. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_1,
  1694. MADERA_ISRC4_FSH_SHIFT, 0xf,
  1695. MADERA_RATE_ENUM_SIZE,
  1696. madera_rate_text, madera_rate_val),
  1697. };
  1698. EXPORT_SYMBOL_GPL(madera_isrc_fsh);
  1699. const struct soc_enum madera_isrc_fsl[] = {
  1700. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_2,
  1701. MADERA_ISRC1_FSL_SHIFT, 0xf,
  1702. MADERA_RATE_ENUM_SIZE,
  1703. madera_rate_text, madera_rate_val),
  1704. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_2,
  1705. MADERA_ISRC2_FSL_SHIFT, 0xf,
  1706. MADERA_RATE_ENUM_SIZE,
  1707. madera_rate_text, madera_rate_val),
  1708. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_2,
  1709. MADERA_ISRC3_FSL_SHIFT, 0xf,
  1710. MADERA_RATE_ENUM_SIZE,
  1711. madera_rate_text, madera_rate_val),
  1712. SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_2,
  1713. MADERA_ISRC4_FSL_SHIFT, 0xf,
  1714. MADERA_RATE_ENUM_SIZE,
  1715. madera_rate_text, madera_rate_val),
  1716. };
  1717. EXPORT_SYMBOL_GPL(madera_isrc_fsl);
  1718. const struct soc_enum madera_asrc1_rate[] = {
  1719. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
  1720. MADERA_ASRC1_RATE1_SHIFT, 0xf,
  1721. MADERA_SYNC_RATE_ENUM_SIZE,
  1722. madera_rate_text, madera_rate_val),
  1723. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
  1724. MADERA_ASRC1_RATE1_SHIFT, 0xf,
  1725. MADERA_ASYNC_RATE_ENUM_SIZE,
  1726. madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
  1727. madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
  1728. };
  1729. EXPORT_SYMBOL_GPL(madera_asrc1_rate);
  1730. const struct soc_enum madera_asrc1_bidir_rate[] = {
  1731. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
  1732. MADERA_ASRC1_RATE1_SHIFT, 0xf,
  1733. MADERA_RATE_ENUM_SIZE,
  1734. madera_rate_text, madera_rate_val),
  1735. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
  1736. MADERA_ASRC1_RATE2_SHIFT, 0xf,
  1737. MADERA_RATE_ENUM_SIZE,
  1738. madera_rate_text, madera_rate_val),
  1739. };
  1740. EXPORT_SYMBOL_GPL(madera_asrc1_bidir_rate);
  1741. const struct soc_enum madera_asrc2_rate[] = {
  1742. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
  1743. MADERA_ASRC2_RATE1_SHIFT, 0xf,
  1744. MADERA_SYNC_RATE_ENUM_SIZE,
  1745. madera_rate_text, madera_rate_val),
  1746. SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE2,
  1747. MADERA_ASRC2_RATE2_SHIFT, 0xf,
  1748. MADERA_ASYNC_RATE_ENUM_SIZE,
  1749. madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
  1750. madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
  1751. };
  1752. EXPORT_SYMBOL_GPL(madera_asrc2_rate);
  1753. static const char * const madera_vol_ramp_text[] = {
  1754. "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
  1755. "15ms/6dB", "30ms/6dB",
  1756. };
  1757. SOC_ENUM_SINGLE_DECL(madera_in_vd_ramp,
  1758. MADERA_INPUT_VOLUME_RAMP,
  1759. MADERA_IN_VD_RAMP_SHIFT,
  1760. madera_vol_ramp_text);
  1761. EXPORT_SYMBOL_GPL(madera_in_vd_ramp);
  1762. SOC_ENUM_SINGLE_DECL(madera_in_vi_ramp,
  1763. MADERA_INPUT_VOLUME_RAMP,
  1764. MADERA_IN_VI_RAMP_SHIFT,
  1765. madera_vol_ramp_text);
  1766. EXPORT_SYMBOL_GPL(madera_in_vi_ramp);
  1767. SOC_ENUM_SINGLE_DECL(madera_out_vd_ramp,
  1768. MADERA_OUTPUT_VOLUME_RAMP,
  1769. MADERA_OUT_VD_RAMP_SHIFT,
  1770. madera_vol_ramp_text);
  1771. EXPORT_SYMBOL_GPL(madera_out_vd_ramp);
  1772. SOC_ENUM_SINGLE_DECL(madera_out_vi_ramp,
  1773. MADERA_OUTPUT_VOLUME_RAMP,
  1774. MADERA_OUT_VI_RAMP_SHIFT,
  1775. madera_vol_ramp_text);
  1776. EXPORT_SYMBOL_GPL(madera_out_vi_ramp);
  1777. static const char * const madera_lhpf_mode_text[] = {
  1778. "Low-pass", "High-pass"
  1779. };
  1780. SOC_ENUM_SINGLE_DECL(madera_lhpf1_mode,
  1781. MADERA_HPLPF1_1,
  1782. MADERA_LHPF1_MODE_SHIFT,
  1783. madera_lhpf_mode_text);
  1784. EXPORT_SYMBOL_GPL(madera_lhpf1_mode);
  1785. SOC_ENUM_SINGLE_DECL(madera_lhpf2_mode,
  1786. MADERA_HPLPF2_1,
  1787. MADERA_LHPF2_MODE_SHIFT,
  1788. madera_lhpf_mode_text);
  1789. EXPORT_SYMBOL_GPL(madera_lhpf2_mode);
  1790. SOC_ENUM_SINGLE_DECL(madera_lhpf3_mode,
  1791. MADERA_HPLPF3_1,
  1792. MADERA_LHPF3_MODE_SHIFT,
  1793. madera_lhpf_mode_text);
  1794. EXPORT_SYMBOL_GPL(madera_lhpf3_mode);
  1795. SOC_ENUM_SINGLE_DECL(madera_lhpf4_mode,
  1796. MADERA_HPLPF4_1,
  1797. MADERA_LHPF4_MODE_SHIFT,
  1798. madera_lhpf_mode_text);
  1799. EXPORT_SYMBOL_GPL(madera_lhpf4_mode);
  1800. static const char * const madera_ng_hold_text[] = {
  1801. "30ms", "120ms", "250ms", "500ms",
  1802. };
  1803. SOC_ENUM_SINGLE_DECL(madera_ng_hold,
  1804. MADERA_NOISE_GATE_CONTROL,
  1805. MADERA_NGATE_HOLD_SHIFT,
  1806. madera_ng_hold_text);
  1807. EXPORT_SYMBOL_GPL(madera_ng_hold);
  1808. static const char * const madera_in_hpf_cut_text[] = {
  1809. "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
  1810. };
  1811. SOC_ENUM_SINGLE_DECL(madera_in_hpf_cut_enum,
  1812. MADERA_HPF_CONTROL,
  1813. MADERA_IN_HPF_CUT_SHIFT,
  1814. madera_in_hpf_cut_text);
  1815. EXPORT_SYMBOL_GPL(madera_in_hpf_cut_enum);
  1816. static const char * const madera_in_dmic_osr_text[MADERA_OSR_ENUM_SIZE] = {
  1817. "384kHz", "768kHz", "1.536MHz", "3.072MHz", "6.144MHz",
  1818. };
  1819. static const unsigned int madera_in_dmic_osr_val[MADERA_OSR_ENUM_SIZE] = {
  1820. 2, 3, 4, 5, 6,
  1821. };
  1822. const struct soc_enum madera_in_dmic_osr[] = {
  1823. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC1L_CONTROL, MADERA_IN1_OSR_SHIFT,
  1824. 0x7, MADERA_OSR_ENUM_SIZE,
  1825. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1826. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC2L_CONTROL, MADERA_IN2_OSR_SHIFT,
  1827. 0x7, MADERA_OSR_ENUM_SIZE,
  1828. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1829. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC3L_CONTROL, MADERA_IN3_OSR_SHIFT,
  1830. 0x7, MADERA_OSR_ENUM_SIZE,
  1831. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1832. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC4L_CONTROL, MADERA_IN4_OSR_SHIFT,
  1833. 0x7, MADERA_OSR_ENUM_SIZE,
  1834. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1835. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC5L_CONTROL, MADERA_IN5_OSR_SHIFT,
  1836. 0x7, MADERA_OSR_ENUM_SIZE,
  1837. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1838. SOC_VALUE_ENUM_SINGLE(MADERA_DMIC6L_CONTROL, MADERA_IN6_OSR_SHIFT,
  1839. 0x7, MADERA_OSR_ENUM_SIZE,
  1840. madera_in_dmic_osr_text, madera_in_dmic_osr_val),
  1841. };
  1842. EXPORT_SYMBOL_GPL(madera_in_dmic_osr);
  1843. static const char * const madera_anc_input_src_text[] = {
  1844. "None", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6",
  1845. };
  1846. static const char * const madera_anc_channel_src_text[] = {
  1847. "None", "Left", "Right", "Combine",
  1848. };
  1849. const struct soc_enum madera_anc_input_src[] = {
  1850. SOC_ENUM_SINGLE(MADERA_ANC_SRC,
  1851. MADERA_IN_RXANCL_SEL_SHIFT,
  1852. ARRAY_SIZE(madera_anc_input_src_text),
  1853. madera_anc_input_src_text),
  1854. SOC_ENUM_SINGLE(MADERA_FCL_ADC_REFORMATTER_CONTROL,
  1855. MADERA_FCL_MIC_MODE_SEL_SHIFT,
  1856. ARRAY_SIZE(madera_anc_channel_src_text),
  1857. madera_anc_channel_src_text),
  1858. SOC_ENUM_SINGLE(MADERA_ANC_SRC,
  1859. MADERA_IN_RXANCR_SEL_SHIFT,
  1860. ARRAY_SIZE(madera_anc_input_src_text),
  1861. madera_anc_input_src_text),
  1862. SOC_ENUM_SINGLE(MADERA_FCR_ADC_REFORMATTER_CONTROL,
  1863. MADERA_FCR_MIC_MODE_SEL_SHIFT,
  1864. ARRAY_SIZE(madera_anc_channel_src_text),
  1865. madera_anc_channel_src_text),
  1866. };
  1867. EXPORT_SYMBOL_GPL(madera_anc_input_src);
  1868. static const char * const madera_anc_ng_texts[] = {
  1869. "None", "Internal", "External",
  1870. };
  1871. SOC_ENUM_SINGLE_DECL(madera_anc_ng_enum, SND_SOC_NOPM, 0, madera_anc_ng_texts);
  1872. EXPORT_SYMBOL_GPL(madera_anc_ng_enum);
  1873. static const char * const madera_out_anc_src_text[] = {
  1874. "None", "RXANCL", "RXANCR",
  1875. };
  1876. const struct soc_enum madera_output_anc_src[] = {
  1877. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1L,
  1878. MADERA_OUT1L_ANC_SRC_SHIFT,
  1879. ARRAY_SIZE(madera_out_anc_src_text),
  1880. madera_out_anc_src_text),
  1881. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1R,
  1882. MADERA_OUT1R_ANC_SRC_SHIFT,
  1883. ARRAY_SIZE(madera_out_anc_src_text),
  1884. madera_out_anc_src_text),
  1885. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2L,
  1886. MADERA_OUT2L_ANC_SRC_SHIFT,
  1887. ARRAY_SIZE(madera_out_anc_src_text),
  1888. madera_out_anc_src_text),
  1889. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2R,
  1890. MADERA_OUT2R_ANC_SRC_SHIFT,
  1891. ARRAY_SIZE(madera_out_anc_src_text),
  1892. madera_out_anc_src_text),
  1893. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3L,
  1894. MADERA_OUT3L_ANC_SRC_SHIFT,
  1895. ARRAY_SIZE(madera_out_anc_src_text),
  1896. madera_out_anc_src_text),
  1897. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3R,
  1898. MADERA_OUT3R_ANC_SRC_SHIFT,
  1899. ARRAY_SIZE(madera_out_anc_src_text),
  1900. madera_out_anc_src_text),
  1901. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4L,
  1902. MADERA_OUT4L_ANC_SRC_SHIFT,
  1903. ARRAY_SIZE(madera_out_anc_src_text),
  1904. madera_out_anc_src_text),
  1905. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4R,
  1906. MADERA_OUT4R_ANC_SRC_SHIFT,
  1907. ARRAY_SIZE(madera_out_anc_src_text),
  1908. madera_out_anc_src_text),
  1909. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5L,
  1910. MADERA_OUT5L_ANC_SRC_SHIFT,
  1911. ARRAY_SIZE(madera_out_anc_src_text),
  1912. madera_out_anc_src_text),
  1913. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5R,
  1914. MADERA_OUT5R_ANC_SRC_SHIFT,
  1915. ARRAY_SIZE(madera_out_anc_src_text),
  1916. madera_out_anc_src_text),
  1917. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6L,
  1918. MADERA_OUT6L_ANC_SRC_SHIFT,
  1919. ARRAY_SIZE(madera_out_anc_src_text),
  1920. madera_out_anc_src_text),
  1921. SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6R,
  1922. MADERA_OUT6R_ANC_SRC_SHIFT,
  1923. ARRAY_SIZE(madera_out_anc_src_text),
  1924. madera_out_anc_src_text),
  1925. };
  1926. EXPORT_SYMBOL_GPL(madera_output_anc_src);
  1927. int madera_dfc_put(struct snd_kcontrol *kcontrol,
  1928. struct snd_ctl_elem_value *ucontrol)
  1929. {
  1930. struct snd_soc_component *component =
  1931. snd_soc_kcontrol_component(kcontrol);
  1932. struct snd_soc_dapm_context *dapm =
  1933. snd_soc_component_get_dapm(component);
  1934. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  1935. unsigned int reg = e->reg;
  1936. unsigned int val;
  1937. int ret = 0;
  1938. reg = ((reg / 6) * 6) - 2;
  1939. snd_soc_dapm_mutex_lock(dapm);
  1940. val = snd_soc_component_read(component, reg);
  1941. if (val & MADERA_DFC1_ENA) {
  1942. ret = -EBUSY;
  1943. dev_err(component->dev, "Can't change mode on an active DFC\n");
  1944. goto exit;
  1945. }
  1946. ret = snd_soc_put_enum_double(kcontrol, ucontrol);
  1947. exit:
  1948. snd_soc_dapm_mutex_unlock(dapm);
  1949. return ret;
  1950. }
  1951. EXPORT_SYMBOL_GPL(madera_dfc_put);
  1952. int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
  1953. struct snd_ctl_elem_value *ucontrol)
  1954. {
  1955. struct soc_mixer_control *mc =
  1956. (struct soc_mixer_control *)kcontrol->private_value;
  1957. struct snd_soc_component *component =
  1958. snd_soc_kcontrol_component(kcontrol);
  1959. struct snd_soc_dapm_context *dapm =
  1960. snd_soc_component_get_dapm(component);
  1961. unsigned int val, mask;
  1962. int ret;
  1963. snd_soc_dapm_mutex_lock(dapm);
  1964. /* Cannot change lp mode on an active input */
  1965. val = snd_soc_component_read(component, MADERA_INPUT_ENABLES);
  1966. mask = (mc->reg - MADERA_ADC_DIGITAL_VOLUME_1L) / 4;
  1967. mask ^= 0x1; /* Flip bottom bit for channel order */
  1968. if (val & (1 << mask)) {
  1969. ret = -EBUSY;
  1970. dev_err(component->dev,
  1971. "Can't change lp mode on an active input\n");
  1972. goto exit;
  1973. }
  1974. ret = snd_soc_put_volsw(kcontrol, ucontrol);
  1975. exit:
  1976. snd_soc_dapm_mutex_unlock(dapm);
  1977. return ret;
  1978. }
  1979. EXPORT_SYMBOL_GPL(madera_lp_mode_put);
  1980. const struct snd_kcontrol_new madera_dsp_trigger_output_mux[] = {
  1981. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1982. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1983. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1984. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1985. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1986. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1987. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1988. };
  1989. EXPORT_SYMBOL_GPL(madera_dsp_trigger_output_mux);
  1990. const struct snd_kcontrol_new madera_drc_activity_output_mux[] = {
  1991. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1992. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
  1993. };
  1994. EXPORT_SYMBOL_GPL(madera_drc_activity_output_mux);
  1995. static void madera_in_set_vu(struct madera_priv *priv, bool enable)
  1996. {
  1997. unsigned int val;
  1998. int i, ret;
  1999. if (enable)
  2000. val = MADERA_IN_VU;
  2001. else
  2002. val = 0;
  2003. for (i = 0; i < priv->num_inputs; i++) {
  2004. ret = regmap_update_bits(priv->madera->regmap,
  2005. MADERA_ADC_DIGITAL_VOLUME_1L + (i * 4),
  2006. MADERA_IN_VU, val);
  2007. if (ret)
  2008. dev_warn(priv->madera->dev,
  2009. "Failed to modify VU bits: %d\n", ret);
  2010. }
  2011. }
  2012. int madera_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
  2013. int event)
  2014. {
  2015. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  2016. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2017. unsigned int reg, val;
  2018. if (w->shift % 2)
  2019. reg = MADERA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
  2020. else
  2021. reg = MADERA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
  2022. switch (event) {
  2023. case SND_SOC_DAPM_PRE_PMU:
  2024. priv->in_pending++;
  2025. break;
  2026. case SND_SOC_DAPM_POST_PMU:
  2027. priv->in_pending--;
  2028. snd_soc_component_update_bits(component, reg,
  2029. MADERA_IN1L_MUTE, 0);
  2030. /* If this is the last input pending then allow VU */
  2031. if (priv->in_pending == 0) {
  2032. usleep_range(1000, 3000);
  2033. madera_in_set_vu(priv, true);
  2034. }
  2035. break;
  2036. case SND_SOC_DAPM_PRE_PMD:
  2037. snd_soc_component_update_bits(component, reg,
  2038. MADERA_IN1L_MUTE | MADERA_IN_VU,
  2039. MADERA_IN1L_MUTE | MADERA_IN_VU);
  2040. break;
  2041. case SND_SOC_DAPM_POST_PMD:
  2042. /* Disable volume updates if no inputs are enabled */
  2043. val = snd_soc_component_read(component, MADERA_INPUT_ENABLES);
  2044. if (!val)
  2045. madera_in_set_vu(priv, false);
  2046. break;
  2047. default:
  2048. break;
  2049. }
  2050. return 0;
  2051. }
  2052. EXPORT_SYMBOL_GPL(madera_in_ev);
  2053. int madera_out_ev(struct snd_soc_dapm_widget *w,
  2054. struct snd_kcontrol *kcontrol, int event)
  2055. {
  2056. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  2057. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2058. struct madera *madera = priv->madera;
  2059. int out_up_delay;
  2060. switch (madera->type) {
  2061. case CS47L90:
  2062. case CS47L91:
  2063. case CS42L92:
  2064. case CS47L92:
  2065. case CS47L93:
  2066. out_up_delay = 6;
  2067. break;
  2068. default:
  2069. out_up_delay = 17;
  2070. break;
  2071. }
  2072. switch (event) {
  2073. case SND_SOC_DAPM_PRE_PMU:
  2074. switch (w->shift) {
  2075. case MADERA_OUT1L_ENA_SHIFT:
  2076. case MADERA_OUT1R_ENA_SHIFT:
  2077. case MADERA_OUT2L_ENA_SHIFT:
  2078. case MADERA_OUT2R_ENA_SHIFT:
  2079. case MADERA_OUT3L_ENA_SHIFT:
  2080. case MADERA_OUT3R_ENA_SHIFT:
  2081. priv->out_up_pending++;
  2082. priv->out_up_delay += out_up_delay;
  2083. break;
  2084. default:
  2085. break;
  2086. }
  2087. break;
  2088. case SND_SOC_DAPM_POST_PMU:
  2089. switch (w->shift) {
  2090. case MADERA_OUT1L_ENA_SHIFT:
  2091. case MADERA_OUT1R_ENA_SHIFT:
  2092. case MADERA_OUT2L_ENA_SHIFT:
  2093. case MADERA_OUT2R_ENA_SHIFT:
  2094. case MADERA_OUT3L_ENA_SHIFT:
  2095. case MADERA_OUT3R_ENA_SHIFT:
  2096. priv->out_up_pending--;
  2097. if (!priv->out_up_pending) {
  2098. msleep(priv->out_up_delay);
  2099. priv->out_up_delay = 0;
  2100. }
  2101. break;
  2102. default:
  2103. break;
  2104. }
  2105. break;
  2106. case SND_SOC_DAPM_PRE_PMD:
  2107. switch (w->shift) {
  2108. case MADERA_OUT1L_ENA_SHIFT:
  2109. case MADERA_OUT1R_ENA_SHIFT:
  2110. case MADERA_OUT2L_ENA_SHIFT:
  2111. case MADERA_OUT2R_ENA_SHIFT:
  2112. case MADERA_OUT3L_ENA_SHIFT:
  2113. case MADERA_OUT3R_ENA_SHIFT:
  2114. priv->out_down_pending++;
  2115. priv->out_down_delay++;
  2116. break;
  2117. default:
  2118. break;
  2119. }
  2120. break;
  2121. case SND_SOC_DAPM_POST_PMD:
  2122. switch (w->shift) {
  2123. case MADERA_OUT1L_ENA_SHIFT:
  2124. case MADERA_OUT1R_ENA_SHIFT:
  2125. case MADERA_OUT2L_ENA_SHIFT:
  2126. case MADERA_OUT2R_ENA_SHIFT:
  2127. case MADERA_OUT3L_ENA_SHIFT:
  2128. case MADERA_OUT3R_ENA_SHIFT:
  2129. priv->out_down_pending--;
  2130. if (!priv->out_down_pending) {
  2131. msleep(priv->out_down_delay);
  2132. priv->out_down_delay = 0;
  2133. }
  2134. break;
  2135. default:
  2136. break;
  2137. }
  2138. break;
  2139. default:
  2140. break;
  2141. }
  2142. return 0;
  2143. }
  2144. EXPORT_SYMBOL_GPL(madera_out_ev);
  2145. int madera_hp_ev(struct snd_soc_dapm_widget *w,
  2146. struct snd_kcontrol *kcontrol, int event)
  2147. {
  2148. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  2149. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2150. struct madera *madera = priv->madera;
  2151. unsigned int mask = 1 << w->shift;
  2152. unsigned int out_num = w->shift / 2;
  2153. unsigned int val;
  2154. unsigned int ep_sel = 0;
  2155. switch (event) {
  2156. case SND_SOC_DAPM_POST_PMU:
  2157. val = mask;
  2158. break;
  2159. case SND_SOC_DAPM_PRE_PMD:
  2160. val = 0;
  2161. break;
  2162. case SND_SOC_DAPM_PRE_PMU:
  2163. case SND_SOC_DAPM_POST_PMD:
  2164. return madera_out_ev(w, kcontrol, event);
  2165. default:
  2166. return 0;
  2167. }
  2168. /* Store the desired state for the HP outputs */
  2169. madera->hp_ena &= ~mask;
  2170. madera->hp_ena |= val;
  2171. switch (madera->type) {
  2172. case CS42L92:
  2173. case CS47L92:
  2174. case CS47L93:
  2175. break;
  2176. default:
  2177. /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
  2178. regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
  2179. ep_sel &= MADERA_EP_SEL_MASK;
  2180. break;
  2181. }
  2182. /* Force off if HPDET has disabled the clamp for this output */
  2183. if (!ep_sel &&
  2184. (!madera->out_clamp[out_num] || madera->out_shorted[out_num]))
  2185. val = 0;
  2186. regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);
  2187. return madera_out_ev(w, kcontrol, event);
  2188. }
  2189. EXPORT_SYMBOL_GPL(madera_hp_ev);
  2190. int madera_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
  2191. int event)
  2192. {
  2193. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  2194. unsigned int val;
  2195. switch (event) {
  2196. case SND_SOC_DAPM_POST_PMU:
  2197. val = 1 << w->shift;
  2198. break;
  2199. case SND_SOC_DAPM_PRE_PMD:
  2200. val = 1 << (w->shift + 1);
  2201. break;
  2202. default:
  2203. return 0;
  2204. }
  2205. snd_soc_component_write(component, MADERA_CLOCK_CONTROL, val);
  2206. return 0;
  2207. }
  2208. EXPORT_SYMBOL_GPL(madera_anc_ev);
  2209. static const unsigned int madera_opclk_ref_48k_rates[] = {
  2210. 6144000,
  2211. 12288000,
  2212. 24576000,
  2213. 49152000,
  2214. };
  2215. static const unsigned int madera_opclk_ref_44k1_rates[] = {
  2216. 5644800,
  2217. 11289600,
  2218. 22579200,
  2219. 45158400,
  2220. };
  2221. static int madera_set_opclk(struct snd_soc_component *component,
  2222. unsigned int clk, unsigned int freq)
  2223. {
  2224. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2225. unsigned int mask = MADERA_OPCLK_DIV_MASK | MADERA_OPCLK_SEL_MASK;
  2226. unsigned int reg, val;
  2227. const unsigned int *rates;
  2228. int ref, div, refclk;
  2229. BUILD_BUG_ON(ARRAY_SIZE(madera_opclk_ref_48k_rates) !=
  2230. ARRAY_SIZE(madera_opclk_ref_44k1_rates));
  2231. switch (clk) {
  2232. case MADERA_CLK_OPCLK:
  2233. reg = MADERA_OUTPUT_SYSTEM_CLOCK;
  2234. refclk = priv->sysclk;
  2235. break;
  2236. case MADERA_CLK_ASYNC_OPCLK:
  2237. reg = MADERA_OUTPUT_ASYNC_CLOCK;
  2238. refclk = priv->asyncclk;
  2239. break;
  2240. default:
  2241. return -EINVAL;
  2242. }
  2243. if (refclk % 4000)
  2244. rates = madera_opclk_ref_44k1_rates;
  2245. else
  2246. rates = madera_opclk_ref_48k_rates;
  2247. for (ref = 0; ref < ARRAY_SIZE(madera_opclk_ref_48k_rates); ++ref) {
  2248. if (rates[ref] > refclk)
  2249. continue;
  2250. div = 2;
  2251. while ((rates[ref] / div >= freq) && (div <= 30)) {
  2252. if (rates[ref] / div == freq) {
  2253. dev_dbg(component->dev, "Configured %dHz OPCLK\n",
  2254. freq);
  2255. val = (div << MADERA_OPCLK_DIV_SHIFT) | ref;
  2256. snd_soc_component_update_bits(component, reg,
  2257. mask, val);
  2258. return 0;
  2259. }
  2260. div += 2;
  2261. }
  2262. }
  2263. dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
  2264. return -EINVAL;
  2265. }
  2266. static int madera_get_sysclk_setting(unsigned int freq)
  2267. {
  2268. switch (freq) {
  2269. case 0:
  2270. case 5644800:
  2271. case 6144000:
  2272. return 0;
  2273. case 11289600:
  2274. case 12288000:
  2275. return MADERA_SYSCLK_12MHZ << MADERA_SYSCLK_FREQ_SHIFT;
  2276. case 22579200:
  2277. case 24576000:
  2278. return MADERA_SYSCLK_24MHZ << MADERA_SYSCLK_FREQ_SHIFT;
  2279. case 45158400:
  2280. case 49152000:
  2281. return MADERA_SYSCLK_49MHZ << MADERA_SYSCLK_FREQ_SHIFT;
  2282. case 90316800:
  2283. case 98304000:
  2284. return MADERA_SYSCLK_98MHZ << MADERA_SYSCLK_FREQ_SHIFT;
  2285. default:
  2286. return -EINVAL;
  2287. }
  2288. }
  2289. static int madera_get_legacy_dspclk_setting(struct madera *madera,
  2290. unsigned int freq)
  2291. {
  2292. switch (freq) {
  2293. case 0:
  2294. return 0;
  2295. case 45158400:
  2296. case 49152000:
  2297. switch (madera->type) {
  2298. case CS47L85:
  2299. case WM1840:
  2300. if (madera->rev < 3)
  2301. return -EINVAL;
  2302. else
  2303. return MADERA_SYSCLK_49MHZ <<
  2304. MADERA_SYSCLK_FREQ_SHIFT;
  2305. default:
  2306. return -EINVAL;
  2307. }
  2308. case 135475200:
  2309. case 147456000:
  2310. return MADERA_DSPCLK_147MHZ << MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
  2311. default:
  2312. return -EINVAL;
  2313. }
  2314. }
  2315. static int madera_get_dspclk_setting(struct madera *madera,
  2316. unsigned int freq,
  2317. unsigned int *clock_2_val)
  2318. {
  2319. switch (madera->type) {
  2320. case CS47L35:
  2321. case CS47L85:
  2322. case WM1840:
  2323. *clock_2_val = 0; /* don't use MADERA_DSP_CLOCK_2 */
  2324. return madera_get_legacy_dspclk_setting(madera, freq);
  2325. default:
  2326. if (freq > 150000000)
  2327. return -EINVAL;
  2328. /* Use new exact frequency control */
  2329. *clock_2_val = freq / 15625; /* freq * (2^6) / (10^6) */
  2330. return 0;
  2331. }
  2332. }
  2333. static int madera_set_outclk(struct snd_soc_component *component,
  2334. unsigned int source, unsigned int freq)
  2335. {
  2336. int div, div_inc, rate;
  2337. switch (source) {
  2338. case MADERA_OUTCLK_SYSCLK:
  2339. dev_dbg(component->dev, "Configured OUTCLK to SYSCLK\n");
  2340. snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
  2341. MADERA_OUT_CLK_SRC_MASK, source);
  2342. return 0;
  2343. case MADERA_OUTCLK_ASYNCCLK:
  2344. dev_dbg(component->dev, "Configured OUTCLK to ASYNCCLK\n");
  2345. snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
  2346. MADERA_OUT_CLK_SRC_MASK, source);
  2347. return 0;
  2348. case MADERA_OUTCLK_MCLK1:
  2349. case MADERA_OUTCLK_MCLK2:
  2350. case MADERA_OUTCLK_MCLK3:
  2351. break;
  2352. default:
  2353. return -EINVAL;
  2354. }
  2355. if (freq % 4000)
  2356. rate = 5644800;
  2357. else
  2358. rate = 6144000;
  2359. div = 1;
  2360. div_inc = 0;
  2361. while (div <= 8) {
  2362. if (freq / div == rate && !(freq % div)) {
  2363. dev_dbg(component->dev, "Configured %dHz OUTCLK\n", rate);
  2364. snd_soc_component_update_bits(component,
  2365. MADERA_OUTPUT_RATE_1,
  2366. MADERA_OUT_EXT_CLK_DIV_MASK |
  2367. MADERA_OUT_CLK_SRC_MASK,
  2368. (div_inc << MADERA_OUT_EXT_CLK_DIV_SHIFT) |
  2369. source);
  2370. return 0;
  2371. }
  2372. div_inc++;
  2373. div *= 2;
  2374. }
  2375. dev_err(component->dev,
  2376. "Unable to generate %dHz OUTCLK from %dHz MCLK\n",
  2377. rate, freq);
  2378. return -EINVAL;
  2379. }
  2380. int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
  2381. int source, unsigned int freq, int dir)
  2382. {
  2383. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2384. struct madera *madera = priv->madera;
  2385. char *name;
  2386. unsigned int reg, clock_2_val = 0;
  2387. unsigned int mask = MADERA_SYSCLK_FREQ_MASK | MADERA_SYSCLK_SRC_MASK;
  2388. unsigned int val = source << MADERA_SYSCLK_SRC_SHIFT;
  2389. int clk_freq_sel, *clk;
  2390. int ret = 0;
  2391. switch (clk_id) {
  2392. case MADERA_CLK_SYSCLK_1:
  2393. name = "SYSCLK";
  2394. reg = MADERA_SYSTEM_CLOCK_1;
  2395. clk = &priv->sysclk;
  2396. clk_freq_sel = madera_get_sysclk_setting(freq);
  2397. mask |= MADERA_SYSCLK_FRAC;
  2398. break;
  2399. case MADERA_CLK_ASYNCCLK_1:
  2400. name = "ASYNCCLK";
  2401. reg = MADERA_ASYNC_CLOCK_1;
  2402. clk = &priv->asyncclk;
  2403. clk_freq_sel = madera_get_sysclk_setting(freq);
  2404. break;
  2405. case MADERA_CLK_DSPCLK:
  2406. name = "DSPCLK";
  2407. reg = MADERA_DSP_CLOCK_1;
  2408. clk = &priv->dspclk;
  2409. clk_freq_sel = madera_get_dspclk_setting(madera, freq,
  2410. &clock_2_val);
  2411. break;
  2412. case MADERA_CLK_OPCLK:
  2413. case MADERA_CLK_ASYNC_OPCLK:
  2414. return madera_set_opclk(component, clk_id, freq);
  2415. case MADERA_CLK_OUTCLK:
  2416. return madera_set_outclk(component, source, freq);
  2417. default:
  2418. return -EINVAL;
  2419. }
  2420. if (clk_freq_sel < 0) {
  2421. dev_err(madera->dev,
  2422. "Failed to get clk setting for %dHZ\n", freq);
  2423. return clk_freq_sel;
  2424. }
  2425. *clk = freq;
  2426. if (freq == 0) {
  2427. dev_dbg(madera->dev, "%s cleared\n", name);
  2428. return 0;
  2429. }
  2430. val |= clk_freq_sel;
  2431. if (clock_2_val) {
  2432. ret = regmap_write(madera->regmap, MADERA_DSP_CLOCK_2,
  2433. clock_2_val);
  2434. if (ret) {
  2435. dev_err(madera->dev,
  2436. "Failed to write DSP_CONFIG2: %d\n", ret);
  2437. return ret;
  2438. }
  2439. /*
  2440. * We're using the frequency setting in MADERA_DSP_CLOCK_2 so
  2441. * don't change the frequency select bits in MADERA_DSP_CLOCK_1
  2442. */
  2443. mask = MADERA_SYSCLK_SRC_MASK;
  2444. }
  2445. if (freq % 6144000)
  2446. val |= MADERA_SYSCLK_FRAC;
  2447. dev_dbg(madera->dev, "%s set to %uHz\n", name, freq);
  2448. return regmap_update_bits(madera->regmap, reg, mask, val);
  2449. }
  2450. EXPORT_SYMBOL_GPL(madera_set_sysclk);
  2451. static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  2452. {
  2453. struct snd_soc_component *component = dai->component;
  2454. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2455. struct madera *madera = priv->madera;
  2456. int lrclk, bclk, mode, base;
  2457. base = dai->driver->base;
  2458. lrclk = 0;
  2459. bclk = 0;
  2460. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  2461. case SND_SOC_DAIFMT_DSP_A:
  2462. mode = MADERA_FMT_DSP_MODE_A;
  2463. break;
  2464. case SND_SOC_DAIFMT_DSP_B:
  2465. if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
  2466. SND_SOC_DAIFMT_CBM_CFM) {
  2467. madera_aif_err(dai, "DSP_B not valid in slave mode\n");
  2468. return -EINVAL;
  2469. }
  2470. mode = MADERA_FMT_DSP_MODE_B;
  2471. break;
  2472. case SND_SOC_DAIFMT_I2S:
  2473. mode = MADERA_FMT_I2S_MODE;
  2474. break;
  2475. case SND_SOC_DAIFMT_LEFT_J:
  2476. if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
  2477. SND_SOC_DAIFMT_CBM_CFM) {
  2478. madera_aif_err(dai, "LEFT_J not valid in slave mode\n");
  2479. return -EINVAL;
  2480. }
  2481. mode = MADERA_FMT_LEFT_JUSTIFIED_MODE;
  2482. break;
  2483. default:
  2484. madera_aif_err(dai, "Unsupported DAI format %d\n",
  2485. fmt & SND_SOC_DAIFMT_FORMAT_MASK);
  2486. return -EINVAL;
  2487. }
  2488. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  2489. case SND_SOC_DAIFMT_CBS_CFS:
  2490. break;
  2491. case SND_SOC_DAIFMT_CBS_CFM:
  2492. lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
  2493. break;
  2494. case SND_SOC_DAIFMT_CBM_CFS:
  2495. bclk |= MADERA_AIF1_BCLK_MSTR;
  2496. break;
  2497. case SND_SOC_DAIFMT_CBM_CFM:
  2498. bclk |= MADERA_AIF1_BCLK_MSTR;
  2499. lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
  2500. break;
  2501. default:
  2502. madera_aif_err(dai, "Unsupported master mode %d\n",
  2503. fmt & SND_SOC_DAIFMT_MASTER_MASK);
  2504. return -EINVAL;
  2505. }
  2506. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  2507. case SND_SOC_DAIFMT_NB_NF:
  2508. break;
  2509. case SND_SOC_DAIFMT_IB_IF:
  2510. bclk |= MADERA_AIF1_BCLK_INV;
  2511. lrclk |= MADERA_AIF1TX_LRCLK_INV;
  2512. break;
  2513. case SND_SOC_DAIFMT_IB_NF:
  2514. bclk |= MADERA_AIF1_BCLK_INV;
  2515. break;
  2516. case SND_SOC_DAIFMT_NB_IF:
  2517. lrclk |= MADERA_AIF1TX_LRCLK_INV;
  2518. break;
  2519. default:
  2520. madera_aif_err(dai, "Unsupported invert mode %d\n",
  2521. fmt & SND_SOC_DAIFMT_INV_MASK);
  2522. return -EINVAL;
  2523. }
  2524. regmap_update_bits(madera->regmap, base + MADERA_AIF_BCLK_CTRL,
  2525. MADERA_AIF1_BCLK_INV | MADERA_AIF1_BCLK_MSTR,
  2526. bclk);
  2527. regmap_update_bits(madera->regmap, base + MADERA_AIF_TX_PIN_CTRL,
  2528. MADERA_AIF1TX_LRCLK_INV | MADERA_AIF1TX_LRCLK_MSTR,
  2529. lrclk);
  2530. regmap_update_bits(madera->regmap, base + MADERA_AIF_RX_PIN_CTRL,
  2531. MADERA_AIF1RX_LRCLK_INV | MADERA_AIF1RX_LRCLK_MSTR,
  2532. lrclk);
  2533. regmap_update_bits(madera->regmap, base + MADERA_AIF_FORMAT,
  2534. MADERA_AIF1_FMT_MASK, mode);
  2535. return 0;
  2536. }
  2537. static const int madera_48k_bclk_rates[] = {
  2538. -1,
  2539. 48000,
  2540. 64000,
  2541. 96000,
  2542. 128000,
  2543. 192000,
  2544. 256000,
  2545. 384000,
  2546. 512000,
  2547. 768000,
  2548. 1024000,
  2549. 1536000,
  2550. 2048000,
  2551. 3072000,
  2552. 4096000,
  2553. 6144000,
  2554. 8192000,
  2555. 12288000,
  2556. 24576000,
  2557. };
  2558. static const int madera_44k1_bclk_rates[] = {
  2559. -1,
  2560. 44100,
  2561. 58800,
  2562. 88200,
  2563. 117600,
  2564. 177640,
  2565. 235200,
  2566. 352800,
  2567. 470400,
  2568. 705600,
  2569. 940800,
  2570. 1411200,
  2571. 1881600,
  2572. 2822400,
  2573. 3763200,
  2574. 5644800,
  2575. 7526400,
  2576. 11289600,
  2577. 22579200,
  2578. };
  2579. static const unsigned int madera_sr_vals[] = {
  2580. 0,
  2581. 12000,
  2582. 24000,
  2583. 48000,
  2584. 96000,
  2585. 192000,
  2586. 384000,
  2587. 768000,
  2588. 0,
  2589. 11025,
  2590. 22050,
  2591. 44100,
  2592. 88200,
  2593. 176400,
  2594. 352800,
  2595. 705600,
  2596. 4000,
  2597. 8000,
  2598. 16000,
  2599. 32000,
  2600. 64000,
  2601. 128000,
  2602. 256000,
  2603. 512000,
  2604. };
  2605. #define MADERA_192K_48K_RATE_MASK 0x0F003E
  2606. #define MADERA_192K_44K1_RATE_MASK 0x003E00
  2607. #define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \
  2608. MADERA_192K_44K1_RATE_MASK)
  2609. #define MADERA_384K_48K_RATE_MASK 0x0F007E
  2610. #define MADERA_384K_44K1_RATE_MASK 0x007E00
  2611. #define MADERA_384K_RATE_MASK (MADERA_384K_48K_RATE_MASK | \
  2612. MADERA_384K_44K1_RATE_MASK)
  2613. static const struct snd_pcm_hw_constraint_list madera_constraint = {
  2614. .count = ARRAY_SIZE(madera_sr_vals),
  2615. .list = madera_sr_vals,
  2616. };
  2617. static int madera_startup(struct snd_pcm_substream *substream,
  2618. struct snd_soc_dai *dai)
  2619. {
  2620. struct snd_soc_component *component = dai->component;
  2621. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2622. struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  2623. struct madera *madera = priv->madera;
  2624. unsigned int base_rate;
  2625. if (!substream->runtime)
  2626. return 0;
  2627. switch (dai_priv->clk) {
  2628. case MADERA_CLK_SYSCLK_1:
  2629. case MADERA_CLK_SYSCLK_2:
  2630. case MADERA_CLK_SYSCLK_3:
  2631. base_rate = priv->sysclk;
  2632. break;
  2633. case MADERA_CLK_ASYNCCLK_1:
  2634. case MADERA_CLK_ASYNCCLK_2:
  2635. base_rate = priv->asyncclk;
  2636. break;
  2637. default:
  2638. return 0;
  2639. }
  2640. switch (madera->type) {
  2641. case CS42L92:
  2642. case CS47L92:
  2643. case CS47L93:
  2644. if (base_rate == 0)
  2645. dai_priv->constraint.mask = MADERA_384K_RATE_MASK;
  2646. else if (base_rate % 4000)
  2647. dai_priv->constraint.mask = MADERA_384K_44K1_RATE_MASK;
  2648. else
  2649. dai_priv->constraint.mask = MADERA_384K_48K_RATE_MASK;
  2650. break;
  2651. default:
  2652. if (base_rate == 0)
  2653. dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
  2654. else if (base_rate % 4000)
  2655. dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
  2656. else
  2657. dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
  2658. break;
  2659. }
  2660. return snd_pcm_hw_constraint_list(substream->runtime, 0,
  2661. SNDRV_PCM_HW_PARAM_RATE,
  2662. &dai_priv->constraint);
  2663. }
  2664. static int madera_hw_params_rate(struct snd_pcm_substream *substream,
  2665. struct snd_pcm_hw_params *params,
  2666. struct snd_soc_dai *dai)
  2667. {
  2668. struct snd_soc_component *component = dai->component;
  2669. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2670. struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  2671. int base = dai->driver->base;
  2672. int i, sr_val;
  2673. unsigned int reg, cur, tar;
  2674. int ret;
  2675. for (i = 0; i < ARRAY_SIZE(madera_sr_vals); i++)
  2676. if (madera_sr_vals[i] == params_rate(params))
  2677. break;
  2678. if (i == ARRAY_SIZE(madera_sr_vals)) {
  2679. madera_aif_err(dai, "Unsupported sample rate %dHz\n",
  2680. params_rate(params));
  2681. return -EINVAL;
  2682. }
  2683. sr_val = i;
  2684. switch (dai_priv->clk) {
  2685. case MADERA_CLK_SYSCLK_1:
  2686. reg = MADERA_SAMPLE_RATE_1;
  2687. tar = 0 << MADERA_AIF1_RATE_SHIFT;
  2688. break;
  2689. case MADERA_CLK_SYSCLK_2:
  2690. reg = MADERA_SAMPLE_RATE_2;
  2691. tar = 1 << MADERA_AIF1_RATE_SHIFT;
  2692. break;
  2693. case MADERA_CLK_SYSCLK_3:
  2694. reg = MADERA_SAMPLE_RATE_3;
  2695. tar = 2 << MADERA_AIF1_RATE_SHIFT;
  2696. break;
  2697. case MADERA_CLK_ASYNCCLK_1:
  2698. reg = MADERA_ASYNC_SAMPLE_RATE_1;
  2699. tar = 8 << MADERA_AIF1_RATE_SHIFT;
  2700. break;
  2701. case MADERA_CLK_ASYNCCLK_2:
  2702. reg = MADERA_ASYNC_SAMPLE_RATE_2;
  2703. tar = 9 << MADERA_AIF1_RATE_SHIFT;
  2704. break;
  2705. default:
  2706. madera_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
  2707. return -EINVAL;
  2708. }
  2709. snd_soc_component_update_bits(component, reg, MADERA_SAMPLE_RATE_1_MASK,
  2710. sr_val);
  2711. if (!base)
  2712. return 0;
  2713. ret = regmap_read(priv->madera->regmap,
  2714. base + MADERA_AIF_RATE_CTRL, &cur);
  2715. if (ret != 0) {
  2716. madera_aif_err(dai, "Failed to check rate: %d\n", ret);
  2717. return ret;
  2718. }
  2719. if ((cur & MADERA_AIF1_RATE_MASK) == (tar & MADERA_AIF1_RATE_MASK))
  2720. return 0;
  2721. mutex_lock(&priv->rate_lock);
  2722. if (!madera_can_change_grp_rate(priv, base + MADERA_AIF_RATE_CTRL)) {
  2723. madera_aif_warn(dai, "Cannot change rate while active\n");
  2724. ret = -EBUSY;
  2725. goto out;
  2726. }
  2727. /* Guard the rate change with SYSCLK cycles */
  2728. madera_spin_sysclk(priv);
  2729. snd_soc_component_update_bits(component, base + MADERA_AIF_RATE_CTRL,
  2730. MADERA_AIF1_RATE_MASK, tar);
  2731. madera_spin_sysclk(priv);
  2732. out:
  2733. mutex_unlock(&priv->rate_lock);
  2734. return ret;
  2735. }
  2736. static int madera_aif_cfg_changed(struct snd_soc_component *component,
  2737. int base, int bclk, int lrclk, int frame)
  2738. {
  2739. unsigned int val;
  2740. val = snd_soc_component_read(component, base + MADERA_AIF_BCLK_CTRL);
  2741. if (bclk != (val & MADERA_AIF1_BCLK_FREQ_MASK))
  2742. return 1;
  2743. val = snd_soc_component_read(component, base + MADERA_AIF_RX_BCLK_RATE);
  2744. if (lrclk != (val & MADERA_AIF1RX_BCPF_MASK))
  2745. return 1;
  2746. val = snd_soc_component_read(component, base + MADERA_AIF_FRAME_CTRL_1);
  2747. if (frame != (val & (MADERA_AIF1TX_WL_MASK |
  2748. MADERA_AIF1TX_SLOT_LEN_MASK)))
  2749. return 1;
  2750. return 0;
  2751. }
  2752. static int madera_hw_params(struct snd_pcm_substream *substream,
  2753. struct snd_pcm_hw_params *params,
  2754. struct snd_soc_dai *dai)
  2755. {
  2756. struct snd_soc_component *component = dai->component;
  2757. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2758. struct madera *madera = priv->madera;
  2759. int base = dai->driver->base;
  2760. const int *rates;
  2761. int i, ret;
  2762. unsigned int val;
  2763. unsigned int channels = params_channels(params);
  2764. unsigned int rate = params_rate(params);
  2765. unsigned int chan_limit =
  2766. madera->pdata.codec.max_channels_clocked[dai->id - 1];
  2767. int tdm_width = priv->tdm_width[dai->id - 1];
  2768. int tdm_slots = priv->tdm_slots[dai->id - 1];
  2769. int bclk, lrclk, wl, frame, bclk_target, num_rates;
  2770. int reconfig;
  2771. unsigned int aif_tx_state = 0, aif_rx_state = 0;
  2772. if (rate % 4000) {
  2773. rates = &madera_44k1_bclk_rates[0];
  2774. num_rates = ARRAY_SIZE(madera_44k1_bclk_rates);
  2775. } else {
  2776. rates = &madera_48k_bclk_rates[0];
  2777. num_rates = ARRAY_SIZE(madera_48k_bclk_rates);
  2778. }
  2779. wl = snd_pcm_format_width(params_format(params));
  2780. if (tdm_slots) {
  2781. madera_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
  2782. tdm_slots, tdm_width);
  2783. bclk_target = tdm_slots * tdm_width * rate;
  2784. channels = tdm_slots;
  2785. } else {
  2786. bclk_target = snd_soc_params_to_bclk(params);
  2787. tdm_width = wl;
  2788. }
  2789. if (chan_limit && chan_limit < channels) {
  2790. madera_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
  2791. bclk_target /= channels;
  2792. bclk_target *= chan_limit;
  2793. }
  2794. /* Force multiple of 2 channels for I2S mode */
  2795. val = snd_soc_component_read(component, base + MADERA_AIF_FORMAT);
  2796. val &= MADERA_AIF1_FMT_MASK;
  2797. if ((channels & 1) && val == MADERA_FMT_I2S_MODE) {
  2798. madera_aif_dbg(dai, "Forcing stereo mode\n");
  2799. bclk_target /= channels;
  2800. bclk_target *= channels + 1;
  2801. }
  2802. for (i = 0; i < num_rates; i++) {
  2803. if (rates[i] >= bclk_target && rates[i] % rate == 0) {
  2804. bclk = i;
  2805. break;
  2806. }
  2807. }
  2808. if (i == num_rates) {
  2809. madera_aif_err(dai, "Unsupported sample rate %dHz\n", rate);
  2810. return -EINVAL;
  2811. }
  2812. lrclk = rates[bclk] / rate;
  2813. madera_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
  2814. rates[bclk], rates[bclk] / lrclk);
  2815. frame = wl << MADERA_AIF1TX_WL_SHIFT | tdm_width;
  2816. reconfig = madera_aif_cfg_changed(component, base, bclk, lrclk, frame);
  2817. if (reconfig < 0)
  2818. return reconfig;
  2819. if (reconfig) {
  2820. /* Save AIF TX/RX state */
  2821. regmap_read(madera->regmap, base + MADERA_AIF_TX_ENABLES,
  2822. &aif_tx_state);
  2823. regmap_read(madera->regmap, base + MADERA_AIF_RX_ENABLES,
  2824. &aif_rx_state);
  2825. /* Disable AIF TX/RX before reconfiguring it */
  2826. regmap_update_bits(madera->regmap,
  2827. base + MADERA_AIF_TX_ENABLES, 0xff, 0x0);
  2828. regmap_update_bits(madera->regmap,
  2829. base + MADERA_AIF_RX_ENABLES, 0xff, 0x0);
  2830. }
  2831. ret = madera_hw_params_rate(substream, params, dai);
  2832. if (ret != 0)
  2833. goto restore_aif;
  2834. if (reconfig) {
  2835. regmap_update_bits(madera->regmap,
  2836. base + MADERA_AIF_BCLK_CTRL,
  2837. MADERA_AIF1_BCLK_FREQ_MASK, bclk);
  2838. regmap_update_bits(madera->regmap,
  2839. base + MADERA_AIF_RX_BCLK_RATE,
  2840. MADERA_AIF1RX_BCPF_MASK, lrclk);
  2841. regmap_update_bits(madera->regmap,
  2842. base + MADERA_AIF_FRAME_CTRL_1,
  2843. MADERA_AIF1TX_WL_MASK |
  2844. MADERA_AIF1TX_SLOT_LEN_MASK, frame);
  2845. regmap_update_bits(madera->regmap,
  2846. base + MADERA_AIF_FRAME_CTRL_2,
  2847. MADERA_AIF1RX_WL_MASK |
  2848. MADERA_AIF1RX_SLOT_LEN_MASK, frame);
  2849. }
  2850. restore_aif:
  2851. if (reconfig) {
  2852. /* Restore AIF TX/RX state */
  2853. regmap_update_bits(madera->regmap,
  2854. base + MADERA_AIF_TX_ENABLES,
  2855. 0xff, aif_tx_state);
  2856. regmap_update_bits(madera->regmap,
  2857. base + MADERA_AIF_RX_ENABLES,
  2858. 0xff, aif_rx_state);
  2859. }
  2860. return ret;
  2861. }
  2862. static int madera_is_syncclk(int clk_id)
  2863. {
  2864. switch (clk_id) {
  2865. case MADERA_CLK_SYSCLK_1:
  2866. case MADERA_CLK_SYSCLK_2:
  2867. case MADERA_CLK_SYSCLK_3:
  2868. return 1;
  2869. case MADERA_CLK_ASYNCCLK_1:
  2870. case MADERA_CLK_ASYNCCLK_2:
  2871. return 0;
  2872. default:
  2873. return -EINVAL;
  2874. }
  2875. }
  2876. static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
  2877. int clk_id, unsigned int freq, int dir)
  2878. {
  2879. struct snd_soc_component *component = dai->component;
  2880. struct snd_soc_dapm_context *dapm =
  2881. snd_soc_component_get_dapm(component);
  2882. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2883. struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
  2884. struct snd_soc_dapm_route routes[2];
  2885. int is_sync;
  2886. is_sync = madera_is_syncclk(clk_id);
  2887. if (is_sync < 0) {
  2888. dev_err(component->dev, "Illegal DAI clock id %d\n", clk_id);
  2889. return is_sync;
  2890. }
  2891. if (is_sync == madera_is_syncclk(dai_priv->clk))
  2892. return 0;
  2893. if (snd_soc_dai_active(dai)) {
  2894. dev_err(component->dev, "Can't change clock on active DAI %d\n",
  2895. dai->id);
  2896. return -EBUSY;
  2897. }
  2898. dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id,
  2899. is_sync ? "SYSCLK" : "ASYNCCLK");
  2900. /*
  2901. * A connection to SYSCLK is always required, we only add and remove
  2902. * a connection to ASYNCCLK
  2903. */
  2904. memset(&routes, 0, sizeof(routes));
  2905. routes[0].sink = dai->driver->capture.stream_name;
  2906. routes[1].sink = dai->driver->playback.stream_name;
  2907. routes[0].source = "ASYNCCLK";
  2908. routes[1].source = "ASYNCCLK";
  2909. if (is_sync)
  2910. snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
  2911. else
  2912. snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
  2913. dai_priv->clk = clk_id;
  2914. return snd_soc_dapm_sync(dapm);
  2915. }
  2916. static int madera_set_tristate(struct snd_soc_dai *dai, int tristate)
  2917. {
  2918. struct snd_soc_component *component = dai->component;
  2919. int base = dai->driver->base;
  2920. unsigned int reg;
  2921. int ret;
  2922. if (tristate)
  2923. reg = MADERA_AIF1_TRI;
  2924. else
  2925. reg = 0;
  2926. ret = snd_soc_component_update_bits(component,
  2927. base + MADERA_AIF_RATE_CTRL,
  2928. MADERA_AIF1_TRI, reg);
  2929. if (ret < 0)
  2930. return ret;
  2931. else
  2932. return 0;
  2933. }
  2934. static void madera_set_channels_to_mask(struct snd_soc_dai *dai,
  2935. unsigned int base,
  2936. int channels, unsigned int mask)
  2937. {
  2938. struct snd_soc_component *component = dai->component;
  2939. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2940. struct madera *madera = priv->madera;
  2941. int slot, i;
  2942. for (i = 0; i < channels; ++i) {
  2943. slot = ffs(mask) - 1;
  2944. if (slot < 0)
  2945. return;
  2946. regmap_write(madera->regmap, base + i, slot);
  2947. mask &= ~(1 << slot);
  2948. }
  2949. if (mask)
  2950. madera_aif_warn(dai, "Too many channels in TDM mask\n");
  2951. }
  2952. static int madera_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
  2953. unsigned int rx_mask, int slots, int slot_width)
  2954. {
  2955. struct snd_soc_component *component = dai->component;
  2956. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  2957. int base = dai->driver->base;
  2958. int rx_max_chan = dai->driver->playback.channels_max;
  2959. int tx_max_chan = dai->driver->capture.channels_max;
  2960. /* Only support TDM for the physical AIFs */
  2961. if (dai->id > MADERA_MAX_AIF)
  2962. return -ENOTSUPP;
  2963. if (slots == 0) {
  2964. tx_mask = (1 << tx_max_chan) - 1;
  2965. rx_mask = (1 << rx_max_chan) - 1;
  2966. }
  2967. madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_3,
  2968. tx_max_chan, tx_mask);
  2969. madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_11,
  2970. rx_max_chan, rx_mask);
  2971. priv->tdm_width[dai->id - 1] = slot_width;
  2972. priv->tdm_slots[dai->id - 1] = slots;
  2973. return 0;
  2974. }
  2975. const struct snd_soc_dai_ops madera_dai_ops = {
  2976. .startup = &madera_startup,
  2977. .set_fmt = &madera_set_fmt,
  2978. .set_tdm_slot = &madera_set_tdm_slot,
  2979. .hw_params = &madera_hw_params,
  2980. .set_sysclk = &madera_dai_set_sysclk,
  2981. .set_tristate = &madera_set_tristate,
  2982. };
  2983. EXPORT_SYMBOL_GPL(madera_dai_ops);
  2984. const struct snd_soc_dai_ops madera_simple_dai_ops = {
  2985. .startup = &madera_startup,
  2986. .hw_params = &madera_hw_params_rate,
  2987. .set_sysclk = &madera_dai_set_sysclk,
  2988. };
  2989. EXPORT_SYMBOL_GPL(madera_simple_dai_ops);
  2990. int madera_init_dai(struct madera_priv *priv, int id)
  2991. {
  2992. struct madera_dai_priv *dai_priv = &priv->dai[id];
  2993. dai_priv->clk = MADERA_CLK_SYSCLK_1;
  2994. dai_priv->constraint = madera_constraint;
  2995. return 0;
  2996. }
  2997. EXPORT_SYMBOL_GPL(madera_init_dai);
  2998. static const struct {
  2999. unsigned int min;
  3000. unsigned int max;
  3001. u16 fratio;
  3002. int ratio;
  3003. } fll_sync_fratios[] = {
  3004. { 0, 64000, 4, 16 },
  3005. { 64000, 128000, 3, 8 },
  3006. { 128000, 256000, 2, 4 },
  3007. { 256000, 1000000, 1, 2 },
  3008. { 1000000, 13500000, 0, 1 },
  3009. };
  3010. static const unsigned int pseudo_fref_max[MADERA_FLL_MAX_FRATIO] = {
  3011. 13500000,
  3012. 6144000,
  3013. 6144000,
  3014. 3072000,
  3015. 3072000,
  3016. 2822400,
  3017. 2822400,
  3018. 1536000,
  3019. 1536000,
  3020. 1536000,
  3021. 1536000,
  3022. 1536000,
  3023. 1536000,
  3024. 1536000,
  3025. 1536000,
  3026. 768000,
  3027. };
  3028. struct madera_fll_gains {
  3029. unsigned int min;
  3030. unsigned int max;
  3031. int gain; /* main gain */
  3032. int alt_gain; /* alternate integer gain */
  3033. };
  3034. static const struct madera_fll_gains madera_fll_sync_gains[] = {
  3035. { 0, 256000, 0, -1 },
  3036. { 256000, 1000000, 2, -1 },
  3037. { 1000000, 13500000, 4, -1 },
  3038. };
  3039. static const struct madera_fll_gains madera_fll_main_gains[] = {
  3040. { 0, 100000, 0, 2 },
  3041. { 100000, 375000, 2, 2 },
  3042. { 375000, 768000, 3, 2 },
  3043. { 768001, 1500000, 3, 3 },
  3044. { 1500000, 6000000, 4, 3 },
  3045. { 6000000, 13500000, 5, 3 },
  3046. };
  3047. static int madera_find_sync_fratio(unsigned int fref, int *fratio)
  3048. {
  3049. int i;
  3050. for (i = 0; i < ARRAY_SIZE(fll_sync_fratios); i++) {
  3051. if (fll_sync_fratios[i].min <= fref &&
  3052. fref <= fll_sync_fratios[i].max) {
  3053. if (fratio)
  3054. *fratio = fll_sync_fratios[i].fratio;
  3055. return fll_sync_fratios[i].ratio;
  3056. }
  3057. }
  3058. return -EINVAL;
  3059. }
  3060. static int madera_find_main_fratio(unsigned int fref, unsigned int fout,
  3061. int *fratio)
  3062. {
  3063. int ratio = 1;
  3064. while ((fout / (ratio * fref)) > MADERA_FLL_MAX_N)
  3065. ratio++;
  3066. if (fratio)
  3067. *fratio = ratio - 1;
  3068. return ratio;
  3069. }
  3070. static int madera_find_fratio(struct madera_fll *fll, unsigned int fref,
  3071. bool sync, int *fratio)
  3072. {
  3073. switch (fll->madera->type) {
  3074. case CS47L35:
  3075. switch (fll->madera->rev) {
  3076. case 0:
  3077. /* rev A0 uses sync calculation for both loops */
  3078. return madera_find_sync_fratio(fref, fratio);
  3079. default:
  3080. if (sync)
  3081. return madera_find_sync_fratio(fref, fratio);
  3082. else
  3083. return madera_find_main_fratio(fref,
  3084. fll->fout,
  3085. fratio);
  3086. }
  3087. break;
  3088. case CS47L85:
  3089. case WM1840:
  3090. /* these use the same calculation for main and sync loops */
  3091. return madera_find_sync_fratio(fref, fratio);
  3092. default:
  3093. if (sync)
  3094. return madera_find_sync_fratio(fref, fratio);
  3095. else
  3096. return madera_find_main_fratio(fref, fll->fout, fratio);
  3097. }
  3098. }
  3099. static int madera_calc_fratio(struct madera_fll *fll,
  3100. struct madera_fll_cfg *cfg,
  3101. unsigned int fref, bool sync)
  3102. {
  3103. int init_ratio, ratio;
  3104. int refdiv, div;
  3105. /* fref must be <=13.5MHz, find initial refdiv */
  3106. div = 1;
  3107. cfg->refdiv = 0;
  3108. while (fref > MADERA_FLL_MAX_FREF) {
  3109. div *= 2;
  3110. fref /= 2;
  3111. cfg->refdiv++;
  3112. if (div > MADERA_FLL_MAX_REFDIV)
  3113. return -EINVAL;
  3114. }
  3115. /* Find an appropriate FLL_FRATIO */
  3116. init_ratio = madera_find_fratio(fll, fref, sync, &cfg->fratio);
  3117. if (init_ratio < 0) {
  3118. madera_fll_err(fll, "Unable to find FRATIO for fref=%uHz\n",
  3119. fref);
  3120. return init_ratio;
  3121. }
  3122. if (!sync)
  3123. cfg->fratio = init_ratio - 1;
  3124. switch (fll->madera->type) {
  3125. case CS47L35:
  3126. switch (fll->madera->rev) {
  3127. case 0:
  3128. if (sync)
  3129. return init_ratio;
  3130. break;
  3131. default:
  3132. return init_ratio;
  3133. }
  3134. break;
  3135. case CS47L85:
  3136. case WM1840:
  3137. if (sync)
  3138. return init_ratio;
  3139. break;
  3140. default:
  3141. return init_ratio;
  3142. }
  3143. /*
  3144. * For CS47L35 rev A0, CS47L85 and WM1840 adjust FRATIO/refdiv to avoid
  3145. * integer mode if possible
  3146. */
  3147. refdiv = cfg->refdiv;
  3148. while (div <= MADERA_FLL_MAX_REFDIV) {
  3149. /*
  3150. * start from init_ratio because this may already give a
  3151. * fractional N.K
  3152. */
  3153. for (ratio = init_ratio; ratio > 0; ratio--) {
  3154. if (fll->fout % (ratio * fref)) {
  3155. cfg->refdiv = refdiv;
  3156. cfg->fratio = ratio - 1;
  3157. return ratio;
  3158. }
  3159. }
  3160. for (ratio = init_ratio + 1; ratio <= MADERA_FLL_MAX_FRATIO;
  3161. ratio++) {
  3162. if ((MADERA_FLL_VCO_CORNER / 2) /
  3163. (MADERA_FLL_VCO_MULT * ratio) < fref)
  3164. break;
  3165. if (fref > pseudo_fref_max[ratio - 1])
  3166. break;
  3167. if (fll->fout % (ratio * fref)) {
  3168. cfg->refdiv = refdiv;
  3169. cfg->fratio = ratio - 1;
  3170. return ratio;
  3171. }
  3172. }
  3173. div *= 2;
  3174. fref /= 2;
  3175. refdiv++;
  3176. init_ratio = madera_find_fratio(fll, fref, sync, NULL);
  3177. }
  3178. madera_fll_warn(fll, "Falling back to integer mode operation\n");
  3179. return cfg->fratio + 1;
  3180. }
  3181. static int madera_find_fll_gain(struct madera_fll *fll,
  3182. struct madera_fll_cfg *cfg,
  3183. unsigned int fref,
  3184. const struct madera_fll_gains *gains,
  3185. int n_gains)
  3186. {
  3187. int i;
  3188. for (i = 0; i < n_gains; i++) {
  3189. if (gains[i].min <= fref && fref <= gains[i].max) {
  3190. cfg->gain = gains[i].gain;
  3191. cfg->alt_gain = gains[i].alt_gain;
  3192. return 0;
  3193. }
  3194. }
  3195. madera_fll_err(fll, "Unable to find gain for fref=%uHz\n", fref);
  3196. return -EINVAL;
  3197. }
  3198. static int madera_calc_fll(struct madera_fll *fll,
  3199. struct madera_fll_cfg *cfg,
  3200. unsigned int fref, bool sync)
  3201. {
  3202. unsigned int gcd_fll;
  3203. const struct madera_fll_gains *gains;
  3204. int n_gains;
  3205. int ratio, ret;
  3206. madera_fll_dbg(fll, "fref=%u Fout=%u fvco=%u\n",
  3207. fref, fll->fout, fll->fout * MADERA_FLL_VCO_MULT);
  3208. /* Find an appropriate FLL_FRATIO and refdiv */
  3209. ratio = madera_calc_fratio(fll, cfg, fref, sync);
  3210. if (ratio < 0)
  3211. return ratio;
  3212. /* Apply the division for our remaining calculations */
  3213. fref = fref / (1 << cfg->refdiv);
  3214. cfg->n = fll->fout / (ratio * fref);
  3215. if (fll->fout % (ratio * fref)) {
  3216. gcd_fll = gcd(fll->fout, ratio * fref);
  3217. madera_fll_dbg(fll, "GCD=%u\n", gcd_fll);
  3218. cfg->theta = (fll->fout - (cfg->n * ratio * fref))
  3219. / gcd_fll;
  3220. cfg->lambda = (ratio * fref) / gcd_fll;
  3221. } else {
  3222. cfg->theta = 0;
  3223. cfg->lambda = 0;
  3224. }
  3225. /*
  3226. * Round down to 16bit range with cost of accuracy lost.
  3227. * Denominator must be bigger than numerator so we only
  3228. * take care of it.
  3229. */
  3230. while (cfg->lambda >= (1 << 16)) {
  3231. cfg->theta >>= 1;
  3232. cfg->lambda >>= 1;
  3233. }
  3234. switch (fll->madera->type) {
  3235. case CS47L35:
  3236. switch (fll->madera->rev) {
  3237. case 0:
  3238. /* Rev A0 uses the sync gains for both loops */
  3239. gains = madera_fll_sync_gains;
  3240. n_gains = ARRAY_SIZE(madera_fll_sync_gains);
  3241. break;
  3242. default:
  3243. if (sync) {
  3244. gains = madera_fll_sync_gains;
  3245. n_gains = ARRAY_SIZE(madera_fll_sync_gains);
  3246. } else {
  3247. gains = madera_fll_main_gains;
  3248. n_gains = ARRAY_SIZE(madera_fll_main_gains);
  3249. }
  3250. break;
  3251. }
  3252. break;
  3253. case CS47L85:
  3254. case WM1840:
  3255. /* These use the sync gains for both loops */
  3256. gains = madera_fll_sync_gains;
  3257. n_gains = ARRAY_SIZE(madera_fll_sync_gains);
  3258. break;
  3259. default:
  3260. if (sync) {
  3261. gains = madera_fll_sync_gains;
  3262. n_gains = ARRAY_SIZE(madera_fll_sync_gains);
  3263. } else {
  3264. gains = madera_fll_main_gains;
  3265. n_gains = ARRAY_SIZE(madera_fll_main_gains);
  3266. }
  3267. break;
  3268. }
  3269. ret = madera_find_fll_gain(fll, cfg, fref, gains, n_gains);
  3270. if (ret)
  3271. return ret;
  3272. madera_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
  3273. cfg->n, cfg->theta, cfg->lambda);
  3274. madera_fll_dbg(fll, "FRATIO=0x%x(%d) REFCLK_DIV=0x%x(%d)\n",
  3275. cfg->fratio, ratio, cfg->refdiv, 1 << cfg->refdiv);
  3276. madera_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
  3277. return 0;
  3278. }
  3279. static bool madera_write_fll(struct madera *madera, unsigned int base,
  3280. struct madera_fll_cfg *cfg, int source,
  3281. bool sync, int gain)
  3282. {
  3283. bool change, fll_change;
  3284. fll_change = false;
  3285. regmap_update_bits_check(madera->regmap,
  3286. base + MADERA_FLL_CONTROL_3_OFFS,
  3287. MADERA_FLL1_THETA_MASK,
  3288. cfg->theta, &change);
  3289. fll_change |= change;
  3290. regmap_update_bits_check(madera->regmap,
  3291. base + MADERA_FLL_CONTROL_4_OFFS,
  3292. MADERA_FLL1_LAMBDA_MASK,
  3293. cfg->lambda, &change);
  3294. fll_change |= change;
  3295. regmap_update_bits_check(madera->regmap,
  3296. base + MADERA_FLL_CONTROL_5_OFFS,
  3297. MADERA_FLL1_FRATIO_MASK,
  3298. cfg->fratio << MADERA_FLL1_FRATIO_SHIFT,
  3299. &change);
  3300. fll_change |= change;
  3301. regmap_update_bits_check(madera->regmap,
  3302. base + MADERA_FLL_CONTROL_6_OFFS,
  3303. MADERA_FLL1_REFCLK_DIV_MASK |
  3304. MADERA_FLL1_REFCLK_SRC_MASK,
  3305. cfg->refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT |
  3306. source << MADERA_FLL1_REFCLK_SRC_SHIFT,
  3307. &change);
  3308. fll_change |= change;
  3309. if (sync) {
  3310. regmap_update_bits_check(madera->regmap,
  3311. base + MADERA_FLL_SYNCHRONISER_7_OFFS,
  3312. MADERA_FLL1_GAIN_MASK,
  3313. gain << MADERA_FLL1_GAIN_SHIFT,
  3314. &change);
  3315. fll_change |= change;
  3316. } else {
  3317. regmap_update_bits_check(madera->regmap,
  3318. base + MADERA_FLL_CONTROL_7_OFFS,
  3319. MADERA_FLL1_GAIN_MASK,
  3320. gain << MADERA_FLL1_GAIN_SHIFT,
  3321. &change);
  3322. fll_change |= change;
  3323. }
  3324. regmap_update_bits_check(madera->regmap,
  3325. base + MADERA_FLL_CONTROL_2_OFFS,
  3326. MADERA_FLL1_CTRL_UPD | MADERA_FLL1_N_MASK,
  3327. MADERA_FLL1_CTRL_UPD | cfg->n, &change);
  3328. fll_change |= change;
  3329. return fll_change;
  3330. }
  3331. static int madera_is_enabled_fll(struct madera_fll *fll, int base)
  3332. {
  3333. struct madera *madera = fll->madera;
  3334. unsigned int reg;
  3335. int ret;
  3336. ret = regmap_read(madera->regmap,
  3337. base + MADERA_FLL_CONTROL_1_OFFS, &reg);
  3338. if (ret != 0) {
  3339. madera_fll_err(fll, "Failed to read current state: %d\n", ret);
  3340. return ret;
  3341. }
  3342. return reg & MADERA_FLL1_ENA;
  3343. }
  3344. static int madera_wait_for_fll(struct madera_fll *fll, bool requested)
  3345. {
  3346. struct madera *madera = fll->madera;
  3347. unsigned int val = 0;
  3348. bool status;
  3349. int i;
  3350. madera_fll_dbg(fll, "Waiting for FLL...\n");
  3351. for (i = 0; i < 30; i++) {
  3352. regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_2, &val);
  3353. status = val & (MADERA_FLL1_LOCK_STS1 << (fll->id - 1));
  3354. if (status == requested)
  3355. return 0;
  3356. switch (i) {
  3357. case 0 ... 5:
  3358. usleep_range(75, 125);
  3359. break;
  3360. case 11 ... 20:
  3361. usleep_range(750, 1250);
  3362. break;
  3363. default:
  3364. msleep(20);
  3365. break;
  3366. }
  3367. }
  3368. madera_fll_warn(fll, "Timed out waiting for lock\n");
  3369. return -ETIMEDOUT;
  3370. }
  3371. static bool madera_set_fll_phase_integrator(struct madera_fll *fll,
  3372. struct madera_fll_cfg *ref_cfg,
  3373. bool sync)
  3374. {
  3375. unsigned int val;
  3376. bool reg_change;
  3377. if (!sync && ref_cfg->theta == 0)
  3378. val = (1 << MADERA_FLL1_PHASE_ENA_SHIFT) |
  3379. (2 << MADERA_FLL1_PHASE_GAIN_SHIFT);
  3380. else
  3381. val = 2 << MADERA_FLL1_PHASE_GAIN_SHIFT;
  3382. regmap_update_bits_check(fll->madera->regmap,
  3383. fll->base + MADERA_FLL_EFS_2_OFFS,
  3384. MADERA_FLL1_PHASE_ENA_MASK |
  3385. MADERA_FLL1_PHASE_GAIN_MASK,
  3386. val, &reg_change);
  3387. return reg_change;
  3388. }
  3389. static int madera_set_fll_clks_reg(struct madera_fll *fll, bool ena,
  3390. unsigned int reg, unsigned int mask,
  3391. unsigned int shift)
  3392. {
  3393. struct madera *madera = fll->madera;
  3394. unsigned int src;
  3395. struct clk *clk;
  3396. int ret;
  3397. ret = regmap_read(madera->regmap, reg, &src);
  3398. if (ret != 0) {
  3399. madera_fll_err(fll, "Failed to read current source: %d\n",
  3400. ret);
  3401. return ret;
  3402. }
  3403. src = (src & mask) >> shift;
  3404. switch (src) {
  3405. case MADERA_FLL_SRC_MCLK1:
  3406. clk = madera->mclk[MADERA_MCLK1].clk;
  3407. break;
  3408. case MADERA_FLL_SRC_MCLK2:
  3409. clk = madera->mclk[MADERA_MCLK2].clk;
  3410. break;
  3411. case MADERA_FLL_SRC_MCLK3:
  3412. clk = madera->mclk[MADERA_MCLK3].clk;
  3413. break;
  3414. default:
  3415. return 0;
  3416. }
  3417. if (ena) {
  3418. return clk_prepare_enable(clk);
  3419. } else {
  3420. clk_disable_unprepare(clk);
  3421. return 0;
  3422. }
  3423. }
  3424. static inline int madera_set_fll_clks(struct madera_fll *fll, int base, bool ena)
  3425. {
  3426. return madera_set_fll_clks_reg(fll, ena,
  3427. base + MADERA_FLL_CONTROL_6_OFFS,
  3428. MADERA_FLL1_REFCLK_SRC_MASK,
  3429. MADERA_FLL1_REFCLK_DIV_SHIFT);
  3430. }
  3431. static inline int madera_set_fllao_clks(struct madera_fll *fll, int base, bool ena)
  3432. {
  3433. return madera_set_fll_clks_reg(fll, ena,
  3434. base + MADERA_FLLAO_CONTROL_6_OFFS,
  3435. MADERA_FLL_AO_REFCLK_SRC_MASK,
  3436. MADERA_FLL_AO_REFCLK_SRC_SHIFT);
  3437. }
  3438. static inline int madera_set_fllhj_clks(struct madera_fll *fll, int base, bool ena)
  3439. {
  3440. return madera_set_fll_clks_reg(fll, ena,
  3441. base + MADERA_FLL_CONTROL_1_OFFS,
  3442. CS47L92_FLL1_REFCLK_SRC_MASK,
  3443. CS47L92_FLL1_REFCLK_SRC_SHIFT);
  3444. }
  3445. static void madera_disable_fll(struct madera_fll *fll)
  3446. {
  3447. struct madera *madera = fll->madera;
  3448. unsigned int sync_base;
  3449. bool ref_change, sync_change;
  3450. switch (madera->type) {
  3451. case CS47L35:
  3452. sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
  3453. break;
  3454. default:
  3455. sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
  3456. break;
  3457. }
  3458. madera_fll_dbg(fll, "Disabling FLL\n");
  3459. regmap_update_bits(madera->regmap,
  3460. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3461. MADERA_FLL1_FREERUN, MADERA_FLL1_FREERUN);
  3462. regmap_update_bits_check(madera->regmap,
  3463. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3464. MADERA_FLL1_ENA, 0, &ref_change);
  3465. regmap_update_bits_check(madera->regmap,
  3466. sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
  3467. MADERA_FLL1_SYNC_ENA, 0, &sync_change);
  3468. regmap_update_bits(madera->regmap,
  3469. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3470. MADERA_FLL1_FREERUN, 0);
  3471. madera_wait_for_fll(fll, false);
  3472. if (sync_change)
  3473. madera_set_fll_clks(fll, sync_base, false);
  3474. if (ref_change) {
  3475. madera_set_fll_clks(fll, fll->base, false);
  3476. pm_runtime_put_autosuspend(madera->dev);
  3477. }
  3478. }
  3479. static int madera_enable_fll(struct madera_fll *fll)
  3480. {
  3481. struct madera *madera = fll->madera;
  3482. bool have_sync = false;
  3483. int already_enabled = madera_is_enabled_fll(fll, fll->base);
  3484. int sync_enabled;
  3485. struct madera_fll_cfg cfg;
  3486. unsigned int sync_base;
  3487. int gain, ret;
  3488. bool fll_change = false;
  3489. if (already_enabled < 0)
  3490. return already_enabled; /* error getting current state */
  3491. if (fll->ref_src < 0 || fll->ref_freq == 0) {
  3492. madera_fll_err(fll, "No REFCLK\n");
  3493. ret = -EINVAL;
  3494. goto err;
  3495. }
  3496. madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
  3497. already_enabled ? "enabled" : "disabled");
  3498. if (fll->fout < MADERA_FLL_MIN_FOUT ||
  3499. fll->fout > MADERA_FLL_MAX_FOUT) {
  3500. madera_fll_err(fll, "invalid fout %uHz\n", fll->fout);
  3501. ret = -EINVAL;
  3502. goto err;
  3503. }
  3504. switch (madera->type) {
  3505. case CS47L35:
  3506. sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
  3507. break;
  3508. default:
  3509. sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
  3510. break;
  3511. }
  3512. sync_enabled = madera_is_enabled_fll(fll, sync_base);
  3513. if (sync_enabled < 0)
  3514. return sync_enabled;
  3515. if (already_enabled) {
  3516. /* Facilitate smooth refclk across the transition */
  3517. regmap_update_bits(fll->madera->regmap,
  3518. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3519. MADERA_FLL1_FREERUN,
  3520. MADERA_FLL1_FREERUN);
  3521. udelay(32);
  3522. regmap_update_bits(fll->madera->regmap,
  3523. fll->base + MADERA_FLL_CONTROL_7_OFFS,
  3524. MADERA_FLL1_GAIN_MASK, 0);
  3525. if (sync_enabled > 0)
  3526. madera_set_fll_clks(fll, sync_base, false);
  3527. madera_set_fll_clks(fll, fll->base, false);
  3528. }
  3529. /* Apply SYNCCLK setting */
  3530. if (fll->sync_src >= 0) {
  3531. ret = madera_calc_fll(fll, &cfg, fll->sync_freq, true);
  3532. if (ret < 0)
  3533. goto err;
  3534. fll_change |= madera_write_fll(madera, sync_base,
  3535. &cfg, fll->sync_src,
  3536. true, cfg.gain);
  3537. have_sync = true;
  3538. }
  3539. if (already_enabled && !!sync_enabled != have_sync)
  3540. madera_fll_warn(fll, "Synchroniser changed on active FLL\n");
  3541. /* Apply REFCLK setting */
  3542. ret = madera_calc_fll(fll, &cfg, fll->ref_freq, false);
  3543. if (ret < 0)
  3544. goto err;
  3545. /* Ref path hardcodes lambda to 65536 when sync is on */
  3546. if (have_sync && cfg.lambda)
  3547. cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
  3548. switch (fll->madera->type) {
  3549. case CS47L35:
  3550. switch (fll->madera->rev) {
  3551. case 0:
  3552. gain = cfg.gain;
  3553. break;
  3554. default:
  3555. fll_change |=
  3556. madera_set_fll_phase_integrator(fll, &cfg,
  3557. have_sync);
  3558. if (!have_sync && cfg.theta == 0)
  3559. gain = cfg.alt_gain;
  3560. else
  3561. gain = cfg.gain;
  3562. break;
  3563. }
  3564. break;
  3565. case CS47L85:
  3566. case WM1840:
  3567. gain = cfg.gain;
  3568. break;
  3569. default:
  3570. fll_change |= madera_set_fll_phase_integrator(fll, &cfg,
  3571. have_sync);
  3572. if (!have_sync && cfg.theta == 0)
  3573. gain = cfg.alt_gain;
  3574. else
  3575. gain = cfg.gain;
  3576. break;
  3577. }
  3578. fll_change |= madera_write_fll(madera, fll->base,
  3579. &cfg, fll->ref_src,
  3580. false, gain);
  3581. /*
  3582. * Increase the bandwidth if we're not using a low frequency
  3583. * sync source.
  3584. */
  3585. if (have_sync && fll->sync_freq > 100000)
  3586. regmap_update_bits(madera->regmap,
  3587. sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
  3588. MADERA_FLL1_SYNC_DFSAT_MASK, 0);
  3589. else
  3590. regmap_update_bits(madera->regmap,
  3591. sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
  3592. MADERA_FLL1_SYNC_DFSAT_MASK,
  3593. MADERA_FLL1_SYNC_DFSAT);
  3594. if (!already_enabled)
  3595. pm_runtime_get_sync(madera->dev);
  3596. if (have_sync) {
  3597. madera_set_fll_clks(fll, sync_base, true);
  3598. regmap_update_bits(madera->regmap,
  3599. sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
  3600. MADERA_FLL1_SYNC_ENA,
  3601. MADERA_FLL1_SYNC_ENA);
  3602. }
  3603. madera_set_fll_clks(fll, fll->base, true);
  3604. regmap_update_bits(madera->regmap,
  3605. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3606. MADERA_FLL1_ENA, MADERA_FLL1_ENA);
  3607. if (already_enabled)
  3608. regmap_update_bits(madera->regmap,
  3609. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3610. MADERA_FLL1_FREERUN, 0);
  3611. if (fll_change || !already_enabled)
  3612. madera_wait_for_fll(fll, true);
  3613. return 0;
  3614. err:
  3615. /* In case of error don't leave the FLL running with an old config */
  3616. madera_disable_fll(fll);
  3617. return ret;
  3618. }
  3619. static int madera_apply_fll(struct madera_fll *fll)
  3620. {
  3621. if (fll->fout) {
  3622. return madera_enable_fll(fll);
  3623. } else {
  3624. madera_disable_fll(fll);
  3625. return 0;
  3626. }
  3627. }
  3628. int madera_set_fll_syncclk(struct madera_fll *fll, int source,
  3629. unsigned int fref, unsigned int fout)
  3630. {
  3631. /*
  3632. * fout is ignored, since the synchronizer is an optional extra
  3633. * constraint on the Fout generated from REFCLK, so the Fout is
  3634. * set when configuring REFCLK
  3635. */
  3636. if (fll->sync_src == source && fll->sync_freq == fref)
  3637. return 0;
  3638. fll->sync_src = source;
  3639. fll->sync_freq = fref;
  3640. return madera_apply_fll(fll);
  3641. }
  3642. EXPORT_SYMBOL_GPL(madera_set_fll_syncclk);
  3643. int madera_set_fll_refclk(struct madera_fll *fll, int source,
  3644. unsigned int fref, unsigned int fout)
  3645. {
  3646. int ret;
  3647. if (fll->ref_src == source &&
  3648. fll->ref_freq == fref && fll->fout == fout)
  3649. return 0;
  3650. /*
  3651. * Changes of fout on an enabled FLL aren't allowed except when
  3652. * setting fout==0 to disable the FLL
  3653. */
  3654. if (fout && fout != fll->fout) {
  3655. ret = madera_is_enabled_fll(fll, fll->base);
  3656. if (ret < 0)
  3657. return ret;
  3658. if (ret) {
  3659. madera_fll_err(fll, "Can't change Fout on active FLL\n");
  3660. return -EBUSY;
  3661. }
  3662. }
  3663. fll->ref_src = source;
  3664. fll->ref_freq = fref;
  3665. fll->fout = fout;
  3666. return madera_apply_fll(fll);
  3667. }
  3668. EXPORT_SYMBOL_GPL(madera_set_fll_refclk);
  3669. int madera_init_fll(struct madera *madera, int id, int base,
  3670. struct madera_fll *fll)
  3671. {
  3672. fll->id = id;
  3673. fll->base = base;
  3674. fll->madera = madera;
  3675. fll->ref_src = MADERA_FLL_SRC_NONE;
  3676. fll->sync_src = MADERA_FLL_SRC_NONE;
  3677. regmap_update_bits(madera->regmap,
  3678. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3679. MADERA_FLL1_FREERUN, 0);
  3680. return 0;
  3681. }
  3682. EXPORT_SYMBOL_GPL(madera_init_fll);
  3683. static const struct reg_sequence madera_fll_ao_32K_49M_patch[] = {
  3684. { MADERA_FLLAO_CONTROL_2, 0x02EE },
  3685. { MADERA_FLLAO_CONTROL_3, 0x0000 },
  3686. { MADERA_FLLAO_CONTROL_4, 0x0001 },
  3687. { MADERA_FLLAO_CONTROL_5, 0x0002 },
  3688. { MADERA_FLLAO_CONTROL_6, 0x8001 },
  3689. { MADERA_FLLAO_CONTROL_7, 0x0004 },
  3690. { MADERA_FLLAO_CONTROL_8, 0x0077 },
  3691. { MADERA_FLLAO_CONTROL_10, 0x06D8 },
  3692. { MADERA_FLLAO_CONTROL_11, 0x0085 },
  3693. { MADERA_FLLAO_CONTROL_2, 0x82EE },
  3694. };
  3695. static const struct reg_sequence madera_fll_ao_32K_45M_patch[] = {
  3696. { MADERA_FLLAO_CONTROL_2, 0x02B1 },
  3697. { MADERA_FLLAO_CONTROL_3, 0x0001 },
  3698. { MADERA_FLLAO_CONTROL_4, 0x0010 },
  3699. { MADERA_FLLAO_CONTROL_5, 0x0002 },
  3700. { MADERA_FLLAO_CONTROL_6, 0x8001 },
  3701. { MADERA_FLLAO_CONTROL_7, 0x0004 },
  3702. { MADERA_FLLAO_CONTROL_8, 0x0077 },
  3703. { MADERA_FLLAO_CONTROL_10, 0x06D8 },
  3704. { MADERA_FLLAO_CONTROL_11, 0x0005 },
  3705. { MADERA_FLLAO_CONTROL_2, 0x82B1 },
  3706. };
  3707. struct madera_fllao_patch {
  3708. unsigned int fin;
  3709. unsigned int fout;
  3710. const struct reg_sequence *patch;
  3711. unsigned int patch_size;
  3712. };
  3713. static const struct madera_fllao_patch madera_fllao_settings[] = {
  3714. {
  3715. .fin = 32768,
  3716. .fout = 49152000,
  3717. .patch = madera_fll_ao_32K_49M_patch,
  3718. .patch_size = ARRAY_SIZE(madera_fll_ao_32K_49M_patch),
  3719. },
  3720. {
  3721. .fin = 32768,
  3722. .fout = 45158400,
  3723. .patch = madera_fll_ao_32K_45M_patch,
  3724. .patch_size = ARRAY_SIZE(madera_fll_ao_32K_45M_patch),
  3725. },
  3726. };
  3727. static int madera_enable_fll_ao(struct madera_fll *fll,
  3728. const struct reg_sequence *patch,
  3729. unsigned int patch_size)
  3730. {
  3731. struct madera *madera = fll->madera;
  3732. int already_enabled = madera_is_enabled_fll(fll, fll->base);
  3733. unsigned int val;
  3734. int i;
  3735. if (already_enabled < 0)
  3736. return already_enabled;
  3737. if (!already_enabled)
  3738. pm_runtime_get_sync(madera->dev);
  3739. madera_fll_dbg(fll, "Enabling FLL_AO, initially %s\n",
  3740. already_enabled ? "enabled" : "disabled");
  3741. /* FLL_AO_HOLD must be set before configuring any registers */
  3742. regmap_update_bits(fll->madera->regmap,
  3743. fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
  3744. MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
  3745. if (already_enabled)
  3746. madera_set_fllao_clks(fll, fll->base, false);
  3747. for (i = 0; i < patch_size; i++) {
  3748. val = patch[i].def;
  3749. /* modify the patch to apply fll->ref_src as input clock */
  3750. if (patch[i].reg == MADERA_FLLAO_CONTROL_6) {
  3751. val &= ~MADERA_FLL_AO_REFCLK_SRC_MASK;
  3752. val |= (fll->ref_src << MADERA_FLL_AO_REFCLK_SRC_SHIFT)
  3753. & MADERA_FLL_AO_REFCLK_SRC_MASK;
  3754. }
  3755. regmap_write(madera->regmap, patch[i].reg, val);
  3756. }
  3757. madera_set_fllao_clks(fll, fll->base, true);
  3758. regmap_update_bits(madera->regmap,
  3759. fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
  3760. MADERA_FLL_AO_ENA, MADERA_FLL_AO_ENA);
  3761. /* Release the hold so that fll_ao locks to external frequency */
  3762. regmap_update_bits(madera->regmap,
  3763. fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
  3764. MADERA_FLL_AO_HOLD, 0);
  3765. if (!already_enabled)
  3766. madera_wait_for_fll(fll, true);
  3767. return 0;
  3768. }
  3769. static int madera_disable_fll_ao(struct madera_fll *fll)
  3770. {
  3771. struct madera *madera = fll->madera;
  3772. bool change;
  3773. madera_fll_dbg(fll, "Disabling FLL_AO\n");
  3774. regmap_update_bits(madera->regmap,
  3775. fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
  3776. MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
  3777. regmap_update_bits_check(madera->regmap,
  3778. fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
  3779. MADERA_FLL_AO_ENA, 0, &change);
  3780. madera_wait_for_fll(fll, false);
  3781. /*
  3782. * ctrl_up gates the writes to all fll_ao register, setting it to 0
  3783. * here ensures that after a runtime suspend/resume cycle when one
  3784. * enables the fllao then ctrl_up is the last bit that is configured
  3785. * by the fllao enable code rather than the cache sync operation which
  3786. * would have updated it much earlier before writing out all fllao
  3787. * registers
  3788. */
  3789. regmap_update_bits(madera->regmap,
  3790. fll->base + MADERA_FLLAO_CONTROL_2_OFFS,
  3791. MADERA_FLL_AO_CTRL_UPD_MASK, 0);
  3792. if (change) {
  3793. madera_set_fllao_clks(fll, fll->base, false);
  3794. pm_runtime_put_autosuspend(madera->dev);
  3795. }
  3796. return 0;
  3797. }
  3798. int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
  3799. unsigned int fin, unsigned int fout)
  3800. {
  3801. int ret = 0;
  3802. const struct reg_sequence *patch = NULL;
  3803. int patch_size = 0;
  3804. unsigned int i;
  3805. if (fll->ref_src == source &&
  3806. fll->ref_freq == fin && fll->fout == fout)
  3807. return 0;
  3808. madera_fll_dbg(fll, "Change FLL_AO refclk to fin=%u fout=%u source=%d\n",
  3809. fin, fout, source);
  3810. if (fout && (fll->ref_freq != fin || fll->fout != fout)) {
  3811. for (i = 0; i < ARRAY_SIZE(madera_fllao_settings); i++) {
  3812. if (madera_fllao_settings[i].fin == fin &&
  3813. madera_fllao_settings[i].fout == fout)
  3814. break;
  3815. }
  3816. if (i == ARRAY_SIZE(madera_fllao_settings)) {
  3817. madera_fll_err(fll,
  3818. "No matching configuration for FLL_AO\n");
  3819. return -EINVAL;
  3820. }
  3821. patch = madera_fllao_settings[i].patch;
  3822. patch_size = madera_fllao_settings[i].patch_size;
  3823. }
  3824. fll->ref_src = source;
  3825. fll->ref_freq = fin;
  3826. fll->fout = fout;
  3827. if (fout)
  3828. ret = madera_enable_fll_ao(fll, patch, patch_size);
  3829. else
  3830. madera_disable_fll_ao(fll);
  3831. return ret;
  3832. }
  3833. EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
  3834. static int madera_fllhj_disable(struct madera_fll *fll)
  3835. {
  3836. struct madera *madera = fll->madera;
  3837. bool change;
  3838. madera_fll_dbg(fll, "Disabling FLL\n");
  3839. /* Disable lockdet, but don't set ctrl_upd update but. This allows the
  3840. * lock status bit to clear as normal, but should the FLL be enabled
  3841. * again due to a control clock being required, the lock won't re-assert
  3842. * as the FLL config registers are automatically applied when the FLL
  3843. * enables.
  3844. */
  3845. regmap_update_bits(madera->regmap,
  3846. fll->base + MADERA_FLL_CONTROL_11_OFFS,
  3847. MADERA_FLL1_LOCKDET_MASK, 0);
  3848. regmap_update_bits(madera->regmap,
  3849. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3850. MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK);
  3851. regmap_update_bits_check(madera->regmap,
  3852. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  3853. MADERA_FLL1_ENA_MASK, 0, &change);
  3854. madera_wait_for_fll(fll, false);
  3855. /* ctrl_up gates the writes to all the fll's registers, setting it to 0
  3856. * here ensures that after a runtime suspend/resume cycle when one
  3857. * enables the fll then ctrl_up is the last bit that is configured
  3858. * by the fll enable code rather than the cache sync operation which
  3859. * would have updated it much earlier before writing out all fll
  3860. * registers
  3861. */
  3862. regmap_update_bits(madera->regmap,
  3863. fll->base + MADERA_FLL_CONTROL_2_OFFS,
  3864. MADERA_FLL1_CTRL_UPD_MASK, 0);
  3865. if (change) {
  3866. madera_set_fllhj_clks(fll, fll->base, false);
  3867. pm_runtime_put_autosuspend(madera->dev);
  3868. }
  3869. return 0;
  3870. }
  3871. static int madera_fllhj_apply(struct madera_fll *fll, int fin)
  3872. {
  3873. struct madera *madera = fll->madera;
  3874. int refdiv, fref, fout, lockdet_thr, fbdiv, hp, fast_clk, fllgcd;
  3875. bool frac = false;
  3876. unsigned int fll_n, min_n, max_n, ratio, theta, lambda;
  3877. unsigned int gains, val, num;
  3878. madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
  3879. for (refdiv = 0; refdiv < 4; refdiv++)
  3880. if ((fin / (1 << refdiv)) <= MADERA_FLLHJ_MAX_THRESH)
  3881. break;
  3882. fref = fin / (1 << refdiv);
  3883. /* Use simple heuristic approach to find a configuration that
  3884. * should work for most input clocks.
  3885. */
  3886. fast_clk = 0;
  3887. fout = fll->fout;
  3888. frac = fout % fref;
  3889. if (fref < MADERA_FLLHJ_LOW_THRESH) {
  3890. lockdet_thr = 2;
  3891. gains = MADERA_FLLHJ_LOW_GAINS;
  3892. if (frac)
  3893. fbdiv = 256;
  3894. else
  3895. fbdiv = 4;
  3896. } else if (fref < MADERA_FLLHJ_MID_THRESH) {
  3897. lockdet_thr = 8;
  3898. gains = MADERA_FLLHJ_MID_GAINS;
  3899. fbdiv = 1;
  3900. } else {
  3901. lockdet_thr = 8;
  3902. gains = MADERA_FLLHJ_HIGH_GAINS;
  3903. fbdiv = 1;
  3904. /* For high speed input clocks, enable 300MHz fast oscillator
  3905. * when we're in fractional divider mode.
  3906. */
  3907. if (frac) {
  3908. fast_clk = 0x3;
  3909. fout = fll->fout * 6;
  3910. }
  3911. }
  3912. /* Use high performance mode for fractional configurations. */
  3913. if (frac) {
  3914. hp = 0x3;
  3915. min_n = MADERA_FLLHJ_FRAC_MIN_N;
  3916. max_n = MADERA_FLLHJ_FRAC_MAX_N;
  3917. } else {
  3918. hp = 0x0;
  3919. min_n = MADERA_FLLHJ_INT_MIN_N;
  3920. max_n = MADERA_FLLHJ_INT_MAX_N;
  3921. }
  3922. ratio = fout / fref;
  3923. madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n",
  3924. refdiv, fref, frac);
  3925. while (ratio / fbdiv < min_n) {
  3926. fbdiv /= 2;
  3927. if (fbdiv < 1) {
  3928. madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv);
  3929. return -EINVAL;
  3930. }
  3931. }
  3932. while (frac && (ratio / fbdiv > max_n)) {
  3933. fbdiv *= 2;
  3934. if (fbdiv >= 1024) {
  3935. madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
  3936. return -EINVAL;
  3937. }
  3938. }
  3939. madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n",
  3940. lockdet_thr, hp, fbdiv);
  3941. /* Calculate N.K values */
  3942. fllgcd = gcd(fout, fbdiv * fref);
  3943. num = fout / fllgcd;
  3944. lambda = (fref * fbdiv) / fllgcd;
  3945. fll_n = num / lambda;
  3946. theta = num % lambda;
  3947. madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
  3948. fll_n, fllgcd, theta, lambda);
  3949. /* Some sanity checks before any registers are written. */
  3950. if (fll_n < min_n || fll_n > max_n) {
  3951. madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
  3952. frac ? "fractional" : "integer", min_n, max_n,
  3953. fll_n);
  3954. return -EINVAL;
  3955. }
  3956. if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
  3957. madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
  3958. frac ? "fractional" : "integer", fbdiv);
  3959. return -EINVAL;
  3960. }
  3961. /* clear the ctrl_upd bit to guarantee we write to it later. */
  3962. regmap_write(madera->regmap,
  3963. fll->base + MADERA_FLL_CONTROL_2_OFFS,
  3964. fll_n << MADERA_FLL1_N_SHIFT);
  3965. regmap_update_bits(madera->regmap,
  3966. fll->base + MADERA_FLL_CONTROL_3_OFFS,
  3967. MADERA_FLL1_THETA_MASK,
  3968. theta << MADERA_FLL1_THETA_SHIFT);
  3969. regmap_update_bits(madera->regmap,
  3970. fll->base + MADERA_FLL_CONTROL_4_OFFS,
  3971. MADERA_FLL1_LAMBDA_MASK,
  3972. lambda << MADERA_FLL1_LAMBDA_SHIFT);
  3973. regmap_update_bits(madera->regmap,
  3974. fll->base + MADERA_FLL_CONTROL_5_OFFS,
  3975. MADERA_FLL1_FB_DIV_MASK,
  3976. fbdiv << MADERA_FLL1_FB_DIV_SHIFT);
  3977. regmap_update_bits(madera->regmap,
  3978. fll->base + MADERA_FLL_CONTROL_6_OFFS,
  3979. MADERA_FLL1_REFCLK_DIV_MASK,
  3980. refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT);
  3981. regmap_update_bits(madera->regmap,
  3982. fll->base + MADERA_FLL_GAIN_OFFS,
  3983. 0xffff,
  3984. gains);
  3985. val = hp << MADERA_FLL1_HP_SHIFT;
  3986. val |= 1 << MADERA_FLL1_PHASEDET_ENA_SHIFT;
  3987. regmap_update_bits(madera->regmap,
  3988. fll->base + MADERA_FLL_CONTROL_10_OFFS,
  3989. MADERA_FLL1_HP_MASK | MADERA_FLL1_PHASEDET_ENA_MASK,
  3990. val);
  3991. regmap_update_bits(madera->regmap,
  3992. fll->base + MADERA_FLL_CONTROL_11_OFFS,
  3993. MADERA_FLL1_LOCKDET_THR_MASK,
  3994. lockdet_thr << MADERA_FLL1_LOCKDET_THR_SHIFT);
  3995. regmap_update_bits(madera->regmap,
  3996. fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS,
  3997. MADERA_FLL1_SYNC_EFS_ENA_MASK |
  3998. MADERA_FLL1_CLK_VCO_FAST_SRC_MASK,
  3999. fast_clk);
  4000. return 0;
  4001. }
  4002. static int madera_fllhj_enable(struct madera_fll *fll)
  4003. {
  4004. struct madera *madera = fll->madera;
  4005. int already_enabled = madera_is_enabled_fll(fll, fll->base);
  4006. int ret;
  4007. if (already_enabled < 0)
  4008. return already_enabled;
  4009. if (!already_enabled)
  4010. pm_runtime_get_sync(madera->dev);
  4011. madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
  4012. already_enabled ? "enabled" : "disabled");
  4013. /* FLLn_HOLD must be set before configuring any registers */
  4014. regmap_update_bits(fll->madera->regmap,
  4015. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  4016. MADERA_FLL1_HOLD_MASK,
  4017. MADERA_FLL1_HOLD_MASK);
  4018. if (already_enabled)
  4019. madera_set_fllhj_clks(fll, fll->base, false);
  4020. /* Apply refclk */
  4021. ret = madera_fllhj_apply(fll, fll->ref_freq);
  4022. if (ret) {
  4023. madera_fll_err(fll, "Failed to set FLL: %d\n", ret);
  4024. goto out;
  4025. }
  4026. regmap_update_bits(madera->regmap,
  4027. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  4028. CS47L92_FLL1_REFCLK_SRC_MASK,
  4029. fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT);
  4030. madera_set_fllhj_clks(fll, fll->base, true);
  4031. regmap_update_bits(madera->regmap,
  4032. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  4033. MADERA_FLL1_ENA_MASK,
  4034. MADERA_FLL1_ENA_MASK);
  4035. out:
  4036. regmap_update_bits(madera->regmap,
  4037. fll->base + MADERA_FLL_CONTROL_11_OFFS,
  4038. MADERA_FLL1_LOCKDET_MASK,
  4039. MADERA_FLL1_LOCKDET_MASK);
  4040. regmap_update_bits(madera->regmap,
  4041. fll->base + MADERA_FLL_CONTROL_2_OFFS,
  4042. MADERA_FLL1_CTRL_UPD_MASK,
  4043. MADERA_FLL1_CTRL_UPD_MASK);
  4044. /* Release the hold so that flln locks to external frequency */
  4045. regmap_update_bits(madera->regmap,
  4046. fll->base + MADERA_FLL_CONTROL_1_OFFS,
  4047. MADERA_FLL1_HOLD_MASK,
  4048. 0);
  4049. if (!already_enabled)
  4050. madera_wait_for_fll(fll, true);
  4051. return 0;
  4052. }
  4053. static int madera_fllhj_validate(struct madera_fll *fll,
  4054. unsigned int ref_in,
  4055. unsigned int fout)
  4056. {
  4057. if (fout && !ref_in) {
  4058. madera_fll_err(fll, "fllout set without valid input clk\n");
  4059. return -EINVAL;
  4060. }
  4061. if (fll->fout && fout != fll->fout) {
  4062. madera_fll_err(fll, "Can't change output on active FLL\n");
  4063. return -EINVAL;
  4064. }
  4065. if (ref_in / MADERA_FLL_MAX_REFDIV > MADERA_FLLHJ_MAX_THRESH) {
  4066. madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
  4067. return -EINVAL;
  4068. }
  4069. return 0;
  4070. }
  4071. int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
  4072. unsigned int fin, unsigned int fout)
  4073. {
  4074. int ret = 0;
  4075. /* To remain consistent with previous FLLs, we expect fout to be
  4076. * provided in the form of the required sysclk rate, which is
  4077. * 2x the calculated fll out.
  4078. */
  4079. if (fout)
  4080. fout /= 2;
  4081. if (fll->ref_src == source && fll->ref_freq == fin &&
  4082. fll->fout == fout)
  4083. return 0;
  4084. if (fin && fout && madera_fllhj_validate(fll, fin, fout))
  4085. return -EINVAL;
  4086. fll->ref_src = source;
  4087. fll->ref_freq = fin;
  4088. fll->fout = fout;
  4089. if (fout)
  4090. ret = madera_fllhj_enable(fll);
  4091. else
  4092. madera_fllhj_disable(fll);
  4093. return ret;
  4094. }
  4095. EXPORT_SYMBOL_GPL(madera_fllhj_set_refclk);
  4096. /**
  4097. * madera_set_output_mode - Set the mode of the specified output
  4098. *
  4099. * @component: Device to configure
  4100. * @output: Output number
  4101. * @differential: True to set the output to differential mode
  4102. *
  4103. * Some systems use external analogue switches to connect more
  4104. * analogue devices to the CODEC than are supported by the device. In
  4105. * some systems this requires changing the switched output from single
  4106. * ended to differential mode dynamically at runtime, an operation
  4107. * supported using this function.
  4108. *
  4109. * Most systems have a single static configuration and should use
  4110. * platform data instead.
  4111. */
  4112. int madera_set_output_mode(struct snd_soc_component *component, int output,
  4113. bool differential)
  4114. {
  4115. unsigned int reg, val;
  4116. int ret;
  4117. if (output < 1 || output > MADERA_MAX_OUTPUT)
  4118. return -EINVAL;
  4119. reg = MADERA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
  4120. if (differential)
  4121. val = MADERA_OUT1_MONO;
  4122. else
  4123. val = 0;
  4124. ret = snd_soc_component_update_bits(component, reg, MADERA_OUT1_MONO,
  4125. val);
  4126. if (ret < 0)
  4127. return ret;
  4128. else
  4129. return 0;
  4130. }
  4131. EXPORT_SYMBOL_GPL(madera_set_output_mode);
  4132. static bool madera_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
  4133. {
  4134. s16 a = be16_to_cpu(_a);
  4135. s16 b = be16_to_cpu(_b);
  4136. if (!mode) {
  4137. return abs(a) >= 4096;
  4138. } else {
  4139. if (abs(b) >= 4096)
  4140. return true;
  4141. return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
  4142. }
  4143. }
  4144. int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
  4145. struct snd_ctl_elem_value *ucontrol)
  4146. {
  4147. struct snd_soc_component *component =
  4148. snd_soc_kcontrol_component(kcontrol);
  4149. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  4150. struct madera *madera = priv->madera;
  4151. struct soc_bytes *params = (void *)kcontrol->private_value;
  4152. unsigned int val;
  4153. __be16 *data;
  4154. int len;
  4155. int ret;
  4156. len = params->num_regs * regmap_get_val_bytes(madera->regmap);
  4157. data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
  4158. if (!data)
  4159. return -ENOMEM;
  4160. data[0] &= cpu_to_be16(MADERA_EQ1_B1_MODE);
  4161. if (madera_eq_filter_unstable(!!data[0], data[1], data[2]) ||
  4162. madera_eq_filter_unstable(true, data[4], data[5]) ||
  4163. madera_eq_filter_unstable(true, data[8], data[9]) ||
  4164. madera_eq_filter_unstable(true, data[12], data[13]) ||
  4165. madera_eq_filter_unstable(false, data[16], data[17])) {
  4166. dev_err(madera->dev, "Rejecting unstable EQ coefficients\n");
  4167. ret = -EINVAL;
  4168. goto out;
  4169. }
  4170. ret = regmap_read(madera->regmap, params->base, &val);
  4171. if (ret != 0)
  4172. goto out;
  4173. val &= ~MADERA_EQ1_B1_MODE;
  4174. data[0] |= cpu_to_be16(val);
  4175. ret = regmap_raw_write(madera->regmap, params->base, data, len);
  4176. out:
  4177. kfree(data);
  4178. return ret;
  4179. }
  4180. EXPORT_SYMBOL_GPL(madera_eq_coeff_put);
  4181. int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
  4182. struct snd_ctl_elem_value *ucontrol)
  4183. {
  4184. struct snd_soc_component *component =
  4185. snd_soc_kcontrol_component(kcontrol);
  4186. struct madera_priv *priv = snd_soc_component_get_drvdata(component);
  4187. struct madera *madera = priv->madera;
  4188. __be16 *data = (__be16 *)ucontrol->value.bytes.data;
  4189. s16 val = be16_to_cpu(*data);
  4190. if (abs(val) >= 4096) {
  4191. dev_err(madera->dev, "Rejecting unstable LHPF coefficients\n");
  4192. return -EINVAL;
  4193. }
  4194. return snd_soc_bytes_put(kcontrol, ucontrol);
  4195. }
  4196. EXPORT_SYMBOL_GPL(madera_lhpf_coeff_put);
  4197. MODULE_SOFTDEP("pre: madera");
  4198. MODULE_DESCRIPTION("ASoC Cirrus Logic Madera codec support");
  4199. MODULE_AUTHOR("Charles Keepax <[email protected]>");
  4200. MODULE_AUTHOR("Richard Fitzgerald <[email protected]>");
  4201. MODULE_LICENSE("GPL v2");