q6asm.c 112 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153
  1. /*
  2. * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  3. * Author: Brian Swetland <swetland@google.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/fs.h>
  16. #include <linux/mutex.h>
  17. #include <linux/wait.h>
  18. #include <linux/miscdevice.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/sched.h>
  21. #include <linux/dma-mapping.h>
  22. #include <linux/miscdevice.h>
  23. #include <linux/delay.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/slab.h>
  26. #include <linux/msm_audio.h>
  27. #include <linux/memory_alloc.h>
  28. #include <linux/debugfs.h>
  29. #include <linux/time.h>
  30. #include <linux/atomic.h>
  31. #include <asm/ioctls.h>
  32. #include <mach/memory.h>
  33. #include <mach/debug_mm.h>
  34. #include <mach/qdsp6v2/audio_acdb.h>
  35. #include <mach/qdsp6v2/rtac.h>
  36. #include <sound/apr_audio.h>
  37. #include <sound/q6asm.h>
  38. #define TRUE 0x01
  39. #define FALSE 0x00
  40. #define READDONE_IDX_STATUS 0
  41. #define READDONE_IDX_BUFFER 1
  42. #define READDONE_IDX_SIZE 2
  43. #define READDONE_IDX_OFFSET 3
  44. #define READDONE_IDX_MSW_TS 4
  45. #define READDONE_IDX_LSW_TS 5
  46. #define READDONE_IDX_FLAGS 6
  47. #define READDONE_IDX_NUMFRAMES 7
  48. #define READDONE_IDX_ID 8
  49. #ifdef CONFIG_DEBUG_FS
  50. #define OUT_BUFFER_SIZE 56
  51. #define IN_BUFFER_SIZE 24
  52. #endif
  53. #define FRAME_NUM (8)
  54. static DEFINE_MUTEX(session_lock);
  55. /* session id: 0 reserved */
  56. static struct audio_client *session[SESSION_MAX+1];
  57. static int32_t q6asm_mmapcallback(struct apr_client_data *data, void *priv);
  58. static int32_t q6asm_callback(struct apr_client_data *data, void *priv);
  59. static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
  60. uint32_t pkt_size, uint32_t cmd_flg);
  61. static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
  62. uint32_t pkt_size, uint32_t cmd_flg);
  63. static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
  64. uint32_t bufsz, uint32_t bufcnt);
  65. static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir,
  66. uint32_t bufsz, uint32_t bufcnt);
  67. static void q6asm_reset_buf_state(struct audio_client *ac);
  68. #ifdef CONFIG_DEBUG_FS
  69. static struct timeval out_cold_tv;
  70. static struct timeval out_warm_tv;
  71. static struct timeval out_cont_tv;
  72. static struct timeval in_cont_tv;
  73. static long out_enable_flag;
  74. static long in_enable_flag;
  75. static struct dentry *out_dentry;
  76. static struct dentry *in_dentry;
  77. static int in_cont_index;
  78. /*This var is used to keep track of first write done for cold output latency */
  79. static int out_cold_index;
  80. static char *out_buffer;
  81. static char *in_buffer;
  82. static int audio_output_latency_dbgfs_open(struct inode *inode,
  83. struct file *file)
  84. {
  85. file->private_data = inode->i_private;
  86. return 0;
  87. }
  88. static ssize_t audio_output_latency_dbgfs_read(struct file *file,
  89. char __user *buf, size_t count, loff_t *ppos)
  90. {
  91. snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
  92. out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
  93. out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
  94. return simple_read_from_buffer(buf, OUT_BUFFER_SIZE, ppos,
  95. out_buffer, OUT_BUFFER_SIZE);
  96. }
  97. static ssize_t audio_output_latency_dbgfs_write(struct file *file,
  98. const char __user *buf, size_t count, loff_t *ppos)
  99. {
  100. char *temp;
  101. if (count > 2*sizeof(char))
  102. return -EINVAL;
  103. else
  104. temp = kmalloc(2*sizeof(char), GFP_KERNEL);
  105. out_cold_index = 0;
  106. if (temp) {
  107. if (copy_from_user(temp, buf, 2*sizeof(char))) {
  108. kfree(temp);
  109. return -EFAULT;
  110. }
  111. if (!strict_strtol(temp, 10, &out_enable_flag)) {
  112. kfree(temp);
  113. return count;
  114. }
  115. kfree(temp);
  116. }
  117. return -EINVAL;
  118. }
  119. static const struct file_operations audio_output_latency_debug_fops = {
  120. .open = audio_output_latency_dbgfs_open,
  121. .read = audio_output_latency_dbgfs_read,
  122. .write = audio_output_latency_dbgfs_write
  123. };
  124. static int audio_input_latency_dbgfs_open(struct inode *inode,
  125. struct file *file)
  126. {
  127. file->private_data = inode->i_private;
  128. return 0;
  129. }
  130. static ssize_t audio_input_latency_dbgfs_read(struct file *file,
  131. char __user *buf, size_t count, loff_t *ppos)
  132. {
  133. snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
  134. in_cont_tv.tv_sec, in_cont_tv.tv_usec);
  135. return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
  136. in_buffer, IN_BUFFER_SIZE);
  137. }
  138. static ssize_t audio_input_latency_dbgfs_write(struct file *file,
  139. const char __user *buf, size_t count, loff_t *ppos)
  140. {
  141. char *temp;
  142. if (count > 2*sizeof(char))
  143. return -EINVAL;
  144. else
  145. temp = kmalloc(2*sizeof(char), GFP_KERNEL);
  146. if (temp) {
  147. if (copy_from_user(temp, buf, 2*sizeof(char))) {
  148. kfree(temp);
  149. return -EFAULT;
  150. }
  151. if (!strict_strtol(temp, 10, &in_enable_flag)) {
  152. kfree(temp);
  153. return count;
  154. }
  155. kfree(temp);
  156. }
  157. return -EINVAL;
  158. }
  159. static const struct file_operations audio_input_latency_debug_fops = {
  160. .open = audio_input_latency_dbgfs_open,
  161. .read = audio_input_latency_dbgfs_read,
  162. .write = audio_input_latency_dbgfs_write
  163. };
  164. #endif
  165. struct asm_mmap {
  166. atomic_t ref_cnt;
  167. atomic_t cmd_state;
  168. wait_queue_head_t cmd_wait;
  169. void *apr;
  170. };
  171. static struct asm_mmap this_mmap;
  172. static int q6asm_session_alloc(struct audio_client *ac)
  173. {
  174. int n;
  175. mutex_lock(&session_lock);
  176. for (n = 1; n <= SESSION_MAX; n++) {
  177. if (!session[n]) {
  178. session[n] = ac;
  179. mutex_unlock(&session_lock);
  180. return n;
  181. }
  182. }
  183. mutex_unlock(&session_lock);
  184. return -ENOMEM;
  185. }
  186. static void q6asm_session_free(struct audio_client *ac)
  187. {
  188. pr_debug("%s: sessionid[%d]\n", __func__, ac->session);
  189. rtac_remove_popp_from_adm_devices(ac->session);
  190. mutex_lock(&session_lock);
  191. session[ac->session] = 0;
  192. mutex_unlock(&session_lock);
  193. ac->session = 0;
  194. ac->perf_mode = false;
  195. return;
  196. }
  197. int q6asm_audio_client_buf_free(unsigned int dir,
  198. struct audio_client *ac)
  199. {
  200. struct audio_port_data *port;
  201. int cnt = 0;
  202. int rc = 0;
  203. pr_debug("%s: Session id %d\n", __func__, ac->session);
  204. mutex_lock(&ac->cmd_lock);
  205. if (ac->io_mode & SYNC_IO_MODE) {
  206. port = &ac->port[dir];
  207. if (!port->buf) {
  208. mutex_unlock(&ac->cmd_lock);
  209. return 0;
  210. }
  211. cnt = port->max_buf_cnt - 1;
  212. if (cnt >= 0) {
  213. rc = q6asm_memory_unmap_regions(ac, dir,
  214. port->buf[0].size,
  215. port->max_buf_cnt);
  216. if (rc < 0)
  217. pr_err("%s CMD Memory_unmap_regions failed\n",
  218. __func__);
  219. }
  220. while (cnt >= 0) {
  221. if (port->buf[cnt].data) {
  222. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  223. ion_unmap_kernel(port->buf[cnt].client,
  224. port->buf[cnt].handle);
  225. ion_free(port->buf[cnt].client,
  226. port->buf[cnt].handle);
  227. ion_client_destroy(port->buf[cnt].client);
  228. #else
  229. pr_debug("%s:data[%p]phys[%p][%p] cnt[%d] mem_buffer[%p]\n",
  230. __func__, (void *)port->buf[cnt].data,
  231. (void *)port->buf[cnt].phys,
  232. (void *)&port->buf[cnt].phys, cnt,
  233. (void *)port->buf[cnt].mem_buffer);
  234. if (IS_ERR((void *)port->buf[cnt].mem_buffer))
  235. pr_err("%s:mem buffer invalid, error = %ld\n",
  236. __func__,
  237. PTR_ERR((void *)port->buf[cnt].mem_buffer));
  238. else {
  239. if (iounmap(
  240. port->buf[cnt].mem_buffer) < 0)
  241. pr_err("%s: unmap buffer failed\n",
  242. __func__);
  243. }
  244. free_contiguous_memory_by_paddr(
  245. port->buf[cnt].phys);
  246. #endif
  247. port->buf[cnt].data = NULL;
  248. port->buf[cnt].phys = 0;
  249. --(port->max_buf_cnt);
  250. }
  251. --cnt;
  252. }
  253. kfree(port->buf);
  254. port->buf = NULL;
  255. }
  256. mutex_unlock(&ac->cmd_lock);
  257. return 0;
  258. }
  259. int q6asm_audio_client_buf_free_contiguous(unsigned int dir,
  260. struct audio_client *ac)
  261. {
  262. struct audio_port_data *port;
  263. int cnt = 0;
  264. int rc = 0;
  265. pr_debug("%s: Session id %d\n", __func__, ac->session);
  266. mutex_lock(&ac->cmd_lock);
  267. port = &ac->port[dir];
  268. if (!port->buf) {
  269. mutex_unlock(&ac->cmd_lock);
  270. return 0;
  271. }
  272. cnt = port->max_buf_cnt - 1;
  273. if (cnt >= 0) {
  274. rc = q6asm_memory_unmap(ac, port->buf[0].phys, dir);
  275. if (rc < 0)
  276. pr_err("%s CMD Memory_unmap_regions failed\n",
  277. __func__);
  278. }
  279. if (port->buf[0].data) {
  280. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  281. ion_unmap_kernel(port->buf[0].client, port->buf[0].handle);
  282. ion_free(port->buf[0].client, port->buf[0].handle);
  283. ion_client_destroy(port->buf[0].client);
  284. pr_debug("%s:data[%p]phys[%p][%p], client[%p] handle[%p]\n",
  285. __func__,
  286. (void *)port->buf[0].data,
  287. (void *)port->buf[0].phys,
  288. (void *)&port->buf[0].phys,
  289. (void *)port->buf[0].client,
  290. (void *)port->buf[0].handle);
  291. #else
  292. pr_debug("%s:data[%p]phys[%p][%p] mem_buffer[%p]\n",
  293. __func__,
  294. (void *)port->buf[0].data,
  295. (void *)port->buf[0].phys,
  296. (void *)&port->buf[0].phys,
  297. (void *)port->buf[0].mem_buffer);
  298. if (IS_ERR((void *)port->buf[0].mem_buffer))
  299. pr_err("%s:mem buffer invalid, error = %ld\n",
  300. __func__,
  301. PTR_ERR((void *)port->buf[0].mem_buffer));
  302. else {
  303. if (iounmap(
  304. port->buf[0].mem_buffer) < 0)
  305. pr_err("%s: unmap buffer failed\n", __func__);
  306. }
  307. free_contiguous_memory_by_paddr(port->buf[0].phys);
  308. #endif
  309. }
  310. while (cnt >= 0) {
  311. port->buf[cnt].data = NULL;
  312. port->buf[cnt].phys = 0;
  313. cnt--;
  314. }
  315. port->max_buf_cnt = 0;
  316. kfree(port->buf);
  317. port->buf = NULL;
  318. mutex_unlock(&ac->cmd_lock);
  319. return 0;
  320. }
  321. void q6asm_audio_client_free(struct audio_client *ac)
  322. {
  323. int loopcnt;
  324. struct audio_port_data *port;
  325. if (!ac || !ac->session)
  326. return;
  327. pr_debug("%s: Session id %d\n", __func__, ac->session);
  328. if (ac->io_mode & SYNC_IO_MODE) {
  329. for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
  330. port = &ac->port[loopcnt];
  331. if (!port->buf)
  332. continue;
  333. pr_debug("%s:loopcnt = %d\n", __func__, loopcnt);
  334. q6asm_audio_client_buf_free(loopcnt, ac);
  335. }
  336. }
  337. apr_deregister(ac->apr);
  338. q6asm_session_free(ac);
  339. pr_debug("%s: APR De-Register\n", __func__);
  340. if (atomic_read(&this_mmap.ref_cnt) <= 0) {
  341. pr_err("%s: APR Common Port Already Closed\n", __func__);
  342. goto done;
  343. }
  344. atomic_dec(&this_mmap.ref_cnt);
  345. if (atomic_read(&this_mmap.ref_cnt) == 0) {
  346. apr_deregister(this_mmap.apr);
  347. pr_debug("%s:APR De-Register common port\n", __func__);
  348. }
  349. done:
  350. kfree(ac);
  351. return;
  352. }
  353. int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode)
  354. {
  355. if (ac == NULL) {
  356. pr_err("%s APR handle NULL\n", __func__);
  357. return -EINVAL;
  358. }
  359. if (mode == ASYNC_IO_MODE) {
  360. ac->io_mode &= ~SYNC_IO_MODE;
  361. ac->io_mode |= ASYNC_IO_MODE;
  362. } else if (mode == SYNC_IO_MODE) {
  363. ac->io_mode &= ~ASYNC_IO_MODE;
  364. ac->io_mode |= SYNC_IO_MODE;
  365. } else {
  366. pr_err("%s:Not an valid IO Mode:%d\n", __func__, ac->io_mode);
  367. return -EINVAL;
  368. }
  369. pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
  370. return 0;
  371. }
  372. struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
  373. {
  374. struct audio_client *ac;
  375. int n;
  376. int lcnt = 0;
  377. ac = kzalloc(sizeof(struct audio_client), GFP_KERNEL);
  378. if (!ac)
  379. return NULL;
  380. n = q6asm_session_alloc(ac);
  381. if (n <= 0)
  382. goto fail_session;
  383. ac->session = n;
  384. ac->cb = cb;
  385. ac->priv = priv;
  386. ac->io_mode = SYNC_IO_MODE;
  387. ac->perf_mode = false;
  388. ac->apr = apr_register("ADSP", "ASM", \
  389. (apr_fn)q6asm_callback,\
  390. ((ac->session) << 8 | 0x0001),\
  391. ac);
  392. if (ac->apr == NULL) {
  393. pr_err("%s Registration with APR failed\n", __func__);
  394. goto fail;
  395. }
  396. rtac_set_asm_handle(n, ac->apr);
  397. pr_debug("%s Registering the common port with APR\n", __func__);
  398. if (atomic_read(&this_mmap.ref_cnt) == 0) {
  399. this_mmap.apr = apr_register("ADSP", "ASM", \
  400. (apr_fn)q6asm_mmapcallback,\
  401. 0x0FFFFFFFF, &this_mmap);
  402. if (this_mmap.apr == NULL) {
  403. pr_debug("%s Unable to register APR ASM common port\n",
  404. __func__);
  405. goto fail;
  406. }
  407. }
  408. atomic_inc(&this_mmap.ref_cnt);
  409. init_waitqueue_head(&ac->cmd_wait);
  410. init_waitqueue_head(&ac->time_wait);
  411. atomic_set(&ac->time_flag, 1);
  412. mutex_init(&ac->cmd_lock);
  413. for (lcnt = 0; lcnt <= OUT; lcnt++) {
  414. mutex_init(&ac->port[lcnt].lock);
  415. spin_lock_init(&ac->port[lcnt].dsp_lock);
  416. }
  417. atomic_set(&ac->cmd_state, 0);
  418. atomic_set(&ac->cmd_response, 0);
  419. pr_debug("%s: session[%d]\n", __func__, ac->session);
  420. return ac;
  421. fail:
  422. q6asm_audio_client_free(ac);
  423. return NULL;
  424. fail_session:
  425. kfree(ac);
  426. return NULL;
  427. }
  428. struct audio_client *q6asm_get_audio_client(int session_id)
  429. {
  430. if ((session_id <= 0) || (session_id > SESSION_MAX)) {
  431. pr_err("%s: invalid session: %d\n", __func__, session_id);
  432. goto err;
  433. }
  434. if (!session[session_id]) {
  435. pr_err("%s: session not active: %d\n", __func__, session_id);
  436. goto err;
  437. }
  438. return session[session_id];
  439. err:
  440. return NULL;
  441. }
  442. int q6asm_audio_client_buf_alloc(unsigned int dir,
  443. struct audio_client *ac,
  444. unsigned int bufsz,
  445. unsigned int bufcnt)
  446. {
  447. int cnt = 0;
  448. int rc = 0;
  449. struct audio_buffer *buf;
  450. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  451. int len;
  452. unsigned int bufsz_4k_aligned;
  453. #endif
  454. if (!(ac) || ((dir != IN) && (dir != OUT)))
  455. return -EINVAL;
  456. pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n", __func__, ac->session,
  457. bufsz, bufcnt);
  458. if (ac->session <= 0 || ac->session > 8)
  459. goto fail;
  460. if (ac->io_mode & SYNC_IO_MODE) {
  461. if (ac->port[dir].buf) {
  462. pr_debug("%s: buffer already allocated\n", __func__);
  463. return 0;
  464. }
  465. if (bufcnt != FRAME_NUM)
  466. goto fail;
  467. mutex_lock(&ac->cmd_lock);
  468. buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
  469. GFP_KERNEL);
  470. if (!buf) {
  471. mutex_unlock(&ac->cmd_lock);
  472. goto fail;
  473. }
  474. ac->port[dir].buf = buf;
  475. while (cnt < bufcnt) {
  476. if (bufsz > 0) {
  477. if (!buf[cnt].data) {
  478. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  479. buf[cnt].client = msm_ion_client_create
  480. (UINT_MAX, "audio_client");
  481. if (IS_ERR_OR_NULL((void *)
  482. buf[cnt].client)) {
  483. pr_err("%s: ION create client for AUDIO failed\n",
  484. __func__);
  485. mutex_unlock(&ac->cmd_lock);
  486. goto fail;
  487. }
  488. bufsz_4k_aligned = (bufsz + 4095) &
  489. (~4095);
  490. pr_debug("%s: bufsz_4k_aligned %d"\
  491. "bufsz = %d\n",
  492. __func__, bufsz_4k_aligned,
  493. bufsz);
  494. buf[cnt].handle = ion_alloc
  495. (buf[cnt].client,
  496. bufsz_4k_aligned, SZ_4K,
  497. (0x1 << ION_AUDIO_HEAP_ID), 0);
  498. if (IS_ERR_OR_NULL((void *)
  499. buf[cnt].handle)) {
  500. pr_err("%s: ION memory allocation for AUDIO failed\n",
  501. __func__);
  502. mutex_unlock(&ac->cmd_lock);
  503. goto fail;
  504. }
  505. rc = ion_phys(buf[cnt].client,
  506. buf[cnt].handle,
  507. (ion_phys_addr_t *)
  508. &buf[cnt].phys,
  509. (size_t *)&len);
  510. if (rc) {
  511. pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
  512. __func__, rc);
  513. mutex_unlock(&ac->cmd_lock);
  514. goto fail;
  515. }
  516. buf[cnt].data = ion_map_kernel
  517. (buf[cnt].client, buf[cnt].handle);
  518. if (IS_ERR_OR_NULL((void *)
  519. buf[cnt].data)) {
  520. pr_err("%s: ION memory mapping for AUDIO failed\n",
  521. __func__);
  522. mutex_unlock(&ac->cmd_lock);
  523. goto fail;
  524. }
  525. memset((void *)buf[cnt].data, 0, bufsz);
  526. #else
  527. unsigned int flags = 0;
  528. buf[cnt].phys =
  529. allocate_contiguous_ebi_nomap(bufsz,
  530. SZ_4K);
  531. if (!buf[cnt].phys) {
  532. pr_err("%s:Buf alloc failed size=%d\n",
  533. __func__,
  534. bufsz);
  535. mutex_unlock(&ac->cmd_lock);
  536. goto fail;
  537. }
  538. buf[cnt].mem_buffer =
  539. ioremap(buf[cnt].phys, bufsz);
  540. if (IS_ERR(
  541. (void *)buf[cnt].mem_buffer)) {
  542. pr_err("%s:map_buffer failed, error = %ld\n",
  543. __func__,
  544. PTR_ERR((void *)buf[cnt].mem_buffer));
  545. mutex_unlock(&ac->cmd_lock);
  546. goto fail;
  547. }
  548. buf[cnt].data =
  549. buf[cnt].mem_buffer;
  550. if (!buf[cnt].data) {
  551. pr_err("%s:invalid vaddr, iomap failed\n",
  552. __func__);
  553. mutex_unlock(&ac->cmd_lock);
  554. goto fail;
  555. }
  556. #endif
  557. buf[cnt].used = 1;
  558. buf[cnt].size = bufsz;
  559. buf[cnt].actual_size = bufsz;
  560. pr_debug("%s data[%p]phys[%p][%p]\n",
  561. __func__,
  562. (void *)buf[cnt].data,
  563. (void *)buf[cnt].phys,
  564. (void *)&buf[cnt].phys);
  565. cnt++;
  566. }
  567. }
  568. }
  569. ac->port[dir].max_buf_cnt = cnt;
  570. mutex_unlock(&ac->cmd_lock);
  571. rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt);
  572. if (rc < 0) {
  573. pr_err("%s:CMD Memory_map_regions failed\n", __func__);
  574. goto fail;
  575. }
  576. }
  577. return 0;
  578. fail:
  579. q6asm_audio_client_buf_free(dir, ac);
  580. return -EINVAL;
  581. }
  582. int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir,
  583. struct audio_client *ac,
  584. unsigned int bufsz,
  585. unsigned int bufcnt)
  586. {
  587. int cnt = 0;
  588. int rc = 0;
  589. struct audio_buffer *buf;
  590. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  591. int len;
  592. #else
  593. int flags = 0;
  594. #endif
  595. if (!(ac) || ((dir != IN) && (dir != OUT)))
  596. return -EINVAL;
  597. pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n",
  598. __func__, ac->session,
  599. bufsz, bufcnt);
  600. if (ac->session <= 0 || ac->session > 8)
  601. goto fail;
  602. if (ac->port[dir].buf) {
  603. pr_debug("%s: buffer already allocated\n", __func__);
  604. return 0;
  605. }
  606. mutex_lock(&ac->cmd_lock);
  607. buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
  608. GFP_KERNEL);
  609. if (!buf) {
  610. mutex_unlock(&ac->cmd_lock);
  611. goto fail;
  612. }
  613. ac->port[dir].buf = buf;
  614. #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
  615. buf[0].client = msm_ion_client_create(UINT_MAX, "audio_client");
  616. if (IS_ERR_OR_NULL((void *)buf[0].client)) {
  617. pr_err("%s: ION create client for AUDIO failed\n", __func__);
  618. mutex_unlock(&ac->cmd_lock);
  619. goto fail;
  620. }
  621. buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
  622. (0x1 << ION_AUDIO_HEAP_ID), 0);
  623. if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
  624. pr_err("%s: ION memory allocation for AUDIO failed\n",
  625. __func__);
  626. mutex_unlock(&ac->cmd_lock);
  627. goto fail;
  628. }
  629. rc = ion_phys(buf[0].client, buf[0].handle,
  630. (ion_phys_addr_t *)&buf[0].phys, (size_t *)&len);
  631. if (rc) {
  632. pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
  633. __func__, rc);
  634. mutex_unlock(&ac->cmd_lock);
  635. goto fail;
  636. }
  637. buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle);
  638. if (IS_ERR_OR_NULL((void *) buf[0].data)) {
  639. pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
  640. mutex_unlock(&ac->cmd_lock);
  641. goto fail;
  642. }
  643. memset((void *)buf[0].data, 0, (bufsz * bufcnt));
  644. #else
  645. buf[0].phys = allocate_contiguous_ebi_nomap(bufsz * bufcnt,
  646. SZ_4K);
  647. if (!buf[0].phys) {
  648. pr_err("%s:Buf alloc failed size=%d, bufcnt=%d\n",
  649. __func__, bufsz, bufcnt);
  650. mutex_unlock(&ac->cmd_lock);
  651. goto fail;
  652. }
  653. buf[0].mem_buffer = ioremap(buf[0].phys, bufsz * bufcnt);
  654. if (IS_ERR((void *)buf[cnt].mem_buffer)) {
  655. pr_err("%s:map_buffer failed, error = %ld\n",
  656. __func__, PTR_ERR((void *)buf[0].mem_buffer));
  657. mutex_unlock(&ac->cmd_lock);
  658. goto fail;
  659. }
  660. buf[0].data = buf[0].mem_buffer;
  661. #endif
  662. if (!buf[0].data) {
  663. pr_err("%s:invalid vaddr, iomap failed\n", __func__);
  664. mutex_unlock(&ac->cmd_lock);
  665. goto fail;
  666. }
  667. buf[0].used = dir ^ 1;
  668. buf[0].size = bufsz;
  669. buf[0].actual_size = bufsz;
  670. cnt = 1;
  671. while (cnt < bufcnt) {
  672. if (bufsz > 0) {
  673. buf[cnt].data = buf[0].data + (cnt * bufsz);
  674. buf[cnt].phys = buf[0].phys + (cnt * bufsz);
  675. if (!buf[cnt].data) {
  676. pr_err("%s Buf alloc failed\n",
  677. __func__);
  678. mutex_unlock(&ac->cmd_lock);
  679. goto fail;
  680. }
  681. buf[cnt].used = dir ^ 1;
  682. buf[cnt].size = bufsz;
  683. buf[cnt].actual_size = bufsz;
  684. pr_debug("%s data[%p]phys[%p][%p]\n", __func__,
  685. (void *)buf[cnt].data,
  686. (void *)buf[cnt].phys,
  687. (void *)&buf[cnt].phys);
  688. }
  689. cnt++;
  690. }
  691. ac->port[dir].max_buf_cnt = cnt;
  692. pr_debug("%s ac->port[%d].max_buf_cnt[%d]\n", __func__, dir,
  693. ac->port[dir].max_buf_cnt);
  694. mutex_unlock(&ac->cmd_lock);
  695. rc = q6asm_memory_map(ac, buf[0].phys, dir, bufsz, cnt);
  696. if (rc < 0) {
  697. pr_err("%s:CMD Memory_map_regions failed\n", __func__);
  698. goto fail;
  699. }
  700. return 0;
  701. fail:
  702. q6asm_audio_client_buf_free_contiguous(dir, ac);
  703. return -EINVAL;
  704. }
  705. static int32_t q6asm_mmapcallback(struct apr_client_data *data, void *priv)
  706. {
  707. uint32_t token;
  708. uint32_t *payload = data->payload;
  709. struct audio_client *ac;
  710. if (data->opcode == RESET_EVENTS) {
  711. pr_debug("%s: Reset event is received: %d %d apr[%p]\n",
  712. __func__,
  713. data->reset_event,
  714. data->reset_proc,
  715. this_mmap.apr);
  716. apr_reset(this_mmap.apr);
  717. this_mmap.apr = NULL;
  718. atomic_set(&this_mmap.cmd_state, 0);
  719. return 0;
  720. }
  721. pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]\n",
  722. __func__, payload[0], payload[1], data->opcode, data->token,
  723. data->payload_size, data->src_port, data->dest_port);
  724. if (data->opcode == APR_BASIC_RSP_RESULT) {
  725. token = data->token;
  726. ac = (struct audio_client *)data->token;
  727. pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
  728. switch (payload[0]) {
  729. case ASM_SESSION_CMD_MEMORY_MAP:
  730. case ASM_SESSION_CMD_MEMORY_UNMAP:
  731. case ASM_SESSION_CMD_MEMORY_MAP_REGIONS:
  732. case ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS:
  733. pr_debug("%s:command[0x%x]success [0x%x]\n",
  734. __func__, payload[0], payload[1]);
  735. if (atomic_read(&ac->cmd_state)) {
  736. atomic_set(&ac->cmd_state, 0);
  737. if (payload[1] != ADSP_EOK) {
  738. pr_err("payload[1]:%d error case\n",
  739. payload[1]);
  740. atomic_set(&ac->cmd_response, 1);
  741. } else
  742. atomic_set(&ac->cmd_response, 0);
  743. wake_up(&ac->cmd_wait);
  744. }
  745. break;
  746. default:
  747. pr_debug("%s:command[0x%x] not expecting rsp\n",
  748. __func__, payload[0]);
  749. break;
  750. }
  751. }
  752. return 0;
  753. }
  754. static int32_t is_no_wait_cmd_rsp(uint32_t opcode, uint32_t *cmd_type)
  755. {
  756. if (opcode == APR_BASIC_RSP_RESULT) {
  757. if (cmd_type != NULL) {
  758. switch (cmd_type[0]) {
  759. case ASM_SESSION_CMD_RUN:
  760. case ASM_SESSION_CMD_PAUSE:
  761. case ASM_DATA_CMD_EOS:
  762. return 1;
  763. default:
  764. break;
  765. }
  766. } else
  767. pr_err("%s: null pointer!", __func__);
  768. } else if (opcode == ASM_DATA_CMDRSP_EOS)
  769. return 1;
  770. return 0;
  771. }
  772. static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
  773. {
  774. int i = 0;
  775. struct audio_client *ac = (struct audio_client *)priv;
  776. uint32_t token;
  777. unsigned long dsp_flags;
  778. uint32_t *payload;
  779. uint32_t wakeup_flag = 1;
  780. if ((ac == NULL) || (data == NULL)) {
  781. pr_err("ac or priv NULL\n");
  782. return -EINVAL;
  783. }
  784. if (ac->session <= 0 || ac->session > 8) {
  785. pr_err("%s:Session ID is invalid, session = %d\n", __func__,
  786. ac->session);
  787. return -EINVAL;
  788. }
  789. payload = data->payload;
  790. if ((atomic_read(&ac->nowait_cmd_cnt) > 0) &&
  791. is_no_wait_cmd_rsp(data->opcode, payload)) {
  792. pr_debug("%s: nowait_cmd_cnt %d\n",
  793. __func__,
  794. atomic_read(&ac->nowait_cmd_cnt));
  795. atomic_dec(&ac->nowait_cmd_cnt);
  796. wakeup_flag = 0;
  797. }
  798. if (data->opcode == RESET_EVENTS) {
  799. pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",
  800. data->reset_event, data->reset_proc, ac->apr);
  801. if (ac->cb)
  802. ac->cb(data->opcode, data->token,
  803. (uint32_t *)data->payload, ac->priv);
  804. apr_reset(ac->apr);
  805. return 0;
  806. }
  807. pr_debug("%s: session[%d]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]\n",
  808. __func__,
  809. ac->session, data->opcode,
  810. data->token, data->payload_size, data->src_port,
  811. data->dest_port);
  812. if (data->opcode == APR_BASIC_RSP_RESULT) {
  813. token = data->token;
  814. pr_debug("%s payload[0]:%x", __func__, payload[0]);
  815. switch (payload[0]) {
  816. case ASM_STREAM_CMD_SET_PP_PARAMS:
  817. if (rtac_make_asm_callback(ac->session, payload,
  818. data->payload_size))
  819. break;
  820. case ASM_SESSION_CMD_PAUSE:
  821. case ASM_DATA_CMD_EOS:
  822. case ASM_STREAM_CMD_CLOSE:
  823. case ASM_STREAM_CMD_FLUSH:
  824. case ASM_SESSION_CMD_RUN:
  825. case ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS:
  826. case ASM_STREAM_CMD_FLUSH_READBUFS:
  827. pr_debug("%s:Payload = [0x%x]\n", __func__, payload[0]);
  828. if (token != ac->session) {
  829. pr_err("%s:Invalid session[%d] rxed expected[%d]",
  830. __func__, token, ac->session);
  831. return -EINVAL;
  832. }
  833. case ASM_STREAM_CMD_OPEN_READ:
  834. case ASM_STREAM_CMD_OPEN_READ_V2_1:
  835. case ASM_STREAM_CMD_OPEN_WRITE:
  836. case ASM_STREAM_CMD_OPEN_WRITE_V2_1:
  837. case ASM_STREAM_CMD_OPEN_READWRITE:
  838. case ASM_STREAM_CMD_OPEN_LOOPBACK:
  839. case ASM_DATA_CMD_MEDIA_FORMAT_UPDATE:
  840. case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
  841. case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
  842. case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
  843. case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK:
  844. if (payload[0] == ASM_STREAM_CMD_CLOSE) {
  845. atomic_set(&ac->cmd_close_state, 0);
  846. wake_up(&ac->cmd_wait);
  847. } else if (atomic_read(&ac->cmd_state) &&
  848. wakeup_flag) {
  849. atomic_set(&ac->cmd_state, 0);
  850. pr_debug("response payload[1]:%d",
  851. payload[1]);
  852. if (payload[1] == ADSP_EUNSUPPORTED ||
  853. payload[1] == ADSP_EBADPARAM ||
  854. payload[1] == ADSP_EFAILED) {
  855. atomic_set(&ac->cmd_response, 1);
  856. }
  857. else
  858. atomic_set(&ac->cmd_response, 0);
  859. wake_up(&ac->cmd_wait);
  860. }
  861. if (ac->cb)
  862. ac->cb(data->opcode, data->token,
  863. (uint32_t *)data->payload, ac->priv);
  864. break;
  865. default:
  866. pr_debug("%s:command[0x%x] not expecting rsp\n",
  867. __func__, payload[0]);
  868. break;
  869. }
  870. return 0;
  871. }
  872. switch (data->opcode) {
  873. case ASM_DATA_EVENT_WRITE_DONE:{
  874. struct audio_port_data *port = &ac->port[IN];
  875. pr_debug("%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
  876. __func__, payload[0], payload[1],
  877. data->token);
  878. if (ac->io_mode & SYNC_IO_MODE) {
  879. if (port->buf == NULL) {
  880. pr_err("%s: Unexpected Write Done\n",
  881. __func__);
  882. return -EINVAL;
  883. }
  884. spin_lock_irqsave(&port->dsp_lock, dsp_flags);
  885. if (port->buf[data->token].phys !=
  886. payload[0]) {
  887. pr_err("Buf expected[%p]rxed[%p]\n",\
  888. (void *)port->buf[data->token].phys,\
  889. (void *)payload[0]);
  890. spin_unlock_irqrestore(&port->dsp_lock,
  891. dsp_flags);
  892. return -EINVAL;
  893. }
  894. token = data->token;
  895. port->buf[token].used = 1;
  896. spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
  897. #ifdef CONFIG_DEBUG_FS
  898. if (out_enable_flag) {
  899. /* For first Write done log the time and reset
  900. out_cold_index*/
  901. if (out_cold_index != 1) {
  902. do_gettimeofday(&out_cold_tv);
  903. pr_debug("COLD: apr_send_pkt at %ld sec %ld microsec\n",
  904. out_cold_tv.tv_sec,
  905. out_cold_tv.tv_usec);
  906. out_cold_index = 1;
  907. }
  908. pr_debug("out_enable_flag %ld",\
  909. out_enable_flag);
  910. }
  911. #endif
  912. for (i = 0; i < port->max_buf_cnt; i++)
  913. pr_debug("%d ", port->buf[i].used);
  914. }
  915. break;
  916. }
  917. case ASM_STREAM_CMDRSP_GET_PP_PARAMS:
  918. rtac_make_asm_callback(ac->session, payload,
  919. data->payload_size);
  920. break;
  921. case ASM_DATA_EVENT_READ_DONE:{
  922. struct audio_port_data *port = &ac->port[OUT];
  923. #ifdef CONFIG_DEBUG_FS
  924. if (in_enable_flag) {
  925. /* when in_cont_index == 7, DSP would be
  926. * writing into the 8th 512 byte buffer and this
  927. * timestamp is tapped here.Once done it then writes
  928. * to 9th 512 byte buffer.These two buffers(8th, 9th)
  929. * reach the test application in 5th iteration and that
  930. * timestamp is tapped at user level. The difference
  931. * of these two timestamps gives us the time between
  932. * the time at which dsp started filling the sample
  933. * required and when it reached the test application.
  934. * Hence continuous input latency
  935. */
  936. if (in_cont_index == 7) {
  937. do_gettimeofday(&in_cont_tv);
  938. pr_err("In_CONT:previous read buffer done at %ld sec %ld microsec\n",
  939. in_cont_tv.tv_sec, in_cont_tv.tv_usec);
  940. }
  941. }
  942. #endif
  943. pr_debug("%s:R-D: status=%d buff_add=%x act_size=%d offset=%d\n",
  944. __func__, payload[READDONE_IDX_STATUS],
  945. payload[READDONE_IDX_BUFFER],
  946. payload[READDONE_IDX_SIZE],
  947. payload[READDONE_IDX_OFFSET]);
  948. pr_debug("%s:R-D:msw_ts=%d lsw_ts=%d flags=%d id=%d num=%d\n",
  949. __func__, payload[READDONE_IDX_MSW_TS],
  950. payload[READDONE_IDX_LSW_TS],
  951. payload[READDONE_IDX_FLAGS],
  952. payload[READDONE_IDX_ID],
  953. payload[READDONE_IDX_NUMFRAMES]);
  954. #ifdef CONFIG_DEBUG_FS
  955. if (in_enable_flag)
  956. in_cont_index++;
  957. #endif
  958. if (ac->io_mode & SYNC_IO_MODE) {
  959. if (port->buf == NULL) {
  960. pr_err("%s: Unexpected Write Done\n", __func__);
  961. return -EINVAL;
  962. }
  963. spin_lock_irqsave(&port->dsp_lock, dsp_flags);
  964. token = data->token;
  965. port->buf[token].used = 0;
  966. if (port->buf[token].phys !=
  967. payload[READDONE_IDX_BUFFER]) {
  968. pr_err("Buf expected[%p]rxed[%p]\n",\
  969. (void *)port->buf[token].phys,\
  970. (void *)payload[READDONE_IDX_BUFFER]);
  971. spin_unlock_irqrestore(&port->dsp_lock,
  972. dsp_flags);
  973. break;
  974. }
  975. port->buf[token].actual_size =
  976. payload[READDONE_IDX_SIZE];
  977. spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
  978. }
  979. break;
  980. }
  981. case ASM_DATA_EVENT_EOS:
  982. case ASM_DATA_CMDRSP_EOS:
  983. pr_debug("%s:EOS ACK received: rxed opcode[0x%x]\n",
  984. __func__, data->opcode);
  985. break;
  986. case ASM_STREAM_CMDRSP_GET_ENCDEC_PARAM:
  987. break;
  988. case ASM_SESSION_EVENT_TX_OVERFLOW:
  989. pr_err("ASM_SESSION_EVENT_TX_OVERFLOW\n");
  990. break;
  991. case ASM_SESSION_CMDRSP_GET_SESSION_TIME:
  992. pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSION_TIME, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
  993. __func__,
  994. payload[0], payload[1], payload[2]);
  995. ac->time_stamp = (uint64_t)(((uint64_t)payload[1] << 32) |
  996. payload[2]);
  997. if (atomic_read(&ac->time_flag)) {
  998. atomic_set(&ac->time_flag, 0);
  999. wake_up(&ac->time_wait);
  1000. }
  1001. break;
  1002. case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
  1003. case ASM_DATA_EVENT_ENC_SR_CM_NOTIFY:
  1004. pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n",
  1005. __func__,
  1006. payload[0], payload[1], payload[2],
  1007. payload[3]);
  1008. break;
  1009. }
  1010. if (ac->cb)
  1011. ac->cb(data->opcode, data->token,
  1012. data->payload, ac->priv);
  1013. return 0;
  1014. }
  1015. int q6asm_open_transcode_loopback(struct audio_client *ac, uint32_t channels)
  1016. {
  1017. int rc = 0x00;
  1018. struct asm_stream_cmd_open_transcode_loopback open;
  1019. if ((ac == NULL) || (ac->apr == NULL)) {
  1020. pr_err("%s: APR handle NULL\n", __func__);
  1021. return -EINVAL;
  1022. }
  1023. pr_debug("%s: session[%d] channels = %d", __func__, ac->session,
  1024. channels);
  1025. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1026. open.hdr.opcode = ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK;
  1027. open.mode_flags = 0;
  1028. if (channels > 2)
  1029. open.src_format_id = MULTI_CHANNEL_PCM;
  1030. else
  1031. open.src_format_id = LINEAR_PCM;
  1032. open.sink_format_id = DTS;
  1033. open.audproc_topo_id = DEFAULT_POPP_TOPOLOGY;
  1034. open.src_endpoint_type = 0;
  1035. open.sink_endpoint_type = 0;
  1036. open.bits_per_sample = 16;
  1037. open.reserved = 0;
  1038. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1039. if (rc < 0) {
  1040. pr_err("%s: open failed op[0x%x]rc[%d]\n", \
  1041. __func__, open.hdr.opcode, rc);
  1042. goto fail_cmd;
  1043. }
  1044. rc = wait_event_timeout(ac->cmd_wait,
  1045. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1046. if (!rc) {
  1047. pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
  1048. rc);
  1049. goto fail_cmd;
  1050. }
  1051. return 0;
  1052. fail_cmd:
  1053. return -EINVAL;
  1054. }
  1055. int q6asm_enc_cfg_blk_dts(struct audio_client *ac,
  1056. uint32_t sample_rate,
  1057. uint32_t channels)
  1058. {
  1059. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  1060. int rc = 0;
  1061. pr_debug("%s: sample_rate=%d,channels=%d\n", __func__,
  1062. sample_rate, channels);
  1063. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  1064. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  1065. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  1066. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  1067. enc_cfg.enc_blk.frames_per_buf = 0;
  1068. enc_cfg.enc_blk.format_id = DTS;
  1069. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_dts_enc_cfg);
  1070. enc_cfg.enc_blk.cfg.dts.sample_rate = sample_rate;
  1071. enc_cfg.enc_blk.cfg.dts.num_channels = channels;
  1072. if (channels == 1) {
  1073. enc_cfg.enc_blk.cfg.dts.channel_mapping[0] = PCM_CHANNEL_FC;
  1074. } else if (channels == 2) {
  1075. enc_cfg.enc_blk.cfg.dts.channel_mapping[0] = PCM_CHANNEL_FL;
  1076. enc_cfg.enc_blk.cfg.dts.channel_mapping[1] = PCM_CHANNEL_FR;
  1077. enc_cfg.enc_blk.cfg.dts.channel_mapping[2] = 0;
  1078. enc_cfg.enc_blk.cfg.dts.channel_mapping[3] = 0;
  1079. enc_cfg.enc_blk.cfg.dts.channel_mapping[4] = 0;
  1080. enc_cfg.enc_blk.cfg.dts.channel_mapping[5] = 0;
  1081. } else if (channels == 4) {
  1082. enc_cfg.enc_blk.cfg.dts.channel_mapping[0] = PCM_CHANNEL_FL;
  1083. enc_cfg.enc_blk.cfg.dts.channel_mapping[1] = PCM_CHANNEL_FR;
  1084. enc_cfg.enc_blk.cfg.dts.channel_mapping[2] = PCM_CHANNEL_LS;
  1085. enc_cfg.enc_blk.cfg.dts.channel_mapping[3] = PCM_CHANNEL_RS;
  1086. enc_cfg.enc_blk.cfg.dts.channel_mapping[4] = 0;
  1087. enc_cfg.enc_blk.cfg.dts.channel_mapping[5] = 0;
  1088. } else if (channels == 6) {
  1089. enc_cfg.enc_blk.cfg.dts.channel_mapping[0] = PCM_CHANNEL_FC;
  1090. enc_cfg.enc_blk.cfg.dts.channel_mapping[1] = PCM_CHANNEL_FL;
  1091. enc_cfg.enc_blk.cfg.dts.channel_mapping[2] = PCM_CHANNEL_FR;
  1092. enc_cfg.enc_blk.cfg.dts.channel_mapping[3] = PCM_CHANNEL_LS;
  1093. enc_cfg.enc_blk.cfg.dts.channel_mapping[4] = PCM_CHANNEL_RS;
  1094. enc_cfg.enc_blk.cfg.dts.channel_mapping[5] = PCM_CHANNEL_LFE;
  1095. }
  1096. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  1097. if (rc < 0) {
  1098. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  1099. rc = -EINVAL;
  1100. goto fail_cmd;
  1101. }
  1102. rc = wait_event_timeout(ac->cmd_wait,
  1103. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1104. if (!rc) {
  1105. pr_err("timeout. waited for FORMAT_UPDATE\n");
  1106. goto fail_cmd;
  1107. }
  1108. return 0;
  1109. fail_cmd:
  1110. return -EINVAL;
  1111. }
  1112. void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size,
  1113. uint32_t *index)
  1114. {
  1115. void *data;
  1116. unsigned char idx;
  1117. struct audio_port_data *port;
  1118. if (!ac || ((dir != IN) && (dir != OUT)))
  1119. return NULL;
  1120. if (ac->io_mode & SYNC_IO_MODE) {
  1121. port = &ac->port[dir];
  1122. mutex_lock(&port->lock);
  1123. idx = port->cpu_buf;
  1124. if (port->buf == NULL) {
  1125. pr_debug("%s:Buffer pointer null\n", __func__);
  1126. mutex_unlock(&port->lock);
  1127. return NULL;
  1128. }
  1129. /* dir 0: used = 0 means buf in use
  1130. dir 1: used = 1 means buf in use */
  1131. if (port->buf[idx].used == dir) {
  1132. /* To make it more robust, we could loop and get the
  1133. next avail buf, its risky though */
  1134. pr_debug("%s:Next buf idx[0x%x] not available,dir[%d]\n",
  1135. __func__, idx, dir);
  1136. mutex_unlock(&port->lock);
  1137. return NULL;
  1138. }
  1139. *size = port->buf[idx].actual_size;
  1140. *index = port->cpu_buf;
  1141. data = port->buf[idx].data;
  1142. pr_debug("%s:session[%d]index[%d] data[%p]size[%d]\n",
  1143. __func__,
  1144. ac->session,
  1145. port->cpu_buf,
  1146. data, *size);
  1147. /* By default increase the cpu_buf cnt
  1148. user accesses this function,increase cpu
  1149. buf(to avoid another api)*/
  1150. port->buf[idx].used = dir;
  1151. port->cpu_buf = ((port->cpu_buf + 1) & (port->max_buf_cnt - 1));
  1152. mutex_unlock(&port->lock);
  1153. return data;
  1154. }
  1155. return NULL;
  1156. }
  1157. void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac,
  1158. uint32_t *size, uint32_t *index)
  1159. {
  1160. void *data;
  1161. unsigned char idx;
  1162. struct audio_port_data *port;
  1163. if (!ac || ((dir != IN) && (dir != OUT)))
  1164. return NULL;
  1165. port = &ac->port[dir];
  1166. idx = port->cpu_buf;
  1167. if (port->buf == NULL) {
  1168. pr_debug("%s:Buffer pointer null\n", __func__);
  1169. return NULL;
  1170. }
  1171. /*
  1172. * dir 0: used = 0 means buf in use
  1173. * dir 1: used = 1 means buf in use
  1174. */
  1175. if (port->buf[idx].used == dir) {
  1176. /*
  1177. * To make it more robust, we could loop and get the
  1178. * next avail buf, its risky though
  1179. */
  1180. pr_debug("%s:Next buf idx[0x%x] not available, dir[%d]\n",
  1181. __func__, idx, dir);
  1182. return NULL;
  1183. }
  1184. *size = port->buf[idx].actual_size;
  1185. *index = port->cpu_buf;
  1186. data = port->buf[idx].data;
  1187. pr_debug("%s:session[%d]index[%d] data[%p]size[%d]\n",
  1188. __func__, ac->session, port->cpu_buf,
  1189. data, *size);
  1190. /*
  1191. * By default increase the cpu_buf cnt
  1192. * user accesses this function,increase cpu
  1193. * buf(to avoid another api)
  1194. */
  1195. port->buf[idx].used = dir;
  1196. port->cpu_buf = ((port->cpu_buf + 1) & (port->max_buf_cnt - 1));
  1197. return data;
  1198. }
  1199. int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac)
  1200. {
  1201. int ret = -1;
  1202. struct audio_port_data *port;
  1203. uint32_t idx;
  1204. if (!ac || (dir != OUT))
  1205. return ret;
  1206. if (ac->io_mode & SYNC_IO_MODE) {
  1207. port = &ac->port[dir];
  1208. mutex_lock(&port->lock);
  1209. idx = port->dsp_buf;
  1210. if (port->buf[idx].used == (dir ^ 1)) {
  1211. /* To make it more robust, we could loop and get the
  1212. next avail buf, its risky though */
  1213. pr_err("Next buf idx[0x%x] not available, dir[%d]\n",
  1214. idx, dir);
  1215. mutex_unlock(&port->lock);
  1216. return ret;
  1217. }
  1218. pr_debug("%s: session[%d]dsp_buf=%d cpu_buf=%d\n", __func__,
  1219. ac->session, port->dsp_buf, port->cpu_buf);
  1220. ret = ((port->dsp_buf != port->cpu_buf) ? 0 : -1);
  1221. mutex_unlock(&port->lock);
  1222. }
  1223. return ret;
  1224. }
  1225. static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
  1226. uint32_t pkt_size, uint32_t cmd_flg)
  1227. {
  1228. pr_debug("%s:session=%d pkt size=%d cmd_flg=%d\n", __func__, pkt_size,
  1229. cmd_flg, ac->session);
  1230. mutex_lock(&ac->cmd_lock);
  1231. hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
  1232. APR_HDR_LEN(sizeof(struct apr_hdr)),\
  1233. APR_PKT_VER);
  1234. hdr->src_svc = ((struct apr_svc *)ac->apr)->id;
  1235. hdr->src_domain = APR_DOMAIN_APPS;
  1236. hdr->dest_svc = APR_SVC_ASM;
  1237. hdr->dest_domain = APR_DOMAIN_ADSP;
  1238. hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
  1239. hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
  1240. if (cmd_flg) {
  1241. hdr->token = ac->session;
  1242. atomic_set(&ac->cmd_state, 1);
  1243. }
  1244. hdr->pkt_size = pkt_size;
  1245. mutex_unlock(&ac->cmd_lock);
  1246. return;
  1247. }
  1248. static void q6asm_add_mmaphdr(struct apr_hdr *hdr, uint32_t pkt_size,
  1249. uint32_t cmd_flg)
  1250. {
  1251. struct audio_client *ac;
  1252. pr_debug("%s:pkt size=%d cmd_flg=%d\n", __func__, pkt_size, cmd_flg);
  1253. ac = (struct audio_client *)hdr->token;
  1254. pr_debug("%s: audio_client = %x\n", __func__, (uint32_t)ac);
  1255. hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
  1256. APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
  1257. hdr->src_port = 0;
  1258. hdr->dest_port = 0;
  1259. if (cmd_flg) {
  1260. atomic_set(&ac->cmd_state, 1);
  1261. }
  1262. hdr->pkt_size = pkt_size;
  1263. return;
  1264. }
  1265. int q6asm_open_read(struct audio_client *ac,
  1266. uint32_t format)
  1267. {
  1268. int rc = 0x00;
  1269. struct asm_stream_cmd_open_read open;
  1270. #ifdef CONFIG_DEBUG_FS
  1271. in_cont_index = 0;
  1272. #endif
  1273. if ((ac == NULL) || (ac->apr == NULL)) {
  1274. pr_err("%s: APR handle NULL\n", __func__);
  1275. return -EINVAL;
  1276. }
  1277. pr_debug("%s:session[%d]", __func__, ac->session);
  1278. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1279. open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ;
  1280. /* Stream prio : High, provide meta info with encoded frames */
  1281. open.src_endpoint = ASM_END_POINT_DEVICE_MATRIX;
  1282. open.pre_proc_top = get_asm_topology();
  1283. if (open.pre_proc_top == 0)
  1284. open.pre_proc_top = DEFAULT_POPP_TOPOLOGY;
  1285. switch (format) {
  1286. case FORMAT_LINEAR_PCM:
  1287. open.uMode = STREAM_PRIORITY_HIGH;
  1288. open.format = LINEAR_PCM;
  1289. break;
  1290. case FORMAT_MULTI_CHANNEL_LINEAR_PCM:
  1291. open.uMode = STREAM_PRIORITY_HIGH;
  1292. open.format = MULTI_CHANNEL_PCM;
  1293. break;
  1294. case FORMAT_MPEG4_AAC:
  1295. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1296. open.format = MPEG4_AAC;
  1297. break;
  1298. case FORMAT_V13K:
  1299. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1300. open.format = V13K_FS;
  1301. break;
  1302. case FORMAT_EVRC:
  1303. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1304. open.format = EVRC_FS;
  1305. break;
  1306. case FORMAT_AMRNB:
  1307. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1308. open.format = AMRNB_FS;
  1309. break;
  1310. case FORMAT_AMRWB:
  1311. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1312. open.format = AMRWB_FS;
  1313. break;
  1314. default:
  1315. pr_err("Invalid format[%d]\n", format);
  1316. goto fail_cmd;
  1317. }
  1318. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1319. if (rc < 0) {
  1320. pr_err("open failed op[0x%x]rc[%d]\n", \
  1321. open.hdr.opcode, rc);
  1322. goto fail_cmd;
  1323. }
  1324. rc = wait_event_timeout(ac->cmd_wait,
  1325. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1326. if (!rc) {
  1327. pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
  1328. rc);
  1329. goto fail_cmd;
  1330. }
  1331. ac->io_mode |= TUN_READ_IO_MODE;
  1332. return 0;
  1333. fail_cmd:
  1334. return -EINVAL;
  1335. }
  1336. int q6asm_open_read_v2_1(struct audio_client *ac,
  1337. uint32_t format)
  1338. {
  1339. int rc = 0x00;
  1340. struct asm_stream_cmd_open_read_v2_1 open;
  1341. #ifdef CONFIG_DEBUG_FS
  1342. in_cont_index = 0;
  1343. #endif
  1344. if ((ac == NULL) || (ac->apr == NULL)) {
  1345. pr_err("%s: APR handle NULL\n", __func__);
  1346. return -EINVAL;
  1347. }
  1348. pr_debug("%s:session[%d]", __func__, ac->session);
  1349. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1350. open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V2_1;
  1351. open.src_endpoint = ASM_END_POINT_DEVICE_MATRIX;
  1352. open.pre_proc_top = get_asm_topology();
  1353. if (open.pre_proc_top == 0)
  1354. open.pre_proc_top = DEFAULT_POPP_TOPOLOGY;
  1355. switch (format) {
  1356. case FORMAT_LINEAR_PCM:
  1357. open.uMode = STREAM_PRIORITY_HIGH;
  1358. open.format = LINEAR_PCM;
  1359. break;
  1360. case FORMAT_MULTI_CHANNEL_LINEAR_PCM:
  1361. open.uMode = STREAM_PRIORITY_HIGH;
  1362. open.format = MULTI_CHANNEL_PCM;
  1363. break;
  1364. case FORMAT_MPEG4_AAC:
  1365. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1366. open.format = MPEG4_AAC;
  1367. break;
  1368. case FORMAT_V13K:
  1369. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1370. open.format = V13K_FS;
  1371. break;
  1372. case FORMAT_EVRC:
  1373. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1374. open.format = EVRC_FS;
  1375. break;
  1376. case FORMAT_AMRNB:
  1377. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1378. open.format = AMRNB_FS;
  1379. break;
  1380. case FORMAT_AMRWB:
  1381. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
  1382. open.format = AMRWB_FS;
  1383. break;
  1384. default:
  1385. pr_err("Invalid format[%d]\n", format);
  1386. goto fail_cmd;
  1387. }
  1388. open.uMode = ASM_OPEN_READ_PERF_MODE_BIT;
  1389. open.bits_per_sample = PCM_BITS_PER_SAMPLE;
  1390. open.reserved = 0;
  1391. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1392. if (rc < 0) {
  1393. pr_err("open failed op[0x%x]rc[%d]\n", \
  1394. open.hdr.opcode, rc);
  1395. goto fail_cmd;
  1396. }
  1397. rc = wait_event_timeout(ac->cmd_wait,
  1398. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1399. if (!rc) {
  1400. pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
  1401. rc);
  1402. goto fail_cmd;
  1403. }
  1404. return 0;
  1405. fail_cmd:
  1406. return -EINVAL;
  1407. }
  1408. int q6asm_open_read_compressed(struct audio_client *ac,
  1409. uint32_t frames_per_buffer, uint32_t meta_data_mode)
  1410. {
  1411. int rc = 0x00;
  1412. struct asm_stream_cmd_open_read_compressed open;
  1413. #ifdef CONFIG_DEBUG_FS
  1414. in_cont_index = 0;
  1415. #endif
  1416. if ((ac == NULL) || (ac->apr == NULL)) {
  1417. pr_err("%s: APR handle NULL\n", __func__);
  1418. return -EINVAL;
  1419. }
  1420. pr_debug("%s:session[%d]", __func__, ac->session);
  1421. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1422. open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_COMPRESSED;
  1423. /* hardcoded as following*/
  1424. open.frame_per_buf = frames_per_buffer;
  1425. open.uMode = meta_data_mode;
  1426. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1427. if (rc < 0) {
  1428. pr_err("open failed op[0x%x]rc[%d]\n", open.hdr.opcode, rc);
  1429. goto fail_cmd;
  1430. }
  1431. rc = wait_event_timeout(ac->cmd_wait,
  1432. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1433. if (!rc) {
  1434. pr_err("%s: timeout. waited for OPEN_READ_COMPRESSED rc[%d]\n",
  1435. __func__, rc);
  1436. goto fail_cmd;
  1437. }
  1438. return 0;
  1439. fail_cmd:
  1440. return -EINVAL;
  1441. }
  1442. int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format)
  1443. {
  1444. int rc = 0x00;
  1445. struct asm_stream_cmd_open_write_compressed open;
  1446. if ((ac == NULL) || (ac->apr == NULL)) {
  1447. pr_err("%s: APR handle NULL\n", __func__);
  1448. return -EINVAL;
  1449. }
  1450. pr_debug("%s: session[%d] wr_format[0x%x]", __func__, ac->session,
  1451. format);
  1452. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1453. open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED;
  1454. switch (format) {
  1455. case FORMAT_AC3:
  1456. open.format = AC3_DECODER;
  1457. break;
  1458. case FORMAT_EAC3:
  1459. open.format = EAC3_DECODER;
  1460. break;
  1461. case FORMAT_MP3:
  1462. open.format = MP3;
  1463. break;
  1464. case FORMAT_DTS:
  1465. open.format = DTS;
  1466. break;
  1467. case FORMAT_DTS_LBR:
  1468. open.format = DTS_LBR;
  1469. break;
  1470. case FORMAT_AAC:
  1471. open.format = MPEG4_AAC;
  1472. break;
  1473. case FORMAT_ATRAC:
  1474. open.format = ATRAC;
  1475. break;
  1476. case FORMAT_WMA_V10PRO:
  1477. open.format = WMA_V10PRO;
  1478. break;
  1479. case FORMAT_MAT:
  1480. open.format = MAT;
  1481. break;
  1482. case FORMAT_MP2:
  1483. open.format = MP2;
  1484. break;
  1485. default:
  1486. pr_err("%s: Invalid format[%d]\n", __func__, format);
  1487. goto fail_cmd;
  1488. }
  1489. /*Below flag indicates the DSP that Compressed audio input
  1490. stream is not IEC 61937 or IEC 60958 packetizied*/
  1491. open.flags = 0x00000000;
  1492. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1493. if (rc < 0) {
  1494. pr_err("%s: open failed op[0x%x]rc[%d]\n", \
  1495. __func__, open.hdr.opcode, rc);
  1496. goto fail_cmd;
  1497. }
  1498. rc = wait_event_timeout(ac->cmd_wait,
  1499. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1500. if (!rc) {
  1501. pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
  1502. rc);
  1503. goto fail_cmd;
  1504. }
  1505. if (atomic_read(&ac->cmd_response)) {
  1506. pr_err("%s: format = %x not supported\n", __func__, format);
  1507. goto fail_cmd;
  1508. }
  1509. return 0;
  1510. fail_cmd:
  1511. return -EINVAL;
  1512. }
  1513. int q6asm_open_write(struct audio_client *ac, uint32_t format)
  1514. {
  1515. int rc = 0x00;
  1516. struct asm_stream_cmd_open_write open;
  1517. if ((ac == NULL) || (ac->apr == NULL)) {
  1518. pr_err("%s: APR handle NULL\n", __func__);
  1519. return -EINVAL;
  1520. }
  1521. pr_debug("%s: session[%d] wr_format[0x%x]", __func__, ac->session,
  1522. format);
  1523. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1524. if (ac->perf_mode) {
  1525. pr_debug("%s In Performance/lowlatency mode", __func__);
  1526. open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V2_1;
  1527. open.uMode = ASM_OPEN_WRITE_PERF_MODE_BIT;
  1528. /* source endpoint : matrix */
  1529. open.sink_endpoint = ASM_END_POINT_DEVICE_MATRIX;
  1530. open.stream_handle = PCM_BITS_PER_SAMPLE;
  1531. } else {
  1532. open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE;
  1533. open.uMode = STREAM_PRIORITY_HIGH;
  1534. /* source endpoint : matrix */
  1535. open.sink_endpoint = ASM_END_POINT_DEVICE_MATRIX;
  1536. open.stream_handle = 0x00;
  1537. }
  1538. open.post_proc_top = get_asm_topology();
  1539. if (open.post_proc_top == 0)
  1540. open.post_proc_top = DEFAULT_POPP_TOPOLOGY;
  1541. switch (format) {
  1542. case FORMAT_LINEAR_PCM:
  1543. open.format = LINEAR_PCM;
  1544. break;
  1545. case FORMAT_MULTI_CHANNEL_LINEAR_PCM:
  1546. open.format = MULTI_CHANNEL_PCM;
  1547. break;
  1548. case FORMAT_MPEG4_AAC:
  1549. open.format = MPEG4_AAC;
  1550. break;
  1551. case FORMAT_MPEG4_MULTI_AAC:
  1552. open.format = MPEG4_MULTI_AAC;
  1553. break;
  1554. case FORMAT_WMA_V9:
  1555. open.format = WMA_V9;
  1556. break;
  1557. case FORMAT_WMA_V10PRO:
  1558. open.format = WMA_V10PRO;
  1559. break;
  1560. case FORMAT_MP3:
  1561. open.format = MP3;
  1562. break;
  1563. case FORMAT_DTS:
  1564. open.format = DTS;
  1565. break;
  1566. case FORMAT_DTS_LBR:
  1567. open.format = DTS_LBR;
  1568. break;
  1569. case FORMAT_AMRWB:
  1570. open.format = AMRWB_FS;
  1571. pr_debug("q6asm_open_write FORMAT_AMRWB");
  1572. break;
  1573. case FORMAT_AMR_WB_PLUS:
  1574. open.format = AMR_WB_PLUS;
  1575. pr_debug("q6asm_open_write FORMAT_AMR_WB_PLUS");
  1576. break;
  1577. case FORMAT_MP2:
  1578. open.format = MP2;
  1579. break;
  1580. default:
  1581. pr_err("%s: Invalid format[%d]\n", __func__, format);
  1582. goto fail_cmd;
  1583. }
  1584. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1585. if (rc < 0) {
  1586. pr_err("%s: open failed op[0x%x]rc[%d]\n", \
  1587. __func__, open.hdr.opcode, rc);
  1588. goto fail_cmd;
  1589. }
  1590. rc = wait_event_timeout(ac->cmd_wait,
  1591. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1592. if (!rc) {
  1593. pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
  1594. rc);
  1595. goto fail_cmd;
  1596. }
  1597. if (atomic_read(&ac->cmd_response)) {
  1598. pr_err("%s: format = %x not supported\n", __func__, format);
  1599. goto fail_cmd;
  1600. }
  1601. ac->io_mode |= TUN_WRITE_IO_MODE;
  1602. return 0;
  1603. fail_cmd:
  1604. return -EINVAL;
  1605. }
  1606. int q6asm_open_read_write(struct audio_client *ac,
  1607. uint32_t rd_format,
  1608. uint32_t wr_format)
  1609. {
  1610. int rc = 0x00;
  1611. struct asm_stream_cmd_open_read_write open;
  1612. if ((ac == NULL) || (ac->apr == NULL)) {
  1613. pr_err("APR handle NULL\n");
  1614. return -EINVAL;
  1615. }
  1616. pr_debug("%s: session[%d]", __func__, ac->session);
  1617. pr_debug("wr_format[0x%x]rd_format[0x%x]",
  1618. wr_format, rd_format);
  1619. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1620. open.hdr.opcode = ASM_STREAM_CMD_OPEN_READWRITE;
  1621. open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_NORMAL;
  1622. /* source endpoint : matrix */
  1623. open.post_proc_top = get_asm_topology();
  1624. if (open.post_proc_top == 0)
  1625. open.post_proc_top = DEFAULT_POPP_TOPOLOGY;
  1626. switch (wr_format) {
  1627. case FORMAT_LINEAR_PCM:
  1628. open.write_format = LINEAR_PCM;
  1629. break;
  1630. case FORMAT_MPEG4_AAC:
  1631. open.write_format = MPEG4_AAC;
  1632. break;
  1633. case FORMAT_MPEG4_MULTI_AAC:
  1634. open.write_format = MPEG4_MULTI_AAC;
  1635. break;
  1636. case FORMAT_WMA_V9:
  1637. open.write_format = WMA_V9;
  1638. break;
  1639. case FORMAT_WMA_V10PRO:
  1640. open.write_format = WMA_V10PRO;
  1641. break;
  1642. case FORMAT_AMRNB:
  1643. open.write_format = AMRNB_FS;
  1644. break;
  1645. case FORMAT_AMRWB:
  1646. open.write_format = AMRWB_FS;
  1647. break;
  1648. case FORMAT_AMR_WB_PLUS:
  1649. open.write_format = AMR_WB_PLUS;
  1650. break;
  1651. case FORMAT_V13K:
  1652. open.write_format = V13K_FS;
  1653. break;
  1654. case FORMAT_EVRC:
  1655. open.write_format = EVRC_FS;
  1656. break;
  1657. case FORMAT_EVRCB:
  1658. open.write_format = EVRCB_FS;
  1659. break;
  1660. case FORMAT_EVRCWB:
  1661. open.write_format = EVRCWB_FS;
  1662. break;
  1663. case FORMAT_MP3:
  1664. open.write_format = MP3;
  1665. break;
  1666. case FORMAT_MP2:
  1667. open.write_format = MP2;
  1668. break;
  1669. default:
  1670. pr_err("Invalid format[%d]\n", wr_format);
  1671. goto fail_cmd;
  1672. }
  1673. switch (rd_format) {
  1674. case FORMAT_LINEAR_PCM:
  1675. open.read_format = LINEAR_PCM;
  1676. break;
  1677. case FORMAT_MPEG4_AAC:
  1678. open.read_format = MPEG4_AAC;
  1679. break;
  1680. case FORMAT_V13K:
  1681. open.read_format = V13K_FS;
  1682. break;
  1683. case FORMAT_EVRC:
  1684. open.read_format = EVRC_FS;
  1685. break;
  1686. case FORMAT_AMRNB:
  1687. open.read_format = AMRNB_FS;
  1688. break;
  1689. case FORMAT_AMRWB:
  1690. open.read_format = AMRWB_FS;
  1691. break;
  1692. default:
  1693. pr_err("Invalid format[%d]\n", rd_format);
  1694. goto fail_cmd;
  1695. }
  1696. pr_debug("%s:rdformat[0x%x]wrformat[0x%x]\n", __func__,
  1697. open.read_format, open.write_format);
  1698. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1699. if (rc < 0) {
  1700. pr_err("open failed op[0x%x]rc[%d]\n", \
  1701. open.hdr.opcode, rc);
  1702. goto fail_cmd;
  1703. }
  1704. rc = wait_event_timeout(ac->cmd_wait,
  1705. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1706. if (!rc) {
  1707. pr_err("timeout. waited for OPEN_WRITE rc[%d]\n", rc);
  1708. goto fail_cmd;
  1709. }
  1710. return 0;
  1711. fail_cmd:
  1712. return -EINVAL;
  1713. }
  1714. int q6asm_open_loopack(struct audio_client *ac)
  1715. {
  1716. int rc = 0x00;
  1717. struct asm_stream_cmd_open_loopback open;
  1718. if ((ac == NULL) || (ac->apr == NULL)) {
  1719. pr_err("APR handle NULL\n");
  1720. return -EINVAL;
  1721. }
  1722. pr_debug("%s: session[%d]", __func__, ac->session);
  1723. q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
  1724. open.hdr.opcode = ASM_STREAM_CMD_OPEN_LOOPBACK;
  1725. open.mode_flags = 0;
  1726. open.src_endpointype = 0;
  1727. open.sink_endpointype = 0;
  1728. /* source endpoint : matrix */
  1729. open.postprocopo_id = get_asm_topology();
  1730. if (open.postprocopo_id == 0)
  1731. open.postprocopo_id = DEFAULT_POPP_TOPOLOGY;
  1732. rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
  1733. if (rc < 0) {
  1734. pr_err("open failed op[0x%x]rc[%d]\n", \
  1735. open.hdr.opcode, rc);
  1736. goto fail_cmd;
  1737. }
  1738. rc = wait_event_timeout(ac->cmd_wait,
  1739. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1740. if (!rc) {
  1741. pr_err("timeout. waited for OPEN_WRITE rc[%d]\n", rc);
  1742. goto fail_cmd;
  1743. }
  1744. return 0;
  1745. fail_cmd:
  1746. return -EINVAL;
  1747. }
  1748. int q6asm_run(struct audio_client *ac, uint32_t flags,
  1749. uint32_t msw_ts, uint32_t lsw_ts)
  1750. {
  1751. struct asm_stream_cmd_run run;
  1752. int rc;
  1753. if (!ac || ac->apr == NULL) {
  1754. pr_err("APR handle NULL\n");
  1755. return -EINVAL;
  1756. }
  1757. pr_debug("%s session[%d]", __func__, ac->session);
  1758. q6asm_add_hdr(ac, &run.hdr, sizeof(run), TRUE);
  1759. run.hdr.opcode = ASM_SESSION_CMD_RUN;
  1760. run.flags = flags;
  1761. run.msw_ts = msw_ts;
  1762. run.lsw_ts = lsw_ts;
  1763. #ifdef CONFIG_DEBUG_FS
  1764. if (out_enable_flag) {
  1765. do_gettimeofday(&out_cold_tv);
  1766. pr_debug("COLD: apr_send_pkt at %ld sec %ld microsec\n",\
  1767. out_cold_tv.tv_sec, out_cold_tv.tv_usec);
  1768. }
  1769. #endif
  1770. rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
  1771. if (rc < 0) {
  1772. pr_err("Commmand run failed[%d]", rc);
  1773. goto fail_cmd;
  1774. }
  1775. rc = wait_event_timeout(ac->cmd_wait,
  1776. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1777. if (!rc) {
  1778. pr_err("timeout. waited for run success rc[%d]", rc);
  1779. goto fail_cmd;
  1780. }
  1781. return 0;
  1782. fail_cmd:
  1783. return -EINVAL;
  1784. }
  1785. int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
  1786. uint32_t msw_ts, uint32_t lsw_ts)
  1787. {
  1788. struct asm_stream_cmd_run run;
  1789. int rc;
  1790. if (!ac || ac->apr == NULL) {
  1791. pr_err("%s:APR handle NULL\n", __func__);
  1792. return -EINVAL;
  1793. }
  1794. pr_debug("session[%d]", ac->session);
  1795. q6asm_add_hdr_async(ac, &run.hdr, sizeof(run), TRUE);
  1796. run.hdr.opcode = ASM_SESSION_CMD_RUN;
  1797. run.flags = flags;
  1798. run.msw_ts = msw_ts;
  1799. run.lsw_ts = lsw_ts;
  1800. rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
  1801. if (rc < 0) {
  1802. pr_err("%s:Commmand run failed[%d]", __func__, rc);
  1803. return -EINVAL;
  1804. }
  1805. atomic_inc(&ac->nowait_cmd_cnt);
  1806. return 0;
  1807. }
  1808. int q6asm_enc_cfg_blk_aac(struct audio_client *ac,
  1809. uint32_t frames_per_buf,
  1810. uint32_t sample_rate, uint32_t channels,
  1811. uint32_t bit_rate, uint32_t mode, uint32_t format)
  1812. {
  1813. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  1814. int rc = 0;
  1815. pr_debug("%s:session[%d]frames[%d]SR[%d]ch[%d]bitrate[%d]mode[%d] format[%d]",
  1816. __func__, ac->session, frames_per_buf,
  1817. sample_rate, channels, bit_rate, mode, format);
  1818. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  1819. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  1820. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  1821. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  1822. enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
  1823. enc_cfg.enc_blk.format_id = MPEG4_AAC;
  1824. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_aac_read_cfg);
  1825. enc_cfg.enc_blk.cfg.aac.bitrate = bit_rate;
  1826. enc_cfg.enc_blk.cfg.aac.enc_mode = mode;
  1827. enc_cfg.enc_blk.cfg.aac.format = format;
  1828. enc_cfg.enc_blk.cfg.aac.ch_cfg = channels;
  1829. enc_cfg.enc_blk.cfg.aac.sample_rate = sample_rate;
  1830. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  1831. if (rc < 0) {
  1832. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  1833. rc = -EINVAL;
  1834. goto fail_cmd;
  1835. }
  1836. rc = wait_event_timeout(ac->cmd_wait,
  1837. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1838. if (!rc) {
  1839. pr_err("timeout. waited for FORMAT_UPDATE\n");
  1840. goto fail_cmd;
  1841. }
  1842. return 0;
  1843. fail_cmd:
  1844. return -EINVAL;
  1845. }
  1846. int q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
  1847. uint32_t rate, uint32_t channels)
  1848. {
  1849. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  1850. int rc = 0;
  1851. pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
  1852. ac->session, rate, channels);
  1853. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  1854. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  1855. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  1856. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  1857. enc_cfg.enc_blk.frames_per_buf = 1;
  1858. enc_cfg.enc_blk.format_id = LINEAR_PCM;
  1859. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_pcm_cfg);
  1860. enc_cfg.enc_blk.cfg.pcm.ch_cfg = channels;
  1861. enc_cfg.enc_blk.cfg.pcm.bits_per_sample = 16;
  1862. enc_cfg.enc_blk.cfg.pcm.sample_rate = rate;
  1863. enc_cfg.enc_blk.cfg.pcm.is_signed = 1;
  1864. enc_cfg.enc_blk.cfg.pcm.interleaved = 1;
  1865. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  1866. if (rc < 0) {
  1867. pr_err("Comamnd open failed\n");
  1868. rc = -EINVAL;
  1869. goto fail_cmd;
  1870. }
  1871. rc = wait_event_timeout(ac->cmd_wait,
  1872. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1873. if (!rc) {
  1874. pr_err("timeout opcode[0x%x] ", enc_cfg.hdr.opcode);
  1875. goto fail_cmd;
  1876. }
  1877. return 0;
  1878. fail_cmd:
  1879. return -EINVAL;
  1880. }
  1881. int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac,
  1882. uint32_t rate, uint32_t channels)
  1883. {
  1884. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  1885. int rc = 0;
  1886. pr_debug("%s: Session %d, rate = %d, channels = %d, setting the rate and channels to 0 for native\n",
  1887. __func__, ac->session, rate, channels);
  1888. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  1889. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  1890. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  1891. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  1892. enc_cfg.enc_blk.frames_per_buf = 1;
  1893. enc_cfg.enc_blk.format_id = LINEAR_PCM;
  1894. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_pcm_cfg);
  1895. enc_cfg.enc_blk.cfg.pcm.ch_cfg = 0;/*channels;*/
  1896. enc_cfg.enc_blk.cfg.pcm.bits_per_sample = 16;
  1897. enc_cfg.enc_blk.cfg.pcm.sample_rate = 0;/*rate;*/
  1898. enc_cfg.enc_blk.cfg.pcm.is_signed = 1;
  1899. enc_cfg.enc_blk.cfg.pcm.interleaved = 1;
  1900. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  1901. if (rc < 0) {
  1902. pr_err("Comamnd open failed\n");
  1903. rc = -EINVAL;
  1904. goto fail_cmd;
  1905. }
  1906. rc = wait_event_timeout(ac->cmd_wait,
  1907. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1908. if (!rc) {
  1909. pr_err("timeout opcode[0x%x] ", enc_cfg.hdr.opcode);
  1910. goto fail_cmd;
  1911. }
  1912. return 0;
  1913. fail_cmd:
  1914. return -EINVAL;
  1915. }
  1916. int q6asm_enc_cfg_blk_multi_ch_pcm(struct audio_client *ac,
  1917. uint32_t rate, uint32_t channels)
  1918. {
  1919. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  1920. int rc = 0;
  1921. pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
  1922. ac->session, rate, channels);
  1923. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  1924. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  1925. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  1926. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  1927. enc_cfg.enc_blk.frames_per_buf = 1;
  1928. enc_cfg.enc_blk.format_id = MULTI_CHANNEL_PCM;
  1929. enc_cfg.enc_blk.cfg_size =
  1930. sizeof(struct asm_multi_channel_pcm_fmt_blk);
  1931. enc_cfg.enc_blk.cfg.mpcm.num_channels = channels;
  1932. enc_cfg.enc_blk.cfg.mpcm.bits_per_sample = 16;
  1933. enc_cfg.enc_blk.cfg.mpcm.sample_rate = rate;
  1934. enc_cfg.enc_blk.cfg.mpcm.is_signed = 1;
  1935. enc_cfg.enc_blk.cfg.mpcm.is_interleaved = 1;
  1936. if (channels == 1) {
  1937. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
  1938. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = 0;
  1939. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
  1940. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = 0;
  1941. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = 0;
  1942. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = 0;
  1943. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
  1944. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
  1945. } else if (channels == 2) {
  1946. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
  1947. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
  1948. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
  1949. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = 0;
  1950. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = 0;
  1951. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = 0;
  1952. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
  1953. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
  1954. } else if (channels == 4) {
  1955. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
  1956. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
  1957. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = PCM_CHANNEL_RB;
  1958. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = PCM_CHANNEL_LB;
  1959. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = 0;
  1960. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = 0;
  1961. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
  1962. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
  1963. } else if (channels == 6) {
  1964. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
  1965. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
  1966. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = PCM_CHANNEL_LFE;
  1967. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = PCM_CHANNEL_FC;
  1968. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = PCM_CHANNEL_LB;
  1969. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = PCM_CHANNEL_RB;
  1970. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
  1971. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
  1972. } else if (channels == 8) {
  1973. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
  1974. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
  1975. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = PCM_CHANNEL_LFE;
  1976. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = PCM_CHANNEL_FC;
  1977. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = PCM_CHANNEL_LB;
  1978. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = PCM_CHANNEL_RB;
  1979. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = PCM_CHANNEL_FLC;
  1980. enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = PCM_CHANNEL_FRC;
  1981. }
  1982. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  1983. if (rc < 0) {
  1984. pr_err("Comamnd open failed\n");
  1985. rc = -EINVAL;
  1986. goto fail_cmd;
  1987. }
  1988. rc = wait_event_timeout(ac->cmd_wait,
  1989. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  1990. if (!rc) {
  1991. pr_err("timeout opcode[0x%x] ", enc_cfg.hdr.opcode);
  1992. goto fail_cmd;
  1993. }
  1994. return 0;
  1995. fail_cmd:
  1996. return -EINVAL;
  1997. }
  1998. int q6asm_enable_sbrps(struct audio_client *ac,
  1999. uint32_t sbr_ps_enable)
  2000. {
  2001. struct asm_stream_cmd_encdec_sbr sbrps;
  2002. int rc = 0;
  2003. pr_debug("%s: Session %d\n", __func__, ac->session);
  2004. q6asm_add_hdr(ac, &sbrps.hdr, sizeof(sbrps), TRUE);
  2005. sbrps.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2006. sbrps.param_id = ASM_ENABLE_SBR_PS;
  2007. sbrps.param_size = sizeof(struct asm_sbr_ps);
  2008. sbrps.sbr_ps.enable = sbr_ps_enable;
  2009. rc = apr_send_pkt(ac->apr, (uint32_t *) &sbrps);
  2010. if (rc < 0) {
  2011. pr_err("Command opcode[0x%x]paramid[0x%x] failed\n",
  2012. ASM_STREAM_CMD_SET_ENCDEC_PARAM,
  2013. ASM_ENABLE_SBR_PS);
  2014. rc = -EINVAL;
  2015. goto fail_cmd;
  2016. }
  2017. rc = wait_event_timeout(ac->cmd_wait,
  2018. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2019. if (!rc) {
  2020. pr_err("timeout opcode[0x%x] ", sbrps.hdr.opcode);
  2021. goto fail_cmd;
  2022. }
  2023. return 0;
  2024. fail_cmd:
  2025. return -EINVAL;
  2026. }
  2027. int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
  2028. uint16_t sce_left, uint16_t sce_right)
  2029. {
  2030. struct asm_stream_cmd_encdec_dualmono dual_mono;
  2031. int rc = 0;
  2032. pr_debug("%s: Session %d, sce_left = %d, sce_right = %d\n",
  2033. __func__, ac->session, sce_left, sce_right);
  2034. q6asm_add_hdr(ac, &dual_mono.hdr, sizeof(dual_mono), TRUE);
  2035. dual_mono.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2036. dual_mono.param_id = ASM_CONFIGURE_DUAL_MONO;
  2037. dual_mono.param_size = sizeof(struct asm_dual_mono);
  2038. dual_mono.channel_map.sce_left = sce_left;
  2039. dual_mono.channel_map.sce_right = sce_right;
  2040. rc = apr_send_pkt(ac->apr, (uint32_t *) &dual_mono);
  2041. if (rc < 0) {
  2042. pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
  2043. __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
  2044. ASM_CONFIGURE_DUAL_MONO);
  2045. rc = -EINVAL;
  2046. goto fail_cmd;
  2047. }
  2048. rc = wait_event_timeout(ac->cmd_wait,
  2049. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2050. if (!rc) {
  2051. pr_err("%s:timeout opcode[0x%x]\n", __func__,
  2052. dual_mono.hdr.opcode);
  2053. goto fail_cmd;
  2054. }
  2055. return 0;
  2056. fail_cmd:
  2057. return -EINVAL;
  2058. }
  2059. int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff)
  2060. {
  2061. struct asm_aac_stereo_mix_coeff_selection_param aac_mix_coeff;
  2062. int rc = 0;
  2063. q6asm_add_hdr(ac, &aac_mix_coeff.hdr, sizeof(aac_mix_coeff), TRUE);
  2064. aac_mix_coeff.hdr.opcode =
  2065. ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2066. aac_mix_coeff.param_id =
  2067. ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG;
  2068. aac_mix_coeff.param_size =
  2069. sizeof(struct asm_aac_stereo_mix_coeff_selection_param);
  2070. aac_mix_coeff.aac_stereo_mix_coeff_flag = mix_coeff;
  2071. pr_debug("%s, mix_coeff = %u", __func__, mix_coeff);
  2072. rc = apr_send_pkt(ac->apr, (uint32_t *) &aac_mix_coeff);
  2073. if (rc < 0) {
  2074. pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
  2075. __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
  2076. ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG);
  2077. rc = -EINVAL;
  2078. goto fail_cmd;
  2079. }
  2080. rc = wait_event_timeout(ac->cmd_wait,
  2081. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2082. if (!rc) {
  2083. pr_err("%s:timeout opcode[0x%x]\n", __func__,
  2084. aac_mix_coeff.hdr.opcode);
  2085. goto fail_cmd;
  2086. }
  2087. return 0;
  2088. fail_cmd:
  2089. return -EINVAL;
  2090. }
  2091. int q6asm_set_encdec_chan_map(struct audio_client *ac,
  2092. uint32_t num_channels)
  2093. {
  2094. struct asm_stream_cmd_encdec_channelmap chan_map;
  2095. u8 *channel_mapping;
  2096. int rc = 0;
  2097. pr_debug("%s: Session %d, num_channels = %d\n",
  2098. __func__, ac->session, num_channels);
  2099. q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE);
  2100. chan_map.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2101. chan_map.param_id = ASM_ENCDEC_DEC_CHAN_MAP;
  2102. chan_map.param_size = sizeof(struct asm_dec_chan_map);
  2103. chan_map.chan_map.num_channels = num_channels;
  2104. channel_mapping =
  2105. chan_map.chan_map.channel_mapping;
  2106. memset(channel_mapping, PCM_CHANNEL_NULL, MAX_CHAN_MAP_CHANNELS);
  2107. if (num_channels == 1) {
  2108. channel_mapping[0] = PCM_CHANNEL_FL;
  2109. } else if (num_channels == 2) {
  2110. channel_mapping[0] = PCM_CHANNEL_FL;
  2111. channel_mapping[1] = PCM_CHANNEL_FR;
  2112. } else if (num_channels == 4) {
  2113. channel_mapping[0] = PCM_CHANNEL_FL;
  2114. channel_mapping[1] = PCM_CHANNEL_FR;
  2115. channel_mapping[1] = PCM_CHANNEL_LB;
  2116. channel_mapping[1] = PCM_CHANNEL_RB;
  2117. } else if (num_channels == 6) {
  2118. channel_mapping[0] = PCM_CHANNEL_FC;
  2119. channel_mapping[1] = PCM_CHANNEL_FL;
  2120. channel_mapping[2] = PCM_CHANNEL_FR;
  2121. channel_mapping[3] = PCM_CHANNEL_LB;
  2122. channel_mapping[4] = PCM_CHANNEL_RB;
  2123. channel_mapping[5] = PCM_CHANNEL_LFE;
  2124. } else if (num_channels == 8) {
  2125. channel_mapping[0] = PCM_CHANNEL_FC;
  2126. channel_mapping[1] = PCM_CHANNEL_FL;
  2127. channel_mapping[2] = PCM_CHANNEL_FR;
  2128. channel_mapping[3] = PCM_CHANNEL_LB;
  2129. channel_mapping[4] = PCM_CHANNEL_RB;
  2130. channel_mapping[5] = PCM_CHANNEL_LFE;
  2131. channel_mapping[6] = PCM_CHANNEL_FLC;
  2132. channel_mapping[7] = PCM_CHANNEL_FRC;
  2133. } else {
  2134. pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__,
  2135. num_channels);
  2136. rc = -EINVAL;
  2137. goto fail_cmd;
  2138. }
  2139. rc = apr_send_pkt(ac->apr, (uint32_t *) &chan_map);
  2140. if (rc < 0) {
  2141. pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
  2142. __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
  2143. ASM_ENCDEC_DEC_CHAN_MAP);
  2144. goto fail_cmd;
  2145. }
  2146. rc = wait_event_timeout(ac->cmd_wait,
  2147. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2148. if (!rc) {
  2149. pr_err("%s:timeout opcode[0x%x]\n", __func__,
  2150. chan_map.hdr.opcode);
  2151. rc = -ETIMEDOUT;
  2152. goto fail_cmd;
  2153. }
  2154. return 0;
  2155. fail_cmd:
  2156. return rc;
  2157. }
  2158. int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
  2159. uint16_t min_rate, uint16_t max_rate,
  2160. uint16_t reduced_rate_level, uint16_t rate_modulation_cmd)
  2161. {
  2162. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  2163. int rc = 0;
  2164. pr_debug("%s:session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] reduced_rate_level[0x%4x]rate_modulation_cmd[0x%4x]",
  2165. __func__,
  2166. ac->session, frames_per_buf, min_rate, max_rate,
  2167. reduced_rate_level, rate_modulation_cmd);
  2168. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  2169. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2170. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  2171. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  2172. enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
  2173. enc_cfg.enc_blk.format_id = V13K_FS;
  2174. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_qcelp13_read_cfg);
  2175. enc_cfg.enc_blk.cfg.qcelp13.min_rate = min_rate;
  2176. enc_cfg.enc_blk.cfg.qcelp13.max_rate = max_rate;
  2177. enc_cfg.enc_blk.cfg.qcelp13.reduced_rate_level = reduced_rate_level;
  2178. enc_cfg.enc_blk.cfg.qcelp13.rate_modulation_cmd = rate_modulation_cmd;
  2179. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  2180. if (rc < 0) {
  2181. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  2182. goto fail_cmd;
  2183. }
  2184. rc = wait_event_timeout(ac->cmd_wait,
  2185. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2186. if (!rc) {
  2187. pr_err("timeout. waited for FORMAT_UPDATE\n");
  2188. goto fail_cmd;
  2189. }
  2190. return 0;
  2191. fail_cmd:
  2192. return -EINVAL;
  2193. }
  2194. int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf,
  2195. uint16_t min_rate, uint16_t max_rate,
  2196. uint16_t rate_modulation_cmd)
  2197. {
  2198. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  2199. int rc = 0;
  2200. pr_debug("%s:session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] rate_modulation_cmd[0x%4x]",
  2201. __func__, ac->session,
  2202. frames_per_buf, min_rate, max_rate, rate_modulation_cmd);
  2203. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  2204. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2205. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  2206. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  2207. enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
  2208. enc_cfg.enc_blk.format_id = EVRC_FS;
  2209. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_evrc_read_cfg);
  2210. enc_cfg.enc_blk.cfg.evrc.min_rate = min_rate;
  2211. enc_cfg.enc_blk.cfg.evrc.max_rate = max_rate;
  2212. enc_cfg.enc_blk.cfg.evrc.rate_modulation_cmd = rate_modulation_cmd;
  2213. enc_cfg.enc_blk.cfg.evrc.reserved = 0;
  2214. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  2215. if (rc < 0) {
  2216. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  2217. goto fail_cmd;
  2218. }
  2219. rc = wait_event_timeout(ac->cmd_wait,
  2220. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2221. if (!rc) {
  2222. pr_err("timeout. waited for FORMAT_UPDATE\n");
  2223. goto fail_cmd;
  2224. }
  2225. return 0;
  2226. fail_cmd:
  2227. return -EINVAL;
  2228. }
  2229. int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf,
  2230. uint16_t band_mode, uint16_t dtx_enable)
  2231. {
  2232. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  2233. int rc = 0;
  2234. pr_debug("%s:session[%d]frames[%d]band_mode[0x%4x]dtx_enable[0x%4x]",
  2235. __func__, ac->session, frames_per_buf, band_mode, dtx_enable);
  2236. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  2237. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2238. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  2239. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  2240. enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
  2241. enc_cfg.enc_blk.format_id = AMRNB_FS;
  2242. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_amrnb_read_cfg);
  2243. enc_cfg.enc_blk.cfg.amrnb.mode = band_mode;
  2244. enc_cfg.enc_blk.cfg.amrnb.dtx_mode = dtx_enable;
  2245. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  2246. if (rc < 0) {
  2247. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  2248. goto fail_cmd;
  2249. }
  2250. rc = wait_event_timeout(ac->cmd_wait,
  2251. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2252. if (!rc) {
  2253. pr_err("timeout. waited for FORMAT_UPDATE\n");
  2254. goto fail_cmd;
  2255. }
  2256. return 0;
  2257. fail_cmd:
  2258. return -EINVAL;
  2259. }
  2260. int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf,
  2261. uint16_t band_mode, uint16_t dtx_enable)
  2262. {
  2263. struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
  2264. int rc = 0;
  2265. pr_debug("%s:session[%d]frames[%d]band_mode[0x%4x]dtx_enable[0x%4x]",
  2266. __func__, ac->session, frames_per_buf, band_mode, dtx_enable);
  2267. q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
  2268. enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
  2269. enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
  2270. enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
  2271. enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
  2272. enc_cfg.enc_blk.format_id = AMRWB_FS;
  2273. enc_cfg.enc_blk.cfg_size = sizeof(struct asm_amrwb_read_cfg);
  2274. enc_cfg.enc_blk.cfg.amrwb.mode = band_mode;
  2275. enc_cfg.enc_blk.cfg.amrwb.dtx_mode = dtx_enable;
  2276. rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
  2277. if (rc < 0) {
  2278. pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
  2279. goto fail_cmd;
  2280. }
  2281. rc = wait_event_timeout(ac->cmd_wait,
  2282. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2283. if (!rc) {
  2284. pr_err("timeout. waited for FORMAT_UPDATE\n");
  2285. goto fail_cmd;
  2286. }
  2287. return 0;
  2288. fail_cmd:
  2289. return -EINVAL;
  2290. }
  2291. int q6asm_media_format_block_pcm(struct audio_client *ac,
  2292. uint32_t rate, uint32_t channels)
  2293. {
  2294. struct asm_stream_media_format_update fmt;
  2295. int rc = 0;
  2296. pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
  2297. channels);
  2298. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2299. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2300. fmt.format = LINEAR_PCM;
  2301. fmt.cfg_size = sizeof(struct asm_pcm_cfg);
  2302. fmt.write_cfg.pcm_cfg.ch_cfg = channels;
  2303. fmt.write_cfg.pcm_cfg.bits_per_sample = 16;
  2304. fmt.write_cfg.pcm_cfg.sample_rate = rate;
  2305. fmt.write_cfg.pcm_cfg.is_signed = 1;
  2306. fmt.write_cfg.pcm_cfg.interleaved = 1;
  2307. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2308. if (rc < 0) {
  2309. pr_err("%s:Comamnd open failed\n", __func__);
  2310. goto fail_cmd;
  2311. }
  2312. rc = wait_event_timeout(ac->cmd_wait,
  2313. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2314. if (!rc) {
  2315. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2316. goto fail_cmd;
  2317. }
  2318. return 0;
  2319. fail_cmd:
  2320. return -EINVAL;
  2321. }
  2322. int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
  2323. uint32_t rate, uint32_t channels, char *channel_map)
  2324. {
  2325. struct asm_stream_media_format_update fmt;
  2326. u8 *channel_mapping;
  2327. int rc = 0;
  2328. pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
  2329. channels);
  2330. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2331. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2332. fmt.format = MULTI_CHANNEL_PCM;
  2333. fmt.cfg_size = sizeof(struct asm_multi_channel_pcm_fmt_blk);
  2334. fmt.write_cfg.multi_ch_pcm_cfg.num_channels = channels;
  2335. fmt.write_cfg.multi_ch_pcm_cfg.bits_per_sample = 16;
  2336. fmt.write_cfg.multi_ch_pcm_cfg.sample_rate = rate;
  2337. fmt.write_cfg.multi_ch_pcm_cfg.is_signed = 1;
  2338. fmt.write_cfg.multi_ch_pcm_cfg.is_interleaved = 1;
  2339. channel_mapping =
  2340. fmt.write_cfg.multi_ch_pcm_cfg.channel_mapping;
  2341. memcpy(channel_mapping, channel_map, PCM_FORMAT_MAX_NUM_CHANNEL);
  2342. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2343. if (rc < 0) {
  2344. pr_err("%s:Comamnd open failed\n", __func__);
  2345. goto fail_cmd;
  2346. }
  2347. rc = wait_event_timeout(ac->cmd_wait,
  2348. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2349. if (!rc) {
  2350. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2351. goto fail_cmd;
  2352. }
  2353. return 0;
  2354. fail_cmd:
  2355. return -EINVAL;
  2356. }
  2357. int q6asm_media_format_block_aac(struct audio_client *ac,
  2358. struct asm_aac_cfg *cfg)
  2359. {
  2360. struct asm_stream_media_format_update fmt;
  2361. int rc = 0;
  2362. pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session,
  2363. cfg->sample_rate, cfg->ch_cfg);
  2364. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2365. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2366. fmt.format = MPEG4_AAC;
  2367. fmt.cfg_size = sizeof(struct asm_aac_cfg);
  2368. fmt.write_cfg.aac_cfg.format = cfg->format;
  2369. fmt.write_cfg.aac_cfg.aot = cfg->aot;
  2370. fmt.write_cfg.aac_cfg.ep_config = cfg->ep_config;
  2371. fmt.write_cfg.aac_cfg.section_data_resilience =
  2372. cfg->section_data_resilience;
  2373. fmt.write_cfg.aac_cfg.scalefactor_data_resilience =
  2374. cfg->scalefactor_data_resilience;
  2375. fmt.write_cfg.aac_cfg.spectral_data_resilience =
  2376. cfg->spectral_data_resilience;
  2377. fmt.write_cfg.aac_cfg.ch_cfg = cfg->ch_cfg;
  2378. fmt.write_cfg.aac_cfg.sample_rate = cfg->sample_rate;
  2379. pr_info("%s:format=%x cfg_size=%d aac-cfg=%x aot=%d ch=%d sr=%d\n",
  2380. __func__, fmt.format, fmt.cfg_size,
  2381. fmt.write_cfg.aac_cfg.format,
  2382. fmt.write_cfg.aac_cfg.aot,
  2383. fmt.write_cfg.aac_cfg.ch_cfg,
  2384. fmt.write_cfg.aac_cfg.sample_rate);
  2385. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2386. if (rc < 0) {
  2387. pr_err("%s:Comamnd open failed\n", __func__);
  2388. goto fail_cmd;
  2389. }
  2390. rc = wait_event_timeout(ac->cmd_wait,
  2391. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2392. if (!rc) {
  2393. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2394. goto fail_cmd;
  2395. }
  2396. return 0;
  2397. fail_cmd:
  2398. return -EINVAL;
  2399. }
  2400. int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
  2401. struct asm_amrwbplus_cfg *cfg)
  2402. {
  2403. struct asm_stream_media_format_update fmt;
  2404. int rc = 0;
  2405. pr_debug("q6asm_media_format_block_amrwbplus");
  2406. pr_debug("%s:session[%d]band-mode[%d]frame-fmt[%d]ch[%d]\n",
  2407. __func__,
  2408. ac->session,
  2409. cfg->amr_band_mode,
  2410. cfg->amr_frame_fmt,
  2411. cfg->num_channels);
  2412. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2413. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2414. fmt.format = AMR_WB_PLUS;
  2415. fmt.cfg_size = cfg->size_bytes;
  2416. fmt.write_cfg.amrwbplus_cfg.size_bytes = cfg->size_bytes;
  2417. fmt.write_cfg.amrwbplus_cfg.version = cfg->version;
  2418. fmt.write_cfg.amrwbplus_cfg.num_channels = cfg->num_channels;
  2419. fmt.write_cfg.amrwbplus_cfg.amr_band_mode = cfg->amr_band_mode;
  2420. fmt.write_cfg.amrwbplus_cfg.amr_dtx_mode = cfg->amr_dtx_mode;
  2421. fmt.write_cfg.amrwbplus_cfg.amr_frame_fmt = cfg->amr_frame_fmt;
  2422. fmt.write_cfg.amrwbplus_cfg.amr_lsf_idx = cfg->amr_lsf_idx;
  2423. pr_debug("%s: num_channels=%x amr_band_mode=%d amr_frame_fmt=%d\n",
  2424. __func__,
  2425. cfg->num_channels,
  2426. cfg->amr_band_mode,
  2427. cfg->amr_frame_fmt);
  2428. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2429. if (rc < 0) {
  2430. pr_err("%s:Comamnd media format update failed..\n", __func__);
  2431. goto fail_cmd;
  2432. }
  2433. rc = wait_event_timeout(ac->cmd_wait,
  2434. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2435. if (!rc) {
  2436. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2437. goto fail_cmd;
  2438. }
  2439. return 0;
  2440. fail_cmd:
  2441. return -EINVAL;
  2442. }
  2443. int q6asm_media_format_block_multi_aac(struct audio_client *ac,
  2444. struct asm_aac_cfg *cfg)
  2445. {
  2446. struct asm_stream_media_format_update fmt;
  2447. int rc = 0;
  2448. pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session,
  2449. cfg->sample_rate, cfg->ch_cfg);
  2450. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2451. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2452. fmt.format = MPEG4_MULTI_AAC;
  2453. fmt.cfg_size = sizeof(struct asm_aac_cfg);
  2454. fmt.write_cfg.aac_cfg.format = cfg->format;
  2455. fmt.write_cfg.aac_cfg.aot = cfg->aot;
  2456. fmt.write_cfg.aac_cfg.ep_config = cfg->ep_config;
  2457. fmt.write_cfg.aac_cfg.section_data_resilience =
  2458. cfg->section_data_resilience;
  2459. fmt.write_cfg.aac_cfg.scalefactor_data_resilience =
  2460. cfg->scalefactor_data_resilience;
  2461. fmt.write_cfg.aac_cfg.spectral_data_resilience =
  2462. cfg->spectral_data_resilience;
  2463. fmt.write_cfg.aac_cfg.ch_cfg = cfg->ch_cfg;
  2464. fmt.write_cfg.aac_cfg.sample_rate = cfg->sample_rate;
  2465. pr_info("%s:format=%x cfg_size=%d aac-cfg=%x aot=%d ch=%d sr=%d\n",
  2466. __func__, fmt.format, fmt.cfg_size,
  2467. fmt.write_cfg.aac_cfg.format,
  2468. fmt.write_cfg.aac_cfg.aot,
  2469. fmt.write_cfg.aac_cfg.ch_cfg,
  2470. fmt.write_cfg.aac_cfg.sample_rate);
  2471. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2472. if (rc < 0) {
  2473. pr_err("%s:Comamnd open failed\n", __func__);
  2474. goto fail_cmd;
  2475. }
  2476. rc = wait_event_timeout(ac->cmd_wait,
  2477. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2478. if (!rc) {
  2479. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2480. goto fail_cmd;
  2481. }
  2482. return 0;
  2483. fail_cmd:
  2484. return -EINVAL;
  2485. }
  2486. int q6asm_media_format_block(struct audio_client *ac, uint32_t format)
  2487. {
  2488. struct asm_stream_media_format_update fmt;
  2489. int rc = 0;
  2490. pr_debug("%s:session[%d] format[0x%x]\n", __func__,
  2491. ac->session, format);
  2492. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2493. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2494. switch (format) {
  2495. case FORMAT_V13K:
  2496. fmt.format = V13K_FS;
  2497. break;
  2498. case FORMAT_EVRC:
  2499. fmt.format = EVRC_FS;
  2500. break;
  2501. case FORMAT_AMRWB:
  2502. fmt.format = AMRWB_FS;
  2503. break;
  2504. case FORMAT_AMR_WB_PLUS:
  2505. fmt.format = AMR_WB_PLUS;
  2506. break;
  2507. case FORMAT_AMRNB:
  2508. fmt.format = AMRNB_FS;
  2509. break;
  2510. case FORMAT_MP3:
  2511. fmt.format = MP3;
  2512. break;
  2513. case FORMAT_DTS:
  2514. fmt.format = DTS;
  2515. break;
  2516. case FORMAT_DTS_LBR:
  2517. fmt.format = DTS_LBR;
  2518. break;
  2519. case FORMAT_MP2:
  2520. fmt.format = MP2;
  2521. break;
  2522. default:
  2523. pr_err("Invalid format[%d]\n", format);
  2524. goto fail_cmd;
  2525. }
  2526. fmt.cfg_size = 0;
  2527. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2528. if (rc < 0) {
  2529. pr_err("%s:Comamnd open failed\n", __func__);
  2530. goto fail_cmd;
  2531. }
  2532. rc = wait_event_timeout(ac->cmd_wait,
  2533. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2534. if (!rc) {
  2535. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2536. goto fail_cmd;
  2537. }
  2538. return 0;
  2539. fail_cmd:
  2540. return -EINVAL;
  2541. }
  2542. int q6asm_media_format_block_wma(struct audio_client *ac,
  2543. void *cfg)
  2544. {
  2545. struct asm_stream_media_format_update fmt;
  2546. struct asm_wma_cfg *wma_cfg = (struct asm_wma_cfg *)cfg;
  2547. int rc = 0;
  2548. pr_debug("session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d], balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x]\n",
  2549. ac->session, wma_cfg->format_tag, wma_cfg->sample_rate,
  2550. wma_cfg->ch_cfg, wma_cfg->avg_bytes_per_sec,
  2551. wma_cfg->block_align, wma_cfg->valid_bits_per_sample,
  2552. wma_cfg->ch_mask, wma_cfg->encode_opt);
  2553. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2554. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2555. fmt.format = WMA_V9;
  2556. fmt.cfg_size = sizeof(struct asm_wma_cfg);
  2557. fmt.write_cfg.wma_cfg.format_tag = wma_cfg->format_tag;
  2558. fmt.write_cfg.wma_cfg.ch_cfg = wma_cfg->ch_cfg;
  2559. fmt.write_cfg.wma_cfg.sample_rate = wma_cfg->sample_rate;
  2560. fmt.write_cfg.wma_cfg.avg_bytes_per_sec = wma_cfg->avg_bytes_per_sec;
  2561. fmt.write_cfg.wma_cfg.block_align = wma_cfg->block_align;
  2562. fmt.write_cfg.wma_cfg.valid_bits_per_sample =
  2563. wma_cfg->valid_bits_per_sample;
  2564. fmt.write_cfg.wma_cfg.ch_mask = wma_cfg->ch_mask;
  2565. fmt.write_cfg.wma_cfg.encode_opt = wma_cfg->encode_opt;
  2566. fmt.write_cfg.wma_cfg.adv_encode_opt = 0;
  2567. fmt.write_cfg.wma_cfg.adv_encode_opt2 = 0;
  2568. fmt.write_cfg.wma_cfg.drc_peak_ref = 0;
  2569. fmt.write_cfg.wma_cfg.drc_peak_target = 0;
  2570. fmt.write_cfg.wma_cfg.drc_ave_ref = 0;
  2571. fmt.write_cfg.wma_cfg.drc_ave_target = 0;
  2572. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2573. if (rc < 0) {
  2574. pr_err("%s:Comamnd open failed\n", __func__);
  2575. goto fail_cmd;
  2576. }
  2577. rc = wait_event_timeout(ac->cmd_wait,
  2578. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2579. if (!rc) {
  2580. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2581. goto fail_cmd;
  2582. }
  2583. return 0;
  2584. fail_cmd:
  2585. return -EINVAL;
  2586. }
  2587. int q6asm_media_format_block_wmapro(struct audio_client *ac,
  2588. void *cfg)
  2589. {
  2590. struct asm_stream_media_format_update fmt;
  2591. struct asm_wmapro_cfg *wmapro_cfg = (struct asm_wmapro_cfg *)cfg;
  2592. int rc = 0;
  2593. pr_debug("session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d], balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x], adv_enc_opt[0x%4x], adv_enc_opt2[0x%8x]\n",
  2594. ac->session, wmapro_cfg->format_tag, wmapro_cfg->sample_rate,
  2595. wmapro_cfg->ch_cfg, wmapro_cfg->avg_bytes_per_sec,
  2596. wmapro_cfg->block_align, wmapro_cfg->valid_bits_per_sample,
  2597. wmapro_cfg->ch_mask, wmapro_cfg->encode_opt,
  2598. wmapro_cfg->adv_encode_opt, wmapro_cfg->adv_encode_opt2);
  2599. q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
  2600. fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
  2601. fmt.format = WMA_V10PRO;
  2602. fmt.cfg_size = sizeof(struct asm_wmapro_cfg);
  2603. fmt.write_cfg.wmapro_cfg.format_tag = wmapro_cfg->format_tag;
  2604. fmt.write_cfg.wmapro_cfg.ch_cfg = wmapro_cfg->ch_cfg;
  2605. fmt.write_cfg.wmapro_cfg.sample_rate = wmapro_cfg->sample_rate;
  2606. fmt.write_cfg.wmapro_cfg.avg_bytes_per_sec =
  2607. wmapro_cfg->avg_bytes_per_sec;
  2608. fmt.write_cfg.wmapro_cfg.block_align = wmapro_cfg->block_align;
  2609. fmt.write_cfg.wmapro_cfg.valid_bits_per_sample =
  2610. wmapro_cfg->valid_bits_per_sample;
  2611. fmt.write_cfg.wmapro_cfg.ch_mask = wmapro_cfg->ch_mask;
  2612. fmt.write_cfg.wmapro_cfg.encode_opt = wmapro_cfg->encode_opt;
  2613. fmt.write_cfg.wmapro_cfg.adv_encode_opt = wmapro_cfg->adv_encode_opt;
  2614. fmt.write_cfg.wmapro_cfg.adv_encode_opt2 = wmapro_cfg->adv_encode_opt2;
  2615. fmt.write_cfg.wmapro_cfg.drc_peak_ref = 0;
  2616. fmt.write_cfg.wmapro_cfg.drc_peak_target = 0;
  2617. fmt.write_cfg.wmapro_cfg.drc_ave_ref = 0;
  2618. fmt.write_cfg.wmapro_cfg.drc_ave_target = 0;
  2619. rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
  2620. if (rc < 0) {
  2621. pr_err("%s:Comamnd open failed\n", __func__);
  2622. goto fail_cmd;
  2623. }
  2624. rc = wait_event_timeout(ac->cmd_wait,
  2625. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2626. if (!rc) {
  2627. pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
  2628. goto fail_cmd;
  2629. }
  2630. return 0;
  2631. fail_cmd:
  2632. return -EINVAL;
  2633. }
  2634. int q6asm_memory_map(struct audio_client *ac, uint32_t buf_add, int dir,
  2635. uint32_t bufsz, uint32_t bufcnt)
  2636. {
  2637. struct asm_stream_cmd_memory_map mem_map;
  2638. int rc = 0;
  2639. if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
  2640. pr_err("APR handle NULL\n");
  2641. return -EINVAL;
  2642. }
  2643. pr_debug("%s: Session[%d]\n", __func__, ac->session);
  2644. mem_map.hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP;
  2645. mem_map.buf_add = buf_add;
  2646. mem_map.buf_size = bufsz * bufcnt;
  2647. mem_map.mempool_id = 0; /* EBI */
  2648. mem_map.reserved = 0;
  2649. pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
  2650. mem_map.hdr.token = (uint32_t)ac;
  2651. q6asm_add_mmaphdr(&mem_map.hdr,
  2652. sizeof(struct asm_stream_cmd_memory_map), TRUE);
  2653. pr_debug("buf add[%x] buf_add_parameter[%x]\n",
  2654. mem_map.buf_add, buf_add);
  2655. rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
  2656. if (rc < 0) {
  2657. pr_err("mem_map op[0x%x]rc[%d]\n",
  2658. mem_map.hdr.opcode, rc);
  2659. rc = -EINVAL;
  2660. goto fail_cmd;
  2661. }
  2662. rc = wait_event_timeout(ac->cmd_wait,
  2663. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2664. if (!rc) {
  2665. pr_err("timeout. waited for memory_map\n");
  2666. rc = -EINVAL;
  2667. goto fail_cmd;
  2668. }
  2669. if (atomic_read(&ac->cmd_response)) {
  2670. pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP cmd failed\n", __func__);
  2671. rc = -EINVAL;
  2672. goto fail_cmd;
  2673. }
  2674. rc = 0;
  2675. fail_cmd:
  2676. return rc;
  2677. }
  2678. int q6asm_memory_unmap(struct audio_client *ac, uint32_t buf_add, int dir)
  2679. {
  2680. struct asm_stream_cmd_memory_unmap mem_unmap;
  2681. int rc = 0;
  2682. if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
  2683. pr_err("APR handle NULL\n");
  2684. return -EINVAL;
  2685. }
  2686. pr_debug("%s: Session[%d]\n", __func__, ac->session);
  2687. pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
  2688. mem_unmap.hdr.token = (uint32_t)ac;
  2689. q6asm_add_mmaphdr(&mem_unmap.hdr,
  2690. sizeof(struct asm_stream_cmd_memory_unmap), TRUE);
  2691. mem_unmap.hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP;
  2692. mem_unmap.buf_add = buf_add;
  2693. rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
  2694. if (rc < 0) {
  2695. pr_err("mem_unmap op[0x%x]rc[%d]\n",
  2696. mem_unmap.hdr.opcode, rc);
  2697. rc = -EINVAL;
  2698. goto fail_cmd;
  2699. }
  2700. rc = wait_event_timeout(ac->cmd_wait,
  2701. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2702. if (!rc) {
  2703. pr_err("timeout. waited for memory_unmap\n");
  2704. rc = -EINVAL;
  2705. goto fail_cmd;
  2706. }
  2707. if (atomic_read(&ac->cmd_response)) {
  2708. pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP cmd failed\n",
  2709. __func__);
  2710. rc = -EINVAL;
  2711. goto fail_cmd;
  2712. }
  2713. rc = 0;
  2714. fail_cmd:
  2715. return rc;
  2716. }
  2717. int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain)
  2718. {
  2719. void *vol_cmd = NULL;
  2720. void *payload = NULL;
  2721. struct asm_pp_params_command *cmd = NULL;
  2722. struct asm_lrchannel_gain_params *lrgain = NULL;
  2723. int sz = 0;
  2724. int rc = 0;
  2725. sz = sizeof(struct asm_pp_params_command) +
  2726. + sizeof(struct asm_lrchannel_gain_params);
  2727. vol_cmd = kzalloc(sz, GFP_KERNEL);
  2728. if (vol_cmd == NULL) {
  2729. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  2730. rc = -EINVAL;
  2731. return rc;
  2732. }
  2733. cmd = (struct asm_pp_params_command *)vol_cmd;
  2734. q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
  2735. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  2736. cmd->payload = NULL;
  2737. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  2738. sizeof(struct asm_lrchannel_gain_params);
  2739. cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
  2740. cmd->params.param_id = L_R_CHANNEL_GAIN_PARAM_ID;
  2741. cmd->params.param_size = sizeof(struct asm_lrchannel_gain_params);
  2742. cmd->params.reserved = 0;
  2743. payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
  2744. lrgain = (struct asm_lrchannel_gain_params *)payload;
  2745. lrgain->left_gain = left_gain;
  2746. lrgain->right_gain = right_gain;
  2747. rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
  2748. if (rc < 0) {
  2749. pr_err("%s: Volume Command failed\n", __func__);
  2750. rc = -EINVAL;
  2751. goto fail_cmd;
  2752. }
  2753. rc = wait_event_timeout(ac->cmd_wait,
  2754. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2755. if (!rc) {
  2756. pr_err("%s: timeout in sending volume command to apr\n",
  2757. __func__);
  2758. rc = -EINVAL;
  2759. goto fail_cmd;
  2760. }
  2761. rc = 0;
  2762. fail_cmd:
  2763. kfree(vol_cmd);
  2764. return rc;
  2765. }
  2766. static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
  2767. uint32_t bufsz, uint32_t bufcnt)
  2768. {
  2769. struct asm_stream_cmd_memory_map_regions *mmap_regions = NULL;
  2770. struct asm_memory_map_regions *mregions = NULL;
  2771. struct audio_port_data *port = NULL;
  2772. struct audio_buffer *ab = NULL;
  2773. void *mmap_region_cmd = NULL;
  2774. void *payload = NULL;
  2775. int rc = 0;
  2776. int i = 0;
  2777. int cmd_size = 0;
  2778. if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
  2779. pr_err("APR handle NULL\n");
  2780. return -EINVAL;
  2781. }
  2782. pr_debug("%s: Session[%d]\n", __func__, ac->session);
  2783. cmd_size = sizeof(struct asm_stream_cmd_memory_map_regions)
  2784. + sizeof(struct asm_memory_map_regions) * bufcnt;
  2785. mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
  2786. if (mmap_region_cmd == NULL) {
  2787. pr_err("%s: Mem alloc failed\n", __func__);
  2788. rc = -EINVAL;
  2789. return rc;
  2790. }
  2791. mmap_regions = (struct asm_stream_cmd_memory_map_regions *)
  2792. mmap_region_cmd;
  2793. mmap_regions->hdr.token = (uint32_t)ac;
  2794. pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
  2795. q6asm_add_mmaphdr(&mmap_regions->hdr, cmd_size, TRUE);
  2796. mmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP_REGIONS;
  2797. mmap_regions->mempool_id = 0;
  2798. mmap_regions->nregions = bufcnt & 0x00ff;
  2799. pr_debug("map_regions->nregions = %d\n", mmap_regions->nregions);
  2800. payload = ((u8 *) mmap_region_cmd +
  2801. sizeof(struct asm_stream_cmd_memory_map_regions));
  2802. mregions = (struct asm_memory_map_regions *)payload;
  2803. port = &ac->port[dir];
  2804. for (i = 0; i < bufcnt; i++) {
  2805. ab = &port->buf[i];
  2806. mregions->phys = ab->phys;
  2807. mregions->buf_size = ab->size;
  2808. ++mregions;
  2809. }
  2810. rc = apr_send_pkt(this_mmap.apr, (uint32_t *) mmap_region_cmd);
  2811. if (rc < 0) {
  2812. pr_err("mmap_regions op[0x%x]rc[%d]\n",
  2813. mmap_regions->hdr.opcode, rc);
  2814. rc = -EINVAL;
  2815. goto fail_cmd;
  2816. }
  2817. rc = wait_event_timeout(ac->cmd_wait,
  2818. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2819. if (!rc) {
  2820. pr_err("timeout. waited for map_regions\n");
  2821. rc = -EINVAL;
  2822. goto fail_cmd;
  2823. }
  2824. if (atomic_read(&ac->cmd_response)) {
  2825. pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP_REGIONS cmd failed\n",
  2826. __func__);
  2827. rc = -EINVAL;
  2828. goto fail_cmd;
  2829. }
  2830. rc = 0;
  2831. fail_cmd:
  2832. kfree(mmap_region_cmd);
  2833. return rc;
  2834. }
  2835. static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir,
  2836. uint32_t bufsz, uint32_t bufcnt)
  2837. {
  2838. struct asm_stream_cmd_memory_unmap_regions *unmap_regions = NULL;
  2839. struct asm_memory_unmap_regions *mregions = NULL;
  2840. struct audio_port_data *port = NULL;
  2841. struct audio_buffer *ab = NULL;
  2842. void *unmap_region_cmd = NULL;
  2843. void *payload = NULL;
  2844. int rc = 0;
  2845. int i = 0;
  2846. int cmd_size = 0;
  2847. if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
  2848. pr_err("APR handle NULL\n");
  2849. return -EINVAL;
  2850. }
  2851. pr_debug("%s: Session[%d]\n", __func__, ac->session);
  2852. cmd_size = sizeof(struct asm_stream_cmd_memory_unmap_regions) +
  2853. sizeof(struct asm_memory_unmap_regions) * bufcnt;
  2854. unmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
  2855. if (unmap_region_cmd == NULL) {
  2856. pr_err("%s: Mem alloc failed\n", __func__);
  2857. rc = -EINVAL;
  2858. return rc;
  2859. }
  2860. unmap_regions = (struct asm_stream_cmd_memory_unmap_regions *)
  2861. unmap_region_cmd;
  2862. unmap_regions->hdr.token = (uint32_t)ac;
  2863. pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
  2864. q6asm_add_mmaphdr(&unmap_regions->hdr, cmd_size, TRUE);
  2865. unmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS;
  2866. unmap_regions->nregions = bufcnt & 0x00ff;
  2867. pr_debug("unmap_regions->nregions = %d\n", unmap_regions->nregions);
  2868. payload = ((u8 *) unmap_region_cmd +
  2869. sizeof(struct asm_stream_cmd_memory_unmap_regions));
  2870. mregions = (struct asm_memory_unmap_regions *)payload;
  2871. port = &ac->port[dir];
  2872. for (i = 0; i < bufcnt; i++) {
  2873. ab = &port->buf[i];
  2874. mregions->phys = ab->phys;
  2875. ++mregions;
  2876. }
  2877. rc = apr_send_pkt(this_mmap.apr, (uint32_t *) unmap_region_cmd);
  2878. if (rc < 0) {
  2879. pr_err("mmap_regions op[0x%x]rc[%d]\n",
  2880. unmap_regions->hdr.opcode, rc);
  2881. goto fail_cmd;
  2882. }
  2883. rc = wait_event_timeout(ac->cmd_wait,
  2884. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2885. if (!rc) {
  2886. pr_err("timeout. waited for unmap_regions\n");
  2887. rc = -EINVAL;
  2888. goto fail_cmd;
  2889. }
  2890. if (atomic_read(&ac->cmd_response)) {
  2891. pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS cmd failed\n",
  2892. __func__);
  2893. rc = -EINVAL;
  2894. goto fail_cmd;
  2895. }
  2896. rc = 0;
  2897. fail_cmd:
  2898. kfree(unmap_region_cmd);
  2899. return rc;
  2900. }
  2901. int q6asm_set_mute(struct audio_client *ac, int muteflag)
  2902. {
  2903. void *vol_cmd = NULL;
  2904. void *payload = NULL;
  2905. struct asm_pp_params_command *cmd = NULL;
  2906. struct asm_mute_params *mute = NULL;
  2907. int sz = 0;
  2908. int rc = 0;
  2909. sz = sizeof(struct asm_pp_params_command) +
  2910. + sizeof(struct asm_mute_params);
  2911. vol_cmd = kzalloc(sz, GFP_KERNEL);
  2912. if (vol_cmd == NULL) {
  2913. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  2914. rc = -EINVAL;
  2915. return rc;
  2916. }
  2917. cmd = (struct asm_pp_params_command *)vol_cmd;
  2918. q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
  2919. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  2920. cmd->payload = NULL;
  2921. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  2922. sizeof(struct asm_mute_params);
  2923. cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
  2924. cmd->params.param_id = MUTE_CONFIG_PARAM_ID;
  2925. cmd->params.param_size = sizeof(struct asm_mute_params);
  2926. cmd->params.reserved = 0;
  2927. payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
  2928. mute = (struct asm_mute_params *)payload;
  2929. mute->muteflag = muteflag;
  2930. rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
  2931. if (rc < 0) {
  2932. pr_err("%s: Mute Command failed\n", __func__);
  2933. rc = -EINVAL;
  2934. goto fail_cmd;
  2935. }
  2936. rc = wait_event_timeout(ac->cmd_wait,
  2937. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2938. if (!rc) {
  2939. pr_err("%s: timeout in sending mute command to apr\n",
  2940. __func__);
  2941. rc = -EINVAL;
  2942. goto fail_cmd;
  2943. }
  2944. rc = 0;
  2945. fail_cmd:
  2946. kfree(vol_cmd);
  2947. return rc;
  2948. }
  2949. int q6asm_set_volume(struct audio_client *ac, int volume)
  2950. {
  2951. void *vol_cmd = NULL;
  2952. void *payload = NULL;
  2953. struct asm_pp_params_command *cmd = NULL;
  2954. struct asm_master_gain_params *mgain = NULL;
  2955. int sz = 0;
  2956. int rc = 0;
  2957. sz = sizeof(struct asm_pp_params_command) +
  2958. + sizeof(struct asm_master_gain_params);
  2959. vol_cmd = kzalloc(sz, GFP_KERNEL);
  2960. if (vol_cmd == NULL) {
  2961. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  2962. rc = -EINVAL;
  2963. return rc;
  2964. }
  2965. cmd = (struct asm_pp_params_command *)vol_cmd;
  2966. q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
  2967. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  2968. cmd->payload = NULL;
  2969. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  2970. sizeof(struct asm_master_gain_params);
  2971. cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
  2972. cmd->params.param_id = MASTER_GAIN_PARAM_ID;
  2973. cmd->params.param_size = sizeof(struct asm_master_gain_params);
  2974. cmd->params.reserved = 0;
  2975. payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
  2976. mgain = (struct asm_master_gain_params *)payload;
  2977. mgain->master_gain = volume;
  2978. mgain->padding = 0x00;
  2979. rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
  2980. if (rc < 0) {
  2981. pr_err("%s: Volume Command failed\n", __func__);
  2982. rc = -EINVAL;
  2983. goto fail_cmd;
  2984. }
  2985. rc = wait_event_timeout(ac->cmd_wait,
  2986. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  2987. if (!rc) {
  2988. pr_err("%s: timeout in sending volume command to apr\n",
  2989. __func__);
  2990. rc = -EINVAL;
  2991. goto fail_cmd;
  2992. }
  2993. rc = 0;
  2994. fail_cmd:
  2995. kfree(vol_cmd);
  2996. return rc;
  2997. }
  2998. int q6asm_set_softpause(struct audio_client *ac,
  2999. struct asm_softpause_params *pause_param)
  3000. {
  3001. void *vol_cmd = NULL;
  3002. void *payload = NULL;
  3003. struct asm_pp_params_command *cmd = NULL;
  3004. struct asm_softpause_params *params = NULL;
  3005. int sz = 0;
  3006. int rc = 0;
  3007. sz = sizeof(struct asm_pp_params_command) +
  3008. + sizeof(struct asm_softpause_params);
  3009. vol_cmd = kzalloc(sz, GFP_KERNEL);
  3010. if (vol_cmd == NULL) {
  3011. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  3012. rc = -EINVAL;
  3013. return rc;
  3014. }
  3015. cmd = (struct asm_pp_params_command *)vol_cmd;
  3016. q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
  3017. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  3018. cmd->payload = NULL;
  3019. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  3020. sizeof(struct asm_softpause_params);
  3021. cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
  3022. cmd->params.param_id = SOFT_PAUSE_PARAM_ID;
  3023. cmd->params.param_size = sizeof(struct asm_softpause_params);
  3024. cmd->params.reserved = 0;
  3025. payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
  3026. params = (struct asm_softpause_params *)payload;
  3027. params->enable = pause_param->enable;
  3028. params->period = pause_param->period;
  3029. params->step = pause_param->step;
  3030. params->rampingcurve = pause_param->rampingcurve;
  3031. pr_debug("%s: soft Pause Command: enable = %d, period = %d, step = %d, curve = %d\n",
  3032. __func__, params->enable,
  3033. params->period, params->step, params->rampingcurve);
  3034. rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
  3035. if (rc < 0) {
  3036. pr_err("%s: Volume Command(soft_pause) failed\n", __func__);
  3037. rc = -EINVAL;
  3038. goto fail_cmd;
  3039. }
  3040. rc = wait_event_timeout(ac->cmd_wait,
  3041. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  3042. if (!rc) {
  3043. pr_err("%s: timeout in sending volume command(soft_pause) to apr\n",
  3044. __func__);
  3045. rc = -EINVAL;
  3046. goto fail_cmd;
  3047. }
  3048. rc = 0;
  3049. fail_cmd:
  3050. kfree(vol_cmd);
  3051. return rc;
  3052. }
  3053. int q6asm_set_softvolume(struct audio_client *ac,
  3054. struct asm_softvolume_params *softvol_param)
  3055. {
  3056. void *vol_cmd = NULL;
  3057. void *payload = NULL;
  3058. struct asm_pp_params_command *cmd = NULL;
  3059. struct asm_softvolume_params *params = NULL;
  3060. int sz = 0;
  3061. int rc = 0;
  3062. sz = sizeof(struct asm_pp_params_command) +
  3063. + sizeof(struct asm_softvolume_params);
  3064. vol_cmd = kzalloc(sz, GFP_KERNEL);
  3065. if (vol_cmd == NULL) {
  3066. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  3067. rc = -EINVAL;
  3068. return rc;
  3069. }
  3070. cmd = (struct asm_pp_params_command *)vol_cmd;
  3071. q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
  3072. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  3073. cmd->payload = NULL;
  3074. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  3075. sizeof(struct asm_softvolume_params);
  3076. cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
  3077. cmd->params.param_id = SOFT_VOLUME_PARAM_ID;
  3078. cmd->params.param_size = sizeof(struct asm_softvolume_params);
  3079. cmd->params.reserved = 0;
  3080. payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
  3081. params = (struct asm_softvolume_params *)payload;
  3082. params->period = softvol_param->period;
  3083. params->step = softvol_param->step;
  3084. params->rampingcurve = softvol_param->rampingcurve;
  3085. pr_debug("%s: soft Volume:opcode = %d,payload_sz =%d,module_id =%d, param_id = %d, param_sz = %d\n",
  3086. __func__,
  3087. cmd->hdr.opcode, cmd->payload_size,
  3088. cmd->params.module_id, cmd->params.param_id,
  3089. cmd->params.param_size);
  3090. pr_debug("%s: soft Volume Command: period = %d, step = %d, curve = %d\n",
  3091. __func__, params->period,
  3092. params->step, params->rampingcurve);
  3093. rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
  3094. if (rc < 0) {
  3095. pr_err("%s: Volume Command(soft_volume) failed\n", __func__);
  3096. rc = -EINVAL;
  3097. goto fail_cmd;
  3098. }
  3099. rc = wait_event_timeout(ac->cmd_wait,
  3100. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  3101. if (!rc) {
  3102. pr_err("%s: timeout in sending volume command(soft_volume) to apr\n",
  3103. __func__);
  3104. rc = -EINVAL;
  3105. goto fail_cmd;
  3106. }
  3107. rc = 0;
  3108. fail_cmd:
  3109. kfree(vol_cmd);
  3110. return rc;
  3111. }
  3112. int q6asm_equalizer(struct audio_client *ac, void *eq)
  3113. {
  3114. void *eq_cmd = NULL;
  3115. void *payload = NULL;
  3116. struct asm_pp_params_command *cmd = NULL;
  3117. struct asm_equalizer_params *equalizer = NULL;
  3118. struct msm_audio_eq_stream_config *eq_params = NULL;
  3119. int i = 0;
  3120. int sz = 0;
  3121. int rc = 0;
  3122. sz = sizeof(struct asm_pp_params_command) +
  3123. + sizeof(struct asm_equalizer_params);
  3124. eq_cmd = kzalloc(sz, GFP_KERNEL);
  3125. if (eq_cmd == NULL) {
  3126. pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
  3127. rc = -EINVAL;
  3128. goto fail_cmd;
  3129. }
  3130. eq_params = (struct msm_audio_eq_stream_config *) eq;
  3131. cmd = (struct asm_pp_params_command *)eq_cmd;
  3132. q6asm_add_hdr(ac, &cmd->hdr, sz, TRUE);
  3133. cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
  3134. cmd->payload = NULL;
  3135. cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
  3136. sizeof(struct asm_equalizer_params);
  3137. cmd->params.module_id = EQUALIZER_MODULE_ID;
  3138. cmd->params.param_id = EQUALIZER_PARAM_ID;
  3139. cmd->params.param_size = sizeof(struct asm_equalizer_params);
  3140. cmd->params.reserved = 0;
  3141. payload = (u8 *)(eq_cmd + sizeof(struct asm_pp_params_command));
  3142. equalizer = (struct asm_equalizer_params *)payload;
  3143. equalizer->enable = eq_params->enable;
  3144. equalizer->num_bands = eq_params->num_bands;
  3145. pr_debug("%s: enable:%d numbands:%d\n", __func__, eq_params->enable,
  3146. eq_params->num_bands);
  3147. for (i = 0; i < eq_params->num_bands; i++) {
  3148. equalizer->eq_bands[i].band_idx =
  3149. eq_params->eq_bands[i].band_idx;
  3150. equalizer->eq_bands[i].filter_type =
  3151. eq_params->eq_bands[i].filter_type;
  3152. equalizer->eq_bands[i].center_freq_hz =
  3153. eq_params->eq_bands[i].center_freq_hz;
  3154. equalizer->eq_bands[i].filter_gain =
  3155. eq_params->eq_bands[i].filter_gain;
  3156. equalizer->eq_bands[i].q_factor =
  3157. eq_params->eq_bands[i].q_factor;
  3158. pr_debug("%s: filter_type:%u bandnum:%d\n", __func__,
  3159. eq_params->eq_bands[i].filter_type, i);
  3160. pr_debug("%s: center_freq_hz:%u bandnum:%d\n", __func__,
  3161. eq_params->eq_bands[i].center_freq_hz, i);
  3162. pr_debug("%s: filter_gain:%d bandnum:%d\n", __func__,
  3163. eq_params->eq_bands[i].filter_gain, i);
  3164. pr_debug("%s: q_factor:%d bandnum:%d\n", __func__,
  3165. eq_params->eq_bands[i].q_factor, i);
  3166. }
  3167. rc = apr_send_pkt(ac->apr, (uint32_t *) eq_cmd);
  3168. if (rc < 0) {
  3169. pr_err("%s: Equalizer Command failed\n", __func__);
  3170. rc = -EINVAL;
  3171. goto fail_cmd;
  3172. }
  3173. rc = wait_event_timeout(ac->cmd_wait,
  3174. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  3175. if (!rc) {
  3176. pr_err("%s: timeout in sending equalizer command to apr\n",
  3177. __func__);
  3178. rc = -EINVAL;
  3179. goto fail_cmd;
  3180. }
  3181. rc = 0;
  3182. fail_cmd:
  3183. kfree(eq_cmd);
  3184. return rc;
  3185. }
  3186. int q6asm_read(struct audio_client *ac)
  3187. {
  3188. struct asm_stream_cmd_read read;
  3189. struct audio_buffer *ab;
  3190. int dsp_buf;
  3191. struct audio_port_data *port;
  3192. int rc;
  3193. if (!ac || ac->apr == NULL) {
  3194. pr_err("APR handle NULL\n");
  3195. return -EINVAL;
  3196. }
  3197. if (ac->io_mode & SYNC_IO_MODE) {
  3198. port = &ac->port[OUT];
  3199. q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE);
  3200. mutex_lock(&port->lock);
  3201. dsp_buf = port->dsp_buf;
  3202. ab = &port->buf[dsp_buf];
  3203. pr_debug("%s:session[%d]dsp-buf[%d][%p]cpu_buf[%d][%p]\n",
  3204. __func__,
  3205. ac->session,
  3206. dsp_buf,
  3207. (void *)port->buf[dsp_buf].data,
  3208. port->cpu_buf,
  3209. (void *)port->buf[port->cpu_buf].phys);
  3210. read.hdr.opcode = ASM_DATA_CMD_READ;
  3211. read.buf_add = ab->phys;
  3212. read.buf_size = ab->size;
  3213. read.uid = port->dsp_buf;
  3214. read.hdr.token = port->dsp_buf;
  3215. port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
  3216. mutex_unlock(&port->lock);
  3217. pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
  3218. read.buf_add,
  3219. read.hdr.token,
  3220. read.uid);
  3221. rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
  3222. if (rc < 0) {
  3223. pr_err("read op[0x%x]rc[%d]\n", read.hdr.opcode, rc);
  3224. goto fail_cmd;
  3225. }
  3226. return 0;
  3227. }
  3228. fail_cmd:
  3229. return -EINVAL;
  3230. }
  3231. int q6asm_read_nolock(struct audio_client *ac)
  3232. {
  3233. struct asm_stream_cmd_read read;
  3234. struct audio_buffer *ab;
  3235. int dsp_buf;
  3236. struct audio_port_data *port;
  3237. int rc;
  3238. if (!ac || ac->apr == NULL) {
  3239. pr_err("APR handle NULL\n");
  3240. return -EINVAL;
  3241. }
  3242. if (ac->io_mode & SYNC_IO_MODE) {
  3243. port = &ac->port[OUT];
  3244. q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
  3245. dsp_buf = port->dsp_buf;
  3246. ab = &port->buf[dsp_buf];
  3247. pr_debug("%s:session[%d]dsp-buf[%d][%p]cpu_buf[%d][%p]\n",
  3248. __func__,
  3249. ac->session,
  3250. dsp_buf,
  3251. (void *)port->buf[dsp_buf].data,
  3252. port->cpu_buf,
  3253. (void *)port->buf[port->cpu_buf].phys);
  3254. read.hdr.opcode = ASM_DATA_CMD_READ;
  3255. read.buf_add = ab->phys;
  3256. read.buf_size = ab->size;
  3257. read.uid = port->dsp_buf;
  3258. read.hdr.token = port->dsp_buf;
  3259. port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
  3260. pr_info("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
  3261. read.buf_add,
  3262. read.hdr.token,
  3263. read.uid);
  3264. rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
  3265. if (rc < 0) {
  3266. pr_err("read op[0x%x]rc[%d]\n", read.hdr.opcode, rc);
  3267. goto fail_cmd;
  3268. }
  3269. return 0;
  3270. }
  3271. fail_cmd:
  3272. return -EINVAL;
  3273. }
  3274. static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
  3275. uint32_t pkt_size, uint32_t cmd_flg)
  3276. {
  3277. pr_debug("session=%d pkt size=%d cmd_flg=%d\n", pkt_size, cmd_flg,
  3278. ac->session);
  3279. hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
  3280. APR_HDR_LEN(sizeof(struct apr_hdr)),\
  3281. APR_PKT_VER);
  3282. hdr->src_svc = ((struct apr_svc *)ac->apr)->id;
  3283. hdr->src_domain = APR_DOMAIN_APPS;
  3284. hdr->dest_svc = APR_SVC_ASM;
  3285. hdr->dest_domain = APR_DOMAIN_ADSP;
  3286. hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
  3287. hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
  3288. if (cmd_flg) {
  3289. hdr->token = ac->session;
  3290. atomic_set(&ac->cmd_state, 1);
  3291. }
  3292. hdr->pkt_size = pkt_size;
  3293. return;
  3294. }
  3295. int q6asm_async_write(struct audio_client *ac,
  3296. struct audio_aio_write_param *param)
  3297. {
  3298. int rc = 0;
  3299. struct asm_stream_cmd_write write;
  3300. if (!ac || ac->apr == NULL) {
  3301. pr_err("%s: APR handle NULL\n", __func__);
  3302. return -EINVAL;
  3303. }
  3304. q6asm_add_hdr_async(ac, &write.hdr, sizeof(write), FALSE);
  3305. /* Pass physical address as token for AIO scheme */
  3306. write.hdr.token = param->uid;
  3307. write.hdr.opcode = ASM_DATA_CMD_WRITE;
  3308. write.buf_add = param->paddr;
  3309. write.avail_bytes = param->len;
  3310. write.uid = param->uid;
  3311. write.msw_ts = param->msw_ts;
  3312. write.lsw_ts = param->lsw_ts;
  3313. /* Use 0xFF00 for disabling timestamps */
  3314. if (param->flags == 0xFF00)
  3315. write.uflags = (0x00000000 | (param->flags & 0x800000FF));
  3316. else
  3317. write.uflags = (0x80000000 | param->flags);
  3318. pr_debug("%s: session[%d] bufadd[0x%x]len[0x%x]", __func__, ac->session,
  3319. write.buf_add, write.avail_bytes);
  3320. rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
  3321. if (rc < 0) {
  3322. pr_debug("[%s] write op[0x%x]rc[%d]\n", __func__,
  3323. write.hdr.opcode, rc);
  3324. goto fail_cmd;
  3325. }
  3326. return 0;
  3327. fail_cmd:
  3328. return -EINVAL;
  3329. }
  3330. int q6asm_async_read(struct audio_client *ac,
  3331. struct audio_aio_read_param *param)
  3332. {
  3333. int rc = 0;
  3334. struct asm_stream_cmd_read read;
  3335. if (!ac || ac->apr == NULL) {
  3336. pr_err("%s: APR handle NULL\n", __func__);
  3337. return -EINVAL;
  3338. }
  3339. q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
  3340. /* Pass physical address as token for AIO scheme */
  3341. read.hdr.token = param->paddr;
  3342. read.hdr.opcode = ASM_DATA_CMD_READ;
  3343. read.buf_add = param->paddr;
  3344. read.buf_size = param->len;
  3345. read.uid = param->uid;
  3346. pr_debug("%s: session[%d] bufadd[0x%x]len[0x%x]", __func__, ac->session,
  3347. read.buf_add, read.buf_size);
  3348. rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
  3349. if (rc < 0) {
  3350. pr_debug("[%s] read op[0x%x]rc[%d]\n", __func__,
  3351. read.hdr.opcode, rc);
  3352. goto fail_cmd;
  3353. }
  3354. return 0;
  3355. fail_cmd:
  3356. return -EINVAL;
  3357. }
  3358. int q6asm_async_read_compressed(struct audio_client *ac,
  3359. struct audio_aio_read_param *param)
  3360. {
  3361. int rc = 0;
  3362. struct asm_stream_cmd_read read;
  3363. if (!ac || ac->apr == NULL) {
  3364. pr_err("%s: APR handle NULL\n", __func__);
  3365. return -EINVAL;
  3366. }
  3367. q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
  3368. /* Pass physical address as token for AIO scheme */
  3369. read.hdr.token = param->paddr;
  3370. read.hdr.opcode = ASM_DATA_CMD_READ_COMPRESSED;
  3371. read.buf_add = param->paddr;
  3372. read.buf_size = param->len;
  3373. read.uid = param->uid;
  3374. pr_debug("%s: session[%d] bufadd[0x%x]len[0x%x]", __func__, ac->session,
  3375. read.buf_add, read.buf_size);
  3376. rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
  3377. if (rc < 0) {
  3378. pr_debug("[%s] read op[0x%x]rc[%d]\n", __func__,
  3379. read.hdr.opcode, rc);
  3380. goto fail_cmd;
  3381. }
  3382. return 0;
  3383. fail_cmd:
  3384. return -EINVAL;
  3385. }
  3386. int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
  3387. uint32_t lsw_ts, uint32_t flags)
  3388. {
  3389. int rc = 0;
  3390. struct asm_stream_cmd_write write;
  3391. struct audio_port_data *port;
  3392. struct audio_buffer *ab;
  3393. int dsp_buf = 0;
  3394. if (!ac || ac->apr == NULL) {
  3395. pr_err("APR handle NULL\n");
  3396. return -EINVAL;
  3397. }
  3398. pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
  3399. if (ac->io_mode & SYNC_IO_MODE) {
  3400. port = &ac->port[IN];
  3401. q6asm_add_hdr(ac, &write.hdr, sizeof(write),
  3402. FALSE);
  3403. mutex_lock(&port->lock);
  3404. dsp_buf = port->dsp_buf;
  3405. ab = &port->buf[dsp_buf];
  3406. write.hdr.token = port->dsp_buf;
  3407. write.hdr.opcode = ASM_DATA_CMD_WRITE;
  3408. write.buf_add = ab->phys;
  3409. write.avail_bytes = len;
  3410. write.uid = port->dsp_buf;
  3411. write.msw_ts = msw_ts;
  3412. write.lsw_ts = lsw_ts;
  3413. /* Use 0xFF00 for disabling timestamps */
  3414. if (flags == 0xFF00)
  3415. write.uflags = (0x00000000 | (flags & 0x800000FF));
  3416. else
  3417. write.uflags = (0x80000000 | flags);
  3418. port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
  3419. pr_debug("%s:ab->phys[0x%x]bufadd[0x%x]token[0x%x]buf_id[0x%x]"
  3420. , __func__,
  3421. ab->phys,
  3422. write.buf_add,
  3423. write.hdr.token,
  3424. write.uid);
  3425. mutex_unlock(&port->lock);
  3426. #ifdef CONFIG_DEBUG_FS
  3427. if (out_enable_flag) {
  3428. char zero_pattern[2] = {0x00, 0x00};
  3429. /* If First two byte is non zero and last two byte
  3430. is zero then it is warm output pattern */
  3431. if ((strncmp(((char *)ab->data), zero_pattern, 2)) &&
  3432. (!strncmp(((char *)ab->data + 2), zero_pattern, 2))) {
  3433. do_gettimeofday(&out_warm_tv);
  3434. pr_debug("WARM:apr_send_pkt at %ld sec %ld microsec\n",
  3435. out_warm_tv.tv_sec,\
  3436. out_warm_tv.tv_usec);
  3437. pr_debug("Warm Pattern Matched");
  3438. }
  3439. /* If First two byte is zero and last two byte is
  3440. non zero then it is cont ouput pattern */
  3441. else if ((!strncmp(((char *)ab->data), zero_pattern, 2))
  3442. && (strncmp(((char *)ab->data + 2), zero_pattern, 2))) {
  3443. do_gettimeofday(&out_cont_tv);
  3444. pr_debug("CONT:apr_send_pkt at %ld sec %ld microsec\n",
  3445. out_cont_tv.tv_sec,\
  3446. out_cont_tv.tv_usec);
  3447. pr_debug("Cont Pattern Matched");
  3448. }
  3449. }
  3450. #endif
  3451. rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
  3452. if (rc < 0) {
  3453. pr_err("write op[0x%x]rc[%d]\n", write.hdr.opcode, rc);
  3454. goto fail_cmd;
  3455. }
  3456. pr_debug("%s: WRITE SUCCESS\n", __func__);
  3457. return 0;
  3458. }
  3459. fail_cmd:
  3460. return -EINVAL;
  3461. }
  3462. int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
  3463. uint32_t lsw_ts, uint32_t flags)
  3464. {
  3465. int rc = 0;
  3466. struct asm_stream_cmd_write write;
  3467. struct audio_port_data *port;
  3468. struct audio_buffer *ab;
  3469. int dsp_buf = 0;
  3470. if (!ac || ac->apr == NULL) {
  3471. pr_err("APR handle NULL\n");
  3472. return -EINVAL;
  3473. }
  3474. pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
  3475. if (ac->io_mode & SYNC_IO_MODE) {
  3476. port = &ac->port[IN];
  3477. q6asm_add_hdr_async(ac, &write.hdr, sizeof(write),
  3478. FALSE);
  3479. dsp_buf = port->dsp_buf;
  3480. ab = &port->buf[dsp_buf];
  3481. write.hdr.token = port->dsp_buf;
  3482. write.hdr.opcode = ASM_DATA_CMD_WRITE;
  3483. write.buf_add = ab->phys;
  3484. write.avail_bytes = len;
  3485. write.uid = port->dsp_buf;
  3486. write.msw_ts = msw_ts;
  3487. write.lsw_ts = lsw_ts;
  3488. /* Use 0xFF00 for disabling timestamps */
  3489. if (flags == 0xFF00)
  3490. write.uflags = (0x00000000 | (flags & 0x800000FF));
  3491. else
  3492. write.uflags = (0x80000000 | flags);
  3493. port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
  3494. pr_debug("%s:ab->phys[0x%x]bufadd[0x%x]token[0x%x]buf_id[0x%x]"
  3495. , __func__,
  3496. ab->phys,
  3497. write.buf_add,
  3498. write.hdr.token,
  3499. write.uid);
  3500. rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
  3501. if (rc < 0) {
  3502. pr_err("write op[0x%x]rc[%d]\n", write.hdr.opcode, rc);
  3503. goto fail_cmd;
  3504. }
  3505. pr_debug("%s: WRITE SUCCESS\n", __func__);
  3506. return 0;
  3507. }
  3508. fail_cmd:
  3509. return -EINVAL;
  3510. }
  3511. int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
  3512. {
  3513. struct apr_hdr hdr;
  3514. int rc;
  3515. if (!ac || ac->apr == NULL || tstamp == NULL) {
  3516. pr_err("APR handle or tstamp NULL\n");
  3517. return -EINVAL;
  3518. }
  3519. q6asm_add_hdr(ac, &hdr, sizeof(hdr), FALSE);
  3520. hdr.opcode = ASM_SESSION_CMD_GET_SESSION_TIME;
  3521. atomic_set(&ac->time_flag, 1);
  3522. pr_debug("%s: session[%d]opcode[0x%x]\n", __func__,
  3523. ac->session,
  3524. hdr.opcode);
  3525. rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
  3526. if (rc < 0) {
  3527. pr_err("Commmand 0x%x failed\n", hdr.opcode);
  3528. goto fail_cmd;
  3529. }
  3530. rc = wait_event_timeout(ac->time_wait,
  3531. (atomic_read(&ac->time_flag) == 0), 5*HZ);
  3532. if (!rc) {
  3533. pr_err("%s: timeout in getting session time from DSP\n",
  3534. __func__);
  3535. goto fail_cmd;
  3536. }
  3537. *tstamp = ac->time_stamp;
  3538. return 0;
  3539. fail_cmd:
  3540. return -EINVAL;
  3541. }
  3542. int q6asm_cmd(struct audio_client *ac, int cmd)
  3543. {
  3544. struct apr_hdr hdr;
  3545. int rc;
  3546. atomic_t *state;
  3547. int cnt = 0;
  3548. if (!ac || ac->apr == NULL) {
  3549. pr_err("APR handle NULL\n");
  3550. return -EINVAL;
  3551. }
  3552. q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
  3553. switch (cmd) {
  3554. case CMD_PAUSE:
  3555. pr_debug("%s:CMD_PAUSE\n", __func__);
  3556. hdr.opcode = ASM_SESSION_CMD_PAUSE;
  3557. state = &ac->cmd_state;
  3558. break;
  3559. case CMD_FLUSH:
  3560. pr_debug("%s:CMD_FLUSH\n", __func__);
  3561. hdr.opcode = ASM_STREAM_CMD_FLUSH;
  3562. state = &ac->cmd_state;
  3563. break;
  3564. case CMD_OUT_FLUSH:
  3565. pr_debug("%s:CMD_OUT_FLUSH\n", __func__);
  3566. hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS;
  3567. state = &ac->cmd_state;
  3568. break;
  3569. case CMD_EOS:
  3570. pr_debug("%s:CMD_EOS\n", __func__);
  3571. hdr.opcode = ASM_DATA_CMD_EOS;
  3572. atomic_set(&ac->cmd_state, 0);
  3573. state = &ac->cmd_state;
  3574. break;
  3575. case CMD_CLOSE:
  3576. pr_debug("%s:CMD_CLOSE\n", __func__);
  3577. hdr.opcode = ASM_STREAM_CMD_CLOSE;
  3578. atomic_set(&ac->cmd_close_state, 1);
  3579. state = &ac->cmd_close_state;
  3580. break;
  3581. default:
  3582. pr_err("Invalid format[%d]\n", cmd);
  3583. goto fail_cmd;
  3584. }
  3585. pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
  3586. ac->session,
  3587. hdr.opcode);
  3588. rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
  3589. if (rc < 0) {
  3590. pr_err("Commmand 0x%x failed\n", hdr.opcode);
  3591. goto fail_cmd;
  3592. }
  3593. rc = wait_event_timeout(ac->cmd_wait, (atomic_read(state) == 0), 5*HZ);
  3594. if (!rc) {
  3595. pr_err("timeout. waited for response opcode[0x%x]\n",
  3596. hdr.opcode);
  3597. goto fail_cmd;
  3598. }
  3599. if (cmd == CMD_FLUSH)
  3600. q6asm_reset_buf_state(ac);
  3601. if (cmd == CMD_CLOSE) {
  3602. /* check if DSP return all buffers */
  3603. if (ac->port[IN].buf) {
  3604. for (cnt = 0; cnt < ac->port[IN].max_buf_cnt;
  3605. cnt++) {
  3606. if (ac->port[IN].buf[cnt].used == IN) {
  3607. pr_debug("Write Buf[%d] not returned\n",
  3608. cnt);
  3609. }
  3610. }
  3611. }
  3612. if (ac->port[OUT].buf) {
  3613. for (cnt = 0; cnt < ac->port[OUT].max_buf_cnt; cnt++) {
  3614. if (ac->port[OUT].buf[cnt].used == OUT) {
  3615. pr_debug("Read Buf[%d] not returned\n",
  3616. cnt);
  3617. }
  3618. }
  3619. }
  3620. }
  3621. return 0;
  3622. fail_cmd:
  3623. return -EINVAL;
  3624. }
  3625. int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
  3626. {
  3627. struct apr_hdr hdr;
  3628. int rc;
  3629. if (!ac || ac->apr == NULL) {
  3630. pr_err("%s:APR handle NULL\n", __func__);
  3631. return -EINVAL;
  3632. }
  3633. q6asm_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE);
  3634. switch (cmd) {
  3635. case CMD_PAUSE:
  3636. pr_debug("%s:CMD_PAUSE\n", __func__);
  3637. hdr.opcode = ASM_SESSION_CMD_PAUSE;
  3638. break;
  3639. case CMD_EOS:
  3640. pr_debug("%s:CMD_EOS\n", __func__);
  3641. hdr.opcode = ASM_DATA_CMD_EOS;
  3642. break;
  3643. default:
  3644. pr_err("%s:Invalid format[%d]\n", __func__, cmd);
  3645. goto fail_cmd;
  3646. }
  3647. pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
  3648. ac->session,
  3649. hdr.opcode);
  3650. rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
  3651. if (rc < 0) {
  3652. pr_err("%s:Commmand 0x%x failed\n", __func__, hdr.opcode);
  3653. goto fail_cmd;
  3654. }
  3655. atomic_inc(&ac->nowait_cmd_cnt);
  3656. return 0;
  3657. fail_cmd:
  3658. return -EINVAL;
  3659. }
  3660. static void q6asm_reset_buf_state(struct audio_client *ac)
  3661. {
  3662. int cnt = 0;
  3663. int loopcnt = 0;
  3664. int used;
  3665. struct audio_port_data *port = NULL;
  3666. if (ac->io_mode & SYNC_IO_MODE) {
  3667. used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0);
  3668. mutex_lock(&ac->cmd_lock);
  3669. for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
  3670. port = &ac->port[loopcnt];
  3671. cnt = port->max_buf_cnt - 1;
  3672. port->dsp_buf = 0;
  3673. port->cpu_buf = 0;
  3674. while (cnt >= 0) {
  3675. if (!port->buf)
  3676. continue;
  3677. port->buf[cnt].used = used;
  3678. cnt--;
  3679. }
  3680. }
  3681. mutex_unlock(&ac->cmd_lock);
  3682. }
  3683. }
  3684. int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable)
  3685. {
  3686. struct asm_stream_cmd_reg_tx_overflow_event tx_overflow;
  3687. int rc;
  3688. if (!ac || ac->apr == NULL) {
  3689. pr_err("APR handle NULL\n");
  3690. return -EINVAL;
  3691. }
  3692. pr_debug("%s:session[%d]enable[%d]\n", __func__,
  3693. ac->session, enable);
  3694. q6asm_add_hdr(ac, &tx_overflow.hdr, sizeof(tx_overflow), TRUE);
  3695. tx_overflow.hdr.opcode = \
  3696. ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS;
  3697. /* tx overflow event: enable */
  3698. tx_overflow.enable = enable;
  3699. rc = apr_send_pkt(ac->apr, (uint32_t *) &tx_overflow);
  3700. if (rc < 0) {
  3701. pr_err("tx overflow op[0x%x]rc[%d]\n", \
  3702. tx_overflow.hdr.opcode, rc);
  3703. goto fail_cmd;
  3704. }
  3705. rc = wait_event_timeout(ac->cmd_wait,
  3706. (atomic_read(&ac->cmd_state) == 0), 5*HZ);
  3707. if (!rc) {
  3708. pr_err("timeout. waited for tx overflow\n");
  3709. goto fail_cmd;
  3710. }
  3711. return 0;
  3712. fail_cmd:
  3713. return -EINVAL;
  3714. }
  3715. int q6asm_get_apr_service_id(int session_id)
  3716. {
  3717. pr_debug("%s\n", __func__);
  3718. if (session_id < 0 || session_id > SESSION_MAX) {
  3719. pr_err("%s: invalid session_id = %d\n", __func__, session_id);
  3720. return -EINVAL;
  3721. }
  3722. return ((struct apr_svc *)session[session_id]->apr)->id;
  3723. }
  3724. static int __init q6asm_init(void)
  3725. {
  3726. pr_debug("%s\n", __func__);
  3727. init_waitqueue_head(&this_mmap.cmd_wait);
  3728. memset(session, 0, sizeof(session));
  3729. #ifdef CONFIG_DEBUG_FS
  3730. out_buffer = kmalloc(OUT_BUFFER_SIZE, GFP_KERNEL);
  3731. out_dentry = debugfs_create_file("audio_out_latency_measurement_node",\
  3732. S_IFREG | S_IRUGO | S_IWUGO,\
  3733. NULL, NULL, &audio_output_latency_debug_fops);
  3734. if (IS_ERR(out_dentry))
  3735. pr_err("debugfs_create_file failed\n");
  3736. in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
  3737. in_dentry = debugfs_create_file("audio_in_latency_measurement_node",\
  3738. S_IFREG | S_IRUGO | S_IWUGO,\
  3739. NULL, NULL, &audio_input_latency_debug_fops);
  3740. if (IS_ERR(in_dentry))
  3741. pr_err("debugfs_create_file failed\n");
  3742. #endif
  3743. return 0;
  3744. }
  3745. device_initcall(q6asm_init);