acp-probes.c 4.0 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) 2023 Advanced Micro Devices, Inc.
  7. //
  8. // Authors: V Sujith Kumar Reddy <Vsujithkumar.Reddy@amd.com>
  9. /*
  10. * Probe interface for generic AMD audio ACP DSP block
  11. */
  12. #include <linux/module.h>
  13. #include <sound/soc.h>
  14. #include "../sof-priv.h"
  15. #include "../sof-client-probes.h"
  16. #include "../sof-client.h"
  17. #include "../ops.h"
  18. #include "acp.h"
  19. #include "acp-dsp-offset.h"
  20. static int acp_probes_compr_startup(struct sof_client_dev *cdev,
  21. struct snd_compr_stream *cstream,
  22. struct snd_soc_dai *dai, u32 *stream_id)
  23. {
  24. struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
  25. struct acp_dsp_stream *stream;
  26. struct acp_dev_data *adata;
  27. adata = sdev->pdata->hw_pdata;
  28. stream = acp_dsp_stream_get(sdev, 0);
  29. if (!stream)
  30. return -ENODEV;
  31. stream->cstream = cstream;
  32. cstream->runtime->private_data = stream;
  33. adata->probe_stream = stream;
  34. *stream_id = stream->stream_tag;
  35. return 0;
  36. }
  37. static int acp_probes_compr_shutdown(struct sof_client_dev *cdev,
  38. struct snd_compr_stream *cstream,
  39. struct snd_soc_dai *dai)
  40. {
  41. struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
  42. struct acp_dsp_stream *stream = cstream->runtime->private_data;
  43. struct acp_dev_data *adata;
  44. int ret;
  45. ret = acp_dsp_stream_put(sdev, stream);
  46. if (ret < 0) {
  47. dev_err(sdev->dev, "Failed to release probe compress stream\n");
  48. return ret;
  49. }
  50. adata = sdev->pdata->hw_pdata;
  51. stream->cstream = NULL;
  52. cstream->runtime->private_data = NULL;
  53. adata->probe_stream = NULL;
  54. return 0;
  55. }
  56. static int acp_probes_compr_set_params(struct sof_client_dev *cdev,
  57. struct snd_compr_stream *cstream,
  58. struct snd_compr_params *params,
  59. struct snd_soc_dai *dai)
  60. {
  61. struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
  62. struct acp_dsp_stream *stream = cstream->runtime->private_data;
  63. unsigned int buf_offset, index;
  64. u32 size;
  65. int ret;
  66. stream->dmab = cstream->runtime->dma_buffer_p;
  67. stream->num_pages = PFN_UP(cstream->runtime->dma_bytes);
  68. size = cstream->runtime->buffer_size;
  69. ret = acp_dsp_stream_config(sdev, stream);
  70. if (ret < 0) {
  71. acp_dsp_stream_put(sdev, stream);
  72. return ret;
  73. }
  74. /* write buffer size of stream in scratch memory */
  75. buf_offset = sdev->debug_box.offset +
  76. offsetof(struct scratch_reg_conf, buf_size);
  77. index = stream->stream_tag - 1;
  78. buf_offset = buf_offset + index * 4;
  79. snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + buf_offset, size);
  80. return 0;
  81. }
  82. static int acp_probes_compr_trigger(struct sof_client_dev *cdev,
  83. struct snd_compr_stream *cstream,
  84. int cmd, struct snd_soc_dai *dai)
  85. {
  86. /* Nothing to do here, as it is a mandatory callback just defined */
  87. return 0;
  88. }
  89. static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
  90. struct snd_compr_stream *cstream,
  91. struct snd_compr_tstamp64 *tstamp,
  92. struct snd_soc_dai *dai)
  93. {
  94. struct acp_dsp_stream *stream = cstream->runtime->private_data;
  95. struct snd_soc_pcm_stream *pstream;
  96. pstream = &dai->driver->capture;
  97. tstamp->copied_total = stream->cstream_posn;
  98. tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
  99. return 0;
  100. }
  101. /* SOF client implementation */
  102. static const struct sof_probes_host_ops acp_probes_ops = {
  103. .startup = acp_probes_compr_startup,
  104. .shutdown = acp_probes_compr_shutdown,
  105. .set_params = acp_probes_compr_set_params,
  106. .trigger = acp_probes_compr_trigger,
  107. .pointer = acp_probes_compr_pointer,
  108. };
  109. int acp_probes_register(struct snd_sof_dev *sdev)
  110. {
  111. return sof_client_dev_register(sdev, "acp-probes", 0, &acp_probes_ops,
  112. sizeof(acp_probes_ops));
  113. }
  114. EXPORT_SYMBOL_NS(acp_probes_register, "SND_SOC_SOF_AMD_COMMON");
  115. void acp_probes_unregister(struct snd_sof_dev *sdev)
  116. {
  117. sof_client_dev_unregister(sdev, "acp-probes", 0);
  118. }
  119. EXPORT_SYMBOL_NS(acp_probes_unregister, "SND_SOC_SOF_AMD_COMMON");
  120. MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT");