soc-compress.c 26 KB

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