amdtp-ff.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * amdtp-ff.c - a part of driver for RME Fireface series
  4. *
  5. * Copyright (c) 2015-2017 Takashi Sakamoto
  6. */
  7. #include <sound/pcm.h>
  8. #include "ff.h"
  9. struct amdtp_ff {
  10. unsigned int pcm_channels;
  11. };
  12. int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,
  13. unsigned int pcm_channels)
  14. {
  15. struct amdtp_ff *p = s->protocol;
  16. unsigned int data_channels;
  17. if (amdtp_stream_running(s))
  18. return -EBUSY;
  19. p->pcm_channels = pcm_channels;
  20. data_channels = pcm_channels;
  21. return amdtp_stream_set_parameters(s, rate, data_channels, 1);
  22. }
  23. static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
  24. __le32 *buffer, unsigned int frames,
  25. unsigned int pcm_frames)
  26. {
  27. struct amdtp_ff *p = s->protocol;
  28. unsigned int channels = p->pcm_channels;
  29. struct snd_pcm_runtime *runtime = pcm->runtime;
  30. unsigned int pcm_buffer_pointer;
  31. int remaining_frames;
  32. const u32 *src;
  33. int i, c;
  34. pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
  35. pcm_buffer_pointer %= runtime->buffer_size;
  36. src = (void *)runtime->dma_area +
  37. frames_to_bytes(runtime, pcm_buffer_pointer);
  38. remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
  39. for (i = 0; i < frames; ++i) {
  40. for (c = 0; c < channels; ++c) {
  41. buffer[c] = cpu_to_le32(*src);
  42. src++;
  43. }
  44. buffer += s->data_block_quadlets;
  45. if (--remaining_frames == 0)
  46. src = (void *)runtime->dma_area;
  47. }
  48. }
  49. static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
  50. __le32 *buffer, unsigned int frames,
  51. unsigned int pcm_frames)
  52. {
  53. struct amdtp_ff *p = s->protocol;
  54. unsigned int channels = p->pcm_channels;
  55. struct snd_pcm_runtime *runtime = pcm->runtime;
  56. unsigned int pcm_buffer_pointer;
  57. int remaining_frames;
  58. u32 *dst;
  59. int i, c;
  60. pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
  61. pcm_buffer_pointer %= runtime->buffer_size;
  62. dst = (void *)runtime->dma_area +
  63. frames_to_bytes(runtime, pcm_buffer_pointer);
  64. remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
  65. for (i = 0; i < frames; ++i) {
  66. for (c = 0; c < channels; ++c) {
  67. *dst = le32_to_cpu(buffer[c]) & 0xffffff00;
  68. dst++;
  69. }
  70. buffer += s->data_block_quadlets;
  71. if (--remaining_frames == 0)
  72. dst = (void *)runtime->dma_area;
  73. }
  74. }
  75. static void write_pcm_silence(struct amdtp_stream *s,
  76. __le32 *buffer, unsigned int frames)
  77. {
  78. struct amdtp_ff *p = s->protocol;
  79. unsigned int i, c, channels = p->pcm_channels;
  80. for (i = 0; i < frames; ++i) {
  81. for (c = 0; c < channels; ++c)
  82. buffer[c] = cpu_to_le32(0x00000000);
  83. buffer += s->data_block_quadlets;
  84. }
  85. }
  86. int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
  87. struct snd_pcm_runtime *runtime)
  88. {
  89. int err;
  90. err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
  91. if (err < 0)
  92. return err;
  93. return amdtp_stream_add_pcm_hw_constraints(s, runtime);
  94. }
  95. static void process_it_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
  96. unsigned int count, struct snd_pcm_substream *pcm)
  97. {
  98. unsigned int pcm_frames = 0;
  99. int i;
  100. for (i = 0; i < count; ++i) {
  101. __le32 *buf = (__le32 *)desc->ctx_payload;
  102. unsigned int data_blocks = desc->data_blocks;
  103. if (pcm) {
  104. write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
  105. pcm_frames += data_blocks;
  106. } else {
  107. write_pcm_silence(s, buf, data_blocks);
  108. }
  109. desc = amdtp_stream_next_packet_desc(s, desc);
  110. }
  111. }
  112. static void process_ir_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
  113. unsigned int count, struct snd_pcm_substream *pcm)
  114. {
  115. unsigned int pcm_frames = 0;
  116. int i;
  117. for (i = 0; i < count; ++i) {
  118. __le32 *buf = (__le32 *)desc->ctx_payload;
  119. unsigned int data_blocks = desc->data_blocks;
  120. if (pcm) {
  121. read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
  122. pcm_frames += data_blocks;
  123. }
  124. desc = amdtp_stream_next_packet_desc(s, desc);
  125. }
  126. }
  127. int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
  128. enum amdtp_stream_direction dir)
  129. {
  130. amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
  131. if (dir == AMDTP_IN_STREAM)
  132. process_ctx_payloads = process_ir_ctx_payloads;
  133. else
  134. process_ctx_payloads = process_it_ctx_payloads;
  135. return amdtp_stream_init(s, unit, dir, CIP_BLOCKING | CIP_UNAWARE_SYT | CIP_NO_HEADER, 0,
  136. process_ctx_payloads, sizeof(struct amdtp_ff));
  137. }