2023-02-01 13:51:22

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 00/14] Add support for compress offload and gapless playback.

Add support for compress offload and gapless playback in audioreach
platform drivers.

Mohammad Rafi Shaik (14):
ALSA: compress: Update compress set params for gapless playback
ASoC: qcom: SC7280: audioreach: Add sc7280 hardware param fixup
callback
ASoC: q6dsp: audioreach: Add placeholder decoder for compress playback
ASoC: q6dsp: audioreach: Add support for compress offload commands
ASoC: q6dsp: audioreach: Add support to set compress params
ASoC: q6dsp: audioreach: Add support for sending real module ID to
ADSP
ASoC: q6dsp: q6apm-dai: Add async compress write support
ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks
ASoC: q6dsp: q6apm-dai: Add compress DAI and codec caps get callbacks
ASoC: q6dsp: q6apm-dai: Add trigger/pointer compress DAI callbacks
ASoC: q6dsp: q6apm-dai: Add compress set params and metadata DAI
callbacks
ASoC: q6dsp: q6apm-dai: Add mmap and copy compress DAI callbacks
ASoC: qdsp6: audioreach: Add MP3, AAC and FLAC compress format support
ASoC: q6dsp: audioreach: Add gapless feature support

sound/core/compress_offload.c | 12 +-
sound/soc/qcom/qdsp6/audioreach.c | 299 +++++++++++++++++--
sound/soc/qcom/qdsp6/audioreach.h | 56 ++++
sound/soc/qcom/qdsp6/q6apm-dai.c | 464 ++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/q6apm.c | 117 ++++++++
sound/soc/qcom/qdsp6/q6apm.h | 8 +
sound/soc/qcom/sc7280.c | 21 +-
7 files changed, 950 insertions(+), 27 deletions(-)

--
2.25.1



2023-02-01 13:51:54

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 01/14] ALSA: compress: Update compress set params for gapless playback

Update compress set params for supporting next track settings
during gapless playback.
Update the runtime state to setup state only if it's in open state.
Allow parameter change only when stream has been opened and running
state.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/core/compress_offload.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 243acad89fd3..9b951d76c120 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -589,7 +589,8 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
struct snd_compr_params *params;
int retval;

- if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
+ if (stream->runtime->state == SNDRV_PCM_STATE_OPEN ||
+ stream->runtime->state == SNDRV_PCM_STATE_RUNNING) {
/*
* we should allow parameter change only when stream has been
* opened not in other cases
@@ -612,10 +613,13 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
if (retval)
goto out;

- stream->metadata_set = false;
- stream->next_track = false;
+ if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
+ stream->metadata_set = false;
+ stream->next_track = false;
+
+ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+ }

- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
} else {
return -EPERM;
}
--
2.25.1


2023-02-01 13:52:01

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 02/14] ASoC: qcom: SC7280: audioreach: Add sc7280 hardware param fixup callback

Add support to set backend params such as sampling rate and
number of channels using backend params fixup callback.
Also remove hardware params constraints setting.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/sc7280.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c
index da7469a6a267..aaa95fe63d83 100644
--- a/sound/soc/qcom/sc7280.c
+++ b/sound/soc/qcom/sc7280.c
@@ -14,6 +14,7 @@
#include <sound/soc.h>
#include <sound/rt5682s.h>
#include <linux/soundwire/sdw.h>
+#include <sound/pcm_params.h>

#include "../codecs/rt5682.h"
#include "../codecs/rt5682s.h"
@@ -24,6 +25,7 @@
#define DEFAULT_MCLK_RATE 19200000
#define RT5682_PLL_FREQ (48000 * 512)
#define MI2S_BCLK_RATE 1536000
+#define DEFAULT_SAMPLE_RATE_48K 48000

struct sc7280_snd_data {
struct snd_soc_card card;
@@ -188,7 +190,6 @@ static int sc7280_init(struct snd_soc_pcm_runtime *rtd)
static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai;
const struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
@@ -196,8 +197,6 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
struct sdw_stream_runtime *sruntime;
int i;

- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 48000, 48000);

switch (cpu_dai->id) {
case LPASS_CDC_DMA_TX3:
@@ -358,6 +357,20 @@ static const struct snd_soc_dapm_widget sc7280_snd_widgets[] = {
SND_SOC_DAPM_MIC("Headset Mic", NULL),
};

+static int sc7280_snd_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+ rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
+ channels->min = channels->max = 2;
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+
+ return 0;
+}
+
static int sc7280_snd_platform_probe(struct platform_device *pdev)
{
struct snd_soc_card *card;
@@ -387,6 +400,8 @@ static int sc7280_snd_platform_probe(struct platform_device *pdev)
for_each_card_prelinks(card, i, link) {
link->init = sc7280_init;
link->ops = &sc7280_ops;
+ if (link->no_pcm == 1)
+ link->be_hw_params_fixup = sc7280_snd_be_hw_params_fixup;
}

return devm_snd_soc_register_card(dev, card);
--
2.25.1


2023-02-01 13:52:07

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 03/14] ASoC: q6dsp: audioreach: Add placeholder decoder for compress playback

Add placeholder decoder graph module for compressed playback feature.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 2 ++
sound/soc/qcom/qdsp6/audioreach.h | 39 +++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 1e0c918eb576..6d3d2a04ffe8 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -1120,6 +1120,8 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod
case MODULE_ID_PCM_DEC:
case MODULE_ID_PCM_ENC:
case MODULE_ID_PCM_CNV:
+ case MODULE_ID_PLACEHOLDER_DECODER:
+ case MODULE_ID_PLACEHOLDER_ENCODER:
rc = audioreach_pcm_set_media_format(graph, module, cfg);
break;
case MODULE_ID_I2S_SOURCE:
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 1d1d47d47d40..b78fd9bc8eb3 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -15,6 +15,8 @@ struct q6apm_graph;
#define MODULE_ID_PCM_CNV 0x07001003
#define MODULE_ID_PCM_ENC 0x07001004
#define MODULE_ID_PCM_DEC 0x07001005
+#define MODULE_ID_PLACEHOLDER_ENCODER 0x07001008
+#define MODULE_ID_PLACEHOLDER_DECODER 0x07001009
#define MODULE_ID_SAL 0x07001010
#define MODULE_ID_MFC 0x07001015
#define MODULE_ID_CODEC_DMA_SINK 0x07001023
@@ -22,6 +24,10 @@ struct q6apm_graph;
#define MODULE_ID_I2S_SINK 0x0700100A
#define MODULE_ID_I2S_SOURCE 0x0700100B
#define MODULE_ID_DATA_LOGGING 0x0700101A
+#define MODULE_ID_AAC_DEC 0x0700101F
+#define MODULE_ID_FLAC_DEC 0x0700102F
+#define MODULE_ID_MP3_DECODE 0x0700103B
+#define MODULE_ID_GAPLESS 0x0700104D

#define APM_CMD_GET_SPF_STATE 0x01001021
#define APM_CMD_RSP_GET_SPF_STATE 0x02001007
@@ -142,12 +148,15 @@ struct param_id_enc_bitrate_param {
} __packed;

#define DATA_FORMAT_FIXED_POINT 1
+#define DATA_FORMAT_GENERIC_COMPRESSED 5
+#define DATA_FORMAT_RAW_COMPRESSED 6
#define PCM_LSB_ALIGNED 1
#define PCM_MSB_ALIGNED 2
#define PCM_LITTLE_ENDIAN 1
#define PCM_BIT_ENDIAN 2

#define MEDIA_FMT_ID_PCM 0x09001000
+#define MEDIA_FMT_ID_MP3 0x09001009
#define PCM_CHANNEL_L 1
#define PCM_CHANNEL_R 2
#define SAMPLE_RATE_48K 48000
@@ -225,6 +234,28 @@ struct apm_media_format {
uint32_t payload_size;
} __packed;

+#define MEDIA_FMT_ID_FLAC 0x09001004
+
+struct payload_media_fmt_flac_t {
+ uint16_t num_channels;
+ uint16_t sample_size;
+ uint16_t min_blk_size;
+ uint16_t max_blk_size;
+ uint32_t sample_rate;
+ uint32_t min_frame_size;
+ uint32_t max_frame_size;
+} __packed;
+
+#define MEDIA_FMT_ID_AAC 0x09001001
+
+struct payload_media_fmt_aac_t {
+ uint16_t aac_fmt_flag;
+ uint16_t audio_obj_type;
+ uint16_t num_channels;
+ uint16_t total_size_of_PCE_bits;
+ uint32_t sample_rate;
+} __packed;
+
#define DATA_CMD_WR_SH_MEM_EP_EOS 0x04001002
#define WR_SH_MEM_EP_EOS_POLICY_LAST 1
#define WR_SH_MEM_EP_EOS_POLICY_EACH 2
@@ -598,6 +629,13 @@ struct param_id_vol_ctrl_master_gain {
} __packed;


+
+#define PARAM_ID_REAL_MODULE_ID 0x0800100B
+
+struct param_id_placeholder_real_module_id {
+ uint32_t real_module_id;
+} __packed;
+
/* Graph */
struct audioreach_connection {
/* Connections */
@@ -704,6 +742,7 @@ struct audioreach_module_config {
u16 active_channels_mask;
u32 sd_line_mask;
int fmt;
+ struct snd_codec codec;
u8 channel_map[AR_PCM_MAX_NUM_CHANNEL];
};

--
2.25.1


2023-02-01 13:52:11

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 04/14] ASoC: q6dsp: audioreach: Add support for compress offload commands

Add functions to send commands to the ADSP for supporting compressed
offload playback.
This includes functions to enable module ID, to remove trailing and
initial silence.
Also add functionality to send 32 bit parameter to ADSP.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 56 +++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/audioreach.h | 7 ++++
sound/soc/qcom/qdsp6/q6apm.c | 39 +++++++++++++++++++++
sound/soc/qcom/qdsp6/q6apm.h | 3 ++
4 files changed, 105 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 6d3d2a04ffe8..a11bab69a676 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -1258,3 +1258,59 @@ int audioreach_shared_memory_send_eos(struct q6apm_graph *graph)
return rc;
}
EXPORT_SYMBOL_GPL(audioreach_shared_memory_send_eos);
+
+int audioreach_send_u32_param(struct q6apm *apm, struct audioreach_module *module,
+ uint32_t param_id, uint32_t param_val)
+{
+ struct apm_module_param_data *param_data;
+ struct gpr_pkt *pkt;
+ uint32_t *param;
+ int rc, payload_size;
+ void *p;
+
+ payload_size = sizeof(uint32_t) + APM_MODULE_PARAM_DATA_SIZE;
+ p = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ if (IS_ERR(p))
+ return -ENOMEM;
+
+ pkt = p;
+ p = p + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
+
+ param_data = p;
+ param_data->module_instance_id = module->instance_id;
+ param_data->error_code = 0;
+ param_data->param_id = param_id;
+ param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
+
+ p = p + APM_MODULE_PARAM_DATA_SIZE;
+ param = p;
+ *param = param_val;
+ rc = q6apm_send_cmd_sync(apm, pkt, 0);
+
+ kfree(pkt);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(audioreach_send_u32_param);
+
+int audioreach_remove_trailing_silence(struct q6apm *apm, struct audioreach_module *module,
+ uint32_t trailing_samples)
+{
+ return audioreach_send_u32_param(apm, module, PARAM_ID_REMOVE_TRAILING_SILENCE,
+ trailing_samples);
+}
+EXPORT_SYMBOL_GPL(audioreach_remove_trailing_silence);
+
+int audioreach_remove_initial_silence(struct q6apm *apm, struct audioreach_module *module,
+ uint32_t initial_samples)
+{
+ return audioreach_send_u32_param(apm, module, PARAM_ID_REMOVE_INITIAL_SILENCE,
+ initial_samples);
+}
+EXPORT_SYMBOL_GPL(audioreach_remove_initial_silence);
+
+int audioreach_enable_module(struct q6apm *apm, struct audioreach_module *module, bool en)
+{
+ return audioreach_send_u32_param(apm, module, PARAM_ID_MODULE_ENABLE, en);
+}
+EXPORT_SYMBOL_GPL(audioreach_enable_module);
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index b78fd9bc8eb3..76dea97773cc 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -629,6 +629,8 @@ struct param_id_vol_ctrl_master_gain {
} __packed;


+#define PARAM_ID_REMOVE_INITIAL_SILENCE 0x0800114B
+#define PARAM_ID_REMOVE_TRAILING_SILENCE 0x0800115D

#define PARAM_ID_REAL_MODULE_ID 0x0800100B

@@ -779,4 +781,9 @@ int audioreach_set_media_format(struct q6apm_graph *graph,
int audioreach_shared_memory_send_eos(struct q6apm_graph *graph);
int audioreach_gain_set_vol_ctrl(struct q6apm *apm,
struct audioreach_module *module, int vol);
+int audioreach_enable_module(struct q6apm *apm, struct audioreach_module *module, bool en);
+int audioreach_remove_initial_silence(struct q6apm *apm, struct audioreach_module *module,
+ uint32_t initial_samples);
+int audioreach_remove_trailing_silence(struct q6apm *apm, struct audioreach_module *module,
+ uint32_t trailing_samples);
#endif /* __AUDIOREACH_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 8a7dfd27d3c5..78c1a7c13348 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -297,6 +297,45 @@ int q6apm_unmap_memory_regions(struct q6apm_graph *graph, unsigned int dir)
}
EXPORT_SYMBOL_GPL(q6apm_unmap_memory_regions);

+int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples)
+{
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct audioreach_module *module;
+
+ module = q6apm_find_module_by_mid(graph, MODULE_ID_PLACEHOLDER_DECODER);
+ if (!module)
+ return -ENODEV;
+
+ return audioreach_remove_initial_silence(apm, module, samples);
+}
+EXPORT_SYMBOL_GPL(q6apm_remove_initial_silence);
+
+int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples)
+{
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct audioreach_module *module;
+
+ module = q6apm_find_module_by_mid(graph, MODULE_ID_PLACEHOLDER_DECODER);
+ if (!module)
+ return -ENODEV;
+
+ return audioreach_remove_trailing_silence(apm, module, samples);
+}
+EXPORT_SYMBOL_GPL(q6apm_remove_trailing_silence);
+
+int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, bool en)
+{
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct audioreach_module *module;
+
+ module = q6apm_find_module_by_mid(graph, MODULE_ID_PLACEHOLDER_DECODER);
+ if (!module)
+ return -ENODEV;
+
+ return audioreach_enable_module(apm, module, en);
+}
+EXPORT_SYMBOL_GPL(q6apm_enable_compress_module);
+
int q6apm_graph_media_format_pcm(struct q6apm_graph *graph, struct audioreach_module_config *cfg)
{
struct audioreach_graph_info *info = graph->info;
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 7005be9b63e3..08b64f78c750 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -147,4 +147,7 @@ int q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph);

bool q6apm_is_adsp_ready(void);

+int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, bool en);
+int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
+int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
#endif /* __APM_GRAPH_ */
--
2.25.1


2023-02-01 13:52:21

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 05/14] ASoC: q6dsp: audioreach: Add support to set compress params

Add function for setting compress params to set the next track
parameters during gapless playback.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 51 +++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/audioreach.h | 1 +
sound/soc/qcom/qdsp6/q6apm-dai.c | 1 +
3 files changed, 53 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index a11bab69a676..a87df09d187f 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -1314,3 +1314,54 @@ int audioreach_enable_module(struct q6apm *apm, struct audioreach_module *module
return audioreach_send_u32_param(apm, module, PARAM_ID_MODULE_ENABLE, en);
}
EXPORT_SYMBOL_GPL(audioreach_enable_module);
+
+int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg)
+{
+ struct media_format *header;
+ struct gpr_pkt *pkt;
+ struct payload_media_fmt_pcm *cfg;
+ uint32_t num_channels = mcfg->num_channels;
+ int iid, payload_size, rc;
+ void *p;
+
+ payload_size = sizeof(struct apm_sh_module_media_fmt_cmd);
+
+ iid = q6apm_graph_get_rx_shmem_module_iid(graph);
+ pkt = audioreach_alloc_cmd_pkt(payload_size, DATA_CMD_WR_SH_MEM_EP_MEDIA_FORMAT,
+ 0, graph->port->id, iid);
+
+ if (IS_ERR(pkt))
+ return -ENOMEM;
+
+ p = (void *)pkt + GPR_HDR_SIZE;
+ header = p;
+
+ if (mcfg->fmt == SND_AUDIOCODEC_PCM) {
+ header->data_format = DATA_FORMAT_FIXED_POINT;
+ header->fmt_id = MEDIA_FMT_ID_PCM;
+ header->payload_size = sizeof(*cfg);
+
+ p = p + sizeof(*header);
+ cfg = p;
+ cfg->sample_rate = mcfg->sample_rate;
+ cfg->bit_width = mcfg->bit_width;
+ cfg->alignment = PCM_LSB_ALIGNED;
+ cfg->bits_per_sample = mcfg->bit_width;
+ cfg->q_factor = mcfg->bit_width - 1;
+ cfg->endianness = PCM_LITTLE_ENDIAN;
+ cfg->num_channels = mcfg->num_channels;
+
+ if (mcfg->num_channels == 1)
+ cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ else if (num_channels == 2) {
+ cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ cfg->channel_mapping[1] = PCM_CHANNEL_R;
+ }
+ }
+
+ rc = gpr_send_port_pkt(graph->port, pkt);
+ kfree(pkt);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(audioreach_compr_set_param);
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 76dea97773cc..4c4bdff45cf1 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -786,4 +786,5 @@ int audioreach_remove_initial_silence(struct q6apm *apm, struct audioreach_modul
uint32_t initial_samples);
int audioreach_remove_trailing_silence(struct q6apm *apm, struct audioreach_module *module,
uint32_t trailing_samples);
+int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg);
#endif /* __AUDIOREACH_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index ee59ef36b85a..8f5d744b3365 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -146,6 +146,7 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
cfg.sample_rate = runtime->rate;
cfg.num_channels = runtime->channels;
cfg.bit_width = prtd->bits_per_sample;
+ cfg.fmt = SND_AUDIOCODEC_PCM;

if (prtd->state) {
/* clear the previous setup if any */
--
2.25.1


2023-02-01 13:52:33

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 06/14] ASoC: q6dsp: audioreach: Add support for sending real module ID to ADSP

Add support for sending the placeholder real module ID to ADSP
for enabling compressed playback. 

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 6 ++++++
sound/soc/qcom/qdsp6/audioreach.h | 1 +
sound/soc/qcom/qdsp6/q6apm.c | 29 +++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/q6apm.h | 1 +
4 files changed, 37 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index a87df09d187f..e84ccbacc0f7 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -1315,6 +1315,12 @@ int audioreach_enable_module(struct q6apm *apm, struct audioreach_module *module
}
EXPORT_SYMBOL_GPL(audioreach_enable_module);

+int audioreach_set_real_module_id(struct q6apm *apm, struct audioreach_module *module, uint32_t id)
+{
+ return audioreach_send_u32_param(apm, module, PARAM_ID_REAL_MODULE_ID, id);
+}
+EXPORT_SYMBOL_GPL(audioreach_set_real_module_id);
+
int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg)
{
struct media_format *header;
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 4c4bdff45cf1..0faaf75115fd 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -787,4 +787,5 @@ int audioreach_remove_initial_silence(struct q6apm *apm, struct audioreach_modul
int audioreach_remove_trailing_silence(struct q6apm *apm, struct audioreach_module *module,
uint32_t trailing_samples);
int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg);
+int audioreach_set_real_module_id(struct q6apm *apm, struct audioreach_module *module, uint32_t id);
#endif /* __AUDIOREACH_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 78c1a7c13348..811d86bdc092 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -336,6 +336,35 @@ int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph,
}
EXPORT_SYMBOL_GPL(q6apm_enable_compress_module);

+int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph,
+ uint32_t codec_id)
+{
+ struct q6apm *apm = dev_get_drvdata(dev->parent);
+ struct audioreach_module *module;
+ uint32_t module_id;
+
+ module = q6apm_find_module_by_mid(graph, MODULE_ID_PLACEHOLDER_DECODER);
+ if (!module)
+ return -ENODEV;
+
+ switch (codec_id) {
+ case SND_AUDIOCODEC_MP3:
+ module_id = MODULE_ID_MP3_DECODE;
+ break;
+ case SND_AUDIOCODEC_AAC:
+ module_id = MODULE_ID_AAC_DEC;
+ break;
+ case SND_AUDIOCODEC_FLAC:
+ module_id = MODULE_ID_FLAC_DEC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return audioreach_set_real_module_id(apm, module, module_id);
+}
+EXPORT_SYMBOL_GPL(q6apm_set_real_module_id);
+
int q6apm_graph_media_format_pcm(struct q6apm_graph *graph, struct audioreach_module_config *cfg)
{
struct audioreach_graph_info *info = graph->info;
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 08b64f78c750..87d67faf5f1a 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -150,4 +150,5 @@ bool q6apm_is_adsp_ready(void);
int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, bool en);
int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
+int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id);
#endif /* __APM_GRAPH_ */
--
2.25.1


2023-02-01 13:52:37

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 07/14] ASoC: q6dsp: q6apm-dai: Add async compress write support

Add async compress write API to send the compressed audio data packet
to ADSP. 

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 38 +++++++++++++++++++++++++
sound/soc/qcom/qdsp6/audioreach.h | 2 ++
sound/soc/qcom/qdsp6/q6apm-dai.c | 7 +++++
sound/soc/qcom/qdsp6/q6apm.c | 46 +++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/q6apm.h | 3 ++
5 files changed, 96 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index e84ccbacc0f7..7c45c36e9156 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -240,6 +240,44 @@ void *audioreach_alloc_pkt(int payload_size, uint32_t opcode, uint32_t token,
}
EXPORT_SYMBOL_GPL(audioreach_alloc_pkt);

+static void __audioreach_update_pkt(struct gpr_pkt *pkt, int payload_size, uint32_t opcode,
+ uint32_t token, uint32_t src_port, uint32_t dest_port,
+ bool has_cmd_hdr)
+{
+ int pkt_size = GPR_HDR_SIZE + payload_size;
+ void *p;
+
+ if (has_cmd_hdr)
+ pkt_size += APM_CMD_HDR_SIZE;
+
+ p = pkt;
+ pkt->hdr.version = GPR_PKT_VER;
+ pkt->hdr.hdr_size = GPR_PKT_HEADER_WORD_SIZE;
+ pkt->hdr.pkt_size = pkt_size;
+ pkt->hdr.dest_port = dest_port;
+ pkt->hdr.src_port = src_port;
+
+ pkt->hdr.dest_domain = GPR_DOMAIN_ID_ADSP;
+ pkt->hdr.src_domain = GPR_DOMAIN_ID_APPS;
+ pkt->hdr.token = token;
+ pkt->hdr.opcode = opcode;
+
+ if (has_cmd_hdr) {
+ struct apm_cmd_header *cmd_header;
+
+ p = p + GPR_HDR_SIZE;
+ cmd_header = p;
+ cmd_header->payload_size = payload_size;
+ }
+}
+
+void audioreach_update_pkt(struct gpr_pkt *pkt, int payload_size, uint32_t opcode, uint32_t token,
+ uint32_t src_port, uint32_t dest_port)
+{
+ __audioreach_update_pkt(pkt, payload_size, opcode, token, src_port, dest_port, false);
+}
+EXPORT_SYMBOL_GPL(audioreach_update_pkt);
+
void *audioreach_alloc_apm_pkt(int pkt_size, uint32_t opcode, uint32_t token, uint32_t src_port)
{
return __audioreach_alloc_pkt(pkt_size, opcode, token, src_port, APM_MODULE_INSTANCE_ID,
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 0faaf75115fd..044994ca4811 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -788,4 +788,6 @@ int audioreach_remove_trailing_silence(struct q6apm *apm, struct audioreach_modu
uint32_t trailing_samples);
int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg);
int audioreach_set_real_module_id(struct q6apm *apm, struct audioreach_module *module, uint32_t id);
+void audioreach_update_pkt(struct gpr_pkt *pkt, int payload_size, uint32_t opcode,
+ uint32_t token, uint32_t src_port, uint32_t dest_port);
#endif /* __AUDIOREACH_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 8f5d744b3365..e621e31294a1 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -38,8 +38,10 @@ enum stream_state {
struct q6apm_dai_rtd {
struct snd_pcm_substream *substream;
struct snd_compr_stream *cstream;
+ struct snd_codec codec;
struct snd_compr_params codec_param;
struct snd_dma_buffer dma_buffer;
+ spinlock_t lock;
phys_addr_t phys;
unsigned int pcm_size;
unsigned int pcm_count;
@@ -51,8 +53,13 @@ struct q6apm_dai_rtd {
uint16_t bits_per_sample;
uint16_t source; /* Encoding source bit mask */
uint16_t session_id;
+ bool next_track;
enum stream_state state;
struct q6apm_graph *graph;
+ uint32_t initial_samples_drop;
+ uint32_t trailing_samples_drop;
+ uint32_t next_track_stream_id;
+ bool notify_on_drain;
};

struct q6apm_dai_data {
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 811d86bdc092..1a6c7108bae0 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -25,6 +25,8 @@ struct apm_graph_mgmt_cmd {
uint32_t sub_graph_id_list[];
} __packed;

+struct gpr_pkt *pkt;
+
#define APM_GRAPH_MGMT_PSIZE(p, n) ALIGN(struct_size(p, sub_graph_id_list, n), 8)

struct q6apm *g_apm;
@@ -457,6 +459,45 @@ int q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
}
EXPORT_SYMBOL_GPL(q6apm_write_async);

+int q6apm_write_async_compr(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
+ uint32_t lsw_ts, uint32_t wflags)
+{
+ struct apm_data_cmd_wr_sh_mem_ep_data_buffer_v2 *write_buffer;
+ struct audio_buffer *ab;
+
+ int rc, iid;
+
+ iid = q6apm_graph_get_rx_shmem_module_iid(graph);
+
+ audioreach_update_pkt(pkt, sizeof(*write_buffer), DATA_CMD_WR_SH_MEM_EP_DATA_BUFFER_V2,
+ graph->rx_data.dsp_buf | (len << APM_WRITE_TOKEN_LEN_SHIFT),
+ graph->port->id, iid);
+
+ write_buffer = (void *)pkt + GPR_HDR_SIZE;
+
+ ab = &graph->rx_data.buf[graph->rx_data.dsp_buf];
+
+ write_buffer->buf_addr_lsw = lower_32_bits(ab->phys);
+ write_buffer->buf_addr_msw = upper_32_bits(ab->phys);
+ write_buffer->buf_size = len;
+ write_buffer->timestamp_lsw = lsw_ts;
+ write_buffer->timestamp_msw = msw_ts;
+ write_buffer->mem_map_handle = graph->rx_data.mem_map_handle;
+ write_buffer->flags = wflags;
+
+ graph->rx_data.dsp_buf++;
+
+ if (graph->rx_data.dsp_buf >= graph->rx_data.num_periods)
+ graph->rx_data.dsp_buf = 0;
+
+ rc = gpr_send_port_pkt(graph->port, pkt);
+
+ memset(pkt, 0, sizeof(write_buffer) + GPR_HDR_SIZE);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(q6apm_write_async_compr);
+
int q6apm_read(struct q6apm_graph *graph)
{
struct data_cmd_rd_sh_mem_ep_data_buffer_v2 *read_buffer;
@@ -724,6 +765,11 @@ static int apm_probe(gpr_device_t *gdev)

dev_set_drvdata(dev, apm);

+ pkt = devm_kzalloc(dev, sizeof(struct apm_data_cmd_wr_sh_mem_ep_data_buffer_v2) +
+ GPR_HDR_SIZE, GFP_KERNEL);
+ if (!pkt)
+ return -ENOMEM;
+
mutex_init(&apm->lock);
apm->dev = dev;
apm->gdev = gdev;
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 87d67faf5f1a..630c2bca0f06 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -45,6 +45,7 @@
#define APM_WRITE_TOKEN_LEN_SHIFT 16

#define APM_MAX_SESSIONS 8
+#define APM_LAST_BUFFER_FLAG BIT(30)

struct q6apm {
struct device *dev;
@@ -128,6 +129,8 @@ int q6apm_send_eos_nowait(struct q6apm_graph *graph);
int q6apm_read(struct q6apm_graph *graph);
int q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
uint32_t lsw_ts, uint32_t wflags);
+int q6apm_write_async_compr(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
+ uint32_t lsw_ts, uint32_t wflags);

/* Memory Map related */
int q6apm_map_memory_regions(struct q6apm_graph *graph,
--
2.25.1


2023-02-01 13:52:42

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 08/14] ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks

Add q6apm open and free compress DAI callbacks to support compress
offload playback.
Include compress event handler callback also.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 135 +++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index e621e31294a1..fd134c268189 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -27,6 +27,8 @@
#define CAPTURE_MIN_PERIOD_SIZE 320
#define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
#define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
+#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
+#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
#define SID_MASK_DEFAULT 0xF

enum stream_state {
@@ -130,6 +132,69 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
}
}

+void event_handler_compr(uint32_t opcode, uint32_t token,
+ uint32_t *payload, void *priv)
+{
+ struct q6apm_dai_rtd *prtd = priv;
+ struct snd_compr_stream *substream = prtd->cstream;
+ unsigned long flags;
+ uint32_t wflags = 0;
+ uint64_t avail;
+ uint32_t bytes_written, bytes_to_write;
+ bool is_last_buffer = false;
+
+ switch (opcode) {
+ case APM_CLIENT_EVENT_CMD_EOS_DONE:
+ spin_lock_irqsave(&prtd->lock, flags);
+ if (prtd->notify_on_drain) {
+ snd_compr_drain_notify(prtd->cstream);
+ prtd->notify_on_drain = false;
+ } else {
+ prtd->state = Q6APM_STREAM_STOPPED;
+ }
+ spin_unlock_irqrestore(&prtd->lock, flags);
+ break;
+ case APM_CLIENT_EVENT_DATA_WRITE_DONE:
+ spin_lock_irqsave(&prtd->lock, flags);
+ bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT;
+ prtd->copied_total += bytes_written;
+ snd_compr_fragment_elapsed(substream);
+
+ if (prtd->state != Q6APM_STREAM_RUNNING) {
+ spin_unlock_irqrestore(&prtd->lock, flags);
+ break;
+ }
+
+ avail = prtd->bytes_received - prtd->bytes_sent;
+
+ if (avail > prtd->pcm_count) {
+ bytes_to_write = prtd->pcm_count;
+ } else {
+ if (substream->partial_drain || prtd->notify_on_drain)
+ is_last_buffer = true;
+ bytes_to_write = avail;
+ }
+
+ if (bytes_to_write) {
+ if (substream->partial_drain && is_last_buffer)
+ wflags |= APM_LAST_BUFFER_FLAG;
+
+ q6apm_write_async_compr(prtd->graph,
+ bytes_to_write, 0, 0, wflags);
+
+ prtd->bytes_sent += bytes_to_write;
+
+ if (prtd->notify_on_drain && is_last_buffer)
+ audioreach_shared_memory_send_eos(prtd->graph);
+ }
+
+ spin_unlock_irqrestore(&prtd->lock, flags);
+ break;
+ default:
+ break;
+ }
+}
+
static int q6apm_dai_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
@@ -378,6 +443,75 @@ static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc
return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size);
}

+static int q6apm_dai_compr_open(struct snd_soc_component *component,
+ struct snd_compr_stream *stream)
+{
+ struct snd_soc_pcm_runtime *rtd = stream->private_data;
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd;
+ struct q6apm_dai_data *pdata;
+ struct device *dev = component->dev;
+ int ret, size;
+ int graph_id;
+
+ graph_id = cpu_dai->driver->id;
+ pdata = snd_soc_component_get_drvdata(component);
+ if (!pdata)
+ return -EINVAL;
+
+ prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ prtd->cstream = stream;
+ prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id);
+ if (IS_ERR(prtd->graph)) {
+ ret = PTR_ERR(prtd->graph);
+ kfree(prtd);
+ return ret;
+ }
+
+ runtime->private_data = prtd;
+ runtime->dma_bytes = BUFFER_BYTES_MAX;
+ size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
+ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &prtd->dma_buffer);
+ if (ret)
+ return ret;
+
+ if (pdata->sid < 0)
+ prtd->phys = prtd->dma_buffer.addr;
+ else
+ prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32);
+
+ snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer);
+ spin_lock_init(&prtd->lock);
+
+ q6apm_enable_compress_module(dev, prtd->graph, true);
+ return 0;
+}
+
+static int q6apm_dai_compr_free(struct snd_soc_component *component,
+ struct snd_compr_stream *stream)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+
+ q6apm_graph_stop(prtd->graph);
+ q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK);
+ q6apm_graph_close(prtd->graph);
+ snd_dma_free_pages(&prtd->dma_buffer);
+ prtd->graph = NULL;
+ kfree(prtd);
+ runtime->private_data = NULL;
+
+ return 0;
+}
+static const struct snd_compress_ops q6apm_dai_compress_ops = {
+ .open = q6apm_dai_compr_open,
+ .free = q6apm_dai_compr_free,
+};
+
static const struct snd_soc_component_driver q6apm_fe_dai_component = {
.name = DRV_NAME,
.open = q6apm_dai_open,
@@ -387,6 +521,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
.hw_params = q6apm_dai_hw_params,
.pointer = q6apm_dai_pointer,
.trigger = q6apm_dai_trigger,
+ .compress_ops = &q6apm_dai_compress_ops,
};

static int q6apm_dai_probe(struct platform_device *pdev)
--
2.25.1


2023-02-01 13:53:05

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 09/14] ASoC: q6dsp: q6apm-dai: Add compress DAI and codec caps get callbacks

Add q6apm get compress DAI capabilities and codec capabilities callbacks
to support compress offload playback.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 51 ++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index fd134c268189..54e1aca61e4c 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -29,8 +29,25 @@
#define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
+#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024)
+#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4)
#define SID_MASK_DEFAULT 0xF

+static const struct snd_compr_codec_caps q6apm_compr_caps = {
+ .num_descriptors = 1,
+ .descriptor[0].max_ch = 2,
+ .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000, 88200,
+ 96000, 176400, 192000 },
+ .descriptor[0].num_sample_rates = 13,
+ .descriptor[0].bit_rate[0] = 320,
+ .descriptor[0].bit_rate[1] = 128,
+ .descriptor[0].num_bitrates = 2,
+ .descriptor[0].profiles = 0,
+ .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO,
+ .descriptor[0].formats = 0,
+};
+
enum stream_state {
Q6APM_STREAM_IDLE = 0,
Q6APM_STREAM_STOPPED,
@@ -507,9 +524,43 @@ static int q6apm_dai_compr_free(struct snd_soc_component *component,

return 0;
}
+
+static int q6apm_dai_compr_get_caps(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_compr_caps *caps)
+{
+ caps->direction = SND_COMPRESS_PLAYBACK;
+ caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE;
+ caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
+ caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
+ caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
+ caps->num_codecs = 3;
+ caps->codecs[0] = SND_AUDIOCODEC_MP3;
+ caps->codecs[1] = SND_AUDIOCODEC_AAC;
+ caps->codecs[2] = SND_AUDIOCODEC_FLAC;
+
+ return 0;
+}
+
+static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_compr_codec_caps *codec)
+{
+ switch (codec->codec) {
+ case SND_AUDIOCODEC_MP3:
+ *codec = q6apm_compr_caps;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
static const struct snd_compress_ops q6apm_dai_compress_ops = {
.open = q6apm_dai_compr_open,
.free = q6apm_dai_compr_free,
+ .get_caps = q6apm_dai_compr_get_caps,
+ .get_codec_caps = q6apm_dai_compr_get_codec_caps,
};

static const struct snd_soc_component_driver q6apm_fe_dai_component = {
--
2.25.1


2023-02-01 13:53:19

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 10/14] ASoC: q6dsp: q6apm-dai: Add trigger/pointer compress DAI callbacks

Add q6apm trigger and pointer compress DAI callbacks to support
compress offload playback.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 68 ++++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/q6apm.h | 1 +
2 files changed, 69 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 54e1aca61e4c..f43b60742e2f 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -556,11 +556,79 @@ static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component,

return 0;
}
+
+static int q6apm_dai_compr_pointer(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_compr_tstamp *tstamp)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&prtd->lock, flags);
+ tstamp->copied_total = prtd->copied_total;
+ tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ return 0;
+}
+
+int q6apm_dai_compr_trigger(struct snd_soc_component *component,
+ struct snd_compr_stream *stream, int cmd)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = q6apm_write_async_compr(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+ case SND_COMPR_TRIGGER_NEXT_TRACK:
+ prtd->next_track = true;
+ prtd->next_track_stream_id = (prtd->graph->id == 1 ? 2 : 1);
+ break;
+ case SND_COMPR_TRIGGER_DRAIN:
+ case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
+ prtd->notify_on_drain = true;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream,
+ size_t count)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&prtd->lock, flags);
+ prtd->bytes_received += count;
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ return count;
+}
+
static const struct snd_compress_ops q6apm_dai_compress_ops = {
.open = q6apm_dai_compr_open,
.free = q6apm_dai_compr_free,
.get_caps = q6apm_dai_compr_get_caps,
.get_codec_caps = q6apm_dai_compr_get_codec_caps,
+ .pointer = q6apm_dai_compr_pointer,
+ .trigger = q6apm_dai_compr_trigger,
+ .ack = q6apm_dai_compr_ack,
};

static const struct snd_soc_component_driver q6apm_fe_dai_component = {
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index 630c2bca0f06..e0247e6e4fd2 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -46,6 +46,7 @@

#define APM_MAX_SESSIONS 8
#define APM_LAST_BUFFER_FLAG BIT(30)
+#define NO_TIMESTAMP 0xFF00

struct q6apm {
struct device *dev;
--
2.25.1


2023-02-01 13:53:23

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 11/14] ASoC: q6dsp: q6apm-dai: Add compress set params and metadata DAI callbacks

Add q6apm compress DAI callbacks for setting params and metadata to support
compress offload playback.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 121 +++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index f43b60742e2f..8ee14822362b 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -621,6 +621,125 @@ int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_st
return count;
}

+static int __q6apm_dai_compr_set_codec_params(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_codec *codec,
+ int stream_id)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ struct device *dev = component->dev;
+ union snd_codec_options *codec_options;
+
+ codec_options = &(prtd->codec.options);
+
+ memcpy(&prtd->codec, codec, sizeof(*codec));
+ q6apm_set_real_module_id(dev, prtd->graph, codec->id);
+
+ return 0;
+}
+
+static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_compr_params *params)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ struct q6apm_dai_data *pdata;
+ struct audioreach_module_config cfg;
+ struct snd_codec *codec = &params->codec;
+ int dir = stream->direction;
+ int ret;
+
+ pdata = snd_soc_component_get_drvdata(component);
+ if (!pdata)
+ return -EINVAL;
+
+ prtd->periods = runtime->fragments;
+ prtd->pcm_count = runtime->fragment_size;
+ prtd->pcm_size = runtime->fragments * runtime->fragment_size;
+ prtd->bits_per_sample = 16;
+
+ prtd->pos = 0;
+
+ if (prtd->next_track != true) {
+ ret = __q6apm_dai_compr_set_codec_params(component, stream,
+ &params->codec, 0);
+ if (ret)
+ return ret;
+
+ cfg.direction = dir;
+ cfg.sample_rate = codec->sample_rate;
+ cfg.num_channels = 2;
+ cfg.bit_width = prtd->bits_per_sample;
+ cfg.fmt = codec->id;
+ memcpy(&cfg.codec, codec, sizeof(*codec));
+
+ ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
+ if (ret < 0)
+ return ret;
+
+ ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg);
+ if (ret)
+ return ret;
+
+ ret = q6apm_map_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK,
+ prtd->phys, (prtd->pcm_size / prtd->periods),
+ prtd->periods);
+ if (ret < 0)
+ return -ENOMEM;
+
+ ret = q6apm_graph_prepare(prtd->graph);
+ if (ret)
+ return ret;
+ ret = q6apm_graph_start(prtd->graph);
+ if (ret)
+ return ret;
+
+ } else {
+ cfg.direction = dir;
+ cfg.sample_rate = codec->sample_rate;
+ cfg.num_channels = 2;
+ cfg.bit_width = prtd->bits_per_sample;
+ cfg.fmt = codec->id;
+ memcpy(&cfg.codec, codec, sizeof(*codec));
+
+ ret = audioreach_compr_set_param(prtd->graph, &cfg);
+ if (ret < 0)
+ return ret;
+ }
+ prtd->state = Q6APM_STREAM_RUNNING;
+
+ return 0;
+}
+
+static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct snd_compr_metadata *metadata)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ int ret = 0;
+
+ switch (metadata->key) {
+ case SNDRV_COMPRESS_ENCODER_PADDING:
+ prtd->trailing_samples_drop = metadata->value[0];
+ q6apm_remove_trailing_silence(component->dev, prtd->graph,
+ prtd->trailing_samples_drop);
+ break;
+ case SNDRV_COMPRESS_ENCODER_DELAY:
+ prtd->initial_samples_drop = metadata->value[0];
+ q6apm_remove_initial_silence(component->dev, prtd->graph,
+ prtd->initial_samples_drop);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static const struct snd_compress_ops q6apm_dai_compress_ops = {
.open = q6apm_dai_compr_open,
.free = q6apm_dai_compr_free,
@@ -629,6 +748,8 @@ static const struct snd_compress_ops q6apm_dai_compress_ops = {
.pointer = q6apm_dai_compr_pointer,
.trigger = q6apm_dai_compr_trigger,
.ack = q6apm_dai_compr_ack,
+ .set_params = q6apm_dai_compr_set_params,
+ .set_metadata = q6apm_dai_compr_set_metadata,
};

static const struct snd_soc_component_driver q6apm_fe_dai_component = {
--
2.25.1


2023-02-01 13:53:27

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 12/14] ASoC: q6dsp: q6apm-dai: Add mmap and copy compress DAI callbacks

Add q6apm mmap and copy compress DAI callbacks to support compress
offload playback.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 81 ++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 8ee14822362b..2c0aa2f4caaf 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -740,6 +740,85 @@ static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
return ret;
}

+static int q6apm_dai_compr_mmap(struct snd_soc_component *component,
+ struct snd_compr_stream *stream,
+ struct vm_area_struct *vma)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ struct device *dev = component->dev;
+
+ return dma_mmap_coherent(dev, vma, prtd->dma_buffer.area, prtd->dma_buffer.addr,
+ prtd->dma_buffer.bytes);
+}
+
+static int q6apm_compr_copy(struct snd_soc_component *component,
+ struct snd_compr_stream *stream, char __user *buf,
+ size_t count)
+{
+ struct snd_compr_runtime *runtime = stream->runtime;
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
+ void *dstn;
+ unsigned long flags;
+ size_t copy;
+ u32 wflags = 0;
+ u32 app_pointer;
+ u32 bytes_received;
+ uint32_t bytes_to_write;
+ int avail, bytes_in_flight = 0;
+
+ bytes_received = prtd->bytes_received;
+
+ /**
+ * Make sure that next track data pointer is aligned at 32 bit boundary
+ * This is a Mandatory requirement from DSP data buffers alignment
+ */
+ if (prtd->next_track)
+ bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
+
+ app_pointer = bytes_received/prtd->pcm_size;
+ app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
+ dstn = prtd->dma_buffer.area + app_pointer;
+
+ if (count < prtd->pcm_size - app_pointer) {
+ if (copy_from_user(dstn, buf, count))
+ return -EFAULT;
+ } else {
+ copy = prtd->pcm_size - app_pointer;
+ if (copy_from_user(dstn, buf, copy))
+ return -EFAULT;
+ if (copy_from_user(prtd->dma_buffer.area, buf + copy, count - copy))
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&prtd->lock, flags);
+ bytes_in_flight = prtd->bytes_received - prtd->copied_total;
+
+ if (prtd->next_track) {
+ prtd->next_track = false;
+ prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count);
+ prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count);
+ }
+
+ prtd->bytes_received = bytes_received + count;
+
+ /* Kick off the data to dsp if its starving!! */
+ if (prtd->state == Q6APM_STREAM_RUNNING && (bytes_in_flight == 0)) {
+ bytes_to_write = prtd->pcm_count;
+ avail = prtd->bytes_received - prtd->bytes_sent;
+
+ if (avail < prtd->pcm_count)
+ bytes_to_write = avail;
+
+ q6apm_write_async_compr(prtd->graph, bytes_to_write, 0, 0, wflags);
+ prtd->bytes_sent += bytes_to_write;
+ }
+
+ spin_unlock_irqrestore(&prtd->lock, flags);
+
+ return count;
+}
+
static const struct snd_compress_ops q6apm_dai_compress_ops = {
.open = q6apm_dai_compr_open,
.free = q6apm_dai_compr_free,
@@ -750,6 +829,8 @@ static const struct snd_compress_ops q6apm_dai_compress_ops = {
.ack = q6apm_dai_compr_ack,
.set_params = q6apm_dai_compr_set_params,
.set_metadata = q6apm_dai_compr_set_metadata,
+ .mmap = q6apm_dai_compr_mmap,
+ .copy = q6apm_compr_copy,
};

static const struct snd_soc_component_driver q6apm_fe_dai_component = {
--
2.25.1


2023-02-01 13:53:32

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 13/14] ASoC: qdsp6: audioreach: Add MP3, AAC and FLAC compress format support

Add support for handling compressed formats such as MP3, AAC and FLAC.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 106 ++++++++++++++++++++++++------
1 file changed, 86 insertions(+), 20 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 7c45c36e9156..250ed828c7d3 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -852,6 +852,68 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
return rc;
}

+static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
+ void *p, struct audioreach_module_config *mcfg)
+{
+ struct payload_media_fmt_aac_t *aac_cfg;
+ struct payload_media_fmt_pcm *mp3_cfg;
+ struct payload_media_fmt_flac_t *flac_cfg;
+ int ret = 0;
+
+ switch (mcfg->fmt) {
+ case SND_AUDIOCODEC_MP3:
+ media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
+ media_fmt_hdr->fmt_id = MEDIA_FMT_ID_MP3;
+ media_fmt_hdr->payload_size = 0;
+ p = p + sizeof(*media_fmt_hdr);
+ mp3_cfg = p;
+ mp3_cfg->sample_rate = mcfg->sample_rate;
+ mp3_cfg->bit_width = mcfg->bit_width;
+ mp3_cfg->alignment = PCM_LSB_ALIGNED;
+ mp3_cfg->bits_per_sample = mcfg->bit_width;
+ mp3_cfg->q_factor = mcfg->bit_width - 1;
+ mp3_cfg->endianness = PCM_LITTLE_ENDIAN;
+ mp3_cfg->num_channels = mcfg->num_channels;
+
+ if (mcfg->num_channels == 1) {
+ mp3_cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ } else if (mcfg->num_channels == 2) {
+ mp3_cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ mp3_cfg->channel_mapping[1] = PCM_CHANNEL_R;
+ }
+ break;
+ case SND_AUDIOCODEC_AAC:
+ media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
+ media_fmt_hdr->fmt_id = MEDIA_FMT_ID_AAC;
+ media_fmt_hdr->payload_size = sizeof(struct payload_media_fmt_aac_t);
+ p = p + sizeof(*media_fmt_hdr);
+ aac_cfg = p;
+ aac_cfg->aac_fmt_flag = 0;
+ aac_cfg->audio_obj_type = 5;
+ aac_cfg->num_channels = mcfg->num_channels;
+ aac_cfg->total_size_of_PCE_bits = 0;
+ aac_cfg->sample_rate = mcfg->sample_rate;
+ break;
+ case SND_AUDIOCODEC_FLAC:
+ media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
+ media_fmt_hdr->fmt_id = MEDIA_FMT_ID_FLAC;
+ media_fmt_hdr->payload_size = sizeof(struct payload_media_fmt_flac_t);
+ p = p + sizeof(*media_fmt_hdr);
+ flac_cfg = p;
+ flac_cfg->sample_size = mcfg->codec.options.flac_d.sample_size;
+ flac_cfg->num_channels = mcfg->num_channels;
+ flac_cfg->min_blk_size = mcfg->codec.options.flac_d.min_blk_size;
+ flac_cfg->max_blk_size = mcfg->codec.options.flac_d.max_blk_size;
+ flac_cfg->sample_rate = mcfg->sample_rate;
+ flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;
+ flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ret;
+}
+
static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
struct audioreach_module *module,
struct audioreach_module_config *cfg)
@@ -1055,26 +1117,29 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
p = p + APM_MODULE_PARAM_DATA_SIZE;

header = p;
- header->data_format = DATA_FORMAT_FIXED_POINT;
- header->fmt_id = MEDIA_FMT_ID_PCM;
- header->payload_size = payload_size - sizeof(*header);
+ if (mcfg->fmt == SND_AUDIOCODEC_PCM) {
+ header->data_format = DATA_FORMAT_FIXED_POINT;
+ header->fmt_id = MEDIA_FMT_ID_PCM;
+ header->payload_size = payload_size - sizeof(*header);

- p = p + sizeof(*header);
- cfg = p;
- cfg->sample_rate = mcfg->sample_rate;
- cfg->bit_width = mcfg->bit_width;
- cfg->alignment = PCM_LSB_ALIGNED;
- cfg->bits_per_sample = mcfg->bit_width;
- cfg->q_factor = mcfg->bit_width - 1;
- cfg->endianness = PCM_LITTLE_ENDIAN;
- cfg->num_channels = mcfg->num_channels;
-
- if (mcfg->num_channels == 1) {
- cfg->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (num_channels == 2) {
- cfg->channel_mapping[0] = PCM_CHANNEL_L;
- cfg->channel_mapping[1] = PCM_CHANNEL_R;
- }
+ p = p + sizeof(*header);
+ cfg = p;
+ cfg->sample_rate = mcfg->sample_rate;
+ cfg->bit_width = mcfg->bit_width;
+ cfg->alignment = PCM_LSB_ALIGNED;
+ cfg->bits_per_sample = mcfg->bit_width;
+ cfg->q_factor = mcfg->bit_width - 1;
+ cfg->endianness = PCM_LITTLE_ENDIAN;
+ cfg->num_channels = mcfg->num_channels;
+
+ if (mcfg->num_channels == 1)
+ cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ else if (num_channels == 2) {
+ cfg->channel_mapping[0] = PCM_CHANNEL_L;
+ cfg->channel_mapping[1] = PCM_CHANNEL_R;
+ }
+ } else
+ audioreach_set_compr_media_format(header, p, mcfg);

rc = audioreach_graph_send_cmd_sync(graph, pkt, 0);

@@ -1401,7 +1466,8 @@ int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_modu
cfg->channel_mapping[0] = PCM_CHANNEL_L;
cfg->channel_mapping[1] = PCM_CHANNEL_R;
}
- }
+ } else
+ audioreach_set_compr_media_format(header, p, mcfg);

rc = gpr_send_port_pkt(graph->port, pkt);
kfree(pkt);
--
2.25.1


2023-02-01 13:53:45

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: [PATCH 14/14] ASoC: q6dsp: audioreach: Add gapless feature support

Add support for setting EOS delay command and receive the
EOS response from ADSP, for seamless compress offload
playback feature.

Signed-off-by: Mohammad Rafi Shaik <[email protected]>
Co-developed-by: Srinivas Kandagatla <[email protected]>
Signed-off-by: Srinivas Kandagatla <[email protected]>
---
sound/soc/qcom/qdsp6/audioreach.c | 40 +++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/audioreach.h | 6 +++++
sound/soc/qcom/qdsp6/q6apm.c | 3 +++
3 files changed, 49 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 250ed828c7d3..71ff705e27cb 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -852,6 +852,43 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
return rc;
}

+static int audioreach_gapless_set_media_format(struct q6apm_graph *graph,
+ struct audioreach_module *module,
+ struct audioreach_module_config *cfg)
+{
+ struct apm_module_param_data *param_data;
+ struct param_id_gapless_early_eos_delay_t *media_format;
+ int payload_size;
+ struct gpr_pkt *pkt;
+ int rc;
+ void *p;
+
+ payload_size = sizeof(struct param_id_gapless_early_eos_delay_t) +
+ APM_MODULE_PARAM_DATA_SIZE;
+
+ pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ if (IS_ERR(pkt))
+ return PTR_ERR(pkt);
+
+ p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
+
+ param_data = p;
+ param_data->module_instance_id = module->instance_id;
+ param_data->error_code = 0;
+ param_data->param_id = PARAM_ID_EARLY_EOS_DELAY;
+ param_data->param_size = sizeof(struct param_id_gapless_early_eos_delay_t);
+ p = p + APM_MODULE_PARAM_DATA_SIZE;
+ media_format = p;
+
+ media_format->early_eos_delay_ms = EARLY_EOS_DELAY_MS;
+
+ rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
+
+ kfree(pkt);
+
+ return rc;
+}
+
static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
void *p, struct audioreach_module_config *mcfg)
{
@@ -1249,6 +1286,9 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod
case MODULE_ID_MFC:
rc = audioreach_mfc_set_media_format(graph, module, cfg);
break;
+ case MODULE_ID_GAPLESS:
+ rc = audioreach_gapless_set_media_format(graph, module, cfg);
+ break;
default:
rc = 0;
}
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index 044994ca4811..a9d4f70ad3e0 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -543,6 +543,8 @@ struct param_id_sal_limiter_enable {
} __packed;

#define PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x08001024
+#define PARAM_ID_EARLY_EOS_DELAY 0x0800114C
+#define EARLY_EOS_DELAY_MS 150

struct param_id_mfc_media_format {
uint32_t sample_rate;
@@ -551,6 +553,10 @@ struct param_id_mfc_media_format {
uint16_t channel_mapping[];
} __packed;

+struct param_id_gapless_early_eos_delay_t {
+ uint32_t early_eos_delay_ms;
+} __packed;
+
struct media_format {
uint32_t data_format;
uint32_t fmt_id;
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 1a6c7108bae0..37ded6e0f4ea 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -605,6 +605,9 @@ static int graph_callback(struct gpr_resp_pkt *data, void *priv, int op)
}
break;
case DATA_CMD_WR_SH_MEM_EP_EOS_RENDERED:
+ client_event = APM_CLIENT_EVENT_CMD_EOS_DONE;
+ if (graph->cb)
+ graph->cb(client_event, hdr->token, data->payload, graph->priv);
break;
case GPR_BASIC_RSP_RESULT:
switch (result->opcode) {
--
2.25.1


2023-02-01 14:41:11

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 02/14] ASoC: qcom: SC7280: audioreach: Add sc7280 hardware param fixup callback

On Wed, Feb 01, 2023 at 07:19:35PM +0530, Mohammad Rafi Shaik wrote:

> +#define DEFAULT_SAMPLE_RATE_48K 48000

Why are we bothering with a define here given that the define also
encodes the value and it's only used in once place?

> for_each_card_prelinks(card, i, link) {
> link->init = sc7280_init;
> link->ops = &sc7280_ops;
> + if (link->no_pcm == 1)
> + link->be_hw_params_fixup = sc7280_snd_be_hw_params_fixup;

We only set the fixup in the case where there's no PCM but we removed
the constraint in all cases - isn't the constraint needed otherwise?


Attachments:
(No filename) (569.00 B)
signature.asc (488.00 B)
Download all attachments

2023-02-01 15:19:34

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 11/14] ASoC: q6dsp: q6apm-dai: Add compress set params and metadata DAI callbacks

Hi Mohammad,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on next-20230201]
[cannot apply to tiwai-sound/for-next tiwai-sound/for-linus linus/master v6.2-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
patch link: https://lore.kernel.org/r/20230201134947.1638197-12-quic_mohs%40quicinc.com
patch subject: [PATCH 11/14] ASoC: q6dsp: q6apm-dai: Add compress set params and metadata DAI callbacks
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230201/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/f6204693a956c267d6cdfd17f5c27da0f4594ca3
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
git checkout f6204693a956c267d6cdfd17f5c27da0f4594ca3
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash sound/soc/qcom/qdsp6/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

sound/soc/qcom/qdsp6/q6apm-dai.c:152:6: warning: no previous prototype for 'event_handler_compr' [-Wmissing-prototypes]
152 | void event_handler_compr(uint32_t opcode, uint32_t token,
| ^~~~~~~~~~~~~~~~~~~
sound/soc/qcom/qdsp6/q6apm-dai.c:576:5: warning: no previous prototype for 'q6apm_dai_compr_trigger' [-Wmissing-prototypes]
576 | int q6apm_dai_compr_trigger(struct snd_soc_component *component,
| ^~~~~~~~~~~~~~~~~~~~~~~
sound/soc/qcom/qdsp6/q6apm-dai.c:610:5: warning: no previous prototype for 'q6apm_dai_compr_ack' [-Wmissing-prototypes]
610 | int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream,
| ^~~~~~~~~~~~~~~~~~~
sound/soc/qcom/qdsp6/q6apm-dai.c: In function '__q6apm_dai_compr_set_codec_params':
>> sound/soc/qcom/qdsp6/q6apm-dai.c:632:34: warning: variable 'codec_options' set but not used [-Wunused-but-set-variable]
632 | union snd_codec_options *codec_options;
| ^~~~~~~~~~~~~


vim +/codec_options +632 sound/soc/qcom/qdsp6/q6apm-dai.c

623
624 static int __q6apm_dai_compr_set_codec_params(struct snd_soc_component *component,
625 struct snd_compr_stream *stream,
626 struct snd_codec *codec,
627 int stream_id)
628 {
629 struct snd_compr_runtime *runtime = stream->runtime;
630 struct q6apm_dai_rtd *prtd = runtime->private_data;
631 struct device *dev = component->dev;
> 632 union snd_codec_options *codec_options;
633
634 codec_options = &(prtd->codec.options);
635
636 memcpy(&prtd->codec, codec, sizeof(*codec));
637 q6apm_set_real_module_id(dev, prtd->graph, codec->id);
638
639 return 0;
640 }
641

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-02-01 15:20:10

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 04/14] ASoC: q6dsp: audioreach: Add support for compress offload commands

Hi Mohammad,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on next-20230201]
[cannot apply to tiwai-sound/for-next tiwai-sound/for-linus linus/master v6.2-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
patch link: https://lore.kernel.org/r/20230201134947.1638197-5-quic_mohs%40quicinc.com
patch subject: [PATCH 04/14] ASoC: q6dsp: audioreach: Add support for compress offload commands
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230201/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/6a2982489303bcf32b927da80e4baffae58437e0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
git checkout 6a2982489303bcf32b927da80e4baffae58437e0
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash sound/soc/qcom/qdsp6/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> sound/soc/qcom/qdsp6/audioreach.c:1262:5: warning: no previous prototype for 'audioreach_send_u32_param' [-Wmissing-prototypes]
1262 | int audioreach_send_u32_param(struct q6apm *apm, struct audioreach_module *module,
| ^~~~~~~~~~~~~~~~~~~~~~~~~


vim +/audioreach_send_u32_param +1262 sound/soc/qcom/qdsp6/audioreach.c

1261
> 1262 int audioreach_send_u32_param(struct q6apm *apm, struct audioreach_module *module,
1263 uint32_t param_id, uint32_t param_val)
1264 {
1265 struct apm_module_param_data *param_data;
1266 struct gpr_pkt *pkt;
1267 uint32_t *param;
1268 int rc, payload_size;
1269 void *p;
1270
1271 payload_size = sizeof(uint32_t) + APM_MODULE_PARAM_DATA_SIZE;
1272 p = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
1273 if (IS_ERR(p))
1274 return -ENOMEM;
1275
1276 pkt = p;
1277 p = p + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
1278
1279 param_data = p;
1280 param_data->module_instance_id = module->instance_id;
1281 param_data->error_code = 0;
1282 param_data->param_id = param_id;
1283 param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
1284
1285 p = p + APM_MODULE_PARAM_DATA_SIZE;
1286 param = p;
1287 *param = param_val;
1288 rc = q6apm_send_cmd_sync(apm, pkt, 0);
1289
1290 kfree(pkt);
1291
1292 return rc;
1293 }
1294 EXPORT_SYMBOL_GPL(audioreach_send_u32_param);
1295

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-02-01 16:11:34

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 08/14] ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks

Hi Mohammad,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on next-20230201]
[cannot apply to tiwai-sound/for-next tiwai-sound/for-linus linus/master v6.2-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
patch link: https://lore.kernel.org/r/20230201134947.1638197-9-quic_mohs%40quicinc.com
patch subject: [PATCH 08/14] ASoC: q6dsp: q6apm-dai: Add open/free compress DAI callbacks
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230201/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/78a6016e006a8e405679fd335940ee710416c43f
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
git checkout 78a6016e006a8e405679fd335940ee710416c43f
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash sound/soc/qcom/qdsp6/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> sound/soc/qcom/qdsp6/q6apm-dai.c:135:6: warning: no previous prototype for 'event_handler_compr' [-Wmissing-prototypes]
135 | void event_handler_compr(uint32_t opcode, uint32_t token,
| ^~~~~~~~~~~~~~~~~~~


vim +/event_handler_compr +135 sound/soc/qcom/qdsp6/q6apm-dai.c

134
> 135 void event_handler_compr(uint32_t opcode, uint32_t token,
136 uint32_t *payload, void *priv)
137 {
138 struct q6apm_dai_rtd *prtd = priv;
139 struct snd_compr_stream *substream = prtd->cstream;
140 unsigned long flags;
141 uint32_t wflags = 0;
142 uint64_t avail;
143 uint32_t bytes_written, bytes_to_write;
144 bool is_last_buffer = false;
145
146 switch (opcode) {
147 case APM_CLIENT_EVENT_CMD_EOS_DONE:
148 spin_lock_irqsave(&prtd->lock, flags);
149 if (prtd->notify_on_drain) {
150 snd_compr_drain_notify(prtd->cstream);
151 prtd->notify_on_drain = false;
152 } else {
153 prtd->state = Q6APM_STREAM_STOPPED;
154 }
155 spin_unlock_irqrestore(&prtd->lock, flags);
156 break;
157 case APM_CLIENT_EVENT_DATA_WRITE_DONE:
158 spin_lock_irqsave(&prtd->lock, flags);
159 bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT;
160 prtd->copied_total += bytes_written;
161 snd_compr_fragment_elapsed(substream);
162
163 if (prtd->state != Q6APM_STREAM_RUNNING) {
164 spin_unlock_irqrestore(&prtd->lock, flags);
165 break;
166 }
167
168 avail = prtd->bytes_received - prtd->bytes_sent;
169
170 if (avail > prtd->pcm_count) {
171 bytes_to_write = prtd->pcm_count;
172 } else {
173 if (substream->partial_drain || prtd->notify_on_drain)
174 is_last_buffer = true;
175 bytes_to_write = avail;
176 }
177
178 if (bytes_to_write) {
179 if (substream->partial_drain && is_last_buffer)
180 wflags |= APM_LAST_BUFFER_FLAG;
181
182 q6apm_write_async_compr(prtd->graph,
183 bytes_to_write, 0, 0, wflags);
184
185 prtd->bytes_sent += bytes_to_write;
186
187 if (prtd->notify_on_drain && is_last_buffer)
188 audioreach_shared_memory_send_eos(prtd->graph);
189 }
190
191 spin_unlock_irqrestore(&prtd->lock, flags);
192 break;
193 default:
194 break;
195 }
196 }
197

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-02-01 16:51:46

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 10/14] ASoC: q6dsp: q6apm-dai: Add trigger/pointer compress DAI callbacks

Hi Mohammad,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on next-20230201]
[cannot apply to tiwai-sound/for-next tiwai-sound/for-linus linus/master v6.2-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
patch link: https://lore.kernel.org/r/20230201134947.1638197-11-quic_mohs%40quicinc.com
patch subject: [PATCH 10/14] ASoC: q6dsp: q6apm-dai: Add trigger/pointer compress DAI callbacks
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230202/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/2b44c079fb2d53ef9e13fc7d7b257fd4c6f4b56a
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mohammad-Rafi-Shaik/ALSA-compress-Update-compress-set-params-for-gapless-playback/20230201-215622
git checkout 2b44c079fb2d53ef9e13fc7d7b257fd4c6f4b56a
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash sound/soc/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

sound/soc/qcom/qdsp6/q6apm-dai.c:152:6: warning: no previous prototype for 'event_handler_compr' [-Wmissing-prototypes]
152 | void event_handler_compr(uint32_t opcode, uint32_t token,
| ^~~~~~~~~~~~~~~~~~~
>> sound/soc/qcom/qdsp6/q6apm-dai.c:576:5: warning: no previous prototype for 'q6apm_dai_compr_trigger' [-Wmissing-prototypes]
576 | int q6apm_dai_compr_trigger(struct snd_soc_component *component,
| ^~~~~~~~~~~~~~~~~~~~~~~
>> sound/soc/qcom/qdsp6/q6apm-dai.c:610:5: warning: no previous prototype for 'q6apm_dai_compr_ack' [-Wmissing-prototypes]
610 | int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream,
| ^~~~~~~~~~~~~~~~~~~


vim +/q6apm_dai_compr_trigger +576 sound/soc/qcom/qdsp6/q6apm-dai.c

575
> 576 int q6apm_dai_compr_trigger(struct snd_soc_component *component,
577 struct snd_compr_stream *stream, int cmd)
578 {
579 struct snd_compr_runtime *runtime = stream->runtime;
580 struct q6apm_dai_rtd *prtd = runtime->private_data;
581 int ret = 0;
582
583 switch (cmd) {
584 case SNDRV_PCM_TRIGGER_START:
585 case SNDRV_PCM_TRIGGER_RESUME:
586 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
587 ret = q6apm_write_async_compr(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
588 break;
589 case SNDRV_PCM_TRIGGER_STOP:
590 break;
591 case SNDRV_PCM_TRIGGER_SUSPEND:
592 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
593 break;
594 case SND_COMPR_TRIGGER_NEXT_TRACK:
595 prtd->next_track = true;
596 prtd->next_track_stream_id = (prtd->graph->id == 1 ? 2 : 1);
597 break;
598 case SND_COMPR_TRIGGER_DRAIN:
599 case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
600 prtd->notify_on_drain = true;
601 break;
602 default:
603 ret = -EINVAL;
604 break;
605 }
606
607 return ret;
608 }
609
> 610 int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream,
611 size_t count)
612 {
613 struct snd_compr_runtime *runtime = stream->runtime;
614 struct q6apm_dai_rtd *prtd = runtime->private_data;
615 unsigned long flags;
616
617 spin_lock_irqsave(&prtd->lock, flags);
618 prtd->bytes_received += count;
619 spin_unlock_irqrestore(&prtd->lock, flags);
620
621 return count;
622 }
623

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

2023-02-03 06:33:50

by Mohammad Rafi Shaik

[permalink] [raw]
Subject: Re: [PATCH 02/14] ASoC: qcom: SC7280: audioreach: Add sc7280 hardware param fixup callback


On 2/1/2023 8:10 PM, Mark Brown wrote:
> On Wed, Feb 01, 2023 at 07:19:35PM +0530, Mohammad Rafi Shaik wrote:
>
>> +#define DEFAULT_SAMPLE_RATE_48K 48000
> Why are we bothering with a define here given that the define also
> encodes the value and it's only used in once place?
okay, will remove it.
>
>> for_each_card_prelinks(card, i, link) {
>> link->init = sc7280_init;
>> link->ops = &sc7280_ops;
>> + if (link->no_pcm == 1)
>> + link->be_hw_params_fixup = sc7280_snd_be_hw_params_fixup;
> We only set the fixup in the case where there's no PCM but we removed
> the constraint in all cases - isn't the constraint needed otherwise?
okay, will add conditional check for constraint and will only do if
no_pcm is zero.