soc-compress.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // soc-compress.c -- ALSA SoC Compress
  4. //
  5. // Copyright (C) 2012 Intel Corp.
  6. //
  7. // Authors: Namarta Kohli <namartax.kohli@intel.com>
  8. // Ramesh Babu K V <ramesh.babu@linux.intel.com>
  9. // Vinod Koul <vinod.koul@linux.intel.com>
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/delay.h>
  13. #include <linux/slab.h>
  14. #include <linux/workqueue.h>
  15. #include <sound/core.h>
  16. #include <sound/compress_params.h>
  17. #include <sound/compress_driver.h>
  18. #include <sound/soc.h>
  19. #include <sound/initval.h>
  20. #include <sound/soc-dpcm.h>
  21. static int soc_compr_components_open(struct snd_compr_stream *cstream,
  22. struct snd_soc_component **last)
  23. {
  24. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  25. struct snd_soc_component *component;
  26. struct snd_soc_rtdcom_list *rtdcom;
  27. int ret;
  28. for_each_rtdcom(rtd, rtdcom) {
  29. component = rtdcom->component;
  30. if (!component->driver->compr_ops ||
  31. !component->driver->compr_ops->open)
  32. continue;
  33. ret = component->driver->compr_ops->open(cstream);
  34. if (ret < 0) {
  35. dev_err(component->dev,
  36. "Compress ASoC: can't open platform %s: %d\n",
  37. component->name, ret);
  38. *last = component;
  39. return ret;
  40. }
  41. }
  42. *last = NULL;
  43. return 0;
  44. }
  45. static int soc_compr_components_free(struct snd_compr_stream *cstream,
  46. struct snd_soc_component *last)
  47. {
  48. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  49. struct snd_soc_component *component;
  50. struct snd_soc_rtdcom_list *rtdcom;
  51. for_each_rtdcom(rtd, rtdcom) {
  52. component = rtdcom->component;
  53. if (component == last)
  54. break;
  55. if (!component->driver->compr_ops ||
  56. !component->driver->compr_ops->free)
  57. continue;
  58. component->driver->compr_ops->free(cstream);
  59. }
  60. return 0;
  61. }
  62. static int soc_compr_open(struct snd_compr_stream *cstream)
  63. {
  64. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  65. struct snd_soc_component *component;
  66. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  67. int ret;
  68. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  69. if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
  70. ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
  71. if (ret < 0) {
  72. dev_err(cpu_dai->dev,
  73. "Compress ASoC: can't open interface %s: %d\n",
  74. cpu_dai->name, ret);
  75. goto out;
  76. }
  77. }
  78. ret = soc_compr_components_open(cstream, &component);
  79. if (ret < 0)
  80. goto machine_err;
  81. if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
  82. ret = rtd->dai_link->compr_ops->startup(cstream);
  83. if (ret < 0) {
  84. dev_err(rtd->dev,
  85. "Compress ASoC: %s startup failed: %d\n",
  86. rtd->dai_link->name, ret);
  87. goto machine_err;
  88. }
  89. }
  90. snd_soc_runtime_activate(rtd, cstream->direction);
  91. mutex_unlock(&rtd->pcm_mutex);
  92. return 0;
  93. machine_err:
  94. soc_compr_components_free(cstream, component);
  95. if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
  96. cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
  97. out:
  98. mutex_unlock(&rtd->pcm_mutex);
  99. return ret;
  100. }
  101. static int soc_compr_open_fe(struct snd_compr_stream *cstream)
  102. {
  103. struct snd_soc_pcm_runtime *fe = cstream->private_data;
  104. struct snd_pcm_substream *fe_substream =
  105. fe->pcm->streams[cstream->direction].substream;
  106. struct snd_soc_component *component;
  107. struct snd_soc_dai *cpu_dai = fe->cpu_dai;
  108. struct snd_soc_dpcm *dpcm;
  109. struct snd_soc_dapm_widget_list *list;
  110. int stream;
  111. int ret;
  112. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  113. stream = SNDRV_PCM_STREAM_PLAYBACK;
  114. else
  115. stream = SNDRV_PCM_STREAM_CAPTURE;
  116. mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
  117. fe->dpcm[stream].runtime = fe_substream->runtime;
  118. ret = dpcm_path_get(fe, stream, &list);
  119. if (ret < 0)
  120. goto be_err;
  121. else if (ret == 0)
  122. dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
  123. fe->dai_link->name, stream ? "capture" : "playback");
  124. /* calculate valid and active FE <-> BE dpcms */
  125. dpcm_process_paths(fe, stream, &list, 1);
  126. fe->dpcm[stream].runtime = fe_substream->runtime;
  127. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  128. ret = dpcm_be_dai_startup(fe, stream);
  129. if (ret < 0) {
  130. /* clean up all links */
  131. list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
  132. dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
  133. dpcm_be_disconnect(fe, stream);
  134. fe->dpcm[stream].runtime = NULL;
  135. goto out;
  136. }
  137. if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
  138. ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
  139. if (ret < 0) {
  140. dev_err(cpu_dai->dev,
  141. "Compress ASoC: can't open interface %s: %d\n",
  142. cpu_dai->name, ret);
  143. goto out;
  144. }
  145. }
  146. ret = soc_compr_components_open(cstream, &component);
  147. if (ret < 0)
  148. goto open_err;
  149. if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
  150. ret = fe->dai_link->compr_ops->startup(cstream);
  151. if (ret < 0) {
  152. pr_err("Compress ASoC: %s startup failed: %d\n",
  153. fe->dai_link->name, ret);
  154. goto machine_err;
  155. }
  156. }
  157. dpcm_clear_pending_state(fe, stream);
  158. dpcm_path_put(&list);
  159. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
  160. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  161. snd_soc_runtime_activate(fe, stream);
  162. mutex_unlock(&fe->card->mutex);
  163. return 0;
  164. machine_err:
  165. soc_compr_components_free(cstream, component);
  166. open_err:
  167. if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
  168. cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
  169. out:
  170. dpcm_path_put(&list);
  171. be_err:
  172. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  173. mutex_unlock(&fe->card->mutex);
  174. return ret;
  175. }
  176. /*
  177. * Power down the audio subsystem pmdown_time msecs after close is called.
  178. * This is to ensure there are no pops or clicks in between any music tracks
  179. * due to DAPM power cycling.
  180. */
  181. static void close_delayed_work(struct work_struct *work)
  182. {
  183. struct snd_soc_pcm_runtime *rtd =
  184. container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
  185. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  186. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  187. dev_dbg(rtd->dev,
  188. "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
  189. codec_dai->driver->playback.stream_name,
  190. codec_dai->playback_active ? "active" : "inactive",
  191. rtd->pop_wait ? "yes" : "no");
  192. /* are we waiting on this codec DAI stream */
  193. if (rtd->pop_wait == 1) {
  194. rtd->pop_wait = 0;
  195. snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
  196. SND_SOC_DAPM_STREAM_STOP);
  197. }
  198. mutex_unlock(&rtd->pcm_mutex);
  199. }
  200. static int soc_compr_free(struct snd_compr_stream *cstream)
  201. {
  202. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  203. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  204. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  205. int stream;
  206. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  207. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  208. stream = SNDRV_PCM_STREAM_PLAYBACK;
  209. else
  210. stream = SNDRV_PCM_STREAM_CAPTURE;
  211. snd_soc_runtime_deactivate(rtd, stream);
  212. snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
  213. if (!cpu_dai->active)
  214. cpu_dai->rate = 0;
  215. if (!codec_dai->active)
  216. codec_dai->rate = 0;
  217. if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
  218. rtd->dai_link->compr_ops->shutdown(cstream);
  219. soc_compr_components_free(cstream, NULL);
  220. if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
  221. cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
  222. if (cstream->direction == SND_COMPRESS_PLAYBACK) {
  223. if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
  224. snd_soc_dapm_stream_event(rtd,
  225. SNDRV_PCM_STREAM_PLAYBACK,
  226. SND_SOC_DAPM_STREAM_STOP);
  227. } else {
  228. rtd->pop_wait = 1;
  229. queue_delayed_work(system_power_efficient_wq,
  230. &rtd->delayed_work,
  231. msecs_to_jiffies(rtd->pmdown_time));
  232. }
  233. } else {
  234. /* capture streams can be powered down now */
  235. snd_soc_dapm_stream_event(rtd,
  236. SNDRV_PCM_STREAM_CAPTURE,
  237. SND_SOC_DAPM_STREAM_STOP);
  238. }
  239. mutex_unlock(&rtd->pcm_mutex);
  240. return 0;
  241. }
  242. static int soc_compr_free_fe(struct snd_compr_stream *cstream)
  243. {
  244. struct snd_soc_pcm_runtime *fe = cstream->private_data;
  245. struct snd_soc_dai *cpu_dai = fe->cpu_dai;
  246. struct snd_soc_dpcm *dpcm;
  247. int stream, ret;
  248. mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
  249. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  250. stream = SNDRV_PCM_STREAM_PLAYBACK;
  251. else
  252. stream = SNDRV_PCM_STREAM_CAPTURE;
  253. snd_soc_runtime_deactivate(fe, stream);
  254. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  255. ret = dpcm_be_dai_hw_free(fe, stream);
  256. if (ret < 0)
  257. dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
  258. ret = dpcm_be_dai_shutdown(fe, stream);
  259. /* mark FE's links ready to prune */
  260. list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
  261. dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
  262. dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
  263. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
  264. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  265. dpcm_be_disconnect(fe, stream);
  266. fe->dpcm[stream].runtime = NULL;
  267. if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
  268. fe->dai_link->compr_ops->shutdown(cstream);
  269. soc_compr_components_free(cstream, NULL);
  270. if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
  271. cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
  272. mutex_unlock(&fe->card->mutex);
  273. return 0;
  274. }
  275. static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
  276. {
  277. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  278. struct snd_soc_component *component;
  279. struct snd_soc_rtdcom_list *rtdcom;
  280. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  281. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  282. int ret = 0, __ret;
  283. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  284. for_each_rtdcom(rtd, rtdcom) {
  285. component = rtdcom->component;
  286. if (!component->driver->compr_ops ||
  287. !component->driver->compr_ops->trigger)
  288. continue;
  289. __ret = component->driver->compr_ops->trigger(cstream, cmd);
  290. if (__ret < 0)
  291. ret = __ret;
  292. }
  293. if (ret < 0)
  294. goto out;
  295. if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
  296. cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
  297. switch (cmd) {
  298. case SNDRV_PCM_TRIGGER_START:
  299. snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
  300. break;
  301. case SNDRV_PCM_TRIGGER_STOP:
  302. snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
  303. break;
  304. }
  305. out:
  306. mutex_unlock(&rtd->pcm_mutex);
  307. return ret;
  308. }
  309. static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
  310. {
  311. struct snd_soc_pcm_runtime *fe = cstream->private_data;
  312. struct snd_soc_component *component;
  313. struct snd_soc_rtdcom_list *rtdcom;
  314. struct snd_soc_dai *cpu_dai = fe->cpu_dai;
  315. int ret = 0, __ret, stream;
  316. if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
  317. cmd == SND_COMPR_TRIGGER_DRAIN) {
  318. for_each_rtdcom(fe, rtdcom) {
  319. component = rtdcom->component;
  320. if (!component->driver->compr_ops ||
  321. !component->driver->compr_ops->trigger)
  322. continue;
  323. __ret = component->driver->compr_ops->trigger(cstream, cmd);
  324. if (__ret < 0)
  325. ret = __ret;
  326. }
  327. return ret;
  328. }
  329. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  330. stream = SNDRV_PCM_STREAM_PLAYBACK;
  331. else
  332. stream = SNDRV_PCM_STREAM_CAPTURE;
  333. mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
  334. if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
  335. ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
  336. if (ret < 0)
  337. goto out;
  338. }
  339. for_each_rtdcom(fe, rtdcom) {
  340. component = rtdcom->component;
  341. if (!component->driver->compr_ops ||
  342. !component->driver->compr_ops->trigger)
  343. continue;
  344. __ret = component->driver->compr_ops->trigger(cstream, cmd);
  345. if (__ret < 0)
  346. ret = __ret;
  347. }
  348. if (ret < 0)
  349. goto out;
  350. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  351. ret = dpcm_be_dai_trigger(fe, stream, cmd);
  352. switch (cmd) {
  353. case SNDRV_PCM_TRIGGER_START:
  354. case SNDRV_PCM_TRIGGER_RESUME:
  355. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  356. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
  357. break;
  358. case SNDRV_PCM_TRIGGER_STOP:
  359. case SNDRV_PCM_TRIGGER_SUSPEND:
  360. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
  361. break;
  362. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  363. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
  364. break;
  365. }
  366. out:
  367. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  368. mutex_unlock(&fe->card->mutex);
  369. return ret;
  370. }
  371. static int soc_compr_set_params(struct snd_compr_stream *cstream,
  372. struct snd_compr_params *params)
  373. {
  374. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  375. struct snd_soc_component *component;
  376. struct snd_soc_rtdcom_list *rtdcom;
  377. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  378. int ret = 0, __ret;
  379. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  380. /*
  381. * First we call set_params for the CPU DAI, then the component
  382. * driver this should configure the SoC side. If the machine has
  383. * compressed ops then we call that as well. The expectation is
  384. * that these callbacks will configure everything for this compress
  385. * path, like configuring a PCM port for a CODEC.
  386. */
  387. if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
  388. ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
  389. if (ret < 0)
  390. goto err;
  391. }
  392. for_each_rtdcom(rtd, rtdcom) {
  393. component = rtdcom->component;
  394. if (!component->driver->compr_ops ||
  395. !component->driver->compr_ops->set_params)
  396. continue;
  397. __ret = component->driver->compr_ops->set_params(cstream, params);
  398. if (__ret < 0)
  399. ret = __ret;
  400. }
  401. if (ret < 0)
  402. goto err;
  403. if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
  404. ret = rtd->dai_link->compr_ops->set_params(cstream);
  405. if (ret < 0)
  406. goto err;
  407. }
  408. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  409. snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
  410. SND_SOC_DAPM_STREAM_START);
  411. else
  412. snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
  413. SND_SOC_DAPM_STREAM_START);
  414. /* cancel any delayed stream shutdown that is pending */
  415. rtd->pop_wait = 0;
  416. mutex_unlock(&rtd->pcm_mutex);
  417. cancel_delayed_work_sync(&rtd->delayed_work);
  418. return ret;
  419. err:
  420. mutex_unlock(&rtd->pcm_mutex);
  421. return ret;
  422. }
  423. static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
  424. struct snd_compr_params *params)
  425. {
  426. struct snd_soc_pcm_runtime *fe = cstream->private_data;
  427. struct snd_pcm_substream *fe_substream =
  428. fe->pcm->streams[cstream->direction].substream;
  429. struct snd_soc_component *component;
  430. struct snd_soc_rtdcom_list *rtdcom;
  431. struct snd_soc_dai *cpu_dai = fe->cpu_dai;
  432. int ret = 0, __ret, stream;
  433. if (cstream->direction == SND_COMPRESS_PLAYBACK)
  434. stream = SNDRV_PCM_STREAM_PLAYBACK;
  435. else
  436. stream = SNDRV_PCM_STREAM_CAPTURE;
  437. mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
  438. /*
  439. * Create an empty hw_params for the BE as the machine driver must
  440. * fix this up to match DSP decoder and ASRC configuration.
  441. * I.e. machine driver fixup for compressed BE is mandatory.
  442. */
  443. memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
  444. sizeof(struct snd_pcm_hw_params));
  445. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
  446. ret = dpcm_be_dai_hw_params(fe, stream);
  447. if (ret < 0)
  448. goto out;
  449. ret = dpcm_be_dai_prepare(fe, stream);
  450. if (ret < 0)
  451. goto out;
  452. if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
  453. ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
  454. if (ret < 0)
  455. goto out;
  456. }
  457. for_each_rtdcom(fe, rtdcom) {
  458. component = rtdcom->component;
  459. if (!component->driver->compr_ops ||
  460. !component->driver->compr_ops->set_params)
  461. continue;
  462. __ret = component->driver->compr_ops->set_params(cstream, params);
  463. if (__ret < 0)
  464. ret = __ret;
  465. }
  466. if (ret < 0)
  467. goto out;
  468. if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
  469. ret = fe->dai_link->compr_ops->set_params(cstream);
  470. if (ret < 0)
  471. goto out;
  472. }
  473. dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
  474. fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
  475. out:
  476. fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
  477. mutex_unlock(&fe->card->mutex);
  478. return ret;
  479. }
  480. static int soc_compr_get_params(struct snd_compr_stream *cstream,
  481. struct snd_codec *params)
  482. {
  483. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  484. struct snd_soc_component *component;
  485. struct snd_soc_rtdcom_list *rtdcom;
  486. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  487. int ret = 0, __ret;
  488. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  489. if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
  490. ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
  491. if (ret < 0)
  492. goto err;
  493. }
  494. for_each_rtdcom(rtd, rtdcom) {
  495. component = rtdcom->component;
  496. if (!component->driver->compr_ops ||
  497. !component->driver->compr_ops->get_params)
  498. continue;
  499. __ret = component->driver->compr_ops->get_params(cstream, params);
  500. if (__ret < 0)
  501. ret = __ret;
  502. }
  503. err:
  504. mutex_unlock(&rtd->pcm_mutex);
  505. return ret;
  506. }
  507. static int soc_compr_get_caps(struct snd_compr_stream *cstream,
  508. struct snd_compr_caps *caps)
  509. {
  510. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  511. struct snd_soc_component *component;
  512. struct snd_soc_rtdcom_list *rtdcom;
  513. int ret = 0, __ret;
  514. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  515. for_each_rtdcom(rtd, rtdcom) {
  516. component = rtdcom->component;
  517. if (!component->driver->compr_ops ||
  518. !component->driver->compr_ops->get_caps)
  519. continue;
  520. __ret = component->driver->compr_ops->get_caps(cstream, caps);
  521. if (__ret < 0)
  522. ret = __ret;
  523. }
  524. mutex_unlock(&rtd->pcm_mutex);
  525. return ret;
  526. }
  527. static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
  528. struct snd_compr_codec_caps *codec)
  529. {
  530. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  531. struct snd_soc_component *component;
  532. struct snd_soc_rtdcom_list *rtdcom;
  533. int ret = 0, __ret;
  534. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  535. for_each_rtdcom(rtd, rtdcom) {
  536. component = rtdcom->component;
  537. if (!component->driver->compr_ops ||
  538. !component->driver->compr_ops->get_codec_caps)
  539. continue;
  540. __ret = component->driver->compr_ops->get_codec_caps(cstream, codec);
  541. if (__ret < 0)
  542. ret = __ret;
  543. }
  544. mutex_unlock(&rtd->pcm_mutex);
  545. return ret;
  546. }
  547. static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
  548. {
  549. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  550. struct snd_soc_component *component;
  551. struct snd_soc_rtdcom_list *rtdcom;
  552. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  553. int ret = 0, __ret;
  554. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  555. if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
  556. ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
  557. if (ret < 0)
  558. goto err;
  559. }
  560. for_each_rtdcom(rtd, rtdcom) {
  561. component = rtdcom->component;
  562. if (!component->driver->compr_ops ||
  563. !component->driver->compr_ops->ack)
  564. continue;
  565. __ret = component->driver->compr_ops->ack(cstream, bytes);
  566. if (__ret < 0)
  567. ret = __ret;
  568. }
  569. err:
  570. mutex_unlock(&rtd->pcm_mutex);
  571. return ret;
  572. }
  573. static int soc_compr_pointer(struct snd_compr_stream *cstream,
  574. struct snd_compr_tstamp *tstamp)
  575. {
  576. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  577. struct snd_soc_component *component;
  578. struct snd_soc_rtdcom_list *rtdcom;
  579. int ret = 0, __ret;
  580. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  581. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  582. if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
  583. cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
  584. for_each_rtdcom(rtd, rtdcom) {
  585. component = rtdcom->component;
  586. if (!component->driver->compr_ops ||
  587. !component->driver->compr_ops->pointer)
  588. continue;
  589. __ret = component->driver->compr_ops->pointer(cstream, tstamp);
  590. if (__ret < 0)
  591. ret = __ret;
  592. }
  593. mutex_unlock(&rtd->pcm_mutex);
  594. return ret;
  595. }
  596. static int soc_compr_copy(struct snd_compr_stream *cstream,
  597. char __user *buf, size_t count)
  598. {
  599. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  600. struct snd_soc_component *component;
  601. struct snd_soc_rtdcom_list *rtdcom;
  602. int ret = 0;
  603. mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
  604. for_each_rtdcom(rtd, rtdcom) {
  605. component = rtdcom->component;
  606. if (!component->driver->compr_ops ||
  607. !component->driver->compr_ops->copy)
  608. continue;
  609. ret = component->driver->compr_ops->copy(cstream, buf, count);
  610. break;
  611. }
  612. mutex_unlock(&rtd->pcm_mutex);
  613. return ret;
  614. }
  615. static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
  616. struct snd_compr_metadata *metadata)
  617. {
  618. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  619. struct snd_soc_component *component;
  620. struct snd_soc_rtdcom_list *rtdcom;
  621. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  622. int ret = 0, __ret;
  623. if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
  624. ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
  625. if (ret < 0)
  626. return ret;
  627. }
  628. for_each_rtdcom(rtd, rtdcom) {
  629. component = rtdcom->component;
  630. if (!component->driver->compr_ops ||
  631. !component->driver->compr_ops->set_metadata)
  632. continue;
  633. __ret = component->driver->compr_ops->set_metadata(cstream, metadata);
  634. if (__ret < 0)
  635. ret = __ret;
  636. }
  637. return ret;
  638. }
  639. static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
  640. struct snd_compr_metadata *metadata)
  641. {
  642. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  643. struct snd_soc_component *component;
  644. struct snd_soc_rtdcom_list *rtdcom;
  645. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  646. int ret = 0, __ret;
  647. if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
  648. ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
  649. if (ret < 0)
  650. return ret;
  651. }
  652. for_each_rtdcom(rtd, rtdcom) {
  653. component = rtdcom->component;
  654. if (!component->driver->compr_ops ||
  655. !component->driver->compr_ops->get_metadata)
  656. continue;
  657. __ret = component->driver->compr_ops->get_metadata(cstream, metadata);
  658. if (__ret < 0)
  659. ret = __ret;
  660. }
  661. return ret;
  662. }
  663. /* ASoC Compress operations */
  664. static struct snd_compr_ops soc_compr_ops = {
  665. .open = soc_compr_open,
  666. .free = soc_compr_free,
  667. .set_params = soc_compr_set_params,
  668. .set_metadata = soc_compr_set_metadata,
  669. .get_metadata = soc_compr_get_metadata,
  670. .get_params = soc_compr_get_params,
  671. .trigger = soc_compr_trigger,
  672. .pointer = soc_compr_pointer,
  673. .ack = soc_compr_ack,
  674. .get_caps = soc_compr_get_caps,
  675. .get_codec_caps = soc_compr_get_codec_caps
  676. };
  677. /* ASoC Dynamic Compress operations */
  678. static struct snd_compr_ops soc_compr_dyn_ops = {
  679. .open = soc_compr_open_fe,
  680. .free = soc_compr_free_fe,
  681. .set_params = soc_compr_set_params_fe,
  682. .get_params = soc_compr_get_params,
  683. .set_metadata = soc_compr_set_metadata,
  684. .get_metadata = soc_compr_get_metadata,
  685. .trigger = soc_compr_trigger_fe,
  686. .pointer = soc_compr_pointer,
  687. .ack = soc_compr_ack,
  688. .get_caps = soc_compr_get_caps,
  689. .get_codec_caps = soc_compr_get_codec_caps
  690. };
  691. /**
  692. * snd_soc_new_compress - create a new compress.
  693. *
  694. * @rtd: The runtime for which we will create compress
  695. * @num: the device index number (zero based - shared with normal PCMs)
  696. *
  697. * Return: 0 for success, else error.
  698. */
  699. int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
  700. {
  701. struct snd_soc_component *component;
  702. struct snd_soc_rtdcom_list *rtdcom;
  703. struct snd_soc_dai *codec_dai = rtd->codec_dai;
  704. struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  705. struct snd_compr *compr;
  706. struct snd_pcm *be_pcm;
  707. char new_name[64];
  708. int ret = 0, direction = 0;
  709. int playback = 0, capture = 0;
  710. if (rtd->num_codecs > 1) {
  711. dev_err(rtd->card->dev,
  712. "Compress ASoC: Multicodec not supported\n");
  713. return -EINVAL;
  714. }
  715. /* check client and interface hw capabilities */
  716. if (codec_dai->driver->playback.channels_min)
  717. playback = 1;
  718. if (codec_dai->driver->capture.channels_min)
  719. capture = 1;
  720. capture = capture && cpu_dai->driver->capture.channels_min;
  721. playback = playback && cpu_dai->driver->playback.channels_min;
  722. /*
  723. * Compress devices are unidirectional so only one of the directions
  724. * should be set, check for that (xor)
  725. */
  726. if (playback + capture != 1) {
  727. dev_err(rtd->card->dev,
  728. "Compress ASoC: Invalid direction for P %d, C %d\n",
  729. playback, capture);
  730. return -EINVAL;
  731. }
  732. if (playback)
  733. direction = SND_COMPRESS_PLAYBACK;
  734. else
  735. direction = SND_COMPRESS_CAPTURE;
  736. compr = kzalloc(sizeof(*compr), GFP_KERNEL);
  737. if (!compr)
  738. return -ENOMEM;
  739. compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
  740. GFP_KERNEL);
  741. if (!compr->ops) {
  742. ret = -ENOMEM;
  743. goto compr_err;
  744. }
  745. if (rtd->dai_link->dynamic) {
  746. snprintf(new_name, sizeof(new_name), "(%s)",
  747. rtd->dai_link->stream_name);
  748. ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
  749. rtd->dai_link->dpcm_playback,
  750. rtd->dai_link->dpcm_capture, &be_pcm);
  751. if (ret < 0) {
  752. dev_err(rtd->card->dev,
  753. "Compress ASoC: can't create compressed for %s: %d\n",
  754. rtd->dai_link->name, ret);
  755. goto compr_err;
  756. }
  757. rtd->pcm = be_pcm;
  758. rtd->fe_compr = 1;
  759. if (rtd->dai_link->dpcm_playback)
  760. be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
  761. else if (rtd->dai_link->dpcm_capture)
  762. be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
  763. memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
  764. } else {
  765. snprintf(new_name, sizeof(new_name), "%s %s-%d",
  766. rtd->dai_link->stream_name, codec_dai->name, num);
  767. memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
  768. }
  769. for_each_rtdcom(rtd, rtdcom) {
  770. component = rtdcom->component;
  771. if (!component->driver->compr_ops ||
  772. !component->driver->compr_ops->copy)
  773. continue;
  774. compr->ops->copy = soc_compr_copy;
  775. break;
  776. }
  777. mutex_init(&compr->lock);
  778. ret = snd_compress_new(rtd->card->snd_card, num, direction,
  779. new_name, compr);
  780. if (ret < 0) {
  781. component = rtd->codec_dai->component;
  782. dev_err(component->dev,
  783. "Compress ASoC: can't create compress for codec %s: %d\n",
  784. component->name, ret);
  785. goto compr_err;
  786. }
  787. /* DAPM dai link stream work */
  788. INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
  789. rtd->compr = compr;
  790. compr->private_data = rtd;
  791. dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
  792. codec_dai->name, cpu_dai->name);
  793. return ret;
  794. compr_err:
  795. kfree(compr);
  796. return ret;
  797. }
  798. EXPORT_SYMBOL_GPL(snd_soc_new_compress);