ctpcm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
  4. *
  5. * @File ctpcm.c
  6. *
  7. * @Brief
  8. * This file contains the definition of the pcm device functions.
  9. *
  10. * @Author Liu Chun
  11. * @Date Apr 2 2008
  12. */
  13. #include "ctpcm.h"
  14. #include "cttimer.h"
  15. #include <linux/slab.h>
  16. #include <sound/pcm.h>
  17. /* Hardware descriptions for playback */
  18. static const struct snd_pcm_hardware ct_pcm_playback_hw = {
  19. .info = (SNDRV_PCM_INFO_MMAP |
  20. SNDRV_PCM_INFO_INTERLEAVED |
  21. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  22. SNDRV_PCM_INFO_MMAP_VALID |
  23. SNDRV_PCM_INFO_PAUSE),
  24. .formats = (SNDRV_PCM_FMTBIT_U8 |
  25. SNDRV_PCM_FMTBIT_S16_LE |
  26. SNDRV_PCM_FMTBIT_S24_3LE |
  27. SNDRV_PCM_FMTBIT_S32_LE |
  28. SNDRV_PCM_FMTBIT_FLOAT_LE),
  29. .rates = (SNDRV_PCM_RATE_CONTINUOUS |
  30. SNDRV_PCM_RATE_8000_192000),
  31. .rate_min = 8000,
  32. .rate_max = 192000,
  33. .channels_min = 1,
  34. .channels_max = 2,
  35. .buffer_bytes_max = (128*1024),
  36. .period_bytes_min = (64),
  37. .period_bytes_max = (128*1024),
  38. .periods_min = 2,
  39. .periods_max = 1024,
  40. .fifo_size = 0,
  41. };
  42. static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
  43. .info = (SNDRV_PCM_INFO_MMAP |
  44. SNDRV_PCM_INFO_INTERLEAVED |
  45. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  46. SNDRV_PCM_INFO_MMAP_VALID |
  47. SNDRV_PCM_INFO_PAUSE),
  48. .formats = SNDRV_PCM_FMTBIT_S16_LE,
  49. .rates = (SNDRV_PCM_RATE_48000 |
  50. SNDRV_PCM_RATE_44100 |
  51. SNDRV_PCM_RATE_32000),
  52. .rate_min = 32000,
  53. .rate_max = 48000,
  54. .channels_min = 2,
  55. .channels_max = 2,
  56. .buffer_bytes_max = (128*1024),
  57. .period_bytes_min = (64),
  58. .period_bytes_max = (128*1024),
  59. .periods_min = 2,
  60. .periods_max = 1024,
  61. .fifo_size = 0,
  62. };
  63. /* Hardware descriptions for capture */
  64. static const struct snd_pcm_hardware ct_pcm_capture_hw = {
  65. .info = (SNDRV_PCM_INFO_MMAP |
  66. SNDRV_PCM_INFO_INTERLEAVED |
  67. SNDRV_PCM_INFO_BLOCK_TRANSFER |
  68. SNDRV_PCM_INFO_PAUSE |
  69. SNDRV_PCM_INFO_MMAP_VALID),
  70. .formats = (SNDRV_PCM_FMTBIT_U8 |
  71. SNDRV_PCM_FMTBIT_S16_LE |
  72. SNDRV_PCM_FMTBIT_S24_3LE |
  73. SNDRV_PCM_FMTBIT_S32_LE |
  74. SNDRV_PCM_FMTBIT_FLOAT_LE),
  75. .rates = (SNDRV_PCM_RATE_CONTINUOUS |
  76. SNDRV_PCM_RATE_8000_96000),
  77. .rate_min = 8000,
  78. .rate_max = 96000,
  79. .channels_min = 1,
  80. .channels_max = 2,
  81. .buffer_bytes_max = (128*1024),
  82. .period_bytes_min = (384),
  83. .period_bytes_max = (64*1024),
  84. .periods_min = 2,
  85. .periods_max = 1024,
  86. .fifo_size = 0,
  87. };
  88. static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
  89. {
  90. struct ct_atc_pcm *apcm = atc_pcm;
  91. if (!apcm->substream)
  92. return;
  93. snd_pcm_period_elapsed(apcm->substream);
  94. }
  95. static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
  96. {
  97. struct ct_atc_pcm *apcm = runtime->private_data;
  98. struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
  99. atc->pcm_release_resources(atc, apcm);
  100. ct_timer_instance_free(apcm->timer);
  101. kfree(apcm);
  102. runtime->private_data = NULL;
  103. }
  104. /* pcm playback operations */
  105. static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
  106. {
  107. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  108. struct snd_pcm_runtime *runtime = substream->runtime;
  109. struct ct_atc_pcm *apcm;
  110. int err;
  111. apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
  112. if (!apcm)
  113. return -ENOMEM;
  114. apcm->substream = substream;
  115. apcm->interrupt = ct_atc_pcm_interrupt;
  116. if (IEC958 == substream->pcm->device) {
  117. runtime->hw = ct_spdif_passthru_playback_hw;
  118. atc->spdif_out_passthru(atc, 1);
  119. } else {
  120. runtime->hw = ct_pcm_playback_hw;
  121. if (FRONT == substream->pcm->device)
  122. runtime->hw.channels_max = 8;
  123. }
  124. err = snd_pcm_hw_constraint_integer(runtime,
  125. SNDRV_PCM_HW_PARAM_PERIODS);
  126. if (err < 0)
  127. goto free_pcm;
  128. err = snd_pcm_hw_constraint_minmax(runtime,
  129. SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
  130. 1024, UINT_MAX);
  131. if (err < 0)
  132. goto free_pcm;
  133. apcm->timer = ct_timer_instance_new(atc->timer, apcm);
  134. if (!apcm->timer) {
  135. err = -ENOMEM;
  136. goto free_pcm;
  137. }
  138. runtime->private_data = apcm;
  139. runtime->private_free = ct_atc_pcm_free_substream;
  140. return 0;
  141. free_pcm:
  142. kfree(apcm);
  143. return err;
  144. }
  145. static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
  146. {
  147. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  148. /* TODO: Notify mixer inactive. */
  149. if (IEC958 == substream->pcm->device)
  150. atc->spdif_out_passthru(atc, 0);
  151. /* The ct_atc_pcm object will be freed by runtime->private_free */
  152. return 0;
  153. }
  154. static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
  155. struct snd_pcm_hw_params *hw_params)
  156. {
  157. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  158. struct ct_atc_pcm *apcm = substream->runtime->private_data;
  159. /* clear previous resources */
  160. atc->pcm_release_resources(atc, apcm);
  161. return 0;
  162. }
  163. static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
  164. {
  165. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  166. struct ct_atc_pcm *apcm = substream->runtime->private_data;
  167. /* clear previous resources */
  168. atc->pcm_release_resources(atc, apcm);
  169. return 0;
  170. }
  171. static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
  172. {
  173. int err;
  174. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  175. struct snd_pcm_runtime *runtime = substream->runtime;
  176. struct ct_atc_pcm *apcm = runtime->private_data;
  177. if (IEC958 == substream->pcm->device)
  178. err = atc->spdif_passthru_playback_prepare(atc, apcm);
  179. else
  180. err = atc->pcm_playback_prepare(atc, apcm);
  181. if (err < 0) {
  182. dev_err(atc->card->dev,
  183. "Preparing pcm playback failed!!!\n");
  184. return err;
  185. }
  186. return 0;
  187. }
  188. static int
  189. ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
  190. {
  191. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  192. struct snd_pcm_runtime *runtime = substream->runtime;
  193. struct ct_atc_pcm *apcm = runtime->private_data;
  194. switch (cmd) {
  195. case SNDRV_PCM_TRIGGER_START:
  196. case SNDRV_PCM_TRIGGER_RESUME:
  197. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  198. atc->pcm_playback_start(atc, apcm);
  199. break;
  200. case SNDRV_PCM_TRIGGER_STOP:
  201. case SNDRV_PCM_TRIGGER_SUSPEND:
  202. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  203. atc->pcm_playback_stop(atc, apcm);
  204. break;
  205. default:
  206. break;
  207. }
  208. return 0;
  209. }
  210. static snd_pcm_uframes_t
  211. ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
  212. {
  213. unsigned long position;
  214. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  215. struct snd_pcm_runtime *runtime = substream->runtime;
  216. struct ct_atc_pcm *apcm = runtime->private_data;
  217. /* Read out playback position */
  218. position = atc->pcm_playback_position(atc, apcm);
  219. position = bytes_to_frames(runtime, position);
  220. if (position >= runtime->buffer_size)
  221. position = 0;
  222. return position;
  223. }
  224. /* pcm capture operations */
  225. static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
  226. {
  227. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  228. struct snd_pcm_runtime *runtime = substream->runtime;
  229. struct ct_atc_pcm *apcm;
  230. int err;
  231. apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
  232. if (!apcm)
  233. return -ENOMEM;
  234. apcm->started = 0;
  235. apcm->substream = substream;
  236. apcm->interrupt = ct_atc_pcm_interrupt;
  237. runtime->hw = ct_pcm_capture_hw;
  238. runtime->hw.rate_max = atc->rsr * atc->msr;
  239. err = snd_pcm_hw_constraint_integer(runtime,
  240. SNDRV_PCM_HW_PARAM_PERIODS);
  241. if (err < 0)
  242. goto free_pcm;
  243. err = snd_pcm_hw_constraint_minmax(runtime,
  244. SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
  245. 1024, UINT_MAX);
  246. if (err < 0)
  247. goto free_pcm;
  248. apcm->timer = ct_timer_instance_new(atc->timer, apcm);
  249. if (!apcm->timer) {
  250. err = -ENOMEM;
  251. goto free_pcm;
  252. }
  253. runtime->private_data = apcm;
  254. runtime->private_free = ct_atc_pcm_free_substream;
  255. return 0;
  256. free_pcm:
  257. kfree(apcm);
  258. return err;
  259. }
  260. static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
  261. {
  262. /* The ct_atc_pcm object will be freed by runtime->private_free */
  263. /* TODO: Notify mixer inactive. */
  264. return 0;
  265. }
  266. static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
  267. {
  268. int err;
  269. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  270. struct snd_pcm_runtime *runtime = substream->runtime;
  271. struct ct_atc_pcm *apcm = runtime->private_data;
  272. err = atc->pcm_capture_prepare(atc, apcm);
  273. if (err < 0) {
  274. dev_err(atc->card->dev,
  275. "Preparing pcm capture failed!!!\n");
  276. return err;
  277. }
  278. return 0;
  279. }
  280. static int
  281. ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
  282. {
  283. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  284. struct snd_pcm_runtime *runtime = substream->runtime;
  285. struct ct_atc_pcm *apcm = runtime->private_data;
  286. switch (cmd) {
  287. case SNDRV_PCM_TRIGGER_START:
  288. atc->pcm_capture_start(atc, apcm);
  289. break;
  290. case SNDRV_PCM_TRIGGER_STOP:
  291. atc->pcm_capture_stop(atc, apcm);
  292. break;
  293. default:
  294. atc->pcm_capture_stop(atc, apcm);
  295. break;
  296. }
  297. return 0;
  298. }
  299. static snd_pcm_uframes_t
  300. ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
  301. {
  302. unsigned long position;
  303. struct ct_atc *atc = snd_pcm_substream_chip(substream);
  304. struct snd_pcm_runtime *runtime = substream->runtime;
  305. struct ct_atc_pcm *apcm = runtime->private_data;
  306. /* Read out playback position */
  307. position = atc->pcm_capture_position(atc, apcm);
  308. position = bytes_to_frames(runtime, position);
  309. if (position >= runtime->buffer_size)
  310. position = 0;
  311. return position;
  312. }
  313. /* PCM operators for playback */
  314. static const struct snd_pcm_ops ct_pcm_playback_ops = {
  315. .open = ct_pcm_playback_open,
  316. .close = ct_pcm_playback_close,
  317. .hw_params = ct_pcm_hw_params,
  318. .hw_free = ct_pcm_hw_free,
  319. .prepare = ct_pcm_playback_prepare,
  320. .trigger = ct_pcm_playback_trigger,
  321. .pointer = ct_pcm_playback_pointer,
  322. };
  323. /* PCM operators for capture */
  324. static const struct snd_pcm_ops ct_pcm_capture_ops = {
  325. .open = ct_pcm_capture_open,
  326. .close = ct_pcm_capture_close,
  327. .hw_params = ct_pcm_hw_params,
  328. .hw_free = ct_pcm_hw_free,
  329. .prepare = ct_pcm_capture_prepare,
  330. .trigger = ct_pcm_capture_trigger,
  331. .pointer = ct_pcm_capture_pointer,
  332. };
  333. static const struct snd_pcm_chmap_elem surround_map[] = {
  334. { .channels = 1,
  335. .map = { SNDRV_CHMAP_MONO } },
  336. { .channels = 2,
  337. .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  338. { }
  339. };
  340. static const struct snd_pcm_chmap_elem clfe_map[] = {
  341. { .channels = 1,
  342. .map = { SNDRV_CHMAP_MONO } },
  343. { .channels = 2,
  344. .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
  345. { }
  346. };
  347. static const struct snd_pcm_chmap_elem side_map[] = {
  348. { .channels = 1,
  349. .map = { SNDRV_CHMAP_MONO } },
  350. { .channels = 2,
  351. .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
  352. { }
  353. };
  354. /* Create ALSA pcm device */
  355. int ct_alsa_pcm_create(struct ct_atc *atc,
  356. enum CTALSADEVS device,
  357. const char *device_name)
  358. {
  359. struct snd_pcm *pcm;
  360. const struct snd_pcm_chmap_elem *map;
  361. int chs;
  362. int err;
  363. int playback_count, capture_count;
  364. playback_count = (IEC958 == device) ? 1 : 256;
  365. capture_count = (FRONT == device) ? 1 : 0;
  366. err = snd_pcm_new(atc->card, "ctxfi", device,
  367. playback_count, capture_count, &pcm);
  368. if (err < 0) {
  369. dev_err(atc->card->dev, "snd_pcm_new failed!! Err=%d\n",
  370. err);
  371. return err;
  372. }
  373. pcm->private_data = atc;
  374. pcm->info_flags = 0;
  375. pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
  376. strscpy(pcm->name, device_name, sizeof(pcm->name));
  377. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
  378. if (FRONT == device)
  379. snd_pcm_set_ops(pcm,
  380. SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
  381. snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
  382. &atc->pci->dev, 128*1024, 128*1024);
  383. chs = 2;
  384. switch (device) {
  385. case FRONT:
  386. chs = 8;
  387. map = snd_pcm_std_chmaps;
  388. break;
  389. case SURROUND:
  390. map = surround_map;
  391. break;
  392. case CLFE:
  393. map = clfe_map;
  394. break;
  395. case SIDE:
  396. map = side_map;
  397. break;
  398. default:
  399. map = snd_pcm_std_chmaps;
  400. break;
  401. }
  402. err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
  403. 0, NULL);
  404. if (err < 0)
  405. return err;
  406. #ifdef CONFIG_PM_SLEEP
  407. atc->pcms[device] = pcm;
  408. #endif
  409. return 0;
  410. }