ipc4-topology.c 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988
  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) 2022 Intel Corporation
  7. //
  8. //
  9. #include <linux/bitfield.h>
  10. #include <linux/cleanup.h>
  11. #include <uapi/sound/sof/tokens.h>
  12. #include <sound/pcm_params.h>
  13. #include <sound/sof/ext_manifest4.h>
  14. #include <sound/intel-nhlt.h>
  15. #include "sof-priv.h"
  16. #include "sof-audio.h"
  17. #include "ipc4-priv.h"
  18. #include "ipc4-topology.h"
  19. #include "ops.h"
  20. /*
  21. * The ignore_cpc flag can be used to ignore the CPC value for all modules by
  22. * using 0 instead.
  23. * The CPC is sent to the firmware along with the SOF_IPC4_MOD_INIT_INSTANCE
  24. * message and it is used for clock scaling.
  25. * 0 as CPC value will instruct the firmware to use maximum frequency, thus
  26. * deactivating the clock scaling.
  27. */
  28. static bool ignore_cpc;
  29. module_param_named(ipc4_ignore_cpc, ignore_cpc, bool, 0444);
  30. MODULE_PARM_DESC(ipc4_ignore_cpc,
  31. "Ignore CPC values. This option will disable clock scaling in firmware.");
  32. #define SOF_IPC4_GAIN_PARAM_ID 0
  33. #define SOF_IPC4_TPLG_ABI_SIZE 6
  34. static DEFINE_IDA(alh_group_ida);
  35. static DEFINE_IDA(pipeline_ida);
  36. struct sof_comp_domains {
  37. const char *name;
  38. enum sof_comp_domain domain;
  39. };
  40. static const struct sof_comp_domains sof_domains[] = {
  41. { "LL", SOF_COMP_DOMAIN_LL, },
  42. { "DP", SOF_COMP_DOMAIN_DP, }
  43. };
  44. static enum sof_comp_domain find_domain(const char *name)
  45. {
  46. int i;
  47. for (i = 0; i < ARRAY_SIZE(sof_domains); i++) {
  48. if (strcmp(name, sof_domains[i].name) == 0)
  49. return sof_domains[i].domain;
  50. }
  51. /* No valid value found, fall back to manifest value */
  52. return SOF_COMP_DOMAIN_UNSET;
  53. }
  54. static int get_token_comp_domain(void *elem, void *object, u32 offset)
  55. {
  56. u32 *val = (u32 *)((u8 *)object + offset);
  57. *val = find_domain((const char *)elem);
  58. return 0;
  59. }
  60. static const struct sof_topology_token ipc4_sched_tokens[] = {
  61. {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  62. offsetof(struct sof_ipc4_pipeline, lp_mode)},
  63. {SOF_TKN_SCHED_USE_CHAIN_DMA, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
  64. offsetof(struct sof_ipc4_pipeline, use_chain_dma)},
  65. {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  66. offsetof(struct sof_ipc4_pipeline, core_id)},
  67. {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  68. offsetof(struct sof_ipc4_pipeline, priority)},
  69. {SOF_TKN_SCHED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  70. offsetof(struct sof_ipc4_pipeline, direction)},
  71. {SOF_TKN_SCHED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
  72. offsetof(struct sof_ipc4_pipeline, direction_valid)},
  73. };
  74. static const struct sof_topology_token pipeline_tokens[] = {
  75. {SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
  76. offsetof(struct snd_sof_widget, dynamic_pipeline_widget)},
  77. };
  78. static const struct sof_topology_token ipc4_comp_tokens[] = {
  79. {SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  80. offsetof(struct sof_ipc4_base_module_cfg, is_pages)},
  81. };
  82. static const struct sof_topology_token ipc4_in_audio_format_tokens[] = {
  83. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  84. offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)},
  85. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  86. offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)},
  87. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  88. offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)},
  89. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  90. offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)},
  91. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  92. get_token_u32, offsetof(struct sof_ipc4_pin_format,
  93. audio_fmt.interleaving_style)},
  94. {SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  95. offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)},
  96. {SOF_TKN_CAVS_AUDIO_FORMAT_INPUT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  97. offsetof(struct sof_ipc4_pin_format, pin_index)},
  98. {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  99. offsetof(struct sof_ipc4_pin_format, buffer_size)},
  100. };
  101. static const struct sof_topology_token ipc4_out_audio_format_tokens[] = {
  102. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  103. offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)},
  104. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  105. offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)},
  106. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  107. offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)},
  108. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  109. offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)},
  110. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  111. get_token_u32, offsetof(struct sof_ipc4_pin_format,
  112. audio_fmt.interleaving_style)},
  113. {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  114. offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)},
  115. {SOF_TKN_CAVS_AUDIO_FORMAT_OUTPUT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  116. offsetof(struct sof_ipc4_pin_format, pin_index)},
  117. {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  118. offsetof(struct sof_ipc4_pin_format, buffer_size)},
  119. };
  120. static const struct sof_topology_token ipc4_copier_deep_buffer_tokens[] = {
  121. {SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
  122. };
  123. static const struct sof_topology_token ipc4_copier_tokens[] = {
  124. {SOF_TKN_INTEL_COPIER_NODE_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
  125. };
  126. static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = {
  127. {SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  128. offsetof(struct sof_ipc4_available_audio_format, num_input_formats)},
  129. {SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  130. offsetof(struct sof_ipc4_available_audio_format, num_output_formats)},
  131. };
  132. static const struct sof_topology_token dai_tokens[] = {
  133. {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type,
  134. offsetof(struct sof_ipc4_copier, dai_type)},
  135. {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  136. offsetof(struct sof_ipc4_copier, dai_index)},
  137. };
  138. /* Component extended tokens */
  139. static const struct sof_topology_token comp_ext_tokens[] = {
  140. {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid,
  141. offsetof(struct snd_sof_widget, uuid)},
  142. {SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  143. offsetof(struct snd_sof_widget, core)},
  144. {SOF_TKN_COMP_SCHED_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_domain,
  145. offsetof(struct snd_sof_widget, comp_domain)},
  146. {SOF_TKN_COMP_DOMAIN_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  147. offsetof(struct snd_sof_widget, dp_domain_id)},
  148. {SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  149. offsetof(struct snd_sof_widget, dp_heap_bytes)},
  150. {SOF_TKN_COMP_STACK_BYTES_REQUIREMENT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  151. offsetof(struct snd_sof_widget, dp_stack_bytes)},
  152. };
  153. static const struct sof_topology_token gain_tokens[] = {
  154. {SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  155. get_token_u32, offsetof(struct sof_ipc4_gain_params, curve_type)},
  156. {SOF_TKN_GAIN_RAMP_DURATION,
  157. SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  158. offsetof(struct sof_ipc4_gain_params, curve_duration_l)},
  159. {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD,
  160. get_token_u32, offsetof(struct sof_ipc4_gain_params, init_val)},
  161. };
  162. /* SRC */
  163. static const struct sof_topology_token src_tokens[] = {
  164. {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  165. offsetof(struct sof_ipc4_src_data, sink_rate)},
  166. };
  167. /* ASRC */
  168. static const struct sof_topology_token asrc_tokens[] = {
  169. {SOF_TKN_ASRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  170. offsetof(struct sof_ipc4_asrc_data, out_freq)},
  171. {SOF_TKN_ASRC_OPERATION_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
  172. offsetof(struct sof_ipc4_asrc_data, asrc_mode)},
  173. };
  174. static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
  175. [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)},
  176. [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)},
  177. [SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens,
  178. ARRAY_SIZE(ipc4_sched_tokens)},
  179. [SOF_COMP_EXT_TOKENS] = {"Comp extended tokens", comp_ext_tokens,
  180. ARRAY_SIZE(comp_ext_tokens)},
  181. [SOF_COMP_TOKENS] = {"IPC4 Component tokens",
  182. ipc4_comp_tokens, ARRAY_SIZE(ipc4_comp_tokens)},
  183. [SOF_IN_AUDIO_FORMAT_TOKENS] = {"IPC4 Input Audio format tokens",
  184. ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)},
  185. [SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens",
  186. ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)},
  187. [SOF_COPIER_DEEP_BUFFER_TOKENS] = {"IPC4 Copier deep buffer tokens",
  188. ipc4_copier_deep_buffer_tokens, ARRAY_SIZE(ipc4_copier_deep_buffer_tokens)},
  189. [SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens,
  190. ARRAY_SIZE(ipc4_copier_tokens)},
  191. [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens",
  192. ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)},
  193. [SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)},
  194. [SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)},
  195. [SOF_ASRC_TOKENS] = {"ASRC tokens", asrc_tokens, ARRAY_SIZE(asrc_tokens)},
  196. };
  197. struct snd_sof_widget *sof_ipc4_find_swidget_by_ids(struct snd_sof_dev *sdev,
  198. u32 module_id, int instance_id)
  199. {
  200. struct snd_sof_widget *swidget;
  201. list_for_each_entry(swidget, &sdev->widget_list, list) {
  202. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  203. /* Only active module instances have valid instance_id */
  204. if (!swidget->use_count)
  205. continue;
  206. if (fw_module && fw_module->man4_module_entry.id == module_id &&
  207. swidget->instance_id == instance_id)
  208. return swidget;
  209. }
  210. return NULL;
  211. }
  212. static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_format *pin_fmt,
  213. int num_formats)
  214. {
  215. int i;
  216. for (i = 0; i < num_formats; i++) {
  217. struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt;
  218. dev_dbg(dev,
  219. "Pin #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n",
  220. pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth,
  221. SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg),
  222. fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg,
  223. pin_fmt[i].buffer_size);
  224. }
  225. }
  226. static void
  227. sof_ipc4_dbg_module_audio_format(struct device *dev,
  228. struct snd_sof_widget *swidget,
  229. struct sof_ipc4_available_audio_format *available_fmt,
  230. int in_fmt_index, int out_fmt_index)
  231. {
  232. struct sof_ipc4_audio_format *in_fmt, *out_fmt;
  233. u32 out_rate, out_channels, out_valid_bits;
  234. u32 in_rate, in_channels, in_valid_bits;
  235. struct sof_ipc4_pin_format *pin_fmt;
  236. if (!available_fmt->num_input_formats &&
  237. !available_fmt->num_output_formats)
  238. return;
  239. /* Only input or output is supported by the module */
  240. if (!available_fmt->num_input_formats) {
  241. if (available_fmt->num_output_formats == 1)
  242. dev_dbg(dev, "Output audio format for %s:\n",
  243. swidget->widget->name);
  244. else
  245. dev_dbg(dev,
  246. "Output audio format (format index: %d) for %s:\n",
  247. out_fmt_index, swidget->widget->name);
  248. pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index];
  249. sof_ipc4_dbg_audio_format(dev, pin_fmt, 1);
  250. return;
  251. } else if (!available_fmt->num_output_formats) {
  252. if (available_fmt->num_input_formats == 1)
  253. dev_dbg(dev, "Input audio format for %s:\n",
  254. swidget->widget->name);
  255. else
  256. dev_dbg(dev,
  257. "Input audio format (format index: %d) for %s:\n",
  258. out_fmt_index, swidget->widget->name);
  259. pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index];
  260. sof_ipc4_dbg_audio_format(dev, pin_fmt, 1);
  261. return;
  262. }
  263. in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt;
  264. out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt;
  265. in_rate = in_fmt->sampling_frequency;
  266. in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
  267. in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
  268. out_rate = out_fmt->sampling_frequency;
  269. out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg);
  270. out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg);
  271. if (!(in_valid_bits != out_valid_bits || in_rate != out_rate ||
  272. in_channels != out_channels)) {
  273. /* There is no change in format */
  274. if (available_fmt->num_input_formats == 1 &&
  275. available_fmt->num_output_formats == 1)
  276. dev_dbg(dev, "Audio format for %s:\n",
  277. swidget->widget->name);
  278. else
  279. dev_dbg(dev,
  280. "Audio format (in/out format index: %d/%d) for %s:\n",
  281. in_fmt_index, out_fmt_index, swidget->widget->name);
  282. pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index];
  283. sof_ipc4_dbg_audio_format(dev, pin_fmt, 1);
  284. return;
  285. }
  286. /* The format is changed by the module */
  287. if (available_fmt->num_input_formats == 1)
  288. dev_dbg(dev, "Input audio format for %s:\n",
  289. swidget->widget->name);
  290. else
  291. dev_dbg(dev, "Input audio format (format index: %d) for %s:\n",
  292. in_fmt_index, swidget->widget->name);
  293. pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index];
  294. sof_ipc4_dbg_audio_format(dev, pin_fmt, 1);
  295. if (available_fmt->num_output_formats == 1)
  296. dev_dbg(dev, "Output audio format for %s:\n",
  297. swidget->widget->name);
  298. else
  299. dev_dbg(dev, "Output audio format (format index: %d) for %s:\n",
  300. out_fmt_index, swidget->widget->name);
  301. pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index];
  302. sof_ipc4_dbg_audio_format(dev, pin_fmt, 1);
  303. }
  304. static const struct sof_ipc4_audio_format *
  305. sof_ipc4_get_input_pin_audio_fmt(struct snd_sof_widget *swidget, int pin_index)
  306. {
  307. struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
  308. struct sof_ipc4_process *process;
  309. int i;
  310. if (swidget->id != snd_soc_dapm_effect) {
  311. struct sof_ipc4_base_module_cfg *base = swidget->private;
  312. /* For non-process modules, base module config format is used for all input pins */
  313. return &base->audio_fmt;
  314. }
  315. process = swidget->private;
  316. /*
  317. * For process modules without base config extension, base module config
  318. * format is used for all input pins
  319. */
  320. if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT)
  321. return &process->base_config.audio_fmt;
  322. base_cfg_ext = process->base_config_ext;
  323. /*
  324. * If there are multiple input formats available for a pin, the first available format
  325. * is chosen.
  326. */
  327. for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) {
  328. struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i];
  329. if (pin_format->pin_index == pin_index)
  330. return &pin_format->audio_fmt;
  331. }
  332. return NULL;
  333. }
  334. /**
  335. * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
  336. * @scomp: pointer to pointer to SOC component
  337. * @swidget: pointer to struct snd_sof_widget containing tuples
  338. * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in
  339. * @module_base_cfg: Pointer to the base_config in the module init IPC payload
  340. *
  341. * Return: 0 if successful
  342. */
  343. static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
  344. struct snd_sof_widget *swidget,
  345. struct sof_ipc4_available_audio_format *available_fmt,
  346. struct sof_ipc4_base_module_cfg *module_base_cfg)
  347. {
  348. struct sof_ipc4_pin_format *in_format = NULL;
  349. struct sof_ipc4_pin_format *out_format;
  350. int ret;
  351. ret = sof_update_ipc_object(scomp, available_fmt,
  352. SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples,
  353. swidget->num_tuples, sizeof(*available_fmt), 1);
  354. if (ret) {
  355. dev_err(scomp->dev, "Failed to parse audio format token count\n");
  356. return ret;
  357. }
  358. if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) {
  359. dev_err(scomp->dev, "No input/output pin formats set in topology\n");
  360. return -EINVAL;
  361. }
  362. dev_dbg(scomp->dev,
  363. "Number of input audio formats: %d. Number of output audio formats: %d\n",
  364. available_fmt->num_input_formats, available_fmt->num_output_formats);
  365. /* set is_pages in the module's base_config */
  366. ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples,
  367. swidget->num_tuples, sizeof(*module_base_cfg), 1);
  368. if (ret) {
  369. dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n",
  370. swidget->widget->name, ret);
  371. return ret;
  372. }
  373. dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name,
  374. module_base_cfg->is_pages);
  375. if (available_fmt->num_input_formats) {
  376. in_format = kzalloc_objs(*in_format,
  377. available_fmt->num_input_formats);
  378. if (!in_format)
  379. return -ENOMEM;
  380. available_fmt->input_pin_fmts = in_format;
  381. ret = sof_update_ipc_object(scomp, in_format,
  382. SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples,
  383. swidget->num_tuples, sizeof(*in_format),
  384. available_fmt->num_input_formats);
  385. if (ret) {
  386. dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret);
  387. goto err_in;
  388. }
  389. dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name);
  390. sof_ipc4_dbg_audio_format(scomp->dev, in_format,
  391. available_fmt->num_input_formats);
  392. }
  393. if (available_fmt->num_output_formats) {
  394. out_format = kzalloc_objs(*out_format,
  395. available_fmt->num_output_formats);
  396. if (!out_format) {
  397. ret = -ENOMEM;
  398. goto err_in;
  399. }
  400. ret = sof_update_ipc_object(scomp, out_format,
  401. SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples,
  402. swidget->num_tuples, sizeof(*out_format),
  403. available_fmt->num_output_formats);
  404. if (ret) {
  405. dev_err(scomp->dev, "parse output audio fmt tokens failed\n");
  406. goto err_out;
  407. }
  408. available_fmt->output_pin_fmts = out_format;
  409. dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name);
  410. sof_ipc4_dbg_audio_format(scomp->dev, out_format,
  411. available_fmt->num_output_formats);
  412. }
  413. return 0;
  414. err_out:
  415. kfree(out_format);
  416. err_in:
  417. kfree(in_format);
  418. available_fmt->input_pin_fmts = NULL;
  419. return ret;
  420. }
  421. /* release the memory allocated in sof_ipc4_get_audio_fmt */
  422. static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt)
  423. {
  424. kfree(available_fmt->output_pin_fmts);
  425. available_fmt->output_pin_fmts = NULL;
  426. kfree(available_fmt->input_pin_fmts);
  427. available_fmt->input_pin_fmts = NULL;
  428. }
  429. static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget)
  430. {
  431. kfree(swidget->private);
  432. }
  433. static int sof_ipc4_widget_set_module_info(struct snd_sof_widget *swidget)
  434. {
  435. struct snd_soc_component *scomp = swidget->scomp;
  436. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  437. swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid);
  438. if (swidget->module_info)
  439. return 0;
  440. dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n",
  441. swidget->widget->name, &swidget->uuid);
  442. return -EINVAL;
  443. }
  444. static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_ipc4_msg *msg)
  445. {
  446. struct sof_ipc4_fw_module *fw_module;
  447. uint32_t type;
  448. int ret;
  449. ret = sof_ipc4_widget_set_module_info(swidget);
  450. if (ret)
  451. return ret;
  452. fw_module = swidget->module_info;
  453. msg->primary = fw_module->man4_module_entry.id;
  454. msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE);
  455. msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  456. msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  457. msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core);
  458. switch (swidget->comp_domain) {
  459. case SOF_COMP_DOMAIN_LL:
  460. type = 0;
  461. break;
  462. case SOF_COMP_DOMAIN_DP:
  463. type = 1;
  464. break;
  465. default:
  466. type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0;
  467. break;
  468. }
  469. msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type);
  470. return 0;
  471. }
  472. static void sof_ipc4_widget_update_kcontrol_module_id(struct snd_sof_widget *swidget)
  473. {
  474. struct snd_soc_component *scomp = swidget->scomp;
  475. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  476. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  477. struct snd_sof_control *scontrol;
  478. /* update module ID for all kcontrols for this widget */
  479. list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
  480. if (scontrol->comp_id == swidget->comp_id) {
  481. struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
  482. struct sof_ipc4_msg *msg = &cdata->msg;
  483. msg->primary |= fw_module->man4_module_entry.id;
  484. }
  485. }
  486. }
  487. static int
  488. sof_ipc4_update_card_components_string(struct snd_sof_widget *swidget,
  489. struct snd_sof_pcm *spcm, int dir)
  490. {
  491. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  492. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  493. struct snd_soc_component *scomp = spcm->scomp;
  494. struct snd_soc_card *card = scomp->card;
  495. const char *pt_marker = "iec61937-pcm";
  496. /*
  497. * Update the card's components list with iec61937-pcm and a list of PCM
  498. * ids where ChainDMA is enabled.
  499. * These PCMs can be used for bytestream passthrough.
  500. */
  501. if (!pipeline->use_chain_dma)
  502. return 0;
  503. if (card->components) {
  504. const char *tmp = card->components;
  505. if (strstr(card->components, pt_marker))
  506. card->components = devm_kasprintf(card->dev, GFP_KERNEL,
  507. "%s,%d",
  508. card->components,
  509. spcm->pcm.pcm_id);
  510. else
  511. card->components = devm_kasprintf(card->dev, GFP_KERNEL,
  512. "%s %s:%d",
  513. card->components,
  514. pt_marker,
  515. spcm->pcm.pcm_id);
  516. devm_kfree(card->dev, tmp);
  517. } else {
  518. card->components = devm_kasprintf(card->dev, GFP_KERNEL,
  519. "%s:%d", pt_marker,
  520. spcm->pcm.pcm_id);
  521. }
  522. if (!card->components)
  523. return -ENOMEM;
  524. return 0;
  525. }
  526. static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
  527. {
  528. struct sof_ipc4_available_audio_format *available_fmt;
  529. struct snd_soc_component *scomp = swidget->scomp;
  530. struct sof_ipc4_copier *ipc4_copier;
  531. struct snd_sof_pcm *spcm;
  532. int node_type = 0;
  533. int ret, dir;
  534. ipc4_copier = kzalloc_obj(*ipc4_copier);
  535. if (!ipc4_copier)
  536. return -ENOMEM;
  537. swidget->private = ipc4_copier;
  538. available_fmt = &ipc4_copier->available_fmt;
  539. dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  540. ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt,
  541. &ipc4_copier->data.base_config);
  542. if (ret)
  543. goto free_copier;
  544. /*
  545. * This callback is used by host copier and module-to-module copier,
  546. * and only host copier needs to set gtw_cfg.
  547. */
  548. if (!WIDGET_IS_AIF(swidget->id))
  549. goto skip_gtw_cfg;
  550. ret = sof_update_ipc_object(scomp, &node_type,
  551. SOF_COPIER_TOKENS, swidget->tuples,
  552. swidget->num_tuples, sizeof(node_type), 1);
  553. if (ret) {
  554. dev_err(scomp->dev, "parse host copier node type token failed %d\n",
  555. ret);
  556. goto free_available_fmt;
  557. }
  558. dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type);
  559. spcm = snd_sof_find_spcm_comp(scomp, swidget->comp_id, &dir);
  560. if (!spcm)
  561. goto skip_gtw_cfg;
  562. ret = sof_ipc4_update_card_components_string(swidget, spcm, dir);
  563. if (ret)
  564. goto free_available_fmt;
  565. if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
  566. struct snd_sof_pcm_stream *sps = &spcm->stream[dir];
  567. sof_update_ipc_object(scomp, &sps->dsp_max_burst_size_in_ms,
  568. SOF_COPIER_DEEP_BUFFER_TOKENS,
  569. swidget->tuples,
  570. swidget->num_tuples, sizeof(u32), 1);
  571. /* Set default DMA buffer size if it is not specified in topology */
  572. if (!sps->dsp_max_burst_size_in_ms) {
  573. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  574. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  575. sps->dsp_max_burst_size_in_ms = pipeline->use_chain_dma ?
  576. SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE;
  577. }
  578. } else {
  579. /* Capture data is copied from DSP to host in 1ms bursts */
  580. spcm->stream[dir].dsp_max_burst_size_in_ms = 1;
  581. }
  582. skip_gtw_cfg:
  583. ipc4_copier->gtw_attr = kzalloc_obj(*ipc4_copier->gtw_attr);
  584. if (!ipc4_copier->gtw_attr) {
  585. ret = -ENOMEM;
  586. goto free_available_fmt;
  587. }
  588. ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
  589. ipc4_copier->data.gtw_cfg.config_length =
  590. sizeof(struct sof_ipc4_gtw_attributes) >> 2;
  591. switch (swidget->id) {
  592. case snd_soc_dapm_aif_in:
  593. case snd_soc_dapm_aif_out:
  594. ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
  595. break;
  596. case snd_soc_dapm_buffer:
  597. ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID;
  598. ipc4_copier->ipc_config_size = 0;
  599. break;
  600. default:
  601. dev_err(scomp->dev, "invalid widget type %d\n", swidget->id);
  602. ret = -EINVAL;
  603. goto free_gtw_attr;
  604. }
  605. /* set up module info and message header */
  606. ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg);
  607. if (ret)
  608. goto free_gtw_attr;
  609. return 0;
  610. free_gtw_attr:
  611. kfree(ipc4_copier->gtw_attr);
  612. free_available_fmt:
  613. sof_ipc4_free_audio_fmt(available_fmt);
  614. free_copier:
  615. kfree(ipc4_copier);
  616. swidget->private = NULL;
  617. return ret;
  618. }
  619. static void sof_ipc4_widget_free_comp_pcm(struct snd_sof_widget *swidget)
  620. {
  621. struct sof_ipc4_copier *ipc4_copier = swidget->private;
  622. struct sof_ipc4_available_audio_format *available_fmt;
  623. if (!ipc4_copier)
  624. return;
  625. available_fmt = &ipc4_copier->available_fmt;
  626. kfree(available_fmt->output_pin_fmts);
  627. kfree(ipc4_copier->gtw_attr);
  628. kfree(ipc4_copier);
  629. swidget->private = NULL;
  630. }
  631. static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
  632. {
  633. struct sof_ipc4_available_audio_format *available_fmt;
  634. struct snd_soc_component *scomp = swidget->scomp;
  635. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  636. struct snd_sof_dai *dai = swidget->private;
  637. struct sof_ipc4_copier *ipc4_copier;
  638. struct snd_sof_widget *pipe_widget;
  639. struct sof_ipc4_pipeline *pipeline;
  640. int node_type = 0;
  641. int ret;
  642. ipc4_copier = kzalloc_obj(*ipc4_copier);
  643. if (!ipc4_copier)
  644. return -ENOMEM;
  645. available_fmt = &ipc4_copier->available_fmt;
  646. dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  647. ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt,
  648. &ipc4_copier->data.base_config);
  649. if (ret)
  650. goto free_copier;
  651. ret = sof_update_ipc_object(scomp, &node_type,
  652. SOF_COPIER_TOKENS, swidget->tuples,
  653. swidget->num_tuples, sizeof(node_type), 1);
  654. if (ret) {
  655. dev_err(scomp->dev, "parse dai node type failed %d\n", ret);
  656. goto free_available_fmt;
  657. }
  658. ret = sof_update_ipc_object(scomp, ipc4_copier,
  659. SOF_DAI_TOKENS, swidget->tuples,
  660. swidget->num_tuples, sizeof(u32), 1);
  661. if (ret) {
  662. dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret);
  663. goto free_available_fmt;
  664. }
  665. dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name,
  666. node_type, ipc4_copier->dai_type, ipc4_copier->dai_index);
  667. dai->type = ipc4_copier->dai_type;
  668. ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
  669. pipe_widget = swidget->spipe->pipe_widget;
  670. pipeline = pipe_widget->private;
  671. if (pipeline->use_chain_dma &&
  672. !snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) {
  673. dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n",
  674. ipc4_copier->dai_type);
  675. ret = -ENODEV;
  676. goto free_available_fmt;
  677. }
  678. switch (ipc4_copier->dai_type) {
  679. case SOF_DAI_INTEL_ALH:
  680. {
  681. struct sof_ipc4_alh_configuration_blob *blob;
  682. struct snd_soc_dapm_path *p;
  683. struct snd_sof_widget *w;
  684. int src_num = 0;
  685. snd_soc_dapm_widget_for_each_source_path(swidget->widget, p)
  686. src_num++;
  687. if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) {
  688. /*
  689. * The blob will not be used if the ALH copier is playback direction
  690. * and doesn't connect to any source.
  691. * It is fine to call kfree(ipc4_copier->copier_config) since
  692. * ipc4_copier->copier_config is null.
  693. */
  694. break;
  695. }
  696. blob = kzalloc_obj(*blob);
  697. if (!blob) {
  698. ret = -ENOMEM;
  699. goto free_available_fmt;
  700. }
  701. list_for_each_entry(w, &sdev->widget_list, list) {
  702. struct snd_sof_dai *alh_dai;
  703. if (!WIDGET_IS_DAI(w->id) || !w->widget->sname ||
  704. strcmp(w->widget->sname, swidget->widget->sname))
  705. continue;
  706. alh_dai = w->private;
  707. if (alh_dai->type != SOF_DAI_INTEL_ALH)
  708. continue;
  709. blob->alh_cfg.device_count++;
  710. }
  711. ipc4_copier->copier_config = (uint32_t *)blob;
  712. /* set data.gtw_cfg.config_length based on device_count */
  713. ipc4_copier->data.gtw_cfg.config_length = (sizeof(blob->gw_attr) +
  714. sizeof(blob->alh_cfg.device_count) +
  715. sizeof(*blob->alh_cfg.mapping) *
  716. blob->alh_cfg.device_count) >> 2;
  717. break;
  718. }
  719. case SOF_DAI_INTEL_SSP:
  720. /* set SSP DAI index as the node_id */
  721. ipc4_copier->data.gtw_cfg.node_id |=
  722. SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index);
  723. break;
  724. case SOF_DAI_INTEL_DMIC:
  725. /* set DMIC DAI index as the node_id */
  726. ipc4_copier->data.gtw_cfg.node_id |=
  727. SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index);
  728. break;
  729. default:
  730. ipc4_copier->gtw_attr = kzalloc_obj(*ipc4_copier->gtw_attr);
  731. if (!ipc4_copier->gtw_attr) {
  732. ret = -ENOMEM;
  733. goto free_available_fmt;
  734. }
  735. ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
  736. ipc4_copier->data.gtw_cfg.config_length =
  737. sizeof(struct sof_ipc4_gtw_attributes) >> 2;
  738. break;
  739. }
  740. dai->scomp = scomp;
  741. dai->private = ipc4_copier;
  742. /* set up module info and message header */
  743. ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg);
  744. if (ret)
  745. goto free_copier_config;
  746. return 0;
  747. free_copier_config:
  748. kfree(ipc4_copier->copier_config);
  749. free_available_fmt:
  750. sof_ipc4_free_audio_fmt(available_fmt);
  751. free_copier:
  752. kfree(ipc4_copier);
  753. dai->private = NULL;
  754. dai->scomp = NULL;
  755. return ret;
  756. }
  757. static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget)
  758. {
  759. struct sof_ipc4_available_audio_format *available_fmt;
  760. struct snd_sof_dai *dai = swidget->private;
  761. struct sof_ipc4_copier *ipc4_copier;
  762. if (!dai)
  763. return;
  764. if (!dai->private) {
  765. kfree(dai);
  766. swidget->private = NULL;
  767. return;
  768. }
  769. ipc4_copier = dai->private;
  770. available_fmt = &ipc4_copier->available_fmt;
  771. kfree(available_fmt->output_pin_fmts);
  772. if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP &&
  773. ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC)
  774. kfree(ipc4_copier->copier_config);
  775. kfree(dai->private);
  776. kfree(dai);
  777. swidget->private = NULL;
  778. }
  779. static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
  780. {
  781. struct snd_soc_component *scomp = swidget->scomp;
  782. struct sof_ipc4_pipeline *pipeline;
  783. struct snd_sof_pipeline *spipe = swidget->spipe;
  784. int ret;
  785. pipeline = kzalloc_obj(*pipeline);
  786. if (!pipeline)
  787. return -ENOMEM;
  788. ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples,
  789. swidget->num_tuples, sizeof(*pipeline), 1);
  790. if (ret) {
  791. dev_err(scomp->dev, "parsing scheduler tokens failed\n");
  792. goto err;
  793. }
  794. swidget->core = pipeline->core_id;
  795. spipe->core_mask |= BIT(pipeline->core_id);
  796. if (pipeline->direction_valid) {
  797. spipe->direction = pipeline->direction;
  798. spipe->direction_valid = true;
  799. }
  800. if (pipeline->use_chain_dma) {
  801. dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name);
  802. swidget->private = pipeline;
  803. return 0;
  804. }
  805. /* parse one set of pipeline tokens */
  806. ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples,
  807. swidget->num_tuples, sizeof(*swidget), 1);
  808. if (ret) {
  809. dev_err(scomp->dev, "parsing pipeline tokens failed\n");
  810. goto err;
  811. }
  812. dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d direction %d\n",
  813. swidget->widget->name, swidget->pipeline_id,
  814. pipeline->priority, pipeline->core_id, pipeline->lp_mode, pipeline->direction);
  815. swidget->private = pipeline;
  816. pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority);
  817. pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE);
  818. pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  819. pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
  820. pipeline->msg.extension = pipeline->lp_mode;
  821. pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id);
  822. pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
  823. return 0;
  824. err:
  825. kfree(pipeline);
  826. return ret;
  827. }
  828. static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
  829. {
  830. struct snd_soc_component *scomp = swidget->scomp;
  831. struct sof_ipc4_gain *gain;
  832. int ret;
  833. gain = kzalloc_obj(*gain);
  834. if (!gain)
  835. return -ENOMEM;
  836. swidget->private = gain;
  837. gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
  838. gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB;
  839. ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config);
  840. if (ret)
  841. goto err;
  842. ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS,
  843. swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1);
  844. if (ret) {
  845. dev_err(scomp->dev, "Parsing gain tokens failed\n");
  846. goto err;
  847. }
  848. dev_dbg(scomp->dev,
  849. "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n",
  850. swidget->widget->name, gain->data.params.curve_type,
  851. gain->data.params.curve_duration_l, gain->data.params.init_val);
  852. ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
  853. if (ret)
  854. goto err;
  855. sof_ipc4_widget_update_kcontrol_module_id(swidget);
  856. return 0;
  857. err:
  858. sof_ipc4_free_audio_fmt(&gain->available_fmt);
  859. kfree(gain);
  860. swidget->private = NULL;
  861. return ret;
  862. }
  863. static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget)
  864. {
  865. struct sof_ipc4_gain *gain = swidget->private;
  866. if (!gain)
  867. return;
  868. sof_ipc4_free_audio_fmt(&gain->available_fmt);
  869. kfree(swidget->private);
  870. swidget->private = NULL;
  871. }
  872. static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
  873. {
  874. struct snd_soc_component *scomp = swidget->scomp;
  875. struct sof_ipc4_mixer *mixer;
  876. int ret;
  877. dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  878. mixer = kzalloc_obj(*mixer);
  879. if (!mixer)
  880. return -ENOMEM;
  881. swidget->private = mixer;
  882. ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt,
  883. &mixer->base_config);
  884. if (ret)
  885. goto err;
  886. ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg);
  887. if (ret)
  888. goto err;
  889. return 0;
  890. err:
  891. sof_ipc4_free_audio_fmt(&mixer->available_fmt);
  892. kfree(mixer);
  893. swidget->private = NULL;
  894. return ret;
  895. }
  896. static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
  897. {
  898. struct snd_soc_component *scomp = swidget->scomp;
  899. struct snd_sof_pipeline *spipe = swidget->spipe;
  900. struct sof_ipc4_src *src;
  901. int ret;
  902. dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  903. src = kzalloc_obj(*src);
  904. if (!src)
  905. return -ENOMEM;
  906. swidget->private = src;
  907. ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt,
  908. &src->data.base_config);
  909. if (ret)
  910. goto err;
  911. ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples,
  912. swidget->num_tuples, sizeof(*src), 1);
  913. if (ret) {
  914. dev_err(scomp->dev, "Parsing SRC tokens failed\n");
  915. goto err;
  916. }
  917. spipe->core_mask |= BIT(swidget->core);
  918. dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate);
  919. ret = sof_ipc4_widget_setup_msg(swidget, &src->msg);
  920. if (ret)
  921. goto err;
  922. return 0;
  923. err:
  924. sof_ipc4_free_audio_fmt(&src->available_fmt);
  925. kfree(src);
  926. swidget->private = NULL;
  927. return ret;
  928. }
  929. static int sof_ipc4_widget_setup_comp_asrc(struct snd_sof_widget *swidget)
  930. {
  931. struct snd_soc_component *scomp = swidget->scomp;
  932. struct snd_sof_pipeline *spipe = swidget->spipe;
  933. struct sof_ipc4_asrc *asrc;
  934. int ret;
  935. dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  936. asrc = kzalloc_obj(*asrc);
  937. if (!asrc)
  938. return -ENOMEM;
  939. swidget->private = asrc;
  940. ret = sof_ipc4_get_audio_fmt(scomp, swidget, &asrc->available_fmt,
  941. &asrc->data.base_config);
  942. if (ret)
  943. goto err;
  944. ret = sof_update_ipc_object(scomp, &asrc->data, SOF_ASRC_TOKENS, swidget->tuples,
  945. swidget->num_tuples, sizeof(*asrc), 1);
  946. if (ret) {
  947. dev_err(scomp->dev, "Parsing ASRC tokens failed\n");
  948. goto err;
  949. }
  950. spipe->core_mask |= BIT(swidget->core);
  951. dev_dbg(scomp->dev, "ASRC sink rate %d, mode 0x%08x\n",
  952. asrc->data.out_freq, asrc->data.asrc_mode);
  953. ret = sof_ipc4_widget_setup_msg(swidget, &asrc->msg);
  954. if (ret)
  955. goto err;
  956. return 0;
  957. err:
  958. sof_ipc4_free_audio_fmt(&asrc->available_fmt);
  959. kfree(asrc);
  960. swidget->private = NULL;
  961. return ret;
  962. }
  963. static void sof_ipc4_widget_free_comp_src(struct snd_sof_widget *swidget)
  964. {
  965. struct sof_ipc4_src *src = swidget->private;
  966. if (!src)
  967. return;
  968. sof_ipc4_free_audio_fmt(&src->available_fmt);
  969. kfree(swidget->private);
  970. swidget->private = NULL;
  971. }
  972. static void sof_ipc4_widget_free_comp_asrc(struct snd_sof_widget *swidget)
  973. {
  974. struct sof_ipc4_asrc *asrc = swidget->private;
  975. if (!asrc)
  976. return;
  977. sof_ipc4_free_audio_fmt(&asrc->available_fmt);
  978. kfree(swidget->private);
  979. swidget->private = NULL;
  980. }
  981. static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget)
  982. {
  983. struct sof_ipc4_mixer *mixer = swidget->private;
  984. if (!mixer)
  985. return;
  986. sof_ipc4_free_audio_fmt(&mixer->available_fmt);
  987. kfree(swidget->private);
  988. swidget->private = NULL;
  989. }
  990. /*
  991. * Add the process modules support. The process modules are defined as snd_soc_dapm_effect modules.
  992. */
  993. static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
  994. {
  995. struct snd_soc_component *scomp = swidget->scomp;
  996. struct sof_ipc4_fw_module *fw_module;
  997. struct snd_sof_pipeline *spipe = swidget->spipe;
  998. struct sof_ipc4_process *process;
  999. void *cfg;
  1000. int ret;
  1001. process = kzalloc_obj(*process);
  1002. if (!process)
  1003. return -ENOMEM;
  1004. swidget->private = process;
  1005. ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt,
  1006. &process->base_config);
  1007. if (ret)
  1008. goto err;
  1009. ret = sof_ipc4_widget_setup_msg(swidget, &process->msg);
  1010. if (ret)
  1011. goto err;
  1012. /* parse process init module payload config type from module info */
  1013. fw_module = swidget->module_info;
  1014. process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK,
  1015. fw_module->man4_module_entry.type);
  1016. process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg);
  1017. /* allocate memory for base config extension if needed */
  1018. if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
  1019. struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
  1020. u32 ext_size = struct_size(base_cfg_ext, pin_formats,
  1021. size_add(swidget->num_input_pins,
  1022. swidget->num_output_pins));
  1023. base_cfg_ext = kzalloc(ext_size, GFP_KERNEL);
  1024. if (!base_cfg_ext) {
  1025. ret = -ENOMEM;
  1026. goto free_available_fmt;
  1027. }
  1028. base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins;
  1029. base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins;
  1030. process->base_config_ext = base_cfg_ext;
  1031. process->base_config_ext_size = ext_size;
  1032. process->ipc_config_size += ext_size;
  1033. }
  1034. cfg = kzalloc(process->ipc_config_size, GFP_KERNEL);
  1035. if (!cfg) {
  1036. ret = -ENOMEM;
  1037. goto free_base_cfg_ext;
  1038. }
  1039. process->ipc_config_data = cfg;
  1040. sof_ipc4_widget_update_kcontrol_module_id(swidget);
  1041. /* set pipeline core mask to keep track of the core the module is scheduled to run on */
  1042. spipe->core_mask |= BIT(swidget->core);
  1043. return 0;
  1044. free_base_cfg_ext:
  1045. kfree(process->base_config_ext);
  1046. process->base_config_ext = NULL;
  1047. free_available_fmt:
  1048. sof_ipc4_free_audio_fmt(&process->available_fmt);
  1049. err:
  1050. kfree(process);
  1051. swidget->private = NULL;
  1052. return ret;
  1053. }
  1054. static void sof_ipc4_widget_free_comp_process(struct snd_sof_widget *swidget)
  1055. {
  1056. struct sof_ipc4_process *process = swidget->private;
  1057. if (!process)
  1058. return;
  1059. kfree(process->ipc_config_data);
  1060. kfree(process->base_config_ext);
  1061. sof_ipc4_free_audio_fmt(&process->available_fmt);
  1062. kfree(swidget->private);
  1063. swidget->private = NULL;
  1064. }
  1065. static void
  1066. sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
  1067. struct sof_ipc4_base_module_cfg *base_config)
  1068. {
  1069. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  1070. struct snd_sof_widget *pipe_widget;
  1071. struct sof_ipc4_pipeline *pipeline;
  1072. int task_mem, queue_mem;
  1073. int ibs, bss, total;
  1074. ibs = base_config->ibs;
  1075. bss = base_config->is_pages;
  1076. task_mem = SOF_IPC4_PIPELINE_OBJECT_SIZE;
  1077. task_mem += SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE + bss;
  1078. if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) {
  1079. task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_LL_TASK_OBJECT_SIZE);
  1080. task_mem += SOF_IPC4_FW_MAX_QUEUE_COUNT * SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE;
  1081. task_mem += SOF_IPC4_LL_TASK_LIST_ITEM_SIZE;
  1082. } else {
  1083. task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_DP_TASK_OBJECT_SIZE);
  1084. task_mem += SOF_IPC4_DP_TASK_LIST_SIZE;
  1085. }
  1086. ibs = SOF_IPC4_FW_ROUNDUP(ibs);
  1087. queue_mem = SOF_IPC4_FW_MAX_QUEUE_COUNT * (SOF_IPC4_DATA_QUEUE_OBJECT_SIZE + ibs);
  1088. total = SOF_IPC4_FW_PAGE(task_mem + queue_mem);
  1089. pipe_widget = swidget->spipe->pipe_widget;
  1090. pipeline = pipe_widget->private;
  1091. pipeline->mem_usage += total;
  1092. /* Update base_config->cpc from the module manifest */
  1093. sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config);
  1094. if (ignore_cpc) {
  1095. dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n",
  1096. swidget->widget->name, base_config->ibs, base_config->obs,
  1097. base_config->cpc);
  1098. base_config->cpc = 0;
  1099. } else {
  1100. dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n",
  1101. swidget->widget->name, base_config->ibs, base_config->obs,
  1102. base_config->cpc);
  1103. }
  1104. }
  1105. static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev,
  1106. struct snd_sof_widget *swidget)
  1107. {
  1108. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  1109. int max_instances = fw_module->man4_module_entry.instance_max_count;
  1110. swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL);
  1111. if (swidget->instance_id < 0) {
  1112. dev_err(sdev->dev, "failed to assign instance id for widget %s",
  1113. swidget->widget->name);
  1114. return swidget->instance_id;
  1115. }
  1116. return 0;
  1117. }
  1118. static u32 sof_ipc4_fmt_cfg_to_type(u32 fmt_cfg)
  1119. {
  1120. /* Fetch the sample type from the fmt for 8 and 32 bit formats */
  1121. u32 __bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt_cfg);
  1122. if (__bits == 8 || __bits == 32)
  1123. return SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE(fmt_cfg);
  1124. /*
  1125. * Return LSB integer type for 20 and 24 formats as the firmware is
  1126. * handling the LSB/MSB alignment internally, for the kernel this
  1127. * should not be taken into account, we treat them as LSB to match with
  1128. * the format we support on the PCM side.
  1129. */
  1130. return SOF_IPC4_TYPE_LSB_INTEGER;
  1131. }
  1132. /* update hw_params based on the audio stream format */
  1133. static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params,
  1134. struct sof_ipc4_audio_format *fmt, u32 param_to_update)
  1135. {
  1136. struct snd_interval *i;
  1137. if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) {
  1138. int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1139. int type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
  1140. snd_pcm_format_t snd_fmt;
  1141. struct snd_mask *m;
  1142. switch (valid_bits) {
  1143. case 8:
  1144. switch (type) {
  1145. case SOF_IPC4_TYPE_A_LAW:
  1146. snd_fmt = SNDRV_PCM_FORMAT_A_LAW;
  1147. break;
  1148. case SOF_IPC4_TYPE_MU_LAW:
  1149. snd_fmt = SNDRV_PCM_FORMAT_MU_LAW;
  1150. break;
  1151. case SOF_IPC4_TYPE_UNSIGNED_INTEGER:
  1152. snd_fmt = SNDRV_PCM_FORMAT_U8;
  1153. break;
  1154. default:
  1155. dev_err(sdev->dev, "Unsupported PCM 8-bit IPC4 type %d\n", type);
  1156. return -EINVAL;
  1157. }
  1158. break;
  1159. case 16:
  1160. snd_fmt = SNDRV_PCM_FORMAT_S16_LE;
  1161. break;
  1162. case 24:
  1163. snd_fmt = SNDRV_PCM_FORMAT_S24_LE;
  1164. break;
  1165. case 32:
  1166. switch (type) {
  1167. case SOF_IPC4_TYPE_LSB_INTEGER:
  1168. snd_fmt = SNDRV_PCM_FORMAT_S32_LE;
  1169. break;
  1170. case SOF_IPC4_TYPE_FLOAT:
  1171. snd_fmt = SNDRV_PCM_FORMAT_FLOAT_LE;
  1172. break;
  1173. default:
  1174. dev_err(sdev->dev, "Unsupported PCM 32-bit IPC4 type %d\n", type);
  1175. return -EINVAL;
  1176. }
  1177. break;
  1178. default:
  1179. dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits);
  1180. return -EINVAL;
  1181. }
  1182. m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  1183. snd_mask_none(m);
  1184. snd_mask_set_format(m, snd_fmt);
  1185. }
  1186. if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_RATE)) {
  1187. unsigned int rate = fmt->sampling_frequency;
  1188. i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
  1189. i->min = rate;
  1190. i->max = rate;
  1191. }
  1192. if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_CHANNELS)) {
  1193. unsigned int channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1194. i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
  1195. i->min = channels;
  1196. i->max = channels;
  1197. }
  1198. return 0;
  1199. }
  1200. static bool sof_ipc4_is_single_format(struct snd_sof_dev *sdev,
  1201. struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
  1202. {
  1203. struct sof_ipc4_audio_format *fmt;
  1204. u32 rate, channels, valid_bits;
  1205. int i;
  1206. fmt = &pin_fmts[0].audio_fmt;
  1207. rate = fmt->sampling_frequency;
  1208. channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1209. valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1210. /* check if all output formats in topology are the same */
  1211. for (i = 1; i < pin_fmts_size; i++) {
  1212. u32 _rate, _channels, _valid_bits;
  1213. fmt = &pin_fmts[i].audio_fmt;
  1214. _rate = fmt->sampling_frequency;
  1215. _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1216. _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1217. if (_rate != rate || _channels != channels || _valid_bits != valid_bits)
  1218. return false;
  1219. }
  1220. return true;
  1221. }
  1222. static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
  1223. struct snd_sof_widget *swidget,
  1224. struct sof_ipc4_base_module_cfg *base_config,
  1225. struct sof_ipc4_available_audio_format *available_fmt,
  1226. u32 out_ref_rate, u32 out_ref_channels,
  1227. u32 out_ref_valid_bits, u32 out_ref_type)
  1228. {
  1229. struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts;
  1230. u32 pin_fmts_size = available_fmt->num_output_formats;
  1231. bool single_format;
  1232. int i = 0;
  1233. if (!pin_fmts_size) {
  1234. dev_err(sdev->dev, "no output formats for %s\n",
  1235. swidget->widget->name);
  1236. return -EINVAL;
  1237. }
  1238. single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size);
  1239. /* pick the first format if there's only one available or if all formats are the same */
  1240. if (single_format)
  1241. goto out_fmt;
  1242. /*
  1243. * if there are multiple output formats, then choose the output format that matches
  1244. * the reference params
  1245. */
  1246. for (i = 0; i < pin_fmts_size; i++) {
  1247. struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt;
  1248. u32 _out_rate, _out_channels, _out_valid_bits, _out_type;
  1249. _out_rate = fmt->sampling_frequency;
  1250. _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1251. _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1252. _out_type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
  1253. if (_out_rate == out_ref_rate && _out_channels == out_ref_channels &&
  1254. _out_valid_bits == out_ref_valid_bits && _out_type == out_ref_type)
  1255. goto out_fmt;
  1256. }
  1257. dev_err(sdev->dev,
  1258. "%s: Unsupported audio format: %uHz, %ubit, %u channels, type: %d\n",
  1259. __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels,
  1260. out_ref_type);
  1261. return -EINVAL;
  1262. out_fmt:
  1263. base_config->obs = pin_fmts[i].buffer_size;
  1264. return i;
  1265. }
  1266. static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
  1267. {
  1268. switch (params_format(params)) {
  1269. case SNDRV_PCM_FORMAT_U8:
  1270. case SNDRV_PCM_FORMAT_MU_LAW:
  1271. case SNDRV_PCM_FORMAT_A_LAW:
  1272. return 8;
  1273. case SNDRV_PCM_FORMAT_S16_LE:
  1274. return 16;
  1275. case SNDRV_PCM_FORMAT_S24_LE:
  1276. return 24;
  1277. case SNDRV_PCM_FORMAT_S32_LE:
  1278. return 32;
  1279. case SNDRV_PCM_FORMAT_FLOAT_LE:
  1280. return 32;
  1281. default:
  1282. dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params));
  1283. return -EINVAL;
  1284. }
  1285. }
  1286. static int sof_ipc4_get_sample_type(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params)
  1287. {
  1288. switch (params_format(params)) {
  1289. case SNDRV_PCM_FORMAT_A_LAW:
  1290. return SOF_IPC4_TYPE_A_LAW;
  1291. case SNDRV_PCM_FORMAT_MU_LAW:
  1292. return SOF_IPC4_TYPE_MU_LAW;
  1293. case SNDRV_PCM_FORMAT_U8:
  1294. return SOF_IPC4_TYPE_UNSIGNED_INTEGER;
  1295. case SNDRV_PCM_FORMAT_S16_LE:
  1296. case SNDRV_PCM_FORMAT_S24_LE:
  1297. case SNDRV_PCM_FORMAT_S32_LE:
  1298. case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
  1299. return SOF_IPC4_TYPE_LSB_INTEGER;
  1300. case SNDRV_PCM_FORMAT_FLOAT_LE:
  1301. return SOF_IPC4_TYPE_FLOAT;
  1302. default:
  1303. dev_err(sdev->dev, "invalid pcm sample type %d\n", params_format(params));
  1304. return -EINVAL;
  1305. }
  1306. }
  1307. static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
  1308. struct snd_sof_widget *swidget,
  1309. struct sof_ipc4_base_module_cfg *base_config,
  1310. struct snd_pcm_hw_params *params,
  1311. struct sof_ipc4_available_audio_format *available_fmt)
  1312. {
  1313. struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts;
  1314. u32 pin_fmts_size = available_fmt->num_input_formats;
  1315. u32 valid_bits;
  1316. u32 channels;
  1317. u32 rate;
  1318. u32 type;
  1319. bool single_format;
  1320. int sample_valid_bits;
  1321. int sample_type;
  1322. int i = 0;
  1323. if (!pin_fmts_size) {
  1324. dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name);
  1325. return -EINVAL;
  1326. }
  1327. single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size);
  1328. if (single_format)
  1329. goto in_fmt;
  1330. sample_valid_bits = sof_ipc4_get_valid_bits(sdev, params);
  1331. if (sample_valid_bits < 0)
  1332. return sample_valid_bits;
  1333. sample_type = sof_ipc4_get_sample_type(sdev, params);
  1334. if (sample_type < 0)
  1335. return sample_type;
  1336. /*
  1337. * Search supported input audio formats with pin index 0 to match rate, channels and
  1338. * sample_valid_bits from reference params
  1339. */
  1340. for (i = 0; i < pin_fmts_size; i++) {
  1341. struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt;
  1342. if (pin_fmts[i].pin_index)
  1343. continue;
  1344. rate = fmt->sampling_frequency;
  1345. channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1346. valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1347. type = sof_ipc4_fmt_cfg_to_type(fmt->fmt_cfg);
  1348. if (params_rate(params) == rate && params_channels(params) == channels &&
  1349. sample_valid_bits == valid_bits && sample_type == type)
  1350. break;
  1351. }
  1352. if (i == pin_fmts_size) {
  1353. dev_err(sdev->dev,
  1354. "%s: Unsupported audio format: %uHz, %ubit, %u channels, type: %d\n",
  1355. __func__, params_rate(params), sample_valid_bits,
  1356. params_channels(params), sample_type);
  1357. return -EINVAL;
  1358. }
  1359. in_fmt:
  1360. /* copy input format */
  1361. memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt,
  1362. sizeof(struct sof_ipc4_audio_format));
  1363. /* set base_cfg ibs/obs */
  1364. base_config->ibs = pin_fmts[i].buffer_size;
  1365. return i;
  1366. }
  1367. static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
  1368. {
  1369. struct sof_ipc4_copier *ipc4_copier = NULL;
  1370. struct snd_sof_widget *pipe_widget;
  1371. struct sof_ipc4_pipeline *pipeline;
  1372. /* reset pipeline memory usage */
  1373. pipe_widget = swidget->spipe->pipe_widget;
  1374. pipeline = pipe_widget->private;
  1375. pipeline->mem_usage = 0;
  1376. if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) {
  1377. if (pipeline->use_chain_dma) {
  1378. pipeline->msg.primary = 0;
  1379. pipeline->msg.extension = 0;
  1380. }
  1381. ipc4_copier = swidget->private;
  1382. } else if (WIDGET_IS_DAI(swidget->id)) {
  1383. struct snd_sof_dai *dai = swidget->private;
  1384. ipc4_copier = dai->private;
  1385. if (pipeline->use_chain_dma) {
  1386. /*
  1387. * Preserve the DMA Link ID and clear other bits since
  1388. * the DMA Link ID is only configured once during
  1389. * dai_config, other fields are expected to be 0 for
  1390. * re-configuration
  1391. */
  1392. pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK;
  1393. pipeline->msg.extension = 0;
  1394. }
  1395. if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
  1396. struct sof_ipc4_alh_configuration_blob *blob;
  1397. unsigned int group_id;
  1398. blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
  1399. if (blob->alh_cfg.device_count > 1) {
  1400. group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) -
  1401. ALH_MULTI_GTW_BASE;
  1402. ida_free(&alh_group_ida, group_id);
  1403. }
  1404. }
  1405. }
  1406. if (ipc4_copier) {
  1407. kfree(ipc4_copier->ipc_config_data);
  1408. ipc4_copier->ipc_config_data = NULL;
  1409. ipc4_copier->ipc_config_size = 0;
  1410. }
  1411. }
  1412. #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
  1413. static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
  1414. int *sample_rate, int *channel_count, int *bit_depth)
  1415. {
  1416. struct snd_soc_tplg_hw_config *hw_config;
  1417. struct snd_sof_dai_link *slink;
  1418. bool dai_link_found = false;
  1419. bool hw_cfg_found = false;
  1420. int i;
  1421. /* get current hw_config from link */
  1422. list_for_each_entry(slink, &sdev->dai_link_list, list) {
  1423. if (!strcmp(slink->link->name, dai->name)) {
  1424. dai_link_found = true;
  1425. break;
  1426. }
  1427. }
  1428. if (!dai_link_found) {
  1429. dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name);
  1430. return -EINVAL;
  1431. }
  1432. for (i = 0; i < slink->num_hw_configs; i++) {
  1433. hw_config = &slink->hw_configs[i];
  1434. if (dai->current_config == le32_to_cpu(hw_config->id)) {
  1435. hw_cfg_found = true;
  1436. break;
  1437. }
  1438. }
  1439. if (!hw_cfg_found) {
  1440. dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__,
  1441. dai->name);
  1442. return -EINVAL;
  1443. }
  1444. *bit_depth = le32_to_cpu(hw_config->tdm_slot_width);
  1445. *channel_count = le32_to_cpu(hw_config->tdm_slots);
  1446. *sample_rate = le32_to_cpu(hw_config->fsync_rate);
  1447. dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n",
  1448. *sample_rate, *bit_depth, *channel_count);
  1449. return 0;
  1450. }
  1451. static int
  1452. snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
  1453. bool single_bitdepth,
  1454. struct snd_pcm_hw_params *params, u32 dai_index,
  1455. u32 linktype, u8 dir, u32 **dst, u32 *len)
  1456. {
  1457. struct sof_ipc4_fw_data *ipc4_data = sdev->private;
  1458. struct nhlt_specific_cfg *cfg;
  1459. int sample_rate, channel_count;
  1460. bool format_change = false;
  1461. int bit_depth, ret;
  1462. u32 nhlt_type;
  1463. int dev_type = 0;
  1464. /* convert to NHLT type */
  1465. switch (linktype) {
  1466. case SOF_DAI_INTEL_DMIC:
  1467. nhlt_type = NHLT_LINK_DMIC;
  1468. channel_count = params_channels(params);
  1469. sample_rate = params_rate(params);
  1470. bit_depth = params_width(params);
  1471. /* Prefer 32-bit blob if copier supports multiple formats */
  1472. if (bit_depth <= 16 && !single_bitdepth) {
  1473. dev_dbg(sdev->dev, "Looking for 32-bit blob first for DMIC\n");
  1474. format_change = true;
  1475. bit_depth = 32;
  1476. }
  1477. break;
  1478. case SOF_DAI_INTEL_SSP:
  1479. nhlt_type = NHLT_LINK_SSP;
  1480. ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count,
  1481. &bit_depth);
  1482. if (ret < 0)
  1483. return ret;
  1484. /*
  1485. * We need to know the type of the external device attached to a SSP
  1486. * port to retrieve the blob from NHLT. However, device type is not
  1487. * specified in topology.
  1488. * Query the type for the port and then pass that information back
  1489. * to the blob lookup function.
  1490. */
  1491. dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt,
  1492. dai_index);
  1493. if (dev_type < 0)
  1494. return dev_type;
  1495. break;
  1496. default:
  1497. return 0;
  1498. }
  1499. dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n",
  1500. dai_index, nhlt_type, dir, dev_type);
  1501. /* find NHLT blob with matching params */
  1502. cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type,
  1503. bit_depth, bit_depth, channel_count, sample_rate,
  1504. dir, dev_type);
  1505. if (!cfg) {
  1506. bool get_new_blob = false;
  1507. if (format_change) {
  1508. /*
  1509. * The 32-bit blob was not found in NHLT table, try to
  1510. * look for 16-bit for DMIC or based on the params for
  1511. * SSP
  1512. */
  1513. if (linktype == SOF_DAI_INTEL_DMIC) {
  1514. bit_depth = 16;
  1515. if (params_width(params) == 16)
  1516. format_change = false;
  1517. } else {
  1518. bit_depth = params_width(params);
  1519. format_change = false;
  1520. }
  1521. get_new_blob = true;
  1522. } else if (linktype == SOF_DAI_INTEL_DMIC && !single_bitdepth) {
  1523. /*
  1524. * The requested 32-bit blob (no format change for the
  1525. * blob request) was not found in NHLT table, try to
  1526. * look for 16-bit blob if the copier supports multiple
  1527. * formats
  1528. */
  1529. bit_depth = 16;
  1530. format_change = true;
  1531. get_new_blob = true;
  1532. }
  1533. if (get_new_blob) {
  1534. cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt,
  1535. dai_index, nhlt_type,
  1536. bit_depth, bit_depth,
  1537. channel_count, sample_rate,
  1538. dir, dev_type);
  1539. if (cfg)
  1540. goto out;
  1541. }
  1542. dev_err(sdev->dev,
  1543. "no matching blob for sample rate: %d sample width: %d channels: %d\n",
  1544. sample_rate, bit_depth, channel_count);
  1545. return -EINVAL;
  1546. }
  1547. out:
  1548. /* config length should be in dwords */
  1549. *len = cfg->size >> 2;
  1550. *dst = (u32 *)cfg->caps;
  1551. if (format_change || params_format(params) == SNDRV_PCM_FORMAT_FLOAT_LE) {
  1552. /*
  1553. * Update the params to reflect that different blob was loaded
  1554. * instead of the requested bit depth (16 -> 32 or 32 -> 16).
  1555. * This information is going to be used by the caller to find
  1556. * matching copier format on the dai side.
  1557. */
  1558. struct snd_mask *m;
  1559. m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  1560. snd_mask_none(m);
  1561. if (bit_depth == 16)
  1562. snd_mask_set_format(m, SNDRV_PCM_FORMAT_S16_LE);
  1563. else
  1564. snd_mask_set_format(m, SNDRV_PCM_FORMAT_S32_LE);
  1565. }
  1566. return 0;
  1567. }
  1568. #else
  1569. static int
  1570. snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
  1571. bool single_bitdepth,
  1572. struct snd_pcm_hw_params *params, u32 dai_index,
  1573. u32 linktype, u8 dir, u32 **dst, u32 *len)
  1574. {
  1575. return 0;
  1576. }
  1577. #endif
  1578. bool sof_ipc4_copier_is_single_bitdepth(struct snd_sof_dev *sdev,
  1579. struct sof_ipc4_pin_format *pin_fmts,
  1580. u32 pin_fmts_size)
  1581. {
  1582. struct sof_ipc4_audio_format *fmt;
  1583. u32 valid_bits;
  1584. int i;
  1585. fmt = &pin_fmts[0].audio_fmt;
  1586. valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1587. /* check if all formats in topology are the same */
  1588. for (i = 1; i < pin_fmts_size; i++) {
  1589. u32 _valid_bits;
  1590. fmt = &pin_fmts[i].audio_fmt;
  1591. _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1592. if (_valid_bits != valid_bits)
  1593. return false;
  1594. }
  1595. return true;
  1596. }
  1597. static int
  1598. sof_ipc4_adjust_params_to_dai_format(struct snd_sof_dev *sdev,
  1599. struct snd_pcm_hw_params *params,
  1600. struct sof_ipc4_pin_format *pin_fmts,
  1601. u32 pin_fmts_size)
  1602. {
  1603. u32 params_mask = BIT(SNDRV_PCM_HW_PARAM_RATE) |
  1604. BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
  1605. BIT(SNDRV_PCM_HW_PARAM_FORMAT);
  1606. struct sof_ipc4_audio_format *fmt;
  1607. u32 rate, channels, valid_bits;
  1608. int i;
  1609. fmt = &pin_fmts[0].audio_fmt;
  1610. rate = fmt->sampling_frequency;
  1611. channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1612. valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1613. /* check if parameters in topology defined formats are the same */
  1614. for (i = 1; i < pin_fmts_size; i++) {
  1615. u32 val;
  1616. fmt = &pin_fmts[i].audio_fmt;
  1617. if (params_mask & BIT(SNDRV_PCM_HW_PARAM_RATE)) {
  1618. val = fmt->sampling_frequency;
  1619. if (val != rate)
  1620. params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_RATE);
  1621. }
  1622. if (params_mask & BIT(SNDRV_PCM_HW_PARAM_CHANNELS)) {
  1623. val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
  1624. if (val != channels)
  1625. params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_CHANNELS);
  1626. }
  1627. if (params_mask & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) {
  1628. val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
  1629. if (val != valid_bits)
  1630. params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_FORMAT);
  1631. }
  1632. }
  1633. if (params_mask)
  1634. return sof_ipc4_update_hw_params(sdev, params,
  1635. &pin_fmts[0].audio_fmt,
  1636. params_mask);
  1637. return 0;
  1638. }
  1639. static int
  1640. sof_ipc4_prepare_dai_copier(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
  1641. struct snd_pcm_hw_params *params, int dir)
  1642. {
  1643. struct sof_ipc4_available_audio_format *available_fmt;
  1644. struct snd_pcm_hw_params dai_params = *params;
  1645. struct sof_ipc4_copier_data *copier_data;
  1646. struct sof_ipc4_pin_format *pin_fmts;
  1647. struct sof_ipc4_copier *ipc4_copier;
  1648. bool single_bitdepth;
  1649. u32 num_pin_fmts;
  1650. int ret;
  1651. ipc4_copier = dai->private;
  1652. copier_data = &ipc4_copier->data;
  1653. available_fmt = &ipc4_copier->available_fmt;
  1654. /*
  1655. * Fixup the params based on the format parameters of the DAI. If any
  1656. * of the RATE, CHANNELS, bit depth is static among the formats then
  1657. * narrow the params to only allow that specific parameter value.
  1658. */
  1659. if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
  1660. pin_fmts = available_fmt->output_pin_fmts;
  1661. num_pin_fmts = available_fmt->num_output_formats;
  1662. } else {
  1663. pin_fmts = available_fmt->input_pin_fmts;
  1664. num_pin_fmts = available_fmt->num_input_formats;
  1665. }
  1666. ret = sof_ipc4_adjust_params_to_dai_format(sdev, &dai_params, pin_fmts,
  1667. num_pin_fmts);
  1668. if (ret)
  1669. return ret;
  1670. single_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, pin_fmts,
  1671. num_pin_fmts);
  1672. ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, single_bitdepth,
  1673. &dai_params,
  1674. ipc4_copier->dai_index,
  1675. ipc4_copier->dai_type, dir,
  1676. &ipc4_copier->copier_config,
  1677. &copier_data->gtw_cfg.config_length);
  1678. /* Update the params to reflect the changes made in this function */
  1679. if (!ret)
  1680. *params = dai_params;
  1681. return ret;
  1682. }
  1683. static void sof_ipc4_host_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
  1684. struct snd_sof_platform_stream_params *platform_params)
  1685. {
  1686. struct sof_ipc4_copier *ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
  1687. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  1688. struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data;
  1689. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  1690. u32 host_dma_id = platform_params->stream_tag - 1;
  1691. if (pipeline->use_chain_dma) {
  1692. pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_HOST_ID_MASK;
  1693. pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id);
  1694. return;
  1695. }
  1696. copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
  1697. copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(host_dma_id);
  1698. }
  1699. static int
  1700. sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
  1701. struct snd_pcm_hw_params *fe_params,
  1702. struct snd_sof_platform_stream_params *platform_params,
  1703. struct snd_pcm_hw_params *pipeline_params, int dir)
  1704. {
  1705. struct sof_ipc4_available_audio_format *available_fmt;
  1706. struct snd_soc_component *scomp = swidget->scomp;
  1707. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  1708. struct sof_ipc4_copier_data *copier_data;
  1709. int input_fmt_index, output_fmt_index;
  1710. struct sof_ipc4_copier *ipc4_copier;
  1711. struct snd_pcm_hw_params *ref_params __free(kfree) = NULL;
  1712. struct snd_sof_dai *dai;
  1713. u32 gtw_cfg_config_length;
  1714. u32 dma_config_tlv_size = 0;
  1715. void **ipc_config_data;
  1716. int *ipc_config_size;
  1717. u32 **data;
  1718. int ipc_size, ret, out_ref_valid_bits;
  1719. u32 out_ref_rate, out_ref_channels, out_ref_type;
  1720. u32 deep_buffer_dma_ms = 0;
  1721. bool single_output_bitdepth;
  1722. int i;
  1723. switch (swidget->id) {
  1724. case snd_soc_dapm_aif_in:
  1725. case snd_soc_dapm_aif_out:
  1726. {
  1727. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  1728. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  1729. struct sof_ipc4_gtw_attributes *gtw_attr;
  1730. dev_dbg(sdev->dev,
  1731. "Host copier %s, type %d, ChainDMA: %s, stream_tag: %d\n",
  1732. swidget->widget->name, swidget->id,
  1733. str_yes_no(pipeline->use_chain_dma),
  1734. platform_params->stream_tag);
  1735. /* parse the deep buffer dma size */
  1736. ret = sof_update_ipc_object(scomp, &deep_buffer_dma_ms,
  1737. SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples,
  1738. swidget->num_tuples, sizeof(u32), 1);
  1739. if (ret) {
  1740. dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n",
  1741. swidget->widget->name);
  1742. return ret;
  1743. }
  1744. ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
  1745. gtw_attr = ipc4_copier->gtw_attr;
  1746. copier_data = &ipc4_copier->data;
  1747. available_fmt = &ipc4_copier->available_fmt;
  1748. if (pipeline->use_chain_dma) {
  1749. u32 host_dma_id;
  1750. u32 fifo_size;
  1751. host_dma_id = platform_params->stream_tag - 1;
  1752. pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id);
  1753. if (params_format(fe_params) == SNDRV_PCM_FORMAT_S16_LE)
  1754. pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK;
  1755. /* Set SCS bit for 8 and 16 bit formats */
  1756. if (params_physical_width(fe_params) <= 16)
  1757. pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK;
  1758. /*
  1759. * Despite its name the bitfield 'fifo_size' is used to define DMA buffer
  1760. * size. The expression calculates 2ms buffer size.
  1761. */
  1762. fifo_size = DIV_ROUND_UP((SOF_IPC4_CHAIN_DMA_BUF_SIZE_MS *
  1763. params_rate(fe_params) *
  1764. params_channels(fe_params) *
  1765. params_physical_width(fe_params)), 8000);
  1766. pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size);
  1767. /*
  1768. * Chain DMA does not support stream timestamping, but it
  1769. * can use the host side registers for delay calculation.
  1770. */
  1771. copier_data->gtw_cfg.node_id = SOF_IPC4_CHAIN_DMA_NODE_ID;
  1772. return 0;
  1773. }
  1774. /*
  1775. * Use the input_pin_fmts to match pcm params for playback and the output_pin_fmts
  1776. * for capture.
  1777. */
  1778. if (dir == SNDRV_PCM_STREAM_PLAYBACK)
  1779. ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL);
  1780. else
  1781. ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL);
  1782. if (!ref_params)
  1783. return -ENOMEM;
  1784. copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
  1785. copier_data->gtw_cfg.node_id |=
  1786. SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1);
  1787. /* set gateway attributes */
  1788. gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
  1789. break;
  1790. }
  1791. case snd_soc_dapm_dai_in:
  1792. case snd_soc_dapm_dai_out:
  1793. {
  1794. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  1795. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  1796. dev_dbg(sdev->dev, "Dai copier %s, type %d, ChainDMA: %s\n",
  1797. swidget->widget->name, swidget->id,
  1798. str_yes_no(pipeline->use_chain_dma));
  1799. if (pipeline->use_chain_dma)
  1800. return 0;
  1801. dai = swidget->private;
  1802. ipc4_copier = (struct sof_ipc4_copier *)dai->private;
  1803. copier_data = &ipc4_copier->data;
  1804. available_fmt = &ipc4_copier->available_fmt;
  1805. /*
  1806. * Use the fe_params as a base for the copier configuration.
  1807. * The ref_params might get updated to reflect what format is
  1808. * supported by the copier on the DAI side.
  1809. *
  1810. * In case of capture the ref_params returned will be used to
  1811. * find the input configuration of the copier.
  1812. */
  1813. ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL);
  1814. if (!ref_params)
  1815. return -ENOMEM;
  1816. ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir);
  1817. if (ret < 0)
  1818. return ret;
  1819. /*
  1820. * For playback the pipeline_params needs to be used to find the
  1821. * input configuration of the copier.
  1822. */
  1823. if (dir == SNDRV_PCM_STREAM_PLAYBACK)
  1824. memcpy(ref_params, pipeline_params, sizeof(*ref_params));
  1825. break;
  1826. }
  1827. case snd_soc_dapm_buffer:
  1828. {
  1829. dev_dbg(sdev->dev, "Module copier %s, type %d\n",
  1830. swidget->widget->name, swidget->id);
  1831. ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
  1832. copier_data = &ipc4_copier->data;
  1833. available_fmt = &ipc4_copier->available_fmt;
  1834. ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL);
  1835. if (!ref_params)
  1836. return -ENOMEM;
  1837. break;
  1838. }
  1839. default:
  1840. dev_err(sdev->dev, "unsupported type %d for copier %s",
  1841. swidget->id, swidget->widget->name);
  1842. return -EINVAL;
  1843. }
  1844. /* set input and output audio formats */
  1845. input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
  1846. &copier_data->base_config,
  1847. ref_params, available_fmt);
  1848. if (input_fmt_index < 0)
  1849. return input_fmt_index;
  1850. /* set the reference params for output format selection */
  1851. single_output_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev,
  1852. available_fmt->output_pin_fmts,
  1853. available_fmt->num_output_formats);
  1854. switch (swidget->id) {
  1855. case snd_soc_dapm_aif_in:
  1856. case snd_soc_dapm_dai_out:
  1857. case snd_soc_dapm_buffer:
  1858. {
  1859. struct sof_ipc4_audio_format *in_fmt;
  1860. in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
  1861. out_ref_rate = in_fmt->sampling_frequency;
  1862. out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
  1863. out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
  1864. if (!single_output_bitdepth)
  1865. out_ref_valid_bits =
  1866. SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
  1867. break;
  1868. }
  1869. case snd_soc_dapm_aif_out:
  1870. case snd_soc_dapm_dai_in:
  1871. out_ref_rate = params_rate(fe_params);
  1872. out_ref_channels = params_channels(fe_params);
  1873. ret = sof_ipc4_get_sample_type(sdev, fe_params);
  1874. if (ret < 0)
  1875. return ret;
  1876. out_ref_type = (u32)ret;
  1877. if (!single_output_bitdepth) {
  1878. out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
  1879. if (out_ref_valid_bits < 0)
  1880. return out_ref_valid_bits;
  1881. }
  1882. break;
  1883. default:
  1884. /*
  1885. * Unsupported type should be caught by the former switch default
  1886. * case, this should never happen in reality.
  1887. */
  1888. return -EINVAL;
  1889. }
  1890. /*
  1891. * if the output format is the same across all available output formats, choose
  1892. * that as the reference.
  1893. */
  1894. if (single_output_bitdepth) {
  1895. struct sof_ipc4_audio_format *out_fmt;
  1896. out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt;
  1897. out_ref_valid_bits =
  1898. SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg);
  1899. out_ref_type = sof_ipc4_fmt_cfg_to_type(out_fmt->fmt_cfg);
  1900. }
  1901. output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
  1902. &copier_data->base_config,
  1903. available_fmt, out_ref_rate,
  1904. out_ref_channels, out_ref_valid_bits,
  1905. out_ref_type);
  1906. if (output_fmt_index < 0)
  1907. return output_fmt_index;
  1908. /*
  1909. * Set the output format. Current topology defines pin 0 input and output formats in pairs.
  1910. * This assumes that the pin 0 formats are defined before all other pins.
  1911. * So pick the output audio format with the same index as the chosen
  1912. * input format. This logic will need to be updated when the format definitions
  1913. * in topology change.
  1914. */
  1915. memcpy(&copier_data->out_format,
  1916. &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt,
  1917. sizeof(struct sof_ipc4_audio_format));
  1918. switch (swidget->id) {
  1919. case snd_soc_dapm_dai_in:
  1920. case snd_soc_dapm_dai_out:
  1921. {
  1922. /*
  1923. * Only SOF_DAI_INTEL_ALH needs copier_data to set blob.
  1924. * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt
  1925. */
  1926. if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
  1927. struct sof_ipc4_alh_configuration_blob *blob;
  1928. struct sof_ipc4_dma_config *dma_config;
  1929. struct sof_ipc4_copier_data *alh_data;
  1930. struct sof_ipc4_copier *alh_copier;
  1931. struct snd_sof_widget *w;
  1932. u32 ch_count = 0;
  1933. u32 ch_mask = 0;
  1934. u32 ch_map;
  1935. u32 step;
  1936. u32 mask;
  1937. blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
  1938. blob->gw_attr.lp_buffer_alloc = 0;
  1939. /* Get channel_mask from ch_map */
  1940. ch_map = copier_data->base_config.audio_fmt.ch_map;
  1941. for (i = 0; ch_map; i++) {
  1942. if ((ch_map & 0xf) != 0xf) {
  1943. ch_mask |= BIT(i);
  1944. ch_count++;
  1945. }
  1946. ch_map >>= 4;
  1947. }
  1948. if (swidget->id == snd_soc_dapm_dai_in && ch_count == out_ref_channels) {
  1949. /*
  1950. * For playback DAI widgets where the channel number is equal to
  1951. * the output reference channels, set the step = 0 to ensure all
  1952. * the ch_mask is applied to all alh mappings.
  1953. */
  1954. mask = ch_mask;
  1955. step = 0;
  1956. } else {
  1957. step = ch_count / blob->alh_cfg.device_count;
  1958. mask = GENMASK(step - 1, 0);
  1959. }
  1960. /*
  1961. * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
  1962. * for all widgets with the same stream name
  1963. */
  1964. i = 0;
  1965. list_for_each_entry(w, &sdev->widget_list, list) {
  1966. u32 node_type;
  1967. if (!WIDGET_IS_DAI(w->id) || !w->widget->sname ||
  1968. strcmp(w->widget->sname, swidget->widget->sname))
  1969. continue;
  1970. dai = w->private;
  1971. if (dai->type != SOF_DAI_INTEL_ALH)
  1972. continue;
  1973. alh_copier = (struct sof_ipc4_copier *)dai->private;
  1974. alh_data = &alh_copier->data;
  1975. node_type = SOF_IPC4_GET_NODE_TYPE(alh_data->gtw_cfg.node_id);
  1976. blob->alh_cfg.mapping[i].device = SOF_IPC4_NODE_TYPE(node_type);
  1977. blob->alh_cfg.mapping[i].device |=
  1978. SOF_IPC4_NODE_INDEX(alh_copier->dai_index);
  1979. /*
  1980. * The mapping[i] device in ALH blob should be the same as the
  1981. * dma_config_tlv[i] mapping device if a dma_config_tlv is present.
  1982. * The device id will be used for DMA tlv mapping purposes.
  1983. */
  1984. if (ipc4_copier->dma_config_tlv[i].length) {
  1985. dma_config = &ipc4_copier->dma_config_tlv[i].dma_config;
  1986. blob->alh_cfg.mapping[i].device =
  1987. dma_config->dma_stream_channel_map.mapping[0].device;
  1988. }
  1989. /*
  1990. * Set the same channel mask if the widget channel count is the same
  1991. * as the FE channels for playback as the audio data is duplicated
  1992. * for all speakers in this case. Otherwise, split the channels
  1993. * among the aggregated DAIs. For example, with 4 channels on 2
  1994. * aggregated DAIs, the channel_mask should be 0x3 and 0xc for the
  1995. * two DAI's.
  1996. * The channel masks used depend on the cpu_dais used in the
  1997. * dailink at the machine driver level, which actually comes from
  1998. * the tables in soc_acpi files depending on the _ADR and devID
  1999. * registers for each codec.
  2000. */
  2001. blob->alh_cfg.mapping[i].channel_mask = mask << (step * i);
  2002. i++;
  2003. }
  2004. if (blob->alh_cfg.device_count > 1) {
  2005. int group_id;
  2006. group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1,
  2007. GFP_KERNEL);
  2008. if (group_id < 0)
  2009. return group_id;
  2010. /* add multi-gateway base */
  2011. group_id += ALH_MULTI_GTW_BASE;
  2012. copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
  2013. copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id);
  2014. }
  2015. }
  2016. }
  2017. }
  2018. /* modify the input params for the next widget */
  2019. ret = sof_ipc4_update_hw_params(sdev, pipeline_params,
  2020. &copier_data->out_format,
  2021. BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
  2022. BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
  2023. BIT(SNDRV_PCM_HW_PARAM_RATE));
  2024. if (ret)
  2025. return ret;
  2026. /*
  2027. * Set the gateway dma_buffer_size to 2ms buffer size to meet the FW expectation. In the
  2028. * deep buffer case, set the dma_buffer_size depending on the deep_buffer_dma_ms set
  2029. * in topology.
  2030. */
  2031. switch (swidget->id) {
  2032. case snd_soc_dapm_dai_in:
  2033. copier_data->gtw_cfg.dma_buffer_size =
  2034. SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs;
  2035. break;
  2036. case snd_soc_dapm_aif_in:
  2037. copier_data->gtw_cfg.dma_buffer_size =
  2038. max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
  2039. copier_data->base_config.ibs;
  2040. dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)",
  2041. swidget->widget->name,
  2042. deep_buffer_dma_ms ? " (using Deep Buffer)" : "",
  2043. max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms),
  2044. copier_data->gtw_cfg.dma_buffer_size);
  2045. break;
  2046. case snd_soc_dapm_dai_out:
  2047. case snd_soc_dapm_aif_out:
  2048. copier_data->gtw_cfg.dma_buffer_size =
  2049. SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs;
  2050. break;
  2051. default:
  2052. break;
  2053. }
  2054. data = &ipc4_copier->copier_config;
  2055. ipc_config_size = &ipc4_copier->ipc_config_size;
  2056. ipc_config_data = &ipc4_copier->ipc_config_data;
  2057. /* config_length is DWORD based */
  2058. gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4;
  2059. ipc_size = sizeof(*copier_data) + gtw_cfg_config_length;
  2060. dma_config_tlv_size = 0;
  2061. for (i = 0; i < SOF_IPC4_DMA_DEVICE_MAX_COUNT; i++) {
  2062. if (ipc4_copier->dma_config_tlv[i].type != SOF_IPC4_GTW_DMA_CONFIG_ID)
  2063. continue;
  2064. dma_config_tlv_size += ipc4_copier->dma_config_tlv[i].length;
  2065. dma_config_tlv_size +=
  2066. ipc4_copier->dma_config_tlv[i].dma_config.dma_priv_config_size;
  2067. dma_config_tlv_size += (sizeof(ipc4_copier->dma_config_tlv[i]) -
  2068. sizeof(ipc4_copier->dma_config_tlv[i].dma_config));
  2069. }
  2070. if (dma_config_tlv_size) {
  2071. ipc_size += dma_config_tlv_size;
  2072. /* we also need to increase the size at the gtw level */
  2073. copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4;
  2074. }
  2075. dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size);
  2076. *ipc_config_data = kzalloc(ipc_size, GFP_KERNEL);
  2077. if (!*ipc_config_data)
  2078. return -ENOMEM;
  2079. *ipc_config_size = ipc_size;
  2080. sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt,
  2081. input_fmt_index, output_fmt_index);
  2082. /* update pipeline memory usage */
  2083. sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);
  2084. /* copy IPC data */
  2085. memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
  2086. if (gtw_cfg_config_length)
  2087. memcpy(*ipc_config_data + sizeof(*copier_data),
  2088. *data, gtw_cfg_config_length);
  2089. /* add DMA Config TLV, if configured */
  2090. if (dma_config_tlv_size)
  2091. memcpy(*ipc_config_data + sizeof(*copier_data) +
  2092. gtw_cfg_config_length,
  2093. &ipc4_copier->dma_config_tlv, dma_config_tlv_size);
  2094. /*
  2095. * Restore gateway config length now that IPC payload is prepared. This avoids
  2096. * counting the DMA CONFIG TLV multiple times
  2097. */
  2098. copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4;
  2099. return 0;
  2100. }
  2101. static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
  2102. struct snd_pcm_hw_params *fe_params,
  2103. struct snd_sof_platform_stream_params *platform_params,
  2104. struct snd_pcm_hw_params *pipeline_params, int dir)
  2105. {
  2106. struct snd_soc_component *scomp = swidget->scomp;
  2107. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2108. struct sof_ipc4_gain *gain = swidget->private;
  2109. struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt;
  2110. struct sof_ipc4_audio_format *in_fmt;
  2111. u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
  2112. int input_fmt_index, output_fmt_index;
  2113. input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
  2114. &gain->data.base_config,
  2115. pipeline_params,
  2116. available_fmt);
  2117. if (input_fmt_index < 0)
  2118. return input_fmt_index;
  2119. in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
  2120. out_ref_rate = in_fmt->sampling_frequency;
  2121. out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
  2122. out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
  2123. out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
  2124. output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
  2125. &gain->data.base_config,
  2126. available_fmt,
  2127. out_ref_rate,
  2128. out_ref_channels,
  2129. out_ref_valid_bits,
  2130. out_ref_type);
  2131. if (output_fmt_index < 0)
  2132. return output_fmt_index;
  2133. sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt,
  2134. input_fmt_index, output_fmt_index);
  2135. /* update pipeline memory usage */
  2136. sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config);
  2137. return 0;
  2138. }
  2139. static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
  2140. struct snd_pcm_hw_params *fe_params,
  2141. struct snd_sof_platform_stream_params *platform_params,
  2142. struct snd_pcm_hw_params *pipeline_params, int dir)
  2143. {
  2144. struct snd_soc_component *scomp = swidget->scomp;
  2145. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2146. struct sof_ipc4_mixer *mixer = swidget->private;
  2147. struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt;
  2148. struct sof_ipc4_audio_format *in_fmt;
  2149. u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
  2150. int input_fmt_index, output_fmt_index;
  2151. input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
  2152. &mixer->base_config,
  2153. pipeline_params,
  2154. available_fmt);
  2155. if (input_fmt_index < 0)
  2156. return input_fmt_index;
  2157. in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
  2158. out_ref_rate = in_fmt->sampling_frequency;
  2159. out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
  2160. out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
  2161. out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
  2162. output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
  2163. &mixer->base_config,
  2164. available_fmt,
  2165. out_ref_rate,
  2166. out_ref_channels,
  2167. out_ref_valid_bits,
  2168. out_ref_type);
  2169. if (output_fmt_index < 0)
  2170. return output_fmt_index;
  2171. sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt,
  2172. input_fmt_index, output_fmt_index);
  2173. /* update pipeline memory usage */
  2174. sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config);
  2175. return 0;
  2176. }
  2177. static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
  2178. struct snd_pcm_hw_params *fe_params,
  2179. struct snd_sof_platform_stream_params *platform_params,
  2180. struct snd_pcm_hw_params *pipeline_params, int dir)
  2181. {
  2182. struct snd_soc_component *scomp = swidget->scomp;
  2183. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2184. struct sof_ipc4_src *src = swidget->private;
  2185. struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt;
  2186. struct sof_ipc4_audio_format *out_audio_fmt;
  2187. struct sof_ipc4_audio_format *in_audio_fmt;
  2188. u32 out_ref_rate, out_ref_channels, out_ref_valid_bits, out_ref_type;
  2189. int output_fmt_index, input_fmt_index;
  2190. input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
  2191. &src->data.base_config,
  2192. pipeline_params,
  2193. available_fmt);
  2194. if (input_fmt_index < 0)
  2195. return input_fmt_index;
  2196. /*
  2197. * For playback, the SRC sink rate will be configured based on the requested output
  2198. * format, which is restricted to only deal with DAI's with a single format for now.
  2199. */
  2200. if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) {
  2201. dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n",
  2202. available_fmt->num_output_formats, swidget->widget->name);
  2203. return -EINVAL;
  2204. }
  2205. /*
  2206. * SRC does not perform format conversion, so the output channels and valid bit depth must
  2207. * be the same as that of the input.
  2208. */
  2209. in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
  2210. out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg);
  2211. out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg);
  2212. out_ref_type = sof_ipc4_fmt_cfg_to_type(in_audio_fmt->fmt_cfg);
  2213. /*
  2214. * For capture, the SRC module should convert the rate to match the rate requested by the
  2215. * PCM hw_params. Set the reference params based on the fe_params unconditionally as it
  2216. * will be ignored for playback anyway.
  2217. */
  2218. out_ref_rate = params_rate(fe_params);
  2219. output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
  2220. &src->data.base_config,
  2221. available_fmt,
  2222. out_ref_rate,
  2223. out_ref_channels,
  2224. out_ref_valid_bits,
  2225. out_ref_type);
  2226. if (output_fmt_index < 0)
  2227. return output_fmt_index;
  2228. sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt,
  2229. input_fmt_index, output_fmt_index);
  2230. /* update pipeline memory usage */
  2231. sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config);
  2232. out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt;
  2233. src->data.sink_rate = out_audio_fmt->sampling_frequency;
  2234. /* update pipeline_params for sink widgets */
  2235. return sof_ipc4_update_hw_params(sdev, pipeline_params, out_audio_fmt,
  2236. BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
  2237. BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
  2238. BIT(SNDRV_PCM_HW_PARAM_RATE));
  2239. }
  2240. static int
  2241. sof_ipc4_process_set_pin_formats(struct snd_sof_widget *swidget, int pin_type)
  2242. {
  2243. struct sof_ipc4_process *process = swidget->private;
  2244. struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext;
  2245. struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt;
  2246. struct sof_ipc4_pin_format *pin_format, *format_list_to_search;
  2247. struct snd_soc_component *scomp = swidget->scomp;
  2248. int num_pins, format_list_count;
  2249. int pin_format_offset = 0;
  2250. int i, j;
  2251. /* set number of pins, offset of pin format and format list to search based on pin type */
  2252. if (pin_type == SOF_PIN_TYPE_INPUT) {
  2253. num_pins = swidget->num_input_pins;
  2254. format_list_to_search = available_fmt->input_pin_fmts;
  2255. format_list_count = available_fmt->num_input_formats;
  2256. } else {
  2257. num_pins = swidget->num_output_pins;
  2258. pin_format_offset = swidget->num_input_pins;
  2259. format_list_to_search = available_fmt->output_pin_fmts;
  2260. format_list_count = available_fmt->num_output_formats;
  2261. }
  2262. for (i = pin_format_offset; i < num_pins + pin_format_offset; i++) {
  2263. pin_format = &base_cfg_ext->pin_formats[i];
  2264. /* Pin 0 audio formats are derived from the base config input/output format */
  2265. if (i == pin_format_offset) {
  2266. if (pin_type == SOF_PIN_TYPE_INPUT) {
  2267. pin_format->buffer_size = process->base_config.ibs;
  2268. pin_format->audio_fmt = process->base_config.audio_fmt;
  2269. } else {
  2270. pin_format->buffer_size = process->base_config.obs;
  2271. pin_format->audio_fmt = process->output_format;
  2272. }
  2273. continue;
  2274. }
  2275. /*
  2276. * For all other pins, find the pin formats from those set in topology. If there
  2277. * is more than one format specified for a pin, this will pick the first available
  2278. * one.
  2279. */
  2280. for (j = 0; j < format_list_count; j++) {
  2281. struct sof_ipc4_pin_format *pin_format_item = &format_list_to_search[j];
  2282. if (pin_format_item->pin_index == i - pin_format_offset) {
  2283. *pin_format = *pin_format_item;
  2284. break;
  2285. }
  2286. }
  2287. if (j == format_list_count) {
  2288. dev_err(scomp->dev, "%s pin %d format not found for %s\n",
  2289. (pin_type == SOF_PIN_TYPE_INPUT) ? "input" : "output",
  2290. i - pin_format_offset, swidget->widget->name);
  2291. return -EINVAL;
  2292. }
  2293. }
  2294. return 0;
  2295. }
  2296. static int sof_ipc4_process_add_base_cfg_extn(struct snd_sof_widget *swidget)
  2297. {
  2298. int ret, i;
  2299. /* copy input and output pin formats */
  2300. for (i = 0; i <= SOF_PIN_TYPE_OUTPUT; i++) {
  2301. ret = sof_ipc4_process_set_pin_formats(swidget, i);
  2302. if (ret < 0)
  2303. return ret;
  2304. }
  2305. return 0;
  2306. }
  2307. static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
  2308. struct snd_pcm_hw_params *fe_params,
  2309. struct snd_sof_platform_stream_params *platform_params,
  2310. struct snd_pcm_hw_params *pipeline_params, int dir)
  2311. {
  2312. struct snd_soc_component *scomp = swidget->scomp;
  2313. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  2314. struct sof_ipc4_process *process = swidget->private;
  2315. struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt;
  2316. void *cfg = process->ipc_config_data;
  2317. int output_fmt_index = 0;
  2318. int input_fmt_index = 0;
  2319. int ret;
  2320. if (available_fmt->num_input_formats) {
  2321. input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget,
  2322. &process->base_config,
  2323. pipeline_params,
  2324. available_fmt);
  2325. if (input_fmt_index < 0)
  2326. return input_fmt_index;
  2327. }
  2328. /* Configure output audio format only if the module supports output */
  2329. if (available_fmt->num_output_formats) {
  2330. struct sof_ipc4_audio_format *in_fmt;
  2331. struct sof_ipc4_pin_format *pin_fmt;
  2332. u32 out_ref_rate, out_ref_channels;
  2333. int out_ref_valid_bits, out_ref_type;
  2334. if (available_fmt->num_input_formats) {
  2335. in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
  2336. out_ref_rate = in_fmt->sampling_frequency;
  2337. out_ref_channels =
  2338. SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
  2339. out_ref_valid_bits =
  2340. SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
  2341. out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
  2342. } else {
  2343. /* for modules without input formats, use FE params as reference */
  2344. out_ref_rate = params_rate(fe_params);
  2345. out_ref_channels = params_channels(fe_params);
  2346. ret = sof_ipc4_get_sample_type(sdev, fe_params);
  2347. if (ret < 0)
  2348. return ret;
  2349. out_ref_type = (u32)ret;
  2350. out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
  2351. if (out_ref_valid_bits < 0)
  2352. return out_ref_valid_bits;
  2353. }
  2354. output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
  2355. &process->base_config,
  2356. available_fmt,
  2357. out_ref_rate,
  2358. out_ref_channels,
  2359. out_ref_valid_bits,
  2360. out_ref_type);
  2361. if (output_fmt_index < 0)
  2362. return output_fmt_index;
  2363. pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index];
  2364. /* copy Pin output format for Pin 0 only */
  2365. if (pin_fmt->pin_index == 0) {
  2366. memcpy(&process->output_format, &pin_fmt->audio_fmt,
  2367. sizeof(struct sof_ipc4_audio_format));
  2368. /* modify the pipeline params with the output format */
  2369. ret = sof_ipc4_update_hw_params(sdev, pipeline_params,
  2370. &process->output_format,
  2371. BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
  2372. BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
  2373. BIT(SNDRV_PCM_HW_PARAM_RATE));
  2374. if (ret)
  2375. return ret;
  2376. }
  2377. /* set base cfg to match the first output format if there are no input formats */
  2378. if (!available_fmt->num_input_formats) {
  2379. struct sof_ipc4_audio_format *out_fmt;
  2380. out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt;
  2381. /* copy output format */
  2382. memcpy(&process->base_config.audio_fmt, out_fmt, sizeof(*out_fmt));
  2383. }
  2384. }
  2385. sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt,
  2386. input_fmt_index, output_fmt_index);
  2387. /* update pipeline memory usage */
  2388. sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config);
  2389. /* ipc_config_data is composed of the base_config followed by an optional extension */
  2390. memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg));
  2391. cfg += sizeof(struct sof_ipc4_base_module_cfg);
  2392. if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
  2393. struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext;
  2394. ret = sof_ipc4_process_add_base_cfg_extn(swidget);
  2395. if (ret < 0)
  2396. return ret;
  2397. memcpy(cfg, base_cfg_ext, process->base_config_ext_size);
  2398. }
  2399. return 0;
  2400. }
  2401. static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  2402. {
  2403. struct sof_ipc4_control_data *control_data;
  2404. struct sof_ipc4_msg *msg;
  2405. int i;
  2406. scontrol->size = struct_size(control_data, chanv, scontrol->num_channels);
  2407. /* scontrol->ipc_control_data will be freed in sof_control_unload */
  2408. scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL);
  2409. if (!scontrol->ipc_control_data)
  2410. return -ENOMEM;
  2411. control_data = scontrol->ipc_control_data;
  2412. control_data->index = scontrol->index;
  2413. msg = &control_data->msg;
  2414. msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
  2415. msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2416. msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  2417. /* volume controls with range 0-1 (off/on) are switch controls */
  2418. if (scontrol->max == 1)
  2419. msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID);
  2420. else
  2421. msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);
  2422. for (i = 0; i < scontrol->num_channels; i++) {
  2423. control_data->chanv[i].channel = i;
  2424. /*
  2425. * Default, initial values:
  2426. * - 0dB for volume controls
  2427. * - off (0) for switch controls - value already zero after
  2428. * memory allocation
  2429. */
  2430. if (scontrol->max > 1)
  2431. control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
  2432. }
  2433. return 0;
  2434. }
  2435. static int sof_ipc4_control_load_enum(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  2436. {
  2437. struct sof_ipc4_control_data *control_data;
  2438. struct sof_ipc4_msg *msg;
  2439. int i;
  2440. scontrol->size = struct_size(control_data, chanv, scontrol->num_channels);
  2441. /* scontrol->ipc_control_data will be freed in sof_control_unload */
  2442. scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL);
  2443. if (!scontrol->ipc_control_data)
  2444. return -ENOMEM;
  2445. control_data = scontrol->ipc_control_data;
  2446. control_data->index = scontrol->index;
  2447. msg = &control_data->msg;
  2448. msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
  2449. msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2450. msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  2451. msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID);
  2452. /* Default, initial value for enums: first enum entry is selected (0) */
  2453. for (i = 0; i < scontrol->num_channels; i++)
  2454. control_data->chanv[i].channel = i;
  2455. return 0;
  2456. }
  2457. static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  2458. {
  2459. struct sof_ipc4_control_data *control_data;
  2460. struct sof_ipc4_msg *msg;
  2461. int ret;
  2462. /*
  2463. * The max_size is coming from topology and indicates the maximum size
  2464. * of sof_abi_hdr plus the payload, which excludes the local only
  2465. * 'struct sof_ipc4_control_data'
  2466. */
  2467. if (scontrol->max_size < sizeof(struct sof_abi_hdr)) {
  2468. dev_err(sdev->dev,
  2469. "insufficient maximum size for a bytes control %s: %zu.\n",
  2470. scontrol->name, scontrol->max_size);
  2471. return -EINVAL;
  2472. }
  2473. if (scontrol->priv_size > scontrol->max_size) {
  2474. dev_err(sdev->dev,
  2475. "bytes control %s initial data size %zu exceeds max %zu.\n",
  2476. scontrol->name, scontrol->priv_size, scontrol->max_size);
  2477. return -EINVAL;
  2478. }
  2479. if (scontrol->priv_size && scontrol->priv_size < sizeof(struct sof_abi_hdr)) {
  2480. dev_err(sdev->dev,
  2481. "bytes control %s initial data size %zu is insufficient.\n",
  2482. scontrol->name, scontrol->priv_size);
  2483. return -EINVAL;
  2484. }
  2485. /*
  2486. * The used size behind the cdata pointer, which can be smaller than
  2487. * the maximum size
  2488. */
  2489. scontrol->size = sizeof(*control_data) + scontrol->priv_size;
  2490. /* Allocate the cdata: local struct size + maximum payload size */
  2491. scontrol->ipc_control_data = kzalloc(sizeof(*control_data) + scontrol->max_size,
  2492. GFP_KERNEL);
  2493. if (!scontrol->ipc_control_data)
  2494. return -ENOMEM;
  2495. control_data = scontrol->ipc_control_data;
  2496. control_data->index = scontrol->index;
  2497. if (scontrol->priv_size > 0) {
  2498. memcpy(control_data->data, scontrol->priv, scontrol->priv_size);
  2499. kfree(scontrol->priv);
  2500. scontrol->priv = NULL;
  2501. if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) {
  2502. dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n",
  2503. control_data->data->magic, scontrol->name);
  2504. ret = -EINVAL;
  2505. goto err;
  2506. }
  2507. /* TODO: check the ABI version */
  2508. if (control_data->data->size + sizeof(struct sof_abi_hdr) !=
  2509. scontrol->priv_size) {
  2510. dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n",
  2511. scontrol->name,
  2512. control_data->data->size + sizeof(struct sof_abi_hdr),
  2513. scontrol->priv_size);
  2514. ret = -EINVAL;
  2515. goto err;
  2516. }
  2517. }
  2518. msg = &control_data->msg;
  2519. msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
  2520. msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2521. msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  2522. msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(control_data->data->type);
  2523. return 0;
  2524. err:
  2525. kfree(scontrol->ipc_control_data);
  2526. scontrol->ipc_control_data = NULL;
  2527. return ret;
  2528. }
  2529. static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  2530. {
  2531. switch (scontrol->info_type) {
  2532. case SND_SOC_TPLG_CTL_VOLSW:
  2533. case SND_SOC_TPLG_CTL_VOLSW_SX:
  2534. case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
  2535. return sof_ipc4_control_load_volume(sdev, scontrol);
  2536. case SND_SOC_TPLG_CTL_BYTES:
  2537. return sof_ipc4_control_load_bytes(sdev, scontrol);
  2538. case SND_SOC_TPLG_CTL_ENUM:
  2539. case SND_SOC_TPLG_CTL_ENUM_VALUE:
  2540. return sof_ipc4_control_load_enum(sdev, scontrol);
  2541. default:
  2542. break;
  2543. }
  2544. return 0;
  2545. }
  2546. static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
  2547. struct snd_sof_widget *swidget,
  2548. struct sof_ipc4_msg *msg,
  2549. void *ipc_data, u32 ipc_size,
  2550. void **new_data)
  2551. {
  2552. struct sof_ipc4_mod_init_ext_dp_memory_data *dp_mem_data;
  2553. struct sof_ipc4_module_init_ext_init *ext_init;
  2554. struct sof_ipc4_module_init_ext_object *hdr;
  2555. int new_size;
  2556. u32 *payload;
  2557. u32 ext_pos;
  2558. /* For the moment the only reason for adding init_ext_init payload is DP
  2559. * memory data. If both stack and heap size are 0 (= use default), then
  2560. * there is no need for init_ext_init payload.
  2561. */
  2562. if (swidget->comp_domain != SOF_COMP_DOMAIN_DP) {
  2563. msg->extension &= ~SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK;
  2564. return 0;
  2565. }
  2566. payload = kzalloc(sdev->ipc->max_payload_size, GFP_KERNEL);
  2567. if (!payload)
  2568. return -ENOMEM;
  2569. /* Add ext_init first and set objects array flag to 1 */
  2570. ext_init = (struct sof_ipc4_module_init_ext_init *)payload;
  2571. ext_init->word0 |= SOF_IPC4_MOD_INIT_EXT_OBJ_ARRAY_MASK;
  2572. ext_pos = DIV_ROUND_UP(sizeof(*ext_init), sizeof(u32));
  2573. /* Add object array objects after ext_init */
  2574. /* Add dp_memory_data if comp_domain indicates DP */
  2575. if (swidget->comp_domain == SOF_COMP_DOMAIN_DP) {
  2576. hdr = (struct sof_ipc4_module_init_ext_object *)&payload[ext_pos];
  2577. hdr->header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK |
  2578. SOF_IPC4_MOD_INIT_EXT_OBJ_ID(SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA) |
  2579. SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS(DIV_ROUND_UP(sizeof(*dp_mem_data),
  2580. sizeof(u32)));
  2581. ext_pos += DIV_ROUND_UP(sizeof(*hdr), sizeof(u32));
  2582. dp_mem_data = (struct sof_ipc4_mod_init_ext_dp_memory_data *)&payload[ext_pos];
  2583. dp_mem_data->domain_id = swidget->dp_domain_id;
  2584. dp_mem_data->stack_bytes = swidget->dp_stack_bytes;
  2585. dp_mem_data->heap_bytes = swidget->dp_heap_bytes;
  2586. ext_pos += DIV_ROUND_UP(sizeof(*dp_mem_data), sizeof(u32));
  2587. }
  2588. /* If another array object is added, remember clear previous OBJ_LAST bit */
  2589. /* Calculate final size and check that it fits to max payload size */
  2590. new_size = ext_pos * sizeof(u32) + ipc_size;
  2591. if (new_size > sdev->ipc->max_payload_size) {
  2592. dev_err(sdev->dev, "Max ipc payload size %zu exceeded: %u",
  2593. sdev->ipc->max_payload_size, new_size);
  2594. kfree(payload);
  2595. return -EINVAL;
  2596. }
  2597. *new_data = payload;
  2598. /* Copy module specific ipc_payload to end */
  2599. memcpy(&payload[ext_pos], ipc_data, ipc_size);
  2600. /* Update msg extension bits according to the payload changes */
  2601. msg->extension |= SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK;
  2602. msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK;
  2603. msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(DIV_ROUND_UP(new_size, sizeof(u32)));
  2604. return new_size;
  2605. }
  2606. static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
  2607. {
  2608. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  2609. struct sof_ipc4_fw_data *ipc4_data = sdev->private;
  2610. struct sof_ipc4_pipeline *pipeline;
  2611. struct sof_ipc4_msg *msg;
  2612. void *ipc_data = NULL;
  2613. void *ext_data = NULL;
  2614. u32 ipc_size = 0;
  2615. int ret;
  2616. switch (swidget->id) {
  2617. case snd_soc_dapm_scheduler:
  2618. pipeline = swidget->private;
  2619. if (pipeline->use_chain_dma) {
  2620. dev_warn(sdev->dev, "use_chain_dma set for scheduler %s",
  2621. swidget->widget->name);
  2622. return 0;
  2623. }
  2624. dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id,
  2625. pipeline->mem_usage);
  2626. msg = &pipeline->msg;
  2627. msg->primary |= pipeline->mem_usage;
  2628. swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines,
  2629. GFP_KERNEL);
  2630. if (swidget->instance_id < 0) {
  2631. dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n",
  2632. swidget->widget->name, swidget->instance_id);
  2633. return swidget->instance_id;
  2634. }
  2635. msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK;
  2636. msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
  2637. break;
  2638. case snd_soc_dapm_aif_in:
  2639. case snd_soc_dapm_aif_out:
  2640. case snd_soc_dapm_buffer:
  2641. {
  2642. struct sof_ipc4_copier *ipc4_copier = swidget->private;
  2643. pipeline = pipe_widget->private;
  2644. if (pipeline->use_chain_dma)
  2645. return 0;
  2646. ipc_size = ipc4_copier->ipc_config_size;
  2647. ipc_data = ipc4_copier->ipc_config_data;
  2648. msg = &ipc4_copier->msg;
  2649. break;
  2650. }
  2651. case snd_soc_dapm_dai_in:
  2652. case snd_soc_dapm_dai_out:
  2653. {
  2654. struct snd_sof_dai *dai = swidget->private;
  2655. struct sof_ipc4_copier *ipc4_copier = dai->private;
  2656. pipeline = pipe_widget->private;
  2657. if (pipeline->use_chain_dma)
  2658. return 0;
  2659. ipc_size = ipc4_copier->ipc_config_size;
  2660. ipc_data = ipc4_copier->ipc_config_data;
  2661. msg = &ipc4_copier->msg;
  2662. break;
  2663. }
  2664. case snd_soc_dapm_pga:
  2665. {
  2666. struct sof_ipc4_gain *gain = swidget->private;
  2667. ipc_size = sizeof(gain->data);
  2668. ipc_data = &gain->data;
  2669. msg = &gain->msg;
  2670. break;
  2671. }
  2672. case snd_soc_dapm_mixer:
  2673. {
  2674. struct sof_ipc4_mixer *mixer = swidget->private;
  2675. ipc_size = sizeof(mixer->base_config);
  2676. ipc_data = &mixer->base_config;
  2677. msg = &mixer->msg;
  2678. break;
  2679. }
  2680. case snd_soc_dapm_src:
  2681. {
  2682. struct sof_ipc4_src *src = swidget->private;
  2683. ipc_size = sizeof(src->data);
  2684. ipc_data = &src->data;
  2685. msg = &src->msg;
  2686. break;
  2687. }
  2688. case snd_soc_dapm_asrc:
  2689. {
  2690. struct sof_ipc4_asrc *asrc = swidget->private;
  2691. ipc_size = sizeof(asrc->data);
  2692. ipc_data = &asrc->data;
  2693. msg = &asrc->msg;
  2694. break;
  2695. }
  2696. case snd_soc_dapm_effect:
  2697. {
  2698. struct sof_ipc4_process *process = swidget->private;
  2699. if (!process->ipc_config_size) {
  2700. dev_err(sdev->dev, "module %s has no config data!\n",
  2701. swidget->widget->name);
  2702. return -EINVAL;
  2703. }
  2704. ipc_size = process->ipc_config_size;
  2705. ipc_data = process->ipc_config_data;
  2706. msg = &process->msg;
  2707. break;
  2708. }
  2709. default:
  2710. dev_err(sdev->dev, "widget type %d not supported", swidget->id);
  2711. return -EINVAL;
  2712. }
  2713. if (swidget->id != snd_soc_dapm_scheduler) {
  2714. int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK;
  2715. ret = sof_ipc4_widget_assign_instance_id(sdev, swidget);
  2716. if (ret < 0) {
  2717. dev_err(sdev->dev, "failed to assign instance id for %s\n",
  2718. swidget->widget->name);
  2719. return ret;
  2720. }
  2721. msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK;
  2722. msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id);
  2723. msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK;
  2724. msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(ipc_size >> 2);
  2725. msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK;
  2726. msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id);
  2727. dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n",
  2728. swidget->widget->name, swidget->pipeline_id, module_id,
  2729. swidget->instance_id, swidget->core);
  2730. ret = sof_ipc4_widget_setup_msg_payload(sdev, swidget, msg, ipc_data, ipc_size,
  2731. &ext_data);
  2732. if (ret < 0)
  2733. goto fail;
  2734. if (ret > 0) {
  2735. ipc_size = ret;
  2736. ipc_data = ext_data;
  2737. }
  2738. } else {
  2739. dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n",
  2740. swidget->widget->name, swidget->pipeline_id,
  2741. swidget->instance_id, swidget->core);
  2742. }
  2743. msg->data_size = ipc_size;
  2744. msg->data_ptr = ipc_data;
  2745. ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size);
  2746. fail:
  2747. if (ret < 0) {
  2748. dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);
  2749. if (swidget->id != snd_soc_dapm_scheduler) {
  2750. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  2751. ida_free(&fw_module->m_ida, swidget->instance_id);
  2752. } else {
  2753. ida_free(&pipeline_ida, swidget->instance_id);
  2754. }
  2755. }
  2756. kfree(ext_data);
  2757. return ret;
  2758. }
  2759. static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
  2760. {
  2761. struct sof_ipc4_fw_module *fw_module = swidget->module_info;
  2762. struct sof_ipc4_fw_data *ipc4_data = sdev->private;
  2763. int ret = 0;
  2764. guard(mutex)(&ipc4_data->pipeline_state_mutex);
  2765. /* freeing a pipeline frees all the widgets associated with it */
  2766. if (swidget->id == snd_soc_dapm_scheduler) {
  2767. struct sof_ipc4_pipeline *pipeline = swidget->private;
  2768. struct sof_ipc4_msg msg = {{ 0 }};
  2769. u32 header;
  2770. if (pipeline->use_chain_dma) {
  2771. dev_warn(sdev->dev, "use_chain_dma set for scheduler %s",
  2772. swidget->widget->name);
  2773. return 0;
  2774. }
  2775. header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
  2776. header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE);
  2777. header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2778. header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
  2779. msg.primary = header;
  2780. ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
  2781. if (ret < 0)
  2782. dev_err(sdev->dev, "failed to free pipeline widget %s\n",
  2783. swidget->widget->name);
  2784. pipeline->mem_usage = 0;
  2785. pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
  2786. ida_free(&pipeline_ida, swidget->instance_id);
  2787. swidget->instance_id = -EINVAL;
  2788. } else {
  2789. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  2790. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  2791. if (!pipeline->use_chain_dma)
  2792. ida_free(&fw_module->m_ida, swidget->instance_id);
  2793. }
  2794. return ret;
  2795. }
  2796. static int sof_ipc4_get_queue_id(struct snd_sof_widget *src_widget,
  2797. struct snd_sof_widget *sink_widget, bool pin_type)
  2798. {
  2799. struct snd_sof_widget *current_swidget;
  2800. struct snd_soc_component *scomp;
  2801. struct ida *queue_ida;
  2802. const char *buddy_name;
  2803. char **pin_binding;
  2804. u32 num_pins;
  2805. int i;
  2806. if (pin_type == SOF_PIN_TYPE_OUTPUT) {
  2807. current_swidget = src_widget;
  2808. pin_binding = src_widget->output_pin_binding;
  2809. queue_ida = &src_widget->output_queue_ida;
  2810. num_pins = src_widget->num_output_pins;
  2811. buddy_name = sink_widget->widget->name;
  2812. } else {
  2813. current_swidget = sink_widget;
  2814. pin_binding = sink_widget->input_pin_binding;
  2815. queue_ida = &sink_widget->input_queue_ida;
  2816. num_pins = sink_widget->num_input_pins;
  2817. buddy_name = src_widget->widget->name;
  2818. }
  2819. scomp = current_swidget->scomp;
  2820. if (num_pins < 1) {
  2821. dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n",
  2822. (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"),
  2823. num_pins, current_swidget->widget->name);
  2824. return -EINVAL;
  2825. }
  2826. /* If there is only one input/output pin, queue id must be 0 */
  2827. if (num_pins == 1)
  2828. return 0;
  2829. /* Allocate queue ID from pin binding array if it is defined in topology. */
  2830. if (pin_binding) {
  2831. for (i = 0; i < num_pins; i++) {
  2832. if (!strcmp(pin_binding[i], buddy_name))
  2833. return i;
  2834. }
  2835. /*
  2836. * Fail if no queue ID found from pin binding array, so that we don't
  2837. * mixed use pin binding array and ida for queue ID allocation.
  2838. */
  2839. dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n",
  2840. (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"),
  2841. current_swidget->widget->name);
  2842. return -EINVAL;
  2843. }
  2844. /* If no pin binding array specified in topology, use ida to allocate one */
  2845. return ida_alloc_max(queue_ida, num_pins, GFP_KERNEL);
  2846. }
  2847. static void sof_ipc4_put_queue_id(struct snd_sof_widget *swidget, int queue_id,
  2848. bool pin_type)
  2849. {
  2850. struct ida *queue_ida;
  2851. char **pin_binding;
  2852. int num_pins;
  2853. if (pin_type == SOF_PIN_TYPE_OUTPUT) {
  2854. pin_binding = swidget->output_pin_binding;
  2855. queue_ida = &swidget->output_queue_ida;
  2856. num_pins = swidget->num_output_pins;
  2857. } else {
  2858. pin_binding = swidget->input_pin_binding;
  2859. queue_ida = &swidget->input_queue_ida;
  2860. num_pins = swidget->num_input_pins;
  2861. }
  2862. /* Nothing to free if queue ID is not allocated with ida. */
  2863. if (num_pins == 1 || pin_binding)
  2864. return;
  2865. ida_free(queue_ida, queue_id);
  2866. }
  2867. static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev,
  2868. struct snd_sof_widget *src_widget,
  2869. struct snd_sof_widget *sink_widget,
  2870. struct snd_sof_route *sroute)
  2871. {
  2872. struct sof_ipc4_copier_config_set_sink_format format;
  2873. const struct sof_ipc_ops *iops = sdev->ipc->ops;
  2874. struct sof_ipc4_base_module_cfg *src_config;
  2875. const struct sof_ipc4_audio_format *pin_fmt;
  2876. struct sof_ipc4_fw_module *fw_module;
  2877. struct sof_ipc4_msg msg = {{ 0 }};
  2878. if (WIDGET_IS_DAI(src_widget->id)) {
  2879. struct snd_sof_dai *dai = src_widget->private;
  2880. src_config = dai->private;
  2881. } else {
  2882. src_config = src_widget->private;
  2883. }
  2884. fw_module = src_widget->module_info;
  2885. format.sink_id = sroute->src_queue_id;
  2886. memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt));
  2887. pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id);
  2888. if (!pin_fmt) {
  2889. dev_err(sdev->dev,
  2890. "Failed to get input audio format of %s:%d for output of %s:%d\n",
  2891. sink_widget->widget->name, sroute->dst_queue_id,
  2892. src_widget->widget->name, sroute->src_queue_id);
  2893. return -EINVAL;
  2894. }
  2895. memcpy(&format.sink_fmt, pin_fmt, sizeof(format.sink_fmt));
  2896. msg.data_size = sizeof(format);
  2897. msg.data_ptr = &format;
  2898. msg.primary = fw_module->man4_module_entry.id;
  2899. msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id);
  2900. msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2901. msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  2902. msg.extension =
  2903. SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_COPIER_MODULE_CFG_PARAM_SET_SINK_FORMAT);
  2904. return iops->set_get_data(sdev, &msg, msg.data_size, true);
  2905. }
  2906. static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
  2907. {
  2908. struct snd_sof_widget *src_widget = sroute->src_widget;
  2909. struct snd_sof_widget *sink_widget = sroute->sink_widget;
  2910. struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget;
  2911. struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget;
  2912. struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
  2913. struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
  2914. struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private;
  2915. struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private;
  2916. struct sof_ipc4_msg msg = {{ 0 }};
  2917. u32 header, extension;
  2918. int ret;
  2919. /* no route set up if chain DMA is used */
  2920. if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) {
  2921. if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) {
  2922. dev_err(sdev->dev,
  2923. "use_chain_dma must be set for both src %s and sink %s pipelines\n",
  2924. src_widget->widget->name, sink_widget->widget->name);
  2925. return -EINVAL;
  2926. }
  2927. return 0;
  2928. }
  2929. if (!src_fw_module || !sink_fw_module) {
  2930. dev_err(sdev->dev,
  2931. "cannot bind %s -> %s, no firmware module for: %s%s\n",
  2932. src_widget->widget->name, sink_widget->widget->name,
  2933. src_fw_module ? "" : " source",
  2934. sink_fw_module ? "" : " sink");
  2935. return -ENODEV;
  2936. }
  2937. sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
  2938. SOF_PIN_TYPE_OUTPUT);
  2939. if (sroute->src_queue_id < 0) {
  2940. dev_err(sdev->dev,
  2941. "failed to get src_queue_id ID from source widget %s\n",
  2942. src_widget->widget->name);
  2943. return sroute->src_queue_id;
  2944. }
  2945. sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
  2946. SOF_PIN_TYPE_INPUT);
  2947. if (sroute->dst_queue_id < 0) {
  2948. dev_err(sdev->dev,
  2949. "failed to get dst_queue_id ID from sink widget %s\n",
  2950. sink_widget->widget->name);
  2951. sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id,
  2952. SOF_PIN_TYPE_OUTPUT);
  2953. return sroute->dst_queue_id;
  2954. }
  2955. /* Pin 0 format is already set during copier module init */
  2956. if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) {
  2957. ret = sof_ipc4_set_copier_sink_format(sdev, src_widget,
  2958. sink_widget, sroute);
  2959. if (ret < 0) {
  2960. dev_err(sdev->dev,
  2961. "failed to set sink format for source %s:%d\n",
  2962. src_widget->widget->name, sroute->src_queue_id);
  2963. goto out;
  2964. }
  2965. }
  2966. dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n",
  2967. src_widget->widget->name, sroute->src_queue_id,
  2968. sink_widget->widget->name, sroute->dst_queue_id);
  2969. header = src_fw_module->man4_module_entry.id;
  2970. header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id);
  2971. header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_BIND);
  2972. header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  2973. header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  2974. extension = sink_fw_module->man4_module_entry.id;
  2975. extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id);
  2976. extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id);
  2977. extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id);
  2978. msg.primary = header;
  2979. msg.extension = extension;
  2980. ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
  2981. if (ret < 0) {
  2982. dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n",
  2983. src_widget->widget->name, sroute->src_queue_id,
  2984. sink_widget->widget->name, sroute->dst_queue_id);
  2985. goto out;
  2986. }
  2987. return ret;
  2988. out:
  2989. sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT);
  2990. sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT);
  2991. return ret;
  2992. }
  2993. static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
  2994. {
  2995. struct snd_sof_widget *src_widget = sroute->src_widget;
  2996. struct snd_sof_widget *sink_widget = sroute->sink_widget;
  2997. struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
  2998. struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
  2999. struct sof_ipc4_msg msg = {{ 0 }};
  3000. struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget;
  3001. struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget;
  3002. struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private;
  3003. struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private;
  3004. u32 header, extension;
  3005. int ret = 0;
  3006. /* no route is set up if chain DMA is used */
  3007. if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma)
  3008. return 0;
  3009. dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n",
  3010. src_widget->widget->name, sroute->src_queue_id,
  3011. sink_widget->widget->name, sroute->dst_queue_id);
  3012. /*
  3013. * routes belonging to the same pipeline will be disconnected by the FW when the pipeline
  3014. * is freed. So avoid sending this IPC which will be ignored by the FW anyway.
  3015. */
  3016. if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget)
  3017. goto out;
  3018. header = src_fw_module->man4_module_entry.id;
  3019. header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id);
  3020. header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_UNBIND);
  3021. header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  3022. header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
  3023. extension = sink_fw_module->man4_module_entry.id;
  3024. extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id);
  3025. extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id);
  3026. extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id);
  3027. msg.primary = header;
  3028. msg.extension = extension;
  3029. ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
  3030. if (ret < 0)
  3031. dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n",
  3032. src_widget->widget->name, sroute->src_queue_id,
  3033. sink_widget->widget->name, sroute->dst_queue_id);
  3034. out:
  3035. sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT);
  3036. sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT);
  3037. return ret;
  3038. }
  3039. static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
  3040. unsigned int flags, struct snd_sof_dai_config_data *data)
  3041. {
  3042. struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
  3043. struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
  3044. struct snd_sof_dai *dai = swidget->private;
  3045. struct sof_ipc4_gtw_attributes *gtw_attr;
  3046. struct sof_ipc4_copier_data *copier_data;
  3047. struct sof_ipc4_copier *ipc4_copier;
  3048. if (!dai || !dai->private) {
  3049. dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n",
  3050. swidget->widget->name);
  3051. return -EINVAL;
  3052. }
  3053. ipc4_copier = (struct sof_ipc4_copier *)dai->private;
  3054. copier_data = &ipc4_copier->data;
  3055. if (!data)
  3056. return 0;
  3057. if (pipeline->use_chain_dma) {
  3058. /*
  3059. * Only configure the DMA Link ID for ChainDMA when this op is
  3060. * invoked with SOF_DAI_CONFIG_FLAGS_HW_PARAMS
  3061. */
  3062. if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
  3063. pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK;
  3064. pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data);
  3065. }
  3066. return 0;
  3067. }
  3068. switch (ipc4_copier->dai_type) {
  3069. case SOF_DAI_INTEL_HDA:
  3070. gtw_attr = ipc4_copier->gtw_attr;
  3071. gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
  3072. if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
  3073. copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
  3074. copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data);
  3075. }
  3076. break;
  3077. case SOF_DAI_INTEL_ALH:
  3078. /*
  3079. * Do not clear the node ID when this op is invoked with
  3080. * SOF_DAI_CONFIG_FLAGS_HW_FREE. It is needed to free the group_ida during
  3081. * unprepare. The node_id for multi-gateway DAI's will be overwritten with the
  3082. * group_id during copier's ipc_prepare op.
  3083. */
  3084. if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
  3085. struct sof_ipc4_alh_configuration_blob *blob;
  3086. blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
  3087. ipc4_copier->dai_index = data->dai_node_id;
  3088. /*
  3089. * no need to set the node_id for aggregated DAI's. These will be assigned
  3090. * a group_id during widget ipc_prepare
  3091. */
  3092. if (blob->alh_cfg.device_count == 1) {
  3093. copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
  3094. copier_data->gtw_cfg.node_id |=
  3095. SOF_IPC4_NODE_INDEX(data->dai_node_id);
  3096. }
  3097. }
  3098. break;
  3099. case SOF_DAI_INTEL_DMIC:
  3100. case SOF_DAI_INTEL_SSP:
  3101. /* nothing to do for SSP/DMIC */
  3102. break;
  3103. default:
  3104. dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__,
  3105. ipc4_copier->dai_type);
  3106. return -EINVAL;
  3107. }
  3108. return 0;
  3109. }
  3110. static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index,
  3111. struct snd_soc_tplg_manifest *man)
  3112. {
  3113. struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
  3114. struct sof_ipc4_fw_data *ipc4_data = sdev->private;
  3115. struct sof_manifest_tlv *manifest_tlv;
  3116. struct sof_manifest *manifest;
  3117. u32 size = le32_to_cpu(man->priv.size);
  3118. u8 *man_ptr = man->priv.data;
  3119. u32 len_check;
  3120. int i;
  3121. if (!size || size < SOF_IPC4_TPLG_ABI_SIZE) {
  3122. dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n",
  3123. __func__, size);
  3124. return -EINVAL;
  3125. }
  3126. manifest = (struct sof_manifest *)man_ptr;
  3127. dev_info(scomp->dev,
  3128. "Topology: ABI %d:%d:%d Kernel ABI %u:%u:%u\n",
  3129. le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor),
  3130. le16_to_cpu(manifest->abi_patch),
  3131. SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH);
  3132. /* TODO: Add ABI compatibility check */
  3133. /* no more data after the ABI version */
  3134. if (size <= SOF_IPC4_TPLG_ABI_SIZE)
  3135. return 0;
  3136. manifest_tlv = manifest->items;
  3137. len_check = sizeof(struct sof_manifest);
  3138. for (i = 0; i < le16_to_cpu(manifest->count); i++) {
  3139. len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size);
  3140. if (len_check > size)
  3141. return -EINVAL;
  3142. switch (le32_to_cpu(manifest_tlv->type)) {
  3143. case SOF_MANIFEST_DATA_TYPE_NHLT:
  3144. /* no NHLT in BIOS, so use the one from topology manifest */
  3145. if (ipc4_data->nhlt)
  3146. break;
  3147. ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data,
  3148. le32_to_cpu(manifest_tlv->size), GFP_KERNEL);
  3149. if (!ipc4_data->nhlt)
  3150. return -ENOMEM;
  3151. break;
  3152. default:
  3153. dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n",
  3154. manifest_tlv->type);
  3155. break;
  3156. }
  3157. man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size);
  3158. manifest_tlv = (struct sof_manifest_tlv *)man_ptr;
  3159. }
  3160. return 0;
  3161. }
  3162. static int sof_ipc4_dai_get_param(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int param_type)
  3163. {
  3164. struct sof_ipc4_copier *ipc4_copier = dai->private;
  3165. struct snd_soc_tplg_hw_config *hw_config;
  3166. struct snd_sof_dai_link *slink;
  3167. bool dai_link_found = false;
  3168. bool hw_cfg_found = false;
  3169. int i;
  3170. if (!ipc4_copier)
  3171. return 0;
  3172. list_for_each_entry(slink, &sdev->dai_link_list, list) {
  3173. if (!strcmp(slink->link->name, dai->name)) {
  3174. dai_link_found = true;
  3175. break;
  3176. }
  3177. }
  3178. if (!dai_link_found) {
  3179. dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name);
  3180. return -EINVAL;
  3181. }
  3182. for (i = 0; i < slink->num_hw_configs; i++) {
  3183. hw_config = &slink->hw_configs[i];
  3184. if (dai->current_config == le32_to_cpu(hw_config->id)) {
  3185. hw_cfg_found = true;
  3186. break;
  3187. }
  3188. }
  3189. if (!hw_cfg_found) {
  3190. dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name);
  3191. return -EINVAL;
  3192. }
  3193. switch (ipc4_copier->dai_type) {
  3194. case SOF_DAI_INTEL_SSP:
  3195. switch (param_type) {
  3196. case SOF_DAI_PARAM_INTEL_SSP_MCLK:
  3197. return le32_to_cpu(hw_config->mclk_rate);
  3198. case SOF_DAI_PARAM_INTEL_SSP_BCLK:
  3199. return le32_to_cpu(hw_config->bclk_rate);
  3200. case SOF_DAI_PARAM_INTEL_SSP_TDM_SLOTS:
  3201. return le32_to_cpu(hw_config->tdm_slots);
  3202. default:
  3203. dev_err(sdev->dev, "invalid SSP param %d\n", param_type);
  3204. break;
  3205. }
  3206. break;
  3207. default:
  3208. dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type);
  3209. break;
  3210. }
  3211. return -EINVAL;
  3212. }
  3213. static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify)
  3214. {
  3215. /*
  3216. * This function is called during system suspend, we need to make sure
  3217. * that all streams have been freed up.
  3218. * Freeing might have been skipped when xrun happened just at the start
  3219. * of the suspend and it sent a SNDRV_PCM_TRIGGER_STOP to the active
  3220. * stream. This will call sof_pcm_stream_free() with
  3221. * free_widget_list = false which will leave the kernel and firmware out
  3222. * of sync during suspend/resume.
  3223. *
  3224. * This will also make sure that paused streams handled correctly.
  3225. */
  3226. return sof_pcm_free_all_streams(sdev);
  3227. }
  3228. static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link)
  3229. {
  3230. if (link->no_pcm)
  3231. return 0;
  3232. /*
  3233. * set default trigger order for all links. Exceptions to
  3234. * the rule will be handled in sof_pcm_dai_link_fixup()
  3235. * For playback, the sequence is the following: start BE,
  3236. * start FE, stop FE, stop BE; for Capture the sequence is
  3237. * inverted start FE, start BE, stop BE, stop FE
  3238. */
  3239. link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST;
  3240. link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE;
  3241. return 0;
  3242. }
  3243. /* Tokens needed for different copier variants (aif, dai and buffer) */
  3244. static enum sof_tokens copier_token_list[] = {
  3245. SOF_COMP_TOKENS,
  3246. SOF_COPIER_TOKENS,
  3247. SOF_AUDIO_FMT_NUM_TOKENS,
  3248. SOF_IN_AUDIO_FORMAT_TOKENS,
  3249. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3250. SOF_COMP_EXT_TOKENS,
  3251. SOF_COPIER_DEEP_BUFFER_TOKENS, /* for AIF copier */
  3252. SOF_DAI_TOKENS, /* for DAI copier */
  3253. };
  3254. static enum sof_tokens pipeline_token_list[] = {
  3255. SOF_SCHED_TOKENS,
  3256. SOF_PIPELINE_TOKENS,
  3257. };
  3258. static enum sof_tokens pga_token_list[] = {
  3259. SOF_COMP_TOKENS,
  3260. SOF_GAIN_TOKENS,
  3261. SOF_AUDIO_FMT_NUM_TOKENS,
  3262. SOF_IN_AUDIO_FORMAT_TOKENS,
  3263. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3264. SOF_COMP_EXT_TOKENS,
  3265. };
  3266. static enum sof_tokens mixer_token_list[] = {
  3267. SOF_COMP_TOKENS,
  3268. SOF_AUDIO_FMT_NUM_TOKENS,
  3269. SOF_IN_AUDIO_FORMAT_TOKENS,
  3270. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3271. SOF_COMP_EXT_TOKENS,
  3272. };
  3273. static enum sof_tokens src_token_list[] = {
  3274. SOF_COMP_TOKENS,
  3275. SOF_SRC_TOKENS,
  3276. SOF_AUDIO_FMT_NUM_TOKENS,
  3277. SOF_IN_AUDIO_FORMAT_TOKENS,
  3278. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3279. SOF_COMP_EXT_TOKENS,
  3280. };
  3281. static enum sof_tokens asrc_token_list[] = {
  3282. SOF_COMP_TOKENS,
  3283. SOF_ASRC_TOKENS,
  3284. SOF_AUDIO_FMT_NUM_TOKENS,
  3285. SOF_IN_AUDIO_FORMAT_TOKENS,
  3286. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3287. SOF_COMP_EXT_TOKENS,
  3288. };
  3289. static enum sof_tokens process_token_list[] = {
  3290. SOF_COMP_TOKENS,
  3291. SOF_AUDIO_FMT_NUM_TOKENS,
  3292. SOF_IN_AUDIO_FORMAT_TOKENS,
  3293. SOF_OUT_AUDIO_FORMAT_TOKENS,
  3294. SOF_COMP_EXT_TOKENS,
  3295. };
  3296. static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = {
  3297. [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
  3298. copier_token_list, ARRAY_SIZE(copier_token_list),
  3299. NULL, sof_ipc4_prepare_copier_module,
  3300. sof_ipc4_unprepare_copier_module},
  3301. [snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
  3302. copier_token_list, ARRAY_SIZE(copier_token_list),
  3303. NULL, sof_ipc4_prepare_copier_module,
  3304. sof_ipc4_unprepare_copier_module},
  3305. [snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai,
  3306. copier_token_list, ARRAY_SIZE(copier_token_list), NULL,
  3307. sof_ipc4_prepare_copier_module,
  3308. sof_ipc4_unprepare_copier_module},
  3309. [snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai,
  3310. copier_token_list, ARRAY_SIZE(copier_token_list), NULL,
  3311. sof_ipc4_prepare_copier_module,
  3312. sof_ipc4_unprepare_copier_module},
  3313. [snd_soc_dapm_buffer] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
  3314. copier_token_list, ARRAY_SIZE(copier_token_list),
  3315. NULL, sof_ipc4_prepare_copier_module,
  3316. sof_ipc4_unprepare_copier_module},
  3317. [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline,
  3318. sof_ipc4_widget_free_comp_pipeline,
  3319. pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL,
  3320. NULL, NULL},
  3321. [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga,
  3322. pga_token_list, ARRAY_SIZE(pga_token_list), NULL,
  3323. sof_ipc4_prepare_gain_module,
  3324. NULL},
  3325. [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer,
  3326. mixer_token_list, ARRAY_SIZE(mixer_token_list),
  3327. NULL, sof_ipc4_prepare_mixer_module,
  3328. NULL},
  3329. [snd_soc_dapm_src] = {sof_ipc4_widget_setup_comp_src, sof_ipc4_widget_free_comp_src,
  3330. src_token_list, ARRAY_SIZE(src_token_list),
  3331. NULL, sof_ipc4_prepare_src_module,
  3332. NULL},
  3333. [snd_soc_dapm_asrc] = {sof_ipc4_widget_setup_comp_asrc, sof_ipc4_widget_free_comp_asrc,
  3334. asrc_token_list, ARRAY_SIZE(asrc_token_list),
  3335. NULL, sof_ipc4_prepare_src_module, /* Common prepare with SRC */
  3336. NULL},
  3337. [snd_soc_dapm_effect] = {sof_ipc4_widget_setup_comp_process,
  3338. sof_ipc4_widget_free_comp_process,
  3339. process_token_list, ARRAY_SIZE(process_token_list),
  3340. NULL, sof_ipc4_prepare_process_module,
  3341. NULL},
  3342. };
  3343. const struct sof_ipc_tplg_ops ipc4_tplg_ops = {
  3344. .widget = tplg_ipc4_widget_ops,
  3345. .token_list = ipc4_token_list,
  3346. .control_setup = sof_ipc4_control_setup,
  3347. .control = &tplg_ipc4_control_ops,
  3348. .widget_setup = sof_ipc4_widget_setup,
  3349. .widget_free = sof_ipc4_widget_free,
  3350. .route_setup = sof_ipc4_route_setup,
  3351. .route_free = sof_ipc4_route_free,
  3352. .dai_config = sof_ipc4_dai_config,
  3353. .parse_manifest = sof_ipc4_parse_manifest,
  3354. .dai_get_param = sof_ipc4_dai_get_param,
  3355. .tear_down_all_pipelines = sof_ipc4_tear_down_all_pipelines,
  3356. .link_setup = sof_ipc4_link_setup,
  3357. .host_config = sof_ipc4_host_config,
  3358. };