compress.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2. //
  3. // This file is provided under a dual BSD/GPLv2 license. When using or
  4. // redistributing this file, you may do so under either license.
  5. //
  6. // Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
  7. //
  8. // Author: Cezary Rojewski <cezary.rojewski@intel.com>
  9. //
  10. #include <sound/soc.h>
  11. #include "compress.h"
  12. #include "ops.h"
  13. #include "probe.h"
  14. struct snd_compress_ops sof_probe_compressed_ops = {
  15. .copy = sof_probe_compr_copy,
  16. };
  17. EXPORT_SYMBOL(sof_probe_compressed_ops);
  18. int sof_probe_compr_open(struct snd_compr_stream *cstream,
  19. struct snd_soc_dai *dai)
  20. {
  21. struct snd_sof_dev *sdev =
  22. snd_soc_component_get_drvdata(dai->component);
  23. int ret;
  24. ret = snd_sof_probe_compr_assign(sdev, cstream, dai);
  25. if (ret < 0) {
  26. dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret);
  27. return ret;
  28. }
  29. sdev->extractor_stream_tag = ret;
  30. return 0;
  31. }
  32. EXPORT_SYMBOL(sof_probe_compr_open);
  33. int sof_probe_compr_free(struct snd_compr_stream *cstream,
  34. struct snd_soc_dai *dai)
  35. {
  36. struct snd_sof_dev *sdev =
  37. snd_soc_component_get_drvdata(dai->component);
  38. struct sof_probe_point_desc *desc;
  39. size_t num_desc;
  40. int i, ret;
  41. /* disconnect all probe points */
  42. ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc);
  43. if (ret < 0) {
  44. dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
  45. goto exit;
  46. }
  47. for (i = 0; i < num_desc; i++)
  48. sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1);
  49. kfree(desc);
  50. exit:
  51. ret = sof_ipc_probe_deinit(sdev);
  52. if (ret < 0)
  53. dev_err(dai->dev, "Failed to deinit probe: %d\n", ret);
  54. sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
  55. snd_compr_free_pages(cstream);
  56. return snd_sof_probe_compr_free(sdev, cstream, dai);
  57. }
  58. EXPORT_SYMBOL(sof_probe_compr_free);
  59. int sof_probe_compr_set_params(struct snd_compr_stream *cstream,
  60. struct snd_compr_params *params, struct snd_soc_dai *dai)
  61. {
  62. struct snd_compr_runtime *rtd = cstream->runtime;
  63. struct snd_sof_dev *sdev =
  64. snd_soc_component_get_drvdata(dai->component);
  65. int ret;
  66. cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG;
  67. cstream->dma_buffer.dev.dev = sdev->dev;
  68. ret = snd_compr_malloc_pages(cstream, rtd->buffer_size);
  69. if (ret < 0)
  70. return ret;
  71. ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai);
  72. if (ret < 0)
  73. return ret;
  74. ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag,
  75. rtd->dma_bytes);
  76. if (ret < 0) {
  77. dev_err(dai->dev, "Failed to init probe: %d\n", ret);
  78. return ret;
  79. }
  80. return 0;
  81. }
  82. EXPORT_SYMBOL(sof_probe_compr_set_params);
  83. int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd,
  84. struct snd_soc_dai *dai)
  85. {
  86. struct snd_sof_dev *sdev =
  87. snd_soc_component_get_drvdata(dai->component);
  88. return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai);
  89. }
  90. EXPORT_SYMBOL(sof_probe_compr_trigger);
  91. int sof_probe_compr_pointer(struct snd_compr_stream *cstream,
  92. struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
  93. {
  94. struct snd_sof_dev *sdev =
  95. snd_soc_component_get_drvdata(dai->component);
  96. return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai);
  97. }
  98. EXPORT_SYMBOL(sof_probe_compr_pointer);
  99. int sof_probe_compr_copy(struct snd_soc_component *component,
  100. struct snd_compr_stream *cstream,
  101. char __user *buf, size_t count)
  102. {
  103. struct snd_compr_runtime *rtd = cstream->runtime;
  104. unsigned int offset, n;
  105. void *ptr;
  106. int ret;
  107. if (count > rtd->buffer_size)
  108. count = rtd->buffer_size;
  109. div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset);
  110. ptr = rtd->dma_area + offset;
  111. n = rtd->buffer_size - offset;
  112. if (count < n) {
  113. ret = copy_to_user(buf, ptr, count);
  114. } else {
  115. ret = copy_to_user(buf, ptr, n);
  116. ret += copy_to_user(buf + n, rtd->dma_area, count - n);
  117. }
  118. if (ret)
  119. return count - ret;
  120. return count;
  121. }
  122. EXPORT_SYMBOL(sof_probe_compr_copy);