fireworks_pcm.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * fireworks_pcm.c - a part of driver for Fireworks based devices
  4. *
  5. * Copyright (c) 2009-2010 Clemens Ladisch
  6. * Copyright (c) 2013-2014 Takashi Sakamoto
  7. */
  8. #include "./fireworks.h"
  9. /*
  10. * NOTE:
  11. * Fireworks changes its AMDTP channels for PCM data according to its sampling
  12. * rate. There are three modes. Here _XX is either _rx or _tx.
  13. * 0: 32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied
  14. * 1: 88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied
  15. * 2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied
  16. *
  17. * The number of PCM channels for analog input and output are always fixed but
  18. * the number of PCM channels for digital input and output are differed.
  19. *
  20. * Additionally, according to "AudioFire Owner's Manual Version 2.2", in some
  21. * model, the number of PCM channels for digital input has more restriction
  22. * depending on which digital interface is selected.
  23. * - S/PDIF coaxial and optical : use input 1-2
  24. * - ADAT optical at 32.0-48.0 kHz : use input 1-8
  25. * - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format)
  26. *
  27. * The data in AMDTP channels for blank PCM channels are zero.
  28. */
  29. static const unsigned int freq_table[] = {
  30. /* multiplier mode 0 */
  31. [0] = 32000,
  32. [1] = 44100,
  33. [2] = 48000,
  34. /* multiplier mode 1 */
  35. [3] = 88200,
  36. [4] = 96000,
  37. /* multiplier mode 2 */
  38. [5] = 176400,
  39. [6] = 192000,
  40. };
  41. static inline unsigned int
  42. get_multiplier_mode_with_index(unsigned int index)
  43. {
  44. return ((int)index - 1) / 2;
  45. }
  46. int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode)
  47. {
  48. unsigned int i;
  49. for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
  50. if (freq_table[i] == sampling_rate) {
  51. *mode = get_multiplier_mode_with_index(i);
  52. return 0;
  53. }
  54. }
  55. return -EINVAL;
  56. }
  57. static int
  58. hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
  59. {
  60. unsigned int *pcm_channels = rule->private;
  61. struct snd_interval *r =
  62. hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
  63. const struct snd_interval *c =
  64. hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
  65. struct snd_interval t = {
  66. .min = UINT_MAX, .max = 0, .integer = 1
  67. };
  68. unsigned int i, mode;
  69. for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
  70. mode = get_multiplier_mode_with_index(i);
  71. if (!snd_interval_test(c, pcm_channels[mode]))
  72. continue;
  73. t.min = min(t.min, freq_table[i]);
  74. t.max = max(t.max, freq_table[i]);
  75. }
  76. return snd_interval_refine(r, &t);
  77. }
  78. static int
  79. hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
  80. {
  81. unsigned int *pcm_channels = rule->private;
  82. struct snd_interval *c =
  83. hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
  84. const struct snd_interval *r =
  85. hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
  86. struct snd_interval t = {
  87. .min = UINT_MAX, .max = 0, .integer = 1
  88. };
  89. unsigned int i, mode;
  90. for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
  91. mode = get_multiplier_mode_with_index(i);
  92. if (!snd_interval_test(r, freq_table[i]))
  93. continue;
  94. t.min = min(t.min, pcm_channels[mode]);
  95. t.max = max(t.max, pcm_channels[mode]);
  96. }
  97. return snd_interval_refine(c, &t);
  98. }
  99. static void
  100. limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels)
  101. {
  102. unsigned int i, mode;
  103. hw->channels_min = UINT_MAX;
  104. hw->channels_max = 0;
  105. for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
  106. mode = get_multiplier_mode_with_index(i);
  107. if (pcm_channels[mode] == 0)
  108. continue;
  109. hw->channels_min = min(hw->channels_min, pcm_channels[mode]);
  110. hw->channels_max = max(hw->channels_max, pcm_channels[mode]);
  111. }
  112. }
  113. static int
  114. pcm_init_hw_params(struct snd_efw *efw,
  115. struct snd_pcm_substream *substream)
  116. {
  117. struct snd_pcm_runtime *runtime = substream->runtime;
  118. struct amdtp_stream *s;
  119. unsigned int *pcm_channels;
  120. int err;
  121. if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
  122. runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
  123. s = &efw->tx_stream;
  124. pcm_channels = efw->pcm_capture_channels;
  125. } else {
  126. runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
  127. s = &efw->rx_stream;
  128. pcm_channels = efw->pcm_playback_channels;
  129. }
  130. /* limit rates */
  131. runtime->hw.rates = efw->supported_sampling_rate;
  132. snd_pcm_limit_hw_rates(runtime);
  133. limit_channels(&runtime->hw, pcm_channels);
  134. err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  135. hw_rule_channels, pcm_channels,
  136. SNDRV_PCM_HW_PARAM_RATE, -1);
  137. if (err < 0)
  138. goto end;
  139. err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  140. hw_rule_rate, pcm_channels,
  141. SNDRV_PCM_HW_PARAM_CHANNELS, -1);
  142. if (err < 0)
  143. goto end;
  144. err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
  145. end:
  146. return err;
  147. }
  148. static int pcm_open(struct snd_pcm_substream *substream)
  149. {
  150. struct snd_efw *efw = substream->private_data;
  151. struct amdtp_domain *d = &efw->domain;
  152. enum snd_efw_clock_source clock_source;
  153. int err;
  154. err = snd_efw_stream_lock_try(efw);
  155. if (err < 0)
  156. return err;
  157. err = pcm_init_hw_params(efw, substream);
  158. if (err < 0)
  159. goto err_locked;
  160. err = snd_efw_command_get_clock_source(efw, &clock_source);
  161. if (err < 0)
  162. goto err_locked;
  163. mutex_lock(&efw->mutex);
  164. // When source of clock is not internal or any stream is reserved for
  165. // transmission of PCM frames, the available sampling rate is limited
  166. // at current one.
  167. if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
  168. (efw->substreams_counter > 0 && d->events_per_period > 0)) {
  169. unsigned int frames_per_period = d->events_per_period;
  170. unsigned int frames_per_buffer = d->events_per_buffer;
  171. unsigned int sampling_rate;
  172. err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
  173. if (err < 0) {
  174. mutex_unlock(&efw->mutex);
  175. goto err_locked;
  176. }
  177. substream->runtime->hw.rate_min = sampling_rate;
  178. substream->runtime->hw.rate_max = sampling_rate;
  179. if (frames_per_period > 0) {
  180. err = snd_pcm_hw_constraint_minmax(substream->runtime,
  181. SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
  182. frames_per_period, frames_per_period);
  183. if (err < 0) {
  184. mutex_unlock(&efw->mutex);
  185. goto err_locked;
  186. }
  187. err = snd_pcm_hw_constraint_minmax(substream->runtime,
  188. SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
  189. frames_per_buffer, frames_per_buffer);
  190. if (err < 0) {
  191. mutex_unlock(&efw->mutex);
  192. goto err_locked;
  193. }
  194. }
  195. }
  196. mutex_unlock(&efw->mutex);
  197. snd_pcm_set_sync(substream);
  198. return 0;
  199. err_locked:
  200. snd_efw_stream_lock_release(efw);
  201. return err;
  202. }
  203. static int pcm_close(struct snd_pcm_substream *substream)
  204. {
  205. struct snd_efw *efw = substream->private_data;
  206. snd_efw_stream_lock_release(efw);
  207. return 0;
  208. }
  209. static int pcm_hw_params(struct snd_pcm_substream *substream,
  210. struct snd_pcm_hw_params *hw_params)
  211. {
  212. struct snd_efw *efw = substream->private_data;
  213. int err = 0;
  214. if (substream->runtime->state == SNDRV_PCM_STATE_OPEN) {
  215. unsigned int rate = params_rate(hw_params);
  216. unsigned int frames_per_period = params_period_size(hw_params);
  217. unsigned int frames_per_buffer = params_buffer_size(hw_params);
  218. mutex_lock(&efw->mutex);
  219. err = snd_efw_stream_reserve_duplex(efw, rate,
  220. frames_per_period, frames_per_buffer);
  221. if (err >= 0)
  222. ++efw->substreams_counter;
  223. mutex_unlock(&efw->mutex);
  224. }
  225. return err;
  226. }
  227. static int pcm_hw_free(struct snd_pcm_substream *substream)
  228. {
  229. struct snd_efw *efw = substream->private_data;
  230. mutex_lock(&efw->mutex);
  231. if (substream->runtime->state != SNDRV_PCM_STATE_OPEN)
  232. --efw->substreams_counter;
  233. snd_efw_stream_stop_duplex(efw);
  234. mutex_unlock(&efw->mutex);
  235. return 0;
  236. }
  237. static int pcm_capture_prepare(struct snd_pcm_substream *substream)
  238. {
  239. struct snd_efw *efw = substream->private_data;
  240. int err;
  241. err = snd_efw_stream_start_duplex(efw);
  242. if (err >= 0)
  243. amdtp_stream_pcm_prepare(&efw->tx_stream);
  244. return err;
  245. }
  246. static int pcm_playback_prepare(struct snd_pcm_substream *substream)
  247. {
  248. struct snd_efw *efw = substream->private_data;
  249. int err;
  250. err = snd_efw_stream_start_duplex(efw);
  251. if (err >= 0)
  252. amdtp_stream_pcm_prepare(&efw->rx_stream);
  253. return err;
  254. }
  255. static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
  256. {
  257. struct snd_efw *efw = substream->private_data;
  258. switch (cmd) {
  259. case SNDRV_PCM_TRIGGER_START:
  260. amdtp_stream_pcm_trigger(&efw->tx_stream, substream);
  261. break;
  262. case SNDRV_PCM_TRIGGER_STOP:
  263. amdtp_stream_pcm_trigger(&efw->tx_stream, NULL);
  264. break;
  265. default:
  266. return -EINVAL;
  267. }
  268. return 0;
  269. }
  270. static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
  271. {
  272. struct snd_efw *efw = substream->private_data;
  273. switch (cmd) {
  274. case SNDRV_PCM_TRIGGER_START:
  275. amdtp_stream_pcm_trigger(&efw->rx_stream, substream);
  276. break;
  277. case SNDRV_PCM_TRIGGER_STOP:
  278. amdtp_stream_pcm_trigger(&efw->rx_stream, NULL);
  279. break;
  280. default:
  281. return -EINVAL;
  282. }
  283. return 0;
  284. }
  285. static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
  286. {
  287. struct snd_efw *efw = sbstrm->private_data;
  288. return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream);
  289. }
  290. static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
  291. {
  292. struct snd_efw *efw = sbstrm->private_data;
  293. return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream);
  294. }
  295. static int pcm_capture_ack(struct snd_pcm_substream *substream)
  296. {
  297. struct snd_efw *efw = substream->private_data;
  298. return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream);
  299. }
  300. static int pcm_playback_ack(struct snd_pcm_substream *substream)
  301. {
  302. struct snd_efw *efw = substream->private_data;
  303. return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream);
  304. }
  305. int snd_efw_create_pcm_devices(struct snd_efw *efw)
  306. {
  307. static const struct snd_pcm_ops capture_ops = {
  308. .open = pcm_open,
  309. .close = pcm_close,
  310. .hw_params = pcm_hw_params,
  311. .hw_free = pcm_hw_free,
  312. .prepare = pcm_capture_prepare,
  313. .trigger = pcm_capture_trigger,
  314. .pointer = pcm_capture_pointer,
  315. .ack = pcm_capture_ack,
  316. };
  317. static const struct snd_pcm_ops playback_ops = {
  318. .open = pcm_open,
  319. .close = pcm_close,
  320. .hw_params = pcm_hw_params,
  321. .hw_free = pcm_hw_free,
  322. .prepare = pcm_playback_prepare,
  323. .trigger = pcm_playback_trigger,
  324. .pointer = pcm_playback_pointer,
  325. .ack = pcm_playback_ack,
  326. };
  327. struct snd_pcm *pcm;
  328. int err;
  329. err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm);
  330. if (err < 0)
  331. goto end;
  332. pcm->private_data = efw;
  333. pcm->nonatomic = true;
  334. snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
  335. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
  336. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
  337. snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
  338. end:
  339. return err;
  340. }