wcd938x.c 115 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  3. #include <linux/module.h>
  4. #include <linux/slab.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/device.h>
  7. #include <linux/delay.h>
  8. #include <linux/gpio/consumer.h>
  9. #include <linux/kernel.h>
  10. #include <linux/pm_runtime.h>
  11. #include <linux/component.h>
  12. #include <sound/tlv.h>
  13. #include <linux/of_gpio.h>
  14. #include <linux/of.h>
  15. #include <sound/jack.h>
  16. #include <sound/pcm.h>
  17. #include <sound/pcm_params.h>
  18. #include <linux/regmap.h>
  19. #include <sound/soc.h>
  20. #include <sound/soc-dapm.h>
  21. #include <linux/regulator/consumer.h>
  22. #include "wcd-clsh-v2.h"
  23. #include "wcd-mbhc-v2.h"
  24. #include "wcd938x.h"
  25. #define WCD938X_MAX_MICBIAS (4)
  26. #define WCD938X_MAX_SUPPLY (4)
  27. #define WCD938X_MBHC_MAX_BUTTONS (8)
  28. #define TX_ADC_MAX (4)
  29. #define WCD938X_TX_MAX_SWR_PORTS (5)
  30. #define WCD938X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
  31. SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
  32. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
  33. /* Fractional Rates */
  34. #define WCD938X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
  35. SNDRV_PCM_RATE_176400)
  36. #define WCD938X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
  37. SNDRV_PCM_FMTBIT_S24_LE)
  38. /* Convert from vout ctl to micbias voltage in mV */
  39. #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
  40. #define SWR_CLK_RATE_0P6MHZ (600000)
  41. #define SWR_CLK_RATE_1P2MHZ (1200000)
  42. #define SWR_CLK_RATE_2P4MHZ (2400000)
  43. #define SWR_CLK_RATE_4P8MHZ (4800000)
  44. #define SWR_CLK_RATE_9P6MHZ (9600000)
  45. #define SWR_CLK_RATE_11P2896MHZ (1128960)
  46. #define WCD938X_DRV_NAME "wcd938x_codec"
  47. #define WCD938X_VERSION_1_0 (1)
  48. #define EAR_RX_PATH_AUX (1)
  49. #define ADC_MODE_VAL_HIFI 0x01
  50. #define ADC_MODE_VAL_LO_HIF 0x02
  51. #define ADC_MODE_VAL_NORMAL 0x03
  52. #define ADC_MODE_VAL_LP 0x05
  53. #define ADC_MODE_VAL_ULP1 0x09
  54. #define ADC_MODE_VAL_ULP2 0x0B
  55. /* Z value defined in milliohm */
  56. #define WCD938X_ZDET_VAL_32 (32000)
  57. #define WCD938X_ZDET_VAL_400 (400000)
  58. #define WCD938X_ZDET_VAL_1200 (1200000)
  59. #define WCD938X_ZDET_VAL_100K (100000000)
  60. /* Z floating defined in ohms */
  61. #define WCD938X_ZDET_FLOATING_IMPEDANCE (0x0FFFFFFE)
  62. #define WCD938X_ZDET_NUM_MEASUREMENTS (900)
  63. #define WCD938X_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
  64. #define WCD938X_MBHC_GET_X1(x) (x & 0x3FFF)
  65. /* Z value compared in milliOhm */
  66. #define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
  67. #define WCD938X_MBHC_ZDET_CONST (86 * 16384)
  68. #define WCD938X_MBHC_MOISTURE_RREF R_24_KOHM
  69. #define WCD_MBHC_HS_V_MAX 1600
  70. #define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
  71. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  72. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  73. SNDRV_CTL_ELEM_ACCESS_READWRITE,\
  74. .tlv.p = (tlv_array), \
  75. .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
  76. .put = wcd938x_ear_pa_put_gain, \
  77. .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
  78. enum {
  79. WCD9380 = 0,
  80. WCD9385 = 5,
  81. };
  82. enum {
  83. TX_HDR12 = 0,
  84. TX_HDR34,
  85. TX_HDR_MAX,
  86. };
  87. enum {
  88. WCD_RX1,
  89. WCD_RX2,
  90. WCD_RX3
  91. };
  92. enum {
  93. /* INTR_CTRL_INT_MASK_0 */
  94. WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
  95. WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET,
  96. WCD938X_IRQ_MBHC_ELECT_INS_REM_DET,
  97. WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
  98. WCD938X_IRQ_MBHC_SW_DET,
  99. WCD938X_IRQ_HPHR_OCP_INT,
  100. WCD938X_IRQ_HPHR_CNP_INT,
  101. WCD938X_IRQ_HPHL_OCP_INT,
  102. /* INTR_CTRL_INT_MASK_1 */
  103. WCD938X_IRQ_HPHL_CNP_INT,
  104. WCD938X_IRQ_EAR_CNP_INT,
  105. WCD938X_IRQ_EAR_SCD_INT,
  106. WCD938X_IRQ_AUX_CNP_INT,
  107. WCD938X_IRQ_AUX_SCD_INT,
  108. WCD938X_IRQ_HPHL_PDM_WD_INT,
  109. WCD938X_IRQ_HPHR_PDM_WD_INT,
  110. WCD938X_IRQ_AUX_PDM_WD_INT,
  111. /* INTR_CTRL_INT_MASK_2 */
  112. WCD938X_IRQ_LDORT_SCD_INT,
  113. WCD938X_IRQ_MBHC_MOISTURE_INT,
  114. WCD938X_IRQ_HPHL_SURGE_DET_INT,
  115. WCD938X_IRQ_HPHR_SURGE_DET_INT,
  116. WCD938X_NUM_IRQS,
  117. };
  118. enum {
  119. WCD_ADC1 = 0,
  120. WCD_ADC2,
  121. WCD_ADC3,
  122. WCD_ADC4,
  123. ALLOW_BUCK_DISABLE,
  124. HPH_COMP_DELAY,
  125. HPH_PA_DELAY,
  126. AMIC2_BCS_ENABLE,
  127. WCD_SUPPLIES_LPM_MODE,
  128. };
  129. enum {
  130. ADC_MODE_INVALID = 0,
  131. ADC_MODE_HIFI,
  132. ADC_MODE_LO_HIF,
  133. ADC_MODE_NORMAL,
  134. ADC_MODE_LP,
  135. ADC_MODE_ULP1,
  136. ADC_MODE_ULP2,
  137. };
  138. enum {
  139. AIF1_PB = 0,
  140. AIF1_CAP,
  141. NUM_CODEC_DAIS,
  142. };
  143. static u8 tx_mode_bit[] = {
  144. [ADC_MODE_INVALID] = 0x00,
  145. [ADC_MODE_HIFI] = 0x01,
  146. [ADC_MODE_LO_HIF] = 0x02,
  147. [ADC_MODE_NORMAL] = 0x04,
  148. [ADC_MODE_LP] = 0x08,
  149. [ADC_MODE_ULP1] = 0x10,
  150. [ADC_MODE_ULP2] = 0x20,
  151. };
  152. struct wcd938x_priv {
  153. struct sdw_slave *tx_sdw_dev;
  154. struct wcd938x_sdw_priv *sdw_priv[NUM_CODEC_DAIS];
  155. struct device *txdev;
  156. struct device *rxdev;
  157. struct device_node *rxnode, *txnode;
  158. struct regmap *regmap;
  159. struct mutex micb_lock;
  160. /* mbhc module */
  161. struct wcd_mbhc *wcd_mbhc;
  162. struct wcd_mbhc_config mbhc_cfg;
  163. struct wcd_mbhc_intr intr_ids;
  164. struct wcd_clsh_ctrl *clsh_info;
  165. struct irq_domain *virq;
  166. struct regmap_irq_chip *wcd_regmap_irq_chip;
  167. struct regmap_irq_chip_data *irq_chip;
  168. struct regulator_bulk_data supplies[WCD938X_MAX_SUPPLY];
  169. struct snd_soc_jack *jack;
  170. unsigned long status_mask;
  171. s32 micb_ref[WCD938X_MAX_MICBIAS];
  172. s32 pullup_ref[WCD938X_MAX_MICBIAS];
  173. u32 hph_mode;
  174. u32 tx_mode[TX_ADC_MAX];
  175. int flyback_cur_det_disable;
  176. int ear_rx_path;
  177. int variant;
  178. int reset_gpio;
  179. struct gpio_desc *us_euro_gpio;
  180. u32 micb1_mv;
  181. u32 micb2_mv;
  182. u32 micb3_mv;
  183. u32 micb4_mv;
  184. int hphr_pdm_wd_int;
  185. int hphl_pdm_wd_int;
  186. int aux_pdm_wd_int;
  187. bool comp1_enable;
  188. bool comp2_enable;
  189. bool ldoh;
  190. bool bcs_dis;
  191. };
  192. static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
  193. static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, -3000);
  194. static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);
  195. struct wcd938x_mbhc_zdet_param {
  196. u16 ldo_ctl;
  197. u16 noff;
  198. u16 nshift;
  199. u16 btn5;
  200. u16 btn6;
  201. u16 btn7;
  202. };
  203. static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
  204. WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD938X_ANA_MBHC_MECH, 0x80),
  205. WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD938X_ANA_MBHC_MECH, 0x40),
  206. WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD938X_ANA_MBHC_MECH, 0x20),
  207. WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x30),
  208. WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD938X_ANA_MBHC_ELECT, 0x08),
  209. WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F),
  210. WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD938X_ANA_MBHC_MECH, 0x04),
  211. WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x10),
  212. WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x08),
  213. WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD938X_ANA_MBHC_MECH, 0x01),
  214. WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD938X_ANA_MBHC_ELECT, 0x06),
  215. WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD938X_ANA_MBHC_ELECT, 0x80),
  216. WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F),
  217. WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD938X_MBHC_NEW_CTL_1, 0x03),
  218. WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD938X_MBHC_NEW_CTL_2, 0x03),
  219. WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x08),
  220. WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
  221. WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x20),
  222. WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x80),
  223. WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x40),
  224. WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD938X_HPH_OCP_CTL, 0x10),
  225. WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x07),
  226. WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD938X_ANA_MBHC_ELECT, 0x70),
  227. WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0xFF),
  228. WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD938X_ANA_MICB2, 0xC0),
  229. WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD938X_HPH_CNP_WG_TIME, 0xFF),
  230. WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD938X_ANA_HPH, 0x40),
  231. WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD938X_ANA_HPH, 0x80),
  232. WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD938X_ANA_HPH, 0xC0),
  233. WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
  234. WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD938X_MBHC_CTL_BCS, 0x02),
  235. WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x01),
  236. WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD938X_MBHC_NEW_CTL_2, 0x70),
  237. WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x20),
  238. WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD938X_HPH_PA_CTL2, 0x40),
  239. WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD938X_HPH_PA_CTL2, 0x10),
  240. WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD938X_HPH_L_TEST, 0x01),
  241. WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD938X_HPH_R_TEST, 0x01),
  242. WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x80),
  243. WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x20),
  244. WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD938X_MBHC_NEW_CTL_1, 0x08),
  245. WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD938X_MBHC_NEW_FSM_STATUS, 0x40),
  246. WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD938X_MBHC_NEW_FSM_STATUS, 0x80),
  247. WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD938X_MBHC_NEW_ADC_RESULT, 0xFF),
  248. WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD938X_ANA_MICB2, 0x3F),
  249. WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD938X_MBHC_NEW_CTL_1, 0x10),
  250. WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD938X_MBHC_NEW_CTL_1, 0x04),
  251. WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD938X_ANA_MBHC_ZDET, 0x02),
  252. };
  253. static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = {
  254. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
  255. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02),
  256. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04),
  257. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08),
  258. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_SW_DET, 0, 0x10),
  259. REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_OCP_INT, 0, 0x20),
  260. REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_CNP_INT, 0, 0x40),
  261. REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_OCP_INT, 0, 0x80),
  262. REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_CNP_INT, 1, 0x01),
  263. REGMAP_IRQ_REG(WCD938X_IRQ_EAR_CNP_INT, 1, 0x02),
  264. REGMAP_IRQ_REG(WCD938X_IRQ_EAR_SCD_INT, 1, 0x04),
  265. REGMAP_IRQ_REG(WCD938X_IRQ_AUX_CNP_INT, 1, 0x08),
  266. REGMAP_IRQ_REG(WCD938X_IRQ_AUX_SCD_INT, 1, 0x10),
  267. REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_PDM_WD_INT, 1, 0x20),
  268. REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_PDM_WD_INT, 1, 0x40),
  269. REGMAP_IRQ_REG(WCD938X_IRQ_AUX_PDM_WD_INT, 1, 0x80),
  270. REGMAP_IRQ_REG(WCD938X_IRQ_LDORT_SCD_INT, 2, 0x01),
  271. REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_MOISTURE_INT, 2, 0x02),
  272. REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04),
  273. REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08),
  274. };
  275. static struct regmap_irq_chip wcd938x_regmap_irq_chip = {
  276. .name = "wcd938x",
  277. .irqs = wcd938x_irqs,
  278. .num_irqs = ARRAY_SIZE(wcd938x_irqs),
  279. .num_regs = 3,
  280. .status_base = WCD938X_DIGITAL_INTR_STATUS_0,
  281. .mask_base = WCD938X_DIGITAL_INTR_MASK_0,
  282. .ack_base = WCD938X_DIGITAL_INTR_CLEAR_0,
  283. .use_ack = 1,
  284. .runtime_pm = true,
  285. .irq_drv_data = NULL,
  286. };
  287. static int wcd938x_get_clk_rate(int mode)
  288. {
  289. int rate;
  290. switch (mode) {
  291. case ADC_MODE_ULP2:
  292. rate = SWR_CLK_RATE_0P6MHZ;
  293. break;
  294. case ADC_MODE_ULP1:
  295. rate = SWR_CLK_RATE_1P2MHZ;
  296. break;
  297. case ADC_MODE_LP:
  298. rate = SWR_CLK_RATE_4P8MHZ;
  299. break;
  300. case ADC_MODE_NORMAL:
  301. case ADC_MODE_LO_HIF:
  302. case ADC_MODE_HIFI:
  303. case ADC_MODE_INVALID:
  304. default:
  305. rate = SWR_CLK_RATE_9P6MHZ;
  306. break;
  307. }
  308. return rate;
  309. }
  310. static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, int rate, int bank)
  311. {
  312. u8 mask = (bank ? 0xF0 : 0x0F);
  313. u8 val = 0;
  314. switch (rate) {
  315. case SWR_CLK_RATE_0P6MHZ:
  316. val = (bank ? 0x60 : 0x06);
  317. break;
  318. case SWR_CLK_RATE_1P2MHZ:
  319. val = (bank ? 0x50 : 0x05);
  320. break;
  321. case SWR_CLK_RATE_2P4MHZ:
  322. val = (bank ? 0x30 : 0x03);
  323. break;
  324. case SWR_CLK_RATE_4P8MHZ:
  325. val = (bank ? 0x10 : 0x01);
  326. break;
  327. case SWR_CLK_RATE_9P6MHZ:
  328. default:
  329. val = 0x00;
  330. break;
  331. }
  332. snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE,
  333. mask, val);
  334. return 0;
  335. }
  336. static int wcd938x_io_init(struct wcd938x_priv *wcd938x)
  337. {
  338. struct regmap *rm = wcd938x->regmap;
  339. regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x0E, 0x0E);
  340. regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x80, 0x80);
  341. /* 1 msec delay as per HW requirement */
  342. usleep_range(1000, 1010);
  343. regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x40, 0x40);
  344. /* 1 msec delay as per HW requirement */
  345. usleep_range(1000, 1010);
  346. regmap_update_bits(rm, WCD938X_LDORXTX_CONFIG, 0x10, 0x00);
  347. regmap_update_bits(rm, WCD938X_BIAS_VBG_FINE_ADJ,
  348. 0xF0, 0x80);
  349. regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x80, 0x80);
  350. regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x40);
  351. /* 10 msec delay as per HW requirement */
  352. usleep_range(10000, 10010);
  353. regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x00);
  354. regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL,
  355. 0xF0, 0x00);
  356. regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW,
  357. 0x1F, 0x15);
  358. regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW,
  359. 0x1F, 0x15);
  360. regmap_update_bits(rm, WCD938X_HPH_REFBUFF_UHQA_CTL,
  361. 0xC0, 0x80);
  362. regmap_update_bits(rm, WCD938X_DIGITAL_CDC_DMIC_CTL,
  363. 0x02, 0x02);
  364. regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP,
  365. 0xFF, 0x14);
  366. regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,
  367. 0x1F, 0x08);
  368. regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0xFF, 0x55);
  369. regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0xFF, 0x44);
  370. regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0xFF, 0x11);
  371. regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00);
  372. regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00);
  373. /* Set Noise Filter Resistor value */
  374. regmap_update_bits(rm, WCD938X_MICB1_TEST_CTL_1, 0xE0, 0xE0);
  375. regmap_update_bits(rm, WCD938X_MICB2_TEST_CTL_1, 0xE0, 0xE0);
  376. regmap_update_bits(rm, WCD938X_MICB3_TEST_CTL_1, 0xE0, 0xE0);
  377. regmap_update_bits(rm, WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0);
  378. regmap_update_bits(rm, WCD938X_TX_3_4_TEST_BLK_EN2, 0x01, 0x00);
  379. regmap_update_bits(rm, WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
  380. return 0;
  381. }
  382. static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
  383. struct sdw_port_config *port_config,
  384. u8 enable)
  385. {
  386. u8 ch_mask, port_num;
  387. port_num = ch_info->port_num;
  388. ch_mask = ch_info->ch_mask;
  389. port_config->num = port_num;
  390. if (enable)
  391. port_config->ch_mask |= ch_mask;
  392. else
  393. port_config->ch_mask &= ~ch_mask;
  394. return 0;
  395. }
  396. static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 port_num, u8 ch_id, u8 enable)
  397. {
  398. return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id],
  399. &wcd->port_config[port_num - 1],
  400. enable);
  401. }
  402. static int wcd938x_codec_enable_rxclk(struct snd_soc_dapm_widget *w,
  403. struct snd_kcontrol *kcontrol,
  404. int event)
  405. {
  406. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  407. switch (event) {
  408. case SND_SOC_DAPM_PRE_PMU:
  409. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  410. WCD938X_ANA_RX_CLK_EN_MASK, 1);
  411. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  412. WCD938X_RX_BIAS_EN_MASK, 1);
  413. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX0_CTL,
  414. WCD938X_DEM_DITHER_ENABLE_MASK, 0);
  415. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX1_CTL,
  416. WCD938X_DEM_DITHER_ENABLE_MASK, 0);
  417. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX2_CTL,
  418. WCD938X_DEM_DITHER_ENABLE_MASK, 0);
  419. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  420. WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 1);
  421. snd_soc_component_write_field(component, WCD938X_AUX_AUXPA,
  422. WCD938X_AUXPA_CLK_EN_MASK, 1);
  423. break;
  424. case SND_SOC_DAPM_POST_PMD:
  425. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  426. WCD938X_VNEG_EN_MASK, 0);
  427. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  428. WCD938X_VPOS_EN_MASK, 0);
  429. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  430. WCD938X_RX_BIAS_EN_MASK, 0);
  431. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  432. WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 0);
  433. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  434. WCD938X_ANA_RX_CLK_EN_MASK, 0);
  435. break;
  436. }
  437. return 0;
  438. }
  439. static int wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
  440. struct snd_kcontrol *kcontrol,
  441. int event)
  442. {
  443. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  444. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  445. switch (event) {
  446. case SND_SOC_DAPM_PRE_PMU:
  447. snd_soc_component_write_field(component,
  448. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  449. WCD938X_RXD0_CLK_EN_MASK, 0x01);
  450. snd_soc_component_write_field(component,
  451. WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
  452. WCD938X_HPHL_RX_EN_MASK, 1);
  453. snd_soc_component_write_field(component,
  454. WCD938X_HPH_RDAC_CLK_CTL1,
  455. WCD938X_CHOP_CLK_EN_MASK, 0);
  456. break;
  457. case SND_SOC_DAPM_POST_PMU:
  458. snd_soc_component_write_field(component,
  459. WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L,
  460. WCD938X_HPH_RES_DIV_MASK, 0x02);
  461. if (wcd938x->comp1_enable) {
  462. snd_soc_component_write_field(component,
  463. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  464. WCD938X_HPHL_COMP_EN_MASK, 1);
  465. /* 5msec compander delay as per HW requirement */
  466. if (!wcd938x->comp2_enable || (snd_soc_component_read(component,
  467. WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x01))
  468. usleep_range(5000, 5010);
  469. snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
  470. WCD938X_AUTOCHOP_TIMER_EN, 0);
  471. } else {
  472. snd_soc_component_write_field(component,
  473. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  474. WCD938X_HPHL_COMP_EN_MASK, 0);
  475. snd_soc_component_write_field(component,
  476. WCD938X_HPH_L_EN,
  477. WCD938X_GAIN_SRC_SEL_MASK,
  478. WCD938X_GAIN_SRC_SEL_REGISTER);
  479. }
  480. break;
  481. case SND_SOC_DAPM_POST_PMD:
  482. snd_soc_component_write_field(component,
  483. WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
  484. WCD938X_HPH_RES_DIV_MASK, 0x1);
  485. break;
  486. }
  487. return 0;
  488. }
  489. static int wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
  490. struct snd_kcontrol *kcontrol,
  491. int event)
  492. {
  493. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  494. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  495. switch (event) {
  496. case SND_SOC_DAPM_PRE_PMU:
  497. snd_soc_component_write_field(component,
  498. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  499. WCD938X_RXD1_CLK_EN_MASK, 1);
  500. snd_soc_component_write_field(component,
  501. WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
  502. WCD938X_HPHR_RX_EN_MASK, 1);
  503. snd_soc_component_write_field(component,
  504. WCD938X_HPH_RDAC_CLK_CTL1,
  505. WCD938X_CHOP_CLK_EN_MASK, 0);
  506. break;
  507. case SND_SOC_DAPM_POST_PMU:
  508. snd_soc_component_write_field(component,
  509. WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
  510. WCD938X_HPH_RES_DIV_MASK, 0x02);
  511. if (wcd938x->comp2_enable) {
  512. snd_soc_component_write_field(component,
  513. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  514. WCD938X_HPHR_COMP_EN_MASK, 1);
  515. /* 5msec compander delay as per HW requirement */
  516. if (!wcd938x->comp1_enable ||
  517. (snd_soc_component_read(component,
  518. WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x02))
  519. usleep_range(5000, 5010);
  520. snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
  521. WCD938X_AUTOCHOP_TIMER_EN, 0);
  522. } else {
  523. snd_soc_component_write_field(component,
  524. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  525. WCD938X_HPHR_COMP_EN_MASK, 0);
  526. snd_soc_component_write_field(component,
  527. WCD938X_HPH_R_EN,
  528. WCD938X_GAIN_SRC_SEL_MASK,
  529. WCD938X_GAIN_SRC_SEL_REGISTER);
  530. }
  531. break;
  532. case SND_SOC_DAPM_POST_PMD:
  533. snd_soc_component_write_field(component,
  534. WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
  535. WCD938X_HPH_RES_DIV_MASK, 0x01);
  536. break;
  537. }
  538. return 0;
  539. }
  540. static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
  541. struct snd_kcontrol *kcontrol,
  542. int event)
  543. {
  544. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  545. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  546. switch (event) {
  547. case SND_SOC_DAPM_PRE_PMU:
  548. wcd938x->ear_rx_path =
  549. snd_soc_component_read(
  550. component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
  551. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
  552. snd_soc_component_write_field(component,
  553. WCD938X_EAR_EAR_DAC_CON,
  554. WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 0);
  555. snd_soc_component_write_field(component,
  556. WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
  557. WCD938X_AUX_EN_MASK, 1);
  558. snd_soc_component_write_field(component,
  559. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  560. WCD938X_RXD2_CLK_EN_MASK, 1);
  561. snd_soc_component_write_field(component,
  562. WCD938X_ANA_EAR_COMPANDER_CTL,
  563. WCD938X_GAIN_OVRD_REG_MASK, 1);
  564. } else {
  565. snd_soc_component_write_field(component,
  566. WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
  567. WCD938X_HPHL_RX_EN_MASK, 1);
  568. snd_soc_component_write_field(component,
  569. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  570. WCD938X_RXD0_CLK_EN_MASK, 1);
  571. if (wcd938x->comp1_enable)
  572. snd_soc_component_write_field(component,
  573. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  574. WCD938X_HPHL_COMP_EN_MASK, 1);
  575. }
  576. /* 5 msec delay as per HW requirement */
  577. usleep_range(5000, 5010);
  578. if (wcd938x->flyback_cur_det_disable == 0)
  579. snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
  580. WCD938X_EN_CUR_DET_MASK, 0);
  581. wcd938x->flyback_cur_det_disable++;
  582. wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
  583. WCD_CLSH_EVENT_PRE_DAC,
  584. WCD_CLSH_STATE_EAR,
  585. wcd938x->hph_mode);
  586. break;
  587. case SND_SOC_DAPM_POST_PMD:
  588. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
  589. snd_soc_component_write_field(component,
  590. WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
  591. WCD938X_AUX_EN_MASK, 0);
  592. snd_soc_component_write_field(component,
  593. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  594. WCD938X_RXD2_CLK_EN_MASK, 0);
  595. } else {
  596. snd_soc_component_write_field(component,
  597. WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
  598. WCD938X_HPHL_RX_EN_MASK, 0);
  599. snd_soc_component_write_field(component,
  600. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  601. WCD938X_RXD0_CLK_EN_MASK, 0);
  602. if (wcd938x->comp1_enable)
  603. snd_soc_component_write_field(component,
  604. WCD938X_DIGITAL_CDC_COMP_CTL_0,
  605. WCD938X_HPHL_COMP_EN_MASK, 0);
  606. }
  607. snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
  608. WCD938X_GAIN_OVRD_REG_MASK, 0);
  609. snd_soc_component_write_field(component,
  610. WCD938X_EAR_EAR_DAC_CON,
  611. WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 1);
  612. break;
  613. }
  614. return 0;
  615. }
  616. static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
  617. struct snd_kcontrol *kcontrol,
  618. int event)
  619. {
  620. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  621. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  622. switch (event) {
  623. case SND_SOC_DAPM_PRE_PMU:
  624. snd_soc_component_write_field(component,
  625. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  626. WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 1);
  627. snd_soc_component_write_field(component,
  628. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  629. WCD938X_RXD2_CLK_EN_MASK, 1);
  630. snd_soc_component_write_field(component,
  631. WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
  632. WCD938X_AUX_EN_MASK, 1);
  633. if (wcd938x->flyback_cur_det_disable == 0)
  634. snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
  635. WCD938X_EN_CUR_DET_MASK, 0);
  636. wcd938x->flyback_cur_det_disable++;
  637. wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
  638. WCD_CLSH_EVENT_PRE_DAC,
  639. WCD_CLSH_STATE_AUX,
  640. wcd938x->hph_mode);
  641. break;
  642. case SND_SOC_DAPM_POST_PMD:
  643. snd_soc_component_write_field(component,
  644. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  645. WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 0);
  646. break;
  647. }
  648. return 0;
  649. }
  650. static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
  651. struct snd_kcontrol *kcontrol, int event)
  652. {
  653. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  654. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  655. int hph_mode = wcd938x->hph_mode;
  656. switch (event) {
  657. case SND_SOC_DAPM_PRE_PMU:
  658. if (wcd938x->ldoh)
  659. snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
  660. WCD938X_LDOH_EN_MASK, 1);
  661. wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
  662. WCD_CLSH_STATE_HPHR, hph_mode);
  663. wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
  664. if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
  665. hph_mode == CLS_H_ULP) {
  666. snd_soc_component_write_field(component,
  667. WCD938X_HPH_REFBUFF_LP_CTL,
  668. WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
  669. }
  670. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  671. WCD938X_HPHR_REF_EN_MASK, 1);
  672. wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
  673. /* 100 usec delay as per HW requirement */
  674. usleep_range(100, 110);
  675. set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  676. snd_soc_component_write_field(component,
  677. WCD938X_DIGITAL_PDM_WD_CTL1,
  678. WCD938X_PDM_WD_EN_MASK, 0x3);
  679. break;
  680. case SND_SOC_DAPM_POST_PMU:
  681. /*
  682. * 7ms sleep is required if compander is enabled as per
  683. * HW requirement. If compander is disabled, then
  684. * 20ms delay is required.
  685. */
  686. if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
  687. if (!wcd938x->comp2_enable)
  688. usleep_range(20000, 20100);
  689. else
  690. usleep_range(7000, 7100);
  691. if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
  692. hph_mode == CLS_H_ULP)
  693. snd_soc_component_write_field(component,
  694. WCD938X_HPH_REFBUFF_LP_CTL,
  695. WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
  696. clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  697. }
  698. snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
  699. WCD938X_AUTOCHOP_TIMER_EN, 1);
  700. if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
  701. hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
  702. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  703. WCD938X_REGULATOR_MODE_MASK,
  704. WCD938X_REGULATOR_MODE_CLASS_AB);
  705. enable_irq(wcd938x->hphr_pdm_wd_int);
  706. break;
  707. case SND_SOC_DAPM_PRE_PMD:
  708. disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
  709. /*
  710. * 7ms sleep is required if compander is enabled as per
  711. * HW requirement. If compander is disabled, then
  712. * 20ms delay is required.
  713. */
  714. if (!wcd938x->comp2_enable)
  715. usleep_range(20000, 20100);
  716. else
  717. usleep_range(7000, 7100);
  718. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  719. WCD938X_HPHR_EN_MASK, 0);
  720. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  721. WCD_EVENT_PRE_HPHR_PA_OFF);
  722. set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  723. break;
  724. case SND_SOC_DAPM_POST_PMD:
  725. /*
  726. * 7ms sleep is required if compander is enabled as per
  727. * HW requirement. If compander is disabled, then
  728. * 20ms delay is required.
  729. */
  730. if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
  731. if (!wcd938x->comp2_enable)
  732. usleep_range(20000, 20100);
  733. else
  734. usleep_range(7000, 7100);
  735. clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  736. }
  737. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  738. WCD_EVENT_POST_HPHR_PA_OFF);
  739. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  740. WCD938X_HPHR_REF_EN_MASK, 0);
  741. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL1,
  742. WCD938X_PDM_WD_EN_MASK, 0);
  743. wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
  744. WCD_CLSH_STATE_HPHR, hph_mode);
  745. if (wcd938x->ldoh)
  746. snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
  747. WCD938X_LDOH_EN_MASK, 0);
  748. break;
  749. }
  750. return 0;
  751. }
  752. static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
  753. struct snd_kcontrol *kcontrol, int event)
  754. {
  755. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  756. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  757. int hph_mode = wcd938x->hph_mode;
  758. switch (event) {
  759. case SND_SOC_DAPM_PRE_PMU:
  760. if (wcd938x->ldoh)
  761. snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
  762. WCD938X_LDOH_EN_MASK, 1);
  763. wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
  764. WCD_CLSH_STATE_HPHL, hph_mode);
  765. wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
  766. if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
  767. hph_mode == CLS_H_ULP) {
  768. snd_soc_component_write_field(component,
  769. WCD938X_HPH_REFBUFF_LP_CTL,
  770. WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
  771. }
  772. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  773. WCD938X_HPHL_REF_EN_MASK, 1);
  774. wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
  775. /* 100 usec delay as per HW requirement */
  776. usleep_range(100, 110);
  777. set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  778. snd_soc_component_write_field(component,
  779. WCD938X_DIGITAL_PDM_WD_CTL0,
  780. WCD938X_PDM_WD_EN_MASK, 0x3);
  781. break;
  782. case SND_SOC_DAPM_POST_PMU:
  783. /*
  784. * 7ms sleep is required if compander is enabled as per
  785. * HW requirement. If compander is disabled, then
  786. * 20ms delay is required.
  787. */
  788. if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
  789. if (!wcd938x->comp1_enable)
  790. usleep_range(20000, 20100);
  791. else
  792. usleep_range(7000, 7100);
  793. if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
  794. hph_mode == CLS_H_ULP)
  795. snd_soc_component_write_field(component,
  796. WCD938X_HPH_REFBUFF_LP_CTL,
  797. WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
  798. clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  799. }
  800. snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
  801. WCD938X_AUTOCHOP_TIMER_EN, 1);
  802. if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
  803. hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
  804. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  805. WCD938X_REGULATOR_MODE_MASK,
  806. WCD938X_REGULATOR_MODE_CLASS_AB);
  807. enable_irq(wcd938x->hphl_pdm_wd_int);
  808. break;
  809. case SND_SOC_DAPM_PRE_PMD:
  810. disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
  811. /*
  812. * 7ms sleep is required if compander is enabled as per
  813. * HW requirement. If compander is disabled, then
  814. * 20ms delay is required.
  815. */
  816. if (!wcd938x->comp1_enable)
  817. usleep_range(20000, 20100);
  818. else
  819. usleep_range(7000, 7100);
  820. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  821. WCD938X_HPHL_EN_MASK, 0);
  822. wcd_mbhc_event_notify(wcd938x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF);
  823. set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  824. break;
  825. case SND_SOC_DAPM_POST_PMD:
  826. /*
  827. * 7ms sleep is required if compander is enabled as per
  828. * HW requirement. If compander is disabled, then
  829. * 20ms delay is required.
  830. */
  831. if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
  832. if (!wcd938x->comp1_enable)
  833. usleep_range(21000, 21100);
  834. else
  835. usleep_range(7000, 7100);
  836. clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
  837. }
  838. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  839. WCD_EVENT_POST_HPHL_PA_OFF);
  840. snd_soc_component_write_field(component, WCD938X_ANA_HPH,
  841. WCD938X_HPHL_REF_EN_MASK, 0);
  842. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
  843. WCD938X_PDM_WD_EN_MASK, 0);
  844. wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
  845. WCD_CLSH_STATE_HPHL, hph_mode);
  846. if (wcd938x->ldoh)
  847. snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
  848. WCD938X_LDOH_EN_MASK, 0);
  849. break;
  850. }
  851. return 0;
  852. }
  853. static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
  854. struct snd_kcontrol *kcontrol, int event)
  855. {
  856. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  857. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  858. int hph_mode = wcd938x->hph_mode;
  859. switch (event) {
  860. case SND_SOC_DAPM_PRE_PMU:
  861. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
  862. WCD938X_AUX_PDM_WD_EN_MASK, 1);
  863. break;
  864. case SND_SOC_DAPM_POST_PMU:
  865. /* 1 msec delay as per HW requirement */
  866. usleep_range(1000, 1010);
  867. if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
  868. hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
  869. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  870. WCD938X_REGULATOR_MODE_MASK,
  871. WCD938X_REGULATOR_MODE_CLASS_AB);
  872. enable_irq(wcd938x->aux_pdm_wd_int);
  873. break;
  874. case SND_SOC_DAPM_PRE_PMD:
  875. disable_irq_nosync(wcd938x->aux_pdm_wd_int);
  876. break;
  877. case SND_SOC_DAPM_POST_PMD:
  878. /* 1 msec delay as per HW requirement */
  879. usleep_range(1000, 1010);
  880. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
  881. WCD938X_AUX_PDM_WD_EN_MASK, 0);
  882. wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
  883. WCD_CLSH_EVENT_POST_PA,
  884. WCD_CLSH_STATE_AUX,
  885. hph_mode);
  886. wcd938x->flyback_cur_det_disable--;
  887. if (wcd938x->flyback_cur_det_disable == 0)
  888. snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
  889. WCD938X_EN_CUR_DET_MASK, 1);
  890. break;
  891. }
  892. return 0;
  893. }
  894. static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
  895. struct snd_kcontrol *kcontrol, int event)
  896. {
  897. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  898. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  899. int hph_mode = wcd938x->hph_mode;
  900. switch (event) {
  901. case SND_SOC_DAPM_PRE_PMU:
  902. /*
  903. * Enable watchdog interrupt for HPHL or AUX
  904. * depending on mux value
  905. */
  906. wcd938x->ear_rx_path = snd_soc_component_read(component,
  907. WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
  908. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
  909. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
  910. WCD938X_AUX_PDM_WD_EN_MASK, 1);
  911. else
  912. snd_soc_component_write_field(component,
  913. WCD938X_DIGITAL_PDM_WD_CTL0,
  914. WCD938X_PDM_WD_EN_MASK, 0x3);
  915. if (!wcd938x->comp1_enable)
  916. snd_soc_component_write_field(component,
  917. WCD938X_ANA_EAR_COMPANDER_CTL,
  918. WCD938X_GAIN_OVRD_REG_MASK, 1);
  919. break;
  920. case SND_SOC_DAPM_POST_PMU:
  921. /* 6 msec delay as per HW requirement */
  922. usleep_range(6000, 6010);
  923. if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
  924. hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
  925. snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
  926. WCD938X_REGULATOR_MODE_MASK,
  927. WCD938X_REGULATOR_MODE_CLASS_AB);
  928. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
  929. enable_irq(wcd938x->aux_pdm_wd_int);
  930. else
  931. enable_irq(wcd938x->hphl_pdm_wd_int);
  932. break;
  933. case SND_SOC_DAPM_PRE_PMD:
  934. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
  935. disable_irq_nosync(wcd938x->aux_pdm_wd_int);
  936. else
  937. disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
  938. break;
  939. case SND_SOC_DAPM_POST_PMD:
  940. if (!wcd938x->comp1_enable)
  941. snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
  942. WCD938X_GAIN_OVRD_REG_MASK, 0);
  943. /* 7 msec delay as per HW requirement */
  944. usleep_range(7000, 7010);
  945. if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
  946. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
  947. WCD938X_AUX_PDM_WD_EN_MASK, 0);
  948. else
  949. snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
  950. WCD938X_PDM_WD_EN_MASK, 0);
  951. wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
  952. WCD_CLSH_STATE_EAR, hph_mode);
  953. wcd938x->flyback_cur_det_disable--;
  954. if (wcd938x->flyback_cur_det_disable == 0)
  955. snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
  956. WCD938X_EN_CUR_DET_MASK, 1);
  957. break;
  958. }
  959. return 0;
  960. }
  961. static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
  962. struct snd_kcontrol *kcontrol,
  963. int event)
  964. {
  965. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  966. u16 dmic_clk_reg, dmic_clk_en_reg;
  967. u8 dmic_sel_mask, dmic_clk_mask;
  968. switch (w->shift) {
  969. case 0:
  970. case 1:
  971. dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
  972. dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL;
  973. dmic_clk_mask = WCD938X_DMIC1_RATE_MASK;
  974. dmic_sel_mask = WCD938X_AMIC1_IN_SEL_MASK;
  975. break;
  976. case 2:
  977. case 3:
  978. dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
  979. dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL;
  980. dmic_clk_mask = WCD938X_DMIC2_RATE_MASK;
  981. dmic_sel_mask = WCD938X_AMIC3_IN_SEL_MASK;
  982. break;
  983. case 4:
  984. case 5:
  985. dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
  986. dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL;
  987. dmic_clk_mask = WCD938X_DMIC3_RATE_MASK;
  988. dmic_sel_mask = WCD938X_AMIC4_IN_SEL_MASK;
  989. break;
  990. case 6:
  991. case 7:
  992. dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
  993. dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL;
  994. dmic_clk_mask = WCD938X_DMIC4_RATE_MASK;
  995. dmic_sel_mask = WCD938X_AMIC5_IN_SEL_MASK;
  996. break;
  997. default:
  998. dev_err(component->dev, "%s: Invalid DMIC Selection\n",
  999. __func__);
  1000. return -EINVAL;
  1001. }
  1002. switch (event) {
  1003. case SND_SOC_DAPM_PRE_PMU:
  1004. snd_soc_component_write_field(component,
  1005. WCD938X_DIGITAL_CDC_AMIC_CTL,
  1006. dmic_sel_mask,
  1007. WCD938X_AMIC1_IN_SEL_DMIC);
  1008. /* 250us sleep as per HW requirement */
  1009. usleep_range(250, 260);
  1010. /* Setting DMIC clock rate to 2.4MHz */
  1011. snd_soc_component_write_field(component, dmic_clk_reg,
  1012. dmic_clk_mask,
  1013. WCD938X_DMIC4_RATE_2P4MHZ);
  1014. snd_soc_component_write_field(component, dmic_clk_en_reg,
  1015. WCD938X_DMIC_CLK_EN_MASK, 1);
  1016. /* enable clock scaling */
  1017. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_DMIC_CTL,
  1018. WCD938X_DMIC_CLK_SCALING_EN_MASK, 0x3);
  1019. break;
  1020. case SND_SOC_DAPM_POST_PMD:
  1021. snd_soc_component_write_field(component,
  1022. WCD938X_DIGITAL_CDC_AMIC_CTL,
  1023. dmic_sel_mask, WCD938X_AMIC1_IN_SEL_AMIC);
  1024. snd_soc_component_write_field(component, dmic_clk_en_reg,
  1025. WCD938X_DMIC_CLK_EN_MASK, 0);
  1026. break;
  1027. }
  1028. return 0;
  1029. }
  1030. static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
  1031. struct snd_kcontrol *kcontrol, int event)
  1032. {
  1033. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  1034. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1035. int bank;
  1036. int rate;
  1037. bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1;
  1038. bank = bank ? 0 : 1;
  1039. switch (event) {
  1040. case SND_SOC_DAPM_PRE_PMU:
  1041. if (strnstr(w->name, "ADC", sizeof("ADC"))) {
  1042. int i = 0, mode = 0;
  1043. if (test_bit(WCD_ADC1, &wcd938x->status_mask))
  1044. mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
  1045. if (test_bit(WCD_ADC2, &wcd938x->status_mask))
  1046. mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
  1047. if (test_bit(WCD_ADC3, &wcd938x->status_mask))
  1048. mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
  1049. if (test_bit(WCD_ADC4, &wcd938x->status_mask))
  1050. mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
  1051. if (mode != 0) {
  1052. for (i = 0; i < ADC_MODE_ULP2; i++) {
  1053. if (mode & (1 << i)) {
  1054. i++;
  1055. break;
  1056. }
  1057. }
  1058. }
  1059. rate = wcd938x_get_clk_rate(i);
  1060. wcd938x_set_swr_clk_rate(component, rate, bank);
  1061. /* Copy clk settings to active bank */
  1062. wcd938x_set_swr_clk_rate(component, rate, !bank);
  1063. }
  1064. break;
  1065. case SND_SOC_DAPM_POST_PMD:
  1066. if (strnstr(w->name, "ADC", sizeof("ADC"))) {
  1067. rate = wcd938x_get_clk_rate(ADC_MODE_INVALID);
  1068. wcd938x_set_swr_clk_rate(component, rate, !bank);
  1069. wcd938x_set_swr_clk_rate(component, rate, bank);
  1070. }
  1071. break;
  1072. }
  1073. return 0;
  1074. }
  1075. static int wcd938x_get_adc_mode(int val)
  1076. {
  1077. int ret = 0;
  1078. switch (val) {
  1079. case ADC_MODE_INVALID:
  1080. ret = ADC_MODE_VAL_NORMAL;
  1081. break;
  1082. case ADC_MODE_HIFI:
  1083. ret = ADC_MODE_VAL_HIFI;
  1084. break;
  1085. case ADC_MODE_LO_HIF:
  1086. ret = ADC_MODE_VAL_LO_HIF;
  1087. break;
  1088. case ADC_MODE_NORMAL:
  1089. ret = ADC_MODE_VAL_NORMAL;
  1090. break;
  1091. case ADC_MODE_LP:
  1092. ret = ADC_MODE_VAL_LP;
  1093. break;
  1094. case ADC_MODE_ULP1:
  1095. ret = ADC_MODE_VAL_ULP1;
  1096. break;
  1097. case ADC_MODE_ULP2:
  1098. ret = ADC_MODE_VAL_ULP2;
  1099. break;
  1100. default:
  1101. ret = -EINVAL;
  1102. break;
  1103. }
  1104. return ret;
  1105. }
  1106. static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
  1107. struct snd_kcontrol *kcontrol, int event)
  1108. {
  1109. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  1110. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1111. switch (event) {
  1112. case SND_SOC_DAPM_PRE_PMU:
  1113. snd_soc_component_write_field(component,
  1114. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  1115. WCD938X_ANA_TX_CLK_EN_MASK, 1);
  1116. snd_soc_component_write_field(component,
  1117. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  1118. WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
  1119. set_bit(w->shift, &wcd938x->status_mask);
  1120. break;
  1121. case SND_SOC_DAPM_POST_PMD:
  1122. snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  1123. WCD938X_ANA_TX_CLK_EN_MASK, 0);
  1124. clear_bit(w->shift, &wcd938x->status_mask);
  1125. break;
  1126. }
  1127. return 0;
  1128. }
  1129. static void wcd938x_tx_channel_config(struct snd_soc_component *component,
  1130. int channel, int mode)
  1131. {
  1132. int reg, mask;
  1133. switch (channel) {
  1134. case 0:
  1135. reg = WCD938X_ANA_TX_CH2;
  1136. mask = WCD938X_HPF1_INIT_MASK;
  1137. break;
  1138. case 1:
  1139. reg = WCD938X_ANA_TX_CH2;
  1140. mask = WCD938X_HPF2_INIT_MASK;
  1141. break;
  1142. case 2:
  1143. reg = WCD938X_ANA_TX_CH4;
  1144. mask = WCD938X_HPF3_INIT_MASK;
  1145. break;
  1146. case 3:
  1147. reg = WCD938X_ANA_TX_CH4;
  1148. mask = WCD938X_HPF4_INIT_MASK;
  1149. break;
  1150. default:
  1151. return;
  1152. }
  1153. snd_soc_component_write_field(component, reg, mask, mode);
  1154. }
  1155. static int wcd938x_adc_enable_req(struct snd_soc_dapm_widget *w,
  1156. struct snd_kcontrol *kcontrol, int event)
  1157. {
  1158. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  1159. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1160. int mode;
  1161. switch (event) {
  1162. case SND_SOC_DAPM_PRE_PMU:
  1163. snd_soc_component_write_field(component,
  1164. WCD938X_DIGITAL_CDC_REQ_CTL,
  1165. WCD938X_FS_RATE_4P8_MASK, 1);
  1166. snd_soc_component_write_field(component,
  1167. WCD938X_DIGITAL_CDC_REQ_CTL,
  1168. WCD938X_NO_NOTCH_MASK, 0);
  1169. wcd938x_tx_channel_config(component, w->shift, 1);
  1170. mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
  1171. if (mode < 0) {
  1172. dev_info(component->dev, "Invalid ADC mode\n");
  1173. return -EINVAL;
  1174. }
  1175. switch (w->shift) {
  1176. case 0:
  1177. snd_soc_component_write_field(component,
  1178. WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
  1179. WCD938X_TXD0_MODE_MASK, mode);
  1180. snd_soc_component_write_field(component,
  1181. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1182. WCD938X_TXD0_CLK_EN_MASK, 1);
  1183. break;
  1184. case 1:
  1185. snd_soc_component_write_field(component,
  1186. WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
  1187. WCD938X_TXD1_MODE_MASK, mode);
  1188. snd_soc_component_write_field(component,
  1189. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1190. WCD938X_TXD1_CLK_EN_MASK, 1);
  1191. break;
  1192. case 2:
  1193. snd_soc_component_write_field(component,
  1194. WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
  1195. WCD938X_TXD2_MODE_MASK, mode);
  1196. snd_soc_component_write_field(component,
  1197. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1198. WCD938X_TXD2_CLK_EN_MASK, 1);
  1199. break;
  1200. case 3:
  1201. snd_soc_component_write_field(component,
  1202. WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
  1203. WCD938X_TXD3_MODE_MASK, mode);
  1204. snd_soc_component_write_field(component,
  1205. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1206. WCD938X_TXD3_CLK_EN_MASK, 1);
  1207. break;
  1208. default:
  1209. break;
  1210. }
  1211. wcd938x_tx_channel_config(component, w->shift, 0);
  1212. break;
  1213. case SND_SOC_DAPM_POST_PMD:
  1214. switch (w->shift) {
  1215. case 0:
  1216. snd_soc_component_write_field(component,
  1217. WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
  1218. WCD938X_TXD0_MODE_MASK, 0);
  1219. snd_soc_component_write_field(component,
  1220. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1221. WCD938X_TXD0_CLK_EN_MASK, 0);
  1222. break;
  1223. case 1:
  1224. snd_soc_component_write_field(component,
  1225. WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
  1226. WCD938X_TXD1_MODE_MASK, 0);
  1227. snd_soc_component_write_field(component,
  1228. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1229. WCD938X_TXD1_CLK_EN_MASK, 0);
  1230. break;
  1231. case 2:
  1232. snd_soc_component_write_field(component,
  1233. WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
  1234. WCD938X_TXD2_MODE_MASK, 0);
  1235. snd_soc_component_write_field(component,
  1236. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1237. WCD938X_TXD2_CLK_EN_MASK, 0);
  1238. break;
  1239. case 3:
  1240. snd_soc_component_write_field(component,
  1241. WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
  1242. WCD938X_TXD3_MODE_MASK, 0);
  1243. snd_soc_component_write_field(component,
  1244. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1245. WCD938X_TXD3_CLK_EN_MASK, 0);
  1246. break;
  1247. default:
  1248. break;
  1249. }
  1250. snd_soc_component_write_field(component,
  1251. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  1252. WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 0);
  1253. break;
  1254. }
  1255. return 0;
  1256. }
  1257. static int wcd938x_micbias_control(struct snd_soc_component *component,
  1258. int micb_num, int req, bool is_dapm)
  1259. {
  1260. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1261. int micb_index = micb_num - 1;
  1262. u16 micb_reg;
  1263. switch (micb_num) {
  1264. case MIC_BIAS_1:
  1265. micb_reg = WCD938X_ANA_MICB1;
  1266. break;
  1267. case MIC_BIAS_2:
  1268. micb_reg = WCD938X_ANA_MICB2;
  1269. break;
  1270. case MIC_BIAS_3:
  1271. micb_reg = WCD938X_ANA_MICB3;
  1272. break;
  1273. case MIC_BIAS_4:
  1274. micb_reg = WCD938X_ANA_MICB4;
  1275. break;
  1276. default:
  1277. dev_err(component->dev, "%s: Invalid micbias number: %d\n",
  1278. __func__, micb_num);
  1279. return -EINVAL;
  1280. }
  1281. switch (req) {
  1282. case MICB_PULLUP_ENABLE:
  1283. wcd938x->pullup_ref[micb_index]++;
  1284. if ((wcd938x->pullup_ref[micb_index] == 1) &&
  1285. (wcd938x->micb_ref[micb_index] == 0))
  1286. snd_soc_component_write_field(component, micb_reg,
  1287. WCD938X_MICB_EN_MASK,
  1288. WCD938X_MICB_PULL_UP);
  1289. break;
  1290. case MICB_PULLUP_DISABLE:
  1291. if (wcd938x->pullup_ref[micb_index] > 0)
  1292. wcd938x->pullup_ref[micb_index]--;
  1293. if ((wcd938x->pullup_ref[micb_index] == 0) &&
  1294. (wcd938x->micb_ref[micb_index] == 0))
  1295. snd_soc_component_write_field(component, micb_reg,
  1296. WCD938X_MICB_EN_MASK, 0);
  1297. break;
  1298. case MICB_ENABLE:
  1299. wcd938x->micb_ref[micb_index]++;
  1300. if (wcd938x->micb_ref[micb_index] == 1) {
  1301. snd_soc_component_write_field(component,
  1302. WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
  1303. WCD938X_TX_CLK_EN_MASK, 0xF);
  1304. snd_soc_component_write_field(component,
  1305. WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
  1306. WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
  1307. snd_soc_component_write_field(component,
  1308. WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL,
  1309. WCD938X_TX_SC_CLK_EN_MASK, 1);
  1310. snd_soc_component_write_field(component, micb_reg,
  1311. WCD938X_MICB_EN_MASK,
  1312. WCD938X_MICB_ENABLE);
  1313. if (micb_num == MIC_BIAS_2)
  1314. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  1315. WCD_EVENT_POST_MICBIAS_2_ON);
  1316. }
  1317. if (micb_num == MIC_BIAS_2 && is_dapm)
  1318. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  1319. WCD_EVENT_POST_DAPM_MICBIAS_2_ON);
  1320. break;
  1321. case MICB_DISABLE:
  1322. if (wcd938x->micb_ref[micb_index] > 0)
  1323. wcd938x->micb_ref[micb_index]--;
  1324. if ((wcd938x->micb_ref[micb_index] == 0) &&
  1325. (wcd938x->pullup_ref[micb_index] > 0))
  1326. snd_soc_component_write_field(component, micb_reg,
  1327. WCD938X_MICB_EN_MASK,
  1328. WCD938X_MICB_PULL_UP);
  1329. else if ((wcd938x->micb_ref[micb_index] == 0) &&
  1330. (wcd938x->pullup_ref[micb_index] == 0)) {
  1331. if (micb_num == MIC_BIAS_2)
  1332. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  1333. WCD_EVENT_PRE_MICBIAS_2_OFF);
  1334. snd_soc_component_write_field(component, micb_reg,
  1335. WCD938X_MICB_EN_MASK, 0);
  1336. if (micb_num == MIC_BIAS_2)
  1337. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  1338. WCD_EVENT_POST_MICBIAS_2_OFF);
  1339. }
  1340. if (is_dapm && micb_num == MIC_BIAS_2)
  1341. wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
  1342. WCD_EVENT_POST_DAPM_MICBIAS_2_OFF);
  1343. break;
  1344. }
  1345. return 0;
  1346. }
  1347. static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
  1348. struct snd_kcontrol *kcontrol,
  1349. int event)
  1350. {
  1351. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  1352. int micb_num = w->shift;
  1353. switch (event) {
  1354. case SND_SOC_DAPM_PRE_PMU:
  1355. wcd938x_micbias_control(component, micb_num, MICB_ENABLE, true);
  1356. break;
  1357. case SND_SOC_DAPM_POST_PMU:
  1358. /* 1 msec delay as per HW requirement */
  1359. usleep_range(1000, 1100);
  1360. break;
  1361. case SND_SOC_DAPM_POST_PMD:
  1362. wcd938x_micbias_control(component, micb_num, MICB_DISABLE, true);
  1363. break;
  1364. }
  1365. return 0;
  1366. }
  1367. static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
  1368. struct snd_kcontrol *kcontrol,
  1369. int event)
  1370. {
  1371. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  1372. int micb_num = w->shift;
  1373. switch (event) {
  1374. case SND_SOC_DAPM_PRE_PMU:
  1375. wcd938x_micbias_control(component, micb_num,
  1376. MICB_PULLUP_ENABLE, true);
  1377. break;
  1378. case SND_SOC_DAPM_POST_PMU:
  1379. /* 1 msec delay as per HW requirement */
  1380. usleep_range(1000, 1100);
  1381. break;
  1382. case SND_SOC_DAPM_POST_PMD:
  1383. wcd938x_micbias_control(component, micb_num,
  1384. MICB_PULLUP_DISABLE, true);
  1385. break;
  1386. }
  1387. return 0;
  1388. }
  1389. static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
  1390. struct snd_ctl_elem_value *ucontrol)
  1391. {
  1392. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1393. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1394. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  1395. int path = e->shift_l;
  1396. ucontrol->value.enumerated.item[0] = wcd938x->tx_mode[path];
  1397. return 0;
  1398. }
  1399. static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol,
  1400. struct snd_ctl_elem_value *ucontrol)
  1401. {
  1402. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1403. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1404. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  1405. int path = e->shift_l;
  1406. if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0])
  1407. return 0;
  1408. wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0];
  1409. return 1;
  1410. }
  1411. static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
  1412. struct snd_ctl_elem_value *ucontrol)
  1413. {
  1414. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1415. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1416. ucontrol->value.enumerated.item[0] = wcd938x->hph_mode;
  1417. return 0;
  1418. }
  1419. static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
  1420. struct snd_ctl_elem_value *ucontrol)
  1421. {
  1422. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1423. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1424. if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0])
  1425. return 0;
  1426. wcd938x->hph_mode = ucontrol->value.enumerated.item[0];
  1427. return 1;
  1428. }
  1429. static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
  1430. struct snd_ctl_elem_value *ucontrol)
  1431. {
  1432. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1433. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1434. if (wcd938x->comp1_enable) {
  1435. dev_err(component->dev, "Can not set EAR PA Gain, compander1 is enabled\n");
  1436. return -EINVAL;
  1437. }
  1438. snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
  1439. WCD938X_EAR_GAIN_MASK,
  1440. ucontrol->value.integer.value[0]);
  1441. return 1;
  1442. }
  1443. static int wcd938x_get_compander(struct snd_kcontrol *kcontrol,
  1444. struct snd_ctl_elem_value *ucontrol)
  1445. {
  1446. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1447. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1448. struct soc_mixer_control *mc;
  1449. bool hphr;
  1450. mc = (struct soc_mixer_control *)(kcontrol->private_value);
  1451. hphr = mc->shift;
  1452. if (hphr)
  1453. ucontrol->value.integer.value[0] = wcd938x->comp2_enable;
  1454. else
  1455. ucontrol->value.integer.value[0] = wcd938x->comp1_enable;
  1456. return 0;
  1457. }
  1458. static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
  1459. struct snd_ctl_elem_value *ucontrol)
  1460. {
  1461. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1462. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1463. struct wcd938x_sdw_priv *wcd;
  1464. int value = ucontrol->value.integer.value[0];
  1465. int portidx;
  1466. struct soc_mixer_control *mc;
  1467. bool hphr;
  1468. mc = (struct soc_mixer_control *)(kcontrol->private_value);
  1469. hphr = mc->shift;
  1470. wcd = wcd938x->sdw_priv[AIF1_PB];
  1471. if (hphr)
  1472. wcd938x->comp2_enable = value;
  1473. else
  1474. wcd938x->comp1_enable = value;
  1475. portidx = wcd->ch_info[mc->reg].port_num;
  1476. if (value)
  1477. wcd938x_connect_port(wcd, portidx, mc->reg, true);
  1478. else
  1479. wcd938x_connect_port(wcd, portidx, mc->reg, false);
  1480. return 1;
  1481. }
  1482. static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
  1483. struct snd_ctl_elem_value *ucontrol)
  1484. {
  1485. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1486. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1487. ucontrol->value.integer.value[0] = wcd938x->ldoh;
  1488. return 0;
  1489. }
  1490. static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol,
  1491. struct snd_ctl_elem_value *ucontrol)
  1492. {
  1493. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1494. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1495. if (wcd938x->ldoh == ucontrol->value.integer.value[0])
  1496. return 0;
  1497. wcd938x->ldoh = ucontrol->value.integer.value[0];
  1498. return 1;
  1499. }
  1500. static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol,
  1501. struct snd_ctl_elem_value *ucontrol)
  1502. {
  1503. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1504. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1505. ucontrol->value.integer.value[0] = wcd938x->bcs_dis;
  1506. return 0;
  1507. }
  1508. static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol,
  1509. struct snd_ctl_elem_value *ucontrol)
  1510. {
  1511. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  1512. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1513. if (wcd938x->bcs_dis == ucontrol->value.integer.value[0])
  1514. return 0;
  1515. wcd938x->bcs_dis = ucontrol->value.integer.value[0];
  1516. return 1;
  1517. }
  1518. static const char * const tx_mode_mux_text_wcd9380[] = {
  1519. "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
  1520. };
  1521. static const char * const tx_mode_mux_text[] = {
  1522. "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
  1523. "ADC_ULP1", "ADC_ULP2",
  1524. };
  1525. static const char * const rx_hph_mode_mux_text_wcd9380[] = {
  1526. "CLS_H_INVALID", "CLS_H_INVALID_1", "CLS_H_LP", "CLS_AB",
  1527. "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_H_INVALID_2", "CLS_AB_LP",
  1528. "CLS_AB_LOHIFI",
  1529. };
  1530. static const char * const rx_hph_mode_mux_text[] = {
  1531. "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
  1532. "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI",
  1533. };
  1534. static const char * const adc2_mux_text[] = {
  1535. "INP2", "INP3"
  1536. };
  1537. static const char * const adc3_mux_text[] = {
  1538. "INP4", "INP6"
  1539. };
  1540. static const char * const adc4_mux_text[] = {
  1541. "INP5", "INP7"
  1542. };
  1543. static const char * const rdac3_mux_text[] = {
  1544. "RX1", "RX3"
  1545. };
  1546. static const char * const hdr12_mux_text[] = {
  1547. "NO_HDR12", "HDR12"
  1548. };
  1549. static const char * const hdr34_mux_text[] = {
  1550. "NO_HDR34", "HDR34"
  1551. };
  1552. static const struct soc_enum tx0_mode_enum_wcd9380 =
  1553. SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
  1554. tx_mode_mux_text_wcd9380);
  1555. static const struct soc_enum tx1_mode_enum_wcd9380 =
  1556. SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
  1557. tx_mode_mux_text_wcd9380);
  1558. static const struct soc_enum tx2_mode_enum_wcd9380 =
  1559. SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
  1560. tx_mode_mux_text_wcd9380);
  1561. static const struct soc_enum tx3_mode_enum_wcd9380 =
  1562. SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
  1563. tx_mode_mux_text_wcd9380);
  1564. static const struct soc_enum tx0_mode_enum_wcd9385 =
  1565. SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text),
  1566. tx_mode_mux_text);
  1567. static const struct soc_enum tx1_mode_enum_wcd9385 =
  1568. SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text),
  1569. tx_mode_mux_text);
  1570. static const struct soc_enum tx2_mode_enum_wcd9385 =
  1571. SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text),
  1572. tx_mode_mux_text);
  1573. static const struct soc_enum tx3_mode_enum_wcd9385 =
  1574. SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text),
  1575. tx_mode_mux_text);
  1576. static const struct soc_enum rx_hph_mode_mux_enum_wcd9380 =
  1577. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9380),
  1578. rx_hph_mode_mux_text_wcd9380);
  1579. static const struct soc_enum rx_hph_mode_mux_enum =
  1580. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
  1581. rx_hph_mode_mux_text);
  1582. static const struct soc_enum adc2_enum =
  1583. SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 7,
  1584. ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
  1585. static const struct soc_enum adc3_enum =
  1586. SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 6,
  1587. ARRAY_SIZE(adc3_mux_text), adc3_mux_text);
  1588. static const struct soc_enum adc4_enum =
  1589. SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 5,
  1590. ARRAY_SIZE(adc4_mux_text), adc4_mux_text);
  1591. static const struct soc_enum hdr12_enum =
  1592. SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 4,
  1593. ARRAY_SIZE(hdr12_mux_text), hdr12_mux_text);
  1594. static const struct soc_enum hdr34_enum =
  1595. SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 3,
  1596. ARRAY_SIZE(hdr34_mux_text), hdr34_mux_text);
  1597. static const struct soc_enum rdac3_enum =
  1598. SOC_ENUM_SINGLE(WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0,
  1599. ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text);
  1600. static const struct snd_kcontrol_new adc1_switch[] = {
  1601. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1602. };
  1603. static const struct snd_kcontrol_new adc2_switch[] = {
  1604. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1605. };
  1606. static const struct snd_kcontrol_new adc3_switch[] = {
  1607. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1608. };
  1609. static const struct snd_kcontrol_new adc4_switch[] = {
  1610. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1611. };
  1612. static const struct snd_kcontrol_new dmic1_switch[] = {
  1613. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1614. };
  1615. static const struct snd_kcontrol_new dmic2_switch[] = {
  1616. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1617. };
  1618. static const struct snd_kcontrol_new dmic3_switch[] = {
  1619. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1620. };
  1621. static const struct snd_kcontrol_new dmic4_switch[] = {
  1622. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1623. };
  1624. static const struct snd_kcontrol_new dmic5_switch[] = {
  1625. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1626. };
  1627. static const struct snd_kcontrol_new dmic6_switch[] = {
  1628. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1629. };
  1630. static const struct snd_kcontrol_new dmic7_switch[] = {
  1631. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1632. };
  1633. static const struct snd_kcontrol_new dmic8_switch[] = {
  1634. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1635. };
  1636. static const struct snd_kcontrol_new ear_rdac_switch[] = {
  1637. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1638. };
  1639. static const struct snd_kcontrol_new aux_rdac_switch[] = {
  1640. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1641. };
  1642. static const struct snd_kcontrol_new hphl_rdac_switch[] = {
  1643. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1644. };
  1645. static const struct snd_kcontrol_new hphr_rdac_switch[] = {
  1646. SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
  1647. };
  1648. static const struct snd_kcontrol_new tx_adc2_mux =
  1649. SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
  1650. static const struct snd_kcontrol_new tx_adc3_mux =
  1651. SOC_DAPM_ENUM("ADC3 MUX Mux", adc3_enum);
  1652. static const struct snd_kcontrol_new tx_adc4_mux =
  1653. SOC_DAPM_ENUM("ADC4 MUX Mux", adc4_enum);
  1654. static const struct snd_kcontrol_new tx_hdr12_mux =
  1655. SOC_DAPM_ENUM("HDR12 MUX Mux", hdr12_enum);
  1656. static const struct snd_kcontrol_new tx_hdr34_mux =
  1657. SOC_DAPM_ENUM("HDR34 MUX Mux", hdr34_enum);
  1658. static const struct snd_kcontrol_new rx_rdac3_mux =
  1659. SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum);
  1660. static const struct snd_kcontrol_new wcd9380_snd_controls[] = {
  1661. SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9380,
  1662. wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
  1663. SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9380,
  1664. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1665. SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9380,
  1666. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1667. SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9380,
  1668. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1669. SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9380,
  1670. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1671. };
  1672. static const struct snd_kcontrol_new wcd9385_snd_controls[] = {
  1673. SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
  1674. wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
  1675. SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9385,
  1676. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1677. SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9385,
  1678. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1679. SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9385,
  1680. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1681. SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9385,
  1682. wcd938x_tx_mode_get, wcd938x_tx_mode_put),
  1683. };
  1684. static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol,
  1685. struct snd_ctl_elem_value *ucontrol)
  1686. {
  1687. struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
  1688. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
  1689. struct wcd938x_sdw_priv *wcd;
  1690. struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
  1691. int dai_id = mixer->shift;
  1692. int portidx, ch_idx = mixer->reg;
  1693. wcd = wcd938x->sdw_priv[dai_id];
  1694. portidx = wcd->ch_info[ch_idx].port_num;
  1695. ucontrol->value.integer.value[0] = wcd->port_enable[portidx];
  1696. return 0;
  1697. }
  1698. static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
  1699. struct snd_ctl_elem_value *ucontrol)
  1700. {
  1701. struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
  1702. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
  1703. struct wcd938x_sdw_priv *wcd;
  1704. struct soc_mixer_control *mixer =
  1705. (struct soc_mixer_control *)kcontrol->private_value;
  1706. int ch_idx = mixer->reg;
  1707. int portidx;
  1708. int dai_id = mixer->shift;
  1709. bool enable;
  1710. wcd = wcd938x->sdw_priv[dai_id];
  1711. portidx = wcd->ch_info[ch_idx].port_num;
  1712. if (ucontrol->value.integer.value[0])
  1713. enable = true;
  1714. else
  1715. enable = false;
  1716. wcd->port_enable[portidx] = enable;
  1717. wcd938x_connect_port(wcd, portidx, ch_idx, enable);
  1718. return 1;
  1719. }
  1720. /* MBHC related */
  1721. static void wcd938x_mbhc_clk_setup(struct snd_soc_component *component,
  1722. bool enable)
  1723. {
  1724. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_1,
  1725. WCD938X_MBHC_CTL_RCO_EN_MASK, enable);
  1726. }
  1727. static void wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component *component,
  1728. bool enable)
  1729. {
  1730. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_ELECT,
  1731. WCD938X_ANA_MBHC_BIAS_EN, enable);
  1732. }
  1733. static void wcd938x_mbhc_program_btn_thr(struct snd_soc_component *component,
  1734. int *btn_low, int *btn_high,
  1735. int num_btn, bool is_micbias)
  1736. {
  1737. int i, vth;
  1738. if (num_btn > WCD_MBHC_DEF_BUTTONS) {
  1739. dev_err(component->dev, "%s: invalid number of buttons: %d\n",
  1740. __func__, num_btn);
  1741. return;
  1742. }
  1743. for (i = 0; i < num_btn; i++) {
  1744. vth = ((btn_high[i] * 2) / 25) & 0x3F;
  1745. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_BTN0 + i,
  1746. WCD938X_MBHC_BTN_VTH_MASK, vth);
  1747. dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n",
  1748. __func__, i, btn_high[i], vth);
  1749. }
  1750. }
  1751. static bool wcd938x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
  1752. {
  1753. u8 val;
  1754. if (micb_num == MIC_BIAS_2) {
  1755. val = snd_soc_component_read_field(component,
  1756. WCD938X_ANA_MICB2,
  1757. WCD938X_ANA_MICB2_ENABLE_MASK);
  1758. if (val == WCD938X_MICB_ENABLE)
  1759. return true;
  1760. }
  1761. return false;
  1762. }
  1763. static void wcd938x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component,
  1764. int pull_up_cur)
  1765. {
  1766. /* Default pull up current to 2uA */
  1767. if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA)
  1768. pull_up_cur = HS_PULLUP_I_2P0_UA;
  1769. snd_soc_component_write_field(component,
  1770. WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT,
  1771. WCD938X_HSDET_PULLUP_C_MASK, pull_up_cur);
  1772. }
  1773. static int wcd938x_mbhc_request_micbias(struct snd_soc_component *component,
  1774. int micb_num, int req)
  1775. {
  1776. return wcd938x_micbias_control(component, micb_num, req, false);
  1777. }
  1778. static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
  1779. bool enable)
  1780. {
  1781. if (enable) {
  1782. snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
  1783. WCD938X_RAMP_SHIFT_CTRL_MASK, 0x0C);
  1784. snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
  1785. WCD938X_RAMP_EN_MASK, 1);
  1786. } else {
  1787. snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
  1788. WCD938X_RAMP_EN_MASK, 0);
  1789. snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
  1790. WCD938X_RAMP_SHIFT_CTRL_MASK, 0);
  1791. }
  1792. }
  1793. static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv)
  1794. {
  1795. /* min micbias voltage is 1V and maximum is 2.85V */
  1796. if (micb_mv < 1000 || micb_mv > 2850)
  1797. return -EINVAL;
  1798. return (micb_mv - 1000) / 50;
  1799. }
  1800. static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
  1801. int req_volt, int micb_num)
  1802. {
  1803. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1804. int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
  1805. switch (micb_num) {
  1806. case MIC_BIAS_1:
  1807. micb_reg = WCD938X_ANA_MICB1;
  1808. break;
  1809. case MIC_BIAS_2:
  1810. micb_reg = WCD938X_ANA_MICB2;
  1811. break;
  1812. case MIC_BIAS_3:
  1813. micb_reg = WCD938X_ANA_MICB3;
  1814. break;
  1815. case MIC_BIAS_4:
  1816. micb_reg = WCD938X_ANA_MICB4;
  1817. break;
  1818. default:
  1819. return -EINVAL;
  1820. }
  1821. mutex_lock(&wcd938x->micb_lock);
  1822. /*
  1823. * If requested micbias voltage is same as current micbias
  1824. * voltage, then just return. Otherwise, adjust voltage as
  1825. * per requested value. If micbias is already enabled, then
  1826. * to avoid slow micbias ramp-up or down enable pull-up
  1827. * momentarily, change the micbias value and then re-enable
  1828. * micbias.
  1829. */
  1830. micb_en = snd_soc_component_read_field(component, micb_reg,
  1831. WCD938X_MICB_EN_MASK);
  1832. cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
  1833. WCD938X_MICB_VOUT_MASK);
  1834. req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt);
  1835. if (req_vout_ctl < 0) {
  1836. ret = -EINVAL;
  1837. goto exit;
  1838. }
  1839. if (cur_vout_ctl == req_vout_ctl) {
  1840. ret = 0;
  1841. goto exit;
  1842. }
  1843. if (micb_en == WCD938X_MICB_ENABLE)
  1844. snd_soc_component_write_field(component, micb_reg,
  1845. WCD938X_MICB_EN_MASK,
  1846. WCD938X_MICB_PULL_UP);
  1847. snd_soc_component_write_field(component, micb_reg,
  1848. WCD938X_MICB_VOUT_MASK,
  1849. req_vout_ctl);
  1850. if (micb_en == WCD938X_MICB_ENABLE) {
  1851. snd_soc_component_write_field(component, micb_reg,
  1852. WCD938X_MICB_EN_MASK,
  1853. WCD938X_MICB_ENABLE);
  1854. /*
  1855. * Add 2ms delay as per HW requirement after enabling
  1856. * micbias
  1857. */
  1858. usleep_range(2000, 2100);
  1859. }
  1860. exit:
  1861. mutex_unlock(&wcd938x->micb_lock);
  1862. return ret;
  1863. }
  1864. static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
  1865. int micb_num, bool req_en)
  1866. {
  1867. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1868. int micb_mv;
  1869. if (micb_num != MIC_BIAS_2)
  1870. return -EINVAL;
  1871. /*
  1872. * If device tree micbias level is already above the minimum
  1873. * voltage needed to detect threshold microphone, then do
  1874. * not change the micbias, just return.
  1875. */
  1876. if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
  1877. return 0;
  1878. micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
  1879. return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
  1880. }
  1881. static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x,
  1882. s16 *d1_a, u16 noff,
  1883. int32_t *zdet)
  1884. {
  1885. int i;
  1886. int val, val1;
  1887. s16 c1;
  1888. s32 x1, d1;
  1889. int32_t denom;
  1890. int minCode_param[] = {
  1891. 3277, 1639, 820, 410, 205, 103, 52, 26
  1892. };
  1893. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20);
  1894. for (i = 0; i < WCD938X_ZDET_NUM_MEASUREMENTS; i++) {
  1895. regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val);
  1896. if (val & 0x80)
  1897. break;
  1898. }
  1899. val = val << 0x8;
  1900. regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1);
  1901. val |= val1;
  1902. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00);
  1903. x1 = WCD938X_MBHC_GET_X1(val);
  1904. c1 = WCD938X_MBHC_GET_C1(val);
  1905. /* If ramp is not complete, give additional 5ms */
  1906. if ((c1 < 2) && x1)
  1907. usleep_range(5000, 5050);
  1908. if (!c1 || !x1) {
  1909. pr_err("%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
  1910. __func__, c1, x1);
  1911. goto ramp_down;
  1912. }
  1913. d1 = d1_a[c1];
  1914. denom = (x1 * d1) - (1 << (14 - noff));
  1915. if (denom > 0)
  1916. *zdet = (WCD938X_MBHC_ZDET_CONST * 1000) / denom;
  1917. else if (x1 < minCode_param[noff])
  1918. *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE;
  1919. pr_debug("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n",
  1920. __func__, d1, c1, x1, *zdet);
  1921. ramp_down:
  1922. i = 0;
  1923. while (x1) {
  1924. regmap_read(wcd938x->regmap,
  1925. WCD938X_ANA_MBHC_RESULT_1, &val);
  1926. regmap_read(wcd938x->regmap,
  1927. WCD938X_ANA_MBHC_RESULT_2, &val1);
  1928. val = val << 0x08;
  1929. val |= val1;
  1930. x1 = WCD938X_MBHC_GET_X1(val);
  1931. i++;
  1932. if (i == WCD938X_ZDET_NUM_MEASUREMENTS)
  1933. break;
  1934. }
  1935. }
  1936. static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component,
  1937. struct wcd938x_mbhc_zdet_param *zdet_param,
  1938. int32_t *zl, int32_t *zr, s16 *d1_a)
  1939. {
  1940. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  1941. int32_t zdet = 0;
  1942. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
  1943. WCD938X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
  1944. snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN5,
  1945. WCD938X_VTH_MASK, zdet_param->btn5);
  1946. snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN6,
  1947. WCD938X_VTH_MASK, zdet_param->btn6);
  1948. snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN7,
  1949. WCD938X_VTH_MASK, zdet_param->btn7);
  1950. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
  1951. WCD938X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
  1952. snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_RAMP_CTL,
  1953. 0x0F, zdet_param->nshift);
  1954. if (!zl)
  1955. goto z_right;
  1956. /* Start impedance measurement for HPH_L */
  1957. regmap_update_bits(wcd938x->regmap,
  1958. WCD938X_ANA_MBHC_ZDET, 0x80, 0x80);
  1959. dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n",
  1960. __func__, zdet_param->noff);
  1961. wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
  1962. regmap_update_bits(wcd938x->regmap,
  1963. WCD938X_ANA_MBHC_ZDET, 0x80, 0x00);
  1964. *zl = zdet;
  1965. z_right:
  1966. if (!zr)
  1967. return;
  1968. /* Start impedance measurement for HPH_R */
  1969. regmap_update_bits(wcd938x->regmap,
  1970. WCD938X_ANA_MBHC_ZDET, 0x40, 0x40);
  1971. dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n",
  1972. __func__, zdet_param->noff);
  1973. wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
  1974. regmap_update_bits(wcd938x->regmap,
  1975. WCD938X_ANA_MBHC_ZDET, 0x40, 0x00);
  1976. *zr = zdet;
  1977. }
  1978. static inline void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
  1979. int32_t *z_val, int flag_l_r)
  1980. {
  1981. s16 q1;
  1982. int q1_cal;
  1983. if (*z_val < (WCD938X_ZDET_VAL_400/1000))
  1984. q1 = snd_soc_component_read(component,
  1985. WCD938X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
  1986. else
  1987. q1 = snd_soc_component_read(component,
  1988. WCD938X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
  1989. if (q1 & 0x80)
  1990. q1_cal = (10000 - ((q1 & 0x7F) * 25));
  1991. else
  1992. q1_cal = (10000 + (q1 * 25));
  1993. if (q1_cal > 0)
  1994. *z_val = ((*z_val) * 10000) / q1_cal;
  1995. }
  1996. static void wcd938x_wcd_mbhc_calc_impedance(struct snd_soc_component *component,
  1997. uint32_t *zl, uint32_t *zr)
  1998. {
  1999. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2000. s16 reg0, reg1, reg2, reg3, reg4;
  2001. int32_t z1L, z1R, z1Ls;
  2002. int zMono, z_diff1, z_diff2;
  2003. bool is_fsm_disable = false;
  2004. struct wcd938x_mbhc_zdet_param zdet_param[] = {
  2005. {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
  2006. {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
  2007. {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
  2008. {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
  2009. };
  2010. struct wcd938x_mbhc_zdet_param *zdet_param_ptr = NULL;
  2011. s16 d1_a[][4] = {
  2012. {0, 30, 90, 30},
  2013. {0, 30, 30, 5},
  2014. {0, 30, 30, 5},
  2015. {0, 30, 30, 5},
  2016. };
  2017. s16 *d1 = NULL;
  2018. reg0 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN5);
  2019. reg1 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN6);
  2020. reg2 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN7);
  2021. reg3 = snd_soc_component_read(component, WCD938X_MBHC_CTL_CLK);
  2022. reg4 = snd_soc_component_read(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL);
  2023. if (snd_soc_component_read(component, WCD938X_ANA_MBHC_ELECT) & 0x80) {
  2024. is_fsm_disable = true;
  2025. regmap_update_bits(wcd938x->regmap,
  2026. WCD938X_ANA_MBHC_ELECT, 0x80, 0x00);
  2027. }
  2028. /* For NO-jack, disable L_DET_EN before Z-det measurements */
  2029. if (wcd938x->mbhc_cfg.hphl_swh)
  2030. regmap_update_bits(wcd938x->regmap,
  2031. WCD938X_ANA_MBHC_MECH, 0x80, 0x00);
  2032. /* Turn off 100k pull down on HPHL */
  2033. regmap_update_bits(wcd938x->regmap,
  2034. WCD938X_ANA_MBHC_MECH, 0x01, 0x00);
  2035. /* Disable surge protection before impedance detection.
  2036. * This is done to give correct value for high impedance.
  2037. */
  2038. regmap_update_bits(wcd938x->regmap,
  2039. WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
  2040. /* 1ms delay needed after disable surge protection */
  2041. usleep_range(1000, 1010);
  2042. /* First get impedance on Left */
  2043. d1 = d1_a[1];
  2044. zdet_param_ptr = &zdet_param[1];
  2045. wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
  2046. if (!WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
  2047. goto left_ch_impedance;
  2048. /* Second ramp for left ch */
  2049. if (z1L < WCD938X_ZDET_VAL_32) {
  2050. zdet_param_ptr = &zdet_param[0];
  2051. d1 = d1_a[0];
  2052. } else if ((z1L > WCD938X_ZDET_VAL_400) &&
  2053. (z1L <= WCD938X_ZDET_VAL_1200)) {
  2054. zdet_param_ptr = &zdet_param[2];
  2055. d1 = d1_a[2];
  2056. } else if (z1L > WCD938X_ZDET_VAL_1200) {
  2057. zdet_param_ptr = &zdet_param[3];
  2058. d1 = d1_a[3];
  2059. }
  2060. wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
  2061. left_ch_impedance:
  2062. if ((z1L == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
  2063. (z1L > WCD938X_ZDET_VAL_100K)) {
  2064. *zl = WCD938X_ZDET_FLOATING_IMPEDANCE;
  2065. zdet_param_ptr = &zdet_param[1];
  2066. d1 = d1_a[1];
  2067. } else {
  2068. *zl = z1L/1000;
  2069. wcd938x_wcd_mbhc_qfuse_cal(component, zl, 0);
  2070. }
  2071. dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
  2072. __func__, *zl);
  2073. /* Start of right impedance ramp and calculation */
  2074. wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
  2075. if (WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
  2076. if (((z1R > WCD938X_ZDET_VAL_1200) &&
  2077. (zdet_param_ptr->noff == 0x6)) ||
  2078. ((*zl) != WCD938X_ZDET_FLOATING_IMPEDANCE))
  2079. goto right_ch_impedance;
  2080. /* Second ramp for right ch */
  2081. if (z1R < WCD938X_ZDET_VAL_32) {
  2082. zdet_param_ptr = &zdet_param[0];
  2083. d1 = d1_a[0];
  2084. } else if ((z1R > WCD938X_ZDET_VAL_400) &&
  2085. (z1R <= WCD938X_ZDET_VAL_1200)) {
  2086. zdet_param_ptr = &zdet_param[2];
  2087. d1 = d1_a[2];
  2088. } else if (z1R > WCD938X_ZDET_VAL_1200) {
  2089. zdet_param_ptr = &zdet_param[3];
  2090. d1 = d1_a[3];
  2091. }
  2092. wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
  2093. }
  2094. right_ch_impedance:
  2095. if ((z1R == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
  2096. (z1R > WCD938X_ZDET_VAL_100K)) {
  2097. *zr = WCD938X_ZDET_FLOATING_IMPEDANCE;
  2098. } else {
  2099. *zr = z1R/1000;
  2100. wcd938x_wcd_mbhc_qfuse_cal(component, zr, 1);
  2101. }
  2102. dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
  2103. __func__, *zr);
  2104. /* Mono/stereo detection */
  2105. if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) &&
  2106. (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE)) {
  2107. dev_dbg(component->dev,
  2108. "%s: plug type is invalid or extension cable\n",
  2109. __func__);
  2110. goto zdet_complete;
  2111. }
  2112. if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
  2113. (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
  2114. ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
  2115. ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
  2116. dev_dbg(component->dev,
  2117. "%s: Mono plug type with one ch floating or shorted to GND\n",
  2118. __func__);
  2119. wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
  2120. goto zdet_complete;
  2121. }
  2122. snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
  2123. WCD938X_HPHPA_GND_OVR_MASK, 1);
  2124. snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
  2125. WCD938X_HPHPA_GND_R_MASK, 1);
  2126. if (*zl < (WCD938X_ZDET_VAL_32/1000))
  2127. wcd938x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1);
  2128. else
  2129. wcd938x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1);
  2130. snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
  2131. WCD938X_HPHPA_GND_R_MASK, 0);
  2132. snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
  2133. WCD938X_HPHPA_GND_OVR_MASK, 0);
  2134. z1Ls /= 1000;
  2135. wcd938x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
  2136. /* Parallel of left Z and 9 ohm pull down resistor */
  2137. zMono = ((*zl) * 9) / ((*zl) + 9);
  2138. z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
  2139. z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
  2140. if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
  2141. dev_dbg(component->dev, "%s: stereo plug type detected\n",
  2142. __func__);
  2143. wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_STEREO);
  2144. } else {
  2145. dev_dbg(component->dev, "%s: MONO plug type detected\n",
  2146. __func__);
  2147. wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
  2148. }
  2149. /* Enable surge protection again after impedance detection */
  2150. regmap_update_bits(wcd938x->regmap,
  2151. WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
  2152. zdet_complete:
  2153. snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0);
  2154. snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1);
  2155. snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN7, reg2);
  2156. /* Turn on 100k pull down on HPHL */
  2157. regmap_update_bits(wcd938x->regmap,
  2158. WCD938X_ANA_MBHC_MECH, 0x01, 0x01);
  2159. /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
  2160. if (wcd938x->mbhc_cfg.hphl_swh)
  2161. regmap_update_bits(wcd938x->regmap,
  2162. WCD938X_ANA_MBHC_MECH, 0x80, 0x80);
  2163. snd_soc_component_write(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, reg4);
  2164. snd_soc_component_write(component, WCD938X_MBHC_CTL_CLK, reg3);
  2165. if (is_fsm_disable)
  2166. regmap_update_bits(wcd938x->regmap,
  2167. WCD938X_ANA_MBHC_ELECT, 0x80, 0x80);
  2168. }
  2169. static void wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
  2170. bool enable)
  2171. {
  2172. if (enable) {
  2173. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
  2174. WCD938X_MBHC_HSG_PULLUP_COMP_EN, 1);
  2175. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
  2176. WCD938X_MBHC_GND_DET_EN_MASK, 1);
  2177. } else {
  2178. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
  2179. WCD938X_MBHC_GND_DET_EN_MASK, 0);
  2180. snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
  2181. WCD938X_MBHC_HSG_PULLUP_COMP_EN, 0);
  2182. }
  2183. }
  2184. static void wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
  2185. bool enable)
  2186. {
  2187. snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
  2188. WCD938X_HPHPA_GND_R_MASK, enable);
  2189. snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
  2190. WCD938X_HPHPA_GND_L_MASK, enable);
  2191. }
  2192. static void wcd938x_mbhc_moisture_config(struct snd_soc_component *component)
  2193. {
  2194. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2195. if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
  2196. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2197. WCD938X_M_RTH_CTL_MASK, R_OFF);
  2198. return;
  2199. }
  2200. /* Do not enable moisture detection if jack type is NC */
  2201. if (!wcd938x->mbhc_cfg.hphl_swh) {
  2202. dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
  2203. __func__);
  2204. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2205. WCD938X_M_RTH_CTL_MASK, R_OFF);
  2206. return;
  2207. }
  2208. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2209. WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
  2210. }
  2211. static void wcd938x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable)
  2212. {
  2213. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2214. if (enable)
  2215. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2216. WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
  2217. else
  2218. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2219. WCD938X_M_RTH_CTL_MASK, R_OFF);
  2220. }
  2221. static bool wcd938x_mbhc_get_moisture_status(struct snd_soc_component *component)
  2222. {
  2223. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2224. bool ret = false;
  2225. if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
  2226. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2227. WCD938X_M_RTH_CTL_MASK, R_OFF);
  2228. goto done;
  2229. }
  2230. /* Do not enable moisture detection if jack type is NC */
  2231. if (!wcd938x->mbhc_cfg.hphl_swh) {
  2232. dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
  2233. __func__);
  2234. snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
  2235. WCD938X_M_RTH_CTL_MASK, R_OFF);
  2236. goto done;
  2237. }
  2238. /*
  2239. * If moisture_en is already enabled, then skip to plug type
  2240. * detection.
  2241. */
  2242. if (snd_soc_component_read_field(component, WCD938X_MBHC_NEW_CTL_2, WCD938X_M_RTH_CTL_MASK))
  2243. goto done;
  2244. wcd938x_mbhc_moisture_detect_en(component, true);
  2245. /* Read moisture comparator status */
  2246. ret = ((snd_soc_component_read(component, WCD938X_MBHC_NEW_FSM_STATUS)
  2247. & 0x20) ? 0 : 1);
  2248. done:
  2249. return ret;
  2250. }
  2251. static void wcd938x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component,
  2252. bool enable)
  2253. {
  2254. snd_soc_component_write_field(component,
  2255. WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,
  2256. WCD938X_MOISTURE_EN_POLLING_MASK, enable);
  2257. }
  2258. static const struct wcd_mbhc_cb mbhc_cb = {
  2259. .clk_setup = wcd938x_mbhc_clk_setup,
  2260. .mbhc_bias = wcd938x_mbhc_mbhc_bias_control,
  2261. .set_btn_thr = wcd938x_mbhc_program_btn_thr,
  2262. .micbias_enable_status = wcd938x_mbhc_micb_en_status,
  2263. .hph_pull_up_control_v2 = wcd938x_mbhc_hph_l_pull_up_control,
  2264. .mbhc_micbias_control = wcd938x_mbhc_request_micbias,
  2265. .mbhc_micb_ramp_control = wcd938x_mbhc_micb_ramp_control,
  2266. .mbhc_micb_ctrl_thr_mic = wcd938x_mbhc_micb_ctrl_threshold_mic,
  2267. .compute_impedance = wcd938x_wcd_mbhc_calc_impedance,
  2268. .mbhc_gnd_det_ctrl = wcd938x_mbhc_gnd_det_ctrl,
  2269. .hph_pull_down_ctrl = wcd938x_mbhc_hph_pull_down_ctrl,
  2270. .mbhc_moisture_config = wcd938x_mbhc_moisture_config,
  2271. .mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
  2272. .mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
  2273. .mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
  2274. };
  2275. static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
  2276. struct snd_ctl_elem_value *ucontrol)
  2277. {
  2278. struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  2279. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2280. ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc);
  2281. return 0;
  2282. }
  2283. static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol,
  2284. struct snd_ctl_elem_value *ucontrol)
  2285. {
  2286. uint32_t zl, zr;
  2287. bool hphr;
  2288. struct soc_mixer_control *mc;
  2289. struct snd_soc_component *component =
  2290. snd_soc_kcontrol_component(kcontrol);
  2291. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2292. mc = (struct soc_mixer_control *)(kcontrol->private_value);
  2293. hphr = mc->shift;
  2294. wcd_mbhc_get_impedance(wcd938x->wcd_mbhc, &zl, &zr);
  2295. dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
  2296. ucontrol->value.integer.value[0] = hphr ? zr : zl;
  2297. return 0;
  2298. }
  2299. static const struct snd_kcontrol_new hph_type_detect_controls[] = {
  2300. SOC_SINGLE_EXT("HPH Type", 0, 0, WCD_MBHC_HPH_STEREO, 0,
  2301. wcd938x_get_hph_type, NULL),
  2302. };
  2303. static const struct snd_kcontrol_new impedance_detect_controls[] = {
  2304. SOC_SINGLE_EXT("HPHL Impedance", 0, 0, INT_MAX, 0,
  2305. wcd938x_hph_impedance_get, NULL),
  2306. SOC_SINGLE_EXT("HPHR Impedance", 0, 1, INT_MAX, 0,
  2307. wcd938x_hph_impedance_get, NULL),
  2308. };
  2309. static int wcd938x_mbhc_init(struct snd_soc_component *component)
  2310. {
  2311. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2312. struct wcd_mbhc_intr *intr_ids = &wcd938x->intr_ids;
  2313. intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd938x->irq_chip,
  2314. WCD938X_IRQ_MBHC_SW_DET);
  2315. intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd938x->irq_chip,
  2316. WCD938X_IRQ_MBHC_BUTTON_PRESS_DET);
  2317. intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd938x->irq_chip,
  2318. WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET);
  2319. intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd938x->irq_chip,
  2320. WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
  2321. intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd938x->irq_chip,
  2322. WCD938X_IRQ_MBHC_ELECT_INS_REM_DET);
  2323. intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
  2324. WCD938X_IRQ_HPHL_OCP_INT);
  2325. intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
  2326. WCD938X_IRQ_HPHR_OCP_INT);
  2327. wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
  2328. if (IS_ERR(wcd938x->wcd_mbhc))
  2329. return PTR_ERR(wcd938x->wcd_mbhc);
  2330. snd_soc_add_component_controls(component, impedance_detect_controls,
  2331. ARRAY_SIZE(impedance_detect_controls));
  2332. snd_soc_add_component_controls(component, hph_type_detect_controls,
  2333. ARRAY_SIZE(hph_type_detect_controls));
  2334. return 0;
  2335. }
  2336. static void wcd938x_mbhc_deinit(struct snd_soc_component *component)
  2337. {
  2338. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2339. wcd_mbhc_deinit(wcd938x->wcd_mbhc);
  2340. }
  2341. /* END MBHC */
  2342. static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
  2343. SOC_SINGLE_EXT("HPHL_COMP Switch", WCD938X_COMP_L, 0, 1, 0,
  2344. wcd938x_get_compander, wcd938x_set_compander),
  2345. SOC_SINGLE_EXT("HPHR_COMP Switch", WCD938X_COMP_R, 1, 1, 0,
  2346. wcd938x_get_compander, wcd938x_set_compander),
  2347. SOC_SINGLE_EXT("HPHL Switch", WCD938X_HPH_L, 0, 1, 0,
  2348. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2349. SOC_SINGLE_EXT("HPHR Switch", WCD938X_HPH_R, 0, 1, 0,
  2350. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2351. SOC_SINGLE_EXT("CLSH Switch", WCD938X_CLSH, 0, 1, 0,
  2352. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2353. SOC_SINGLE_EXT("LO Switch", WCD938X_LO, 0, 1, 0,
  2354. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2355. SOC_SINGLE_EXT("DSD_L Switch", WCD938X_DSD_L, 0, 1, 0,
  2356. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2357. SOC_SINGLE_EXT("DSD_R Switch", WCD938X_DSD_R, 0, 1, 0,
  2358. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2359. SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 0x18, 1, line_gain),
  2360. SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 0x18, 1, line_gain),
  2361. WCD938X_EAR_PA_GAIN_TLV("EAR_PA Volume", WCD938X_ANA_EAR_COMPANDER_CTL,
  2362. 2, 0x10, 0, ear_pa_gain),
  2363. SOC_SINGLE_EXT("ADC1 Switch", WCD938X_ADC1, 1, 1, 0,
  2364. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2365. SOC_SINGLE_EXT("ADC2 Switch", WCD938X_ADC2, 1, 1, 0,
  2366. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2367. SOC_SINGLE_EXT("ADC3 Switch", WCD938X_ADC3, 1, 1, 0,
  2368. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2369. SOC_SINGLE_EXT("ADC4 Switch", WCD938X_ADC4, 1, 1, 0,
  2370. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2371. SOC_SINGLE_EXT("DMIC0 Switch", WCD938X_DMIC0, 1, 1, 0,
  2372. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2373. SOC_SINGLE_EXT("DMIC1 Switch", WCD938X_DMIC1, 1, 1, 0,
  2374. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2375. SOC_SINGLE_EXT("MBHC Switch", WCD938X_MBHC, 1, 1, 0,
  2376. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2377. SOC_SINGLE_EXT("DMIC2 Switch", WCD938X_DMIC2, 1, 1, 0,
  2378. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2379. SOC_SINGLE_EXT("DMIC3 Switch", WCD938X_DMIC3, 1, 1, 0,
  2380. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2381. SOC_SINGLE_EXT("DMIC4 Switch", WCD938X_DMIC4, 1, 1, 0,
  2382. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2383. SOC_SINGLE_EXT("DMIC5 Switch", WCD938X_DMIC5, 1, 1, 0,
  2384. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2385. SOC_SINGLE_EXT("DMIC6 Switch", WCD938X_DMIC6, 1, 1, 0,
  2386. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2387. SOC_SINGLE_EXT("DMIC7 Switch", WCD938X_DMIC7, 1, 1, 0,
  2388. wcd938x_get_swr_port, wcd938x_set_swr_port),
  2389. SOC_SINGLE_EXT("LDOH Enable Switch", SND_SOC_NOPM, 0, 1, 0,
  2390. wcd938x_ldoh_get, wcd938x_ldoh_put),
  2391. SOC_SINGLE_EXT("ADC2_BCS Disable Switch", SND_SOC_NOPM, 0, 1, 0,
  2392. wcd938x_bcs_get, wcd938x_bcs_put),
  2393. SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, analog_gain),
  2394. SOC_SINGLE_TLV("ADC2 Volume", WCD938X_ANA_TX_CH2, 0, 20, 0, analog_gain),
  2395. SOC_SINGLE_TLV("ADC3 Volume", WCD938X_ANA_TX_CH3, 0, 20, 0, analog_gain),
  2396. SOC_SINGLE_TLV("ADC4 Volume", WCD938X_ANA_TX_CH4, 0, 20, 0, analog_gain),
  2397. };
  2398. static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
  2399. /*input widgets*/
  2400. SND_SOC_DAPM_INPUT("AMIC1"),
  2401. SND_SOC_DAPM_INPUT("AMIC2"),
  2402. SND_SOC_DAPM_INPUT("AMIC3"),
  2403. SND_SOC_DAPM_INPUT("AMIC4"),
  2404. SND_SOC_DAPM_INPUT("AMIC5"),
  2405. SND_SOC_DAPM_INPUT("AMIC6"),
  2406. SND_SOC_DAPM_INPUT("AMIC7"),
  2407. SND_SOC_DAPM_MIC("Analog Mic1", NULL),
  2408. SND_SOC_DAPM_MIC("Analog Mic2", NULL),
  2409. SND_SOC_DAPM_MIC("Analog Mic3", NULL),
  2410. SND_SOC_DAPM_MIC("Analog Mic4", NULL),
  2411. SND_SOC_DAPM_MIC("Analog Mic5", NULL),
  2412. /*tx widgets*/
  2413. SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
  2414. wcd938x_codec_enable_adc,
  2415. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2416. SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0,
  2417. wcd938x_codec_enable_adc,
  2418. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2419. SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0,
  2420. wcd938x_codec_enable_adc,
  2421. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2422. SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 3, 0,
  2423. wcd938x_codec_enable_adc,
  2424. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2425. SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
  2426. wcd938x_codec_enable_dmic,
  2427. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2428. SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0,
  2429. wcd938x_codec_enable_dmic,
  2430. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2431. SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0,
  2432. wcd938x_codec_enable_dmic,
  2433. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2434. SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0,
  2435. wcd938x_codec_enable_dmic,
  2436. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2437. SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0,
  2438. wcd938x_codec_enable_dmic,
  2439. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2440. SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0,
  2441. wcd938x_codec_enable_dmic,
  2442. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2443. SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 6, 0,
  2444. wcd938x_codec_enable_dmic,
  2445. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2446. SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 7, 0,
  2447. wcd938x_codec_enable_dmic,
  2448. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2449. SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0,
  2450. NULL, 0, wcd938x_adc_enable_req,
  2451. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2452. SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 1, 0,
  2453. NULL, 0, wcd938x_adc_enable_req,
  2454. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2455. SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 2, 0,
  2456. NULL, 0, wcd938x_adc_enable_req,
  2457. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2458. SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 3, 0, NULL, 0,
  2459. wcd938x_adc_enable_req,
  2460. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2461. SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
  2462. SND_SOC_DAPM_MUX("ADC3 MUX", SND_SOC_NOPM, 0, 0, &tx_adc3_mux),
  2463. SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux),
  2464. SND_SOC_DAPM_MUX("HDR12 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr12_mux),
  2465. SND_SOC_DAPM_MUX("HDR34 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr34_mux),
  2466. /*tx mixers*/
  2467. SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch,
  2468. ARRAY_SIZE(adc1_switch), wcd938x_tx_swr_ctrl,
  2469. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2470. SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, adc2_switch,
  2471. ARRAY_SIZE(adc2_switch), wcd938x_tx_swr_ctrl,
  2472. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2473. SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch,
  2474. ARRAY_SIZE(adc3_switch), wcd938x_tx_swr_ctrl,
  2475. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2476. SND_SOC_DAPM_MIXER_E("ADC4_MIXER", SND_SOC_NOPM, 0, 0, adc4_switch,
  2477. ARRAY_SIZE(adc4_switch), wcd938x_tx_swr_ctrl,
  2478. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2479. SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, dmic1_switch,
  2480. ARRAY_SIZE(dmic1_switch), wcd938x_tx_swr_ctrl,
  2481. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2482. SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, 0, dmic2_switch,
  2483. ARRAY_SIZE(dmic2_switch), wcd938x_tx_swr_ctrl,
  2484. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2485. SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, 0, dmic3_switch,
  2486. ARRAY_SIZE(dmic3_switch), wcd938x_tx_swr_ctrl,
  2487. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2488. SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, 0, dmic4_switch,
  2489. ARRAY_SIZE(dmic4_switch), wcd938x_tx_swr_ctrl,
  2490. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2491. SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, 0, dmic5_switch,
  2492. ARRAY_SIZE(dmic5_switch), wcd938x_tx_swr_ctrl,
  2493. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2494. SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, 0, dmic6_switch,
  2495. ARRAY_SIZE(dmic6_switch), wcd938x_tx_swr_ctrl,
  2496. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2497. SND_SOC_DAPM_MIXER_E("DMIC7_MIXER", SND_SOC_NOPM, 0, 0, dmic7_switch,
  2498. ARRAY_SIZE(dmic7_switch), wcd938x_tx_swr_ctrl,
  2499. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2500. SND_SOC_DAPM_MIXER_E("DMIC8_MIXER", SND_SOC_NOPM, 0, 0, dmic8_switch,
  2501. ARRAY_SIZE(dmic8_switch), wcd938x_tx_swr_ctrl,
  2502. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
  2503. /* micbias widgets*/
  2504. SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
  2505. wcd938x_codec_enable_micbias,
  2506. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2507. SND_SOC_DAPM_POST_PMD),
  2508. SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
  2509. wcd938x_codec_enable_micbias,
  2510. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2511. SND_SOC_DAPM_POST_PMD),
  2512. SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
  2513. wcd938x_codec_enable_micbias,
  2514. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2515. SND_SOC_DAPM_POST_PMD),
  2516. SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
  2517. wcd938x_codec_enable_micbias,
  2518. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2519. SND_SOC_DAPM_POST_PMD),
  2520. /* micbias pull up widgets*/
  2521. SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
  2522. wcd938x_codec_enable_micbias_pullup,
  2523. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2524. SND_SOC_DAPM_POST_PMD),
  2525. SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
  2526. wcd938x_codec_enable_micbias_pullup,
  2527. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2528. SND_SOC_DAPM_POST_PMD),
  2529. SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
  2530. wcd938x_codec_enable_micbias_pullup,
  2531. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2532. SND_SOC_DAPM_POST_PMD),
  2533. SND_SOC_DAPM_SUPPLY("VA MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
  2534. wcd938x_codec_enable_micbias_pullup,
  2535. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2536. SND_SOC_DAPM_POST_PMD),
  2537. /*output widgets tx*/
  2538. SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
  2539. SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
  2540. SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"),
  2541. SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"),
  2542. SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
  2543. SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
  2544. SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"),
  2545. SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"),
  2546. SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"),
  2547. SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"),
  2548. SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"),
  2549. SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"),
  2550. SND_SOC_DAPM_INPUT("IN1_HPHL"),
  2551. SND_SOC_DAPM_INPUT("IN2_HPHR"),
  2552. SND_SOC_DAPM_INPUT("IN3_AUX"),
  2553. /*rx widgets*/
  2554. SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0,
  2555. wcd938x_codec_enable_ear_pa,
  2556. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2557. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2558. SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0,
  2559. wcd938x_codec_enable_aux_pa,
  2560. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2561. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2562. SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0,
  2563. wcd938x_codec_enable_hphl_pa,
  2564. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2565. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2566. SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0,
  2567. wcd938x_codec_enable_hphr_pa,
  2568. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2569. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2570. SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0,
  2571. wcd938x_codec_hphl_dac_event,
  2572. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2573. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2574. SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0,
  2575. wcd938x_codec_hphr_dac_event,
  2576. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2577. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2578. SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0,
  2579. wcd938x_codec_ear_dac_event,
  2580. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2581. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2582. SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0,
  2583. wcd938x_codec_aux_dac_event,
  2584. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2585. SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
  2586. SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux),
  2587. SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, NULL, 0),
  2588. SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0,
  2589. wcd938x_codec_enable_rxclk,
  2590. SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
  2591. SND_SOC_DAPM_POST_PMD),
  2592. SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
  2593. SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
  2594. SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
  2595. SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
  2596. /* rx mixer widgets*/
  2597. SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0,
  2598. ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)),
  2599. SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0,
  2600. aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)),
  2601. SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0,
  2602. hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)),
  2603. SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0,
  2604. hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)),
  2605. /*output widgets rx*/
  2606. SND_SOC_DAPM_OUTPUT("EAR"),
  2607. SND_SOC_DAPM_OUTPUT("AUX"),
  2608. SND_SOC_DAPM_OUTPUT("HPHL"),
  2609. SND_SOC_DAPM_OUTPUT("HPHR"),
  2610. };
  2611. static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
  2612. {"ADC1_OUTPUT", NULL, "ADC1_MIXER"},
  2613. {"ADC1_MIXER", "Switch", "ADC1 REQ"},
  2614. {"ADC1 REQ", NULL, "ADC1"},
  2615. {"ADC1", NULL, "AMIC1"},
  2616. {"ADC2_OUTPUT", NULL, "ADC2_MIXER"},
  2617. {"ADC2_MIXER", "Switch", "ADC2 REQ"},
  2618. {"ADC2 REQ", NULL, "ADC2"},
  2619. {"ADC2", NULL, "HDR12 MUX"},
  2620. {"HDR12 MUX", "NO_HDR12", "ADC2 MUX"},
  2621. {"HDR12 MUX", "HDR12", "AMIC1"},
  2622. {"ADC2 MUX", "INP3", "AMIC3"},
  2623. {"ADC2 MUX", "INP2", "AMIC2"},
  2624. {"ADC3_OUTPUT", NULL, "ADC3_MIXER"},
  2625. {"ADC3_MIXER", "Switch", "ADC3 REQ"},
  2626. {"ADC3 REQ", NULL, "ADC3"},
  2627. {"ADC3", NULL, "HDR34 MUX"},
  2628. {"HDR34 MUX", "NO_HDR34", "ADC3 MUX"},
  2629. {"HDR34 MUX", "HDR34", "AMIC5"},
  2630. {"ADC3 MUX", "INP4", "AMIC4"},
  2631. {"ADC3 MUX", "INP6", "AMIC6"},
  2632. {"ADC4_OUTPUT", NULL, "ADC4_MIXER"},
  2633. {"ADC4_MIXER", "Switch", "ADC4 REQ"},
  2634. {"ADC4 REQ", NULL, "ADC4"},
  2635. {"ADC4", NULL, "ADC4 MUX"},
  2636. {"ADC4 MUX", "INP5", "AMIC5"},
  2637. {"ADC4 MUX", "INP7", "AMIC7"},
  2638. {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"},
  2639. {"DMIC1_MIXER", "Switch", "DMIC1"},
  2640. {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"},
  2641. {"DMIC2_MIXER", "Switch", "DMIC2"},
  2642. {"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"},
  2643. {"DMIC3_MIXER", "Switch", "DMIC3"},
  2644. {"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"},
  2645. {"DMIC4_MIXER", "Switch", "DMIC4"},
  2646. {"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"},
  2647. {"DMIC5_MIXER", "Switch", "DMIC5"},
  2648. {"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"},
  2649. {"DMIC6_MIXER", "Switch", "DMIC6"},
  2650. {"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"},
  2651. {"DMIC7_MIXER", "Switch", "DMIC7"},
  2652. {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"},
  2653. {"DMIC8_MIXER", "Switch", "DMIC8"},
  2654. {"IN1_HPHL", NULL, "VDD_BUCK"},
  2655. {"IN1_HPHL", NULL, "CLS_H_PORT"},
  2656. {"RX1", NULL, "IN1_HPHL"},
  2657. {"RX1", NULL, "RXCLK"},
  2658. {"RDAC1", NULL, "RX1"},
  2659. {"HPHL_RDAC", "Switch", "RDAC1"},
  2660. {"HPHL PGA", NULL, "HPHL_RDAC"},
  2661. {"HPHL", NULL, "HPHL PGA"},
  2662. {"IN2_HPHR", NULL, "VDD_BUCK"},
  2663. {"IN2_HPHR", NULL, "CLS_H_PORT"},
  2664. {"RX2", NULL, "IN2_HPHR"},
  2665. {"RDAC2", NULL, "RX2"},
  2666. {"RX2", NULL, "RXCLK"},
  2667. {"HPHR_RDAC", "Switch", "RDAC2"},
  2668. {"HPHR PGA", NULL, "HPHR_RDAC"},
  2669. {"HPHR", NULL, "HPHR PGA"},
  2670. {"IN3_AUX", NULL, "VDD_BUCK"},
  2671. {"IN3_AUX", NULL, "CLS_H_PORT"},
  2672. {"RX3", NULL, "IN3_AUX"},
  2673. {"RDAC4", NULL, "RX3"},
  2674. {"RX3", NULL, "RXCLK"},
  2675. {"AUX_RDAC", "Switch", "RDAC4"},
  2676. {"AUX PGA", NULL, "AUX_RDAC"},
  2677. {"AUX", NULL, "AUX PGA"},
  2678. {"RDAC3_MUX", "RX3", "RX3"},
  2679. {"RDAC3_MUX", "RX1", "RX1"},
  2680. {"RDAC3", NULL, "RDAC3_MUX"},
  2681. {"EAR_RDAC", "Switch", "RDAC3"},
  2682. {"EAR PGA", NULL, "EAR_RDAC"},
  2683. {"EAR", NULL, "EAR PGA"},
  2684. };
  2685. static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x)
  2686. {
  2687. int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
  2688. /* set micbias voltage */
  2689. vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv);
  2690. vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv);
  2691. vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv);
  2692. vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv);
  2693. if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
  2694. return -EINVAL;
  2695. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1,
  2696. WCD938X_MICB_VOUT_MASK, vout_ctl_1);
  2697. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2,
  2698. WCD938X_MICB_VOUT_MASK, vout_ctl_2);
  2699. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3,
  2700. WCD938X_MICB_VOUT_MASK, vout_ctl_3);
  2701. regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4,
  2702. WCD938X_MICB_VOUT_MASK, vout_ctl_4);
  2703. return 0;
  2704. }
  2705. static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
  2706. {
  2707. return IRQ_HANDLED;
  2708. }
  2709. static struct irq_chip wcd_irq_chip = {
  2710. .name = "WCD938x",
  2711. };
  2712. static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
  2713. irq_hw_number_t hw)
  2714. {
  2715. irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq);
  2716. irq_set_nested_thread(virq, 1);
  2717. irq_set_noprobe(virq);
  2718. return 0;
  2719. }
  2720. static const struct irq_domain_ops wcd_domain_ops = {
  2721. .map = wcd_irq_chip_map,
  2722. };
  2723. static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev)
  2724. {
  2725. wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
  2726. if (!(wcd->virq)) {
  2727. dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
  2728. return -EINVAL;
  2729. }
  2730. return devm_regmap_add_irq_chip(dev, wcd->regmap,
  2731. irq_create_mapping(wcd->virq, 0),
  2732. IRQF_ONESHOT, 0, &wcd938x_regmap_irq_chip,
  2733. &wcd->irq_chip);
  2734. }
  2735. static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
  2736. {
  2737. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2738. struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev;
  2739. struct device *dev = component->dev;
  2740. unsigned long time_left;
  2741. int ret, i;
  2742. time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete,
  2743. msecs_to_jiffies(2000));
  2744. if (!time_left) {
  2745. dev_err(dev, "soundwire device init timeout\n");
  2746. return -ETIMEDOUT;
  2747. }
  2748. snd_soc_component_init_regmap(component, wcd938x->regmap);
  2749. ret = pm_runtime_resume_and_get(dev);
  2750. if (ret < 0)
  2751. return ret;
  2752. wcd938x->variant = snd_soc_component_read_field(component,
  2753. WCD938X_DIGITAL_EFUSE_REG_0,
  2754. WCD938X_ID_MASK);
  2755. wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X);
  2756. if (IS_ERR(wcd938x->clsh_info)) {
  2757. pm_runtime_put(dev);
  2758. return PTR_ERR(wcd938x->clsh_info);
  2759. }
  2760. wcd938x_io_init(wcd938x);
  2761. /* Set all interrupts as edge triggered */
  2762. for (i = 0; i < wcd938x_regmap_irq_chip.num_regs; i++) {
  2763. regmap_write(wcd938x->regmap,
  2764. (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0);
  2765. }
  2766. pm_runtime_put(dev);
  2767. wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
  2768. WCD938X_IRQ_HPHR_PDM_WD_INT);
  2769. wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
  2770. WCD938X_IRQ_HPHL_PDM_WD_INT);
  2771. wcd938x->aux_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
  2772. WCD938X_IRQ_AUX_PDM_WD_INT);
  2773. /* Request for watchdog interrupt */
  2774. ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
  2775. IRQF_ONESHOT | IRQF_TRIGGER_RISING,
  2776. "HPHR PDM WD INT", wcd938x);
  2777. if (ret) {
  2778. dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret);
  2779. goto err_free_clsh_ctrl;
  2780. }
  2781. ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
  2782. IRQF_ONESHOT | IRQF_TRIGGER_RISING,
  2783. "HPHL PDM WD INT", wcd938x);
  2784. if (ret) {
  2785. dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret);
  2786. goto err_free_hphr_pdm_wd_int;
  2787. }
  2788. ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
  2789. IRQF_ONESHOT | IRQF_TRIGGER_RISING,
  2790. "AUX PDM WD INT", wcd938x);
  2791. if (ret) {
  2792. dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret);
  2793. goto err_free_hphl_pdm_wd_int;
  2794. }
  2795. /* Disable watchdog interrupt for HPH and AUX */
  2796. disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
  2797. disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
  2798. disable_irq_nosync(wcd938x->aux_pdm_wd_int);
  2799. switch (wcd938x->variant) {
  2800. case WCD9380:
  2801. ret = snd_soc_add_component_controls(component, wcd9380_snd_controls,
  2802. ARRAY_SIZE(wcd9380_snd_controls));
  2803. if (ret < 0) {
  2804. dev_err(component->dev,
  2805. "%s: Failed to add snd ctrls for variant: %d\n",
  2806. __func__, wcd938x->variant);
  2807. goto err_free_aux_pdm_wd_int;
  2808. }
  2809. break;
  2810. case WCD9385:
  2811. ret = snd_soc_add_component_controls(component, wcd9385_snd_controls,
  2812. ARRAY_SIZE(wcd9385_snd_controls));
  2813. if (ret < 0) {
  2814. dev_err(component->dev,
  2815. "%s: Failed to add snd ctrls for variant: %d\n",
  2816. __func__, wcd938x->variant);
  2817. goto err_free_aux_pdm_wd_int;
  2818. }
  2819. break;
  2820. default:
  2821. break;
  2822. }
  2823. ret = wcd938x_mbhc_init(component);
  2824. if (ret) {
  2825. dev_err(component->dev, "mbhc initialization failed\n");
  2826. goto err_free_aux_pdm_wd_int;
  2827. }
  2828. return 0;
  2829. err_free_aux_pdm_wd_int:
  2830. free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
  2831. err_free_hphl_pdm_wd_int:
  2832. free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
  2833. err_free_hphr_pdm_wd_int:
  2834. free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
  2835. err_free_clsh_ctrl:
  2836. wcd_clsh_ctrl_free(wcd938x->clsh_info);
  2837. return ret;
  2838. }
  2839. static void wcd938x_soc_codec_remove(struct snd_soc_component *component)
  2840. {
  2841. struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
  2842. wcd938x_mbhc_deinit(component);
  2843. free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
  2844. free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
  2845. free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
  2846. wcd_clsh_ctrl_free(wcd938x->clsh_info);
  2847. }
  2848. static int wcd938x_codec_set_jack(struct snd_soc_component *comp,
  2849. struct snd_soc_jack *jack, void *data)
  2850. {
  2851. struct wcd938x_priv *wcd = dev_get_drvdata(comp->dev);
  2852. if (jack)
  2853. return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack);
  2854. else
  2855. wcd_mbhc_stop(wcd->wcd_mbhc);
  2856. return 0;
  2857. }
  2858. static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
  2859. .name = "wcd938x_codec",
  2860. .probe = wcd938x_soc_codec_probe,
  2861. .remove = wcd938x_soc_codec_remove,
  2862. .controls = wcd938x_snd_controls,
  2863. .num_controls = ARRAY_SIZE(wcd938x_snd_controls),
  2864. .dapm_widgets = wcd938x_dapm_widgets,
  2865. .num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
  2866. .dapm_routes = wcd938x_audio_map,
  2867. .num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
  2868. .set_jack = wcd938x_codec_set_jack,
  2869. .endianness = 1,
  2870. };
  2871. static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
  2872. {
  2873. struct device_node *np = dev->of_node;
  2874. u32 prop_val = 0;
  2875. int rc = 0;
  2876. rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
  2877. if (!rc)
  2878. wcd->micb1_mv = prop_val/1000;
  2879. else
  2880. dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
  2881. rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
  2882. if (!rc)
  2883. wcd->micb2_mv = prop_val/1000;
  2884. else
  2885. dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
  2886. rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
  2887. if (!rc)
  2888. wcd->micb3_mv = prop_val/1000;
  2889. else
  2890. dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
  2891. rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val);
  2892. if (!rc)
  2893. wcd->micb4_mv = prop_val/1000;
  2894. else
  2895. dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
  2896. }
  2897. static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active)
  2898. {
  2899. int value;
  2900. struct wcd938x_priv *wcd938x;
  2901. wcd938x = snd_soc_component_get_drvdata(component);
  2902. value = gpiod_get_value(wcd938x->us_euro_gpio);
  2903. gpiod_set_value(wcd938x->us_euro_gpio, !value);
  2904. return true;
  2905. }
  2906. static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device *dev)
  2907. {
  2908. struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg;
  2909. int ret;
  2910. wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
  2911. if (wcd938x->reset_gpio < 0)
  2912. return dev_err_probe(dev, wcd938x->reset_gpio,
  2913. "Failed to get reset gpio\n");
  2914. wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro",
  2915. GPIOD_OUT_LOW);
  2916. if (IS_ERR(wcd938x->us_euro_gpio))
  2917. return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio),
  2918. "us-euro swap Control GPIO not found\n");
  2919. cfg->swap_gnd_mic = wcd938x_swap_gnd_mic;
  2920. wcd938x->supplies[0].supply = "vdd-rxtx";
  2921. wcd938x->supplies[1].supply = "vdd-io";
  2922. wcd938x->supplies[2].supply = "vdd-buck";
  2923. wcd938x->supplies[3].supply = "vdd-mic-bias";
  2924. ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies);
  2925. if (ret)
  2926. return dev_err_probe(dev, ret, "Failed to get supplies\n");
  2927. ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  2928. if (ret) {
  2929. regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  2930. return dev_err_probe(dev, ret, "Failed to enable supplies\n");
  2931. }
  2932. wcd938x_dt_parse_micbias_info(dev, wcd938x);
  2933. cfg->mbhc_micbias = MIC_BIAS_2;
  2934. cfg->anc_micbias = MIC_BIAS_2;
  2935. cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
  2936. cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS;
  2937. cfg->micb_mv = wcd938x->micb2_mv;
  2938. cfg->linein_th = 5000;
  2939. cfg->hs_thr = 1700;
  2940. cfg->hph_thr = 50;
  2941. wcd_dt_parse_mbhc_data(dev, cfg);
  2942. return 0;
  2943. }
  2944. static int wcd938x_reset(struct wcd938x_priv *wcd938x)
  2945. {
  2946. gpio_direction_output(wcd938x->reset_gpio, 0);
  2947. /* 20us sleep required after pulling the reset gpio to LOW */
  2948. usleep_range(20, 30);
  2949. gpio_set_value(wcd938x->reset_gpio, 1);
  2950. /* 20us sleep required after pulling the reset gpio to HIGH */
  2951. usleep_range(20, 30);
  2952. return 0;
  2953. }
  2954. static int wcd938x_codec_hw_params(struct snd_pcm_substream *substream,
  2955. struct snd_pcm_hw_params *params,
  2956. struct snd_soc_dai *dai)
  2957. {
  2958. struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
  2959. struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
  2960. return wcd938x_sdw_hw_params(wcd, substream, params, dai);
  2961. }
  2962. static int wcd938x_codec_free(struct snd_pcm_substream *substream,
  2963. struct snd_soc_dai *dai)
  2964. {
  2965. struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
  2966. struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
  2967. return wcd938x_sdw_free(wcd, substream, dai);
  2968. }
  2969. static int wcd938x_codec_set_sdw_stream(struct snd_soc_dai *dai,
  2970. void *stream, int direction)
  2971. {
  2972. struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
  2973. struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
  2974. return wcd938x_sdw_set_sdw_stream(wcd, dai, stream, direction);
  2975. }
  2976. static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = {
  2977. .hw_params = wcd938x_codec_hw_params,
  2978. .hw_free = wcd938x_codec_free,
  2979. .set_stream = wcd938x_codec_set_sdw_stream,
  2980. };
  2981. static struct snd_soc_dai_driver wcd938x_dais[] = {
  2982. [0] = {
  2983. .name = "wcd938x-sdw-rx",
  2984. .playback = {
  2985. .stream_name = "WCD AIF1 Playback",
  2986. .rates = WCD938X_RATES_MASK | WCD938X_FRAC_RATES_MASK,
  2987. .formats = WCD938X_FORMATS_S16_S24_LE,
  2988. .rate_max = 192000,
  2989. .rate_min = 8000,
  2990. .channels_min = 1,
  2991. .channels_max = 2,
  2992. },
  2993. .ops = &wcd938x_sdw_dai_ops,
  2994. },
  2995. [1] = {
  2996. .name = "wcd938x-sdw-tx",
  2997. .capture = {
  2998. .stream_name = "WCD AIF1 Capture",
  2999. .rates = WCD938X_RATES_MASK,
  3000. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  3001. .rate_min = 8000,
  3002. .rate_max = 192000,
  3003. .channels_min = 1,
  3004. .channels_max = 4,
  3005. },
  3006. .ops = &wcd938x_sdw_dai_ops,
  3007. },
  3008. };
  3009. static int wcd938x_bind(struct device *dev)
  3010. {
  3011. struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
  3012. int ret;
  3013. ret = component_bind_all(dev, wcd938x);
  3014. if (ret) {
  3015. dev_err(dev, "%s: Slave bind failed, ret = %d\n",
  3016. __func__, ret);
  3017. return ret;
  3018. }
  3019. wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode);
  3020. if (!wcd938x->rxdev) {
  3021. dev_err(dev, "could not find slave with matching of node\n");
  3022. ret = -EINVAL;
  3023. goto err_unbind;
  3024. }
  3025. wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev);
  3026. wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x;
  3027. wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode);
  3028. if (!wcd938x->txdev) {
  3029. dev_err(dev, "could not find txslave with matching of node\n");
  3030. ret = -EINVAL;
  3031. goto err_put_rxdev;
  3032. }
  3033. wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev);
  3034. wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x;
  3035. wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev);
  3036. /* As TX is main CSR reg interface, which should not be suspended first.
  3037. * expicilty add the dependency link */
  3038. if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS |
  3039. DL_FLAG_PM_RUNTIME)) {
  3040. dev_err(dev, "could not devlink tx and rx\n");
  3041. ret = -EINVAL;
  3042. goto err_put_txdev;
  3043. }
  3044. if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS |
  3045. DL_FLAG_PM_RUNTIME)) {
  3046. dev_err(dev, "could not devlink wcd and tx\n");
  3047. ret = -EINVAL;
  3048. goto err_remove_rxtx_link;
  3049. }
  3050. if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS |
  3051. DL_FLAG_PM_RUNTIME)) {
  3052. dev_err(dev, "could not devlink wcd and rx\n");
  3053. ret = -EINVAL;
  3054. goto err_remove_tx_link;
  3055. }
  3056. wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL);
  3057. if (!wcd938x->regmap) {
  3058. dev_err(dev, "could not get TX device regmap\n");
  3059. ret = -EINVAL;
  3060. goto err_remove_rx_link;
  3061. }
  3062. ret = wcd938x_irq_init(wcd938x, dev);
  3063. if (ret) {
  3064. dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret);
  3065. goto err_remove_rx_link;
  3066. }
  3067. wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
  3068. wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq;
  3069. ret = wcd938x_set_micbias_data(wcd938x);
  3070. if (ret < 0) {
  3071. dev_err(dev, "%s: bad micbias pdata\n", __func__);
  3072. goto err_remove_rx_link;
  3073. }
  3074. ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
  3075. wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
  3076. if (ret) {
  3077. dev_err(dev, "%s: Codec registration failed\n",
  3078. __func__);
  3079. goto err_remove_rx_link;
  3080. }
  3081. return 0;
  3082. err_remove_rx_link:
  3083. device_link_remove(dev, wcd938x->rxdev);
  3084. err_remove_tx_link:
  3085. device_link_remove(dev, wcd938x->txdev);
  3086. err_remove_rxtx_link:
  3087. device_link_remove(wcd938x->rxdev, wcd938x->txdev);
  3088. err_put_txdev:
  3089. put_device(wcd938x->txdev);
  3090. err_put_rxdev:
  3091. put_device(wcd938x->rxdev);
  3092. err_unbind:
  3093. component_unbind_all(dev, wcd938x);
  3094. return ret;
  3095. }
  3096. static void wcd938x_unbind(struct device *dev)
  3097. {
  3098. struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
  3099. snd_soc_unregister_component(dev);
  3100. device_link_remove(dev, wcd938x->txdev);
  3101. device_link_remove(dev, wcd938x->rxdev);
  3102. device_link_remove(wcd938x->rxdev, wcd938x->txdev);
  3103. put_device(wcd938x->txdev);
  3104. put_device(wcd938x->rxdev);
  3105. component_unbind_all(dev, wcd938x);
  3106. }
  3107. static const struct component_master_ops wcd938x_comp_ops = {
  3108. .bind = wcd938x_bind,
  3109. .unbind = wcd938x_unbind,
  3110. };
  3111. static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
  3112. struct device *dev,
  3113. struct component_match **matchptr)
  3114. {
  3115. struct device_node *np;
  3116. np = dev->of_node;
  3117. wcd938x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0);
  3118. if (!wcd938x->rxnode) {
  3119. dev_err(dev, "%s: Rx-device node not defined\n", __func__);
  3120. return -ENODEV;
  3121. }
  3122. of_node_get(wcd938x->rxnode);
  3123. component_match_add_release(dev, matchptr, component_release_of,
  3124. component_compare_of, wcd938x->rxnode);
  3125. wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
  3126. if (!wcd938x->txnode) {
  3127. dev_err(dev, "%s: Tx-device node not defined\n", __func__);
  3128. return -ENODEV;
  3129. }
  3130. of_node_get(wcd938x->txnode);
  3131. component_match_add_release(dev, matchptr, component_release_of,
  3132. component_compare_of, wcd938x->txnode);
  3133. return 0;
  3134. }
  3135. static int wcd938x_probe(struct platform_device *pdev)
  3136. {
  3137. struct component_match *match = NULL;
  3138. struct wcd938x_priv *wcd938x = NULL;
  3139. struct device *dev = &pdev->dev;
  3140. int ret;
  3141. wcd938x = devm_kzalloc(dev, sizeof(struct wcd938x_priv),
  3142. GFP_KERNEL);
  3143. if (!wcd938x)
  3144. return -ENOMEM;
  3145. dev_set_drvdata(dev, wcd938x);
  3146. mutex_init(&wcd938x->micb_lock);
  3147. ret = wcd938x_populate_dt_data(wcd938x, dev);
  3148. if (ret) {
  3149. dev_err(dev, "%s: Fail to obtain platform data\n", __func__);
  3150. return -EINVAL;
  3151. }
  3152. ret = wcd938x_add_slave_components(wcd938x, dev, &match);
  3153. if (ret)
  3154. goto err_disable_regulators;
  3155. wcd938x_reset(wcd938x);
  3156. ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match);
  3157. if (ret)
  3158. goto err_disable_regulators;
  3159. pm_runtime_set_autosuspend_delay(dev, 1000);
  3160. pm_runtime_use_autosuspend(dev);
  3161. pm_runtime_mark_last_busy(dev);
  3162. pm_runtime_set_active(dev);
  3163. pm_runtime_enable(dev);
  3164. pm_runtime_idle(dev);
  3165. return 0;
  3166. err_disable_regulators:
  3167. regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  3168. regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  3169. return ret;
  3170. }
  3171. static void wcd938x_remove(struct platform_device *pdev)
  3172. {
  3173. struct device *dev = &pdev->dev;
  3174. struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
  3175. component_master_del(dev, &wcd938x_comp_ops);
  3176. pm_runtime_disable(dev);
  3177. pm_runtime_set_suspended(dev);
  3178. pm_runtime_dont_use_autosuspend(dev);
  3179. regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  3180. regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
  3181. }
  3182. #if defined(CONFIG_OF)
  3183. static const struct of_device_id wcd938x_dt_match[] = {
  3184. { .compatible = "qcom,wcd9380-codec" },
  3185. { .compatible = "qcom,wcd9385-codec" },
  3186. {}
  3187. };
  3188. MODULE_DEVICE_TABLE(of, wcd938x_dt_match);
  3189. #endif
  3190. static struct platform_driver wcd938x_codec_driver = {
  3191. .probe = wcd938x_probe,
  3192. .remove_new = wcd938x_remove,
  3193. .driver = {
  3194. .name = "wcd938x_codec",
  3195. .of_match_table = of_match_ptr(wcd938x_dt_match),
  3196. .suppress_bind_attrs = true,
  3197. },
  3198. };
  3199. module_platform_driver(wcd938x_codec_driver);
  3200. MODULE_DESCRIPTION("WCD938X Codec driver");
  3201. MODULE_LICENSE("GPL");