topology.c 103 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2. //
  3. // This file is provided under a dual BSD/GPLv2 license. When using or
  4. // redistributing this file, you may do so under either license.
  5. //
  6. // Copyright(c) 2018 Intel Corporation. All rights reserved.
  7. //
  8. // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
  9. //
  10. #include <linux/bits.h>
  11. #include <linux/device.h>
  12. #include <linux/errno.h>
  13. #include <linux/firmware.h>
  14. #include <linux/workqueue.h>
  15. #include <sound/tlv.h>
  16. #include <sound/pcm_params.h>
  17. #include <uapi/sound/sof/tokens.h>
  18. #include "sof-priv.h"
  19. #include "sof-audio.h"
  20. #include "ops.h"
  21. #define COMP_ID_UNASSIGNED 0xffffffff
  22. /*
  23. * Constants used in the computation of linear volume gain
  24. * from dB gain 20th root of 10 in Q1.16 fixed-point notation
  25. */
  26. #define VOL_TWENTIETH_ROOT_OF_TEN 73533
  27. /* 40th root of 10 in Q1.16 fixed-point notation*/
  28. #define VOL_FORTIETH_ROOT_OF_TEN 69419
  29. /*
  30. * Volume fractional word length define to 16 sets
  31. * the volume linear gain value to use Qx.16 format
  32. */
  33. #define VOLUME_FWL 16
  34. /* 0.5 dB step value in topology TLV */
  35. #define VOL_HALF_DB_STEP 50
  36. /* Full volume for default values */
  37. #define VOL_ZERO_DB BIT(VOLUME_FWL)
  38. /* TLV data items */
  39. #define TLV_ITEMS 3
  40. #define TLV_MIN 0
  41. #define TLV_STEP 1
  42. #define TLV_MUTE 2
  43. /* size of tplg abi in byte */
  44. #define SOF_TPLG_ABI_SIZE 3
  45. struct sof_widget_data {
  46. int ctrl_type;
  47. int ipc_cmd;
  48. struct sof_abi_hdr *pdata;
  49. struct snd_sof_control *control;
  50. };
  51. /* send pcm params ipc */
  52. static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir)
  53. {
  54. struct sof_ipc_pcm_params_reply ipc_params_reply;
  55. struct snd_soc_component *scomp = swidget->scomp;
  56. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  57. struct sof_ipc_pcm_params pcm;
  58. struct snd_pcm_hw_params *params;
  59. struct snd_sof_pcm *spcm;
  60. int ret;
  61. memset(&pcm, 0, sizeof(pcm));
  62. /* get runtime PCM params using widget's stream name */
  63. spcm = snd_sof_find_spcm_name(scomp, swidget->widget->sname);
  64. if (!spcm) {
  65. dev_err(scomp->dev, "error: cannot find PCM for %s\n",
  66. swidget->widget->name);
  67. return -EINVAL;
  68. }
  69. params = &spcm->params[dir];
  70. /* set IPC PCM params */
  71. pcm.hdr.size = sizeof(pcm);
  72. pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS;
  73. pcm.comp_id = swidget->comp_id;
  74. pcm.params.hdr.size = sizeof(pcm.params);
  75. pcm.params.direction = dir;
  76. pcm.params.sample_valid_bytes = params_width(params) >> 3;
  77. pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
  78. pcm.params.rate = params_rate(params);
  79. pcm.params.channels = params_channels(params);
  80. pcm.params.host_period_bytes = params_period_bytes(params);
  81. /* set format */
  82. switch (params_format(params)) {
  83. case SNDRV_PCM_FORMAT_S16:
  84. pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE;
  85. break;
  86. case SNDRV_PCM_FORMAT_S24:
  87. pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE;
  88. break;
  89. case SNDRV_PCM_FORMAT_S32:
  90. pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
  91. break;
  92. default:
  93. return -EINVAL;
  94. }
  95. /* send IPC to the DSP */
  96. ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
  97. &ipc_params_reply, sizeof(ipc_params_reply));
  98. if (ret < 0)
  99. dev_err(scomp->dev, "error: pcm params failed for %s\n",
  100. swidget->widget->name);
  101. return ret;
  102. }
  103. /* send stream trigger ipc */
  104. static int ipc_trigger(struct snd_sof_widget *swidget, int cmd)
  105. {
  106. struct snd_soc_component *scomp = swidget->scomp;
  107. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  108. struct sof_ipc_stream stream;
  109. struct sof_ipc_reply reply;
  110. int ret;
  111. /* set IPC stream params */
  112. stream.hdr.size = sizeof(stream);
  113. stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | cmd;
  114. stream.comp_id = swidget->comp_id;
  115. /* send IPC to the DSP */
  116. ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
  117. sizeof(stream), &reply, sizeof(reply));
  118. if (ret < 0)
  119. dev_err(scomp->dev, "error: failed to trigger %s\n",
  120. swidget->widget->name);
  121. return ret;
  122. }
  123. static int sof_keyword_dapm_event(struct snd_soc_dapm_widget *w,
  124. struct snd_kcontrol *k, int event)
  125. {
  126. struct snd_sof_widget *swidget = w->dobj.private;
  127. struct snd_soc_component *scomp;
  128. int stream = SNDRV_PCM_STREAM_CAPTURE;
  129. struct snd_sof_pcm *spcm;
  130. int ret = 0;
  131. if (!swidget)
  132. return 0;
  133. scomp = swidget->scomp;
  134. dev_dbg(scomp->dev, "received event %d for widget %s\n",
  135. event, w->name);
  136. /* get runtime PCM params using widget's stream name */
  137. spcm = snd_sof_find_spcm_name(scomp, swidget->widget->sname);
  138. if (!spcm) {
  139. dev_err(scomp->dev, "error: cannot find PCM for %s\n",
  140. swidget->widget->name);
  141. return -EINVAL;
  142. }
  143. /* process events */
  144. switch (event) {
  145. case SND_SOC_DAPM_PRE_PMU:
  146. if (spcm->stream[stream].suspend_ignored) {
  147. dev_dbg(scomp->dev, "PRE_PMU event ignored, KWD pipeline is already RUNNING\n");
  148. return 0;
  149. }
  150. /* set pcm params */
  151. ret = ipc_pcm_params(swidget, stream);
  152. if (ret < 0) {
  153. dev_err(scomp->dev,
  154. "error: failed to set pcm params for widget %s\n",
  155. swidget->widget->name);
  156. break;
  157. }
  158. /* start trigger */
  159. ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_START);
  160. if (ret < 0)
  161. dev_err(scomp->dev,
  162. "error: failed to trigger widget %s\n",
  163. swidget->widget->name);
  164. break;
  165. case SND_SOC_DAPM_POST_PMD:
  166. if (spcm->stream[stream].suspend_ignored) {
  167. dev_dbg(scomp->dev, "POST_PMD even ignored, KWD pipeline will remain RUNNING\n");
  168. return 0;
  169. }
  170. /* stop trigger */
  171. ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_STOP);
  172. if (ret < 0)
  173. dev_err(scomp->dev,
  174. "error: failed to trigger widget %s\n",
  175. swidget->widget->name);
  176. /* pcm free */
  177. ret = ipc_trigger(swidget, SOF_IPC_STREAM_PCM_FREE);
  178. if (ret < 0)
  179. dev_err(scomp->dev,
  180. "error: failed to trigger widget %s\n",
  181. swidget->widget->name);
  182. break;
  183. default:
  184. break;
  185. }
  186. return ret;
  187. }
  188. /* event handlers for keyword detect component */
  189. static const struct snd_soc_tplg_widget_events sof_kwd_events[] = {
  190. {SOF_KEYWORD_DETECT_DAPM_EVENT, sof_keyword_dapm_event},
  191. };
  192. static inline int get_tlv_data(const int *p, int tlv[TLV_ITEMS])
  193. {
  194. /* we only support dB scale TLV type at the moment */
  195. if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
  196. return -EINVAL;
  197. /* min value in topology tlv data is multiplied by 100 */
  198. tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100;
  199. /* volume steps */
  200. tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
  201. TLV_DB_SCALE_MASK);
  202. /* mute ON/OFF */
  203. if ((p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] &
  204. TLV_DB_SCALE_MUTE) == 0)
  205. tlv[TLV_MUTE] = 0;
  206. else
  207. tlv[TLV_MUTE] = 1;
  208. return 0;
  209. }
  210. /*
  211. * Function to truncate an unsigned 64-bit number
  212. * by x bits and return 32-bit unsigned number. This
  213. * function also takes care of rounding while truncating
  214. */
  215. static inline u32 vol_shift_64(u64 i, u32 x)
  216. {
  217. /* do not truncate more than 32 bits */
  218. if (x > 32)
  219. x = 32;
  220. if (x == 0)
  221. return (u32)i;
  222. return (u32)(((i >> (x - 1)) + 1) >> 1);
  223. }
  224. /*
  225. * Function to compute a ^ exp where,
  226. * a is a fractional number represented by a fixed-point
  227. * integer with a fractional world length of "fwl"
  228. * exp is an integer
  229. * fwl is the fractional word length
  230. * Return value is a fractional number represented by a
  231. * fixed-point integer with a fractional word length of "fwl"
  232. */
  233. static u32 vol_pow32(u32 a, int exp, u32 fwl)
  234. {
  235. int i, iter;
  236. u32 power = 1 << fwl;
  237. u64 numerator;
  238. /* if exponent is 0, return 1 */
  239. if (exp == 0)
  240. return power;
  241. /* determine the number of iterations based on the exponent */
  242. if (exp < 0)
  243. iter = exp * -1;
  244. else
  245. iter = exp;
  246. /* mutiply a "iter" times to compute power */
  247. for (i = 0; i < iter; i++) {
  248. /*
  249. * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl
  250. * Truncate product back to fwl fractional bits with rounding
  251. */
  252. power = vol_shift_64((u64)power * a, fwl);
  253. }
  254. if (exp > 0) {
  255. /* if exp is positive, return the result */
  256. return power;
  257. }
  258. /* if exp is negative, return the multiplicative inverse */
  259. numerator = (u64)1 << (fwl << 1);
  260. do_div(numerator, power);
  261. return (u32)numerator;
  262. }
  263. /*
  264. * Function to calculate volume gain from TLV data.
  265. * This function can only handle gain steps that are multiples of 0.5 dB
  266. */
  267. static u32 vol_compute_gain(u32 value, int *tlv)
  268. {
  269. int dB_gain;
  270. u32 linear_gain;
  271. int f_step;
  272. /* mute volume */
  273. if (value == 0 && tlv[TLV_MUTE])
  274. return 0;
  275. /*
  276. * compute dB gain from tlv. tlv_step
  277. * in topology is multiplied by 100
  278. */
  279. dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100;
  280. /*
  281. * compute linear gain represented by fixed-point
  282. * int with VOLUME_FWL fractional bits
  283. */
  284. linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL);
  285. /* extract the fractional part of volume step */
  286. f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100);
  287. /* if volume step is an odd multiple of 0.5 dB */
  288. if (f_step == VOL_HALF_DB_STEP && (value & 1))
  289. linear_gain = vol_shift_64((u64)linear_gain *
  290. VOL_FORTIETH_ROOT_OF_TEN,
  291. VOLUME_FWL);
  292. return linear_gain;
  293. }
  294. /*
  295. * Set up volume table for kcontrols from tlv data
  296. * "size" specifies the number of entries in the table
  297. */
  298. static int set_up_volume_table(struct snd_sof_control *scontrol,
  299. int tlv[TLV_ITEMS], int size)
  300. {
  301. int j;
  302. /* init the volume table */
  303. scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL);
  304. if (!scontrol->volume_table)
  305. return -ENOMEM;
  306. /* populate the volume table */
  307. for (j = 0; j < size ; j++)
  308. scontrol->volume_table[j] = vol_compute_gain(j, tlv);
  309. return 0;
  310. }
  311. struct sof_dai_types {
  312. const char *name;
  313. enum sof_ipc_dai_type type;
  314. };
  315. static const struct sof_dai_types sof_dais[] = {
  316. {"SSP", SOF_DAI_INTEL_SSP},
  317. {"HDA", SOF_DAI_INTEL_HDA},
  318. {"DMIC", SOF_DAI_INTEL_DMIC},
  319. {"ALH", SOF_DAI_INTEL_ALH},
  320. {"SAI", SOF_DAI_IMX_SAI},
  321. {"ESAI", SOF_DAI_IMX_ESAI},
  322. };
  323. static enum sof_ipc_dai_type find_dai(const char *name)
  324. {
  325. int i;
  326. for (i = 0; i < ARRAY_SIZE(sof_dais); i++) {
  327. if (strcmp(name, sof_dais[i].name) == 0)
  328. return sof_dais[i].type;
  329. }
  330. return SOF_DAI_INTEL_NONE;
  331. }
  332. /*
  333. * Supported Frame format types and lookup, add new ones to end of list.
  334. */
  335. struct sof_frame_types {
  336. const char *name;
  337. enum sof_ipc_frame frame;
  338. };
  339. static const struct sof_frame_types sof_frames[] = {
  340. {"s16le", SOF_IPC_FRAME_S16_LE},
  341. {"s24le", SOF_IPC_FRAME_S24_4LE},
  342. {"s32le", SOF_IPC_FRAME_S32_LE},
  343. {"float", SOF_IPC_FRAME_FLOAT},
  344. };
  345. static enum sof_ipc_frame find_format(const char *name)
  346. {
  347. int i;
  348. for (i = 0; i < ARRAY_SIZE(sof_frames); i++) {
  349. if (strcmp(name, sof_frames[i].name) == 0)
  350. return sof_frames[i].frame;
  351. }
  352. /* use s32le if nothing is specified */
  353. return SOF_IPC_FRAME_S32_LE;
  354. }
  355. struct sof_process_types {
  356. const char *name;
  357. enum sof_ipc_process_type type;
  358. enum sof_comp_type comp_type;
  359. };
  360. static const struct sof_process_types sof_process[] = {
  361. {"EQFIR", SOF_PROCESS_EQFIR, SOF_COMP_EQ_FIR},
  362. {"EQIIR", SOF_PROCESS_EQIIR, SOF_COMP_EQ_IIR},
  363. {"KEYWORD_DETECT", SOF_PROCESS_KEYWORD_DETECT, SOF_COMP_KEYWORD_DETECT},
  364. {"KPB", SOF_PROCESS_KPB, SOF_COMP_KPB},
  365. {"CHAN_SELECTOR", SOF_PROCESS_CHAN_SELECTOR, SOF_COMP_SELECTOR},
  366. {"MUX", SOF_PROCESS_MUX, SOF_COMP_MUX},
  367. {"DEMUX", SOF_PROCESS_DEMUX, SOF_COMP_DEMUX},
  368. {"DCBLOCK", SOF_PROCESS_DCBLOCK, SOF_COMP_DCBLOCK},
  369. {"SMART_AMP", SOF_PROCESS_SMART_AMP, SOF_COMP_SMART_AMP},
  370. };
  371. static enum sof_ipc_process_type find_process(const char *name)
  372. {
  373. int i;
  374. for (i = 0; i < ARRAY_SIZE(sof_process); i++) {
  375. if (strcmp(name, sof_process[i].name) == 0)
  376. return sof_process[i].type;
  377. }
  378. return SOF_PROCESS_NONE;
  379. }
  380. static enum sof_comp_type find_process_comp_type(enum sof_ipc_process_type type)
  381. {
  382. int i;
  383. for (i = 0; i < ARRAY_SIZE(sof_process); i++) {
  384. if (sof_process[i].type == type)
  385. return sof_process[i].comp_type;
  386. }
  387. return SOF_COMP_NONE;
  388. }
  389. /*
  390. * Topology Token Parsing.
  391. * New tokens should be added to headers and parsing tables below.
  392. */
  393. struct sof_topology_token {
  394. u32 token;
  395. u32 type;
  396. int (*get_token)(void *elem, void *object, u32 offset, u32 size);
  397. u32 offset;
  398. u32 size;
  399. };
  400. static int get_token_u32(void *elem, void *object, u32 offset, u32 size)
  401. {
  402. struct snd_soc_tplg_vendor_value_elem *velem = elem;
  403. u32 *val = (u32 *)((u8 *)object + offset);
  404. *val = le32_to_cpu(velem->value);
  405. return 0;
  406. }
  407. static int get_token_u16(void *elem, void *object, u32 offset, u32 size)
  408. {
  409. struct snd_soc_tplg_vendor_value_elem *velem = elem;
  410. u16 *val = (u16 *)((u8 *)object + offset);
  411. *val = (u16)le32_to_cpu(velem->value);
  412. return 0;
  413. }
  414. static int get_token_uuid(void *elem, void *object, u32 offset, u32 size)
  415. {
  416. struct snd_soc_tplg_vendor_uuid_elem *velem = elem;
  417. u8 *dst = (u8 *)object + offset;
  418. memcpy(dst, velem->uuid, UUID_SIZE);
  419. return 0;
  420. }
  421. static int get_token_comp_format(void *elem, void *object, u32 offset, u32 size)
  422. {
  423. struct snd_soc_tplg_vendor_string_elem *velem = elem;
  424. u32 *val = (u32 *)((u8 *)object + offset);
  425. *val = find_format(velem->string);
  426. return 0;
  427. }
  428. static int get_token_dai_type(void *elem, void *object, u32 offset, u32 size)
  429. {
  430. struct snd_soc_tplg_vendor_string_elem *velem = elem;
  431. u32 *val = (u32 *)((u8 *)object + offset);
  432. *val = find_dai(velem->string);
  433. return 0;
  434. }
  435. static int get_token_process_type(void *elem, void *object, u32 offset,
  436. u32 size)
  437. {
  438. struct snd_soc_tplg_vendor_string_elem *velem = elem;
  439. u32 *val = (u32 *)((u8 *)object + offset);
  440. *val = find_process(velem->string);
  441. return 0;
  442. }
  443. /* Buffers */
  444. static const struct sof_topology_token buffer_tokens[] = {
  445. {SOF_TKN_BUF_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  446. offsetof(struct sof_ipc_buffer, size), 0},
  447. {SOF_TKN_BUF_CAPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  448. offsetof(struct sof_ipc_buffer, caps), 0},
  449. };
  450. /* DAI */
  451. static const struct sof_topology_token dai_tokens[] = {
  452. {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
  453. offsetof(struct sof_ipc_comp_dai, type), 0},
  454. {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  455. offsetof(struct sof_ipc_comp_dai, dai_index), 0},
  456. {SOF_TKN_DAI_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  457. offsetof(struct sof_ipc_comp_dai, direction), 0},
  458. };
  459. /* BE DAI link */
  460. static const struct sof_topology_token dai_link_tokens[] = {
  461. {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
  462. offsetof(struct sof_ipc_dai_config, type), 0},
  463. {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  464. offsetof(struct sof_ipc_dai_config, dai_index), 0},
  465. };
  466. /* scheduling */
  467. static const struct sof_topology_token sched_tokens[] = {
  468. {SOF_TKN_SCHED_PERIOD, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  469. offsetof(struct sof_ipc_pipe_new, period), 0},
  470. {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  471. offsetof(struct sof_ipc_pipe_new, priority), 0},
  472. {SOF_TKN_SCHED_MIPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  473. offsetof(struct sof_ipc_pipe_new, period_mips), 0},
  474. {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  475. offsetof(struct sof_ipc_pipe_new, core), 0},
  476. {SOF_TKN_SCHED_FRAMES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  477. offsetof(struct sof_ipc_pipe_new, frames_per_sched), 0},
  478. {SOF_TKN_SCHED_TIME_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  479. offsetof(struct sof_ipc_pipe_new, time_domain), 0},
  480. };
  481. /* volume */
  482. static const struct sof_topology_token volume_tokens[] = {
  483. {SOF_TKN_VOLUME_RAMP_STEP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  484. get_token_u32, offsetof(struct sof_ipc_comp_volume, ramp), 0},
  485. {SOF_TKN_VOLUME_RAMP_STEP_MS,
  486. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  487. offsetof(struct sof_ipc_comp_volume, initial_ramp), 0},
  488. };
  489. /* SRC */
  490. static const struct sof_topology_token src_tokens[] = {
  491. {SOF_TKN_SRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  492. offsetof(struct sof_ipc_comp_src, source_rate), 0},
  493. {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  494. offsetof(struct sof_ipc_comp_src, sink_rate), 0},
  495. };
  496. /* ASRC */
  497. static const struct sof_topology_token asrc_tokens[] = {
  498. {SOF_TKN_ASRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  499. offsetof(struct sof_ipc_comp_asrc, source_rate), 0},
  500. {SOF_TKN_ASRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  501. offsetof(struct sof_ipc_comp_asrc, sink_rate), 0},
  502. {SOF_TKN_ASRC_ASYNCHRONOUS_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  503. get_token_u32,
  504. offsetof(struct sof_ipc_comp_asrc, asynchronous_mode), 0},
  505. {SOF_TKN_ASRC_OPERATION_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  506. get_token_u32,
  507. offsetof(struct sof_ipc_comp_asrc, operation_mode), 0},
  508. };
  509. /* Tone */
  510. static const struct sof_topology_token tone_tokens[] = {
  511. };
  512. /* EFFECT */
  513. static const struct sof_topology_token process_tokens[] = {
  514. {SOF_TKN_PROCESS_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING,
  515. get_token_process_type,
  516. offsetof(struct sof_ipc_comp_process, type), 0},
  517. };
  518. /* PCM */
  519. static const struct sof_topology_token pcm_tokens[] = {
  520. {SOF_TKN_PCM_DMAC_CONFIG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  521. offsetof(struct sof_ipc_comp_host, dmac_config), 0},
  522. };
  523. /* PCM */
  524. static const struct sof_topology_token stream_tokens[] = {
  525. {SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3,
  526. SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
  527. offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible), 0},
  528. {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3,
  529. SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
  530. offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible), 0},
  531. };
  532. /* Generic components */
  533. static const struct sof_topology_token comp_tokens[] = {
  534. {SOF_TKN_COMP_PERIOD_SINK_COUNT,
  535. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  536. offsetof(struct sof_ipc_comp_config, periods_sink), 0},
  537. {SOF_TKN_COMP_PERIOD_SOURCE_COUNT,
  538. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  539. offsetof(struct sof_ipc_comp_config, periods_source), 0},
  540. {SOF_TKN_COMP_FORMAT,
  541. SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format,
  542. offsetof(struct sof_ipc_comp_config, frame_fmt), 0},
  543. };
  544. /* SSP */
  545. static const struct sof_topology_token ssp_tokens[] = {
  546. {SOF_TKN_INTEL_SSP_CLKS_CONTROL,
  547. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  548. offsetof(struct sof_ipc_dai_ssp_params, clks_control), 0},
  549. {SOF_TKN_INTEL_SSP_MCLK_ID,
  550. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  551. offsetof(struct sof_ipc_dai_ssp_params, mclk_id), 0},
  552. {SOF_TKN_INTEL_SSP_SAMPLE_BITS, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  553. get_token_u32,
  554. offsetof(struct sof_ipc_dai_ssp_params, sample_valid_bits), 0},
  555. {SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH, SND_SOC_TPLG_TUPLE_TYPE_SHORT,
  556. get_token_u16,
  557. offsetof(struct sof_ipc_dai_ssp_params, frame_pulse_width), 0},
  558. {SOF_TKN_INTEL_SSP_QUIRKS, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  559. get_token_u32,
  560. offsetof(struct sof_ipc_dai_ssp_params, quirks), 0},
  561. {SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT, SND_SOC_TPLG_TUPLE_TYPE_BOOL,
  562. get_token_u16,
  563. offsetof(struct sof_ipc_dai_ssp_params,
  564. tdm_per_slot_padding_flag), 0},
  565. {SOF_TKN_INTEL_SSP_BCLK_DELAY, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  566. get_token_u32,
  567. offsetof(struct sof_ipc_dai_ssp_params, bclk_delay), 0},
  568. };
  569. /* ALH */
  570. static const struct sof_topology_token alh_tokens[] = {
  571. {SOF_TKN_INTEL_ALH_RATE,
  572. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  573. offsetof(struct sof_ipc_dai_alh_params, rate), 0},
  574. {SOF_TKN_INTEL_ALH_CH,
  575. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  576. offsetof(struct sof_ipc_dai_alh_params, channels), 0},
  577. };
  578. /* DMIC */
  579. static const struct sof_topology_token dmic_tokens[] = {
  580. {SOF_TKN_INTEL_DMIC_DRIVER_VERSION,
  581. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  582. offsetof(struct sof_ipc_dai_dmic_params, driver_ipc_version),
  583. 0},
  584. {SOF_TKN_INTEL_DMIC_CLK_MIN,
  585. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  586. offsetof(struct sof_ipc_dai_dmic_params, pdmclk_min), 0},
  587. {SOF_TKN_INTEL_DMIC_CLK_MAX,
  588. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  589. offsetof(struct sof_ipc_dai_dmic_params, pdmclk_max), 0},
  590. {SOF_TKN_INTEL_DMIC_SAMPLE_RATE,
  591. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  592. offsetof(struct sof_ipc_dai_dmic_params, fifo_fs), 0},
  593. {SOF_TKN_INTEL_DMIC_DUTY_MIN,
  594. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  595. offsetof(struct sof_ipc_dai_dmic_params, duty_min), 0},
  596. {SOF_TKN_INTEL_DMIC_DUTY_MAX,
  597. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  598. offsetof(struct sof_ipc_dai_dmic_params, duty_max), 0},
  599. {SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE,
  600. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  601. offsetof(struct sof_ipc_dai_dmic_params,
  602. num_pdm_active), 0},
  603. {SOF_TKN_INTEL_DMIC_FIFO_WORD_LENGTH,
  604. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  605. offsetof(struct sof_ipc_dai_dmic_params, fifo_bits), 0},
  606. {SOF_TKN_INTEL_DMIC_UNMUTE_RAMP_TIME_MS,
  607. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  608. offsetof(struct sof_ipc_dai_dmic_params, unmute_ramp_time), 0},
  609. };
  610. /* ESAI */
  611. static const struct sof_topology_token esai_tokens[] = {
  612. {SOF_TKN_IMX_ESAI_MCLK_ID,
  613. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  614. offsetof(struct sof_ipc_dai_esai_params, mclk_id), 0},
  615. };
  616. /* SAI */
  617. static const struct sof_topology_token sai_tokens[] = {
  618. {SOF_TKN_IMX_SAI_MCLK_ID,
  619. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  620. offsetof(struct sof_ipc_dai_sai_params, mclk_id), 0},
  621. };
  622. /* Core tokens */
  623. static const struct sof_topology_token core_tokens[] = {
  624. {SOF_TKN_COMP_CORE_ID,
  625. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  626. offsetof(struct sof_ipc_comp, core), 0},
  627. };
  628. /* Component extended tokens */
  629. static const struct sof_topology_token comp_ext_tokens[] = {
  630. {SOF_TKN_COMP_UUID,
  631. SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid,
  632. offsetof(struct sof_ipc_comp_ext, uuid), 0},
  633. };
  634. /*
  635. * DMIC PDM Tokens
  636. * SOF_TKN_INTEL_DMIC_PDM_CTRL_ID should be the first token
  637. * as it increments the index while parsing the array of pdm tokens
  638. * and determines the correct offset
  639. */
  640. static const struct sof_topology_token dmic_pdm_tokens[] = {
  641. {SOF_TKN_INTEL_DMIC_PDM_CTRL_ID,
  642. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  643. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, id),
  644. 0},
  645. {SOF_TKN_INTEL_DMIC_PDM_MIC_A_Enable,
  646. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  647. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, enable_mic_a),
  648. 0},
  649. {SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable,
  650. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  651. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, enable_mic_b),
  652. 0},
  653. {SOF_TKN_INTEL_DMIC_PDM_POLARITY_A,
  654. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  655. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, polarity_mic_a),
  656. 0},
  657. {SOF_TKN_INTEL_DMIC_PDM_POLARITY_B,
  658. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  659. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, polarity_mic_b),
  660. 0},
  661. {SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE,
  662. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  663. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, clk_edge),
  664. 0},
  665. {SOF_TKN_INTEL_DMIC_PDM_SKEW,
  666. SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
  667. offsetof(struct sof_ipc_dai_dmic_pdm_ctrl, skew),
  668. 0},
  669. };
  670. /* HDA */
  671. static const struct sof_topology_token hda_tokens[] = {
  672. {SOF_TKN_INTEL_HDA_RATE,
  673. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  674. offsetof(struct sof_ipc_dai_hda_params, rate), 0},
  675. {SOF_TKN_INTEL_HDA_CH,
  676. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  677. offsetof(struct sof_ipc_dai_hda_params, channels), 0},
  678. };
  679. /* Leds */
  680. static const struct sof_topology_token led_tokens[] = {
  681. {SOF_TKN_MUTE_LED_USE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  682. offsetof(struct snd_sof_led_control, use_led), 0},
  683. {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  684. get_token_u32, offsetof(struct snd_sof_led_control, direction), 0},
  685. };
  686. static int sof_parse_uuid_tokens(struct snd_soc_component *scomp,
  687. void *object,
  688. const struct sof_topology_token *tokens,
  689. int count,
  690. struct snd_soc_tplg_vendor_array *array,
  691. size_t offset)
  692. {
  693. struct snd_soc_tplg_vendor_uuid_elem *elem;
  694. int found = 0;
  695. int i, j;
  696. /* parse element by element */
  697. for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
  698. elem = &array->uuid[i];
  699. /* search for token */
  700. for (j = 0; j < count; j++) {
  701. /* match token type */
  702. if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID)
  703. continue;
  704. /* match token id */
  705. if (tokens[j].token != le32_to_cpu(elem->token))
  706. continue;
  707. /* matched - now load token */
  708. tokens[j].get_token(elem, object,
  709. offset + tokens[j].offset,
  710. tokens[j].size);
  711. found++;
  712. }
  713. }
  714. return found;
  715. }
  716. static int sof_parse_string_tokens(struct snd_soc_component *scomp,
  717. void *object,
  718. const struct sof_topology_token *tokens,
  719. int count,
  720. struct snd_soc_tplg_vendor_array *array,
  721. size_t offset)
  722. {
  723. struct snd_soc_tplg_vendor_string_elem *elem;
  724. int found = 0;
  725. int i, j;
  726. /* parse element by element */
  727. for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
  728. elem = &array->string[i];
  729. /* search for token */
  730. for (j = 0; j < count; j++) {
  731. /* match token type */
  732. if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING)
  733. continue;
  734. /* match token id */
  735. if (tokens[j].token != le32_to_cpu(elem->token))
  736. continue;
  737. /* matched - now load token */
  738. tokens[j].get_token(elem, object,
  739. offset + tokens[j].offset,
  740. tokens[j].size);
  741. found++;
  742. }
  743. }
  744. return found;
  745. }
  746. static int sof_parse_word_tokens(struct snd_soc_component *scomp,
  747. void *object,
  748. const struct sof_topology_token *tokens,
  749. int count,
  750. struct snd_soc_tplg_vendor_array *array,
  751. size_t offset)
  752. {
  753. struct snd_soc_tplg_vendor_value_elem *elem;
  754. int found = 0;
  755. int i, j;
  756. /* parse element by element */
  757. for (i = 0; i < le32_to_cpu(array->num_elems); i++) {
  758. elem = &array->value[i];
  759. /* search for token */
  760. for (j = 0; j < count; j++) {
  761. /* match token type */
  762. if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD ||
  763. tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT ||
  764. tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE ||
  765. tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL))
  766. continue;
  767. /* match token id */
  768. if (tokens[j].token != le32_to_cpu(elem->token))
  769. continue;
  770. /* load token */
  771. tokens[j].get_token(elem, object,
  772. offset + tokens[j].offset,
  773. tokens[j].size);
  774. found++;
  775. }
  776. }
  777. return found;
  778. }
  779. /**
  780. * sof_parse_token_sets - Parse multiple sets of tokens
  781. * @scomp: pointer to soc component
  782. * @object: target ipc struct for parsed values
  783. * @tokens: token definition array describing what tokens to parse
  784. * @count: number of tokens in definition array
  785. * @array: source pointer to consecutive vendor arrays to be parsed
  786. * @priv_size: total size of the consecutive source arrays
  787. * @sets: number of similar token sets to be parsed, 1 set has count elements
  788. * @object_size: offset to next target ipc struct with multiple sets
  789. *
  790. * This function parses multiple sets of tokens in vendor arrays into
  791. * consecutive ipc structs.
  792. */
  793. static int sof_parse_token_sets(struct snd_soc_component *scomp,
  794. void *object,
  795. const struct sof_topology_token *tokens,
  796. int count,
  797. struct snd_soc_tplg_vendor_array *array,
  798. int priv_size, int sets, size_t object_size)
  799. {
  800. size_t offset = 0;
  801. int found = 0;
  802. int total = 0;
  803. int asize;
  804. while (priv_size > 0 && total < count * sets) {
  805. asize = le32_to_cpu(array->size);
  806. /* validate asize */
  807. if (asize < 0) { /* FIXME: A zero-size array makes no sense */
  808. dev_err(scomp->dev, "error: invalid array size 0x%x\n",
  809. asize);
  810. return -EINVAL;
  811. }
  812. /* make sure there is enough data before parsing */
  813. priv_size -= asize;
  814. if (priv_size < 0) {
  815. dev_err(scomp->dev, "error: invalid array size 0x%x\n",
  816. asize);
  817. return -EINVAL;
  818. }
  819. /* call correct parser depending on type */
  820. switch (le32_to_cpu(array->type)) {
  821. case SND_SOC_TPLG_TUPLE_TYPE_UUID:
  822. found += sof_parse_uuid_tokens(scomp, object, tokens,
  823. count, array, offset);
  824. break;
  825. case SND_SOC_TPLG_TUPLE_TYPE_STRING:
  826. found += sof_parse_string_tokens(scomp, object, tokens,
  827. count, array, offset);
  828. break;
  829. case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
  830. case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
  831. case SND_SOC_TPLG_TUPLE_TYPE_WORD:
  832. case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
  833. found += sof_parse_word_tokens(scomp, object, tokens,
  834. count, array, offset);
  835. break;
  836. default:
  837. dev_err(scomp->dev, "error: unknown token type %d\n",
  838. array->type);
  839. return -EINVAL;
  840. }
  841. /* next array */
  842. array = (struct snd_soc_tplg_vendor_array *)((u8 *)array
  843. + asize);
  844. /* move to next target struct */
  845. if (found >= count) {
  846. offset += object_size;
  847. total += found;
  848. found = 0;
  849. }
  850. }
  851. return 0;
  852. }
  853. static int sof_parse_tokens(struct snd_soc_component *scomp,
  854. void *object,
  855. const struct sof_topology_token *tokens,
  856. int count,
  857. struct snd_soc_tplg_vendor_array *array,
  858. int priv_size)
  859. {
  860. /*
  861. * sof_parse_tokens is used when topology contains only a single set of
  862. * identical tuples arrays. So additional parameters to
  863. * sof_parse_token_sets are sets = 1 (only 1 set) and
  864. * object_size = 0 (irrelevant).
  865. */
  866. return sof_parse_token_sets(scomp, object, tokens, count, array,
  867. priv_size, 1, 0);
  868. }
  869. static void sof_dbg_comp_config(struct snd_soc_component *scomp,
  870. struct sof_ipc_comp_config *config)
  871. {
  872. dev_dbg(scomp->dev, " config: periods snk %d src %d fmt %d\n",
  873. config->periods_sink, config->periods_source,
  874. config->frame_fmt);
  875. }
  876. /*
  877. * Standard Kcontrols.
  878. */
  879. static int sof_control_load_volume(struct snd_soc_component *scomp,
  880. struct snd_sof_control *scontrol,
  881. struct snd_kcontrol_new *kc,
  882. struct snd_soc_tplg_ctl_hdr *hdr)
  883. {
  884. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  885. struct snd_soc_tplg_mixer_control *mc =
  886. container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
  887. struct sof_ipc_ctrl_data *cdata;
  888. int tlv[TLV_ITEMS];
  889. unsigned int i;
  890. int ret;
  891. /* validate topology data */
  892. if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) {
  893. ret = -EINVAL;
  894. goto out;
  895. }
  896. /* init the volume get/put data */
  897. scontrol->size = struct_size(scontrol->control_data, chanv,
  898. le32_to_cpu(mc->num_channels));
  899. scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
  900. if (!scontrol->control_data) {
  901. ret = -ENOMEM;
  902. goto out;
  903. }
  904. scontrol->comp_id = sdev->next_comp_id;
  905. scontrol->min_volume_step = le32_to_cpu(mc->min);
  906. scontrol->max_volume_step = le32_to_cpu(mc->max);
  907. scontrol->num_channels = le32_to_cpu(mc->num_channels);
  908. /* set cmd for mixer control */
  909. if (le32_to_cpu(mc->max) == 1) {
  910. scontrol->cmd = SOF_CTRL_CMD_SWITCH;
  911. goto skip;
  912. }
  913. scontrol->cmd = SOF_CTRL_CMD_VOLUME;
  914. /* extract tlv data */
  915. if (get_tlv_data(kc->tlv.p, tlv) < 0) {
  916. dev_err(scomp->dev, "error: invalid TLV data\n");
  917. ret = -EINVAL;
  918. goto out_free;
  919. }
  920. /* set up volume table */
  921. ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1);
  922. if (ret < 0) {
  923. dev_err(scomp->dev, "error: setting up volume table\n");
  924. goto out_free;
  925. }
  926. /* set default volume values to 0dB in control */
  927. cdata = scontrol->control_data;
  928. for (i = 0; i < scontrol->num_channels; i++) {
  929. cdata->chanv[i].channel = i;
  930. cdata->chanv[i].value = VOL_ZERO_DB;
  931. }
  932. skip:
  933. /* set up possible led control from mixer private data */
  934. ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens,
  935. ARRAY_SIZE(led_tokens), mc->priv.array,
  936. le32_to_cpu(mc->priv.size));
  937. if (ret != 0) {
  938. dev_err(scomp->dev, "error: parse led tokens failed %d\n",
  939. le32_to_cpu(mc->priv.size));
  940. goto out_free_table;
  941. }
  942. dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
  943. scontrol->comp_id, scontrol->num_channels);
  944. return 0;
  945. out_free_table:
  946. if (le32_to_cpu(mc->max) > 1)
  947. kfree(scontrol->volume_table);
  948. out_free:
  949. kfree(scontrol->control_data);
  950. out:
  951. return ret;
  952. }
  953. static int sof_control_load_enum(struct snd_soc_component *scomp,
  954. struct snd_sof_control *scontrol,
  955. struct snd_kcontrol_new *kc,
  956. struct snd_soc_tplg_ctl_hdr *hdr)
  957. {
  958. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  959. struct snd_soc_tplg_enum_control *ec =
  960. container_of(hdr, struct snd_soc_tplg_enum_control, hdr);
  961. /* validate topology data */
  962. if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN)
  963. return -EINVAL;
  964. /* init the enum get/put data */
  965. scontrol->size = struct_size(scontrol->control_data, chanv,
  966. le32_to_cpu(ec->num_channels));
  967. scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
  968. if (!scontrol->control_data)
  969. return -ENOMEM;
  970. scontrol->comp_id = sdev->next_comp_id;
  971. scontrol->num_channels = le32_to_cpu(ec->num_channels);
  972. scontrol->cmd = SOF_CTRL_CMD_ENUM;
  973. dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n",
  974. scontrol->comp_id, scontrol->num_channels, scontrol->comp_id);
  975. return 0;
  976. }
  977. static int sof_control_load_bytes(struct snd_soc_component *scomp,
  978. struct snd_sof_control *scontrol,
  979. struct snd_kcontrol_new *kc,
  980. struct snd_soc_tplg_ctl_hdr *hdr)
  981. {
  982. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  983. struct sof_ipc_ctrl_data *cdata;
  984. struct snd_soc_tplg_bytes_control *control =
  985. container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
  986. struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
  987. size_t max_size = sbe->max;
  988. size_t priv_size = le32_to_cpu(control->priv.size);
  989. int ret;
  990. if (max_size < sizeof(struct sof_ipc_ctrl_data) ||
  991. max_size < sizeof(struct sof_abi_hdr)) {
  992. ret = -EINVAL;
  993. goto out;
  994. }
  995. /* init the get/put bytes data */
  996. if (priv_size > max_size - sizeof(struct sof_ipc_ctrl_data)) {
  997. dev_err(scomp->dev, "err: bytes data size %zu exceeds max %zu.\n",
  998. priv_size, max_size - sizeof(struct sof_ipc_ctrl_data));
  999. ret = -EINVAL;
  1000. goto out;
  1001. }
  1002. scontrol->size = sizeof(struct sof_ipc_ctrl_data) + priv_size;
  1003. scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
  1004. cdata = scontrol->control_data;
  1005. if (!scontrol->control_data) {
  1006. ret = -ENOMEM;
  1007. goto out;
  1008. }
  1009. scontrol->comp_id = sdev->next_comp_id;
  1010. scontrol->cmd = SOF_CTRL_CMD_BINARY;
  1011. dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
  1012. scontrol->comp_id, scontrol->num_channels);
  1013. if (le32_to_cpu(control->priv.size) > 0) {
  1014. memcpy(cdata->data, control->priv.data,
  1015. le32_to_cpu(control->priv.size));
  1016. if (cdata->data->magic != SOF_ABI_MAGIC) {
  1017. dev_err(scomp->dev, "error: Wrong ABI magic 0x%08x.\n",
  1018. cdata->data->magic);
  1019. ret = -EINVAL;
  1020. goto out_free;
  1021. }
  1022. if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION,
  1023. cdata->data->abi)) {
  1024. dev_err(scomp->dev,
  1025. "error: Incompatible ABI version 0x%08x.\n",
  1026. cdata->data->abi);
  1027. ret = -EINVAL;
  1028. goto out_free;
  1029. }
  1030. if (cdata->data->size + sizeof(const struct sof_abi_hdr) !=
  1031. le32_to_cpu(control->priv.size)) {
  1032. dev_err(scomp->dev,
  1033. "error: Conflict in bytes vs. priv size.\n");
  1034. ret = -EINVAL;
  1035. goto out_free;
  1036. }
  1037. }
  1038. return 0;
  1039. out_free:
  1040. kfree(scontrol->control_data);
  1041. out:
  1042. return ret;
  1043. }
  1044. /* external kcontrol init - used for any driver specific init */
  1045. static int sof_control_load(struct snd_soc_component *scomp, int index,
  1046. struct snd_kcontrol_new *kc,
  1047. struct snd_soc_tplg_ctl_hdr *hdr)
  1048. {
  1049. struct soc_mixer_control *sm;
  1050. struct soc_bytes_ext *sbe;
  1051. struct soc_enum *se;
  1052. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1053. struct snd_soc_dobj *dobj;
  1054. struct snd_sof_control *scontrol;
  1055. int ret;
  1056. dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n",
  1057. hdr->type, hdr->name);
  1058. scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL);
  1059. if (!scontrol)
  1060. return -ENOMEM;
  1061. scontrol->scomp = scomp;
  1062. switch (le32_to_cpu(hdr->ops.info)) {
  1063. case SND_SOC_TPLG_CTL_VOLSW:
  1064. case SND_SOC_TPLG_CTL_VOLSW_SX:
  1065. case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
  1066. sm = (struct soc_mixer_control *)kc->private_value;
  1067. dobj = &sm->dobj;
  1068. ret = sof_control_load_volume(scomp, scontrol, kc, hdr);
  1069. break;
  1070. case SND_SOC_TPLG_CTL_BYTES:
  1071. sbe = (struct soc_bytes_ext *)kc->private_value;
  1072. dobj = &sbe->dobj;
  1073. ret = sof_control_load_bytes(scomp, scontrol, kc, hdr);
  1074. break;
  1075. case SND_SOC_TPLG_CTL_ENUM:
  1076. case SND_SOC_TPLG_CTL_ENUM_VALUE:
  1077. se = (struct soc_enum *)kc->private_value;
  1078. dobj = &se->dobj;
  1079. ret = sof_control_load_enum(scomp, scontrol, kc, hdr);
  1080. break;
  1081. case SND_SOC_TPLG_CTL_RANGE:
  1082. case SND_SOC_TPLG_CTL_STROBE:
  1083. case SND_SOC_TPLG_DAPM_CTL_VOLSW:
  1084. case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
  1085. case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
  1086. case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
  1087. case SND_SOC_TPLG_DAPM_CTL_PIN:
  1088. default:
  1089. dev_warn(scomp->dev, "control type not supported %d:%d:%d\n",
  1090. hdr->ops.get, hdr->ops.put, hdr->ops.info);
  1091. kfree(scontrol);
  1092. return 0;
  1093. }
  1094. if (ret < 0) {
  1095. kfree(scontrol);
  1096. return ret;
  1097. }
  1098. scontrol->led_ctl.led_value = -1;
  1099. dobj->private = scontrol;
  1100. list_add(&scontrol->list, &sdev->kcontrol_list);
  1101. return 0;
  1102. }
  1103. static int sof_control_unload(struct snd_soc_component *scomp,
  1104. struct snd_soc_dobj *dobj)
  1105. {
  1106. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1107. struct sof_ipc_free fcomp;
  1108. struct snd_sof_control *scontrol = dobj->private;
  1109. dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scomp->name);
  1110. fcomp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_FREE;
  1111. fcomp.hdr.size = sizeof(fcomp);
  1112. fcomp.id = scontrol->comp_id;
  1113. kfree(scontrol->control_data);
  1114. list_del(&scontrol->list);
  1115. kfree(scontrol);
  1116. /* send IPC to the DSP */
  1117. return sof_ipc_tx_message(sdev->ipc,
  1118. fcomp.hdr.cmd, &fcomp, sizeof(fcomp),
  1119. NULL, 0);
  1120. }
  1121. /*
  1122. * DAI Topology
  1123. */
  1124. /* Static DSP core power management so far, should be extended in the future */
  1125. static int sof_core_enable(struct snd_sof_dev *sdev, int core)
  1126. {
  1127. struct sof_ipc_pm_core_config pm_core_config = {
  1128. .hdr = {
  1129. .cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE,
  1130. .size = sizeof(pm_core_config),
  1131. },
  1132. .enable_mask = sdev->enabled_cores_mask | BIT(core),
  1133. };
  1134. int ret;
  1135. if (sdev->enabled_cores_mask & BIT(core))
  1136. return 0;
  1137. /* power up the core if it is host managed */
  1138. ret = snd_sof_dsp_core_power_up(sdev, BIT(core));
  1139. if (ret < 0) {
  1140. dev_err(sdev->dev, "error: %d powering up core %d\n",
  1141. ret, core);
  1142. return ret;
  1143. }
  1144. /* Now notify DSP */
  1145. ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd,
  1146. &pm_core_config, sizeof(pm_core_config),
  1147. &pm_core_config, sizeof(pm_core_config));
  1148. if (ret < 0) {
  1149. dev_err(sdev->dev, "error: core %d enable ipc failure %d\n",
  1150. core, ret);
  1151. goto err;
  1152. }
  1153. /* update enabled cores mask */
  1154. sdev->enabled_cores_mask |= BIT(core);
  1155. return ret;
  1156. err:
  1157. /* power down core if it is host managed and return the original error if this fails too */
  1158. if (snd_sof_dsp_core_power_down(sdev, BIT(core)) < 0)
  1159. dev_err(sdev->dev, "error: powering down core %d\n", core);
  1160. return ret;
  1161. }
  1162. int sof_pipeline_core_enable(struct snd_sof_dev *sdev,
  1163. const struct snd_sof_widget *swidget)
  1164. {
  1165. const struct sof_ipc_pipe_new *pipeline;
  1166. int ret;
  1167. if (swidget->id == snd_soc_dapm_scheduler) {
  1168. pipeline = swidget->private;
  1169. } else {
  1170. pipeline = snd_sof_pipeline_find(sdev, swidget->pipeline_id);
  1171. if (!pipeline)
  1172. return -ENOENT;
  1173. }
  1174. /* First enable the pipeline core */
  1175. ret = sof_core_enable(sdev, pipeline->core);
  1176. if (ret < 0)
  1177. return ret;
  1178. return sof_core_enable(sdev, swidget->core);
  1179. }
  1180. static int sof_connect_dai_widget(struct snd_soc_component *scomp,
  1181. struct snd_soc_dapm_widget *w,
  1182. struct snd_soc_tplg_dapm_widget *tw,
  1183. struct snd_sof_dai *dai)
  1184. {
  1185. struct snd_soc_card *card = scomp->card;
  1186. struct snd_soc_pcm_runtime *rtd;
  1187. struct snd_soc_dai *cpu_dai;
  1188. int i;
  1189. list_for_each_entry(rtd, &card->rtd_list, list) {
  1190. dev_vdbg(scomp->dev, "tplg: check widget: %s stream: %s dai stream: %s\n",
  1191. w->name, w->sname, rtd->dai_link->stream_name);
  1192. if (!w->sname || !rtd->dai_link->stream_name)
  1193. continue;
  1194. /* does stream match DAI link ? */
  1195. if (strcmp(w->sname, rtd->dai_link->stream_name))
  1196. continue;
  1197. switch (w->id) {
  1198. case snd_soc_dapm_dai_out:
  1199. for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
  1200. /*
  1201. * Please create DAI widget in the right order
  1202. * to ensure BE will connect to the right DAI
  1203. * widget.
  1204. */
  1205. if (!cpu_dai->capture_widget) {
  1206. cpu_dai->capture_widget = w;
  1207. break;
  1208. }
  1209. }
  1210. if (i == rtd->num_cpus) {
  1211. dev_err(scomp->dev, "error: can't find BE for DAI %s\n",
  1212. w->name);
  1213. return -EINVAL;
  1214. }
  1215. dai->name = rtd->dai_link->name;
  1216. dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
  1217. w->name, rtd->dai_link->name);
  1218. break;
  1219. case snd_soc_dapm_dai_in:
  1220. for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
  1221. /*
  1222. * Please create DAI widget in the right order
  1223. * to ensure BE will connect to the right DAI
  1224. * widget.
  1225. */
  1226. if (!cpu_dai->playback_widget) {
  1227. cpu_dai->playback_widget = w;
  1228. break;
  1229. }
  1230. }
  1231. if (i == rtd->num_cpus) {
  1232. dev_err(scomp->dev, "error: can't find BE for DAI %s\n",
  1233. w->name);
  1234. return -EINVAL;
  1235. }
  1236. dai->name = rtd->dai_link->name;
  1237. dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n",
  1238. w->name, rtd->dai_link->name);
  1239. break;
  1240. default:
  1241. break;
  1242. }
  1243. }
  1244. /* check we have a connection */
  1245. if (!dai->name) {
  1246. dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n",
  1247. w->name, w->sname);
  1248. return -EINVAL;
  1249. }
  1250. return 0;
  1251. }
  1252. /**
  1253. * sof_comp_alloc - allocate and initialize buffer for a new component
  1254. * @swidget: pointer to struct snd_sof_widget containing extended data
  1255. * @ipc_size: IPC payload size that will be updated depending on valid
  1256. * extended data.
  1257. * @index: ID of the pipeline the component belongs to
  1258. *
  1259. * Return: The pointer to the new allocated component, NULL if failed.
  1260. */
  1261. static struct sof_ipc_comp *sof_comp_alloc(struct snd_sof_widget *swidget,
  1262. size_t *ipc_size, int index)
  1263. {
  1264. u8 nil_uuid[SOF_UUID_SIZE] = {0};
  1265. struct sof_ipc_comp *comp;
  1266. size_t total_size = *ipc_size;
  1267. /* only non-zero UUID is valid */
  1268. if (memcmp(&swidget->comp_ext, nil_uuid, SOF_UUID_SIZE))
  1269. total_size += sizeof(swidget->comp_ext);
  1270. comp = kzalloc(total_size, GFP_KERNEL);
  1271. if (!comp)
  1272. return NULL;
  1273. /* configure comp new IPC message */
  1274. comp->hdr.size = total_size;
  1275. comp->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW;
  1276. comp->id = swidget->comp_id;
  1277. comp->pipeline_id = index;
  1278. comp->core = swidget->core;
  1279. /* handle the extended data if needed */
  1280. if (total_size > *ipc_size) {
  1281. /* append extended data to the end of the component */
  1282. memcpy((u8 *)comp + *ipc_size, &swidget->comp_ext, sizeof(swidget->comp_ext));
  1283. comp->ext_data_length = sizeof(swidget->comp_ext);
  1284. }
  1285. /* update ipc_size and return */
  1286. *ipc_size = total_size;
  1287. return comp;
  1288. }
  1289. static int sof_widget_load_dai(struct snd_soc_component *scomp, int index,
  1290. struct snd_sof_widget *swidget,
  1291. struct snd_soc_tplg_dapm_widget *tw,
  1292. struct sof_ipc_comp_reply *r,
  1293. struct snd_sof_dai *dai)
  1294. {
  1295. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1296. struct snd_soc_tplg_private *private = &tw->priv;
  1297. struct sof_ipc_comp_dai *comp_dai;
  1298. size_t ipc_size = sizeof(*comp_dai);
  1299. int ret;
  1300. comp_dai = (struct sof_ipc_comp_dai *)
  1301. sof_comp_alloc(swidget, &ipc_size, index);
  1302. if (!comp_dai)
  1303. return -ENOMEM;
  1304. /* configure dai IPC message */
  1305. comp_dai->comp.type = SOF_COMP_DAI;
  1306. comp_dai->config.hdr.size = sizeof(comp_dai->config);
  1307. ret = sof_parse_tokens(scomp, comp_dai, dai_tokens,
  1308. ARRAY_SIZE(dai_tokens), private->array,
  1309. le32_to_cpu(private->size));
  1310. if (ret != 0) {
  1311. dev_err(scomp->dev, "error: parse dai tokens failed %d\n",
  1312. le32_to_cpu(private->size));
  1313. goto finish;
  1314. }
  1315. ret = sof_parse_tokens(scomp, &comp_dai->config, comp_tokens,
  1316. ARRAY_SIZE(comp_tokens), private->array,
  1317. le32_to_cpu(private->size));
  1318. if (ret != 0) {
  1319. dev_err(scomp->dev, "error: parse dai.cfg tokens failed %d\n",
  1320. private->size);
  1321. goto finish;
  1322. }
  1323. dev_dbg(scomp->dev, "dai %s: type %d index %d\n",
  1324. swidget->widget->name, comp_dai->type, comp_dai->dai_index);
  1325. sof_dbg_comp_config(scomp, &comp_dai->config);
  1326. ret = sof_ipc_tx_message(sdev->ipc, comp_dai->comp.hdr.cmd,
  1327. comp_dai, ipc_size, r, sizeof(*r));
  1328. if (ret == 0 && dai) {
  1329. dai->scomp = scomp;
  1330. /*
  1331. * copy only the sof_ipc_comp_dai to avoid collapsing
  1332. * the snd_sof_dai, the extended data is kept in the
  1333. * snd_sof_widget.
  1334. */
  1335. memcpy(&dai->comp_dai, comp_dai, sizeof(*comp_dai));
  1336. }
  1337. finish:
  1338. kfree(comp_dai);
  1339. return ret;
  1340. }
  1341. /*
  1342. * Buffer topology
  1343. */
  1344. static int sof_widget_load_buffer(struct snd_soc_component *scomp, int index,
  1345. struct snd_sof_widget *swidget,
  1346. struct snd_soc_tplg_dapm_widget *tw,
  1347. struct sof_ipc_comp_reply *r)
  1348. {
  1349. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1350. struct snd_soc_tplg_private *private = &tw->priv;
  1351. struct sof_ipc_buffer *buffer;
  1352. int ret;
  1353. buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
  1354. if (!buffer)
  1355. return -ENOMEM;
  1356. /* configure dai IPC message */
  1357. buffer->comp.hdr.size = sizeof(*buffer);
  1358. buffer->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_BUFFER_NEW;
  1359. buffer->comp.id = swidget->comp_id;
  1360. buffer->comp.type = SOF_COMP_BUFFER;
  1361. buffer->comp.pipeline_id = index;
  1362. buffer->comp.core = swidget->core;
  1363. ret = sof_parse_tokens(scomp, buffer, buffer_tokens,
  1364. ARRAY_SIZE(buffer_tokens), private->array,
  1365. le32_to_cpu(private->size));
  1366. if (ret != 0) {
  1367. dev_err(scomp->dev, "error: parse buffer tokens failed %d\n",
  1368. private->size);
  1369. kfree(buffer);
  1370. return ret;
  1371. }
  1372. dev_dbg(scomp->dev, "buffer %s: size %d caps 0x%x\n",
  1373. swidget->widget->name, buffer->size, buffer->caps);
  1374. swidget->private = buffer;
  1375. ret = sof_ipc_tx_message(sdev->ipc, buffer->comp.hdr.cmd, buffer,
  1376. sizeof(*buffer), r, sizeof(*r));
  1377. if (ret < 0) {
  1378. dev_err(scomp->dev, "error: buffer %s load failed\n",
  1379. swidget->widget->name);
  1380. kfree(buffer);
  1381. }
  1382. return ret;
  1383. }
  1384. /* bind PCM ID to host component ID */
  1385. static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm,
  1386. int dir)
  1387. {
  1388. struct snd_sof_widget *host_widget;
  1389. host_widget = snd_sof_find_swidget_sname(scomp,
  1390. spcm->pcm.caps[dir].name,
  1391. dir);
  1392. if (!host_widget) {
  1393. dev_err(scomp->dev, "can't find host comp to bind pcm\n");
  1394. return -EINVAL;
  1395. }
  1396. spcm->stream[dir].comp_id = host_widget->comp_id;
  1397. return 0;
  1398. }
  1399. /*
  1400. * PCM Topology
  1401. */
  1402. static int sof_widget_load_pcm(struct snd_soc_component *scomp, int index,
  1403. struct snd_sof_widget *swidget,
  1404. enum sof_ipc_stream_direction dir,
  1405. struct snd_soc_tplg_dapm_widget *tw,
  1406. struct sof_ipc_comp_reply *r)
  1407. {
  1408. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1409. struct snd_soc_tplg_private *private = &tw->priv;
  1410. struct sof_ipc_comp_host *host;
  1411. size_t ipc_size = sizeof(*host);
  1412. int ret;
  1413. host = (struct sof_ipc_comp_host *)
  1414. sof_comp_alloc(swidget, &ipc_size, index);
  1415. if (!host)
  1416. return -ENOMEM;
  1417. /* configure host comp IPC message */
  1418. host->comp.type = SOF_COMP_HOST;
  1419. host->direction = dir;
  1420. host->config.hdr.size = sizeof(host->config);
  1421. ret = sof_parse_tokens(scomp, host, pcm_tokens,
  1422. ARRAY_SIZE(pcm_tokens), private->array,
  1423. le32_to_cpu(private->size));
  1424. if (ret != 0) {
  1425. dev_err(scomp->dev, "error: parse host tokens failed %d\n",
  1426. private->size);
  1427. goto err;
  1428. }
  1429. ret = sof_parse_tokens(scomp, &host->config, comp_tokens,
  1430. ARRAY_SIZE(comp_tokens), private->array,
  1431. le32_to_cpu(private->size));
  1432. if (ret != 0) {
  1433. dev_err(scomp->dev, "error: parse host.cfg tokens failed %d\n",
  1434. le32_to_cpu(private->size));
  1435. goto err;
  1436. }
  1437. dev_dbg(scomp->dev, "loaded host %s\n", swidget->widget->name);
  1438. sof_dbg_comp_config(scomp, &host->config);
  1439. swidget->private = host;
  1440. ret = sof_ipc_tx_message(sdev->ipc, host->comp.hdr.cmd, host,
  1441. ipc_size, r, sizeof(*r));
  1442. if (ret >= 0)
  1443. return ret;
  1444. err:
  1445. kfree(host);
  1446. return ret;
  1447. }
  1448. /*
  1449. * Pipeline Topology
  1450. */
  1451. int sof_load_pipeline_ipc(struct device *dev,
  1452. struct sof_ipc_pipe_new *pipeline,
  1453. struct sof_ipc_comp_reply *r)
  1454. {
  1455. struct snd_sof_dev *sdev = dev_get_drvdata(dev);
  1456. int ret = sof_core_enable(sdev, pipeline->core);
  1457. if (ret < 0)
  1458. return ret;
  1459. ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline,
  1460. sizeof(*pipeline), r, sizeof(*r));
  1461. if (ret < 0)
  1462. dev_err(dev, "error: load pipeline ipc failure\n");
  1463. return ret;
  1464. }
  1465. static int sof_widget_load_pipeline(struct snd_soc_component *scomp, int index,
  1466. struct snd_sof_widget *swidget,
  1467. struct snd_soc_tplg_dapm_widget *tw,
  1468. struct sof_ipc_comp_reply *r)
  1469. {
  1470. struct snd_soc_tplg_private *private = &tw->priv;
  1471. struct sof_ipc_pipe_new *pipeline;
  1472. struct snd_sof_widget *comp_swidget;
  1473. int ret;
  1474. pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
  1475. if (!pipeline)
  1476. return -ENOMEM;
  1477. /* configure dai IPC message */
  1478. pipeline->hdr.size = sizeof(*pipeline);
  1479. pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW;
  1480. pipeline->pipeline_id = index;
  1481. pipeline->comp_id = swidget->comp_id;
  1482. /* component at start of pipeline is our stream id */
  1483. comp_swidget = snd_sof_find_swidget(scomp, tw->sname);
  1484. if (!comp_swidget) {
  1485. dev_err(scomp->dev, "error: widget %s refers to non existent widget %s\n",
  1486. tw->name, tw->sname);
  1487. ret = -EINVAL;
  1488. goto err;
  1489. }
  1490. pipeline->sched_id = comp_swidget->comp_id;
  1491. dev_dbg(scomp->dev, "tplg: pipeline id %d comp %d scheduling comp id %d\n",
  1492. pipeline->pipeline_id, pipeline->comp_id, pipeline->sched_id);
  1493. ret = sof_parse_tokens(scomp, pipeline, sched_tokens,
  1494. ARRAY_SIZE(sched_tokens), private->array,
  1495. le32_to_cpu(private->size));
  1496. if (ret != 0) {
  1497. dev_err(scomp->dev, "error: parse pipeline tokens failed %d\n",
  1498. private->size);
  1499. goto err;
  1500. }
  1501. dev_dbg(scomp->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d\n",
  1502. swidget->widget->name, pipeline->period, pipeline->priority,
  1503. pipeline->period_mips, pipeline->core, pipeline->frames_per_sched);
  1504. swidget->private = pipeline;
  1505. /* send ipc's to create pipeline comp and power up schedule core */
  1506. ret = sof_load_pipeline_ipc(scomp->dev, pipeline, r);
  1507. if (ret >= 0)
  1508. return ret;
  1509. err:
  1510. kfree(pipeline);
  1511. return ret;
  1512. }
  1513. /*
  1514. * Mixer topology
  1515. */
  1516. static int sof_widget_load_mixer(struct snd_soc_component *scomp, int index,
  1517. struct snd_sof_widget *swidget,
  1518. struct snd_soc_tplg_dapm_widget *tw,
  1519. struct sof_ipc_comp_reply *r)
  1520. {
  1521. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1522. struct snd_soc_tplg_private *private = &tw->priv;
  1523. struct sof_ipc_comp_mixer *mixer;
  1524. size_t ipc_size = sizeof(*mixer);
  1525. int ret;
  1526. mixer = (struct sof_ipc_comp_mixer *)
  1527. sof_comp_alloc(swidget, &ipc_size, index);
  1528. if (!mixer)
  1529. return -ENOMEM;
  1530. /* configure mixer IPC message */
  1531. mixer->comp.type = SOF_COMP_MIXER;
  1532. mixer->config.hdr.size = sizeof(mixer->config);
  1533. ret = sof_parse_tokens(scomp, &mixer->config, comp_tokens,
  1534. ARRAY_SIZE(comp_tokens), private->array,
  1535. le32_to_cpu(private->size));
  1536. if (ret != 0) {
  1537. dev_err(scomp->dev, "error: parse mixer.cfg tokens failed %d\n",
  1538. private->size);
  1539. kfree(mixer);
  1540. return ret;
  1541. }
  1542. sof_dbg_comp_config(scomp, &mixer->config);
  1543. swidget->private = mixer;
  1544. ret = sof_ipc_tx_message(sdev->ipc, mixer->comp.hdr.cmd, mixer,
  1545. ipc_size, r, sizeof(*r));
  1546. if (ret < 0)
  1547. kfree(mixer);
  1548. return ret;
  1549. }
  1550. /*
  1551. * Mux topology
  1552. */
  1553. static int sof_widget_load_mux(struct snd_soc_component *scomp, int index,
  1554. struct snd_sof_widget *swidget,
  1555. struct snd_soc_tplg_dapm_widget *tw,
  1556. struct sof_ipc_comp_reply *r)
  1557. {
  1558. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1559. struct snd_soc_tplg_private *private = &tw->priv;
  1560. struct sof_ipc_comp_mux *mux;
  1561. size_t ipc_size = sizeof(*mux);
  1562. int ret;
  1563. mux = (struct sof_ipc_comp_mux *)
  1564. sof_comp_alloc(swidget, &ipc_size, index);
  1565. if (!mux)
  1566. return -ENOMEM;
  1567. /* configure mux IPC message */
  1568. mux->comp.type = SOF_COMP_MUX;
  1569. mux->config.hdr.size = sizeof(mux->config);
  1570. ret = sof_parse_tokens(scomp, &mux->config, comp_tokens,
  1571. ARRAY_SIZE(comp_tokens), private->array,
  1572. le32_to_cpu(private->size));
  1573. if (ret != 0) {
  1574. dev_err(scomp->dev, "error: parse mux.cfg tokens failed %d\n",
  1575. private->size);
  1576. kfree(mux);
  1577. return ret;
  1578. }
  1579. sof_dbg_comp_config(scomp, &mux->config);
  1580. swidget->private = mux;
  1581. ret = sof_ipc_tx_message(sdev->ipc, mux->comp.hdr.cmd, mux,
  1582. ipc_size, r, sizeof(*r));
  1583. if (ret < 0)
  1584. kfree(mux);
  1585. return ret;
  1586. }
  1587. /*
  1588. * PGA Topology
  1589. */
  1590. static int sof_widget_load_pga(struct snd_soc_component *scomp, int index,
  1591. struct snd_sof_widget *swidget,
  1592. struct snd_soc_tplg_dapm_widget *tw,
  1593. struct sof_ipc_comp_reply *r)
  1594. {
  1595. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1596. struct snd_soc_tplg_private *private = &tw->priv;
  1597. struct sof_ipc_comp_volume *volume;
  1598. struct snd_sof_control *scontrol;
  1599. size_t ipc_size = sizeof(*volume);
  1600. int min_step;
  1601. int max_step;
  1602. int ret;
  1603. volume = (struct sof_ipc_comp_volume *)
  1604. sof_comp_alloc(swidget, &ipc_size, index);
  1605. if (!volume)
  1606. return -ENOMEM;
  1607. if (!le32_to_cpu(tw->num_kcontrols)) {
  1608. dev_err(scomp->dev, "error: invalid kcontrol count %d for volume\n",
  1609. tw->num_kcontrols);
  1610. ret = -EINVAL;
  1611. goto err;
  1612. }
  1613. /* configure volume IPC message */
  1614. volume->comp.type = SOF_COMP_VOLUME;
  1615. volume->config.hdr.size = sizeof(volume->config);
  1616. ret = sof_parse_tokens(scomp, volume, volume_tokens,
  1617. ARRAY_SIZE(volume_tokens), private->array,
  1618. le32_to_cpu(private->size));
  1619. if (ret != 0) {
  1620. dev_err(scomp->dev, "error: parse volume tokens failed %d\n",
  1621. private->size);
  1622. goto err;
  1623. }
  1624. ret = sof_parse_tokens(scomp, &volume->config, comp_tokens,
  1625. ARRAY_SIZE(comp_tokens), private->array,
  1626. le32_to_cpu(private->size));
  1627. if (ret != 0) {
  1628. dev_err(scomp->dev, "error: parse volume.cfg tokens failed %d\n",
  1629. le32_to_cpu(private->size));
  1630. goto err;
  1631. }
  1632. sof_dbg_comp_config(scomp, &volume->config);
  1633. swidget->private = volume;
  1634. list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
  1635. if (scontrol->comp_id == swidget->comp_id &&
  1636. scontrol->volume_table) {
  1637. min_step = scontrol->min_volume_step;
  1638. max_step = scontrol->max_volume_step;
  1639. volume->min_value = scontrol->volume_table[min_step];
  1640. volume->max_value = scontrol->volume_table[max_step];
  1641. volume->channels = scontrol->num_channels;
  1642. break;
  1643. }
  1644. }
  1645. ret = sof_ipc_tx_message(sdev->ipc, volume->comp.hdr.cmd, volume,
  1646. ipc_size, r, sizeof(*r));
  1647. if (ret >= 0)
  1648. return ret;
  1649. err:
  1650. kfree(volume);
  1651. return ret;
  1652. }
  1653. /*
  1654. * SRC Topology
  1655. */
  1656. static int sof_widget_load_src(struct snd_soc_component *scomp, int index,
  1657. struct snd_sof_widget *swidget,
  1658. struct snd_soc_tplg_dapm_widget *tw,
  1659. struct sof_ipc_comp_reply *r)
  1660. {
  1661. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1662. struct snd_soc_tplg_private *private = &tw->priv;
  1663. struct sof_ipc_comp_src *src;
  1664. size_t ipc_size = sizeof(*src);
  1665. int ret;
  1666. src = (struct sof_ipc_comp_src *)
  1667. sof_comp_alloc(swidget, &ipc_size, index);
  1668. if (!src)
  1669. return -ENOMEM;
  1670. /* configure src IPC message */
  1671. src->comp.type = SOF_COMP_SRC;
  1672. src->config.hdr.size = sizeof(src->config);
  1673. ret = sof_parse_tokens(scomp, src, src_tokens,
  1674. ARRAY_SIZE(src_tokens), private->array,
  1675. le32_to_cpu(private->size));
  1676. if (ret != 0) {
  1677. dev_err(scomp->dev, "error: parse src tokens failed %d\n",
  1678. private->size);
  1679. goto err;
  1680. }
  1681. ret = sof_parse_tokens(scomp, &src->config, comp_tokens,
  1682. ARRAY_SIZE(comp_tokens), private->array,
  1683. le32_to_cpu(private->size));
  1684. if (ret != 0) {
  1685. dev_err(scomp->dev, "error: parse src.cfg tokens failed %d\n",
  1686. le32_to_cpu(private->size));
  1687. goto err;
  1688. }
  1689. dev_dbg(scomp->dev, "src %s: source rate %d sink rate %d\n",
  1690. swidget->widget->name, src->source_rate, src->sink_rate);
  1691. sof_dbg_comp_config(scomp, &src->config);
  1692. swidget->private = src;
  1693. ret = sof_ipc_tx_message(sdev->ipc, src->comp.hdr.cmd, src,
  1694. ipc_size, r, sizeof(*r));
  1695. if (ret >= 0)
  1696. return ret;
  1697. err:
  1698. kfree(src);
  1699. return ret;
  1700. }
  1701. /*
  1702. * ASRC Topology
  1703. */
  1704. static int sof_widget_load_asrc(struct snd_soc_component *scomp, int index,
  1705. struct snd_sof_widget *swidget,
  1706. struct snd_soc_tplg_dapm_widget *tw,
  1707. struct sof_ipc_comp_reply *r)
  1708. {
  1709. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1710. struct snd_soc_tplg_private *private = &tw->priv;
  1711. struct sof_ipc_comp_asrc *asrc;
  1712. size_t ipc_size = sizeof(*asrc);
  1713. int ret;
  1714. asrc = (struct sof_ipc_comp_asrc *)
  1715. sof_comp_alloc(swidget, &ipc_size, index);
  1716. if (!asrc)
  1717. return -ENOMEM;
  1718. /* configure ASRC IPC message */
  1719. asrc->comp.type = SOF_COMP_ASRC;
  1720. asrc->config.hdr.size = sizeof(asrc->config);
  1721. ret = sof_parse_tokens(scomp, asrc, asrc_tokens,
  1722. ARRAY_SIZE(asrc_tokens), private->array,
  1723. le32_to_cpu(private->size));
  1724. if (ret != 0) {
  1725. dev_err(scomp->dev, "error: parse asrc tokens failed %d\n",
  1726. private->size);
  1727. goto err;
  1728. }
  1729. ret = sof_parse_tokens(scomp, &asrc->config, comp_tokens,
  1730. ARRAY_SIZE(comp_tokens), private->array,
  1731. le32_to_cpu(private->size));
  1732. if (ret != 0) {
  1733. dev_err(scomp->dev, "error: parse asrc.cfg tokens failed %d\n",
  1734. le32_to_cpu(private->size));
  1735. goto err;
  1736. }
  1737. dev_dbg(scomp->dev, "asrc %s: source rate %d sink rate %d "
  1738. "asynch %d operation %d\n",
  1739. swidget->widget->name, asrc->source_rate, asrc->sink_rate,
  1740. asrc->asynchronous_mode, asrc->operation_mode);
  1741. sof_dbg_comp_config(scomp, &asrc->config);
  1742. swidget->private = asrc;
  1743. ret = sof_ipc_tx_message(sdev->ipc, asrc->comp.hdr.cmd, asrc,
  1744. ipc_size, r, sizeof(*r));
  1745. if (ret >= 0)
  1746. return ret;
  1747. err:
  1748. kfree(asrc);
  1749. return ret;
  1750. }
  1751. /*
  1752. * Signal Generator Topology
  1753. */
  1754. static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index,
  1755. struct snd_sof_widget *swidget,
  1756. struct snd_soc_tplg_dapm_widget *tw,
  1757. struct sof_ipc_comp_reply *r)
  1758. {
  1759. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1760. struct snd_soc_tplg_private *private = &tw->priv;
  1761. struct sof_ipc_comp_tone *tone;
  1762. size_t ipc_size = sizeof(*tone);
  1763. int ret;
  1764. tone = (struct sof_ipc_comp_tone *)
  1765. sof_comp_alloc(swidget, &ipc_size, index);
  1766. if (!tone)
  1767. return -ENOMEM;
  1768. /* configure siggen IPC message */
  1769. tone->comp.type = SOF_COMP_TONE;
  1770. tone->config.hdr.size = sizeof(tone->config);
  1771. ret = sof_parse_tokens(scomp, tone, tone_tokens,
  1772. ARRAY_SIZE(tone_tokens), private->array,
  1773. le32_to_cpu(private->size));
  1774. if (ret != 0) {
  1775. dev_err(scomp->dev, "error: parse tone tokens failed %d\n",
  1776. le32_to_cpu(private->size));
  1777. goto err;
  1778. }
  1779. ret = sof_parse_tokens(scomp, &tone->config, comp_tokens,
  1780. ARRAY_SIZE(comp_tokens), private->array,
  1781. le32_to_cpu(private->size));
  1782. if (ret != 0) {
  1783. dev_err(scomp->dev, "error: parse tone.cfg tokens failed %d\n",
  1784. le32_to_cpu(private->size));
  1785. goto err;
  1786. }
  1787. dev_dbg(scomp->dev, "tone %s: frequency %d amplitude %d\n",
  1788. swidget->widget->name, tone->frequency, tone->amplitude);
  1789. sof_dbg_comp_config(scomp, &tone->config);
  1790. swidget->private = tone;
  1791. ret = sof_ipc_tx_message(sdev->ipc, tone->comp.hdr.cmd, tone,
  1792. ipc_size, r, sizeof(*r));
  1793. if (ret >= 0)
  1794. return ret;
  1795. err:
  1796. kfree(tone);
  1797. return ret;
  1798. }
  1799. static int sof_get_control_data(struct snd_soc_component *scomp,
  1800. struct snd_soc_dapm_widget *widget,
  1801. struct sof_widget_data *wdata,
  1802. size_t *size)
  1803. {
  1804. const struct snd_kcontrol_new *kc;
  1805. struct soc_mixer_control *sm;
  1806. struct soc_bytes_ext *sbe;
  1807. struct soc_enum *se;
  1808. int i;
  1809. *size = 0;
  1810. for (i = 0; i < widget->num_kcontrols; i++) {
  1811. kc = &widget->kcontrol_news[i];
  1812. switch (widget->dobj.widget.kcontrol_type) {
  1813. case SND_SOC_TPLG_TYPE_MIXER:
  1814. sm = (struct soc_mixer_control *)kc->private_value;
  1815. wdata[i].control = sm->dobj.private;
  1816. break;
  1817. case SND_SOC_TPLG_TYPE_BYTES:
  1818. sbe = (struct soc_bytes_ext *)kc->private_value;
  1819. wdata[i].control = sbe->dobj.private;
  1820. break;
  1821. case SND_SOC_TPLG_TYPE_ENUM:
  1822. se = (struct soc_enum *)kc->private_value;
  1823. wdata[i].control = se->dobj.private;
  1824. break;
  1825. default:
  1826. dev_err(scomp->dev, "error: unknown kcontrol type %d in widget %s\n",
  1827. widget->dobj.widget.kcontrol_type,
  1828. widget->name);
  1829. return -EINVAL;
  1830. }
  1831. if (!wdata[i].control) {
  1832. dev_err(scomp->dev, "error: no scontrol for widget %s\n",
  1833. widget->name);
  1834. return -EINVAL;
  1835. }
  1836. wdata[i].pdata = wdata[i].control->control_data->data;
  1837. if (!wdata[i].pdata)
  1838. return -EINVAL;
  1839. /* make sure data is valid - data can be updated at runtime */
  1840. if (wdata[i].pdata->magic != SOF_ABI_MAGIC)
  1841. return -EINVAL;
  1842. *size += wdata[i].pdata->size;
  1843. /* get data type */
  1844. switch (wdata[i].control->cmd) {
  1845. case SOF_CTRL_CMD_VOLUME:
  1846. case SOF_CTRL_CMD_ENUM:
  1847. case SOF_CTRL_CMD_SWITCH:
  1848. wdata[i].ipc_cmd = SOF_IPC_COMP_SET_VALUE;
  1849. wdata[i].ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_SET;
  1850. break;
  1851. case SOF_CTRL_CMD_BINARY:
  1852. wdata[i].ipc_cmd = SOF_IPC_COMP_SET_DATA;
  1853. wdata[i].ctrl_type = SOF_CTRL_TYPE_DATA_SET;
  1854. break;
  1855. default:
  1856. break;
  1857. }
  1858. }
  1859. return 0;
  1860. }
  1861. static int sof_process_load(struct snd_soc_component *scomp, int index,
  1862. struct snd_sof_widget *swidget,
  1863. struct snd_soc_tplg_dapm_widget *tw,
  1864. struct sof_ipc_comp_reply *r,
  1865. int type)
  1866. {
  1867. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1868. struct snd_soc_dapm_widget *widget = swidget->widget;
  1869. struct snd_soc_tplg_private *private = &tw->priv;
  1870. struct sof_ipc_comp_process *process;
  1871. struct sof_widget_data *wdata = NULL;
  1872. size_t ipc_data_size = 0;
  1873. size_t ipc_size;
  1874. int offset = 0;
  1875. int ret;
  1876. int i;
  1877. /* allocate struct for widget control data sizes and types */
  1878. if (widget->num_kcontrols) {
  1879. wdata = kcalloc(widget->num_kcontrols,
  1880. sizeof(*wdata),
  1881. GFP_KERNEL);
  1882. if (!wdata)
  1883. return -ENOMEM;
  1884. /* get possible component controls and get size of all pdata */
  1885. ret = sof_get_control_data(scomp, widget, wdata,
  1886. &ipc_data_size);
  1887. if (ret < 0)
  1888. goto out;
  1889. }
  1890. ipc_size = sizeof(struct sof_ipc_comp_process) + ipc_data_size;
  1891. /* we are exceeding max ipc size, config needs to be sent separately */
  1892. if (ipc_size > SOF_IPC_MSG_MAX_SIZE) {
  1893. ipc_size -= ipc_data_size;
  1894. ipc_data_size = 0;
  1895. }
  1896. process = (struct sof_ipc_comp_process *)
  1897. sof_comp_alloc(swidget, &ipc_size, index);
  1898. if (!process) {
  1899. ret = -ENOMEM;
  1900. goto out;
  1901. }
  1902. /* configure iir IPC message */
  1903. process->comp.type = type;
  1904. process->config.hdr.size = sizeof(process->config);
  1905. ret = sof_parse_tokens(scomp, &process->config, comp_tokens,
  1906. ARRAY_SIZE(comp_tokens), private->array,
  1907. le32_to_cpu(private->size));
  1908. if (ret != 0) {
  1909. dev_err(scomp->dev, "error: parse process.cfg tokens failed %d\n",
  1910. le32_to_cpu(private->size));
  1911. goto err;
  1912. }
  1913. sof_dbg_comp_config(scomp, &process->config);
  1914. /*
  1915. * found private data in control, so copy it.
  1916. * get possible component controls - get size of all pdata,
  1917. * then memcpy with headers
  1918. */
  1919. if (ipc_data_size) {
  1920. for (i = 0; i < widget->num_kcontrols; i++) {
  1921. memcpy(&process->data + offset,
  1922. wdata[i].pdata->data,
  1923. wdata[i].pdata->size);
  1924. offset += wdata[i].pdata->size;
  1925. }
  1926. }
  1927. process->size = ipc_data_size;
  1928. swidget->private = process;
  1929. ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process,
  1930. ipc_size, r, sizeof(*r));
  1931. if (ret < 0) {
  1932. dev_err(scomp->dev, "error: create process failed\n");
  1933. goto err;
  1934. }
  1935. /* we sent the data in single message so return */
  1936. if (ipc_data_size)
  1937. goto out;
  1938. /* send control data with large message supported method */
  1939. for (i = 0; i < widget->num_kcontrols; i++) {
  1940. wdata[i].control->readback_offset = 0;
  1941. ret = snd_sof_ipc_set_get_comp_data(wdata[i].control,
  1942. wdata[i].ipc_cmd,
  1943. wdata[i].ctrl_type,
  1944. wdata[i].control->cmd,
  1945. true);
  1946. if (ret != 0) {
  1947. dev_err(scomp->dev, "error: send control failed\n");
  1948. break;
  1949. }
  1950. }
  1951. err:
  1952. if (ret < 0)
  1953. kfree(process);
  1954. out:
  1955. kfree(wdata);
  1956. return ret;
  1957. }
  1958. /*
  1959. * Processing Component Topology - can be "effect", "codec", or general
  1960. * "processing".
  1961. */
  1962. static int sof_widget_load_process(struct snd_soc_component *scomp, int index,
  1963. struct snd_sof_widget *swidget,
  1964. struct snd_soc_tplg_dapm_widget *tw,
  1965. struct sof_ipc_comp_reply *r)
  1966. {
  1967. struct snd_soc_tplg_private *private = &tw->priv;
  1968. struct sof_ipc_comp_process config;
  1969. int ret;
  1970. /* check we have some tokens - we need at least process type */
  1971. if (le32_to_cpu(private->size) == 0) {
  1972. dev_err(scomp->dev, "error: process tokens not found\n");
  1973. return -EINVAL;
  1974. }
  1975. memset(&config, 0, sizeof(config));
  1976. config.comp.core = swidget->core;
  1977. /* get the process token */
  1978. ret = sof_parse_tokens(scomp, &config, process_tokens,
  1979. ARRAY_SIZE(process_tokens), private->array,
  1980. le32_to_cpu(private->size));
  1981. if (ret != 0) {
  1982. dev_err(scomp->dev, "error: parse process tokens failed %d\n",
  1983. le32_to_cpu(private->size));
  1984. return ret;
  1985. }
  1986. /* now load process specific data and send IPC */
  1987. ret = sof_process_load(scomp, index, swidget, tw, r,
  1988. find_process_comp_type(config.type));
  1989. if (ret < 0) {
  1990. dev_err(scomp->dev, "error: process loading failed\n");
  1991. return ret;
  1992. }
  1993. return 0;
  1994. }
  1995. static int sof_widget_bind_event(struct snd_soc_component *scomp,
  1996. struct snd_sof_widget *swidget,
  1997. u16 event_type)
  1998. {
  1999. struct sof_ipc_comp *ipc_comp;
  2000. /* validate widget event type */
  2001. switch (event_type) {
  2002. case SOF_KEYWORD_DETECT_DAPM_EVENT:
  2003. /* only KEYWORD_DETECT comps should handle this */
  2004. if (swidget->id != snd_soc_dapm_effect)
  2005. break;
  2006. ipc_comp = swidget->private;
  2007. if (ipc_comp && ipc_comp->type != SOF_COMP_KEYWORD_DETECT)
  2008. break;
  2009. /* bind event to keyword detect comp */
  2010. return snd_soc_tplg_widget_bind_event(swidget->widget,
  2011. sof_kwd_events,
  2012. ARRAY_SIZE(sof_kwd_events),
  2013. event_type);
  2014. default:
  2015. break;
  2016. }
  2017. dev_err(scomp->dev,
  2018. "error: invalid event type %d for widget %s\n",
  2019. event_type, swidget->widget->name);
  2020. return -EINVAL;
  2021. }
  2022. /* external widget init - used for any driver specific init */
  2023. static int sof_widget_ready(struct snd_soc_component *scomp, int index,
  2024. struct snd_soc_dapm_widget *w,
  2025. struct snd_soc_tplg_dapm_widget *tw)
  2026. {
  2027. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2028. struct snd_sof_widget *swidget;
  2029. struct snd_sof_dai *dai;
  2030. struct sof_ipc_comp_reply reply;
  2031. struct snd_sof_control *scontrol;
  2032. struct sof_ipc_comp comp = {
  2033. .core = SOF_DSP_PRIMARY_CORE,
  2034. };
  2035. int ret = 0;
  2036. swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
  2037. if (!swidget)
  2038. return -ENOMEM;
  2039. swidget->scomp = scomp;
  2040. swidget->widget = w;
  2041. swidget->comp_id = sdev->next_comp_id++;
  2042. swidget->complete = 0;
  2043. swidget->id = w->id;
  2044. swidget->pipeline_id = index;
  2045. swidget->private = NULL;
  2046. memset(&reply, 0, sizeof(reply));
  2047. dev_dbg(scomp->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n",
  2048. swidget->comp_id, index, swidget->id, tw->name,
  2049. strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
  2050. ? tw->sname : "none");
  2051. ret = sof_parse_tokens(scomp, &comp, core_tokens,
  2052. ARRAY_SIZE(core_tokens), tw->priv.array,
  2053. le32_to_cpu(tw->priv.size));
  2054. if (ret != 0) {
  2055. dev_err(scomp->dev, "error: parsing core tokens failed %d\n",
  2056. ret);
  2057. kfree(swidget);
  2058. return ret;
  2059. }
  2060. swidget->core = comp.core;
  2061. /* default is primary core, safe to call for already enabled cores */
  2062. ret = sof_core_enable(sdev, comp.core);
  2063. if (ret < 0) {
  2064. dev_err(scomp->dev, "error: enable core: %d\n", ret);
  2065. kfree(swidget);
  2066. return ret;
  2067. }
  2068. ret = sof_parse_tokens(scomp, &swidget->comp_ext, comp_ext_tokens,
  2069. ARRAY_SIZE(comp_ext_tokens), tw->priv.array,
  2070. le32_to_cpu(tw->priv.size));
  2071. if (ret != 0) {
  2072. dev_err(scomp->dev, "error: parsing comp_ext_tokens failed %d\n",
  2073. ret);
  2074. kfree(swidget);
  2075. return ret;
  2076. }
  2077. /* handle any special case widgets */
  2078. switch (w->id) {
  2079. case snd_soc_dapm_dai_in:
  2080. case snd_soc_dapm_dai_out:
  2081. dai = kzalloc(sizeof(*dai), GFP_KERNEL);
  2082. if (!dai) {
  2083. kfree(swidget);
  2084. return -ENOMEM;
  2085. }
  2086. ret = sof_widget_load_dai(scomp, index, swidget, tw, &reply, dai);
  2087. if (ret == 0) {
  2088. sof_connect_dai_widget(scomp, w, tw, dai);
  2089. list_add(&dai->list, &sdev->dai_list);
  2090. swidget->private = dai;
  2091. } else {
  2092. kfree(dai);
  2093. }
  2094. break;
  2095. case snd_soc_dapm_mixer:
  2096. ret = sof_widget_load_mixer(scomp, index, swidget, tw, &reply);
  2097. break;
  2098. case snd_soc_dapm_pga:
  2099. ret = sof_widget_load_pga(scomp, index, swidget, tw, &reply);
  2100. /* Find scontrol for this pga and set readback offset*/
  2101. list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
  2102. if (scontrol->comp_id == swidget->comp_id) {
  2103. scontrol->readback_offset = reply.offset;
  2104. break;
  2105. }
  2106. }
  2107. break;
  2108. case snd_soc_dapm_buffer:
  2109. ret = sof_widget_load_buffer(scomp, index, swidget, tw, &reply);
  2110. break;
  2111. case snd_soc_dapm_scheduler:
  2112. ret = sof_widget_load_pipeline(scomp, index, swidget, tw, &reply);
  2113. break;
  2114. case snd_soc_dapm_aif_out:
  2115. ret = sof_widget_load_pcm(scomp, index, swidget,
  2116. SOF_IPC_STREAM_CAPTURE, tw, &reply);
  2117. break;
  2118. case snd_soc_dapm_aif_in:
  2119. ret = sof_widget_load_pcm(scomp, index, swidget,
  2120. SOF_IPC_STREAM_PLAYBACK, tw, &reply);
  2121. break;
  2122. case snd_soc_dapm_src:
  2123. ret = sof_widget_load_src(scomp, index, swidget, tw, &reply);
  2124. break;
  2125. case snd_soc_dapm_asrc:
  2126. ret = sof_widget_load_asrc(scomp, index, swidget, tw, &reply);
  2127. break;
  2128. case snd_soc_dapm_siggen:
  2129. ret = sof_widget_load_siggen(scomp, index, swidget, tw, &reply);
  2130. break;
  2131. case snd_soc_dapm_effect:
  2132. ret = sof_widget_load_process(scomp, index, swidget, tw, &reply);
  2133. break;
  2134. case snd_soc_dapm_mux:
  2135. case snd_soc_dapm_demux:
  2136. ret = sof_widget_load_mux(scomp, index, swidget, tw, &reply);
  2137. break;
  2138. case snd_soc_dapm_switch:
  2139. case snd_soc_dapm_dai_link:
  2140. case snd_soc_dapm_kcontrol:
  2141. default:
  2142. dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name);
  2143. break;
  2144. }
  2145. /* check IPC reply */
  2146. if (ret < 0 || reply.rhdr.error < 0) {
  2147. dev_err(scomp->dev,
  2148. "error: DSP failed to add widget id %d type %d name : %s stream %s reply %d\n",
  2149. tw->shift, swidget->id, tw->name,
  2150. strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
  2151. ? tw->sname : "none", reply.rhdr.error);
  2152. kfree(swidget);
  2153. return ret;
  2154. }
  2155. /* bind widget to external event */
  2156. if (tw->event_type) {
  2157. ret = sof_widget_bind_event(scomp, swidget,
  2158. le16_to_cpu(tw->event_type));
  2159. if (ret) {
  2160. dev_err(scomp->dev, "error: widget event binding failed\n");
  2161. kfree(swidget->private);
  2162. kfree(swidget);
  2163. return ret;
  2164. }
  2165. }
  2166. w->dobj.private = swidget;
  2167. list_add(&swidget->list, &sdev->widget_list);
  2168. return ret;
  2169. }
  2170. static int sof_route_unload(struct snd_soc_component *scomp,
  2171. struct snd_soc_dobj *dobj)
  2172. {
  2173. struct snd_sof_route *sroute;
  2174. sroute = dobj->private;
  2175. if (!sroute)
  2176. return 0;
  2177. /* free sroute and its private data */
  2178. kfree(sroute->private);
  2179. list_del(&sroute->list);
  2180. kfree(sroute);
  2181. return 0;
  2182. }
  2183. static int sof_widget_unload(struct snd_soc_component *scomp,
  2184. struct snd_soc_dobj *dobj)
  2185. {
  2186. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2187. const struct snd_kcontrol_new *kc;
  2188. struct snd_soc_dapm_widget *widget;
  2189. struct sof_ipc_pipe_new *pipeline;
  2190. struct snd_sof_control *scontrol;
  2191. struct snd_sof_widget *swidget;
  2192. struct soc_mixer_control *sm;
  2193. struct soc_bytes_ext *sbe;
  2194. struct snd_sof_dai *dai;
  2195. struct soc_enum *se;
  2196. int ret = 0;
  2197. int i;
  2198. swidget = dobj->private;
  2199. if (!swidget)
  2200. return 0;
  2201. widget = swidget->widget;
  2202. switch (swidget->id) {
  2203. case snd_soc_dapm_dai_in:
  2204. case snd_soc_dapm_dai_out:
  2205. dai = swidget->private;
  2206. if (dai) {
  2207. /* free dai config */
  2208. kfree(dai->dai_config);
  2209. list_del(&dai->list);
  2210. }
  2211. break;
  2212. case snd_soc_dapm_scheduler:
  2213. /* power down the pipeline schedule core */
  2214. pipeline = swidget->private;
  2215. /*
  2216. * Runtime PM should still function normally if topology loading fails and
  2217. * it's components are unloaded. Do not power down the primary core so that the
  2218. * CTX_SAVE IPC can succeed during runtime suspend.
  2219. */
  2220. if (pipeline->core == SOF_DSP_PRIMARY_CORE)
  2221. break;
  2222. ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core);
  2223. if (ret < 0)
  2224. dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n",
  2225. pipeline->core);
  2226. /* update enabled cores mask */
  2227. sdev->enabled_cores_mask &= ~(1 << pipeline->core);
  2228. break;
  2229. default:
  2230. break;
  2231. }
  2232. for (i = 0; i < widget->num_kcontrols; i++) {
  2233. kc = &widget->kcontrol_news[i];
  2234. switch (dobj->widget.kcontrol_type) {
  2235. case SND_SOC_TPLG_TYPE_MIXER:
  2236. sm = (struct soc_mixer_control *)kc->private_value;
  2237. scontrol = sm->dobj.private;
  2238. if (sm->max > 1)
  2239. kfree(scontrol->volume_table);
  2240. break;
  2241. case SND_SOC_TPLG_TYPE_ENUM:
  2242. se = (struct soc_enum *)kc->private_value;
  2243. scontrol = se->dobj.private;
  2244. break;
  2245. case SND_SOC_TPLG_TYPE_BYTES:
  2246. sbe = (struct soc_bytes_ext *)kc->private_value;
  2247. scontrol = sbe->dobj.private;
  2248. break;
  2249. default:
  2250. dev_warn(scomp->dev, "unsupported kcontrol_type\n");
  2251. goto out;
  2252. }
  2253. kfree(scontrol->control_data);
  2254. list_del(&scontrol->list);
  2255. kfree(scontrol);
  2256. }
  2257. out:
  2258. /* free private value */
  2259. kfree(swidget->private);
  2260. /* remove and free swidget object */
  2261. list_del(&swidget->list);
  2262. kfree(swidget);
  2263. return ret;
  2264. }
  2265. /*
  2266. * DAI HW configuration.
  2267. */
  2268. /* FE DAI - used for any driver specific init */
  2269. static int sof_dai_load(struct snd_soc_component *scomp, int index,
  2270. struct snd_soc_dai_driver *dai_drv,
  2271. struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
  2272. {
  2273. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2274. struct snd_soc_tplg_stream_caps *caps;
  2275. struct snd_soc_tplg_private *private = &pcm->priv;
  2276. struct snd_sof_pcm *spcm;
  2277. int stream;
  2278. int ret;
  2279. /* nothing to do for BEs atm */
  2280. if (!pcm)
  2281. return 0;
  2282. spcm = kzalloc(sizeof(*spcm), GFP_KERNEL);
  2283. if (!spcm)
  2284. return -ENOMEM;
  2285. spcm->scomp = scomp;
  2286. for_each_pcm_streams(stream) {
  2287. spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED;
  2288. INIT_WORK(&spcm->stream[stream].period_elapsed_work,
  2289. snd_sof_pcm_period_elapsed_work);
  2290. }
  2291. spcm->pcm = *pcm;
  2292. dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
  2293. dai_drv->dobj.private = spcm;
  2294. list_add(&spcm->list, &sdev->pcm_list);
  2295. ret = sof_parse_tokens(scomp, spcm, stream_tokens,
  2296. ARRAY_SIZE(stream_tokens), private->array,
  2297. le32_to_cpu(private->size));
  2298. if (ret) {
  2299. dev_err(scomp->dev, "error: parse stream tokens failed %d\n",
  2300. le32_to_cpu(private->size));
  2301. return ret;
  2302. }
  2303. /* do we need to allocate playback PCM DMA pages */
  2304. if (!spcm->pcm.playback)
  2305. goto capture;
  2306. stream = SNDRV_PCM_STREAM_PLAYBACK;
  2307. dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n",
  2308. spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
  2309. caps = &spcm->pcm.caps[stream];
  2310. /* allocate playback page table buffer */
  2311. ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
  2312. PAGE_SIZE, &spcm->stream[stream].page_table);
  2313. if (ret < 0) {
  2314. dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
  2315. caps->name, ret);
  2316. return ret;
  2317. }
  2318. /* bind pcm to host comp */
  2319. ret = spcm_bind(scomp, spcm, stream);
  2320. if (ret) {
  2321. dev_err(scomp->dev,
  2322. "error: can't bind pcm to host\n");
  2323. goto free_playback_tables;
  2324. }
  2325. capture:
  2326. stream = SNDRV_PCM_STREAM_CAPTURE;
  2327. /* do we need to allocate capture PCM DMA pages */
  2328. if (!spcm->pcm.capture)
  2329. return ret;
  2330. dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n",
  2331. spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
  2332. caps = &spcm->pcm.caps[stream];
  2333. /* allocate capture page table buffer */
  2334. ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
  2335. PAGE_SIZE, &spcm->stream[stream].page_table);
  2336. if (ret < 0) {
  2337. dev_err(scomp->dev, "error: can't alloc page table for %s %d\n",
  2338. caps->name, ret);
  2339. goto free_playback_tables;
  2340. }
  2341. /* bind pcm to host comp */
  2342. ret = spcm_bind(scomp, spcm, stream);
  2343. if (ret) {
  2344. dev_err(scomp->dev,
  2345. "error: can't bind pcm to host\n");
  2346. snd_dma_free_pages(&spcm->stream[stream].page_table);
  2347. goto free_playback_tables;
  2348. }
  2349. return ret;
  2350. free_playback_tables:
  2351. if (spcm->pcm.playback)
  2352. snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
  2353. return ret;
  2354. }
  2355. static int sof_dai_unload(struct snd_soc_component *scomp,
  2356. struct snd_soc_dobj *dobj)
  2357. {
  2358. struct snd_sof_pcm *spcm = dobj->private;
  2359. /* free PCM DMA pages */
  2360. if (spcm->pcm.playback)
  2361. snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table);
  2362. if (spcm->pcm.capture)
  2363. snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table);
  2364. /* remove from list and free spcm */
  2365. list_del(&spcm->list);
  2366. kfree(spcm);
  2367. return 0;
  2368. }
  2369. static void sof_dai_set_format(struct snd_soc_tplg_hw_config *hw_config,
  2370. struct sof_ipc_dai_config *config)
  2371. {
  2372. /* clock directions wrt codec */
  2373. if (hw_config->bclk_master == SND_SOC_TPLG_BCLK_CM) {
  2374. /* codec is bclk master */
  2375. if (hw_config->fsync_master == SND_SOC_TPLG_FSYNC_CM)
  2376. config->format |= SOF_DAI_FMT_CBM_CFM;
  2377. else
  2378. config->format |= SOF_DAI_FMT_CBM_CFS;
  2379. } else {
  2380. /* codec is bclk slave */
  2381. if (hw_config->fsync_master == SND_SOC_TPLG_FSYNC_CM)
  2382. config->format |= SOF_DAI_FMT_CBS_CFM;
  2383. else
  2384. config->format |= SOF_DAI_FMT_CBS_CFS;
  2385. }
  2386. /* inverted clocks ? */
  2387. if (hw_config->invert_bclk) {
  2388. if (hw_config->invert_fsync)
  2389. config->format |= SOF_DAI_FMT_IB_IF;
  2390. else
  2391. config->format |= SOF_DAI_FMT_IB_NF;
  2392. } else {
  2393. if (hw_config->invert_fsync)
  2394. config->format |= SOF_DAI_FMT_NB_IF;
  2395. else
  2396. config->format |= SOF_DAI_FMT_NB_NF;
  2397. }
  2398. }
  2399. /*
  2400. * Send IPC and set the same config for all DAIs with name matching the link
  2401. * name. Note that the function can only be used for the case that all DAIs
  2402. * have a common DAI config for now.
  2403. */
  2404. static int sof_set_dai_config(struct snd_sof_dev *sdev, u32 size,
  2405. struct snd_soc_dai_link *link,
  2406. struct sof_ipc_dai_config *config)
  2407. {
  2408. struct snd_sof_dai *dai;
  2409. int found = 0;
  2410. list_for_each_entry(dai, &sdev->dai_list, list) {
  2411. if (!dai->name)
  2412. continue;
  2413. if (strcmp(link->name, dai->name) == 0) {
  2414. struct sof_ipc_reply reply;
  2415. int ret;
  2416. /*
  2417. * the same dai config will be applied to all DAIs in
  2418. * the same dai link. We have to ensure that the ipc
  2419. * dai config's dai_index match to the component's
  2420. * dai_index.
  2421. */
  2422. config->dai_index = dai->comp_dai.dai_index;
  2423. /* send message to DSP */
  2424. ret = sof_ipc_tx_message(sdev->ipc,
  2425. config->hdr.cmd, config, size,
  2426. &reply, sizeof(reply));
  2427. if (ret < 0) {
  2428. dev_err(sdev->dev, "error: failed to set DAI config for %s index %d\n",
  2429. dai->name, config->dai_index);
  2430. return ret;
  2431. }
  2432. dai->dai_config = kmemdup(config, size, GFP_KERNEL);
  2433. if (!dai->dai_config)
  2434. return -ENOMEM;
  2435. /* set cpu_dai_name */
  2436. dai->cpu_dai_name = link->cpus->dai_name;
  2437. found = 1;
  2438. }
  2439. }
  2440. /*
  2441. * machine driver may define a dai link with playback and capture
  2442. * dai enabled, but the dai link in topology would support both, one
  2443. * or none of them. Here print a warning message to notify user
  2444. */
  2445. if (!found) {
  2446. dev_warn(sdev->dev, "warning: failed to find dai for dai link %s",
  2447. link->name);
  2448. }
  2449. return 0;
  2450. }
  2451. static int sof_link_ssp_load(struct snd_soc_component *scomp, int index,
  2452. struct snd_soc_dai_link *link,
  2453. struct snd_soc_tplg_link_config *cfg,
  2454. struct snd_soc_tplg_hw_config *hw_config,
  2455. struct sof_ipc_dai_config *config)
  2456. {
  2457. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2458. struct snd_soc_tplg_private *private = &cfg->priv;
  2459. u32 size = sizeof(*config);
  2460. int ret;
  2461. /* handle master/slave and inverted clocks */
  2462. sof_dai_set_format(hw_config, config);
  2463. /* init IPC */
  2464. memset(&config->ssp, 0, sizeof(struct sof_ipc_dai_ssp_params));
  2465. config->hdr.size = size;
  2466. ret = sof_parse_tokens(scomp, &config->ssp, ssp_tokens,
  2467. ARRAY_SIZE(ssp_tokens), private->array,
  2468. le32_to_cpu(private->size));
  2469. if (ret != 0) {
  2470. dev_err(scomp->dev, "error: parse ssp tokens failed %d\n",
  2471. le32_to_cpu(private->size));
  2472. return ret;
  2473. }
  2474. config->ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate);
  2475. config->ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate);
  2476. config->ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
  2477. config->ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
  2478. config->ssp.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width);
  2479. config->ssp.mclk_direction = hw_config->mclk_direction;
  2480. config->ssp.rx_slots = le32_to_cpu(hw_config->rx_slots);
  2481. config->ssp.tx_slots = le32_to_cpu(hw_config->tx_slots);
  2482. dev_dbg(scomp->dev, "tplg: config SSP%d fmt 0x%x mclk %d bclk %d fclk %d width (%d)%d slots %d mclk id %d quirks %d\n",
  2483. config->dai_index, config->format,
  2484. config->ssp.mclk_rate, config->ssp.bclk_rate,
  2485. config->ssp.fsync_rate, config->ssp.sample_valid_bits,
  2486. config->ssp.tdm_slot_width, config->ssp.tdm_slots,
  2487. config->ssp.mclk_id, config->ssp.quirks);
  2488. /* validate SSP fsync rate and channel count */
  2489. if (config->ssp.fsync_rate < 8000 || config->ssp.fsync_rate > 192000) {
  2490. dev_err(scomp->dev, "error: invalid fsync rate for SSP%d\n",
  2491. config->dai_index);
  2492. return -EINVAL;
  2493. }
  2494. if (config->ssp.tdm_slots < 1 || config->ssp.tdm_slots > 8) {
  2495. dev_err(scomp->dev, "error: invalid channel count for SSP%d\n",
  2496. config->dai_index);
  2497. return -EINVAL;
  2498. }
  2499. /* set config for all DAI's with name matching the link name */
  2500. ret = sof_set_dai_config(sdev, size, link, config);
  2501. if (ret < 0)
  2502. dev_err(scomp->dev, "error: failed to save DAI config for SSP%d\n",
  2503. config->dai_index);
  2504. return ret;
  2505. }
  2506. static int sof_link_sai_load(struct snd_soc_component *scomp, int index,
  2507. struct snd_soc_dai_link *link,
  2508. struct snd_soc_tplg_link_config *cfg,
  2509. struct snd_soc_tplg_hw_config *hw_config,
  2510. struct sof_ipc_dai_config *config)
  2511. {
  2512. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2513. struct snd_soc_tplg_private *private = &cfg->priv;
  2514. u32 size = sizeof(*config);
  2515. int ret;
  2516. /* handle master/slave and inverted clocks */
  2517. sof_dai_set_format(hw_config, config);
  2518. /* init IPC */
  2519. memset(&config->sai, 0, sizeof(struct sof_ipc_dai_sai_params));
  2520. config->hdr.size = size;
  2521. ret = sof_parse_tokens(scomp, &config->sai, sai_tokens,
  2522. ARRAY_SIZE(sai_tokens), private->array,
  2523. le32_to_cpu(private->size));
  2524. if (ret != 0) {
  2525. dev_err(scomp->dev, "error: parse sai tokens failed %d\n",
  2526. le32_to_cpu(private->size));
  2527. return ret;
  2528. }
  2529. config->sai.mclk_rate = le32_to_cpu(hw_config->mclk_rate);
  2530. config->sai.bclk_rate = le32_to_cpu(hw_config->bclk_rate);
  2531. config->sai.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
  2532. config->sai.mclk_direction = hw_config->mclk_direction;
  2533. config->sai.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
  2534. config->sai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width);
  2535. config->sai.rx_slots = le32_to_cpu(hw_config->rx_slots);
  2536. config->sai.tx_slots = le32_to_cpu(hw_config->tx_slots);
  2537. dev_info(scomp->dev,
  2538. "tplg: config SAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n",
  2539. config->dai_index, config->format,
  2540. config->sai.mclk_rate, config->sai.tdm_slot_width,
  2541. config->sai.tdm_slots, config->sai.mclk_id);
  2542. if (config->sai.tdm_slots < 1 || config->sai.tdm_slots > 8) {
  2543. dev_err(scomp->dev, "error: invalid channel count for SAI%d\n",
  2544. config->dai_index);
  2545. return -EINVAL;
  2546. }
  2547. /* set config for all DAI's with name matching the link name */
  2548. ret = sof_set_dai_config(sdev, size, link, config);
  2549. if (ret < 0)
  2550. dev_err(scomp->dev, "error: failed to save DAI config for SAI%d\n",
  2551. config->dai_index);
  2552. return ret;
  2553. }
  2554. static int sof_link_esai_load(struct snd_soc_component *scomp, int index,
  2555. struct snd_soc_dai_link *link,
  2556. struct snd_soc_tplg_link_config *cfg,
  2557. struct snd_soc_tplg_hw_config *hw_config,
  2558. struct sof_ipc_dai_config *config)
  2559. {
  2560. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2561. struct snd_soc_tplg_private *private = &cfg->priv;
  2562. u32 size = sizeof(*config);
  2563. int ret;
  2564. /* handle master/slave and inverted clocks */
  2565. sof_dai_set_format(hw_config, config);
  2566. /* init IPC */
  2567. memset(&config->esai, 0, sizeof(struct sof_ipc_dai_esai_params));
  2568. config->hdr.size = size;
  2569. ret = sof_parse_tokens(scomp, &config->esai, esai_tokens,
  2570. ARRAY_SIZE(esai_tokens), private->array,
  2571. le32_to_cpu(private->size));
  2572. if (ret != 0) {
  2573. dev_err(scomp->dev, "error: parse esai tokens failed %d\n",
  2574. le32_to_cpu(private->size));
  2575. return ret;
  2576. }
  2577. config->esai.mclk_rate = le32_to_cpu(hw_config->mclk_rate);
  2578. config->esai.bclk_rate = le32_to_cpu(hw_config->bclk_rate);
  2579. config->esai.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
  2580. config->esai.mclk_direction = hw_config->mclk_direction;
  2581. config->esai.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
  2582. config->esai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width);
  2583. config->esai.rx_slots = le32_to_cpu(hw_config->rx_slots);
  2584. config->esai.tx_slots = le32_to_cpu(hw_config->tx_slots);
  2585. dev_info(scomp->dev,
  2586. "tplg: config ESAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n",
  2587. config->dai_index, config->format,
  2588. config->esai.mclk_rate, config->esai.tdm_slot_width,
  2589. config->esai.tdm_slots, config->esai.mclk_id);
  2590. if (config->esai.tdm_slots < 1 || config->esai.tdm_slots > 8) {
  2591. dev_err(scomp->dev, "error: invalid channel count for ESAI%d\n",
  2592. config->dai_index);
  2593. return -EINVAL;
  2594. }
  2595. /* set config for all DAI's with name matching the link name */
  2596. ret = sof_set_dai_config(sdev, size, link, config);
  2597. if (ret < 0)
  2598. dev_err(scomp->dev, "error: failed to save DAI config for ESAI%d\n",
  2599. config->dai_index);
  2600. return ret;
  2601. }
  2602. static int sof_link_dmic_load(struct snd_soc_component *scomp, int index,
  2603. struct snd_soc_dai_link *link,
  2604. struct snd_soc_tplg_link_config *cfg,
  2605. struct snd_soc_tplg_hw_config *hw_config,
  2606. struct sof_ipc_dai_config *config)
  2607. {
  2608. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2609. struct snd_soc_tplg_private *private = &cfg->priv;
  2610. struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
  2611. struct sof_ipc_fw_version *v = &ready->version;
  2612. size_t size = sizeof(*config);
  2613. int ret, j;
  2614. /* Ensure the entire DMIC config struct is zeros */
  2615. memset(&config->dmic, 0, sizeof(struct sof_ipc_dai_dmic_params));
  2616. /* get DMIC tokens */
  2617. ret = sof_parse_tokens(scomp, &config->dmic, dmic_tokens,
  2618. ARRAY_SIZE(dmic_tokens), private->array,
  2619. le32_to_cpu(private->size));
  2620. if (ret != 0) {
  2621. dev_err(scomp->dev, "error: parse dmic tokens failed %d\n",
  2622. le32_to_cpu(private->size));
  2623. return ret;
  2624. }
  2625. /* get DMIC PDM tokens */
  2626. ret = sof_parse_token_sets(scomp, &config->dmic.pdm[0], dmic_pdm_tokens,
  2627. ARRAY_SIZE(dmic_pdm_tokens), private->array,
  2628. le32_to_cpu(private->size),
  2629. config->dmic.num_pdm_active,
  2630. sizeof(struct sof_ipc_dai_dmic_pdm_ctrl));
  2631. if (ret != 0) {
  2632. dev_err(scomp->dev, "error: parse dmic pdm tokens failed %d\n",
  2633. le32_to_cpu(private->size));
  2634. return ret;
  2635. }
  2636. /* set IPC header size */
  2637. config->hdr.size = size;
  2638. /* debug messages */
  2639. dev_dbg(scomp->dev, "tplg: config DMIC%d driver version %d\n",
  2640. config->dai_index, config->dmic.driver_ipc_version);
  2641. dev_dbg(scomp->dev, "pdmclk_min %d pdm_clkmax %d duty_min %hd\n",
  2642. config->dmic.pdmclk_min, config->dmic.pdmclk_max,
  2643. config->dmic.duty_min);
  2644. dev_dbg(scomp->dev, "duty_max %hd fifo_fs %d num_pdms active %d\n",
  2645. config->dmic.duty_max, config->dmic.fifo_fs,
  2646. config->dmic.num_pdm_active);
  2647. dev_dbg(scomp->dev, "fifo word length %hd\n", config->dmic.fifo_bits);
  2648. for (j = 0; j < config->dmic.num_pdm_active; j++) {
  2649. dev_dbg(scomp->dev, "pdm %hd mic a %hd mic b %hd\n",
  2650. config->dmic.pdm[j].id,
  2651. config->dmic.pdm[j].enable_mic_a,
  2652. config->dmic.pdm[j].enable_mic_b);
  2653. dev_dbg(scomp->dev, "pdm %hd polarity a %hd polarity b %hd\n",
  2654. config->dmic.pdm[j].id,
  2655. config->dmic.pdm[j].polarity_mic_a,
  2656. config->dmic.pdm[j].polarity_mic_b);
  2657. dev_dbg(scomp->dev, "pdm %hd clk_edge %hd skew %hd\n",
  2658. config->dmic.pdm[j].id,
  2659. config->dmic.pdm[j].clk_edge,
  2660. config->dmic.pdm[j].skew);
  2661. }
  2662. /*
  2663. * this takes care of backwards compatible handling of fifo_bits_b.
  2664. * It is deprecated since firmware ABI version 3.0.1.
  2665. */
  2666. if (SOF_ABI_VER(v->major, v->minor, v->micro) < SOF_ABI_VER(3, 0, 1))
  2667. config->dmic.fifo_bits_b = config->dmic.fifo_bits;
  2668. /* set config for all DAI's with name matching the link name */
  2669. ret = sof_set_dai_config(sdev, size, link, config);
  2670. if (ret < 0)
  2671. dev_err(scomp->dev, "error: failed to save DAI config for DMIC%d\n",
  2672. config->dai_index);
  2673. return ret;
  2674. }
  2675. static int sof_link_hda_load(struct snd_soc_component *scomp, int index,
  2676. struct snd_soc_dai_link *link,
  2677. struct snd_soc_tplg_link_config *cfg,
  2678. struct snd_soc_tplg_hw_config *hw_config,
  2679. struct sof_ipc_dai_config *config)
  2680. {
  2681. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2682. struct snd_soc_tplg_private *private = &cfg->priv;
  2683. struct snd_soc_dai *dai;
  2684. u32 size = sizeof(*config);
  2685. int ret;
  2686. /* init IPC */
  2687. memset(&config->hda, 0, sizeof(struct sof_ipc_dai_hda_params));
  2688. config->hdr.size = size;
  2689. /* get any bespoke DAI tokens */
  2690. ret = sof_parse_tokens(scomp, &config->hda, hda_tokens,
  2691. ARRAY_SIZE(hda_tokens), private->array,
  2692. le32_to_cpu(private->size));
  2693. if (ret != 0) {
  2694. dev_err(scomp->dev, "error: parse hda tokens failed %d\n",
  2695. le32_to_cpu(private->size));
  2696. return ret;
  2697. }
  2698. dev_dbg(scomp->dev, "HDA config rate %d channels %d\n",
  2699. config->hda.rate, config->hda.channels);
  2700. dai = snd_soc_find_dai(link->cpus);
  2701. if (!dai) {
  2702. dev_err(scomp->dev, "error: failed to find dai %s in %s",
  2703. link->cpus->dai_name, __func__);
  2704. return -EINVAL;
  2705. }
  2706. config->hda.link_dma_ch = DMA_CHAN_INVALID;
  2707. ret = sof_set_dai_config(sdev, size, link, config);
  2708. if (ret < 0)
  2709. dev_err(scomp->dev, "error: failed to process hda dai link %s",
  2710. link->name);
  2711. return ret;
  2712. }
  2713. static int sof_link_alh_load(struct snd_soc_component *scomp, int index,
  2714. struct snd_soc_dai_link *link,
  2715. struct snd_soc_tplg_link_config *cfg,
  2716. struct snd_soc_tplg_hw_config *hw_config,
  2717. struct sof_ipc_dai_config *config)
  2718. {
  2719. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2720. struct snd_soc_tplg_private *private = &cfg->priv;
  2721. u32 size = sizeof(*config);
  2722. int ret;
  2723. ret = sof_parse_tokens(scomp, &config->alh, alh_tokens,
  2724. ARRAY_SIZE(alh_tokens), private->array,
  2725. le32_to_cpu(private->size));
  2726. if (ret != 0) {
  2727. dev_err(scomp->dev, "error: parse alh tokens failed %d\n",
  2728. le32_to_cpu(private->size));
  2729. return ret;
  2730. }
  2731. /* init IPC */
  2732. config->hdr.size = size;
  2733. /* set config for all DAI's with name matching the link name */
  2734. ret = sof_set_dai_config(sdev, size, link, config);
  2735. if (ret < 0)
  2736. dev_err(scomp->dev, "error: failed to save DAI config for ALH %d\n",
  2737. config->dai_index);
  2738. return ret;
  2739. }
  2740. /* DAI link - used for any driver specific init */
  2741. static int sof_link_load(struct snd_soc_component *scomp, int index,
  2742. struct snd_soc_dai_link *link,
  2743. struct snd_soc_tplg_link_config *cfg)
  2744. {
  2745. struct snd_soc_tplg_private *private = &cfg->priv;
  2746. struct sof_ipc_dai_config config;
  2747. struct snd_soc_tplg_hw_config *hw_config;
  2748. int num_hw_configs;
  2749. int ret;
  2750. int i = 0;
  2751. if (!link->platforms) {
  2752. dev_err(scomp->dev, "error: no platforms\n");
  2753. return -EINVAL;
  2754. }
  2755. link->platforms->name = dev_name(scomp->dev);
  2756. /*
  2757. * Set nonatomic property for FE dai links as their trigger action
  2758. * involves IPC's.
  2759. */
  2760. if (!link->no_pcm) {
  2761. link->nonatomic = true;
  2762. /*
  2763. * set default trigger order for all links. Exceptions to
  2764. * the rule will be handled in sof_pcm_dai_link_fixup()
  2765. * For playback, the sequence is the following: start FE,
  2766. * start BE, stop BE, stop FE; for Capture the sequence is
  2767. * inverted start BE, start FE, stop FE, stop BE
  2768. */
  2769. link->trigger[SNDRV_PCM_STREAM_PLAYBACK] =
  2770. SND_SOC_DPCM_TRIGGER_PRE;
  2771. link->trigger[SNDRV_PCM_STREAM_CAPTURE] =
  2772. SND_SOC_DPCM_TRIGGER_POST;
  2773. /* nothing more to do for FE dai links */
  2774. return 0;
  2775. }
  2776. /* check we have some tokens - we need at least DAI type */
  2777. if (le32_to_cpu(private->size) == 0) {
  2778. dev_err(scomp->dev, "error: expected tokens for DAI, none found\n");
  2779. return -EINVAL;
  2780. }
  2781. /* Send BE DAI link configurations to DSP */
  2782. memset(&config, 0, sizeof(config));
  2783. /* get any common DAI tokens */
  2784. ret = sof_parse_tokens(scomp, &config, dai_link_tokens,
  2785. ARRAY_SIZE(dai_link_tokens), private->array,
  2786. le32_to_cpu(private->size));
  2787. if (ret != 0) {
  2788. dev_err(scomp->dev, "error: parse link tokens failed %d\n",
  2789. le32_to_cpu(private->size));
  2790. return ret;
  2791. }
  2792. /*
  2793. * DAI links are expected to have at least 1 hw_config.
  2794. * But some older topologies might have no hw_config for HDA dai links.
  2795. */
  2796. num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
  2797. if (!num_hw_configs) {
  2798. if (config.type != SOF_DAI_INTEL_HDA) {
  2799. dev_err(scomp->dev, "error: unexpected DAI config count %d!\n",
  2800. le32_to_cpu(cfg->num_hw_configs));
  2801. return -EINVAL;
  2802. }
  2803. } else {
  2804. dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d!\n",
  2805. cfg->num_hw_configs, le32_to_cpu(cfg->default_hw_config_id));
  2806. for (i = 0; i < num_hw_configs; i++) {
  2807. if (cfg->hw_config[i].id == cfg->default_hw_config_id)
  2808. break;
  2809. }
  2810. if (i == num_hw_configs) {
  2811. dev_err(scomp->dev, "error: default hw_config id: %d not found!\n",
  2812. le32_to_cpu(cfg->default_hw_config_id));
  2813. return -EINVAL;
  2814. }
  2815. }
  2816. /* configure dai IPC message */
  2817. hw_config = &cfg->hw_config[i];
  2818. config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG;
  2819. config.format = le32_to_cpu(hw_config->fmt);
  2820. /* now load DAI specific data and send IPC - type comes from token */
  2821. switch (config.type) {
  2822. case SOF_DAI_INTEL_SSP:
  2823. ret = sof_link_ssp_load(scomp, index, link, cfg, hw_config,
  2824. &config);
  2825. break;
  2826. case SOF_DAI_INTEL_DMIC:
  2827. ret = sof_link_dmic_load(scomp, index, link, cfg, hw_config,
  2828. &config);
  2829. break;
  2830. case SOF_DAI_INTEL_HDA:
  2831. ret = sof_link_hda_load(scomp, index, link, cfg, hw_config,
  2832. &config);
  2833. break;
  2834. case SOF_DAI_INTEL_ALH:
  2835. ret = sof_link_alh_load(scomp, index, link, cfg, hw_config,
  2836. &config);
  2837. break;
  2838. case SOF_DAI_IMX_SAI:
  2839. ret = sof_link_sai_load(scomp, index, link, cfg, hw_config,
  2840. &config);
  2841. break;
  2842. case SOF_DAI_IMX_ESAI:
  2843. ret = sof_link_esai_load(scomp, index, link, cfg, hw_config,
  2844. &config);
  2845. break;
  2846. default:
  2847. dev_err(scomp->dev, "error: invalid DAI type %d\n",
  2848. config.type);
  2849. ret = -EINVAL;
  2850. break;
  2851. }
  2852. if (ret < 0)
  2853. return ret;
  2854. return 0;
  2855. }
  2856. static int sof_link_hda_unload(struct snd_sof_dev *sdev,
  2857. struct snd_soc_dai_link *link)
  2858. {
  2859. struct snd_soc_dai *dai;
  2860. dai = snd_soc_find_dai(link->cpus);
  2861. if (!dai) {
  2862. dev_err(sdev->dev, "error: failed to find dai %s in %s",
  2863. link->cpus->dai_name, __func__);
  2864. return -EINVAL;
  2865. }
  2866. return 0;
  2867. }
  2868. static int sof_link_unload(struct snd_soc_component *scomp,
  2869. struct snd_soc_dobj *dobj)
  2870. {
  2871. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2872. struct snd_soc_dai_link *link =
  2873. container_of(dobj, struct snd_soc_dai_link, dobj);
  2874. struct snd_sof_dai *sof_dai;
  2875. int ret = 0;
  2876. /* only BE link is loaded by sof */
  2877. if (!link->no_pcm)
  2878. return 0;
  2879. list_for_each_entry(sof_dai, &sdev->dai_list, list) {
  2880. if (!sof_dai->name)
  2881. continue;
  2882. if (strcmp(link->name, sof_dai->name) == 0)
  2883. goto found;
  2884. }
  2885. dev_err(scomp->dev, "error: failed to find dai %s in %s",
  2886. link->name, __func__);
  2887. return -EINVAL;
  2888. found:
  2889. switch (sof_dai->dai_config->type) {
  2890. case SOF_DAI_INTEL_SSP:
  2891. case SOF_DAI_INTEL_DMIC:
  2892. case SOF_DAI_INTEL_ALH:
  2893. case SOF_DAI_IMX_SAI:
  2894. case SOF_DAI_IMX_ESAI:
  2895. /* no resource needs to be released for all cases above */
  2896. break;
  2897. case SOF_DAI_INTEL_HDA:
  2898. ret = sof_link_hda_unload(sdev, link);
  2899. break;
  2900. default:
  2901. dev_err(scomp->dev, "error: invalid DAI type %d\n",
  2902. sof_dai->dai_config->type);
  2903. ret = -EINVAL;
  2904. break;
  2905. }
  2906. return ret;
  2907. }
  2908. /* DAI link - used for any driver specific init */
  2909. static int sof_route_load(struct snd_soc_component *scomp, int index,
  2910. struct snd_soc_dapm_route *route)
  2911. {
  2912. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2913. struct sof_ipc_pipe_comp_connect *connect;
  2914. struct snd_sof_widget *source_swidget, *sink_swidget;
  2915. struct snd_soc_dobj *dobj = &route->dobj;
  2916. struct snd_sof_route *sroute;
  2917. struct sof_ipc_reply reply;
  2918. int ret = 0;
  2919. /* allocate memory for sroute and connect */
  2920. sroute = kzalloc(sizeof(*sroute), GFP_KERNEL);
  2921. if (!sroute)
  2922. return -ENOMEM;
  2923. sroute->scomp = scomp;
  2924. connect = kzalloc(sizeof(*connect), GFP_KERNEL);
  2925. if (!connect) {
  2926. kfree(sroute);
  2927. return -ENOMEM;
  2928. }
  2929. connect->hdr.size = sizeof(*connect);
  2930. connect->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_CONNECT;
  2931. dev_dbg(scomp->dev, "sink %s control %s source %s\n",
  2932. route->sink, route->control ? route->control : "none",
  2933. route->source);
  2934. /* source component */
  2935. source_swidget = snd_sof_find_swidget(scomp, (char *)route->source);
  2936. if (!source_swidget) {
  2937. dev_err(scomp->dev, "error: source %s not found\n",
  2938. route->source);
  2939. ret = -EINVAL;
  2940. goto err;
  2941. }
  2942. /*
  2943. * Virtual widgets of type output/out_drv may be added in topology
  2944. * for compatibility. These are not handled by the FW.
  2945. * So, don't send routes whose source/sink widget is of such types
  2946. * to the DSP.
  2947. */
  2948. if (source_swidget->id == snd_soc_dapm_out_drv ||
  2949. source_swidget->id == snd_soc_dapm_output)
  2950. goto err;
  2951. connect->source_id = source_swidget->comp_id;
  2952. /* sink component */
  2953. sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink);
  2954. if (!sink_swidget) {
  2955. dev_err(scomp->dev, "error: sink %s not found\n",
  2956. route->sink);
  2957. ret = -EINVAL;
  2958. goto err;
  2959. }
  2960. /*
  2961. * Don't send routes whose sink widget is of type
  2962. * output or out_drv to the DSP
  2963. */
  2964. if (sink_swidget->id == snd_soc_dapm_out_drv ||
  2965. sink_swidget->id == snd_soc_dapm_output)
  2966. goto err;
  2967. connect->sink_id = sink_swidget->comp_id;
  2968. /*
  2969. * For virtual routes, both sink and source are not
  2970. * buffer. Since only buffer linked to component is supported by
  2971. * FW, others are reported as error, add check in route function,
  2972. * do not send it to FW when both source and sink are not buffer
  2973. */
  2974. if (source_swidget->id != snd_soc_dapm_buffer &&
  2975. sink_swidget->id != snd_soc_dapm_buffer) {
  2976. dev_dbg(scomp->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n",
  2977. route->source, route->sink);
  2978. goto err;
  2979. } else {
  2980. ret = sof_ipc_tx_message(sdev->ipc,
  2981. connect->hdr.cmd,
  2982. connect, sizeof(*connect),
  2983. &reply, sizeof(reply));
  2984. /* check IPC return value */
  2985. if (ret < 0) {
  2986. dev_err(scomp->dev, "error: failed to add route sink %s control %s source %s\n",
  2987. route->sink,
  2988. route->control ? route->control : "none",
  2989. route->source);
  2990. goto err;
  2991. }
  2992. /* check IPC reply */
  2993. if (reply.error < 0) {
  2994. dev_err(scomp->dev, "error: DSP failed to add route sink %s control %s source %s result %d\n",
  2995. route->sink,
  2996. route->control ? route->control : "none",
  2997. route->source, reply.error);
  2998. ret = reply.error;
  2999. goto err;
  3000. }
  3001. sroute->route = route;
  3002. dobj->private = sroute;
  3003. sroute->private = connect;
  3004. /* add route to route list */
  3005. list_add(&sroute->list, &sdev->route_list);
  3006. return 0;
  3007. }
  3008. err:
  3009. kfree(connect);
  3010. kfree(sroute);
  3011. return ret;
  3012. }
  3013. /* Function to set the initial value of SOF kcontrols.
  3014. * The value will be stored in scontrol->control_data
  3015. */
  3016. static int snd_sof_cache_kcontrol_val(struct snd_soc_component *scomp)
  3017. {
  3018. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  3019. struct snd_sof_control *scontrol = NULL;
  3020. int ipc_cmd, ctrl_type;
  3021. int ret = 0;
  3022. list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
  3023. /* notify DSP of kcontrol values */
  3024. switch (scontrol->cmd) {
  3025. case SOF_CTRL_CMD_VOLUME:
  3026. case SOF_CTRL_CMD_ENUM:
  3027. case SOF_CTRL_CMD_SWITCH:
  3028. ipc_cmd = SOF_IPC_COMP_GET_VALUE;
  3029. ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_GET;
  3030. break;
  3031. case SOF_CTRL_CMD_BINARY:
  3032. ipc_cmd = SOF_IPC_COMP_GET_DATA;
  3033. ctrl_type = SOF_CTRL_TYPE_DATA_GET;
  3034. break;
  3035. default:
  3036. dev_err(scomp->dev,
  3037. "error: Invalid scontrol->cmd: %d\n",
  3038. scontrol->cmd);
  3039. return -EINVAL;
  3040. }
  3041. ret = snd_sof_ipc_set_get_comp_data(scontrol,
  3042. ipc_cmd, ctrl_type,
  3043. scontrol->cmd,
  3044. false);
  3045. if (ret < 0) {
  3046. dev_warn(scomp->dev,
  3047. "error: kcontrol value get for widget: %d\n",
  3048. scontrol->comp_id);
  3049. }
  3050. }
  3051. return ret;
  3052. }
  3053. int snd_sof_complete_pipeline(struct device *dev,
  3054. struct snd_sof_widget *swidget)
  3055. {
  3056. struct snd_sof_dev *sdev = dev_get_drvdata(dev);
  3057. struct sof_ipc_pipe_ready ready;
  3058. struct sof_ipc_reply reply;
  3059. int ret;
  3060. dev_dbg(dev, "tplg: complete pipeline %s id %d\n",
  3061. swidget->widget->name, swidget->comp_id);
  3062. memset(&ready, 0, sizeof(ready));
  3063. ready.hdr.size = sizeof(ready);
  3064. ready.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_COMPLETE;
  3065. ready.comp_id = swidget->comp_id;
  3066. ret = sof_ipc_tx_message(sdev->ipc,
  3067. ready.hdr.cmd, &ready, sizeof(ready), &reply,
  3068. sizeof(reply));
  3069. if (ret < 0)
  3070. return ret;
  3071. return 1;
  3072. }
  3073. /* completion - called at completion of firmware loading */
  3074. static void sof_complete(struct snd_soc_component *scomp)
  3075. {
  3076. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  3077. struct snd_sof_widget *swidget;
  3078. /* some widget types require completion notificattion */
  3079. list_for_each_entry(swidget, &sdev->widget_list, list) {
  3080. if (swidget->complete)
  3081. continue;
  3082. switch (swidget->id) {
  3083. case snd_soc_dapm_scheduler:
  3084. swidget->complete =
  3085. snd_sof_complete_pipeline(scomp->dev, swidget);
  3086. break;
  3087. default:
  3088. break;
  3089. }
  3090. }
  3091. /*
  3092. * cache initial values of SOF kcontrols by reading DSP value over
  3093. * IPC. It may be overwritten by alsa-mixer after booting up
  3094. */
  3095. snd_sof_cache_kcontrol_val(scomp);
  3096. }
  3097. /* manifest - optional to inform component of manifest */
  3098. static int sof_manifest(struct snd_soc_component *scomp, int index,
  3099. struct snd_soc_tplg_manifest *man)
  3100. {
  3101. u32 size;
  3102. u32 abi_version;
  3103. size = le32_to_cpu(man->priv.size);
  3104. /* backward compatible with tplg without ABI info */
  3105. if (!size) {
  3106. dev_dbg(scomp->dev, "No topology ABI info\n");
  3107. return 0;
  3108. }
  3109. if (size != SOF_TPLG_ABI_SIZE) {
  3110. dev_err(scomp->dev, "error: invalid topology ABI size\n");
  3111. return -EINVAL;
  3112. }
  3113. dev_info(scomp->dev,
  3114. "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
  3115. man->priv.data[0], man->priv.data[1],
  3116. man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR,
  3117. SOF_ABI_PATCH);
  3118. abi_version = SOF_ABI_VER(man->priv.data[0],
  3119. man->priv.data[1],
  3120. man->priv.data[2]);
  3121. if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) {
  3122. dev_err(scomp->dev, "error: incompatible topology ABI version\n");
  3123. return -EINVAL;
  3124. }
  3125. if (abi_version > SOF_ABI_VERSION) {
  3126. if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) {
  3127. dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n");
  3128. } else {
  3129. dev_err(scomp->dev, "error: topology ABI is more recent than kernel\n");
  3130. return -EINVAL;
  3131. }
  3132. }
  3133. return 0;
  3134. }
  3135. /* vendor specific kcontrol handlers available for binding */
  3136. static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
  3137. {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put},
  3138. {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put},
  3139. {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put},
  3140. {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put},
  3141. };
  3142. /* vendor specific bytes ext handlers available for binding */
  3143. static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
  3144. {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put},
  3145. {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
  3146. };
  3147. static struct snd_soc_tplg_ops sof_tplg_ops = {
  3148. /* external kcontrol init - used for any driver specific init */
  3149. .control_load = sof_control_load,
  3150. .control_unload = sof_control_unload,
  3151. /* external kcontrol init - used for any driver specific init */
  3152. .dapm_route_load = sof_route_load,
  3153. .dapm_route_unload = sof_route_unload,
  3154. /* external widget init - used for any driver specific init */
  3155. /* .widget_load is not currently used */
  3156. .widget_ready = sof_widget_ready,
  3157. .widget_unload = sof_widget_unload,
  3158. /* FE DAI - used for any driver specific init */
  3159. .dai_load = sof_dai_load,
  3160. .dai_unload = sof_dai_unload,
  3161. /* DAI link - used for any driver specific init */
  3162. .link_load = sof_link_load,
  3163. .link_unload = sof_link_unload,
  3164. /* completion - called at completion of firmware loading */
  3165. .complete = sof_complete,
  3166. /* manifest - optional to inform component of manifest */
  3167. .manifest = sof_manifest,
  3168. /* vendor specific kcontrol handlers available for binding */
  3169. .io_ops = sof_io_ops,
  3170. .io_ops_count = ARRAY_SIZE(sof_io_ops),
  3171. /* vendor specific bytes ext handlers available for binding */
  3172. .bytes_ext_ops = sof_bytes_ext_ops,
  3173. .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops),
  3174. };
  3175. int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
  3176. {
  3177. const struct firmware *fw;
  3178. int ret;
  3179. dev_dbg(scomp->dev, "loading topology:%s\n", file);
  3180. ret = request_firmware(&fw, file, scomp->dev);
  3181. if (ret < 0) {
  3182. dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
  3183. file, ret);
  3184. return ret;
  3185. }
  3186. ret = snd_soc_tplg_component_load(scomp,
  3187. &sof_tplg_ops, fw,
  3188. SND_SOC_TPLG_INDEX_ALL);
  3189. if (ret < 0) {
  3190. dev_err(scomp->dev, "error: tplg component load failed %d\n",
  3191. ret);
  3192. ret = -EINVAL;
  3193. }
  3194. release_firmware(fw);
  3195. return ret;
  3196. }
  3197. EXPORT_SYMBOL(snd_sof_load_topology);