wcd9xxx-mbhc.c 155 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196
  1. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/firmware.h>
  15. #include <linux/slab.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/device.h>
  18. #include <linux/printk.h>
  19. #include <linux/ratelimit.h>
  20. #include <linux/debugfs.h>
  21. #include <linux/list.h>
  22. #include <linux/mfd/wcd9xxx/core.h>
  23. #include <linux/mfd/wcd9xxx/core-resource.h>
  24. #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
  25. #include <linux/mfd/wcd9xxx/wcd9320_registers.h>
  26. #include <linux/mfd/wcd9xxx/pdata.h>
  27. #include <sound/pcm.h>
  28. #include <sound/pcm_params.h>
  29. #include <sound/soc.h>
  30. #include <sound/soc-dapm.h>
  31. #include <sound/tlv.h>
  32. #include <linux/wakelock.h>
  33. #include <linux/bitops.h>
  34. #include <linux/delay.h>
  35. #include <linux/pm_runtime.h>
  36. #include <linux/kernel.h>
  37. #include <linux/gpio.h>
  38. #include <linux/input.h>
  39. #include "wcdcal-hwdep.h"
  40. #include "wcd9320.h"
  41. #include "wcd9306.h"
  42. #include "wcd9xxx-mbhc.h"
  43. #include "wcd9xxx-resmgr.h"
  44. #include "wcd9xxx-common.h"
  45. #define WCD9XXX_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
  46. SND_JACK_OC_HPHR | SND_JACK_LINEOUT | \
  47. SND_JACK_UNSUPPORTED | SND_JACK_MICROPHONE2)
  48. #define WCD9XXX_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
  49. SND_JACK_BTN_2 | SND_JACK_BTN_3 | \
  50. SND_JACK_BTN_4 | SND_JACK_BTN_5 | \
  51. SND_JACK_BTN_6 | SND_JACK_BTN_7)
  52. #define NUM_DCE_PLUG_DETECT 3
  53. #define NUM_DCE_PLUG_INS_DETECT 5
  54. #define NUM_ATTEMPTS_INSERT_DETECT 25
  55. #define NUM_ATTEMPTS_TO_REPORT 5
  56. #define FAKE_INS_LOW 10
  57. #define FAKE_INS_HIGH 80
  58. #define FAKE_INS_HIGH_NO_SWCH 150
  59. #define FAKE_REMOVAL_MIN_PERIOD_MS 50
  60. #define FAKE_INS_DELTA_SCALED_MV 300
  61. #define BUTTON_MIN 0x8000
  62. #define STATUS_REL_DETECTION 0x0C
  63. #define HS_DETECT_PLUG_TIME_MS (5 * 1000)
  64. #define ANC_HPH_DETECT_PLUG_TIME_MS (5 * 1000)
  65. #define HS_DETECT_PLUG_INERVAL_MS 100
  66. #define SWCH_REL_DEBOUNCE_TIME_MS 50
  67. #define SWCH_IRQ_DEBOUNCE_TIME_US 5000
  68. #define BTN_RELEASE_DEBOUNCE_TIME_MS 25
  69. #define GND_MIC_SWAP_THRESHOLD 2
  70. #define OCP_ATTEMPT 1
  71. #define FW_READ_ATTEMPTS 15
  72. #define FW_READ_TIMEOUT 4000000
  73. #define BUTTON_POLLING_SUPPORTED true
  74. #define MCLK_RATE_12288KHZ 12288000
  75. #define MCLK_RATE_9600KHZ 9600000
  76. #define DEFAULT_DCE_STA_WAIT 55
  77. #define DEFAULT_DCE_WAIT 60000
  78. #define DEFAULT_STA_WAIT 5000
  79. #define VDDIO_MICBIAS_MV 1800
  80. #define WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US 5000
  81. #define WCD9XXX_HPHL_STATUS_READY_WAIT_US 1000
  82. #define WCD9XXX_MUX_SWITCH_READY_WAIT_MS 50
  83. #define WCD9XXX_MEAS_DELTA_MAX_MV 120
  84. #define WCD9XXX_MEAS_INVALD_RANGE_LOW_MV 20
  85. #define WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV 80
  86. /*
  87. * Invalid voltage range for the detection
  88. * of plug type with current source
  89. */
  90. #define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 160
  91. #define WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV 170
  92. /*
  93. * Threshold used to detect euro headset
  94. * with current source
  95. */
  96. #define WCD9XXX_CS_GM_SWAP_THRES_MIN_MV 10
  97. #define WCD9XXX_CS_GM_SWAP_THRES_MAX_MV 40
  98. #define WCD9XXX_MBHC_NSC_CS 9
  99. #define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
  100. #define WCD9XXX_GM_SWAP_THRES_MAX_MV 650
  101. #define WCD9XXX_THRESHOLD_MIC_THRESHOLD 200
  102. #define WCD9XXX_USLEEP_RANGE_MARGIN_US 100
  103. /* RX_HPH_CNP_WG_TIME increases by 0.24ms */
  104. #define WCD9XXX_WG_TIME_FACTOR_US 240
  105. #define WCD9XXX_V_CS_HS_MAX 650
  106. #define WCD9XXX_V_CS_NO_MIC 0
  107. #define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80
  108. #define WCD9XXX_CS_MEAS_DELTA_MAX_MV 12
  109. static int impedance_detect_en;
  110. module_param(impedance_detect_en, int,
  111. S_IRUGO | S_IWUSR | S_IWGRP);
  112. MODULE_PARM_DESC(impedance_detect_en, "enable/disable impedance detect");
  113. static bool detect_use_vddio_switch;
  114. struct wcd9xxx_mbhc_detect {
  115. u16 dce;
  116. u16 sta;
  117. u16 hphl_status;
  118. bool swap_gnd;
  119. bool vddio;
  120. bool hwvalue;
  121. bool mic_bias;
  122. /* internal purpose from here */
  123. bool _above_no_mic;
  124. bool _below_v_hs_max;
  125. s16 _vdces;
  126. enum wcd9xxx_mbhc_plug_type _type;
  127. };
  128. struct wake_lock det_wake_lock;
  129. enum meas_type {
  130. STA = 0,
  131. DCE,
  132. };
  133. enum {
  134. MBHC_USE_HPHL_TRIGGER = 1,
  135. MBHC_USE_MB_TRIGGER = 2
  136. };
  137. /*
  138. * Flags to track of PA and DAC state.
  139. * PA and DAC should be tracked separately as AUXPGA loopback requires
  140. * only PA to be turned on without DAC being on.
  141. */
  142. enum pa_dac_ack_flags {
  143. WCD9XXX_HPHL_PA_OFF_ACK = 0,
  144. WCD9XXX_HPHR_PA_OFF_ACK,
  145. WCD9XXX_HPHL_DAC_OFF_ACK,
  146. WCD9XXX_HPHR_DAC_OFF_ACK
  147. };
  148. enum wcd9xxx_current_v_idx {
  149. WCD9XXX_CURRENT_V_INS_H,
  150. WCD9XXX_CURRENT_V_INS_HU,
  151. WCD9XXX_CURRENT_V_B1_H,
  152. WCD9XXX_CURRENT_V_B1_HU,
  153. WCD9XXX_CURRENT_V_BR_H,
  154. };
  155. static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
  156. uint32_t *zr);
  157. static s16 wcd9xxx_get_current_v(struct wcd9xxx_mbhc *mbhc,
  158. const enum wcd9xxx_current_v_idx idx);
  159. static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z,
  160. struct mbhc_micbias_regs *micb_regs,
  161. bool norel);
  162. static void wcd9xxx_mbhc_calc_thres(struct wcd9xxx_mbhc *mbhc);
  163. static u16 wcd9xxx_codec_v_sta_dce(struct wcd9xxx_mbhc *mbhc,
  164. enum meas_type dce, s16 vin_mv,
  165. bool cs_enable);
  166. static bool wcd9xxx_mbhc_polling(struct wcd9xxx_mbhc *mbhc)
  167. {
  168. return (snd_soc_read(mbhc->codec, WCD9XXX_A_CDC_MBHC_EN_CTL) & 0x1);
  169. }
  170. static void wcd9xxx_turn_onoff_override(struct wcd9xxx_mbhc *mbhc, bool on)
  171. {
  172. struct snd_soc_codec *codec = mbhc->codec;
  173. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  174. 0x04, on ? 0x04 : 0x00);
  175. }
  176. /* called under codec_resource_lock acquisition */
  177. static void wcd9xxx_pause_hs_polling(struct wcd9xxx_mbhc *mbhc)
  178. {
  179. struct snd_soc_codec *codec = mbhc->codec;
  180. pr_debug("%s: enter\n", __func__);
  181. if (!mbhc->polling_active) {
  182. pr_debug("polling not active, nothing to pause\n");
  183. return;
  184. }
  185. /* Soft reset MBHC block */
  186. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
  187. pr_debug("%s: leave\n", __func__);
  188. }
  189. /* called under codec_resource_lock acquisition */
  190. static void wcd9xxx_start_hs_polling(struct wcd9xxx_mbhc *mbhc)
  191. {
  192. struct snd_soc_codec *codec = mbhc->codec;
  193. int mbhc_state = mbhc->mbhc_state;
  194. pr_debug("%s: enter\n", __func__);
  195. if (!mbhc->polling_active) {
  196. pr_debug("Polling is not active, do not start polling\n");
  197. return;
  198. }
  199. /*
  200. * setup internal micbias if codec uses internal micbias for
  201. * headset detection
  202. */
  203. if (mbhc->mbhc_cfg->use_int_rbias) {
  204. if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
  205. mbhc->mbhc_cb->setup_int_rbias(codec, true);
  206. else
  207. pr_err("%s: internal bias requested but codec did not provide callback\n",
  208. __func__);
  209. }
  210. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
  211. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  212. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  213. else
  214. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  215. 0x80, 0x80);
  216. if (!mbhc->no_mic_headset_override &&
  217. mbhc_state == MBHC_STATE_POTENTIAL) {
  218. pr_debug("%s recovering MBHC state machine\n", __func__);
  219. mbhc->mbhc_state = MBHC_STATE_POTENTIAL_RECOVERY;
  220. /* set to max button press threshold */
  221. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL, 0x7F);
  222. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL, 0xFF);
  223. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL, 0x7F);
  224. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, 0xFF);
  225. /* set to max */
  226. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL, 0x7F);
  227. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, 0xFF);
  228. }
  229. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x1);
  230. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x0);
  231. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x1);
  232. pr_debug("%s: leave\n", __func__);
  233. }
  234. static int __wcd9xxx_resmgr_get_k_val(struct wcd9xxx_mbhc *mbhc,
  235. unsigned int cfilt_mv)
  236. {
  237. return wcd9xxx_resmgr_get_k_val(mbhc->resmgr, cfilt_mv);
  238. }
  239. /*
  240. * called under codec_resource_lock acquisition
  241. * return old status
  242. */
  243. static bool __wcd9xxx_switch_micbias(struct wcd9xxx_mbhc *mbhc,
  244. int vddio_switch, bool restartpolling,
  245. bool checkpolling)
  246. {
  247. bool ret;
  248. int cfilt_k_val;
  249. bool override;
  250. struct snd_soc_codec *codec;
  251. struct mbhc_internal_cal_data *d = &mbhc->mbhc_data;
  252. codec = mbhc->codec;
  253. if (mbhc->micbias_enable) {
  254. pr_debug("%s: micbias is already on\n", __func__);
  255. ret = mbhc->mbhc_micbias_switched;
  256. return ret;
  257. }
  258. ret = mbhc->mbhc_micbias_switched;
  259. if (vddio_switch && !mbhc->mbhc_micbias_switched &&
  260. (!checkpolling || mbhc->polling_active)) {
  261. if (restartpolling)
  262. wcd9xxx_pause_hs_polling(mbhc);
  263. override = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) &
  264. 0x04;
  265. if (!override)
  266. wcd9xxx_turn_onoff_override(mbhc, true);
  267. /* Adjust threshold if Mic Bias voltage changes */
  268. if (d->micb_mv != VDDIO_MICBIAS_MV) {
  269. cfilt_k_val = __wcd9xxx_resmgr_get_k_val(mbhc,
  270. VDDIO_MICBIAS_MV);
  271. usleep_range(10000, 10000);
  272. snd_soc_update_bits(codec,
  273. mbhc->mbhc_bias_regs.cfilt_val,
  274. 0xFC, (cfilt_k_val << 2));
  275. usleep_range(10000, 10000);
  276. /* Threshods for insertion/removal */
  277. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL,
  278. d->v_ins_hu[MBHC_V_IDX_VDDIO] & 0xFF);
  279. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
  280. (d->v_ins_hu[MBHC_V_IDX_VDDIO] >> 8) &
  281. 0xFF);
  282. if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
  283. /* Threshods for button press */
  284. snd_soc_write(codec,
  285. WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
  286. d->v_b1_hu[MBHC_V_IDX_VDDIO] & 0xFF);
  287. snd_soc_write(codec,
  288. WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
  289. (d->v_b1_hu[MBHC_V_IDX_VDDIO] >> 8) &
  290. 0xFF);
  291. snd_soc_write(codec,
  292. WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
  293. d->v_b1_h[MBHC_V_IDX_VDDIO] & 0xFF);
  294. snd_soc_write(codec,
  295. WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
  296. (d->v_b1_h[MBHC_V_IDX_VDDIO] >> 8) &
  297. 0xFF);
  298. /* Threshods for button release */
  299. snd_soc_write(codec,
  300. WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
  301. d->v_brh[MBHC_V_IDX_VDDIO] & 0xFF);
  302. snd_soc_write(codec,
  303. WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
  304. (d->v_brh[MBHC_V_IDX_VDDIO] >> 8) &
  305. 0xFF);
  306. }
  307. pr_debug("%s: Programmed MBHC thresholds to VDDIO\n",
  308. __func__);
  309. }
  310. /* Enable MIC BIAS Switch to VDDIO */
  311. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
  312. 0x80, 0x80);
  313. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
  314. 0x10, 0x00);
  315. if (!override)
  316. wcd9xxx_turn_onoff_override(mbhc, false);
  317. if (restartpolling)
  318. wcd9xxx_start_hs_polling(mbhc);
  319. mbhc->mbhc_micbias_switched = true;
  320. pr_debug("%s: VDDIO switch enabled\n", __func__);
  321. } else if (!vddio_switch && mbhc->mbhc_micbias_switched) {
  322. if ((!checkpolling || mbhc->polling_active) &&
  323. restartpolling)
  324. wcd9xxx_pause_hs_polling(mbhc);
  325. /* Reprogram thresholds */
  326. if (d->micb_mv != VDDIO_MICBIAS_MV) {
  327. cfilt_k_val =
  328. __wcd9xxx_resmgr_get_k_val(mbhc,
  329. d->micb_mv);
  330. snd_soc_update_bits(codec,
  331. mbhc->mbhc_bias_regs.cfilt_val,
  332. 0xFC, (cfilt_k_val << 2));
  333. usleep_range(10000, 10000);
  334. /* Revert threshods for insertion/removal */
  335. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL,
  336. d->v_ins_hu[MBHC_V_IDX_CFILT] & 0xFF);
  337. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
  338. (d->v_ins_hu[MBHC_V_IDX_CFILT] >> 8) &
  339. 0xFF);
  340. if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
  341. /* Revert threshods for button press */
  342. snd_soc_write(codec,
  343. WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL,
  344. d->v_b1_hu[MBHC_V_IDX_CFILT] & 0xFF);
  345. snd_soc_write(codec,
  346. WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
  347. (d->v_b1_hu[MBHC_V_IDX_CFILT] >> 8) &
  348. 0xFF);
  349. snd_soc_write(codec,
  350. WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL,
  351. d->v_b1_h[MBHC_V_IDX_CFILT] & 0xFF);
  352. snd_soc_write(codec,
  353. WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
  354. (d->v_b1_h[MBHC_V_IDX_CFILT] >> 8) &
  355. 0xFF);
  356. /* Revert threshods for button release */
  357. snd_soc_write(codec,
  358. WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL,
  359. d->v_brh[MBHC_V_IDX_CFILT] & 0xFF);
  360. snd_soc_write(codec,
  361. WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
  362. (d->v_brh[MBHC_V_IDX_CFILT] >> 8) &
  363. 0xFF);
  364. }
  365. pr_debug("%s: Programmed MBHC thresholds to MICBIAS\n",
  366. __func__);
  367. }
  368. /* Disable MIC BIAS Switch to VDDIO */
  369. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x80,
  370. 0x00);
  371. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x10,
  372. 0x00);
  373. if ((!checkpolling || mbhc->polling_active) && restartpolling)
  374. wcd9xxx_start_hs_polling(mbhc);
  375. mbhc->mbhc_micbias_switched = false;
  376. pr_debug("%s: VDDIO switch disabled\n", __func__);
  377. }
  378. return ret;
  379. }
  380. static void wcd9xxx_switch_micbias(struct wcd9xxx_mbhc *mbhc, int vddio_switch)
  381. {
  382. __wcd9xxx_switch_micbias(mbhc, vddio_switch, true, true);
  383. }
  384. static s16 wcd9xxx_get_current_v(struct wcd9xxx_mbhc *mbhc,
  385. const enum wcd9xxx_current_v_idx idx)
  386. {
  387. enum mbhc_v_index vidx;
  388. s16 ret = -EINVAL;
  389. if ((mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV) &&
  390. mbhc->mbhc_micbias_switched)
  391. vidx = MBHC_V_IDX_VDDIO;
  392. else
  393. vidx = MBHC_V_IDX_CFILT;
  394. switch (idx) {
  395. case WCD9XXX_CURRENT_V_INS_H:
  396. ret = (s16)mbhc->mbhc_data.v_ins_h[vidx];
  397. break;
  398. case WCD9XXX_CURRENT_V_INS_HU:
  399. ret = (s16)mbhc->mbhc_data.v_ins_hu[vidx];
  400. break;
  401. case WCD9XXX_CURRENT_V_B1_H:
  402. ret = (s16)mbhc->mbhc_data.v_b1_h[vidx];
  403. break;
  404. case WCD9XXX_CURRENT_V_B1_HU:
  405. ret = (s16)mbhc->mbhc_data.v_b1_hu[vidx];
  406. break;
  407. case WCD9XXX_CURRENT_V_BR_H:
  408. ret = (s16)mbhc->mbhc_data.v_brh[vidx];
  409. break;
  410. }
  411. return ret;
  412. }
  413. void *wcd9xxx_mbhc_cal_btn_det_mp(
  414. const struct wcd9xxx_mbhc_btn_detect_cfg *btn_det,
  415. const enum wcd9xxx_mbhc_btn_det_mem mem)
  416. {
  417. void *ret = (void *)&btn_det->_v_btn_low;
  418. switch (mem) {
  419. case MBHC_BTN_DET_GAIN:
  420. ret += sizeof(btn_det->_n_cic);
  421. case MBHC_BTN_DET_N_CIC:
  422. ret += sizeof(btn_det->_n_ready);
  423. case MBHC_BTN_DET_N_READY:
  424. ret += sizeof(btn_det->_v_btn_high[0]) * btn_det->num_btn;
  425. case MBHC_BTN_DET_V_BTN_HIGH:
  426. ret += sizeof(btn_det->_v_btn_low[0]) * btn_det->num_btn;
  427. case MBHC_BTN_DET_V_BTN_LOW:
  428. /* do nothing */
  429. break;
  430. default:
  431. ret = NULL;
  432. }
  433. return ret;
  434. }
  435. EXPORT_SYMBOL(wcd9xxx_mbhc_cal_btn_det_mp);
  436. static void wcd9xxx_calibrate_hs_polling(struct wcd9xxx_mbhc *mbhc)
  437. {
  438. struct snd_soc_codec *codec = mbhc->codec;
  439. const s16 v_ins_hu = wcd9xxx_get_current_v(mbhc,
  440. WCD9XXX_CURRENT_V_INS_HU);
  441. const s16 v_b1_hu = wcd9xxx_get_current_v(mbhc,
  442. WCD9XXX_CURRENT_V_B1_HU);
  443. const s16 v_b1_h = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_H);
  444. const s16 v_brh = wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_BR_H);
  445. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL, v_ins_hu & 0xFF);
  446. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL,
  447. (v_ins_hu >> 8) & 0xFF);
  448. if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
  449. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
  450. 0xFF);
  451. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
  452. (v_b1_hu >> 8) & 0xFF);
  453. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL, v_b1_h &
  454. 0xFF);
  455. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL,
  456. (v_b1_h >> 8) & 0xFF);
  457. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
  458. 0xFF);
  459. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
  460. (v_brh >> 8) & 0xFF);
  461. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL,
  462. mbhc->mbhc_data.v_brl & 0xFF);
  463. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL,
  464. (mbhc->mbhc_data.v_brl >> 8) & 0xFF);
  465. }
  466. }
  467. static void wcd9xxx_codec_switch_cfilt_mode(struct wcd9xxx_mbhc *mbhc,
  468. bool fast)
  469. {
  470. struct snd_soc_codec *codec = mbhc->codec;
  471. struct wcd9xxx_cfilt_mode cfilt_mode;
  472. if (mbhc->mbhc_cb && mbhc->mbhc_cb->switch_cfilt_mode) {
  473. cfilt_mode = mbhc->mbhc_cb->switch_cfilt_mode(mbhc, fast);
  474. } else {
  475. if (fast)
  476. cfilt_mode.reg_mode_val = WCD9XXX_CFILT_FAST_MODE;
  477. else
  478. cfilt_mode.reg_mode_val = WCD9XXX_CFILT_SLOW_MODE;
  479. cfilt_mode.reg_mask = 0x40;
  480. cfilt_mode.cur_mode_val =
  481. snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl) & 0x40;
  482. }
  483. if (cfilt_mode.cur_mode_val
  484. != cfilt_mode.reg_mode_val) {
  485. if (mbhc->polling_active && wcd9xxx_mbhc_polling(mbhc))
  486. wcd9xxx_pause_hs_polling(mbhc);
  487. snd_soc_update_bits(codec,
  488. mbhc->mbhc_bias_regs.cfilt_ctl,
  489. cfilt_mode.reg_mask,
  490. cfilt_mode.reg_mode_val);
  491. if (mbhc->polling_active && wcd9xxx_mbhc_polling(mbhc))
  492. wcd9xxx_start_hs_polling(mbhc);
  493. pr_debug("%s: CFILT mode change (%x to %x)\n", __func__,
  494. cfilt_mode.cur_mode_val,
  495. cfilt_mode.reg_mode_val);
  496. } else {
  497. pr_debug("%s: CFILT Value is already %x\n",
  498. __func__, cfilt_mode.cur_mode_val);
  499. }
  500. }
  501. static void wcd9xxx_jack_report(struct wcd9xxx_mbhc *mbhc,
  502. struct snd_soc_jack *jack, int status, int mask)
  503. {
  504. if (jack == &mbhc->headset_jack) {
  505. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  506. WCD9XXX_COND_HPH_MIC,
  507. status & SND_JACK_MICROPHONE);
  508. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  509. WCD9XXX_COND_HPH,
  510. status & SND_JACK_HEADPHONE);
  511. }
  512. snd_soc_jack_report_no_dapm(jack, status, mask);
  513. }
  514. static void __hphocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status,
  515. int irq)
  516. {
  517. struct snd_soc_codec *codec;
  518. pr_debug("%s: clear ocp status %x\n", __func__, jack_status);
  519. codec = mbhc->codec;
  520. if (mbhc->hph_status & jack_status) {
  521. mbhc->hph_status &= ~jack_status;
  522. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
  523. mbhc->hph_status, WCD9XXX_JACK_MASK);
  524. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
  525. 0x00);
  526. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
  527. 0x10);
  528. /*
  529. * reset retry counter as PA is turned off signifying
  530. * start of new OCP detection session
  531. */
  532. if (mbhc->intr_ids->hph_left_ocp)
  533. mbhc->hphlocp_cnt = 0;
  534. else
  535. mbhc->hphrocp_cnt = 0;
  536. wcd9xxx_enable_irq(mbhc->resmgr->core_res, irq);
  537. }
  538. }
  539. static void hphrocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status)
  540. {
  541. __hphocp_off_report(mbhc, SND_JACK_OC_HPHR,
  542. mbhc->intr_ids->hph_right_ocp);
  543. }
  544. static void hphlocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status)
  545. {
  546. __hphocp_off_report(mbhc, SND_JACK_OC_HPHL,
  547. mbhc->intr_ids->hph_left_ocp);
  548. }
  549. static void wcd9xxx_get_mbhc_micbias_regs(struct wcd9xxx_mbhc *mbhc,
  550. enum wcd9xxx_mbhc_micbias_type mb_type)
  551. {
  552. unsigned int cfilt;
  553. struct wcd9xxx_micbias_setting *micbias_pdata =
  554. mbhc->resmgr->micbias_pdata;
  555. struct mbhc_micbias_regs *micbias_regs;
  556. enum wcd9xxx_micbias_num mb_num;
  557. if (mb_type == MBHC_ANC_MIC_MB) {
  558. micbias_regs = &mbhc->mbhc_anc_bias_regs;
  559. mb_num = mbhc->mbhc_cfg->anc_micbias;
  560. } else {
  561. micbias_regs = &mbhc->mbhc_bias_regs;
  562. mb_num = mbhc->mbhc_cfg->micbias;
  563. }
  564. switch (mb_num) {
  565. case MBHC_MICBIAS1:
  566. cfilt = micbias_pdata->bias1_cfilt_sel;
  567. micbias_regs->mbhc_reg = WCD9XXX_A_MICB_1_MBHC;
  568. micbias_regs->int_rbias = WCD9XXX_A_MICB_1_INT_RBIAS;
  569. micbias_regs->ctl_reg = WCD9XXX_A_MICB_1_CTL;
  570. break;
  571. case MBHC_MICBIAS2:
  572. cfilt = micbias_pdata->bias2_cfilt_sel;
  573. micbias_regs->mbhc_reg = WCD9XXX_A_MICB_2_MBHC;
  574. micbias_regs->int_rbias = WCD9XXX_A_MICB_2_INT_RBIAS;
  575. micbias_regs->ctl_reg = WCD9XXX_A_MICB_2_CTL;
  576. break;
  577. case MBHC_MICBIAS3:
  578. cfilt = micbias_pdata->bias3_cfilt_sel;
  579. micbias_regs->mbhc_reg = WCD9XXX_A_MICB_3_MBHC;
  580. micbias_regs->int_rbias = WCD9XXX_A_MICB_3_INT_RBIAS;
  581. micbias_regs->ctl_reg = WCD9XXX_A_MICB_3_CTL;
  582. break;
  583. case MBHC_MICBIAS4:
  584. cfilt = micbias_pdata->bias4_cfilt_sel;
  585. micbias_regs->mbhc_reg = mbhc->resmgr->reg_addr->micb_4_mbhc;
  586. micbias_regs->int_rbias =
  587. mbhc->resmgr->reg_addr->micb_4_int_rbias;
  588. micbias_regs->ctl_reg = mbhc->resmgr->reg_addr->micb_4_ctl;
  589. break;
  590. default:
  591. /* Should never reach here */
  592. pr_err("%s: Invalid MIC BIAS for MBHC\n", __func__);
  593. return;
  594. }
  595. micbias_regs->cfilt_sel = cfilt;
  596. switch (cfilt) {
  597. case WCD9XXX_CFILT1_SEL:
  598. micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_1_VAL;
  599. micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_1_CTL;
  600. break;
  601. case WCD9XXX_CFILT2_SEL:
  602. micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_2_VAL;
  603. micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_2_CTL;
  604. break;
  605. case WCD9XXX_CFILT3_SEL:
  606. micbias_regs->cfilt_val = WCD9XXX_A_MICB_CFILT_3_VAL;
  607. micbias_regs->cfilt_ctl = WCD9XXX_A_MICB_CFILT_3_CTL;
  608. break;
  609. }
  610. if (mb_type == MBHC_PRIMARY_MIC_MB) {
  611. switch (cfilt) {
  612. case WCD9XXX_CFILT1_SEL:
  613. mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt1_mv;
  614. break;
  615. case WCD9XXX_CFILT2_SEL:
  616. mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt2_mv;
  617. break;
  618. case WCD9XXX_CFILT3_SEL:
  619. mbhc->mbhc_data.micb_mv = micbias_pdata->cfilt3_mv;
  620. break;
  621. }
  622. }
  623. }
  624. static void wcd9xxx_clr_and_turnon_hph_padac(struct wcd9xxx_mbhc *mbhc)
  625. {
  626. bool pa_turned_on = false;
  627. struct snd_soc_codec *codec = mbhc->codec;
  628. u8 wg_time;
  629. wg_time = snd_soc_read(codec, WCD9XXX_A_RX_HPH_CNP_WG_TIME) ;
  630. wg_time += 1;
  631. if (test_and_clear_bit(WCD9XXX_HPHR_DAC_OFF_ACK,
  632. &mbhc->hph_pa_dac_state)) {
  633. pr_debug("%s: HPHR clear flag and enable DAC\n", __func__);
  634. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_R_DAC_CTL,
  635. 0xC0, 0xC0);
  636. }
  637. if (test_and_clear_bit(WCD9XXX_HPHL_DAC_OFF_ACK,
  638. &mbhc->hph_pa_dac_state)) {
  639. pr_debug("%s: HPHL clear flag and enable DAC\n", __func__);
  640. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_L_DAC_CTL,
  641. 0x80, 0x80);
  642. }
  643. if (test_and_clear_bit(WCD9XXX_HPHR_PA_OFF_ACK,
  644. &mbhc->hph_pa_dac_state)) {
  645. pr_debug("%s: HPHR clear flag and enable PA\n", __func__);
  646. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x10,
  647. 1 << 4);
  648. pa_turned_on = true;
  649. }
  650. if (test_and_clear_bit(WCD9XXX_HPHL_PA_OFF_ACK,
  651. &mbhc->hph_pa_dac_state)) {
  652. pr_debug("%s: HPHL clear flag and enable PA\n", __func__);
  653. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x20, 1
  654. << 5);
  655. pa_turned_on = true;
  656. }
  657. if (pa_turned_on) {
  658. pr_debug("%s: PA was turned off by MBHC and not by DAPM\n",
  659. __func__);
  660. usleep_range(wg_time * 1000, wg_time * 1000);
  661. }
  662. }
  663. static int wcd9xxx_cancel_btn_work(struct wcd9xxx_mbhc *mbhc)
  664. {
  665. int r;
  666. r = cancel_delayed_work_sync(&mbhc->mbhc_btn_dwork);
  667. if (r)
  668. /* if scheduled mbhc.mbhc_btn_dwork is canceled from here,
  669. * we have to unlock from here instead btn_work */
  670. wcd9xxx_unlock_sleep(mbhc->resmgr->core_res);
  671. return r;
  672. }
  673. static bool wcd9xxx_is_hph_dac_on(struct snd_soc_codec *codec, int left)
  674. {
  675. u8 hph_reg_val = 0;
  676. if (left)
  677. hph_reg_val = snd_soc_read(codec, WCD9XXX_A_RX_HPH_L_DAC_CTL);
  678. else
  679. hph_reg_val = snd_soc_read(codec, WCD9XXX_A_RX_HPH_R_DAC_CTL);
  680. return (hph_reg_val & 0xC0) ? true : false;
  681. }
  682. static bool wcd9xxx_is_hph_pa_on(struct snd_soc_codec *codec)
  683. {
  684. u8 hph_reg_val = 0;
  685. hph_reg_val = snd_soc_read(codec, WCD9XXX_A_RX_HPH_CNP_EN);
  686. return (hph_reg_val & 0x30) ? true : false;
  687. }
  688. /* called under codec_resource_lock acquisition */
  689. static void wcd9xxx_set_and_turnoff_hph_padac(struct wcd9xxx_mbhc *mbhc)
  690. {
  691. u8 wg_time;
  692. struct snd_soc_codec *codec = mbhc->codec;
  693. wg_time = snd_soc_read(codec, WCD9XXX_A_RX_HPH_CNP_WG_TIME);
  694. wg_time += 1;
  695. /* If headphone PA is on, check if userspace receives
  696. * removal event to sync-up PA's state */
  697. if (wcd9xxx_is_hph_pa_on(codec)) {
  698. pr_debug("%s PA is on, setting PA_OFF_ACK\n", __func__);
  699. set_bit(WCD9XXX_HPHL_PA_OFF_ACK, &mbhc->hph_pa_dac_state);
  700. set_bit(WCD9XXX_HPHR_PA_OFF_ACK, &mbhc->hph_pa_dac_state);
  701. } else {
  702. pr_debug("%s PA is off\n", __func__);
  703. }
  704. if (wcd9xxx_is_hph_dac_on(codec, 1))
  705. set_bit(WCD9XXX_HPHL_DAC_OFF_ACK, &mbhc->hph_pa_dac_state);
  706. if (wcd9xxx_is_hph_dac_on(codec, 0))
  707. set_bit(WCD9XXX_HPHR_DAC_OFF_ACK, &mbhc->hph_pa_dac_state);
  708. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_CNP_EN, 0x30, 0x00);
  709. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_L_DAC_CTL, 0x80, 0x00);
  710. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_R_DAC_CTL, 0xC0, 0x00);
  711. usleep_range(wg_time * 1000, wg_time * 1000);
  712. }
  713. static void wcd9xxx_insert_detect_setup(struct wcd9xxx_mbhc *mbhc, bool ins)
  714. {
  715. if (!mbhc->mbhc_cfg->insert_detect)
  716. return;
  717. pr_debug("%s: Setting up %s detection\n", __func__,
  718. ins ? "insert" : "removal");
  719. /* Disable detection to avoid glitch */
  720. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT, 1, 0);
  721. if (mbhc->mbhc_cfg->gpio_level_insert)
  722. snd_soc_write(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT,
  723. (0x68 | (ins ? (1 << 1) : 0)));
  724. else
  725. snd_soc_write(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT,
  726. (0x6C | (ins ? (1 << 1) : 0)));
  727. /* Re-enable detection */
  728. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MBHC_INSERT_DETECT, 1, 1);
  729. }
  730. /* called under codec_resource_lock acquisition */
  731. static void wcd9xxx_report_plug(struct wcd9xxx_mbhc *mbhc, int insertion,
  732. enum snd_jack_types jack_type)
  733. {
  734. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  735. pr_debug("%s: enter insertion %d hph_status %x\n",
  736. __func__, insertion, mbhc->hph_status);
  737. wake_lock_timeout(&det_wake_lock, (HZ * 5));
  738. if (!insertion) {
  739. /* Report removal */
  740. mbhc->hph_status &= ~jack_type;
  741. /*
  742. * cancel possibly scheduled btn work and
  743. * report release if we reported button press
  744. */
  745. if (wcd9xxx_cancel_btn_work(mbhc))
  746. pr_debug("%s: button press is canceled\n", __func__);
  747. else if (mbhc->buttons_pressed) {
  748. pr_debug("%s: release of button press%d\n",
  749. __func__, jack_type);
  750. wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
  751. mbhc->buttons_pressed);
  752. mbhc->buttons_pressed &=
  753. ~WCD9XXX_JACK_BUTTON_MASK;
  754. }
  755. if (mbhc->micbias_enable && mbhc->micbias_enable_cb) {
  756. pr_debug("%s: Disabling micbias\n", __func__);
  757. mbhc->micbias_enable = false;
  758. mbhc->micbias_enable_cb(mbhc->codec, false,
  759. mbhc->mbhc_cfg->micbias);
  760. }
  761. mbhc->zl = mbhc->zr = 0;
  762. pr_info("%s: Reporting removal %d(%x)\n", __func__,
  763. jack_type, mbhc->hph_status);
  764. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status,
  765. WCD9XXX_JACK_MASK);
  766. wcd9xxx_set_and_turnoff_hph_padac(mbhc);
  767. hphrocp_off_report(mbhc, SND_JACK_OC_HPHR);
  768. hphlocp_off_report(mbhc, SND_JACK_OC_HPHL);
  769. mbhc->current_plug = PLUG_TYPE_NONE;
  770. mbhc->polling_active = false;
  771. } else {
  772. /*
  773. * Report removal of current jack type.
  774. * Headphone to headset shouldn't report headphone
  775. * removal.
  776. */
  777. if (mbhc->mbhc_cfg->detect_extn_cable &&
  778. !(mbhc->current_plug == PLUG_TYPE_HEADPHONE &&
  779. jack_type == SND_JACK_HEADSET) &&
  780. (mbhc->hph_status && mbhc->hph_status != jack_type)) {
  781. if (mbhc->micbias_enable && mbhc->micbias_enable_cb &&
  782. mbhc->hph_status == SND_JACK_HEADSET) {
  783. pr_debug("%s: Disabling micbias\n", __func__);
  784. mbhc->micbias_enable = false;
  785. mbhc->micbias_enable_cb(mbhc->codec, false,
  786. mbhc->mbhc_cfg->micbias);
  787. }
  788. pr_info("%s: Reporting removal (%x)\n",
  789. __func__, mbhc->hph_status);
  790. mbhc->zl = mbhc->zr = 0;
  791. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
  792. 0, WCD9XXX_JACK_MASK);
  793. mbhc->hph_status &= ~(SND_JACK_HEADSET |
  794. SND_JACK_LINEOUT |
  795. SND_JACK_ANC_HEADPHONE |
  796. SND_JACK_UNSUPPORTED);
  797. }
  798. /* Report insertion */
  799. mbhc->hph_status |= jack_type;
  800. if (jack_type == SND_JACK_HEADPHONE) {
  801. mbhc->current_plug = PLUG_TYPE_HEADPHONE;
  802. } else if (jack_type == SND_JACK_UNSUPPORTED) {
  803. mbhc->current_plug = PLUG_TYPE_GND_MIC_SWAP;
  804. } else if (jack_type == SND_JACK_HEADSET) {
  805. mbhc->polling_active = BUTTON_POLLING_SUPPORTED;
  806. mbhc->current_plug = PLUG_TYPE_HEADSET;
  807. mbhc->update_z = true;
  808. } else if (jack_type == SND_JACK_LINEOUT) {
  809. mbhc->current_plug = PLUG_TYPE_HIGH_HPH;
  810. } else if (jack_type == SND_JACK_ANC_HEADPHONE) {
  811. mbhc->polling_active = BUTTON_POLLING_SUPPORTED;
  812. mbhc->current_plug = PLUG_TYPE_ANC_HEADPHONE;
  813. }
  814. if (mbhc->micbias_enable && mbhc->micbias_enable_cb) {
  815. pr_debug("%s: Enabling micbias\n", __func__);
  816. mbhc->micbias_enable_cb(mbhc->codec, true,
  817. mbhc->mbhc_cfg->micbias);
  818. }
  819. if (mbhc->impedance_detect && impedance_detect_en)
  820. wcd9xxx_detect_impedance(mbhc, &mbhc->zl, &mbhc->zr);
  821. pr_info("%s: Reporting insertion %d(%x)\n", __func__,
  822. jack_type, mbhc->hph_status);
  823. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
  824. mbhc->hph_status, WCD9XXX_JACK_MASK);
  825. wcd9xxx_clr_and_turnon_hph_padac(mbhc);
  826. }
  827. /* Setup insert detect */
  828. wcd9xxx_insert_detect_setup(mbhc, !insertion);
  829. pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status);
  830. }
  831. /* should be called under interrupt context that hold suspend */
  832. static void wcd9xxx_schedule_hs_detect_plug(struct wcd9xxx_mbhc *mbhc,
  833. struct work_struct *work)
  834. {
  835. pr_debug("%s: scheduling wcd9xxx_correct_swch_plug\n", __func__);
  836. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  837. mbhc->hs_detect_work_stop = false;
  838. wcd9xxx_lock_sleep(mbhc->resmgr->core_res);
  839. schedule_work(work);
  840. }
  841. /* called under codec_resource_lock acquisition */
  842. static void wcd9xxx_cancel_hs_detect_plug(struct wcd9xxx_mbhc *mbhc,
  843. struct work_struct *work)
  844. {
  845. pr_debug("%s: Canceling correct_plug_swch\n", __func__);
  846. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  847. mbhc->hs_detect_work_stop = true;
  848. wmb();
  849. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  850. if (cancel_work_sync(work)) {
  851. pr_debug("%s: correct_plug_swch is canceled\n",
  852. __func__);
  853. wcd9xxx_unlock_sleep(mbhc->resmgr->core_res);
  854. }
  855. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  856. }
  857. static s16 scale_v_micb_vddio(struct wcd9xxx_mbhc *mbhc, int v, bool tovddio)
  858. {
  859. int r;
  860. int vddio_k, mb_k;
  861. vddio_k = __wcd9xxx_resmgr_get_k_val(mbhc, VDDIO_MICBIAS_MV);
  862. mb_k = __wcd9xxx_resmgr_get_k_val(mbhc, mbhc->mbhc_data.micb_mv);
  863. if (tovddio)
  864. r = v * (vddio_k + 4) / (mb_k + 4);
  865. else
  866. r = v * (mb_k + 4) / (vddio_k + 4);
  867. return r;
  868. }
  869. static s16 wcd9xxx_get_current_v_hs_max(struct wcd9xxx_mbhc *mbhc)
  870. {
  871. s16 v_hs_max;
  872. struct wcd9xxx_mbhc_plug_type_cfg *plug_type;
  873. plug_type = WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  874. if ((mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV) &&
  875. mbhc->mbhc_micbias_switched)
  876. v_hs_max = scale_v_micb_vddio(mbhc, plug_type->v_hs_max, true);
  877. else
  878. v_hs_max = plug_type->v_hs_max;
  879. return v_hs_max;
  880. }
  881. static short wcd9xxx_read_sta_result(struct snd_soc_codec *codec)
  882. {
  883. u8 bias_msb, bias_lsb;
  884. short bias_value;
  885. bias_msb = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B3_STATUS);
  886. bias_lsb = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B2_STATUS);
  887. bias_value = (bias_msb << 8) | bias_lsb;
  888. return bias_value;
  889. }
  890. static short wcd9xxx_read_dce_result(struct snd_soc_codec *codec)
  891. {
  892. u8 bias_msb, bias_lsb;
  893. short bias_value;
  894. bias_msb = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B5_STATUS);
  895. bias_lsb = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B4_STATUS);
  896. bias_value = (bias_msb << 8) | bias_lsb;
  897. return bias_value;
  898. }
  899. static void wcd9xxx_turn_onoff_rel_detection(struct snd_soc_codec *codec,
  900. bool on)
  901. {
  902. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x02, on << 1);
  903. }
  904. static short __wcd9xxx_codec_sta_dce(struct wcd9xxx_mbhc *mbhc, int dce,
  905. bool override_bypass, bool noreldetection)
  906. {
  907. short bias_value;
  908. struct snd_soc_codec *codec = mbhc->codec;
  909. wcd9xxx_disable_irq(mbhc->resmgr->core_res,
  910. mbhc->intr_ids->dce_est_complete);
  911. if (noreldetection)
  912. wcd9xxx_turn_onoff_rel_detection(codec, false);
  913. if (mbhc->mbhc_cfg->do_recalibration)
  914. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x2,
  915. 0x0);
  916. /* Turn on the override */
  917. if (!override_bypass)
  918. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x4, 0x4);
  919. if (dce) {
  920. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8,
  921. 0x8);
  922. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x4);
  923. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8,
  924. 0x0);
  925. if (mbhc->mbhc_cfg->do_recalibration)
  926. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
  927. 0x2, 0x2);
  928. usleep_range(mbhc->mbhc_data.t_sta_dce,
  929. mbhc->mbhc_data.t_sta_dce);
  930. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x4);
  931. usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
  932. bias_value = wcd9xxx_read_dce_result(codec);
  933. } else {
  934. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8,
  935. 0x8);
  936. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x2);
  937. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8,
  938. 0x0);
  939. if (mbhc->mbhc_cfg->do_recalibration)
  940. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
  941. 0x2, 0x2);
  942. usleep_range(mbhc->mbhc_data.t_sta_dce,
  943. mbhc->mbhc_data.t_sta_dce);
  944. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x2);
  945. usleep_range(mbhc->mbhc_data.t_sta,
  946. mbhc->mbhc_data.t_sta);
  947. bias_value = wcd9xxx_read_sta_result(codec);
  948. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8,
  949. 0x8);
  950. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x0);
  951. }
  952. /* Turn off the override after measuring mic voltage */
  953. if (!override_bypass)
  954. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04,
  955. 0x00);
  956. if (noreldetection)
  957. wcd9xxx_turn_onoff_rel_detection(codec, true);
  958. wcd9xxx_enable_irq(mbhc->resmgr->core_res,
  959. mbhc->intr_ids->dce_est_complete);
  960. return bias_value;
  961. }
  962. static short wcd9xxx_codec_sta_dce(struct wcd9xxx_mbhc *mbhc, int dce,
  963. bool norel)
  964. {
  965. bool override_bypass;
  966. /* Bypass override if it is already enabled */
  967. override_bypass = (snd_soc_read(mbhc->codec,
  968. WCD9XXX_A_CDC_MBHC_B1_CTL) &
  969. 0x04) ? true : false;
  970. return __wcd9xxx_codec_sta_dce(mbhc, dce, override_bypass, norel);
  971. }
  972. static s32 __wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce,
  973. u16 bias_value, s16 z, u32 micb_mv)
  974. {
  975. s16 value, mb;
  976. s32 mv;
  977. value = bias_value;
  978. if (dce) {
  979. mb = (mbhc->mbhc_data.dce_mb);
  980. mv = (value - z) * (s32)micb_mv / (mb - z);
  981. } else {
  982. mb = (mbhc->mbhc_data.sta_mb);
  983. mv = (value - z) * (s32)micb_mv / (mb - z);
  984. }
  985. return mv;
  986. }
  987. static s32 wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce,
  988. u16 bias_value)
  989. {
  990. s16 z;
  991. z = dce ? (s16)mbhc->mbhc_data.dce_z : (s16)mbhc->mbhc_data.sta_z;
  992. return __wcd9xxx_codec_sta_dce_v(mbhc, dce, bias_value, z,
  993. mbhc->mbhc_data.micb_mv);
  994. }
  995. /* To enable/disable bandgap and RC oscillator */
  996. static void wcd9xxx_mbhc_ctrl_clk_bandgap(struct wcd9xxx_mbhc *mbhc,
  997. bool enable)
  998. {
  999. if (enable) {
  1000. WCD9XXX_BG_CLK_LOCK(mbhc->resmgr);
  1001. wcd9xxx_resmgr_get_bandgap(mbhc->resmgr,
  1002. WCD9XXX_BANDGAP_AUDIO_MODE);
  1003. wcd9xxx_resmgr_get_clk_block(mbhc->resmgr,
  1004. WCD9XXX_CLK_RCO);
  1005. WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr);
  1006. } else {
  1007. WCD9XXX_BG_CLK_LOCK(mbhc->resmgr);
  1008. wcd9xxx_resmgr_put_clk_block(mbhc->resmgr,
  1009. WCD9XXX_CLK_RCO);
  1010. wcd9xxx_resmgr_put_bandgap(mbhc->resmgr,
  1011. WCD9XXX_BANDGAP_AUDIO_MODE);
  1012. WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr);
  1013. }
  1014. }
  1015. /* called only from interrupt which is under codec_resource_lock acquisition */
  1016. static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
  1017. struct mbhc_micbias_regs *mbhc_micb_regs,
  1018. bool is_cs_enable)
  1019. {
  1020. struct snd_soc_codec *codec = mbhc->codec;
  1021. short bias_value;
  1022. u8 cfilt_mode;
  1023. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1024. pr_debug("%s: enter\n", __func__);
  1025. if (!mbhc->mbhc_cfg->calibration) {
  1026. pr_err("%s: Error, no calibration exists\n", __func__);
  1027. return -ENODEV;
  1028. }
  1029. /* Enable external voltage source to micbias if present */
  1030. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
  1031. mbhc->mbhc_cb->enable_mb_source(codec, true, true);
  1032. /*
  1033. * setup internal micbias if codec uses internal micbias for
  1034. * headset detection
  1035. */
  1036. if (mbhc->mbhc_cfg->use_int_rbias) {
  1037. if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
  1038. mbhc->mbhc_cb->setup_int_rbias(codec, true);
  1039. else
  1040. pr_err("%s: internal bias requested but codec did not provide callback\n",
  1041. __func__);
  1042. }
  1043. snd_soc_update_bits(codec, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x01);
  1044. /* Make sure CFILT is in fast mode, save current mode */
  1045. cfilt_mode = snd_soc_read(codec, mbhc_micb_regs->cfilt_ctl);
  1046. if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
  1047. mbhc->mbhc_cb->cfilt_fast_mode(codec, mbhc);
  1048. else
  1049. snd_soc_update_bits(codec, mbhc_micb_regs->cfilt_ctl,
  1050. 0x70, 0x00);
  1051. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x2, 0x2);
  1052. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  1053. mbhc->scaling_mux_in);
  1054. pr_debug("%s: scaling_mux_input: %d\n", __func__,
  1055. mbhc->scaling_mux_in);
  1056. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  1057. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  1058. else
  1059. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  1060. 0x80, 0x80);
  1061. snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0x80, 0x80);
  1062. snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0x1F, 0x1C);
  1063. snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0x40, 0x40);
  1064. snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0x80, 0x00);
  1065. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
  1066. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x00);
  1067. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x2, 0x2);
  1068. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
  1069. if (!mbhc->mbhc_cfg->do_recalibration) {
  1070. if (!is_cs_enable)
  1071. wcd9xxx_calibrate_hs_polling(mbhc);
  1072. }
  1073. /* don't flip override */
  1074. bias_value = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
  1075. snd_soc_write(codec, mbhc_micb_regs->cfilt_ctl, cfilt_mode);
  1076. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
  1077. return bias_value;
  1078. }
  1079. static void wcd9xxx_recalibrate(struct wcd9xxx_mbhc *mbhc,
  1080. struct mbhc_micbias_regs *mbhc_micb_regs,
  1081. bool is_cs_enable)
  1082. {
  1083. struct snd_soc_codec *codec = mbhc->codec;
  1084. s16 reg;
  1085. int change;
  1086. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  1087. s16 sta_z = 0, dce_z = 0;
  1088. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  1089. if (mbhc->mbhc_cfg->do_recalibration) {
  1090. /* recalibrate dce_z and sta_z */
  1091. reg = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
  1092. change = snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  1093. 0x78, btn_det->mbhc_nsc << 3);
  1094. wcd9xxx_get_z(mbhc, &dce_z, &sta_z, mbhc_micb_regs, true);
  1095. if (change)
  1096. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, reg);
  1097. if (dce_z && sta_z) {
  1098. pr_debug("%s: sta_z 0x%x -> 0x%x, dce_z 0x%x -> 0x%x\n",
  1099. __func__,
  1100. mbhc->mbhc_data.sta_z, sta_z & 0xffff,
  1101. mbhc->mbhc_data.dce_z, dce_z & 0xffff);
  1102. mbhc->mbhc_data.dce_z = dce_z;
  1103. mbhc->mbhc_data.sta_z = sta_z;
  1104. wcd9xxx_mbhc_calc_thres(mbhc);
  1105. wcd9xxx_calibrate_hs_polling(mbhc);
  1106. } else {
  1107. pr_warn("%s: failed get new dce_z/sta_z 0x%x/0x%x\n",
  1108. __func__, dce_z, sta_z);
  1109. }
  1110. if (is_cs_enable) {
  1111. /* recalibrate dce_nsc_cs_z */
  1112. reg = snd_soc_read(mbhc->codec,
  1113. WCD9XXX_A_CDC_MBHC_B1_CTL);
  1114. snd_soc_update_bits(mbhc->codec,
  1115. WCD9XXX_A_CDC_MBHC_B1_CTL,
  1116. 0x78, WCD9XXX_MBHC_NSC_CS << 3);
  1117. wcd9xxx_get_z(mbhc, &dce_z, NULL, mbhc_micb_regs,
  1118. true);
  1119. snd_soc_write(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  1120. reg);
  1121. if (dce_z) {
  1122. mbhc->mbhc_data.dce_nsc_cs_z = dce_z;
  1123. /* update v_cs_ins_h with new dce_nsc_cs_z */
  1124. mbhc->mbhc_data.v_cs_ins_h =
  1125. wcd9xxx_codec_v_sta_dce(
  1126. mbhc, DCE,
  1127. WCD9XXX_V_CS_HS_MAX,
  1128. is_cs_enable);
  1129. pr_debug("%s: dce_nsc_cs_z 0x%x -> 0x%x, v_cs_ins_h 0x%x\n",
  1130. __func__,
  1131. mbhc->mbhc_data.dce_nsc_cs_z,
  1132. dce_z & 0xffff,
  1133. mbhc->mbhc_data.v_cs_ins_h);
  1134. } else {
  1135. pr_debug("%s: failed get new dce_nsc_cs_z\n",
  1136. __func__);
  1137. }
  1138. }
  1139. }
  1140. }
  1141. static void wcd9xxx_shutdown_hs_removal_detect(struct wcd9xxx_mbhc *mbhc)
  1142. {
  1143. struct snd_soc_codec *codec = mbhc->codec;
  1144. const struct wcd9xxx_mbhc_general_cfg *generic =
  1145. WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
  1146. /* Need MBHC clock */
  1147. WCD9XXX_BG_CLK_LOCK(mbhc->resmgr);
  1148. wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO);
  1149. WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr);
  1150. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x2, 0x2);
  1151. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x6, 0x0);
  1152. __wcd9xxx_switch_micbias(mbhc, 0, false, false);
  1153. usleep_range(generic->t_shutdown_plug_rem,
  1154. generic->t_shutdown_plug_rem);
  1155. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0xA, 0x8);
  1156. WCD9XXX_BG_CLK_LOCK(mbhc->resmgr);
  1157. /* Put requested CLK back */
  1158. wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO);
  1159. WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr);
  1160. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x00);
  1161. }
  1162. static void wcd9xxx_cleanup_hs_polling(struct wcd9xxx_mbhc *mbhc)
  1163. {
  1164. pr_debug("%s: enter\n", __func__);
  1165. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1166. wcd9xxx_shutdown_hs_removal_detect(mbhc);
  1167. /* Disable external voltage source to micbias if present */
  1168. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
  1169. mbhc->mbhc_cb->enable_mb_source(mbhc->codec, false, true);
  1170. mbhc->polling_active = false;
  1171. mbhc->mbhc_state = MBHC_STATE_NONE;
  1172. pr_debug("%s: leave\n", __func__);
  1173. }
  1174. /* called under codec_resource_lock acquisition */
  1175. static void wcd9xxx_codec_hphr_gnd_switch(struct snd_soc_codec *codec, bool on)
  1176. {
  1177. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x01, on);
  1178. if (on)
  1179. usleep_range(5000, 5000);
  1180. }
  1181. static void wcd9xxx_onoff_vddio_switch(struct wcd9xxx_mbhc *mbhc, bool on)
  1182. {
  1183. pr_debug("%s: vddio %d\n", __func__, on);
  1184. if (mbhc->mbhc_cb && mbhc->mbhc_cb->pull_mb_to_vddio) {
  1185. mbhc->mbhc_cb->pull_mb_to_vddio(mbhc->codec, on);
  1186. goto exit;
  1187. }
  1188. if (on) {
  1189. snd_soc_update_bits(mbhc->codec, mbhc->mbhc_bias_regs.mbhc_reg,
  1190. 1 << 7, 1 << 7);
  1191. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
  1192. 1 << 4, 0);
  1193. } else {
  1194. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
  1195. 1 << 4, 1 << 4);
  1196. snd_soc_update_bits(mbhc->codec, mbhc->mbhc_bias_regs.mbhc_reg,
  1197. 1 << 7, 0);
  1198. }
  1199. exit:
  1200. /*
  1201. * Wait for the micbias to settle down to vddio
  1202. * when the micbias to vddio switch is enabled.
  1203. */
  1204. if (on)
  1205. usleep_range(10000, 10000);
  1206. }
  1207. static int wcd9xxx_hphl_status(struct wcd9xxx_mbhc *mbhc)
  1208. {
  1209. u16 hph, status;
  1210. struct snd_soc_codec *codec = mbhc->codec;
  1211. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1212. hph = snd_soc_read(codec, WCD9XXX_A_MBHC_HPH);
  1213. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x12, 0x02);
  1214. usleep_range(WCD9XXX_HPHL_STATUS_READY_WAIT_US,
  1215. WCD9XXX_HPHL_STATUS_READY_WAIT_US +
  1216. WCD9XXX_USLEEP_RANGE_MARGIN_US);
  1217. status = snd_soc_read(codec, WCD9XXX_A_RX_HPH_L_STATUS);
  1218. snd_soc_write(codec, WCD9XXX_A_MBHC_HPH, hph);
  1219. return status;
  1220. }
  1221. static enum wcd9xxx_mbhc_plug_type
  1222. wcd9xxx_cs_find_plug_type(struct wcd9xxx_mbhc *mbhc,
  1223. struct wcd9xxx_mbhc_detect *dt, const int size,
  1224. bool highhph,
  1225. unsigned long event_state)
  1226. {
  1227. int i;
  1228. int vdce, mb_mv;
  1229. int ch, sz, delta_thr;
  1230. int minv = 0, maxv = INT_MIN;
  1231. struct wcd9xxx_mbhc_detect *d = dt;
  1232. struct wcd9xxx_mbhc_detect *dprev = d, *dmicbias = NULL, *dgnd = NULL;
  1233. enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
  1234. const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
  1235. WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  1236. s16 hs_max, no_mic, dce_z;
  1237. int highhph_cnt = 0;
  1238. pr_debug("%s: enter\n", __func__);
  1239. pr_debug("%s: event_state 0x%lx\n", __func__, event_state);
  1240. sz = size - 1;
  1241. for (i = 0, d = dt, ch = 0; i < sz; i++, d++) {
  1242. if (d->mic_bias) {
  1243. dce_z = mbhc->mbhc_data.dce_z;
  1244. mb_mv = mbhc->mbhc_data.micb_mv;
  1245. hs_max = plug_type->v_hs_max;
  1246. no_mic = plug_type->v_no_mic;
  1247. } else {
  1248. dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
  1249. mb_mv = VDDIO_MICBIAS_MV;
  1250. hs_max = WCD9XXX_V_CS_HS_MAX;
  1251. no_mic = WCD9XXX_V_CS_NO_MIC;
  1252. }
  1253. vdce = __wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce,
  1254. dce_z, (u32)mb_mv);
  1255. d->_vdces = vdce;
  1256. if (d->_vdces < no_mic)
  1257. d->_type = PLUG_TYPE_HEADPHONE;
  1258. else if (d->_vdces >= hs_max) {
  1259. d->_type = PLUG_TYPE_HIGH_HPH;
  1260. highhph_cnt++;
  1261. } else
  1262. d->_type = PLUG_TYPE_HEADSET;
  1263. pr_debug("%s: DCE #%d, %04x, V %04d(%04d), HPHL %d TYPE %d\n",
  1264. __func__, i, d->dce, vdce, d->_vdces,
  1265. d->hphl_status & 0x01,
  1266. d->_type);
  1267. ch += d->hphl_status & 0x01;
  1268. if (!d->swap_gnd && !d->mic_bias) {
  1269. if (maxv < d->_vdces)
  1270. maxv = d->_vdces;
  1271. if (!minv || minv > d->_vdces)
  1272. minv = d->_vdces;
  1273. }
  1274. if ((!d->mic_bias &&
  1275. (d->_vdces >= WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV &&
  1276. d->_vdces <= WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV)) ||
  1277. (d->mic_bias &&
  1278. (d->_vdces >= WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
  1279. d->_vdces <= WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV))) {
  1280. pr_debug("%s: within invalid range\n", __func__);
  1281. type = PLUG_TYPE_INVALID;
  1282. goto exit;
  1283. }
  1284. }
  1285. delta_thr = ((highhph_cnt == sz) || highhph) ?
  1286. WCD9XXX_MB_MEAS_DELTA_MAX_MV :
  1287. WCD9XXX_CS_MEAS_DELTA_MAX_MV;
  1288. for (i = 0, d = dt; i < sz; i++, d++) {
  1289. if ((i > 0) && !d->mic_bias && !d->swap_gnd &&
  1290. (d->_type != dprev->_type)) {
  1291. pr_debug("%s: Invalid, inconsistent types\n", __func__);
  1292. type = PLUG_TYPE_INVALID;
  1293. goto exit;
  1294. }
  1295. if (!d->swap_gnd && !d->mic_bias &&
  1296. (abs(minv - d->_vdces) > delta_thr ||
  1297. abs(maxv - d->_vdces) > delta_thr)) {
  1298. pr_debug("%s: Invalid, delta %dmv, %dmv and %dmv\n",
  1299. __func__, d->_vdces, minv, maxv);
  1300. type = PLUG_TYPE_INVALID;
  1301. goto exit;
  1302. } else if (d->swap_gnd) {
  1303. dgnd = d;
  1304. }
  1305. if (!d->mic_bias && !d->swap_gnd)
  1306. dprev = d;
  1307. else if (d->mic_bias)
  1308. dmicbias = d;
  1309. }
  1310. if (dgnd && dt->_type != PLUG_TYPE_HEADSET &&
  1311. dt->_type != dgnd->_type) {
  1312. pr_debug("%s: Invalid, inconsistent types\n", __func__);
  1313. type = PLUG_TYPE_INVALID;
  1314. goto exit;
  1315. }
  1316. type = dt->_type;
  1317. if (dmicbias) {
  1318. if (dmicbias->_type == PLUG_TYPE_HEADSET &&
  1319. (dt->_type == PLUG_TYPE_HIGH_HPH ||
  1320. dt->_type == PLUG_TYPE_HEADSET)) {
  1321. type = PLUG_TYPE_HEADSET;
  1322. if (dt->_type == PLUG_TYPE_HIGH_HPH) {
  1323. pr_debug("%s: Headset with threshold on MIC detected\n",
  1324. __func__);
  1325. if (mbhc->mbhc_cfg->micbias_enable_flags &
  1326. (1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET))
  1327. mbhc->micbias_enable = true;
  1328. }
  1329. }
  1330. }
  1331. if (type == PLUG_TYPE_HEADSET && dgnd && !dgnd->mic_bias) {
  1332. /* if plug type is Headphone report as GND_MIC_SWAP */
  1333. if (dgnd->_type == PLUG_TYPE_HEADPHONE) {
  1334. pr_debug("%s: GND_MIC_SWAP\n", __func__);
  1335. type = PLUG_TYPE_GND_MIC_SWAP;
  1336. /*
  1337. * if type is GND_MIC_SWAP we should not check
  1338. * HPHL status hence goto exit
  1339. */
  1340. goto exit;
  1341. } else if (dgnd->_type != PLUG_TYPE_HEADSET && !dmicbias) {
  1342. pr_debug("%s: Invalid, inconsistent types\n", __func__);
  1343. type = PLUG_TYPE_INVALID;
  1344. }
  1345. }
  1346. if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
  1347. pr_debug("%s: HPHL PA was ON\n", __func__);
  1348. } else if (ch != sz && ch > 0) {
  1349. pr_debug("%s: Invalid, inconsistent HPHL..\n", __func__);
  1350. type = PLUG_TYPE_INVALID;
  1351. goto exit;
  1352. }
  1353. if (!(event_state & (1UL << MBHC_EVENT_PA_HPHL))) {
  1354. if (((type == PLUG_TYPE_HEADSET ||
  1355. type == PLUG_TYPE_HEADPHONE) && ch != sz)) {
  1356. pr_debug("%s: Invalid, not fully inserted, TYPE %d\n",
  1357. __func__, type);
  1358. type = PLUG_TYPE_INVALID;
  1359. }
  1360. }
  1361. if (type == PLUG_TYPE_HEADSET &&
  1362. (mbhc->mbhc_cfg->micbias_enable_flags &
  1363. (1 << MBHC_MICBIAS_ENABLE_REGULAR_HEADSET)))
  1364. mbhc->micbias_enable = true;
  1365. exit:
  1366. pr_debug("%s: Plug type %d detected\n", __func__, type);
  1367. return type;
  1368. }
  1369. /*
  1370. * wcd9xxx_find_plug_type : Find out and return the best plug type with given
  1371. * list of wcd9xxx_mbhc_detect structure.
  1372. * param mbhc wcd9xxx_mbhc structure
  1373. * param dt collected measurements
  1374. * param size array size of dt
  1375. * param event_state mbhc->event_state when dt is collected
  1376. */
  1377. static enum wcd9xxx_mbhc_plug_type
  1378. wcd9xxx_find_plug_type(struct wcd9xxx_mbhc *mbhc,
  1379. struct wcd9xxx_mbhc_detect *dt, const int size,
  1380. unsigned long event_state)
  1381. {
  1382. int i;
  1383. int ch;
  1384. enum wcd9xxx_mbhc_plug_type type;
  1385. int vdce;
  1386. struct wcd9xxx_mbhc_detect *d, *dprev, *dgnd = NULL, *dvddio = NULL;
  1387. int maxv = 0, minv = 0;
  1388. const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
  1389. WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  1390. const s16 hs_max = plug_type->v_hs_max;
  1391. const s16 no_mic = plug_type->v_no_mic;
  1392. pr_debug("%s: event_state 0x%lx\n", __func__, event_state);
  1393. for (i = 0, d = dt, ch = 0; i < size; i++, d++) {
  1394. vdce = wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce);
  1395. if (d->vddio)
  1396. d->_vdces = scale_v_micb_vddio(mbhc, vdce, false);
  1397. else
  1398. d->_vdces = vdce;
  1399. if (d->_vdces >= no_mic && d->_vdces < hs_max)
  1400. d->_type = PLUG_TYPE_HEADSET;
  1401. else if (d->_vdces < no_mic)
  1402. d->_type = PLUG_TYPE_HEADPHONE;
  1403. else
  1404. d->_type = PLUG_TYPE_HIGH_HPH;
  1405. ch += d->hphl_status & 0x01;
  1406. if (!d->swap_gnd && !d->hwvalue && !d->vddio) {
  1407. if (maxv < d->_vdces)
  1408. maxv = d->_vdces;
  1409. if (!minv || minv > d->_vdces)
  1410. minv = d->_vdces;
  1411. }
  1412. pr_debug("%s: DCE #%d, %04x, V %04d(%04d), GND %d, VDDIO %d, HPHL %d TYPE %d\n",
  1413. __func__, i, d->dce, vdce, d->_vdces,
  1414. d->swap_gnd, d->vddio, d->hphl_status & 0x01,
  1415. d->_type);
  1416. /*
  1417. * If GND and MIC prongs are aligned to HPHR and GND of
  1418. * headphone, codec measures the voltage based on
  1419. * impedance between HPHR and GND which results in ~80mv.
  1420. * Avoid this.
  1421. */
  1422. if (d->_vdces >= WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
  1423. d->_vdces <= WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV) {
  1424. pr_debug("%s: within invalid range\n", __func__);
  1425. type = PLUG_TYPE_INVALID;
  1426. goto exit;
  1427. }
  1428. }
  1429. if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
  1430. pr_debug("%s: HPHL PA was ON\n", __func__);
  1431. } else if (ch != size && ch > 0) {
  1432. pr_debug("%s: Invalid, inconsistent HPHL\n", __func__);
  1433. type = PLUG_TYPE_INVALID;
  1434. goto exit;
  1435. }
  1436. for (i = 0, dprev = NULL, d = dt; i < size; i++, d++) {
  1437. if (d->vddio) {
  1438. dvddio = d;
  1439. continue;
  1440. }
  1441. if ((i > 0) && (dprev != NULL) && (d->_type != dprev->_type)) {
  1442. pr_debug("%s: Invalid, inconsistent types\n", __func__);
  1443. type = PLUG_TYPE_INVALID;
  1444. goto exit;
  1445. }
  1446. if (!d->swap_gnd && !d->hwvalue &&
  1447. (abs(minv - d->_vdces) > WCD9XXX_MEAS_DELTA_MAX_MV ||
  1448. abs(maxv - d->_vdces) > WCD9XXX_MEAS_DELTA_MAX_MV)) {
  1449. pr_debug("%s: Invalid, delta %dmv, %dmv and %dmv\n",
  1450. __func__, d->_vdces, minv, maxv);
  1451. type = PLUG_TYPE_INVALID;
  1452. goto exit;
  1453. } else if (d->swap_gnd) {
  1454. dgnd = d;
  1455. }
  1456. dprev = d;
  1457. }
  1458. WARN_ON(i != size);
  1459. type = dt->_type;
  1460. if (type == PLUG_TYPE_HEADSET && dgnd) {
  1461. if ((dgnd->_vdces + WCD9XXX_GM_SWAP_THRES_MIN_MV <
  1462. minv) &&
  1463. (dgnd->_vdces + WCD9XXX_GM_SWAP_THRES_MAX_MV >
  1464. maxv))
  1465. type = PLUG_TYPE_GND_MIC_SWAP;
  1466. }
  1467. /* if HPHL PA was on, we cannot use hphl status */
  1468. if (!(event_state & (1UL << MBHC_EVENT_PA_HPHL))) {
  1469. if (((type == PLUG_TYPE_HEADSET ||
  1470. type == PLUG_TYPE_HEADPHONE) && ch != size) ||
  1471. (type == PLUG_TYPE_GND_MIC_SWAP && ch)) {
  1472. pr_debug("%s: Invalid, not fully inserted, TYPE %d\n",
  1473. __func__, type);
  1474. type = PLUG_TYPE_INVALID;
  1475. }
  1476. }
  1477. if (type == PLUG_TYPE_HEADSET) {
  1478. if (dvddio && ((dvddio->_vdces > hs_max) ||
  1479. (dvddio->_vdces > minv + WCD9XXX_THRESHOLD_MIC_THRESHOLD))) {
  1480. pr_debug("%s: Headset with threshold on MIC detected\n",
  1481. __func__);
  1482. if (mbhc->mbhc_cfg->micbias_enable_flags &
  1483. (1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET))
  1484. mbhc->micbias_enable = true;
  1485. } else {
  1486. pr_debug("%s: Headset with regular MIC detected\n",
  1487. __func__);
  1488. if (mbhc->mbhc_cfg->micbias_enable_flags &
  1489. (1 << MBHC_MICBIAS_ENABLE_REGULAR_HEADSET))
  1490. mbhc->micbias_enable = true;
  1491. }
  1492. }
  1493. exit:
  1494. pr_debug("%s: Plug type %d detected, micbias_enable %d\n", __func__,
  1495. type, mbhc->micbias_enable);
  1496. return type;
  1497. }
  1498. /*
  1499. * Pull down MBHC micbias for provided duration in microsecond.
  1500. */
  1501. static int wcd9xxx_pull_down_micbias(struct wcd9xxx_mbhc *mbhc, int us)
  1502. {
  1503. bool micbiasconn = false;
  1504. struct snd_soc_codec *codec = mbhc->codec;
  1505. const u16 ctlreg = mbhc->mbhc_bias_regs.ctl_reg;
  1506. /*
  1507. * Disable MBHC to micbias connection to pull down
  1508. * micbias and pull down micbias for a moment.
  1509. */
  1510. if ((snd_soc_read(mbhc->codec, ctlreg) & 0x01)) {
  1511. WARN_ONCE(1, "MBHC micbias is already pulled down unexpectedly\n");
  1512. return -EFAULT;
  1513. }
  1514. if ((snd_soc_read(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL) & 1 << 4)) {
  1515. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
  1516. 1 << 4, 0);
  1517. micbiasconn = true;
  1518. }
  1519. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x01);
  1520. /*
  1521. * Pull down for 1ms to discharge bias. Give small margin (10us) to be
  1522. * able to get consistent result across DCEs.
  1523. */
  1524. usleep_range(1000, 1000 + 10);
  1525. if (micbiasconn)
  1526. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_MAD_ANA_CTRL,
  1527. 1 << 4, 1 << 4);
  1528. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
  1529. usleep_range(us, us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
  1530. return 0;
  1531. }
  1532. void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc,
  1533. struct mbhc_micbias_regs *mbhc_micb_regs,
  1534. bool on, bool highhph)
  1535. {
  1536. struct snd_soc_codec *codec;
  1537. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  1538. const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
  1539. WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
  1540. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  1541. codec = mbhc->codec;
  1542. if (on) {
  1543. pr_debug("%s: enabling current source\n", __func__);
  1544. /* Nsc to 9 */
  1545. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  1546. 0x78, 0x48);
  1547. /* pull down diode bit to 0 */
  1548. snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
  1549. 0x01, 0x00);
  1550. /*
  1551. * Keep the low power insertion/removal
  1552. * detection (reg 0x3DD) disabled
  1553. */
  1554. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL,
  1555. 0x01, 0x00);
  1556. /*
  1557. * Enable the Mic Bias current source
  1558. * Write bits[6:5] of register MICB_2_MBHC to 0x3 (V_20_UA)
  1559. * Write bit[7] of register MICB_2_MBHC to 1
  1560. * (INS_DET_ISRC_EN__ENABLE)
  1561. * MICB_2_MBHC__SCHT_TRIG_EN to 1
  1562. */
  1563. snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
  1564. 0xF0, 0xF0);
  1565. /* Disconnect MBHC Override from MicBias and LDOH */
  1566. snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x00);
  1567. } else {
  1568. pr_debug("%s: disabling current source\n", __func__);
  1569. /* Connect MBHC Override from MicBias and LDOH */
  1570. snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x10);
  1571. /* INS_DET_ISRC_CTL to acdb value */
  1572. snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg,
  1573. 0x60, plug_det->mic_current << 5);
  1574. if (!highhph) {
  1575. /* INS_DET_ISRC_EN__ENABLE to 0 */
  1576. snd_soc_update_bits(codec,
  1577. mbhc_micb_regs->mbhc_reg,
  1578. 0x80, 0x00);
  1579. /* MICB_2_MBHC__SCHT_TRIG_EN to 0 */
  1580. snd_soc_update_bits(codec,
  1581. mbhc_micb_regs->mbhc_reg,
  1582. 0x10, 0x00);
  1583. }
  1584. /* Nsc to acdb value */
  1585. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
  1586. btn_det->mbhc_nsc << 3);
  1587. }
  1588. }
  1589. static enum wcd9xxx_mbhc_plug_type
  1590. wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
  1591. {
  1592. struct snd_soc_codec *codec = mbhc->codec;
  1593. struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT];
  1594. enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
  1595. int i;
  1596. pr_debug("%s: enter\n", __func__);
  1597. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1598. BUG_ON(NUM_DCE_PLUG_INS_DETECT < 4);
  1599. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
  1600. rt[0].swap_gnd = false;
  1601. rt[0].vddio = false;
  1602. rt[0].hwvalue = true;
  1603. rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
  1604. rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, &mbhc->mbhc_bias_regs,
  1605. true);
  1606. rt[0].mic_bias = false;
  1607. for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
  1608. rt[i].swap_gnd = (i == NUM_DCE_PLUG_INS_DETECT - 3);
  1609. rt[i].mic_bias = ((i == NUM_DCE_PLUG_INS_DETECT - 4) &&
  1610. highhph);
  1611. rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
  1612. if (rt[i].swap_gnd)
  1613. wcd9xxx_codec_hphr_gnd_switch(codec, true);
  1614. if (rt[i].mic_bias)
  1615. wcd9xxx_turn_onoff_current_source(mbhc,
  1616. &mbhc->mbhc_bias_regs,
  1617. false, false);
  1618. rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, !highhph, true);
  1619. if (rt[i].mic_bias)
  1620. wcd9xxx_turn_onoff_current_source(mbhc,
  1621. &mbhc->mbhc_bias_regs,
  1622. true, false);
  1623. if (rt[i].swap_gnd)
  1624. wcd9xxx_codec_hphr_gnd_switch(codec, false);
  1625. }
  1626. /* recalibrate DCE/STA GND voltages */
  1627. wcd9xxx_recalibrate(mbhc, &mbhc->mbhc_bias_regs, true);
  1628. type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph,
  1629. mbhc->event_state);
  1630. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  1631. pr_debug("%s: plug_type:%d\n", __func__, type);
  1632. return type;
  1633. }
  1634. static enum wcd9xxx_mbhc_plug_type
  1635. wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
  1636. {
  1637. int i;
  1638. bool vddioon;
  1639. struct wcd9xxx_mbhc_plug_type_cfg *plug_type_ptr;
  1640. struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT];
  1641. enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
  1642. struct snd_soc_codec *codec = mbhc->codec;
  1643. pr_debug("%s: enter\n", __func__);
  1644. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1645. /* make sure override is on */
  1646. WARN_ON(!(snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x04));
  1647. /* GND and MIC swap detection requires at least 2 rounds of DCE */
  1648. BUG_ON(NUM_DCE_PLUG_INS_DETECT < 2);
  1649. detect_use_vddio_switch = mbhc->mbhc_cfg->use_vddio_meas;
  1650. /*
  1651. * There are chances vddio switch is on and cfilt voltage is adjusted
  1652. * to vddio voltage even after plug type removal reported.
  1653. */
  1654. vddioon = __wcd9xxx_switch_micbias(mbhc, 0, false, false);
  1655. pr_debug("%s: vddio switch was %s\n", __func__, vddioon ? "on" : "off");
  1656. plug_type_ptr =
  1657. WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  1658. /*
  1659. * cfilter in fast mode requires 1ms to charge up and down micbias
  1660. * fully.
  1661. */
  1662. (void) wcd9xxx_pull_down_micbias(mbhc,
  1663. WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US);
  1664. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
  1665. rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
  1666. rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, &mbhc->mbhc_bias_regs,
  1667. false);
  1668. rt[0].swap_gnd = false;
  1669. rt[0].vddio = false;
  1670. rt[0].hwvalue = true;
  1671. for (i = 1; i < NUM_DCE_PLUG_INS_DETECT; i++) {
  1672. rt[i].swap_gnd = (i == NUM_DCE_PLUG_INS_DETECT - 2);
  1673. if (detect_use_vddio_switch)
  1674. rt[i].vddio = (i == 1);
  1675. else
  1676. rt[i].vddio = false;
  1677. rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
  1678. rt[i].hwvalue = false;
  1679. if (rt[i].swap_gnd)
  1680. wcd9xxx_codec_hphr_gnd_switch(codec, true);
  1681. if (rt[i].vddio)
  1682. wcd9xxx_onoff_vddio_switch(mbhc, true);
  1683. /*
  1684. * Pull down micbias to detect headset with mic which has
  1685. * threshold and to have more consistent voltage measurements.
  1686. *
  1687. * cfilter in fast mode requires 1ms to charge up and down
  1688. * micbias fully.
  1689. */
  1690. (void) wcd9xxx_pull_down_micbias(mbhc,
  1691. WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US);
  1692. rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
  1693. if (rt[i].vddio)
  1694. wcd9xxx_onoff_vddio_switch(mbhc, false);
  1695. if (rt[i].swap_gnd)
  1696. wcd9xxx_codec_hphr_gnd_switch(codec, false);
  1697. }
  1698. /* recalibrate DCE/STA GND voltages */
  1699. wcd9xxx_recalibrate(mbhc, &mbhc->mbhc_bias_regs, false);
  1700. if (vddioon)
  1701. __wcd9xxx_switch_micbias(mbhc, 1, false, false);
  1702. type = wcd9xxx_find_plug_type(mbhc, rt, ARRAY_SIZE(rt),
  1703. mbhc->event_state);
  1704. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  1705. pr_debug("%s: leave\n", __func__);
  1706. return type;
  1707. }
  1708. static bool wcd9xxx_swch_level_remove(struct wcd9xxx_mbhc *mbhc)
  1709. {
  1710. if (mbhc->mbhc_cfg->gpio)
  1711. return (gpio_get_value_cansleep(mbhc->mbhc_cfg->gpio) !=
  1712. mbhc->mbhc_cfg->gpio_level_insert);
  1713. else if (mbhc->mbhc_cfg->insert_detect)
  1714. return snd_soc_read(mbhc->codec,
  1715. WCD9XXX_A_MBHC_INSERT_DET_STATUS) &
  1716. (1 << 2);
  1717. else
  1718. WARN(1, "Invalid jack detection configuration\n");
  1719. return true;
  1720. }
  1721. static bool is_clk_active(struct snd_soc_codec *codec)
  1722. {
  1723. return !!(snd_soc_read(codec, WCD9XXX_A_CDC_CLK_MCLK_CTL) & 0x05);
  1724. }
  1725. static int wcd9xxx_enable_hs_detect(struct wcd9xxx_mbhc *mbhc,
  1726. int insertion, int trigger, bool padac_off)
  1727. {
  1728. struct snd_soc_codec *codec = mbhc->codec;
  1729. int central_bias_enabled = 0;
  1730. const struct wcd9xxx_mbhc_general_cfg *generic =
  1731. WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
  1732. const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
  1733. WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
  1734. pr_debug("%s: enter insertion(%d) trigger(0x%x)\n",
  1735. __func__, insertion, trigger);
  1736. if (!mbhc->mbhc_cfg->calibration) {
  1737. pr_err("Error, no wcd9xxx calibration\n");
  1738. return -EINVAL;
  1739. }
  1740. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x1, 0);
  1741. /*
  1742. * Make sure mic bias and Mic line schmitt trigger
  1743. * are turned OFF
  1744. */
  1745. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x01);
  1746. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x90, 0x00);
  1747. if (insertion) {
  1748. wcd9xxx_switch_micbias(mbhc, 0);
  1749. /* DAPM can manipulate PA/DAC bits concurrently */
  1750. if (padac_off == true)
  1751. wcd9xxx_set_and_turnoff_hph_padac(mbhc);
  1752. if (trigger & MBHC_USE_HPHL_TRIGGER) {
  1753. /* Enable HPH Schmitt Trigger */
  1754. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x11,
  1755. 0x11);
  1756. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x0C,
  1757. plug_det->hph_current << 2);
  1758. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x02,
  1759. 0x02);
  1760. }
  1761. if (trigger & MBHC_USE_MB_TRIGGER) {
  1762. /* enable the mic line schmitt trigger */
  1763. snd_soc_update_bits(codec,
  1764. mbhc->mbhc_bias_regs.mbhc_reg,
  1765. 0x60, plug_det->mic_current << 5);
  1766. snd_soc_update_bits(codec,
  1767. mbhc->mbhc_bias_regs.mbhc_reg,
  1768. 0x80, 0x80);
  1769. usleep_range(plug_det->t_mic_pid, plug_det->t_mic_pid);
  1770. snd_soc_update_bits(codec,
  1771. mbhc->mbhc_bias_regs.ctl_reg, 0x01,
  1772. 0x00);
  1773. snd_soc_update_bits(codec,
  1774. mbhc->mbhc_bias_regs.mbhc_reg,
  1775. 0x10, 0x10);
  1776. }
  1777. /* setup for insetion detection */
  1778. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x2, 0);
  1779. } else {
  1780. pr_debug("setup for removal detection\n");
  1781. /* Make sure the HPH schmitt trigger is OFF */
  1782. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x12, 0x00);
  1783. /* enable the mic line schmitt trigger */
  1784. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg,
  1785. 0x01, 0x00);
  1786. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x60,
  1787. plug_det->mic_current << 5);
  1788. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
  1789. 0x80, 0x80);
  1790. usleep_range(plug_det->t_mic_pid, plug_det->t_mic_pid);
  1791. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
  1792. 0x10, 0x10);
  1793. /* Setup for low power removal detection */
  1794. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x2,
  1795. 0x2);
  1796. }
  1797. if (snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x4) {
  1798. /* called by interrupt */
  1799. if (!is_clk_active(codec)) {
  1800. wcd9xxx_resmgr_enable_config_mode(mbhc->resmgr, 1);
  1801. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  1802. 0x06, 0);
  1803. usleep_range(generic->t_shutdown_plug_rem,
  1804. generic->t_shutdown_plug_rem);
  1805. wcd9xxx_resmgr_enable_config_mode(mbhc->resmgr, 0);
  1806. } else
  1807. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  1808. 0x06, 0);
  1809. }
  1810. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.int_rbias, 0x80, 0);
  1811. /* If central bandgap disabled */
  1812. if (!(snd_soc_read(codec, WCD9XXX_A_PIN_CTL_OE1) & 1)) {
  1813. snd_soc_update_bits(codec, WCD9XXX_A_PIN_CTL_OE1, 0x3, 0x3);
  1814. usleep_range(generic->t_bg_fast_settle,
  1815. generic->t_bg_fast_settle);
  1816. central_bias_enabled = 1;
  1817. }
  1818. /* If LDO_H disabled */
  1819. if (snd_soc_read(codec, WCD9XXX_A_PIN_CTL_OE0) & 0x80) {
  1820. snd_soc_update_bits(codec, WCD9XXX_A_PIN_CTL_OE0, 0x10, 0);
  1821. snd_soc_update_bits(codec, WCD9XXX_A_PIN_CTL_OE0, 0x80, 0x80);
  1822. usleep_range(generic->t_ldoh, generic->t_ldoh);
  1823. snd_soc_update_bits(codec, WCD9XXX_A_PIN_CTL_OE0, 0x80, 0);
  1824. if (central_bias_enabled)
  1825. snd_soc_update_bits(codec, WCD9XXX_A_PIN_CTL_OE1, 0x1,
  1826. 0);
  1827. }
  1828. if (mbhc->resmgr->reg_addr && mbhc->resmgr->reg_addr->micb_4_mbhc)
  1829. snd_soc_update_bits(codec, mbhc->resmgr->reg_addr->micb_4_mbhc,
  1830. 0x3, mbhc->mbhc_cfg->micbias);
  1831. wcd9xxx_enable_irq(mbhc->resmgr->core_res, mbhc->intr_ids->insertion);
  1832. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
  1833. pr_debug("%s: leave\n", __func__);
  1834. return 0;
  1835. }
  1836. /*
  1837. * Function to determine whether anc microphone is preset or not.
  1838. * Return true if anc microphone is detected or false if not detected.
  1839. */
  1840. static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc)
  1841. {
  1842. struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT - 1];
  1843. bool anc_mic_found = true;
  1844. int i, mb_mv;
  1845. const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
  1846. WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  1847. s16 hs_max, dce_z;
  1848. s16 no_mic;
  1849. bool override_en;
  1850. bool timedout;
  1851. unsigned long timeout, retry = 0;
  1852. enum wcd9xxx_mbhc_plug_type type;
  1853. bool cs_enable;
  1854. if (mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS3 &&
  1855. mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS2)
  1856. return false;
  1857. pr_debug("%s: enter\n", __func__);
  1858. override_en = (snd_soc_read(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL) &
  1859. 0x04) ? true : false;
  1860. cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
  1861. (1 << MBHC_CS_ENABLE_DET_ANC)) != 0) &&
  1862. (!(snd_soc_read(mbhc->codec,
  1863. mbhc->mbhc_anc_bias_regs.ctl_reg) & 0x80)) &&
  1864. (mbhc->mbhc_cfg->micbias != mbhc->mbhc_cfg->anc_micbias);
  1865. if (cs_enable) {
  1866. wcd9xxx_turn_onoff_current_source(mbhc,
  1867. &mbhc->mbhc_anc_bias_regs,
  1868. true, false);
  1869. } else {
  1870. if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) {
  1871. if (mbhc->micbias_enable_cb)
  1872. mbhc->micbias_enable_cb(mbhc->codec, true,
  1873. mbhc->mbhc_cfg->anc_micbias);
  1874. else
  1875. return false;
  1876. } else {
  1877. /* Enable override */
  1878. if (!override_en)
  1879. wcd9xxx_turn_onoff_override(mbhc, true);
  1880. }
  1881. }
  1882. if (!cs_enable) {
  1883. hs_max = plug_type->v_hs_max;
  1884. no_mic = plug_type->v_no_mic;
  1885. dce_z = mbhc->mbhc_data.dce_z;
  1886. mb_mv = mbhc->mbhc_data.micb_mv;
  1887. } else {
  1888. hs_max = WCD9XXX_V_CS_HS_MAX;
  1889. no_mic = WCD9XXX_V_CS_NO_MIC;
  1890. mb_mv = VDDIO_MICBIAS_MV;
  1891. dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
  1892. }
  1893. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
  1894. timeout = jiffies + msecs_to_jiffies(ANC_HPH_DETECT_PLUG_TIME_MS);
  1895. anc_mic_found = true;
  1896. while (!(timedout = time_after(jiffies, timeout))) {
  1897. retry++;
  1898. if (wcd9xxx_swch_level_remove(mbhc)) {
  1899. pr_debug("%s: Switch level is low\n", __func__);
  1900. anc_mic_found = false;
  1901. break;
  1902. }
  1903. pr_debug("%s: Retry attempt %lu", __func__, retry - 1);
  1904. rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
  1905. rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc,
  1906. &mbhc->mbhc_anc_bias_regs,
  1907. cs_enable);
  1908. rt[0]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true, rt[0].dce,
  1909. dce_z, (u32)mb_mv);
  1910. if (rt[0]._vdces >= no_mic && rt[0]._vdces < hs_max)
  1911. rt[0]._type = PLUG_TYPE_HEADSET;
  1912. else if (rt[0]._vdces < no_mic)
  1913. rt[0]._type = PLUG_TYPE_HEADPHONE;
  1914. else
  1915. rt[0]._type = PLUG_TYPE_HIGH_HPH;
  1916. pr_debug("%s: DCE #%d, V %04d, HPHL %d TYPE %d\n",
  1917. __func__, 0, rt[0]._vdces,
  1918. rt[0].hphl_status & 0x01,
  1919. rt[0]._type);
  1920. for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
  1921. rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1,
  1922. true, true);
  1923. rt[i]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true,
  1924. rt[i].dce, dce_z,
  1925. (u32) mb_mv);
  1926. if (rt[i]._vdces >= no_mic && rt[i]._vdces < hs_max)
  1927. rt[i]._type = PLUG_TYPE_HEADSET;
  1928. else if (rt[i]._vdces < no_mic)
  1929. rt[i]._type = PLUG_TYPE_HEADPHONE;
  1930. else
  1931. rt[i]._type = PLUG_TYPE_HIGH_HPH;
  1932. rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
  1933. pr_debug("%s: DCE #%d, V %04d, HPHL %d TYPE %d\n",
  1934. __func__, i, rt[i]._vdces,
  1935. rt[i].hphl_status & 0x01,
  1936. rt[i]._type);
  1937. }
  1938. /*
  1939. * Check for the "type" of all the 4 measurements
  1940. * If all 4 measurements have the Type as PLUG_TYPE_HEADSET
  1941. * then it is proper mic and declare that the plug has two mics
  1942. */
  1943. for (i = 0; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
  1944. if (i > 0 && (rt[i - 1]._type != rt[i]._type)) {
  1945. type = PLUG_TYPE_INVALID;
  1946. break;
  1947. } else {
  1948. type = rt[0]._type;
  1949. }
  1950. }
  1951. pr_debug("%s: Plug type found in ANC detection :%d",
  1952. __func__, type);
  1953. if (type != PLUG_TYPE_HEADSET)
  1954. anc_mic_found = false;
  1955. if (anc_mic_found || (type == PLUG_TYPE_HEADPHONE &&
  1956. mbhc->mbhc_cfg->hw_jack_type == FIVE_POLE_JACK) ||
  1957. (type == PLUG_TYPE_HIGH_HPH &&
  1958. mbhc->mbhc_cfg->hw_jack_type == SIX_POLE_JACK))
  1959. break;
  1960. }
  1961. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  1962. if (cs_enable) {
  1963. wcd9xxx_turn_onoff_current_source(mbhc,
  1964. &mbhc->mbhc_anc_bias_regs,
  1965. false, false);
  1966. } else {
  1967. if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) {
  1968. if (mbhc->micbias_enable_cb)
  1969. mbhc->micbias_enable_cb(mbhc->codec, false,
  1970. mbhc->mbhc_cfg->anc_micbias);
  1971. } else {
  1972. /* Disable override */
  1973. if (!override_en)
  1974. wcd9xxx_turn_onoff_override(mbhc, false);
  1975. }
  1976. }
  1977. pr_debug("%s: leave\n", __func__);
  1978. return anc_mic_found;
  1979. }
  1980. /* called under codec_resource_lock acquisition */
  1981. static void wcd9xxx_find_plug_and_report(struct wcd9xxx_mbhc *mbhc,
  1982. enum wcd9xxx_mbhc_plug_type plug_type)
  1983. {
  1984. bool anc_mic_found = false;
  1985. pr_debug("%s: enter current_plug(%d) new_plug(%d)\n",
  1986. __func__, mbhc->current_plug, plug_type);
  1987. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  1988. if (plug_type == PLUG_TYPE_HEADPHONE &&
  1989. mbhc->current_plug == PLUG_TYPE_NONE) {
  1990. /*
  1991. * Nothing was reported previously
  1992. * report a headphone or unsupported
  1993. */
  1994. wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADPHONE);
  1995. wcd9xxx_cleanup_hs_polling(mbhc);
  1996. } else if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
  1997. if (!mbhc->mbhc_cfg->detect_extn_cable) {
  1998. if (mbhc->current_plug == PLUG_TYPE_HEADSET)
  1999. wcd9xxx_report_plug(mbhc, 0,
  2000. SND_JACK_HEADSET);
  2001. else if (mbhc->current_plug == PLUG_TYPE_HEADPHONE)
  2002. wcd9xxx_report_plug(mbhc, 0,
  2003. SND_JACK_HEADPHONE);
  2004. }
  2005. wcd9xxx_report_plug(mbhc, 1, SND_JACK_UNSUPPORTED);
  2006. wcd9xxx_cleanup_hs_polling(mbhc);
  2007. } else if (plug_type == PLUG_TYPE_HEADSET) {
  2008. if (mbhc->mbhc_cfg->enable_anc_mic_detect) {
  2009. /*
  2010. * Do not report Headset, because at this point
  2011. * it could be a ANC headphone having two mics.
  2012. * So, proceed further to detect if there is a
  2013. * second mic.
  2014. */
  2015. mbhc->scaling_mux_in = 0x08;
  2016. anc_mic_found = wcd9xxx_detect_anc_plug_type(mbhc);
  2017. }
  2018. if (anc_mic_found) {
  2019. /* Report ANC headphone */
  2020. wcd9xxx_report_plug(mbhc, 1, SND_JACK_ANC_HEADPHONE);
  2021. } else {
  2022. /*
  2023. * If Headphone was reported previously, this will
  2024. * only report the mic line
  2025. */
  2026. wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADSET);
  2027. }
  2028. /* Button detection required RC oscillator */
  2029. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true);
  2030. /*
  2031. * sleep so that audio path completely tears down
  2032. * before report plug insertion to the user space
  2033. */
  2034. msleep(100);
  2035. /*
  2036. * if PA is already on, switch micbias
  2037. * source to VDDIO
  2038. */
  2039. if (mbhc->event_state &
  2040. (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR |
  2041. 1 << MBHC_EVENT_PRE_TX_1_3_ON))
  2042. __wcd9xxx_switch_micbias(mbhc, 1, false,
  2043. false);
  2044. wcd9xxx_start_hs_polling(mbhc);
  2045. } else if (plug_type == PLUG_TYPE_HIGH_HPH) {
  2046. if (mbhc->mbhc_cfg->detect_extn_cable) {
  2047. /* High impedance device found. Report as LINEOUT*/
  2048. if (mbhc->current_plug == PLUG_TYPE_NONE)
  2049. wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT);
  2050. wcd9xxx_cleanup_hs_polling(mbhc);
  2051. pr_debug("%s: setup mic trigger for further detection\n",
  2052. __func__);
  2053. mbhc->lpi_enabled = true;
  2054. /*
  2055. * Do not enable HPHL trigger. If playback is active,
  2056. * it might lead to continuous false HPHL triggers
  2057. */
  2058. wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_MB_TRIGGER,
  2059. false);
  2060. } else {
  2061. if (mbhc->current_plug == PLUG_TYPE_NONE)
  2062. wcd9xxx_report_plug(mbhc, 1,
  2063. SND_JACK_HEADPHONE);
  2064. wcd9xxx_cleanup_hs_polling(mbhc);
  2065. pr_debug("setup mic trigger for further detection\n");
  2066. mbhc->lpi_enabled = true;
  2067. wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_MB_TRIGGER |
  2068. MBHC_USE_HPHL_TRIGGER,
  2069. false);
  2070. }
  2071. } else {
  2072. WARN(1, "Unexpected current plug_type %d, plug_type %d\n",
  2073. mbhc->current_plug, plug_type);
  2074. }
  2075. pr_debug("%s: leave\n", __func__);
  2076. }
  2077. /* called under codec_resource_lock acquisition */
  2078. static void wcd9xxx_mbhc_decide_swch_plug(struct wcd9xxx_mbhc *mbhc)
  2079. {
  2080. enum wcd9xxx_mbhc_plug_type plug_type;
  2081. bool current_source_enable;
  2082. pr_debug("%s: enter\n", __func__);
  2083. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  2084. current_source_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
  2085. (1 << MBHC_CS_ENABLE_INSERTION)) != 0) &&
  2086. (!(snd_soc_read(mbhc->codec,
  2087. mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
  2088. mbhc->scaling_mux_in = 0x04;
  2089. if (current_source_enable) {
  2090. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2091. true, false);
  2092. plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, false);
  2093. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2094. false, false);
  2095. } else {
  2096. wcd9xxx_turn_onoff_override(mbhc, true);
  2097. plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
  2098. wcd9xxx_turn_onoff_override(mbhc, false);
  2099. }
  2100. if (wcd9xxx_swch_level_remove(mbhc)) {
  2101. pr_debug("%s: Switch level is low when determining plug\n",
  2102. __func__);
  2103. return;
  2104. }
  2105. if (plug_type == PLUG_TYPE_INVALID ||
  2106. plug_type == PLUG_TYPE_GND_MIC_SWAP) {
  2107. wcd9xxx_cleanup_hs_polling(mbhc);
  2108. wcd9xxx_schedule_hs_detect_plug(mbhc,
  2109. &mbhc->correct_plug_swch);
  2110. } else if (plug_type == PLUG_TYPE_HEADPHONE) {
  2111. wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADPHONE);
  2112. wcd9xxx_cleanup_hs_polling(mbhc);
  2113. wcd9xxx_schedule_hs_detect_plug(mbhc,
  2114. &mbhc->correct_plug_swch);
  2115. } else if (plug_type == PLUG_TYPE_HIGH_HPH) {
  2116. wcd9xxx_cleanup_hs_polling(mbhc);
  2117. wcd9xxx_schedule_hs_detect_plug(mbhc,
  2118. &mbhc->correct_plug_swch);
  2119. } else {
  2120. pr_debug("%s: Valid plug found, determine plug type %d\n",
  2121. __func__, plug_type);
  2122. wcd9xxx_find_plug_and_report(mbhc, plug_type);
  2123. }
  2124. pr_debug("%s: leave\n", __func__);
  2125. }
  2126. /* called under codec_resource_lock acquisition */
  2127. static void wcd9xxx_mbhc_detect_plug_type(struct wcd9xxx_mbhc *mbhc)
  2128. {
  2129. pr_debug("%s: enter\n", __func__);
  2130. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  2131. if (wcd9xxx_swch_level_remove(mbhc))
  2132. pr_debug("%s: Switch level low when determining plug\n",
  2133. __func__);
  2134. else
  2135. wcd9xxx_mbhc_decide_swch_plug(mbhc);
  2136. pr_debug("%s: leave\n", __func__);
  2137. }
  2138. /* called only from interrupt which is under codec_resource_lock acquisition */
  2139. static void wcd9xxx_hs_insert_irq_swch(struct wcd9xxx_mbhc *mbhc,
  2140. bool is_removal)
  2141. {
  2142. if (!is_removal) {
  2143. pr_debug("%s: MIC trigger insertion interrupt\n", __func__);
  2144. rmb();
  2145. if (mbhc->lpi_enabled)
  2146. msleep(100);
  2147. rmb();
  2148. if (!mbhc->lpi_enabled) {
  2149. pr_debug("%s: lpi is disabled\n", __func__);
  2150. } else if (!wcd9xxx_swch_level_remove(mbhc)) {
  2151. pr_debug("%s: Valid insertion, detect plug type\n",
  2152. __func__);
  2153. wcd9xxx_mbhc_decide_swch_plug(mbhc);
  2154. } else {
  2155. pr_debug("%s: Invalid insertion stop plug detection\n",
  2156. __func__);
  2157. }
  2158. } else if (mbhc->mbhc_cfg->detect_extn_cable) {
  2159. pr_debug("%s: Removal\n", __func__);
  2160. if (!wcd9xxx_swch_level_remove(mbhc)) {
  2161. /*
  2162. * Switch indicates, something is still inserted.
  2163. * This could be extension cable i.e. headset is
  2164. * removed from extension cable.
  2165. */
  2166. /* cancel detect plug */
  2167. wcd9xxx_cancel_hs_detect_plug(mbhc,
  2168. &mbhc->correct_plug_swch);
  2169. wcd9xxx_mbhc_decide_swch_plug(mbhc);
  2170. }
  2171. } else {
  2172. pr_err("%s: Switch IRQ used, invalid MBHC Removal\n", __func__);
  2173. }
  2174. }
  2175. static bool is_valid_mic_voltage(struct wcd9xxx_mbhc *mbhc, s32 mic_mv,
  2176. bool cs_enable)
  2177. {
  2178. const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
  2179. WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  2180. const s16 v_hs_max = wcd9xxx_get_current_v_hs_max(mbhc);
  2181. if (cs_enable)
  2182. return ((mic_mv > WCD9XXX_V_CS_NO_MIC) &&
  2183. (mic_mv < WCD9XXX_V_CS_HS_MAX)) ? true : false;
  2184. else
  2185. return (!(mic_mv > WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
  2186. mic_mv < WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV) &&
  2187. (mic_mv > plug_type->v_no_mic) &&
  2188. (mic_mv < v_hs_max)) ? true : false;
  2189. }
  2190. /*
  2191. * called under codec_resource_lock acquisition
  2192. * returns true if mic voltage range is back to normal insertion
  2193. * returns false either if timedout or removed
  2194. */
  2195. static bool wcd9xxx_hs_remove_settle(struct wcd9xxx_mbhc *mbhc)
  2196. {
  2197. int i;
  2198. bool timedout, settled = false;
  2199. s32 mic_mv[NUM_DCE_PLUG_DETECT];
  2200. short mb_v[NUM_DCE_PLUG_DETECT];
  2201. unsigned long retry = 0, timeout;
  2202. bool cs_enable;
  2203. cs_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
  2204. (1 << MBHC_CS_ENABLE_REMOVAL)) != 0) &&
  2205. (!(snd_soc_read(mbhc->codec,
  2206. mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
  2207. if (cs_enable)
  2208. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2209. true, false);
  2210. timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
  2211. while (!(timedout = time_after(jiffies, timeout))) {
  2212. retry++;
  2213. if (wcd9xxx_swch_level_remove(mbhc)) {
  2214. pr_debug("%s: Switch indicates removal\n", __func__);
  2215. break;
  2216. }
  2217. if (retry > 1)
  2218. msleep(250);
  2219. else
  2220. msleep(50);
  2221. if (wcd9xxx_swch_level_remove(mbhc)) {
  2222. pr_debug("%s: Switch indicates removal\n", __func__);
  2223. break;
  2224. }
  2225. if (cs_enable) {
  2226. for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
  2227. mb_v[i] = __wcd9xxx_codec_sta_dce(mbhc, 1,
  2228. true, true);
  2229. mic_mv[i] = __wcd9xxx_codec_sta_dce_v(mbhc,
  2230. true,
  2231. mb_v[i],
  2232. mbhc->mbhc_data.dce_nsc_cs_z,
  2233. (u32)VDDIO_MICBIAS_MV);
  2234. pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
  2235. __func__, retry, mic_mv[i], mb_v[i]);
  2236. }
  2237. } else {
  2238. for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
  2239. mb_v[i] = wcd9xxx_codec_sta_dce(mbhc, 1,
  2240. true);
  2241. mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1,
  2242. mb_v[i]);
  2243. pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
  2244. __func__, retry, mic_mv[i],
  2245. mb_v[i]);
  2246. }
  2247. }
  2248. if (wcd9xxx_swch_level_remove(mbhc)) {
  2249. pr_debug("%s: Switcn indicates removal\n", __func__);
  2250. break;
  2251. }
  2252. if (mbhc->current_plug == PLUG_TYPE_NONE) {
  2253. pr_debug("%s : headset/headphone is removed\n",
  2254. __func__);
  2255. break;
  2256. }
  2257. for (i = 0; i < NUM_DCE_PLUG_DETECT; i++)
  2258. if (!is_valid_mic_voltage(mbhc, mic_mv[i], cs_enable))
  2259. break;
  2260. if (i == NUM_DCE_PLUG_DETECT) {
  2261. pr_debug("%s: MIC voltage settled\n", __func__);
  2262. settled = true;
  2263. msleep(200);
  2264. break;
  2265. }
  2266. }
  2267. if (cs_enable)
  2268. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2269. false, false);
  2270. if (timedout)
  2271. pr_debug("%s: Microphone did not settle in %d seconds\n",
  2272. __func__, HS_DETECT_PLUG_TIME_MS);
  2273. return settled;
  2274. }
  2275. /* called only from interrupt which is under codec_resource_lock acquisition */
  2276. static void wcd9xxx_hs_remove_irq_swch(struct wcd9xxx_mbhc *mbhc)
  2277. {
  2278. pr_debug("%s: enter\n", __func__);
  2279. if (wcd9xxx_hs_remove_settle(mbhc))
  2280. wcd9xxx_start_hs_polling(mbhc);
  2281. pr_debug("%s: leave\n", __func__);
  2282. }
  2283. /* called only from interrupt which is under codec_resource_lock acquisition */
  2284. static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc)
  2285. {
  2286. s16 dce, dcez;
  2287. unsigned long timeout;
  2288. bool removed = true;
  2289. struct snd_soc_codec *codec = mbhc->codec;
  2290. const struct wcd9xxx_mbhc_general_cfg *generic =
  2291. WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
  2292. bool cs_enable;
  2293. s16 cur_v_ins_h;
  2294. u32 mb_mv;
  2295. pr_debug("%s: enter\n", __func__);
  2296. if (mbhc->current_plug != PLUG_TYPE_HEADSET &&
  2297. mbhc->current_plug != PLUG_TYPE_ANC_HEADPHONE) {
  2298. pr_debug("%s(): Headset is not inserted, ignore removal\n",
  2299. __func__);
  2300. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
  2301. 0x08, 0x08);
  2302. return;
  2303. }
  2304. usleep_range(generic->t_shutdown_plug_rem,
  2305. generic->t_shutdown_plug_rem);
  2306. /* If micbias is enabled, don't enable current source */
  2307. cs_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
  2308. (1 << MBHC_CS_ENABLE_REMOVAL)) != 0) &&
  2309. (!(snd_soc_read(codec,
  2310. mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
  2311. if (cs_enable)
  2312. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2313. true, false);
  2314. timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS);
  2315. do {
  2316. if (cs_enable) {
  2317. dce = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
  2318. dcez = mbhc->mbhc_data.dce_nsc_cs_z;
  2319. mb_mv = VDDIO_MICBIAS_MV;
  2320. } else {
  2321. dce = wcd9xxx_codec_sta_dce(mbhc, 1, true);
  2322. dcez = mbhc->mbhc_data.dce_z;
  2323. mb_mv = mbhc->mbhc_data.micb_mv;
  2324. }
  2325. pr_debug("%s: DCE 0x%x,%d\n", __func__, dce,
  2326. __wcd9xxx_codec_sta_dce_v(mbhc, true, dce,
  2327. dcez, mb_mv));
  2328. cur_v_ins_h = cs_enable ? (s16) mbhc->mbhc_data.v_cs_ins_h :
  2329. (wcd9xxx_get_current_v(mbhc,
  2330. WCD9XXX_CURRENT_V_INS_H));
  2331. if (dce < cur_v_ins_h) {
  2332. removed = false;
  2333. break;
  2334. }
  2335. } while (!time_after(jiffies, timeout));
  2336. pr_debug("%s: headset %sactually removed\n", __func__,
  2337. removed ? "" : "not ");
  2338. if (cs_enable)
  2339. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2340. false, false);
  2341. if (removed) {
  2342. if (mbhc->mbhc_cfg->detect_extn_cable) {
  2343. if (!wcd9xxx_swch_level_remove(mbhc)) {
  2344. /*
  2345. * extension cable is still plugged in
  2346. * report it as LINEOUT device
  2347. */
  2348. if (mbhc->hph_status == SND_JACK_HEADSET)
  2349. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc,
  2350. false);
  2351. wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT);
  2352. wcd9xxx_cleanup_hs_polling(mbhc);
  2353. wcd9xxx_enable_hs_detect(mbhc, 1,
  2354. MBHC_USE_MB_TRIGGER,
  2355. false);
  2356. }
  2357. } else {
  2358. /* Cancel possibly running hs_detect_work */
  2359. wcd9xxx_cancel_hs_detect_plug(mbhc,
  2360. &mbhc->correct_plug_noswch);
  2361. /*
  2362. * If this removal is not false, first check the micbias
  2363. * switch status and switch it to LDOH if it is already
  2364. * switched to VDDIO.
  2365. */
  2366. wcd9xxx_switch_micbias(mbhc, 0);
  2367. wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET);
  2368. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  2369. wcd9xxx_cleanup_hs_polling(mbhc);
  2370. wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_MB_TRIGGER |
  2371. MBHC_USE_HPHL_TRIGGER,
  2372. true);
  2373. }
  2374. } else {
  2375. wcd9xxx_start_hs_polling(mbhc);
  2376. }
  2377. pr_debug("%s: leave\n", __func__);
  2378. }
  2379. /* called only from interrupt which is under codec_resource_lock acquisition */
  2380. static void wcd9xxx_hs_insert_irq_extn(struct wcd9xxx_mbhc *mbhc,
  2381. bool is_mb_trigger)
  2382. {
  2383. /* Cancel possibly running hs_detect_work */
  2384. wcd9xxx_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
  2385. if (is_mb_trigger) {
  2386. pr_debug("%s: Waiting for Headphone left trigger\n", __func__);
  2387. wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_HPHL_TRIGGER, false);
  2388. } else {
  2389. pr_debug("%s: HPHL trigger received, detecting plug type\n",
  2390. __func__);
  2391. wcd9xxx_mbhc_detect_plug_type(mbhc);
  2392. }
  2393. }
  2394. static irqreturn_t wcd9xxx_hs_remove_irq(int irq, void *data)
  2395. {
  2396. struct wcd9xxx_mbhc *mbhc = data;
  2397. pr_debug("%s: enter, removal interrupt\n", __func__);
  2398. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2399. /*
  2400. * While we don't know whether MIC is there or not, let the resmgr know
  2401. * so micbias can be disabled temporarily
  2402. */
  2403. if (mbhc->current_plug == PLUG_TYPE_HEADSET) {
  2404. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2405. WCD9XXX_COND_HPH_MIC, false);
  2406. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2407. WCD9XXX_COND_HPH, false);
  2408. } else if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
  2409. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2410. WCD9XXX_COND_HPH, false);
  2411. }
  2412. if (mbhc->mbhc_cfg->detect_extn_cable &&
  2413. !wcd9xxx_swch_level_remove(mbhc))
  2414. wcd9xxx_hs_remove_irq_noswch(mbhc);
  2415. else
  2416. wcd9xxx_hs_remove_irq_swch(mbhc);
  2417. if (mbhc->current_plug == PLUG_TYPE_HEADSET) {
  2418. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2419. WCD9XXX_COND_HPH, true);
  2420. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2421. WCD9XXX_COND_HPH_MIC, true);
  2422. } else if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
  2423. wcd9xxx_resmgr_cond_update_cond(mbhc->resmgr,
  2424. WCD9XXX_COND_HPH, true);
  2425. }
  2426. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2427. return IRQ_HANDLED;
  2428. }
  2429. static irqreturn_t wcd9xxx_hs_insert_irq(int irq, void *data)
  2430. {
  2431. bool is_mb_trigger, is_removal;
  2432. struct wcd9xxx_mbhc *mbhc = data;
  2433. struct snd_soc_codec *codec = mbhc->codec;
  2434. pr_debug("%s: enter\n", __func__);
  2435. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2436. wcd9xxx_disable_irq(mbhc->resmgr->core_res, mbhc->intr_ids->insertion);
  2437. is_mb_trigger = !!(snd_soc_read(codec, mbhc->mbhc_bias_regs.mbhc_reg) &
  2438. 0x10);
  2439. is_removal = !!(snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_INT_CTL) & 0x02);
  2440. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x03, 0x00);
  2441. /* Turn off both HPH and MIC line schmitt triggers */
  2442. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x90, 0x00);
  2443. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
  2444. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
  2445. if (mbhc->mbhc_cfg->detect_extn_cable &&
  2446. mbhc->current_plug == PLUG_TYPE_HIGH_HPH)
  2447. wcd9xxx_hs_insert_irq_extn(mbhc, is_mb_trigger);
  2448. else
  2449. wcd9xxx_hs_insert_irq_swch(mbhc, is_removal);
  2450. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2451. return IRQ_HANDLED;
  2452. }
  2453. static void wcd9xxx_btn_lpress_fn(struct work_struct *work)
  2454. {
  2455. struct delayed_work *dwork;
  2456. short bias_value;
  2457. int dce_mv, sta_mv;
  2458. struct wcd9xxx_mbhc *mbhc;
  2459. pr_debug("%s:\n", __func__);
  2460. dwork = to_delayed_work(work);
  2461. mbhc = container_of(dwork, struct wcd9xxx_mbhc, mbhc_btn_dwork);
  2462. bias_value = wcd9xxx_read_sta_result(mbhc->codec);
  2463. sta_mv = wcd9xxx_codec_sta_dce_v(mbhc, 0, bias_value);
  2464. bias_value = wcd9xxx_read_dce_result(mbhc->codec);
  2465. dce_mv = wcd9xxx_codec_sta_dce_v(mbhc, 1, bias_value);
  2466. pr_debug("%s: STA: %d, DCE: %d\n", __func__, sta_mv, dce_mv);
  2467. pr_debug("%s: Reporting long button press event\n", __func__);
  2468. wcd9xxx_jack_report(mbhc, &mbhc->button_jack, mbhc->buttons_pressed,
  2469. mbhc->buttons_pressed);
  2470. pr_debug("%s: leave\n", __func__);
  2471. wcd9xxx_unlock_sleep(mbhc->resmgr->core_res);
  2472. }
  2473. static void wcd9xxx_mbhc_insert_work(struct work_struct *work)
  2474. {
  2475. struct delayed_work *dwork;
  2476. struct wcd9xxx_mbhc *mbhc;
  2477. struct snd_soc_codec *codec;
  2478. struct wcd9xxx_core_resource *core_res;
  2479. dwork = to_delayed_work(work);
  2480. mbhc = container_of(dwork, struct wcd9xxx_mbhc, mbhc_insert_dwork);
  2481. codec = mbhc->codec;
  2482. core_res = mbhc->resmgr->core_res;
  2483. pr_debug("%s:\n", __func__);
  2484. /* Turn off both HPH and MIC line schmitt triggers */
  2485. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x90, 0x00);
  2486. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
  2487. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
  2488. wcd9xxx_disable_irq_sync(core_res, mbhc->intr_ids->insertion);
  2489. wcd9xxx_mbhc_detect_plug_type(mbhc);
  2490. wcd9xxx_unlock_sleep(core_res);
  2491. }
  2492. static bool wcd9xxx_mbhc_fw_validate(const void *data, size_t size)
  2493. {
  2494. u32 cfg_offset;
  2495. struct wcd9xxx_mbhc_imped_detect_cfg *imped_cfg;
  2496. struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg;
  2497. struct firmware_cal fw;
  2498. fw.data = (void *)data;
  2499. fw.size = size;
  2500. if (fw.size < WCD9XXX_MBHC_CAL_MIN_SIZE)
  2501. return false;
  2502. /*
  2503. * Previous check guarantees that there is enough fw data up
  2504. * to num_btn
  2505. */
  2506. btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(fw.data);
  2507. cfg_offset = (u32) ((void *) btn_cfg - (void *) fw.data);
  2508. if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_BTN_SZ(btn_cfg)))
  2509. return false;
  2510. /*
  2511. * Previous check guarantees that there is enough fw data up
  2512. * to start of impedance detection configuration
  2513. */
  2514. imped_cfg = WCD9XXX_MBHC_CAL_IMPED_DET_PTR(fw.data);
  2515. cfg_offset = (u32) ((void *) imped_cfg - (void *) fw.data);
  2516. if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_MIN_SZ))
  2517. return false;
  2518. if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_SZ(imped_cfg)))
  2519. return false;
  2520. return true;
  2521. }
  2522. static u16 wcd9xxx_codec_v_sta_dce(struct wcd9xxx_mbhc *mbhc,
  2523. enum meas_type dce, s16 vin_mv,
  2524. bool cs_enable)
  2525. {
  2526. s16 diff, zero;
  2527. u32 mb_mv, in;
  2528. u16 value;
  2529. s16 dce_z;
  2530. mb_mv = mbhc->mbhc_data.micb_mv;
  2531. dce_z = mbhc->mbhc_data.dce_z;
  2532. if (mb_mv == 0) {
  2533. pr_err("%s: Mic Bias voltage is set to zero\n", __func__);
  2534. return -EINVAL;
  2535. }
  2536. if (cs_enable) {
  2537. mb_mv = VDDIO_MICBIAS_MV;
  2538. dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
  2539. }
  2540. if (dce) {
  2541. diff = (mbhc->mbhc_data.dce_mb) - (dce_z);
  2542. zero = (dce_z);
  2543. } else {
  2544. diff = (mbhc->mbhc_data.sta_mb) - (mbhc->mbhc_data.sta_z);
  2545. zero = (mbhc->mbhc_data.sta_z);
  2546. }
  2547. in = (u32) diff * vin_mv;
  2548. value = (u16) (in / mb_mv) + zero;
  2549. return value;
  2550. }
  2551. static void wcd9xxx_mbhc_calc_thres(struct wcd9xxx_mbhc *mbhc)
  2552. {
  2553. struct snd_soc_codec *codec;
  2554. s16 adj_v_hs_max;
  2555. s16 btn_mv = 0, btn_mv_sta[MBHC_V_IDX_NUM], btn_mv_dce[MBHC_V_IDX_NUM];
  2556. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  2557. struct wcd9xxx_mbhc_plug_type_cfg *plug_type;
  2558. u16 *btn_high;
  2559. int i;
  2560. pr_debug("%s: enter\n", __func__);
  2561. codec = mbhc->codec;
  2562. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  2563. plug_type = WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
  2564. mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_CFILT] =
  2565. wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_hs_max, false);
  2566. mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_CFILT] =
  2567. wcd9xxx_codec_v_sta_dce(mbhc, DCE, plug_type->v_hs_max, false);
  2568. mbhc->mbhc_data.v_inval_ins_low = FAKE_INS_LOW;
  2569. mbhc->mbhc_data.v_inval_ins_high = FAKE_INS_HIGH;
  2570. if (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV) {
  2571. adj_v_hs_max = scale_v_micb_vddio(mbhc, plug_type->v_hs_max,
  2572. true);
  2573. mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_VDDIO] =
  2574. wcd9xxx_codec_v_sta_dce(mbhc, STA, adj_v_hs_max, false);
  2575. mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_VDDIO] =
  2576. wcd9xxx_codec_v_sta_dce(mbhc, DCE, adj_v_hs_max, false);
  2577. mbhc->mbhc_data.v_inval_ins_low =
  2578. scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_low,
  2579. false);
  2580. mbhc->mbhc_data.v_inval_ins_high =
  2581. scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_high,
  2582. false);
  2583. }
  2584. mbhc->mbhc_data.v_cs_ins_h = wcd9xxx_codec_v_sta_dce(mbhc, DCE,
  2585. WCD9XXX_V_CS_HS_MAX,
  2586. true);
  2587. pr_debug("%s: v_ins_h for current source: 0x%x\n", __func__,
  2588. mbhc->mbhc_data.v_cs_ins_h);
  2589. btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
  2590. MBHC_BTN_DET_V_BTN_HIGH);
  2591. for (i = 0; i < btn_det->num_btn; i++)
  2592. btn_mv = btn_high[i] > btn_mv ? btn_high[i] : btn_mv;
  2593. btn_mv_sta[MBHC_V_IDX_CFILT] = btn_mv + btn_det->v_btn_press_delta_sta;
  2594. btn_mv_dce[MBHC_V_IDX_CFILT] = btn_mv + btn_det->v_btn_press_delta_cic;
  2595. btn_mv_sta[MBHC_V_IDX_VDDIO] =
  2596. scale_v_micb_vddio(mbhc, btn_mv_sta[MBHC_V_IDX_CFILT], true);
  2597. btn_mv_dce[MBHC_V_IDX_VDDIO] =
  2598. scale_v_micb_vddio(mbhc, btn_mv_dce[MBHC_V_IDX_CFILT], true);
  2599. mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_CFILT] =
  2600. wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_CFILT],
  2601. false);
  2602. mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT] =
  2603. wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_CFILT],
  2604. false);
  2605. mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_VDDIO] =
  2606. wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_VDDIO],
  2607. false);
  2608. mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_VDDIO] =
  2609. wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_VDDIO],
  2610. false);
  2611. mbhc->mbhc_data.v_brh[MBHC_V_IDX_CFILT] =
  2612. mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT];
  2613. mbhc->mbhc_data.v_brh[MBHC_V_IDX_VDDIO] =
  2614. mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_VDDIO];
  2615. mbhc->mbhc_data.v_brl = BUTTON_MIN;
  2616. mbhc->mbhc_data.v_no_mic =
  2617. wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_no_mic, false);
  2618. pr_debug("%s: leave\n", __func__);
  2619. }
  2620. static void wcd9xxx_onoff_ext_mclk(struct wcd9xxx_mbhc *mbhc, bool on)
  2621. {
  2622. /*
  2623. * XXX: {codec}_mclk_enable holds WCD9XXX_BCL_LOCK,
  2624. * therefore wcd9xxx_onoff_ext_mclk caller SHOULDN'T hold
  2625. * WCD9XXX_BCL_LOCK when it calls wcd9xxx_onoff_ext_mclk()
  2626. */
  2627. mbhc->mbhc_cfg->mclk_cb_fn(mbhc->codec, on, false);
  2628. }
  2629. /*
  2630. * Mic Bias Enable Decision
  2631. * Return true if high_hph_cnt is a power of 2 (!= 2)
  2632. * otherwise return false
  2633. */
  2634. static bool wcd9xxx_mbhc_enable_mb_decision(int high_hph_cnt)
  2635. {
  2636. return (high_hph_cnt > 2) && !(high_hph_cnt & (high_hph_cnt - 1));
  2637. }
  2638. static void wcd9xxx_correct_swch_plug(struct work_struct *work)
  2639. {
  2640. struct wcd9xxx_mbhc *mbhc;
  2641. struct snd_soc_codec *codec;
  2642. enum wcd9xxx_mbhc_plug_type plug_type = PLUG_TYPE_INVALID;
  2643. unsigned long timeout;
  2644. int retry = 0, pt_gnd_mic_swap_cnt = 0;
  2645. int highhph_cnt = 0;
  2646. bool correction = false;
  2647. bool current_source_enable;
  2648. bool wrk_complete = true, highhph = false;
  2649. pr_debug("%s: enter\n", __func__);
  2650. mbhc = container_of(work, struct wcd9xxx_mbhc, correct_plug_swch);
  2651. codec = mbhc->codec;
  2652. current_source_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
  2653. (1 << MBHC_CS_ENABLE_POLLING)) != 0) &&
  2654. (!(snd_soc_read(codec,
  2655. mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
  2656. wcd9xxx_onoff_ext_mclk(mbhc, true);
  2657. /*
  2658. * Keep override on during entire plug type correction work.
  2659. *
  2660. * This is okay under the assumption that any switch irqs which use
  2661. * MBHC block cancel and sync this work so override is off again
  2662. * prior to switch interrupt handler's MBHC block usage.
  2663. * Also while this correction work is running, we can guarantee
  2664. * DAPM doesn't use any MBHC block as this work only runs with
  2665. * headphone detection.
  2666. */
  2667. if (current_source_enable)
  2668. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2669. true, false);
  2670. else
  2671. wcd9xxx_turn_onoff_override(mbhc, true);
  2672. timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
  2673. while (!time_after(jiffies, timeout)) {
  2674. ++retry;
  2675. rmb();
  2676. if (mbhc->hs_detect_work_stop) {
  2677. wrk_complete = false;
  2678. pr_debug("%s: stop requested\n", __func__);
  2679. break;
  2680. }
  2681. msleep(HS_DETECT_PLUG_INERVAL_MS);
  2682. if (wcd9xxx_swch_level_remove(mbhc)) {
  2683. wrk_complete = false;
  2684. pr_debug("%s: Switch level is low\n", __func__);
  2685. break;
  2686. }
  2687. /* can race with removal interrupt */
  2688. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2689. if (current_source_enable)
  2690. plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc,
  2691. highhph);
  2692. else
  2693. plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
  2694. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2695. pr_debug("%s: attempt(%d) current_plug(%d) new_plug(%d)\n",
  2696. __func__, retry, mbhc->current_plug, plug_type);
  2697. highhph_cnt = (plug_type == PLUG_TYPE_HIGH_HPH) ?
  2698. (highhph_cnt + 1) :
  2699. 0;
  2700. highhph = wcd9xxx_mbhc_enable_mb_decision(highhph_cnt);
  2701. if (plug_type == PLUG_TYPE_INVALID) {
  2702. pr_debug("Invalid plug in attempt # %d\n", retry);
  2703. if (!mbhc->mbhc_cfg->detect_extn_cable &&
  2704. retry == NUM_ATTEMPTS_TO_REPORT &&
  2705. mbhc->current_plug == PLUG_TYPE_NONE) {
  2706. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2707. wcd9xxx_report_plug(mbhc, 1,
  2708. SND_JACK_HEADPHONE);
  2709. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2710. }
  2711. } else if (plug_type == PLUG_TYPE_HEADPHONE) {
  2712. pr_debug("Good headphone detected, continue polling\n");
  2713. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2714. if (mbhc->mbhc_cfg->detect_extn_cable) {
  2715. if (mbhc->current_plug != plug_type)
  2716. wcd9xxx_report_plug(mbhc, 1,
  2717. SND_JACK_HEADPHONE);
  2718. } else if (mbhc->current_plug == PLUG_TYPE_NONE) {
  2719. wcd9xxx_report_plug(mbhc, 1,
  2720. SND_JACK_HEADPHONE);
  2721. }
  2722. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2723. } else if (plug_type == PLUG_TYPE_HIGH_HPH) {
  2724. pr_debug("%s: High HPH detected, continue polling\n",
  2725. __func__);
  2726. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2727. if (mbhc->mbhc_cfg->detect_extn_cable) {
  2728. if (mbhc->current_plug != plug_type)
  2729. wcd9xxx_report_plug(mbhc, 1,
  2730. SND_JACK_LINEOUT);
  2731. } else if (mbhc->current_plug == PLUG_TYPE_NONE) {
  2732. wcd9xxx_report_plug(mbhc, 1,
  2733. SND_JACK_HEADPHONE);
  2734. }
  2735. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2736. } else {
  2737. if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
  2738. pt_gnd_mic_swap_cnt++;
  2739. if (pt_gnd_mic_swap_cnt <
  2740. GND_MIC_SWAP_THRESHOLD)
  2741. continue;
  2742. else if (pt_gnd_mic_swap_cnt >
  2743. GND_MIC_SWAP_THRESHOLD) {
  2744. /*
  2745. * This is due to GND/MIC switch didn't
  2746. * work, Report unsupported plug
  2747. */
  2748. } else if (mbhc->mbhc_cfg->swap_gnd_mic) {
  2749. /*
  2750. * if switch is toggled, check again,
  2751. * otherwise report unsupported plug
  2752. */
  2753. if (mbhc->mbhc_cfg->swap_gnd_mic(codec))
  2754. continue;
  2755. }
  2756. } else
  2757. pt_gnd_mic_swap_cnt = 0;
  2758. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2759. /* Turn off override/current source */
  2760. if (current_source_enable)
  2761. wcd9xxx_turn_onoff_current_source(mbhc,
  2762. &mbhc->mbhc_bias_regs,
  2763. false, false);
  2764. else
  2765. wcd9xxx_turn_onoff_override(mbhc, false);
  2766. /*
  2767. * The valid plug also includes PLUG_TYPE_GND_MIC_SWAP
  2768. */
  2769. wcd9xxx_find_plug_and_report(mbhc, plug_type);
  2770. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2771. pr_debug("Attempt %d found correct plug %d\n", retry,
  2772. plug_type);
  2773. correction = true;
  2774. break;
  2775. }
  2776. }
  2777. highhph = false;
  2778. if (wrk_complete && plug_type == PLUG_TYPE_HIGH_HPH) {
  2779. pr_debug("%s: polling is done, still HPH, so enabling MIC trigger\n",
  2780. __func__);
  2781. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2782. wcd9xxx_find_plug_and_report(mbhc, plug_type);
  2783. highhph = true;
  2784. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2785. }
  2786. if (!correction && current_source_enable)
  2787. wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs,
  2788. false, highhph);
  2789. else if (!correction)
  2790. wcd9xxx_turn_onoff_override(mbhc, false);
  2791. wcd9xxx_onoff_ext_mclk(mbhc, false);
  2792. if (mbhc->mbhc_cfg->detect_extn_cable) {
  2793. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2794. if ((mbhc->current_plug == PLUG_TYPE_HEADPHONE &&
  2795. wrk_complete) ||
  2796. mbhc->current_plug == PLUG_TYPE_GND_MIC_SWAP ||
  2797. mbhc->current_plug == PLUG_TYPE_INVALID ||
  2798. (plug_type == PLUG_TYPE_INVALID && wrk_complete)) {
  2799. /* Enable removal detection */
  2800. wcd9xxx_cleanup_hs_polling(mbhc);
  2801. wcd9xxx_enable_hs_detect(mbhc, 0, 0, false);
  2802. }
  2803. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2804. }
  2805. pr_debug("%s: leave current_plug(%d)\n", __func__, mbhc->current_plug);
  2806. /* unlock sleep */
  2807. wcd9xxx_unlock_sleep(mbhc->resmgr->core_res);
  2808. }
  2809. static void wcd9xxx_swch_irq_handler(struct wcd9xxx_mbhc *mbhc)
  2810. {
  2811. bool insert;
  2812. bool is_removed = false;
  2813. struct snd_soc_codec *codec = mbhc->codec;
  2814. pr_debug("%s: enter\n", __func__);
  2815. mbhc->in_swch_irq_handler = true;
  2816. /* Wait here for debounce time */
  2817. usleep_range(SWCH_IRQ_DEBOUNCE_TIME_US, SWCH_IRQ_DEBOUNCE_TIME_US);
  2818. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  2819. /* cancel pending button press */
  2820. if (wcd9xxx_cancel_btn_work(mbhc))
  2821. pr_debug("%s: button press is canceled\n", __func__);
  2822. insert = !wcd9xxx_swch_level_remove(mbhc);
  2823. pr_debug("%s: Current plug type %d, insert %d\n", __func__,
  2824. mbhc->current_plug, insert);
  2825. if ((mbhc->current_plug == PLUG_TYPE_NONE) && insert) {
  2826. mbhc->lpi_enabled = false;
  2827. wmb();
  2828. /* cancel detect plug */
  2829. wcd9xxx_cancel_hs_detect_plug(mbhc,
  2830. &mbhc->correct_plug_swch);
  2831. if ((mbhc->current_plug != PLUG_TYPE_NONE) &&
  2832. (mbhc->current_plug != PLUG_TYPE_HIGH_HPH) &&
  2833. !(snd_soc_read(codec, WCD9XXX_A_MBHC_INSERT_DETECT) &
  2834. (1 << 1))) {
  2835. pr_debug("%s: current plug: %d\n", __func__,
  2836. mbhc->current_plug);
  2837. goto exit;
  2838. }
  2839. /* Disable Mic Bias pull down and HPH Switch to GND */
  2840. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01,
  2841. 0x00);
  2842. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x01, 0x00);
  2843. wcd9xxx_mbhc_detect_plug_type(mbhc);
  2844. } else if ((mbhc->current_plug != PLUG_TYPE_NONE) && !insert) {
  2845. mbhc->lpi_enabled = false;
  2846. wmb();
  2847. /* cancel detect plug */
  2848. wcd9xxx_cancel_hs_detect_plug(mbhc,
  2849. &mbhc->correct_plug_swch);
  2850. if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
  2851. wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
  2852. is_removed = true;
  2853. } else if (mbhc->current_plug == PLUG_TYPE_GND_MIC_SWAP) {
  2854. wcd9xxx_report_plug(mbhc, 0, SND_JACK_UNSUPPORTED);
  2855. is_removed = true;
  2856. } else if (mbhc->current_plug == PLUG_TYPE_HEADSET) {
  2857. wcd9xxx_pause_hs_polling(mbhc);
  2858. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  2859. wcd9xxx_cleanup_hs_polling(mbhc);
  2860. wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET);
  2861. is_removed = true;
  2862. } else if (mbhc->current_plug == PLUG_TYPE_HIGH_HPH) {
  2863. wcd9xxx_report_plug(mbhc, 0, SND_JACK_LINEOUT);
  2864. is_removed = true;
  2865. } else if (mbhc->current_plug == PLUG_TYPE_ANC_HEADPHONE) {
  2866. wcd9xxx_pause_hs_polling(mbhc);
  2867. wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false);
  2868. wcd9xxx_cleanup_hs_polling(mbhc);
  2869. wcd9xxx_report_plug(mbhc, 0, SND_JACK_ANC_HEADPHONE);
  2870. is_removed = true;
  2871. }
  2872. if (is_removed) {
  2873. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  2874. 0x00);
  2875. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  2876. 0x02, 0x00);
  2877. /* Enable Mic Bias pull down and HPH Switch to GND */
  2878. snd_soc_update_bits(codec,
  2879. mbhc->mbhc_bias_regs.ctl_reg, 0x01,
  2880. 0x01);
  2881. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x01,
  2882. 0x01);
  2883. /* Make sure mic trigger is turned off */
  2884. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg,
  2885. 0x01, 0x01);
  2886. snd_soc_update_bits(codec,
  2887. mbhc->mbhc_bias_regs.mbhc_reg,
  2888. 0x90, 0x00);
  2889. /* Reset MBHC State Machine */
  2890. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
  2891. 0x08, 0x08);
  2892. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL,
  2893. 0x08, 0x00);
  2894. /* Turn off override */
  2895. wcd9xxx_turn_onoff_override(mbhc, false);
  2896. }
  2897. }
  2898. exit:
  2899. mbhc->in_swch_irq_handler = false;
  2900. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  2901. pr_debug("%s: leave\n", __func__);
  2902. }
  2903. static irqreturn_t wcd9xxx_mech_plug_detect_irq(int irq, void *data)
  2904. {
  2905. int r = IRQ_HANDLED;
  2906. struct wcd9xxx_mbhc *mbhc = data;
  2907. pr_debug("%s: enter\n", __func__);
  2908. if (unlikely(wcd9xxx_lock_sleep(mbhc->resmgr->core_res) == false)) {
  2909. pr_warn("%s: failed to hold suspend\n", __func__);
  2910. r = IRQ_NONE;
  2911. } else {
  2912. /* Call handler */
  2913. wcd9xxx_swch_irq_handler(mbhc);
  2914. wcd9xxx_unlock_sleep(mbhc->resmgr->core_res);
  2915. }
  2916. pr_debug("%s: leave %d\n", __func__, r);
  2917. return r;
  2918. }
  2919. static int wcd9xxx_is_false_press(struct wcd9xxx_mbhc *mbhc)
  2920. {
  2921. s16 mb_v;
  2922. int i = 0;
  2923. int r = 0;
  2924. const s16 v_ins_hu =
  2925. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_HU);
  2926. const s16 v_ins_h =
  2927. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_H);
  2928. const s16 v_b1_hu =
  2929. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_HU);
  2930. const s16 v_b1_h =
  2931. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_H);
  2932. const unsigned long timeout =
  2933. jiffies + msecs_to_jiffies(BTN_RELEASE_DEBOUNCE_TIME_MS);
  2934. while (time_before(jiffies, timeout)) {
  2935. /*
  2936. * This function needs to run measurements just few times during
  2937. * release debounce time. Make 1ms interval to avoid
  2938. * unnecessary excessive measurements.
  2939. */
  2940. usleep_range(1000, 1000 + WCD9XXX_USLEEP_RANGE_MARGIN_US);
  2941. if (i == 0) {
  2942. mb_v = wcd9xxx_codec_sta_dce(mbhc, 0, true);
  2943. pr_debug("%s: STA[0]: %d,%d\n", __func__, mb_v,
  2944. wcd9xxx_codec_sta_dce_v(mbhc, 0, mb_v));
  2945. if (mb_v < v_b1_hu || mb_v > v_ins_hu) {
  2946. r = 1;
  2947. break;
  2948. }
  2949. } else {
  2950. mb_v = wcd9xxx_codec_sta_dce(mbhc, 1, true);
  2951. pr_debug("%s: DCE[%d]: %d,%d\n", __func__, i, mb_v,
  2952. wcd9xxx_codec_sta_dce_v(mbhc, 1, mb_v));
  2953. if (mb_v < v_b1_h || mb_v > v_ins_h) {
  2954. r = 1;
  2955. break;
  2956. }
  2957. }
  2958. i++;
  2959. }
  2960. return r;
  2961. }
  2962. /* called under codec_resource_lock acquisition */
  2963. static int wcd9xxx_determine_button(const struct wcd9xxx_mbhc *mbhc,
  2964. const s32 micmv)
  2965. {
  2966. s16 *v_btn_low, *v_btn_high;
  2967. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  2968. int i, btn = -1;
  2969. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  2970. v_btn_low = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
  2971. MBHC_BTN_DET_V_BTN_LOW);
  2972. v_btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
  2973. MBHC_BTN_DET_V_BTN_HIGH);
  2974. for (i = 0; i < btn_det->num_btn; i++) {
  2975. if ((v_btn_low[i] <= micmv) && (v_btn_high[i] >= micmv)) {
  2976. btn = i;
  2977. break;
  2978. }
  2979. }
  2980. if (btn == -1)
  2981. pr_debug("%s: couldn't find button number for mic mv %d\n",
  2982. __func__, micmv);
  2983. return btn;
  2984. }
  2985. static int wcd9xxx_get_button_mask(const int btn)
  2986. {
  2987. int mask = 0;
  2988. switch (btn) {
  2989. case 0:
  2990. mask = SND_JACK_BTN_0;
  2991. break;
  2992. case 1:
  2993. mask = SND_JACK_BTN_1;
  2994. break;
  2995. case 2:
  2996. mask = SND_JACK_BTN_2;
  2997. break;
  2998. case 3:
  2999. mask = SND_JACK_BTN_3;
  3000. break;
  3001. case 4:
  3002. mask = SND_JACK_BTN_4;
  3003. break;
  3004. case 5:
  3005. mask = SND_JACK_BTN_5;
  3006. break;
  3007. case 6:
  3008. mask = SND_JACK_BTN_6;
  3009. break;
  3010. case 7:
  3011. mask = SND_JACK_BTN_7;
  3012. break;
  3013. }
  3014. return mask;
  3015. }
  3016. static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z,
  3017. struct mbhc_micbias_regs *micb_regs,
  3018. bool norel_detection)
  3019. {
  3020. s16 reg0, reg1;
  3021. int change;
  3022. struct snd_soc_codec *codec = mbhc->codec;
  3023. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  3024. /* Pull down micbias to ground and disconnect vddio switch */
  3025. reg0 = snd_soc_read(codec, micb_regs->ctl_reg);
  3026. snd_soc_update_bits(codec, micb_regs->ctl_reg, 0x81, 0x1);
  3027. reg1 = snd_soc_read(codec, micb_regs->mbhc_reg);
  3028. snd_soc_update_bits(codec, micb_regs->mbhc_reg, 1 << 7, 0);
  3029. /* Disconnect override from micbias */
  3030. change = snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4,
  3031. 1 << 0);
  3032. usleep_range(1000, 1000 + 1000);
  3033. if (sta_z) {
  3034. *sta_z = wcd9xxx_codec_sta_dce(mbhc, 0, norel_detection);
  3035. pr_debug("%s: sta_z 0x%x\n", __func__, *sta_z & 0xFFFF);
  3036. }
  3037. if (dce_z) {
  3038. *dce_z = wcd9xxx_codec_sta_dce(mbhc, 1, norel_detection);
  3039. pr_debug("%s: dce_z 0x%x\n", __func__, *dce_z & 0xFFFF);
  3040. }
  3041. /* Connect override from micbias */
  3042. if (change)
  3043. snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4,
  3044. 1 << 4);
  3045. /* Disable pull down micbias to ground */
  3046. snd_soc_write(codec, micb_regs->mbhc_reg, reg1);
  3047. snd_soc_write(codec, micb_regs->ctl_reg, reg0);
  3048. }
  3049. /*
  3050. * This function recalibrates dce_z and sta_z parameters.
  3051. * No release detection will be false when this function is
  3052. * used.
  3053. */
  3054. void wcd9xxx_update_z(struct wcd9xxx_mbhc *mbhc)
  3055. {
  3056. const u16 sta_z = mbhc->mbhc_data.sta_z;
  3057. const u16 dce_z = mbhc->mbhc_data.dce_z;
  3058. wcd9xxx_get_z(mbhc, &mbhc->mbhc_data.dce_z, &mbhc->mbhc_data.sta_z,
  3059. &mbhc->mbhc_bias_regs, false);
  3060. pr_debug("%s: sta_z 0x%x,dce_z 0x%x -> sta_z 0x%x,dce_z 0x%x\n",
  3061. __func__, sta_z & 0xFFFF, dce_z & 0xFFFF,
  3062. mbhc->mbhc_data.sta_z & 0xFFFF,
  3063. mbhc->mbhc_data.dce_z & 0xFFFF);
  3064. wcd9xxx_mbhc_calc_thres(mbhc);
  3065. wcd9xxx_calibrate_hs_polling(mbhc);
  3066. }
  3067. /*
  3068. * wcd9xxx_update_rel_threshold : update mbhc release upper bound threshold
  3069. * to ceilmv + buffer
  3070. */
  3071. static int wcd9xxx_update_rel_threshold(struct wcd9xxx_mbhc *mbhc, int ceilmv, bool vddio)
  3072. {
  3073. u16 v_brh, v_b1_hu;
  3074. int mv;
  3075. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  3076. void *calibration = mbhc->mbhc_cfg->calibration;
  3077. struct snd_soc_codec *codec = mbhc->codec;
  3078. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(calibration);
  3079. mv = ceilmv + btn_det->v_btn_press_delta_cic;
  3080. if (vddio)
  3081. mv = scale_v_micb_vddio(mbhc, mv, true);
  3082. pr_debug("%s: reprogram vb1hu/vbrh to %dmv\n", __func__, mv);
  3083. if (mbhc->mbhc_state != MBHC_STATE_POTENTIAL_RECOVERY) {
  3084. /*
  3085. * update LSB first so mbhc hardware block
  3086. * doesn't see too low value.
  3087. */
  3088. v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
  3089. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu &
  3090. 0xFF);
  3091. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
  3092. (v_b1_hu >> 8) & 0xFF);
  3093. v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
  3094. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh &
  3095. 0xFF);
  3096. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
  3097. (v_brh >> 8) & 0xFF);
  3098. }
  3099. return 0;
  3100. }
  3101. irqreturn_t wcd9xxx_dce_handler(int irq, void *data)
  3102. {
  3103. int i, mask;
  3104. bool vddio;
  3105. u8 mbhc_status;
  3106. s16 dce_z, sta_z;
  3107. s32 stamv, stamv_s;
  3108. s16 *v_btn_high;
  3109. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  3110. int btn = -1, meas = 0;
  3111. struct wcd9xxx_mbhc *mbhc = data;
  3112. const struct wcd9xxx_mbhc_btn_detect_cfg *d =
  3113. WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  3114. short btnmeas[d->n_btn_meas + 1];
  3115. short dce[d->n_btn_meas + 1], sta;
  3116. s32 mv[d->n_btn_meas + 1], mv_s[d->n_btn_meas + 1];
  3117. struct snd_soc_codec *codec = mbhc->codec;
  3118. struct wcd9xxx_core_resource *core_res = mbhc->resmgr->core_res;
  3119. int n_btn_meas = d->n_btn_meas;
  3120. void *calibration = mbhc->mbhc_cfg->calibration;
  3121. pr_debug("%s: enter\n", __func__);
  3122. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  3123. mutex_lock(&mbhc->mbhc_lock);
  3124. mbhc_status = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_STATUS) & 0x3E;
  3125. if (mbhc->mbhc_state == MBHC_STATE_POTENTIAL_RECOVERY) {
  3126. pr_debug("%s: mbhc is being recovered, skip button press\n",
  3127. __func__);
  3128. goto done;
  3129. }
  3130. mbhc->mbhc_state = MBHC_STATE_POTENTIAL;
  3131. if (!mbhc->polling_active) {
  3132. pr_warn("%s: mbhc polling is not active, skip button press\n",
  3133. __func__);
  3134. goto done;
  3135. }
  3136. /* If switch nterrupt already kicked in, ignore button press */
  3137. if (mbhc->in_swch_irq_handler) {
  3138. pr_debug("%s: Swtich level changed, ignore button press\n",
  3139. __func__);
  3140. btn = -1;
  3141. goto done;
  3142. }
  3143. /*
  3144. * setup internal micbias if codec uses internal micbias for
  3145. * headset detection
  3146. */
  3147. if (mbhc->mbhc_cfg->use_int_rbias) {
  3148. if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
  3149. mbhc->mbhc_cb->setup_int_rbias(codec, true);
  3150. else
  3151. pr_err("%s: internal bias requested but codec did not provide callback\n",
  3152. __func__);
  3153. }
  3154. /* Measure scaled HW DCE */
  3155. vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
  3156. mbhc->mbhc_micbias_switched);
  3157. dce_z = mbhc->mbhc_data.dce_z;
  3158. sta_z = mbhc->mbhc_data.sta_z;
  3159. /* Measure scaled HW STA */
  3160. dce[0] = wcd9xxx_read_dce_result(codec);
  3161. sta = wcd9xxx_read_sta_result(codec);
  3162. if (mbhc_status != STATUS_REL_DETECTION) {
  3163. if (mbhc->mbhc_last_resume &&
  3164. !time_after(jiffies, mbhc->mbhc_last_resume + HZ)) {
  3165. pr_debug("%s: Button is released after resume\n",
  3166. __func__);
  3167. n_btn_meas = 0;
  3168. } else {
  3169. pr_debug("%s: Button is released without resume",
  3170. __func__);
  3171. if (mbhc->update_z) {
  3172. wcd9xxx_update_z(mbhc);
  3173. dce_z = mbhc->mbhc_data.dce_z;
  3174. sta_z = mbhc->mbhc_data.sta_z;
  3175. mbhc->update_z = true;
  3176. }
  3177. stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
  3178. mbhc->mbhc_data.micb_mv);
  3179. if (vddio)
  3180. stamv_s = scale_v_micb_vddio(mbhc, stamv,
  3181. false);
  3182. else
  3183. stamv_s = stamv;
  3184. mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0],
  3185. dce_z, mbhc->mbhc_data.micb_mv);
  3186. mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0],
  3187. false) : mv[0];
  3188. btn = wcd9xxx_determine_button(mbhc, mv_s[0]);
  3189. if (btn != wcd9xxx_determine_button(mbhc, stamv_s))
  3190. btn = -1;
  3191. goto done;
  3192. }
  3193. }
  3194. for (meas = 1; ((d->n_btn_meas) && (meas < (d->n_btn_meas + 1)));
  3195. meas++)
  3196. dce[meas] = wcd9xxx_codec_sta_dce(mbhc, 1, false);
  3197. if (mbhc->update_z) {
  3198. wcd9xxx_update_z(mbhc);
  3199. dce_z = mbhc->mbhc_data.dce_z;
  3200. sta_z = mbhc->mbhc_data.sta_z;
  3201. mbhc->update_z = true;
  3202. }
  3203. stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
  3204. mbhc->mbhc_data.micb_mv);
  3205. if (vddio)
  3206. stamv_s = scale_v_micb_vddio(mbhc, stamv, false);
  3207. else
  3208. stamv_s = stamv;
  3209. pr_info("%s: Meas HW - STA 0x%x,%d,%d\n", __func__,
  3210. sta & 0xFFFF, stamv, stamv_s);
  3211. /* determine pressed button */
  3212. mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0], dce_z,
  3213. mbhc->mbhc_data.micb_mv);
  3214. mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0], false) : mv[0];
  3215. btnmeas[0] = wcd9xxx_determine_button(mbhc, mv_s[0]);
  3216. pr_info("%s: Meas HW - DCE 0x%x,%d,%d button %d\n", __func__,
  3217. dce[0] & 0xFFFF, mv[0], mv_s[0], btnmeas[0]);
  3218. if (n_btn_meas == 0)
  3219. btn = btnmeas[0];
  3220. for (meas = 1; (n_btn_meas && d->n_btn_meas &&
  3221. (meas < (d->n_btn_meas + 1))); meas++) {
  3222. mv[meas] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[meas], dce_z,
  3223. mbhc->mbhc_data.micb_mv);
  3224. mv_s[meas] = vddio ? scale_v_micb_vddio(mbhc, mv[meas], false) :
  3225. mv[meas];
  3226. btnmeas[meas] = wcd9xxx_determine_button(mbhc, mv_s[meas]);
  3227. pr_info("%s: Meas %d - DCE 0x%x,%d,%d button %d\n",
  3228. __func__, meas, dce[meas] & 0xFFFF, mv[meas],
  3229. mv_s[meas], btnmeas[meas]);
  3230. /*
  3231. * if large enough measurements are collected,
  3232. * start to check if last all n_btn_con measurements were
  3233. * in same button low/high range
  3234. */
  3235. if (meas + 1 >= d->n_btn_con) {
  3236. for (i = 0; i < d->n_btn_con; i++)
  3237. if ((btnmeas[meas] < 0) ||
  3238. (btnmeas[meas] != btnmeas[meas - i]))
  3239. break;
  3240. if (i == d->n_btn_con) {
  3241. /* button pressed */
  3242. btn = btnmeas[meas];
  3243. break;
  3244. } else if ((n_btn_meas - meas) < (d->n_btn_con - 1)) {
  3245. /*
  3246. * if left measurements are less than n_btn_con,
  3247. * it's impossible to find button number
  3248. */
  3249. break;
  3250. }
  3251. }
  3252. }
  3253. if (btn >= 0) {
  3254. if (mbhc->in_swch_irq_handler) {
  3255. pr_debug(
  3256. "%s: Switch irq triggered, ignore button press\n",
  3257. __func__);
  3258. goto done;
  3259. }
  3260. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(calibration);
  3261. v_btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
  3262. MBHC_BTN_DET_V_BTN_HIGH);
  3263. WARN_ON(btn >= btn_det->num_btn);
  3264. /* reprogram release threshold to catch voltage ramp up early */
  3265. wcd9xxx_update_rel_threshold(mbhc, v_btn_high[btn], vddio);
  3266. mask = wcd9xxx_get_button_mask(btn);
  3267. mbhc->buttons_pressed |= mask;
  3268. wcd9xxx_lock_sleep(core_res);
  3269. if (schedule_delayed_work(&mbhc->mbhc_btn_dwork,
  3270. msecs_to_jiffies(400)) == 0) {
  3271. WARN(1, "Button pressed twice without release event\n");
  3272. wcd9xxx_unlock_sleep(core_res);
  3273. }
  3274. } else {
  3275. pr_debug("%s: bogus button press, too short press?\n",
  3276. __func__);
  3277. }
  3278. done:
  3279. pr_debug("%s: leave\n", __func__);
  3280. mutex_unlock(&mbhc->mbhc_lock);
  3281. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  3282. return IRQ_HANDLED;
  3283. }
  3284. static irqreturn_t wcd9xxx_release_handler(int irq, void *data)
  3285. {
  3286. int ret;
  3287. bool waitdebounce = true;
  3288. struct wcd9xxx_mbhc *mbhc = data;
  3289. pr_debug("%s: enter\n", __func__);
  3290. WCD9XXX_BCL_LOCK(mbhc->resmgr);
  3291. mbhc->mbhc_state = MBHC_STATE_RELEASE;
  3292. if (mbhc->buttons_pressed & WCD9XXX_JACK_BUTTON_MASK) {
  3293. ret = wcd9xxx_cancel_btn_work(mbhc);
  3294. if (ret == 0) {
  3295. pr_debug("%s: Reporting long button release event\n",
  3296. __func__);
  3297. wcd9xxx_jack_report(mbhc, &mbhc->button_jack, 0,
  3298. mbhc->buttons_pressed);
  3299. } else {
  3300. if (wcd9xxx_is_false_press(mbhc)) {
  3301. pr_debug("%s: Fake button press interrupt\n",
  3302. __func__);
  3303. } else {
  3304. if (mbhc->in_swch_irq_handler) {
  3305. pr_debug("%s: Switch irq kicked in, ignore\n",
  3306. __func__);
  3307. } else {
  3308. pr_info("%s: Reporting btn press\n",
  3309. __func__);
  3310. wcd9xxx_jack_report(mbhc,
  3311. &mbhc->button_jack,
  3312. mbhc->buttons_pressed,
  3313. mbhc->buttons_pressed);
  3314. pr_info("%s: Reporting btn release\n",
  3315. __func__);
  3316. wcd9xxx_jack_report(mbhc,
  3317. &mbhc->button_jack,
  3318. 0, mbhc->buttons_pressed);
  3319. waitdebounce = false;
  3320. }
  3321. }
  3322. }
  3323. mbhc->buttons_pressed &= ~WCD9XXX_JACK_BUTTON_MASK;
  3324. }
  3325. wcd9xxx_calibrate_hs_polling(mbhc);
  3326. if (waitdebounce)
  3327. msleep(SWCH_REL_DEBOUNCE_TIME_MS);
  3328. wcd9xxx_start_hs_polling(mbhc);
  3329. pr_debug("%s: leave\n", __func__);
  3330. WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
  3331. return IRQ_HANDLED;
  3332. }
  3333. static irqreturn_t wcd9xxx_hphl_ocp_irq(int irq, void *data)
  3334. {
  3335. struct wcd9xxx_mbhc *mbhc = data;
  3336. struct snd_soc_codec *codec;
  3337. pr_info("%s: received HPHL OCP irq\n", __func__);
  3338. if (mbhc) {
  3339. codec = mbhc->codec;
  3340. if ((mbhc->hphlocp_cnt < OCP_ATTEMPT) &&
  3341. (!mbhc->hphrocp_cnt)) {
  3342. pr_info("%s: retry\n", __func__);
  3343. mbhc->hphlocp_cnt++;
  3344. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL,
  3345. 0x10, 0x00);
  3346. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL,
  3347. 0x10, 0x10);
  3348. } else {
  3349. wcd9xxx_disable_irq(mbhc->resmgr->core_res,
  3350. mbhc->intr_ids->hph_left_ocp);
  3351. mbhc->hph_status |= SND_JACK_OC_HPHL;
  3352. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
  3353. mbhc->hph_status,
  3354. WCD9XXX_JACK_MASK);
  3355. }
  3356. } else {
  3357. pr_err("%s: Bad wcd9xxx private data\n", __func__);
  3358. }
  3359. return IRQ_HANDLED;
  3360. }
  3361. static irqreturn_t wcd9xxx_hphr_ocp_irq(int irq, void *data)
  3362. {
  3363. struct wcd9xxx_mbhc *mbhc = data;
  3364. struct snd_soc_codec *codec;
  3365. pr_info("%s: received HPHR OCP irq\n", __func__);
  3366. codec = mbhc->codec;
  3367. if ((mbhc->hphrocp_cnt < OCP_ATTEMPT) &&
  3368. (!mbhc->hphlocp_cnt)) {
  3369. pr_info("%s: retry\n", __func__);
  3370. mbhc->hphrocp_cnt++;
  3371. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
  3372. 0x00);
  3373. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
  3374. 0x10);
  3375. } else {
  3376. wcd9xxx_disable_irq(mbhc->resmgr->core_res,
  3377. mbhc->intr_ids->hph_right_ocp);
  3378. mbhc->hph_status |= SND_JACK_OC_HPHR;
  3379. wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
  3380. mbhc->hph_status, WCD9XXX_JACK_MASK);
  3381. }
  3382. return IRQ_HANDLED;
  3383. }
  3384. static int wcd9xxx_acdb_mclk_index(const int rate)
  3385. {
  3386. if (rate == MCLK_RATE_12288KHZ)
  3387. return 0;
  3388. else if (rate == MCLK_RATE_9600KHZ)
  3389. return 1;
  3390. else {
  3391. BUG_ON(1);
  3392. return -EINVAL;
  3393. }
  3394. }
  3395. static void wcd9xxx_update_mbhc_clk_rate(struct wcd9xxx_mbhc *mbhc, u32 rate)
  3396. {
  3397. u32 dce_wait, sta_wait;
  3398. u8 ncic, nmeas, navg;
  3399. void *calibration;
  3400. u8 *n_cic, *n_ready;
  3401. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  3402. u8 npoll = 4, nbounce_wait = 30;
  3403. struct snd_soc_codec *codec = mbhc->codec;
  3404. int idx = wcd9xxx_acdb_mclk_index(rate);
  3405. int idxmclk = wcd9xxx_acdb_mclk_index(mbhc->mbhc_cfg->mclk_rate);
  3406. pr_debug("%s: Updating clock rate dependents, rate = %u\n", __func__,
  3407. rate);
  3408. calibration = mbhc->mbhc_cfg->calibration;
  3409. /*
  3410. * First compute the DCE / STA wait times depending on tunable
  3411. * parameters. The value is computed in microseconds
  3412. */
  3413. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(calibration);
  3414. n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_det, MBHC_BTN_DET_N_READY);
  3415. n_cic = wcd9xxx_mbhc_cal_btn_det_mp(btn_det, MBHC_BTN_DET_N_CIC);
  3416. nmeas = WCD9XXX_MBHC_CAL_BTN_DET_PTR(calibration)->n_meas;
  3417. navg = WCD9XXX_MBHC_CAL_GENERAL_PTR(calibration)->mbhc_navg;
  3418. /* ncic stays with the same what we had during calibration */
  3419. ncic = n_cic[idxmclk];
  3420. dce_wait = (1000 * 512 * ncic * (nmeas + 1)) / (rate / 1000);
  3421. sta_wait = (1000 * 128 * (navg + 1)) / (rate / 1000);
  3422. mbhc->mbhc_data.t_dce = dce_wait;
  3423. /* give extra margin to sta for safety */
  3424. mbhc->mbhc_data.t_sta = sta_wait + 250;
  3425. mbhc->mbhc_data.t_sta_dce = ((1000 * 256) / (rate / 1000) *
  3426. n_ready[idx]) + 10;
  3427. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_TIMER_B1_CTL, n_ready[idx]);
  3428. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_TIMER_B6_CTL, ncic);
  3429. if (rate == MCLK_RATE_12288KHZ) {
  3430. npoll = 4;
  3431. nbounce_wait = 30;
  3432. } else if (rate == MCLK_RATE_9600KHZ) {
  3433. npoll = 3;
  3434. nbounce_wait = 23;
  3435. }
  3436. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_TIMER_B2_CTL, npoll);
  3437. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_TIMER_B3_CTL, nbounce_wait);
  3438. pr_debug("%s: leave\n", __func__);
  3439. }
  3440. static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
  3441. {
  3442. u8 cfilt_mode;
  3443. u16 reg0, reg1, reg2;
  3444. struct snd_soc_codec *codec = mbhc->codec;
  3445. pr_debug("%s: enter\n", __func__);
  3446. wcd9xxx_disable_irq(mbhc->resmgr->core_res,
  3447. mbhc->intr_ids->dce_est_complete);
  3448. wcd9xxx_turn_onoff_rel_detection(codec, false);
  3449. /* t_dce and t_sta are updated by wcd9xxx_update_mbhc_clk_rate() */
  3450. WARN_ON(!mbhc->mbhc_data.t_dce);
  3451. WARN_ON(!mbhc->mbhc_data.t_sta);
  3452. /*
  3453. * LDOH and CFILT are already configured during pdata handling.
  3454. * Only need to make sure CFILT and bandgap are in Fast mode.
  3455. * Need to restore defaults once calculation is done.
  3456. *
  3457. * In case when Micbias is powered by external source, request
  3458. * turn on the external voltage source for Calibration.
  3459. */
  3460. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
  3461. mbhc->mbhc_cb->enable_mb_source(codec, true, false);
  3462. cfilt_mode = snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl);
  3463. if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
  3464. mbhc->mbhc_cb->cfilt_fast_mode(codec, mbhc);
  3465. else
  3466. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.cfilt_ctl,
  3467. 0x40, 0x00);
  3468. /*
  3469. * Micbias, CFILT, LDOH, MBHC MUX mode settings
  3470. * to perform ADC calibration
  3471. */
  3472. if (mbhc->mbhc_cb && mbhc->mbhc_cb->select_cfilt)
  3473. mbhc->mbhc_cb->select_cfilt(codec, mbhc);
  3474. else
  3475. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x60,
  3476. mbhc->mbhc_cfg->micbias << 5);
  3477. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
  3478. snd_soc_update_bits(codec, WCD9XXX_A_LDO_H_MODE_1, 0x60, 0x60);
  3479. snd_soc_write(codec, WCD9XXX_A_TX_7_MBHC_TEST_CTL, 0x78);
  3480. if (mbhc->mbhc_cb && mbhc->mbhc_cb->codec_specific_cal)
  3481. mbhc->mbhc_cb->codec_specific_cal(codec, mbhc);
  3482. else
  3483. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
  3484. 0x04, 0x04);
  3485. /* Pull down micbias to ground */
  3486. reg0 = snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg);
  3487. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 1, 1);
  3488. /* Disconnect override from micbias */
  3489. reg1 = snd_soc_read(codec, WCD9XXX_A_MAD_ANA_CTRL);
  3490. snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4, 1 << 0);
  3491. /* Connect the MUX to micbias */
  3492. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
  3493. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  3494. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  3495. else
  3496. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  3497. 0x80, 0x80);
  3498. /*
  3499. * Hardware that has external cap can delay mic bias ramping down up
  3500. * to 50ms.
  3501. */
  3502. msleep(WCD9XXX_MUX_SWITCH_READY_WAIT_MS);
  3503. /* DCE measurement for 0 voltage */
  3504. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
  3505. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
  3506. mbhc->mbhc_data.dce_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true, false);
  3507. /* compute dce_z for current source */
  3508. reg2 = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
  3509. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
  3510. WCD9XXX_MBHC_NSC_CS << 3);
  3511. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
  3512. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
  3513. mbhc->mbhc_data.dce_nsc_cs_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true,
  3514. false);
  3515. pr_debug("%s: dce_z with nsc cs: 0x%x\n", __func__,
  3516. mbhc->mbhc_data.dce_nsc_cs_z);
  3517. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, reg2);
  3518. /* STA measurement for 0 voltage */
  3519. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
  3520. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
  3521. mbhc->mbhc_data.sta_z = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
  3522. /* Restore registers */
  3523. snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
  3524. snd_soc_write(codec, WCD9XXX_A_MAD_ANA_CTRL, reg1);
  3525. /* DCE measurment for MB voltage */
  3526. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
  3527. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
  3528. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
  3529. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  3530. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  3531. else
  3532. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  3533. 0x80, 0x80);
  3534. /*
  3535. * Hardware that has external cap can delay mic bias ramping down up
  3536. * to 50ms.
  3537. */
  3538. msleep(WCD9XXX_MUX_SWITCH_READY_WAIT_MS);
  3539. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
  3540. usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
  3541. mbhc->mbhc_data.dce_mb = wcd9xxx_read_dce_result(codec);
  3542. /* STA Measurement for MB Voltage */
  3543. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
  3544. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
  3545. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
  3546. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
  3547. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  3548. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  3549. else
  3550. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  3551. 0x80, 0x80);
  3552. /*
  3553. * Hardware that has external cap can delay mic bias ramping down up
  3554. * to 50ms.
  3555. */
  3556. msleep(WCD9XXX_MUX_SWITCH_READY_WAIT_MS);
  3557. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
  3558. usleep_range(mbhc->mbhc_data.t_sta, mbhc->mbhc_data.t_sta);
  3559. mbhc->mbhc_data.sta_mb = wcd9xxx_read_sta_result(codec);
  3560. /* Restore default settings. */
  3561. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04, 0x00);
  3562. snd_soc_write(codec, mbhc->mbhc_bias_regs.cfilt_ctl, cfilt_mode);
  3563. snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
  3564. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  3565. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  3566. else
  3567. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_1,
  3568. 0x80, 0x80);
  3569. usleep_range(100, 100);
  3570. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
  3571. mbhc->mbhc_cb->enable_mb_source(codec, false, false);
  3572. wcd9xxx_enable_irq(mbhc->resmgr->core_res,
  3573. mbhc->intr_ids->dce_est_complete);
  3574. wcd9xxx_turn_onoff_rel_detection(codec, true);
  3575. pr_debug("%s: leave\n", __func__);
  3576. }
  3577. static void wcd9xxx_mbhc_setup(struct wcd9xxx_mbhc *mbhc)
  3578. {
  3579. int n;
  3580. u8 *gain;
  3581. struct wcd9xxx_mbhc_general_cfg *generic;
  3582. struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
  3583. struct snd_soc_codec *codec = mbhc->codec;
  3584. const int idx = wcd9xxx_acdb_mclk_index(mbhc->mbhc_cfg->mclk_rate);
  3585. pr_debug("%s: enter\n", __func__);
  3586. generic = WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
  3587. btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
  3588. for (n = 0; n < 8; n++) {
  3589. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_FIR_B1_CFG,
  3590. 0x07, n);
  3591. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_FIR_B2_CFG,
  3592. btn_det->c[n]);
  3593. }
  3594. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B2_CTL, 0x07,
  3595. btn_det->nc);
  3596. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL, 0x70,
  3597. generic->mbhc_nsa << 4);
  3598. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL, 0x0F,
  3599. btn_det->n_meas);
  3600. snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL,
  3601. generic->mbhc_navg);
  3602. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x80, 0x80);
  3603. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
  3604. btn_det->mbhc_nsc << 3);
  3605. if (mbhc->mbhc_cb &&
  3606. mbhc->mbhc_cb->get_cdc_type() !=
  3607. WCD9XXX_CDC_TYPE_HELICON) {
  3608. if (mbhc->resmgr->reg_addr->micb_4_mbhc)
  3609. snd_soc_update_bits(codec,
  3610. mbhc->resmgr->reg_addr->micb_4_mbhc,
  3611. 0x03, MBHC_MICBIAS2);
  3612. }
  3613. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x02, 0x02);
  3614. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_SCALING_MUX_2, 0xF0, 0xF0);
  3615. gain = wcd9xxx_mbhc_cal_btn_det_mp(btn_det, MBHC_BTN_DET_GAIN);
  3616. snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B2_CTL, 0x78,
  3617. gain[idx] << 3);
  3618. snd_soc_update_bits(codec, WCD9XXX_A_MICB_2_MBHC, 0x04, 0x04);
  3619. pr_debug("%s: leave\n", __func__);
  3620. }
  3621. static int wcd9xxx_setup_jack_detect_irq(struct wcd9xxx_mbhc *mbhc)
  3622. {
  3623. int ret = 0;
  3624. void *core_res = mbhc->resmgr->core_res;
  3625. if (mbhc->mbhc_cfg->gpio) {
  3626. ret = request_threaded_irq(mbhc->mbhc_cfg->gpio_irq, NULL,
  3627. wcd9xxx_mech_plug_detect_irq,
  3628. (IRQF_TRIGGER_RISING |
  3629. IRQF_TRIGGER_FALLING |
  3630. IRQF_DISABLED),
  3631. "headset detect", mbhc);
  3632. if (ret) {
  3633. pr_err("%s: Failed to request gpio irq %d\n", __func__,
  3634. mbhc->mbhc_cfg->gpio_irq);
  3635. } else {
  3636. ret = enable_irq_wake(mbhc->mbhc_cfg->gpio_irq);
  3637. if (ret)
  3638. pr_err("%s: Failed to enable wake up irq %d\n",
  3639. __func__, mbhc->mbhc_cfg->gpio_irq);
  3640. }
  3641. } else if (mbhc->mbhc_cfg->insert_detect) {
  3642. /* Enable HPHL_10K_SW */
  3643. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_RX_HPH_OCP_CTL,
  3644. 1 << 1, 1 << 1);
  3645. ret = wcd9xxx_request_irq(core_res,
  3646. mbhc->intr_ids->hs_jack_switch,
  3647. wcd9xxx_mech_plug_detect_irq,
  3648. "Jack Detect",
  3649. mbhc);
  3650. if (ret)
  3651. pr_err("%s: Failed to request insert detect irq %d\n",
  3652. __func__, mbhc->intr_ids->hs_jack_switch);
  3653. }
  3654. return ret;
  3655. }
  3656. static int wcd9xxx_init_and_calibrate(struct wcd9xxx_mbhc *mbhc)
  3657. {
  3658. int ret = 0;
  3659. struct snd_soc_codec *codec = mbhc->codec;
  3660. pr_debug("%s: enter\n", __func__);
  3661. /* Enable MCLK during calibration */
  3662. wcd9xxx_onoff_ext_mclk(mbhc, true);
  3663. wcd9xxx_mbhc_setup(mbhc);
  3664. wcd9xxx_mbhc_cal(mbhc);
  3665. wcd9xxx_mbhc_calc_thres(mbhc);
  3666. wcd9xxx_onoff_ext_mclk(mbhc, false);
  3667. wcd9xxx_calibrate_hs_polling(mbhc);
  3668. /* Enable Mic Bias pull down and HPH Switch to GND */
  3669. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x01);
  3670. snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x01, 0x01);
  3671. INIT_WORK(&mbhc->correct_plug_swch, wcd9xxx_correct_swch_plug);
  3672. if (!IS_ERR_VALUE(ret)) {
  3673. snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
  3674. 0x10);
  3675. wcd9xxx_enable_irq(mbhc->resmgr->core_res,
  3676. mbhc->intr_ids->hph_left_ocp);
  3677. wcd9xxx_enable_irq(mbhc->resmgr->core_res,
  3678. mbhc->intr_ids->hph_right_ocp);
  3679. /* Initialize mechanical mbhc */
  3680. ret = wcd9xxx_setup_jack_detect_irq(mbhc);
  3681. if (!ret && mbhc->mbhc_cfg->gpio) {
  3682. /* Requested with IRQF_DISABLED */
  3683. enable_irq(mbhc->mbhc_cfg->gpio_irq);
  3684. /* Bootup time detection */
  3685. wcd9xxx_swch_irq_handler(mbhc);
  3686. } else if (!ret && mbhc->mbhc_cfg->insert_detect) {
  3687. pr_debug("%s: Setting up codec own insert detection\n",
  3688. __func__);
  3689. /* Setup for insertion detection */
  3690. wcd9xxx_insert_detect_setup(mbhc, true);
  3691. }
  3692. }
  3693. pr_debug("%s: leave\n", __func__);
  3694. return ret;
  3695. }
  3696. static void wcd9xxx_mbhc_fw_read(struct work_struct *work)
  3697. {
  3698. struct delayed_work *dwork;
  3699. struct wcd9xxx_mbhc *mbhc;
  3700. struct snd_soc_codec *codec;
  3701. const struct firmware *fw;
  3702. struct firmware_cal *fw_data = NULL;
  3703. int ret = -1, retry = 0;
  3704. bool use_default_cal = false;
  3705. dwork = to_delayed_work(work);
  3706. mbhc = container_of(dwork, struct wcd9xxx_mbhc, mbhc_firmware_dwork);
  3707. codec = mbhc->codec;
  3708. while (retry < FW_READ_ATTEMPTS) {
  3709. retry++;
  3710. pr_debug("%s:Attempt %d to request MBHC firmware\n",
  3711. __func__, retry);
  3712. if (mbhc->mbhc_cb->get_hwdep_fw_cal)
  3713. fw_data = mbhc->mbhc_cb->get_hwdep_fw_cal(codec,
  3714. WCD9XXX_MBHC_CAL);
  3715. if (!fw_data)
  3716. ret = request_firmware(&fw, "wcd9320/wcd9320_mbhc.bin",
  3717. codec->dev);
  3718. /*
  3719. * if request_firmware and hwdep cal both fail then
  3720. * retry for few times before bailing out
  3721. */
  3722. if ((ret != 0) && !fw_data) {
  3723. usleep_range(FW_READ_TIMEOUT, FW_READ_TIMEOUT);
  3724. } else {
  3725. pr_info("%s: MBHC Firmware read succesful\n", __func__);
  3726. break;
  3727. }
  3728. }
  3729. if (!fw_data)
  3730. pr_debug("%s: using request_firmware\n", __func__);
  3731. else
  3732. pr_debug("%s: using hwdep cal\n", __func__);
  3733. if (ret != 0 && !fw_data) {
  3734. pr_err("%s: Cannot load MBHC firmware use default cal\n",
  3735. __func__);
  3736. use_default_cal = true;
  3737. }
  3738. if (!use_default_cal) {
  3739. const void *data;
  3740. size_t size;
  3741. if (fw_data) {
  3742. data = fw_data->data;
  3743. size = fw_data->size;
  3744. } else {
  3745. data = fw->data;
  3746. size = fw->size;
  3747. }
  3748. if (wcd9xxx_mbhc_fw_validate(data, size) == false) {
  3749. pr_err("%s: Invalid MBHC cal data size use default cal\n",
  3750. __func__);
  3751. if (!fw_data)
  3752. release_firmware(fw);
  3753. } else {
  3754. if (fw_data) {
  3755. mbhc->mbhc_cfg->calibration =
  3756. (void *)fw_data->data;
  3757. mbhc->mbhc_cal = fw_data;
  3758. } else {
  3759. mbhc->mbhc_cfg->calibration =
  3760. (void *)fw->data;
  3761. mbhc->mbhc_fw = fw;
  3762. }
  3763. }
  3764. }
  3765. (void) wcd9xxx_init_and_calibrate(mbhc);
  3766. }
  3767. #ifdef CONFIG_DEBUG_FS
  3768. ssize_t codec_mbhc_debug_read(struct file *file, char __user *buf,
  3769. size_t count, loff_t *pos)
  3770. {
  3771. const int size = 768;
  3772. char buffer[size];
  3773. int n = 0;
  3774. struct wcd9xxx_mbhc *mbhc = file->private_data;
  3775. const struct mbhc_internal_cal_data *p = &mbhc->mbhc_data;
  3776. const s16 v_ins_hu =
  3777. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_HU);
  3778. const s16 v_ins_h =
  3779. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_H);
  3780. const s16 v_b1_hu =
  3781. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_HU);
  3782. const s16 v_b1_h =
  3783. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_B1_H);
  3784. const s16 v_br_h =
  3785. wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_BR_H);
  3786. n = scnprintf(buffer, size - n, "dce_z = %x(%dmv)\n",
  3787. p->dce_z, wcd9xxx_codec_sta_dce_v(mbhc, 1, p->dce_z));
  3788. n += scnprintf(buffer + n, size - n, "dce_mb = %x(%dmv)\n",
  3789. p->dce_mb, wcd9xxx_codec_sta_dce_v(mbhc, 1, p->dce_mb));
  3790. n += scnprintf(buffer + n, size - n, "dce_nsc_cs_z = %x(%dmv)\n",
  3791. p->dce_nsc_cs_z,
  3792. __wcd9xxx_codec_sta_dce_v(mbhc, 1, p->dce_nsc_cs_z,
  3793. p->dce_nsc_cs_z,
  3794. VDDIO_MICBIAS_MV));
  3795. n += scnprintf(buffer + n, size - n, "sta_z = %x(%dmv)\n",
  3796. p->sta_z, wcd9xxx_codec_sta_dce_v(mbhc, 0, p->sta_z));
  3797. n += scnprintf(buffer + n, size - n, "sta_mb = %x(%dmv)\n",
  3798. p->sta_mb, wcd9xxx_codec_sta_dce_v(mbhc, 0, p->sta_mb));
  3799. n += scnprintf(buffer + n, size - n, "t_dce = %d\n", p->t_dce);
  3800. n += scnprintf(buffer + n, size - n, "t_sta = %d\n", p->t_sta);
  3801. n += scnprintf(buffer + n, size - n, "micb_mv = %dmv\n", p->micb_mv);
  3802. n += scnprintf(buffer + n, size - n, "v_ins_hu = %x(%dmv)\n",
  3803. v_ins_hu, wcd9xxx_codec_sta_dce_v(mbhc, 0, v_ins_hu));
  3804. n += scnprintf(buffer + n, size - n, "v_ins_h = %x(%dmv)\n",
  3805. v_ins_h, wcd9xxx_codec_sta_dce_v(mbhc, 1, v_ins_h));
  3806. n += scnprintf(buffer + n, size - n, "v_b1_hu = %x(%dmv)\n",
  3807. v_b1_hu, wcd9xxx_codec_sta_dce_v(mbhc, 0, v_b1_hu));
  3808. n += scnprintf(buffer + n, size - n, "v_b1_h = %x(%dmv)\n",
  3809. v_b1_h, wcd9xxx_codec_sta_dce_v(mbhc, 1, v_b1_h));
  3810. n += scnprintf(buffer + n, size - n, "v_brh = %x(%dmv)\n",
  3811. v_br_h, wcd9xxx_codec_sta_dce_v(mbhc, 1, v_br_h));
  3812. n += scnprintf(buffer + n, size - n, "v_brl = %x(%dmv)\n", p->v_brl,
  3813. wcd9xxx_codec_sta_dce_v(mbhc, 0, p->v_brl));
  3814. n += scnprintf(buffer + n, size - n, "v_no_mic = %x(%dmv)\n",
  3815. p->v_no_mic,
  3816. wcd9xxx_codec_sta_dce_v(mbhc, 0, p->v_no_mic));
  3817. n += scnprintf(buffer + n, size - n, "v_inval_ins_low = %d\n",
  3818. p->v_inval_ins_low);
  3819. n += scnprintf(buffer + n, size - n, "v_inval_ins_high = %d\n",
  3820. p->v_inval_ins_high);
  3821. n += scnprintf(buffer + n, size - n, "Insert detect insert = %d\n",
  3822. !wcd9xxx_swch_level_remove(mbhc));
  3823. buffer[n] = 0;
  3824. return simple_read_from_buffer(buf, count, pos, buffer, n);
  3825. }
  3826. static int codec_debug_open(struct inode *inode, struct file *file)
  3827. {
  3828. file->private_data = inode->i_private;
  3829. return 0;
  3830. }
  3831. static ssize_t codec_debug_write(struct file *filp,
  3832. const char __user *ubuf, size_t cnt,
  3833. loff_t *ppos)
  3834. {
  3835. char lbuf[32];
  3836. char *buf;
  3837. int rc;
  3838. struct wcd9xxx_mbhc *mbhc = filp->private_data;
  3839. if (cnt > sizeof(lbuf) - 1)
  3840. return -EINVAL;
  3841. rc = copy_from_user(lbuf, ubuf, cnt);
  3842. if (rc)
  3843. return -EFAULT;
  3844. lbuf[cnt] = '\0';
  3845. buf = (char *)lbuf;
  3846. mbhc->no_mic_headset_override = (*strsep(&buf, " ") == '0') ?
  3847. false : true;
  3848. return rc;
  3849. }
  3850. static const struct file_operations mbhc_trrs_debug_ops = {
  3851. .open = codec_debug_open,
  3852. .write = codec_debug_write,
  3853. };
  3854. static const struct file_operations mbhc_debug_ops = {
  3855. .open = codec_debug_open,
  3856. .read = codec_mbhc_debug_read,
  3857. };
  3858. static void wcd9xxx_init_debugfs(struct wcd9xxx_mbhc *mbhc)
  3859. {
  3860. mbhc->debugfs_poke =
  3861. debugfs_create_file("TRRS", S_IFREG | S_IRUGO, NULL, mbhc,
  3862. &mbhc_trrs_debug_ops);
  3863. mbhc->debugfs_mbhc =
  3864. debugfs_create_file("wcd9xxx_mbhc", S_IFREG | S_IRUGO,
  3865. NULL, mbhc, &mbhc_debug_ops);
  3866. }
  3867. static void wcd9xxx_cleanup_debugfs(struct wcd9xxx_mbhc *mbhc)
  3868. {
  3869. debugfs_remove(mbhc->debugfs_poke);
  3870. debugfs_remove(mbhc->debugfs_mbhc);
  3871. }
  3872. #else
  3873. static void wcd9xxx_init_debugfs(struct wcd9xxx_mbhc *mbhc)
  3874. {
  3875. }
  3876. static void wcd9xxx_cleanup_debugfs(struct wcd9xxx_mbhc *mbhc)
  3877. {
  3878. }
  3879. #endif
  3880. int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc,
  3881. struct wcd9xxx_mbhc_config *mbhc_cfg)
  3882. {
  3883. int rc = 0;
  3884. struct snd_soc_codec *codec = mbhc->codec;
  3885. pr_debug("%s: enter\n", __func__);
  3886. if (!codec) {
  3887. pr_err("%s: no codec\n", __func__);
  3888. return -EINVAL;
  3889. }
  3890. if (mbhc_cfg->mclk_rate != MCLK_RATE_12288KHZ &&
  3891. mbhc_cfg->mclk_rate != MCLK_RATE_9600KHZ) {
  3892. pr_err("Error: unsupported clock rate %d\n",
  3893. mbhc_cfg->mclk_rate);
  3894. return -EINVAL;
  3895. }
  3896. /* Save mbhc config */
  3897. mbhc->mbhc_cfg = mbhc_cfg;
  3898. /* Get HW specific mbhc registers' address */
  3899. wcd9xxx_get_mbhc_micbias_regs(mbhc, MBHC_PRIMARY_MIC_MB);
  3900. /* Get HW specific mbhc registers' address for anc */
  3901. wcd9xxx_get_mbhc_micbias_regs(mbhc, MBHC_ANC_MIC_MB);
  3902. /* Put CFILT in fast mode by default */
  3903. if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
  3904. mbhc->mbhc_cb->cfilt_fast_mode(codec, mbhc);
  3905. else
  3906. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.cfilt_ctl,
  3907. 0x40, WCD9XXX_CFILT_FAST_MODE);
  3908. /*
  3909. * setup internal micbias if codec uses internal micbias for
  3910. * headset detection
  3911. */
  3912. if (mbhc->mbhc_cfg->use_int_rbias) {
  3913. if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias) {
  3914. mbhc->mbhc_cb->setup_int_rbias(codec, true);
  3915. } else {
  3916. pr_info("%s: internal bias requested but codec did not provide callback\n",
  3917. __func__);
  3918. }
  3919. }
  3920. /*
  3921. * If codec has specific clock gating for MBHC,
  3922. * remove the clock gate
  3923. */
  3924. if (mbhc->mbhc_cb &&
  3925. mbhc->mbhc_cb->enable_clock_gate)
  3926. mbhc->mbhc_cb->enable_clock_gate(mbhc->codec, true);
  3927. if (!mbhc->mbhc_cfg->read_fw_bin ||
  3928. (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw) ||
  3929. (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_cal)) {
  3930. rc = wcd9xxx_init_and_calibrate(mbhc);
  3931. } else {
  3932. if (!mbhc->mbhc_fw || !mbhc->mbhc_cal)
  3933. schedule_delayed_work(&mbhc->mbhc_firmware_dwork,
  3934. usecs_to_jiffies(FW_READ_TIMEOUT));
  3935. else
  3936. pr_debug("%s: Skipping to read mbhc fw, 0x%p 0x%p\n",
  3937. __func__, mbhc->mbhc_fw, mbhc->mbhc_cal);
  3938. }
  3939. pr_debug("%s: leave %d\n", __func__, rc);
  3940. return rc;
  3941. }
  3942. EXPORT_SYMBOL(wcd9xxx_mbhc_start);
  3943. void wcd9xxx_mbhc_stop(struct wcd9xxx_mbhc *mbhc)
  3944. {
  3945. if (mbhc->mbhc_fw || mbhc->mbhc_cal) {
  3946. cancel_delayed_work_sync(&mbhc->mbhc_firmware_dwork);
  3947. if (!mbhc->mbhc_cal)
  3948. release_firmware(mbhc->mbhc_fw);
  3949. mbhc->mbhc_fw = NULL;
  3950. mbhc->mbhc_cal = NULL;
  3951. }
  3952. }
  3953. EXPORT_SYMBOL(wcd9xxx_mbhc_stop);
  3954. static enum wcd9xxx_micbias_num
  3955. wcd9xxx_event_to_micbias(const enum wcd9xxx_notify_event event)
  3956. {
  3957. enum wcd9xxx_micbias_num ret;
  3958. switch (event) {
  3959. case WCD9XXX_EVENT_PRE_MICBIAS_1_ON:
  3960. case WCD9XXX_EVENT_PRE_MICBIAS_1_OFF:
  3961. case WCD9XXX_EVENT_POST_MICBIAS_1_ON:
  3962. case WCD9XXX_EVENT_POST_MICBIAS_1_OFF:
  3963. ret = MBHC_MICBIAS1;
  3964. break;
  3965. case WCD9XXX_EVENT_PRE_MICBIAS_2_ON:
  3966. case WCD9XXX_EVENT_PRE_MICBIAS_2_OFF:
  3967. case WCD9XXX_EVENT_POST_MICBIAS_2_ON:
  3968. case WCD9XXX_EVENT_POST_MICBIAS_2_OFF:
  3969. ret = MBHC_MICBIAS2;
  3970. break;
  3971. case WCD9XXX_EVENT_PRE_MICBIAS_3_ON:
  3972. case WCD9XXX_EVENT_PRE_MICBIAS_3_OFF:
  3973. case WCD9XXX_EVENT_POST_MICBIAS_3_ON:
  3974. case WCD9XXX_EVENT_POST_MICBIAS_3_OFF:
  3975. ret = MBHC_MICBIAS3;
  3976. break;
  3977. case WCD9XXX_EVENT_PRE_MICBIAS_4_ON:
  3978. case WCD9XXX_EVENT_PRE_MICBIAS_4_OFF:
  3979. case WCD9XXX_EVENT_POST_MICBIAS_4_ON:
  3980. case WCD9XXX_EVENT_POST_MICBIAS_4_OFF:
  3981. ret = MBHC_MICBIAS4;
  3982. break;
  3983. default:
  3984. WARN_ONCE(1, "Cannot convert event %d to micbias\n", event);
  3985. ret = MBHC_MICBIAS_INVALID;
  3986. break;
  3987. }
  3988. return ret;
  3989. }
  3990. static int wcd9xxx_event_to_cfilt(const enum wcd9xxx_notify_event event)
  3991. {
  3992. int ret;
  3993. switch (event) {
  3994. case WCD9XXX_EVENT_PRE_CFILT_1_OFF:
  3995. case WCD9XXX_EVENT_POST_CFILT_1_OFF:
  3996. case WCD9XXX_EVENT_PRE_CFILT_1_ON:
  3997. case WCD9XXX_EVENT_POST_CFILT_1_ON:
  3998. ret = WCD9XXX_CFILT1_SEL;
  3999. break;
  4000. case WCD9XXX_EVENT_PRE_CFILT_2_OFF:
  4001. case WCD9XXX_EVENT_POST_CFILT_2_OFF:
  4002. case WCD9XXX_EVENT_PRE_CFILT_2_ON:
  4003. case WCD9XXX_EVENT_POST_CFILT_2_ON:
  4004. ret = WCD9XXX_CFILT2_SEL;
  4005. break;
  4006. case WCD9XXX_EVENT_PRE_CFILT_3_OFF:
  4007. case WCD9XXX_EVENT_POST_CFILT_3_OFF:
  4008. case WCD9XXX_EVENT_PRE_CFILT_3_ON:
  4009. case WCD9XXX_EVENT_POST_CFILT_3_ON:
  4010. ret = WCD9XXX_CFILT3_SEL;
  4011. break;
  4012. default:
  4013. ret = -1;
  4014. }
  4015. return ret;
  4016. }
  4017. static int wcd9xxx_get_mbhc_cfilt_sel(struct wcd9xxx_mbhc *mbhc)
  4018. {
  4019. int cfilt;
  4020. const struct wcd9xxx_micbias_setting *mb_pdata =
  4021. mbhc->resmgr->micbias_pdata;
  4022. switch (mbhc->mbhc_cfg->micbias) {
  4023. case MBHC_MICBIAS1:
  4024. cfilt = mb_pdata->bias1_cfilt_sel;
  4025. break;
  4026. case MBHC_MICBIAS2:
  4027. cfilt = mb_pdata->bias2_cfilt_sel;
  4028. break;
  4029. case MBHC_MICBIAS3:
  4030. cfilt = mb_pdata->bias3_cfilt_sel;
  4031. break;
  4032. case MBHC_MICBIAS4:
  4033. cfilt = mb_pdata->bias4_cfilt_sel;
  4034. break;
  4035. default:
  4036. cfilt = MBHC_MICBIAS_INVALID;
  4037. break;
  4038. }
  4039. return cfilt;
  4040. }
  4041. static void wcd9xxx_enable_mbhc_txfe(struct wcd9xxx_mbhc *mbhc, bool on)
  4042. {
  4043. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mbhc_txfe)
  4044. mbhc->mbhc_cb->enable_mbhc_txfe(mbhc->codec, on);
  4045. else
  4046. snd_soc_update_bits(mbhc->codec, WCD9XXX_A_TX_7_MBHC_TEST_CTL,
  4047. 0x40, on ? 0x40 : 0x00);
  4048. }
  4049. static int wcd9xxx_event_notify(struct notifier_block *self, unsigned long val,
  4050. void *data)
  4051. {
  4052. int ret = 0;
  4053. struct wcd9xxx_mbhc *mbhc = ((struct wcd9xxx_resmgr *)data)->mbhc;
  4054. struct snd_soc_codec *codec = mbhc->codec;
  4055. enum wcd9xxx_notify_event event = (enum wcd9xxx_notify_event)val;
  4056. pr_debug("%s: enter event %s(%d)\n", __func__,
  4057. wcd9xxx_get_event_string(event), event);
  4058. mutex_lock(&mbhc->mbhc_lock);
  4059. switch (event) {
  4060. /* MICBIAS usage change */
  4061. case WCD9XXX_EVENT_PRE_MICBIAS_1_ON:
  4062. case WCD9XXX_EVENT_PRE_MICBIAS_2_ON:
  4063. case WCD9XXX_EVENT_PRE_MICBIAS_3_ON:
  4064. case WCD9XXX_EVENT_PRE_MICBIAS_4_ON:
  4065. if (mbhc->mbhc_cfg && mbhc->mbhc_cfg->micbias ==
  4066. wcd9xxx_event_to_micbias(event)) {
  4067. wcd9xxx_switch_micbias(mbhc, 0);
  4068. /*
  4069. * Enable MBHC TxFE whenever micbias is
  4070. * turned ON and polling is active
  4071. */
  4072. if (mbhc->polling_active)
  4073. wcd9xxx_enable_mbhc_txfe(mbhc, true);
  4074. }
  4075. break;
  4076. case WCD9XXX_EVENT_POST_MICBIAS_1_ON:
  4077. case WCD9XXX_EVENT_POST_MICBIAS_2_ON:
  4078. case WCD9XXX_EVENT_POST_MICBIAS_3_ON:
  4079. case WCD9XXX_EVENT_POST_MICBIAS_4_ON:
  4080. if (mbhc->mbhc_cfg && mbhc->mbhc_cfg->micbias ==
  4081. wcd9xxx_event_to_micbias(event) &&
  4082. wcd9xxx_mbhc_polling(mbhc)) {
  4083. /* if polling is on, restart it */
  4084. wcd9xxx_pause_hs_polling(mbhc);
  4085. wcd9xxx_start_hs_polling(mbhc);
  4086. }
  4087. break;
  4088. case WCD9XXX_EVENT_POST_MICBIAS_1_OFF:
  4089. case WCD9XXX_EVENT_POST_MICBIAS_2_OFF:
  4090. case WCD9XXX_EVENT_POST_MICBIAS_3_OFF:
  4091. case WCD9XXX_EVENT_POST_MICBIAS_4_OFF:
  4092. if (mbhc->mbhc_cfg && mbhc->mbhc_cfg->micbias ==
  4093. wcd9xxx_event_to_micbias(event)) {
  4094. if (mbhc->event_state &
  4095. (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR))
  4096. wcd9xxx_switch_micbias(mbhc, 1);
  4097. /*
  4098. * Disable MBHC TxFE, in case it was enabled earlier
  4099. * when micbias was enabled and polling is not active.
  4100. */
  4101. if (!mbhc->polling_active)
  4102. wcd9xxx_enable_mbhc_txfe(mbhc, false);
  4103. }
  4104. if (mbhc->micbias_enable && mbhc->polling_active &&
  4105. !(snd_soc_read(mbhc->codec, mbhc->mbhc_bias_regs.ctl_reg)
  4106. & 0x80)) {
  4107. pr_debug("%s:Micbias turned off by recording, set up again",
  4108. __func__);
  4109. snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg,
  4110. 0x80, 0x80);
  4111. }
  4112. break;
  4113. /* PA usage change */
  4114. case WCD9XXX_EVENT_PRE_HPHL_PA_ON:
  4115. set_bit(MBHC_EVENT_PA_HPHL, &mbhc->event_state);
  4116. if (!(snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg) & 0x80))
  4117. /* if micbias is not enabled, switch to vddio */
  4118. wcd9xxx_switch_micbias(mbhc, 1);
  4119. break;
  4120. case WCD9XXX_EVENT_PRE_HPHR_PA_ON:
  4121. set_bit(MBHC_EVENT_PA_HPHR, &mbhc->event_state);
  4122. break;
  4123. case WCD9XXX_EVENT_POST_HPHL_PA_OFF:
  4124. clear_bit(MBHC_EVENT_PA_HPHL, &mbhc->event_state);
  4125. /* if HPH PAs are off, report OCP and switch back to CFILT */
  4126. clear_bit(WCD9XXX_HPHL_PA_OFF_ACK, &mbhc->hph_pa_dac_state);
  4127. clear_bit(WCD9XXX_HPHL_DAC_OFF_ACK, &mbhc->hph_pa_dac_state);
  4128. if (mbhc->hph_status & SND_JACK_OC_HPHL)
  4129. hphlocp_off_report(mbhc, SND_JACK_OC_HPHL);
  4130. if (!(mbhc->event_state &
  4131. (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR |
  4132. 1 << MBHC_EVENT_PRE_TX_1_3_ON)))
  4133. wcd9xxx_switch_micbias(mbhc, 0);
  4134. break;
  4135. case WCD9XXX_EVENT_POST_HPHR_PA_OFF:
  4136. clear_bit(MBHC_EVENT_PA_HPHR, &mbhc->event_state);
  4137. /* if HPH PAs are off, report OCP and switch back to CFILT */
  4138. clear_bit(WCD9XXX_HPHR_PA_OFF_ACK, &mbhc->hph_pa_dac_state);
  4139. clear_bit(WCD9XXX_HPHR_DAC_OFF_ACK, &mbhc->hph_pa_dac_state);
  4140. if (mbhc->hph_status & SND_JACK_OC_HPHR)
  4141. hphrocp_off_report(mbhc, SND_JACK_OC_HPHL);
  4142. if (!(mbhc->event_state &
  4143. (1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR |
  4144. 1 << MBHC_EVENT_PRE_TX_1_3_ON)))
  4145. wcd9xxx_switch_micbias(mbhc, 0);
  4146. break;
  4147. /* Clock usage change */
  4148. case WCD9XXX_EVENT_PRE_MCLK_ON:
  4149. break;
  4150. case WCD9XXX_EVENT_POST_MCLK_ON:
  4151. /* Change to lower TxAAF frequency */
  4152. snd_soc_update_bits(codec, WCD9XXX_A_TX_COM_BIAS, 1 << 4,
  4153. 1 << 4);
  4154. /* Re-calibrate clock rate dependent values */
  4155. wcd9xxx_update_mbhc_clk_rate(mbhc, mbhc->mbhc_cfg->mclk_rate);
  4156. /* If clock source changes, stop and restart polling */
  4157. if (wcd9xxx_mbhc_polling(mbhc)) {
  4158. wcd9xxx_calibrate_hs_polling(mbhc);
  4159. wcd9xxx_start_hs_polling(mbhc);
  4160. }
  4161. break;
  4162. case WCD9XXX_EVENT_PRE_MCLK_OFF:
  4163. /* If clock source changes, stop and restart polling */
  4164. if (wcd9xxx_mbhc_polling(mbhc))
  4165. wcd9xxx_pause_hs_polling(mbhc);
  4166. break;
  4167. case WCD9XXX_EVENT_POST_MCLK_OFF:
  4168. break;
  4169. case WCD9XXX_EVENT_PRE_RCO_ON:
  4170. break;
  4171. case WCD9XXX_EVENT_POST_RCO_ON:
  4172. /* Change to higher TxAAF frequency */
  4173. snd_soc_update_bits(codec, WCD9XXX_A_TX_COM_BIAS, 1 << 4,
  4174. 0 << 4);
  4175. /* Re-calibrate clock rate dependent values */
  4176. wcd9xxx_update_mbhc_clk_rate(mbhc, mbhc->rco_clk_rate);
  4177. /* If clock source changes, stop and restart polling */
  4178. if (wcd9xxx_mbhc_polling(mbhc)) {
  4179. wcd9xxx_calibrate_hs_polling(mbhc);
  4180. wcd9xxx_start_hs_polling(mbhc);
  4181. }
  4182. break;
  4183. case WCD9XXX_EVENT_PRE_RCO_OFF:
  4184. /* If clock source changes, stop and restart polling */
  4185. if (wcd9xxx_mbhc_polling(mbhc))
  4186. wcd9xxx_pause_hs_polling(mbhc);
  4187. break;
  4188. case WCD9XXX_EVENT_POST_RCO_OFF:
  4189. break;
  4190. /* CFILT usage change */
  4191. case WCD9XXX_EVENT_PRE_CFILT_1_ON:
  4192. case WCD9XXX_EVENT_PRE_CFILT_2_ON:
  4193. case WCD9XXX_EVENT_PRE_CFILT_3_ON:
  4194. if (wcd9xxx_get_mbhc_cfilt_sel(mbhc) ==
  4195. wcd9xxx_event_to_cfilt(event))
  4196. /*
  4197. * Switch CFILT to slow mode if MBHC CFILT is being
  4198. * used.
  4199. */
  4200. wcd9xxx_codec_switch_cfilt_mode(mbhc, false);
  4201. break;
  4202. case WCD9XXX_EVENT_POST_CFILT_1_OFF:
  4203. case WCD9XXX_EVENT_POST_CFILT_2_OFF:
  4204. case WCD9XXX_EVENT_POST_CFILT_3_OFF:
  4205. if (wcd9xxx_get_mbhc_cfilt_sel(mbhc) ==
  4206. wcd9xxx_event_to_cfilt(event))
  4207. /*
  4208. * Switch CFILT to fast mode if MBHC CFILT is not
  4209. * used anymore.
  4210. */
  4211. wcd9xxx_codec_switch_cfilt_mode(mbhc, true);
  4212. break;
  4213. /* System resume */
  4214. case WCD9XXX_EVENT_POST_RESUME:
  4215. mbhc->mbhc_last_resume = jiffies;
  4216. break;
  4217. /* BG mode chage */
  4218. case WCD9XXX_EVENT_PRE_BG_OFF:
  4219. case WCD9XXX_EVENT_POST_BG_OFF:
  4220. case WCD9XXX_EVENT_PRE_BG_AUDIO_ON:
  4221. case WCD9XXX_EVENT_POST_BG_AUDIO_ON:
  4222. case WCD9XXX_EVENT_PRE_BG_MBHC_ON:
  4223. case WCD9XXX_EVENT_POST_BG_MBHC_ON:
  4224. /* Not used for now */
  4225. break;
  4226. case WCD9XXX_EVENT_PRE_TX_1_3_ON:
  4227. /*
  4228. * if polling is ON, mbhc micbias not enabled
  4229. * switch micbias source to VDDIO
  4230. */
  4231. set_bit(MBHC_EVENT_PRE_TX_1_3_ON, &mbhc->event_state);
  4232. if (!(snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg)
  4233. & 0x80) &&
  4234. mbhc->polling_active && !mbhc->mbhc_micbias_switched)
  4235. wcd9xxx_switch_micbias(mbhc, 1);
  4236. break;
  4237. case WCD9XXX_EVENT_POST_TX_1_3_OFF:
  4238. /*
  4239. * Switch back to micbias if HPH PA or TX3 path
  4240. * is disabled
  4241. */
  4242. clear_bit(MBHC_EVENT_PRE_TX_1_3_ON, &mbhc->event_state);
  4243. if (mbhc->polling_active && mbhc->mbhc_micbias_switched &&
  4244. !(mbhc->event_state & (1 << MBHC_EVENT_PA_HPHL |
  4245. 1 << MBHC_EVENT_PA_HPHR)))
  4246. wcd9xxx_switch_micbias(mbhc, 0);
  4247. break;
  4248. default:
  4249. WARN(1, "Unknown event %d\n", event);
  4250. ret = -EINVAL;
  4251. }
  4252. mutex_unlock(&mbhc->mbhc_lock);
  4253. pr_debug("%s: leave\n", __func__);
  4254. return ret;
  4255. }
  4256. static ssize_t key_state_onoff_show(struct device *dev,
  4257. struct device_attribute *attr, char *buf)
  4258. {
  4259. struct wcd9xxx_mbhc *mbhc = dev_get_drvdata(dev);
  4260. int value = 0;
  4261. if (mbhc->buttons_pressed & SND_JACK_BTN_0)
  4262. value = 1;
  4263. return snprintf(buf, 4, "%d\n", value);
  4264. }
  4265. static DEVICE_ATTR(key_state, 0664 , key_state_onoff_show,
  4266. NULL);
  4267. static ssize_t earjack_state_onoff_show(struct device *dev,
  4268. struct device_attribute *attr, char *buf)
  4269. {
  4270. struct wcd9xxx_mbhc *mbhc = dev_get_drvdata(dev);
  4271. int value = 0;
  4272. if (mbhc->hph_status == SND_JACK_HEADSET)
  4273. value = 1;
  4274. return snprintf(buf, 4, "%d\n", value);
  4275. }
  4276. static DEVICE_ATTR(state, 0664 , earjack_state_onoff_show,
  4277. NULL);
  4278. static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
  4279. uint32_t *zr)
  4280. {
  4281. int i;
  4282. int ret = 0;
  4283. s16 l[3], r[3];
  4284. s16 *z[] = {
  4285. &l[0], &r[0], &r[1], &l[1], &l[2], &r[2],
  4286. };
  4287. bool override_en;
  4288. struct snd_soc_codec *codec = mbhc->codec;
  4289. const int mux_wait_us = 25;
  4290. const struct wcd9xxx_reg_mask_val reg_set_mux[] = {
  4291. /* Phase 1 */
  4292. /* Set MBHC_MUX for HPHL without ical */
  4293. {WCD9XXX_A_MBHC_SCALING_MUX_2, 0xFF, 0xF0},
  4294. /* Set MBHC_MUX for HPHR without ical */
  4295. {WCD9XXX_A_MBHC_SCALING_MUX_1, 0xFF, 0xA0},
  4296. /* Set MBHC_MUX for HPHR with ical */
  4297. {WCD9XXX_A_MBHC_SCALING_MUX_2, 0xFF, 0xF8},
  4298. /* Set MBHC_MUX for HPHL with ical */
  4299. {WCD9XXX_A_MBHC_SCALING_MUX_1, 0xFF, 0xC0},
  4300. /* Phase 2 */
  4301. {WCD9XXX_A_MBHC_SCALING_MUX_2, 0xFF, 0xF0},
  4302. /* Set MBHC_MUX for HPHR without ical and wait for 25us */
  4303. {WCD9XXX_A_MBHC_SCALING_MUX_1, 0xFF, 0xA0},
  4304. };
  4305. pr_debug("%s: enter\n", __func__);
  4306. WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
  4307. if (!mbhc->mbhc_cb || !mbhc->mbhc_cb->setup_zdet ||
  4308. !mbhc->mbhc_cb->compute_impedance || !zl ||
  4309. !zr)
  4310. return -EINVAL;
  4311. /*
  4312. * Impedance detection is an intrusive function as it mutes RX paths,
  4313. * enable PAs and etc. Therefore codec drvier including ALSA
  4314. * shouldn't read and write hardware registers during detection.
  4315. */
  4316. mutex_lock(&codec->mutex);
  4317. wcd9xxx_onoff_ext_mclk(mbhc, true);
  4318. override_en = (snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x04) ?
  4319. true : false;
  4320. if (!override_en)
  4321. wcd9xxx_turn_onoff_override(mbhc, true);
  4322. pr_debug("%s: Setting impedance detection\n", __func__);
  4323. /* Codec specific setup for L0, R0, L1 and R1 measurements */
  4324. mbhc->mbhc_cb->setup_zdet(mbhc, PRE_MEAS);
  4325. pr_debug("%s: Performing impedance detection\n", __func__);
  4326. for (i = 0; i < ARRAY_SIZE(reg_set_mux) - 2; i++) {
  4327. snd_soc_update_bits(codec, reg_set_mux[i].reg,
  4328. reg_set_mux[i].mask,
  4329. reg_set_mux[i].val);
  4330. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  4331. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  4332. else
  4333. snd_soc_update_bits(codec,
  4334. WCD9XXX_A_MBHC_SCALING_MUX_1,
  4335. 0x80, 0x80);
  4336. /* 25us is required after mux change to settle down */
  4337. usleep_range(mux_wait_us,
  4338. mux_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
  4339. *(z[i]) = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
  4340. }
  4341. /* Codec specific setup for L2 and R2 measurements */
  4342. mbhc->mbhc_cb->setup_zdet(mbhc, POST_MEAS);
  4343. for (; i < ARRAY_SIZE(reg_set_mux); i++) {
  4344. snd_soc_update_bits(codec, reg_set_mux[i].reg,
  4345. reg_set_mux[i].mask,
  4346. reg_set_mux[i].val);
  4347. if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
  4348. mbhc->mbhc_cb->enable_mux_bias_block(codec);
  4349. else
  4350. snd_soc_update_bits(codec,
  4351. WCD9XXX_A_MBHC_SCALING_MUX_1,
  4352. 0x80, 0x80);
  4353. /* 25us is required after mux change to settle down */
  4354. usleep_range(mux_wait_us,
  4355. mux_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
  4356. *(z[i]) = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
  4357. }
  4358. mbhc->mbhc_cb->setup_zdet(mbhc, PA_DISABLE);
  4359. mutex_unlock(&codec->mutex);
  4360. wcd9xxx_onoff_ext_mclk(mbhc, false);
  4361. if (!override_en)
  4362. wcd9xxx_turn_onoff_override(mbhc, false);
  4363. mbhc->mbhc_cb->compute_impedance(l, r, zl, zr);
  4364. pr_debug("%s: L0: 0x%x(%d), L1: 0x%x(%d), L2: 0x%x(%d)\n",
  4365. __func__,
  4366. l[0] & 0xffff, l[0], l[1] & 0xffff, l[1], l[2] & 0xffff, l[2]);
  4367. pr_debug("%s: R0: 0x%x(%d), R1: 0x%x(%d), R2: 0x%x(%d)\n",
  4368. __func__,
  4369. r[0] & 0xffff, r[0], r[1] & 0xffff, r[1], r[2] & 0xffff, r[2]);
  4370. pr_debug("%s: RL %d milliohm, RR %d milliohm\n", __func__, *zl, *zr);
  4371. pr_debug("%s: Impedance detection completed\n", __func__);
  4372. return ret;
  4373. }
  4374. int wcd9xxx_mbhc_get_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
  4375. uint32_t *zr)
  4376. {
  4377. *zl = mbhc->zl;
  4378. *zr = mbhc->zr;
  4379. if (*zl && *zr)
  4380. return 0;
  4381. else
  4382. return -EINVAL;
  4383. }
  4384. /*
  4385. * wcd9xxx_mbhc_init : initialize MBHC internal structures.
  4386. *
  4387. * NOTE: mbhc->mbhc_cfg is not YET configure so shouldn't be used
  4388. */
  4389. int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
  4390. struct snd_soc_codec *codec,
  4391. int (*micbias_enable_cb) (struct snd_soc_codec*, bool,
  4392. enum wcd9xxx_micbias_num),
  4393. const struct wcd9xxx_mbhc_cb *mbhc_cb,
  4394. const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
  4395. int rco_clk_rate,
  4396. bool impedance_det_en)
  4397. {
  4398. int ret;
  4399. void *core_res;
  4400. struct class *audio;
  4401. struct device *earjack;
  4402. pr_debug("%s: enter\n", __func__);
  4403. memset(&mbhc->mbhc_bias_regs, 0, sizeof(struct mbhc_micbias_regs));
  4404. memset(&mbhc->mbhc_data, 0, sizeof(struct mbhc_internal_cal_data));
  4405. mbhc->mbhc_data.t_sta_dce = DEFAULT_DCE_STA_WAIT;
  4406. mbhc->mbhc_data.t_dce = DEFAULT_DCE_WAIT;
  4407. mbhc->mbhc_data.t_sta = DEFAULT_STA_WAIT;
  4408. mbhc->mbhc_micbias_switched = false;
  4409. mbhc->polling_active = false;
  4410. mbhc->mbhc_state = MBHC_STATE_NONE;
  4411. mbhc->in_swch_irq_handler = false;
  4412. mbhc->current_plug = PLUG_TYPE_NONE;
  4413. mbhc->lpi_enabled = false;
  4414. mbhc->no_mic_headset_override = false;
  4415. mbhc->mbhc_last_resume = 0;
  4416. mbhc->codec = codec;
  4417. mbhc->resmgr = resmgr;
  4418. mbhc->resmgr->mbhc = mbhc;
  4419. mbhc->micbias_enable_cb = micbias_enable_cb;
  4420. mbhc->rco_clk_rate = rco_clk_rate;
  4421. mbhc->mbhc_cb = mbhc_cb;
  4422. mbhc->intr_ids = mbhc_cdc_intr_ids;
  4423. mbhc->impedance_detect = impedance_det_en;
  4424. if (mbhc->intr_ids == NULL) {
  4425. pr_err("%s: Interrupt mapping not provided\n", __func__);
  4426. return -EINVAL;
  4427. }
  4428. if (mbhc->headset_jack.jack == NULL) {
  4429. ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
  4430. &mbhc->headset_jack);
  4431. if (ret) {
  4432. pr_err("%s: Failed to create new jack\n", __func__);
  4433. return ret;
  4434. }
  4435. ret = snd_soc_jack_new(codec, "Button Jack",
  4436. WCD9XXX_JACK_BUTTON_MASK,
  4437. &mbhc->button_jack);
  4438. if (ret) {
  4439. pr_err("Failed to create new jack\n");
  4440. return ret;
  4441. }
  4442. snd_jack_set_key(mbhc->button_jack.jack,
  4443. SND_JACK_BTN_0, KEY_MEDIA);
  4444. snd_jack_set_key(mbhc->button_jack.jack,
  4445. SND_JACK_BTN_1, KEY_VOLUMEUP);
  4446. snd_jack_set_key(mbhc->button_jack.jack,
  4447. SND_JACK_BTN_2, KEY_VOLUMEDOWN);
  4448. audio = class_create(THIS_MODULE, "audio");
  4449. if (IS_ERR(audio))
  4450. pr_err("Failed to create class(audio)!\n");
  4451. earjack = device_create(audio, NULL, 0, NULL, "earjack");
  4452. if (IS_ERR(earjack))
  4453. pr_err("Failed to create device(earjack)!\n");
  4454. ret = device_create_file(earjack, &dev_attr_key_state);
  4455. if (ret)
  4456. pr_err("Failed to create device file in sysfs entries(%s)!\n",
  4457. dev_attr_key_state.attr.name);
  4458. ret = device_create_file(earjack, &dev_attr_state);
  4459. if (ret)
  4460. pr_err("Failed to create device file in sysfs entries(%s)!\n",
  4461. dev_attr_state.attr.name);
  4462. dev_set_drvdata(earjack, mbhc);
  4463. INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork,
  4464. wcd9xxx_mbhc_fw_read);
  4465. INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
  4466. INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork,
  4467. wcd9xxx_mbhc_insert_work);
  4468. }
  4469. mutex_init(&mbhc->mbhc_lock);
  4470. /* Register event notifier */
  4471. mbhc->nblock.notifier_call = wcd9xxx_event_notify;
  4472. ret = wcd9xxx_resmgr_register_notifier(mbhc->resmgr, &mbhc->nblock);
  4473. if (ret) {
  4474. pr_err("%s: Failed to register notifier %d\n", __func__, ret);
  4475. mutex_destroy(&mbhc->mbhc_lock);
  4476. return ret;
  4477. }
  4478. wcd9xxx_init_debugfs(mbhc);
  4479. /* Disable Impedance detection by default for certain codec types */
  4480. if (mbhc->mbhc_cb &&
  4481. mbhc->mbhc_cb->get_cdc_type() == WCD9XXX_CDC_TYPE_HELICON)
  4482. impedance_detect_en = 0;
  4483. else
  4484. impedance_detect_en = impedance_det_en ? 1 : 0;
  4485. core_res = mbhc->resmgr->core_res;
  4486. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->insertion,
  4487. wcd9xxx_hs_insert_irq,
  4488. "Headset insert detect", mbhc);
  4489. if (ret) {
  4490. pr_err("%s: Failed to request irq %d, ret = %d\n", __func__,
  4491. mbhc->intr_ids->insertion, ret);
  4492. goto err_insert_irq;
  4493. }
  4494. wcd9xxx_disable_irq(core_res, mbhc->intr_ids->insertion);
  4495. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->poll_plug_rem,
  4496. wcd9xxx_hs_remove_irq,
  4497. "Headset remove detect", mbhc);
  4498. if (ret) {
  4499. pr_err("%s: Failed to request irq %d\n", __func__,
  4500. mbhc->intr_ids->poll_plug_rem);
  4501. goto err_remove_irq;
  4502. }
  4503. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->dce_est_complete,
  4504. wcd9xxx_dce_handler, "DC Estimation detect",
  4505. mbhc);
  4506. if (ret) {
  4507. pr_err("%s: Failed to request irq %d\n", __func__,
  4508. mbhc->intr_ids->dce_est_complete);
  4509. goto err_potential_irq;
  4510. }
  4511. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->button_release,
  4512. wcd9xxx_release_handler,
  4513. "Button Release detect", mbhc);
  4514. if (ret) {
  4515. pr_err("%s: Failed to request irq %d\n", __func__,
  4516. mbhc->intr_ids->button_release);
  4517. goto err_release_irq;
  4518. }
  4519. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->hph_left_ocp,
  4520. wcd9xxx_hphl_ocp_irq, "HPH_L OCP detect",
  4521. mbhc);
  4522. if (ret) {
  4523. pr_err("%s: Failed to request irq %d\n", __func__,
  4524. mbhc->intr_ids->hph_left_ocp);
  4525. goto err_hphl_ocp_irq;
  4526. }
  4527. wcd9xxx_disable_irq(core_res, mbhc->intr_ids->hph_left_ocp);
  4528. ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->hph_right_ocp,
  4529. wcd9xxx_hphr_ocp_irq, "HPH_R OCP detect",
  4530. mbhc);
  4531. if (ret) {
  4532. pr_err("%s: Failed to request irq %d\n", __func__,
  4533. mbhc->intr_ids->hph_right_ocp);
  4534. goto err_hphr_ocp_irq;
  4535. }
  4536. wcd9xxx_disable_irq(core_res, mbhc->intr_ids->hph_right_ocp);
  4537. wake_lock_init(&det_wake_lock, WAKE_LOCK_SUSPEND, "mbhc_wake_lock");
  4538. wcd9xxx_regmgr_cond_register(resmgr, 1 << WCD9XXX_COND_HPH_MIC |
  4539. 1 << WCD9XXX_COND_HPH);
  4540. pr_debug("%s: leave ret %d\n", __func__, ret);
  4541. return ret;
  4542. err_hphr_ocp_irq:
  4543. wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_left_ocp, mbhc);
  4544. err_hphl_ocp_irq:
  4545. wcd9xxx_free_irq(core_res, mbhc->intr_ids->button_release, mbhc);
  4546. err_release_irq:
  4547. wcd9xxx_free_irq(core_res, mbhc->intr_ids->dce_est_complete, mbhc);
  4548. err_potential_irq:
  4549. wcd9xxx_free_irq(core_res, mbhc->intr_ids->poll_plug_rem, mbhc);
  4550. err_remove_irq:
  4551. wcd9xxx_free_irq(core_res, mbhc->intr_ids->insertion, mbhc);
  4552. err_insert_irq:
  4553. wcd9xxx_resmgr_unregister_notifier(mbhc->resmgr, &mbhc->nblock);
  4554. mutex_destroy(&mbhc->mbhc_lock);
  4555. wake_lock_destroy(&det_wake_lock);
  4556. pr_debug("%s: leave ret %d\n", __func__, ret);
  4557. return ret;
  4558. }
  4559. EXPORT_SYMBOL(wcd9xxx_mbhc_init);
  4560. void wcd9xxx_mbhc_deinit(struct wcd9xxx_mbhc *mbhc)
  4561. {
  4562. struct wcd9xxx_core_resource *core_res =
  4563. mbhc->resmgr->core_res;
  4564. wcd9xxx_regmgr_cond_deregister(mbhc->resmgr, 1 << WCD9XXX_COND_HPH_MIC |
  4565. 1 << WCD9XXX_COND_HPH);
  4566. wcd9xxx_free_irq(core_res, mbhc->intr_ids->button_release, mbhc);
  4567. wcd9xxx_free_irq(core_res, mbhc->intr_ids->dce_est_complete, mbhc);
  4568. wcd9xxx_free_irq(core_res, mbhc->intr_ids->poll_plug_rem, mbhc);
  4569. wcd9xxx_free_irq(core_res, mbhc->intr_ids->insertion, mbhc);
  4570. wcd9xxx_free_irq(core_res, mbhc->intr_ids->hs_jack_switch, mbhc);
  4571. wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_left_ocp, mbhc);
  4572. wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_right_ocp, mbhc);
  4573. mutex_destroy(&mbhc->mbhc_lock);
  4574. wcd9xxx_resmgr_unregister_notifier(mbhc->resmgr, &mbhc->nblock);
  4575. wcd9xxx_cleanup_debugfs(mbhc);
  4576. wake_lock_destroy(&det_wake_lock);
  4577. }
  4578. EXPORT_SYMBOL(wcd9xxx_mbhc_deinit);
  4579. MODULE_DESCRIPTION("wcd9xxx MBHC module");
  4580. MODULE_LICENSE("GPL v2");