sst-haswell-pcm.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. /*
  2. * Intel SST Haswell/Broadwell PCM Support
  3. *
  4. * Copyright (C) 2013, Intel Corporation. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License version
  8. * 2 as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/module.h>
  17. #include <linux/dma-mapping.h>
  18. #include <linux/slab.h>
  19. #include <linux/delay.h>
  20. #include <asm/page.h>
  21. #include <asm/pgtable.h>
  22. #include <sound/core.h>
  23. #include <sound/pcm.h>
  24. #include <sound/pcm_params.h>
  25. #include <sound/dmaengine_pcm.h>
  26. #include <sound/soc.h>
  27. #include <sound/tlv.h>
  28. #include <sound/compress_driver.h>
  29. #include "sst-haswell-ipc.h"
  30. #include "sst-dsp-priv.h"
  31. #include "sst-dsp.h"
  32. #define HSW_PCM_COUNT 6
  33. #define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
  34. /* simple volume table */
  35. static const u32 volume_map[] = {
  36. HSW_VOLUME_MAX >> 30,
  37. HSW_VOLUME_MAX >> 29,
  38. HSW_VOLUME_MAX >> 28,
  39. HSW_VOLUME_MAX >> 27,
  40. HSW_VOLUME_MAX >> 26,
  41. HSW_VOLUME_MAX >> 25,
  42. HSW_VOLUME_MAX >> 24,
  43. HSW_VOLUME_MAX >> 23,
  44. HSW_VOLUME_MAX >> 22,
  45. HSW_VOLUME_MAX >> 21,
  46. HSW_VOLUME_MAX >> 20,
  47. HSW_VOLUME_MAX >> 19,
  48. HSW_VOLUME_MAX >> 18,
  49. HSW_VOLUME_MAX >> 17,
  50. HSW_VOLUME_MAX >> 16,
  51. HSW_VOLUME_MAX >> 15,
  52. HSW_VOLUME_MAX >> 14,
  53. HSW_VOLUME_MAX >> 13,
  54. HSW_VOLUME_MAX >> 12,
  55. HSW_VOLUME_MAX >> 11,
  56. HSW_VOLUME_MAX >> 10,
  57. HSW_VOLUME_MAX >> 9,
  58. HSW_VOLUME_MAX >> 8,
  59. HSW_VOLUME_MAX >> 7,
  60. HSW_VOLUME_MAX >> 6,
  61. HSW_VOLUME_MAX >> 5,
  62. HSW_VOLUME_MAX >> 4,
  63. HSW_VOLUME_MAX >> 3,
  64. HSW_VOLUME_MAX >> 2,
  65. HSW_VOLUME_MAX >> 1,
  66. HSW_VOLUME_MAX >> 0,
  67. };
  68. #define HSW_PCM_PERIODS_MAX 64
  69. #define HSW_PCM_PERIODS_MIN 2
  70. static const struct snd_pcm_hardware hsw_pcm_hardware = {
  71. .info = SNDRV_PCM_INFO_MMAP |
  72. SNDRV_PCM_INFO_MMAP_VALID |
  73. SNDRV_PCM_INFO_INTERLEAVED |
  74. SNDRV_PCM_INFO_PAUSE |
  75. SNDRV_PCM_INFO_RESUME |
  76. SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
  77. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
  78. SNDRV_PCM_FMTBIT_S32_LE,
  79. .period_bytes_min = PAGE_SIZE,
  80. .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE,
  81. .periods_min = HSW_PCM_PERIODS_MIN,
  82. .periods_max = HSW_PCM_PERIODS_MAX,
  83. .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE,
  84. };
  85. /* private data for each PCM DSP stream */
  86. struct hsw_pcm_data {
  87. int dai_id;
  88. struct sst_hsw_stream *stream;
  89. u32 volume[2];
  90. struct snd_pcm_substream *substream;
  91. struct snd_compr_stream *cstream;
  92. unsigned int wpos;
  93. struct mutex mutex;
  94. bool allocated;
  95. };
  96. /* private data for the driver */
  97. struct hsw_priv_data {
  98. /* runtime DSP */
  99. struct sst_hsw *hsw;
  100. /* page tables */
  101. struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
  102. /* DAI data */
  103. struct hsw_pcm_data pcm[HSW_PCM_COUNT];
  104. };
  105. static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
  106. static inline u32 hsw_mixer_to_ipc(unsigned int value)
  107. {
  108. if (value >= ARRAY_SIZE(volume_map))
  109. return volume_map[0];
  110. else
  111. return volume_map[value];
  112. }
  113. static inline unsigned int hsw_ipc_to_mixer(u32 value)
  114. {
  115. int i;
  116. for (i = 0; i < ARRAY_SIZE(volume_map); i++) {
  117. if (volume_map[i] >= value)
  118. return i;
  119. }
  120. return i - 1;
  121. }
  122. static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
  123. struct snd_ctl_elem_value *ucontrol)
  124. {
  125. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  126. struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
  127. struct soc_mixer_control *mc =
  128. (struct soc_mixer_control *)kcontrol->private_value;
  129. struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
  130. struct sst_hsw *hsw = pdata->hsw;
  131. u32 volume;
  132. mutex_lock(&pcm_data->mutex);
  133. if (!pcm_data->stream) {
  134. pcm_data->volume[0] =
  135. hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
  136. pcm_data->volume[1] =
  137. hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
  138. mutex_unlock(&pcm_data->mutex);
  139. return 0;
  140. }
  141. if (ucontrol->value.integer.value[0] ==
  142. ucontrol->value.integer.value[1]) {
  143. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
  144. sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume);
  145. } else {
  146. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
  147. sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
  148. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
  149. sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume);
  150. }
  151. mutex_unlock(&pcm_data->mutex);
  152. return 0;
  153. }
  154. static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
  155. struct snd_ctl_elem_value *ucontrol)
  156. {
  157. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  158. struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
  159. struct soc_mixer_control *mc =
  160. (struct soc_mixer_control *)kcontrol->private_value;
  161. struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
  162. struct sst_hsw *hsw = pdata->hsw;
  163. u32 volume;
  164. mutex_lock(&pcm_data->mutex);
  165. if (!pcm_data->stream) {
  166. ucontrol->value.integer.value[0] =
  167. hsw_ipc_to_mixer(pcm_data->volume[0]);
  168. ucontrol->value.integer.value[1] =
  169. hsw_ipc_to_mixer(pcm_data->volume[1]);
  170. mutex_unlock(&pcm_data->mutex);
  171. return 0;
  172. }
  173. sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 0, &volume);
  174. ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
  175. sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume);
  176. ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
  177. mutex_unlock(&pcm_data->mutex);
  178. return 0;
  179. }
  180. static int hsw_volume_put(struct snd_kcontrol *kcontrol,
  181. struct snd_ctl_elem_value *ucontrol)
  182. {
  183. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  184. struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
  185. struct sst_hsw *hsw = pdata->hsw;
  186. u32 volume;
  187. if (ucontrol->value.integer.value[0] ==
  188. ucontrol->value.integer.value[1]) {
  189. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
  190. sst_hsw_mixer_set_volume(hsw, 0, 2, volume);
  191. } else {
  192. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
  193. sst_hsw_mixer_set_volume(hsw, 0, 0, volume);
  194. volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
  195. sst_hsw_mixer_set_volume(hsw, 0, 1, volume);
  196. }
  197. return 0;
  198. }
  199. static int hsw_volume_get(struct snd_kcontrol *kcontrol,
  200. struct snd_ctl_elem_value *ucontrol)
  201. {
  202. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  203. struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
  204. struct sst_hsw *hsw = pdata->hsw;
  205. unsigned int volume = 0;
  206. sst_hsw_mixer_get_volume(hsw, 0, 0, &volume);
  207. ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
  208. sst_hsw_mixer_get_volume(hsw, 0, 1, &volume);
  209. ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
  210. return 0;
  211. }
  212. /* TLV used by both global and stream volumes */
  213. static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
  214. /* System Pin has no volume control */
  215. static const struct snd_kcontrol_new hsw_volume_controls[] = {
  216. /* Global DSP volume */
  217. SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
  218. ARRAY_SIZE(volume_map) -1, 0,
  219. hsw_volume_get, hsw_volume_put, hsw_vol_tlv),
  220. /* Offload 0 volume */
  221. SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
  222. ARRAY_SIZE(volume_map), 0,
  223. hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
  224. /* Offload 1 volume */
  225. SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
  226. ARRAY_SIZE(volume_map), 0,
  227. hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
  228. /* Loopback volume */
  229. SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8,
  230. ARRAY_SIZE(volume_map), 0,
  231. hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
  232. /* Mic Capture volume */
  233. SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
  234. ARRAY_SIZE(volume_map), 0,
  235. hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
  236. };
  237. /* Create DMA buffer page table for DSP */
  238. static int create_adsp_page_table(struct snd_pcm_substream *substream,
  239. struct hsw_priv_data *pdata, struct snd_soc_pcm_runtime *rtd,
  240. unsigned char *dma_area, size_t size, int pcm)
  241. {
  242. struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream);
  243. int i, pages, stream = substream->stream;
  244. pages = snd_sgbuf_aligned_pages(size);
  245. dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n",
  246. dma_area, size, pages);
  247. for (i = 0; i < pages; i++) {
  248. u32 idx = (((i << 2) + i)) >> 1;
  249. u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
  250. u32 *pg_table;
  251. dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
  252. pg_table = (u32 *)(pdata->dmab[pcm][stream].area + idx);
  253. if (i & 1)
  254. *pg_table |= (pfn << 4);
  255. else
  256. *pg_table |= pfn;
  257. }
  258. return 0;
  259. }
  260. /* this may get called several times by oss emulation */
  261. static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
  262. struct snd_pcm_hw_params *params)
  263. {
  264. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  265. struct snd_pcm_runtime *runtime = substream->runtime;
  266. struct hsw_priv_data *pdata =
  267. snd_soc_platform_get_drvdata(rtd->platform);
  268. struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
  269. struct sst_hsw *hsw = pdata->hsw;
  270. struct sst_module *module_data;
  271. struct sst_dsp *dsp;
  272. struct snd_dma_buffer *dmab;
  273. enum sst_hsw_stream_type stream_type;
  274. enum sst_hsw_stream_path_id path_id;
  275. u32 rate, bits, map, pages, module_id;
  276. u8 channels;
  277. int ret;
  278. /* check if we are being called a subsequent time */
  279. if (pcm_data->allocated) {
  280. ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
  281. if (ret < 0)
  282. dev_dbg(rtd->dev, "error: reset stream failed %d\n",
  283. ret);
  284. ret = sst_hsw_stream_free(hsw, pcm_data->stream);
  285. if (ret < 0) {
  286. dev_dbg(rtd->dev, "error: free stream failed %d\n",
  287. ret);
  288. return ret;
  289. }
  290. pcm_data->allocated = false;
  291. pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
  292. hsw_notify_pointer, pcm_data);
  293. if (pcm_data->stream == NULL) {
  294. dev_err(rtd->dev, "error: failed to create stream\n");
  295. return -EINVAL;
  296. }
  297. }
  298. /* stream direction */
  299. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  300. path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
  301. else
  302. path_id = SST_HSW_STREAM_PATH_SSP0_IN;
  303. /* DSP stream type depends on DAI ID */
  304. switch (rtd->cpu_dai->id) {
  305. case 0:
  306. stream_type = SST_HSW_STREAM_TYPE_SYSTEM;
  307. module_id = SST_HSW_MODULE_PCM_SYSTEM;
  308. break;
  309. case 1:
  310. case 2:
  311. stream_type = SST_HSW_STREAM_TYPE_RENDER;
  312. module_id = SST_HSW_MODULE_PCM;
  313. break;
  314. case 3:
  315. /* path ID needs to be OUT for loopback */
  316. stream_type = SST_HSW_STREAM_TYPE_LOOPBACK;
  317. path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
  318. module_id = SST_HSW_MODULE_PCM_REFERENCE;
  319. break;
  320. case 4:
  321. stream_type = SST_HSW_STREAM_TYPE_CAPTURE;
  322. module_id = SST_HSW_MODULE_PCM_CAPTURE;
  323. break;
  324. default:
  325. dev_err(rtd->dev, "error: invalid DAI ID %d\n",
  326. rtd->cpu_dai->id);
  327. return -EINVAL;
  328. };
  329. ret = sst_hsw_stream_format(hsw, pcm_data->stream,
  330. path_id, stream_type, SST_HSW_STREAM_FORMAT_PCM_FORMAT);
  331. if (ret < 0) {
  332. dev_err(rtd->dev, "error: failed to set format %d\n", ret);
  333. return ret;
  334. }
  335. rate = params_rate(params);
  336. ret = sst_hsw_stream_set_rate(hsw, pcm_data->stream, rate);
  337. if (ret < 0) {
  338. dev_err(rtd->dev, "error: could not set rate %d\n", rate);
  339. return ret;
  340. }
  341. switch (params_format(params)) {
  342. case SNDRV_PCM_FORMAT_S16_LE:
  343. bits = SST_HSW_DEPTH_16BIT;
  344. sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16);
  345. break;
  346. case SNDRV_PCM_FORMAT_S24_LE:
  347. bits = SST_HSW_DEPTH_32BIT;
  348. sst_hsw_stream_set_valid(hsw, pcm_data->stream, 24);
  349. break;
  350. case SNDRV_PCM_FORMAT_S8:
  351. bits = SST_HSW_DEPTH_8BIT;
  352. sst_hsw_stream_set_valid(hsw, pcm_data->stream, 8);
  353. break;
  354. case SNDRV_PCM_FORMAT_S32_LE:
  355. bits = SST_HSW_DEPTH_32BIT;
  356. sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32);
  357. break;
  358. default:
  359. dev_err(rtd->dev, "error: invalid format %d\n",
  360. params_format(params));
  361. return -EINVAL;
  362. }
  363. ret = sst_hsw_stream_set_bits(hsw, pcm_data->stream, bits);
  364. if (ret < 0) {
  365. dev_err(rtd->dev, "error: could not set bits %d\n", bits);
  366. return ret;
  367. }
  368. /* we only support stereo atm */
  369. channels = params_channels(params);
  370. if (channels != 2) {
  371. dev_err(rtd->dev, "error: invalid channels %d\n", channels);
  372. return -EINVAL;
  373. }
  374. map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO);
  375. sst_hsw_stream_set_map_config(hsw, pcm_data->stream,
  376. map, SST_HSW_CHANNEL_CONFIG_STEREO);
  377. ret = sst_hsw_stream_set_channels(hsw, pcm_data->stream, channels);
  378. if (ret < 0) {
  379. dev_err(rtd->dev, "error: could not set channels %d\n",
  380. channels);
  381. return ret;
  382. }
  383. ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
  384. if (ret < 0) {
  385. dev_err(rtd->dev, "error: could not allocate %d bytes for PCM %d\n",
  386. params_buffer_bytes(params), ret);
  387. return ret;
  388. }
  389. dmab = snd_pcm_get_dma_buf(substream);
  390. ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area,
  391. runtime->dma_bytes, rtd->cpu_dai->id);
  392. if (ret < 0)
  393. return ret;
  394. sst_hsw_stream_set_style(hsw, pcm_data->stream,
  395. SST_HSW_INTERLEAVING_PER_CHANNEL);
  396. if (runtime->dma_bytes % PAGE_SIZE)
  397. pages = (runtime->dma_bytes / PAGE_SIZE) + 1;
  398. else
  399. pages = runtime->dma_bytes / PAGE_SIZE;
  400. ret = sst_hsw_stream_buffer(hsw, pcm_data->stream,
  401. pdata->dmab[rtd->cpu_dai->id][substream->stream].addr,
  402. pages, runtime->dma_bytes, 0,
  403. snd_sgbuf_get_addr(dmab, 0) >> PAGE_SHIFT);
  404. if (ret < 0) {
  405. dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret);
  406. return ret;
  407. }
  408. dsp = sst_hsw_get_dsp(hsw);
  409. module_data = sst_module_get_from_id(dsp, module_id);
  410. if (module_data == NULL) {
  411. dev_err(rtd->dev, "error: failed to get module config\n");
  412. return -EINVAL;
  413. }
  414. /* we use hardcoded memory offsets atm, will be updated for new FW */
  415. if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) {
  416. sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
  417. SST_HSW_MODULE_PCM_CAPTURE, module_data->entry);
  418. sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
  419. 0x449400, 0x4000);
  420. sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
  421. 0x400000, 0);
  422. } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
  423. sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
  424. SST_HSW_MODULE_PCM_SYSTEM, module_data->entry);
  425. sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
  426. module_data->offset, module_data->size);
  427. sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
  428. 0x44d400, 0x3800);
  429. sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
  430. module_data->offset, module_data->size);
  431. sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
  432. 0x400000, 0);
  433. }
  434. ret = sst_hsw_stream_commit(hsw, pcm_data->stream);
  435. if (ret < 0) {
  436. dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
  437. return ret;
  438. }
  439. pcm_data->allocated = true;
  440. ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
  441. if (ret < 0)
  442. dev_err(rtd->dev, "error: failed to pause %d\n", ret);
  443. return 0;
  444. }
  445. static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
  446. {
  447. snd_pcm_lib_free_pages(substream);
  448. return 0;
  449. }
  450. static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  451. {
  452. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  453. struct hsw_priv_data *pdata =
  454. snd_soc_platform_get_drvdata(rtd->platform);
  455. struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
  456. struct sst_hsw *hsw = pdata->hsw;
  457. switch (cmd) {
  458. case SNDRV_PCM_TRIGGER_START:
  459. case SNDRV_PCM_TRIGGER_RESUME:
  460. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  461. sst_hsw_stream_resume(hsw, pcm_data->stream, 0);
  462. break;
  463. case SNDRV_PCM_TRIGGER_STOP:
  464. case SNDRV_PCM_TRIGGER_SUSPEND:
  465. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  466. sst_hsw_stream_pause(hsw, pcm_data->stream, 0);
  467. break;
  468. default:
  469. break;
  470. }
  471. return 0;
  472. }
  473. static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
  474. {
  475. struct hsw_pcm_data *pcm_data = data;
  476. struct snd_pcm_substream *substream = pcm_data->substream;
  477. struct snd_pcm_runtime *runtime = substream->runtime;
  478. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  479. u32 pos;
  480. pos = frames_to_bytes(runtime,
  481. (runtime->control->appl_ptr % runtime->buffer_size));
  482. dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
  483. /* let alsa know we have play a period */
  484. snd_pcm_period_elapsed(substream);
  485. return pos;
  486. }
  487. static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
  488. {
  489. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  490. struct snd_pcm_runtime *runtime = substream->runtime;
  491. struct hsw_priv_data *pdata =
  492. snd_soc_platform_get_drvdata(rtd->platform);
  493. struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
  494. struct sst_hsw *hsw = pdata->hsw;
  495. snd_pcm_uframes_t offset;
  496. uint64_t ppos;
  497. u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
  498. offset = bytes_to_frames(runtime, position);
  499. ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
  500. dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
  501. position, ppos);
  502. return offset;
  503. }
  504. static int hsw_pcm_open(struct snd_pcm_substream *substream)
  505. {
  506. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  507. struct hsw_priv_data *pdata =
  508. snd_soc_platform_get_drvdata(rtd->platform);
  509. struct hsw_pcm_data *pcm_data;
  510. struct sst_hsw *hsw = pdata->hsw;
  511. pcm_data = &pdata->pcm[rtd->cpu_dai->id];
  512. mutex_lock(&pcm_data->mutex);
  513. snd_soc_pcm_set_drvdata(rtd, pcm_data);
  514. pcm_data->substream = substream;
  515. snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware);
  516. pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
  517. hsw_notify_pointer, pcm_data);
  518. if (pcm_data->stream == NULL) {
  519. dev_err(rtd->dev, "error: failed to create stream\n");
  520. mutex_unlock(&pcm_data->mutex);
  521. return -EINVAL;
  522. }
  523. /* Set previous saved volume */
  524. sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
  525. 0, pcm_data->volume[0]);
  526. sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
  527. 1, pcm_data->volume[1]);
  528. mutex_unlock(&pcm_data->mutex);
  529. return 0;
  530. }
  531. static int hsw_pcm_close(struct snd_pcm_substream *substream)
  532. {
  533. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  534. struct hsw_priv_data *pdata =
  535. snd_soc_platform_get_drvdata(rtd->platform);
  536. struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
  537. struct sst_hsw *hsw = pdata->hsw;
  538. int ret;
  539. mutex_lock(&pcm_data->mutex);
  540. ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
  541. if (ret < 0) {
  542. dev_dbg(rtd->dev, "error: reset stream failed %d\n", ret);
  543. goto out;
  544. }
  545. ret = sst_hsw_stream_free(hsw, pcm_data->stream);
  546. if (ret < 0) {
  547. dev_dbg(rtd->dev, "error: free stream failed %d\n", ret);
  548. goto out;
  549. }
  550. pcm_data->allocated = 0;
  551. pcm_data->stream = NULL;
  552. out:
  553. mutex_unlock(&pcm_data->mutex);
  554. return ret;
  555. }
  556. static struct snd_pcm_ops hsw_pcm_ops = {
  557. .open = hsw_pcm_open,
  558. .close = hsw_pcm_close,
  559. .ioctl = snd_pcm_lib_ioctl,
  560. .hw_params = hsw_pcm_hw_params,
  561. .hw_free = hsw_pcm_hw_free,
  562. .trigger = hsw_pcm_trigger,
  563. .pointer = hsw_pcm_pointer,
  564. .page = snd_pcm_sgbuf_ops_page,
  565. };
  566. static void hsw_pcm_free(struct snd_pcm *pcm)
  567. {
  568. snd_pcm_lib_preallocate_free_for_all(pcm);
  569. }
  570. static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
  571. {
  572. struct snd_pcm *pcm = rtd->pcm;
  573. struct snd_soc_platform *platform = rtd->platform;
  574. struct sst_pdata *pdata = dev_get_platdata(platform->dev);
  575. struct device *dev = pdata->dma_dev;
  576. int ret = 0;
  577. if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
  578. pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
  579. ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
  580. SNDRV_DMA_TYPE_DEV_SG,
  581. dev,
  582. hsw_pcm_hardware.buffer_bytes_max,
  583. hsw_pcm_hardware.buffer_bytes_max);
  584. if (ret) {
  585. dev_err(rtd->dev, "dma buffer allocation failed %d\n",
  586. ret);
  587. return ret;
  588. }
  589. }
  590. return ret;
  591. }
  592. #define HSW_FORMATS \
  593. (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
  594. static struct snd_soc_dai_driver hsw_dais[] = {
  595. {
  596. .name = "System Pin",
  597. .playback = {
  598. .stream_name = "System Playback",
  599. .channels_min = 2,
  600. .channels_max = 2,
  601. .rates = SNDRV_PCM_RATE_48000,
  602. .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
  603. },
  604. },
  605. {
  606. /* PCM */
  607. .name = "Offload0 Pin",
  608. .playback = {
  609. .stream_name = "Offload0 Playback",
  610. .channels_min = 2,
  611. .channels_max = 2,
  612. .rates = SNDRV_PCM_RATE_8000_192000,
  613. .formats = HSW_FORMATS,
  614. },
  615. },
  616. {
  617. /* PCM */
  618. .name = "Offload1 Pin",
  619. .playback = {
  620. .stream_name = "Offload1 Playback",
  621. .channels_min = 2,
  622. .channels_max = 2,
  623. .rates = SNDRV_PCM_RATE_8000_192000,
  624. .formats = HSW_FORMATS,
  625. },
  626. },
  627. {
  628. .name = "Loopback Pin",
  629. .capture = {
  630. .stream_name = "Loopback Capture",
  631. .channels_min = 2,
  632. .channels_max = 2,
  633. .rates = SNDRV_PCM_RATE_48000,
  634. .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
  635. },
  636. },
  637. {
  638. .name = "Capture Pin",
  639. .capture = {
  640. .stream_name = "Analog Capture",
  641. .channels_min = 2,
  642. .channels_max = 2,
  643. .rates = SNDRV_PCM_RATE_48000,
  644. .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
  645. },
  646. },
  647. };
  648. static const struct snd_soc_dapm_widget widgets[] = {
  649. /* Backend DAIs */
  650. SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0),
  651. SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
  652. SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0),
  653. SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
  654. /* Global Playback Mixer */
  655. SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
  656. };
  657. static const struct snd_soc_dapm_route graph[] = {
  658. /* Playback Mixer */
  659. {"Playback VMixer", NULL, "System Playback"},
  660. {"Playback VMixer", NULL, "Offload0 Playback"},
  661. {"Playback VMixer", NULL, "Offload1 Playback"},
  662. {"SSP0 CODEC OUT", NULL, "Playback VMixer"},
  663. {"Analog Capture", NULL, "SSP0 CODEC IN"},
  664. };
  665. static int hsw_pcm_probe(struct snd_soc_platform *platform)
  666. {
  667. struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
  668. struct sst_pdata *pdata = dev_get_platdata(platform->dev);
  669. struct device *dma_dev = pdata->dma_dev;
  670. int i, ret = 0;
  671. /* allocate DSP buffer page tables */
  672. for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
  673. mutex_init(&priv_data->pcm[i].mutex);
  674. /* playback */
  675. if (hsw_dais[i].playback.channels_min) {
  676. ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
  677. PAGE_SIZE, &priv_data->dmab[i][0]);
  678. if (ret < 0)
  679. goto err;
  680. }
  681. /* capture */
  682. if (hsw_dais[i].capture.channels_min) {
  683. ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
  684. PAGE_SIZE, &priv_data->dmab[i][1]);
  685. if (ret < 0)
  686. goto err;
  687. }
  688. }
  689. return 0;
  690. err:
  691. for (;i >= 0; i--) {
  692. if (hsw_dais[i].playback.channels_min)
  693. snd_dma_free_pages(&priv_data->dmab[i][0]);
  694. if (hsw_dais[i].capture.channels_min)
  695. snd_dma_free_pages(&priv_data->dmab[i][1]);
  696. }
  697. return ret;
  698. }
  699. static int hsw_pcm_remove(struct snd_soc_platform *platform)
  700. {
  701. struct hsw_priv_data *priv_data =
  702. snd_soc_platform_get_drvdata(platform);
  703. int i;
  704. for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
  705. if (hsw_dais[i].playback.channels_min)
  706. snd_dma_free_pages(&priv_data->dmab[i][0]);
  707. if (hsw_dais[i].capture.channels_min)
  708. snd_dma_free_pages(&priv_data->dmab[i][1]);
  709. }
  710. return 0;
  711. }
  712. static struct snd_soc_platform_driver hsw_soc_platform = {
  713. .probe = hsw_pcm_probe,
  714. .remove = hsw_pcm_remove,
  715. .ops = &hsw_pcm_ops,
  716. .pcm_new = hsw_pcm_new,
  717. .pcm_free = hsw_pcm_free,
  718. };
  719. static const struct snd_soc_component_driver hsw_dai_component = {
  720. .name = "haswell-dai",
  721. .controls = hsw_volume_controls,
  722. .num_controls = ARRAY_SIZE(hsw_volume_controls),
  723. .dapm_widgets = widgets,
  724. .num_dapm_widgets = ARRAY_SIZE(widgets),
  725. .dapm_routes = graph,
  726. .num_dapm_routes = ARRAY_SIZE(graph),
  727. };
  728. static int hsw_pcm_dev_probe(struct platform_device *pdev)
  729. {
  730. struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
  731. struct hsw_priv_data *priv_data;
  732. int ret;
  733. if (!sst_pdata)
  734. return -EINVAL;
  735. priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv_data), GFP_KERNEL);
  736. if (!priv_data)
  737. return -ENOMEM;
  738. ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata);
  739. if (ret < 0)
  740. return -ENODEV;
  741. priv_data->hsw = sst_pdata->dsp;
  742. platform_set_drvdata(pdev, priv_data);
  743. ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
  744. if (ret < 0)
  745. goto err_plat;
  746. ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component,
  747. hsw_dais, ARRAY_SIZE(hsw_dais));
  748. if (ret < 0)
  749. goto err_comp;
  750. return 0;
  751. err_comp:
  752. snd_soc_unregister_platform(&pdev->dev);
  753. err_plat:
  754. sst_hsw_dsp_free(&pdev->dev, sst_pdata);
  755. return 0;
  756. }
  757. static int hsw_pcm_dev_remove(struct platform_device *pdev)
  758. {
  759. struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
  760. snd_soc_unregister_platform(&pdev->dev);
  761. snd_soc_unregister_component(&pdev->dev);
  762. sst_hsw_dsp_free(&pdev->dev, sst_pdata);
  763. return 0;
  764. }
  765. static struct platform_driver hsw_pcm_driver = {
  766. .driver = {
  767. .name = "haswell-pcm-audio",
  768. .owner = THIS_MODULE,
  769. },
  770. .probe = hsw_pcm_dev_probe,
  771. .remove = hsw_pcm_dev_remove,
  772. };
  773. module_platform_driver(hsw_pcm_driver);
  774. MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
  775. MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
  776. MODULE_LICENSE("GPL v2");
  777. MODULE_ALIAS("platform:haswell-pcm-audio");