summaryrefslogtreecommitdiff
path: root/sound/soc/qcom/qdsp6/audioreach.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/qcom/qdsp6/audioreach.c')
-rw-r--r--sound/soc/qcom/qdsp6/audioreach.c515
1 files changed, 298 insertions, 217 deletions
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 1e0c918eb576..ded49124581b 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -196,6 +196,12 @@ struct apm_codec_dma_module_intf_cfg {
#define APM_CDMA_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_codec_dma_module_intf_cfg), 8)
+struct apm_display_port_module_intf_cfg {
+ struct apm_module_param_data param_data;
+ struct param_id_display_port_intf_cfg cfg;
+} __packed;
+#define APM_DP_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_display_port_module_intf_cfg), 8)
+
static void *__audioreach_alloc_pkt(int payload_size, uint32_t opcode, uint32_t token,
uint32_t src_port, uint32_t dest_port, bool has_cmd_hdr)
{
@@ -261,6 +267,22 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
}
EXPORT_SYMBOL_GPL(audioreach_alloc_apm_cmd_pkt);
+void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
+{
+ if (num_channels == 1) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ } else if (num_channels == 2) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ ch_map[1] = PCM_CHANNEL_FR;
+ } else if (num_channels == 4) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ ch_map[1] = PCM_CHANNEL_FR;
+ ch_map[2] = PCM_CHANNEL_LS;
+ ch_map[3] = PCM_CHANNEL_RS;
+ }
+}
+EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
+
static void apm_populate_container_config(struct apm_container_obj *cfg,
struct audioreach_container *cont)
{
@@ -582,6 +604,61 @@ int audioreach_graph_send_cmd_sync(struct q6apm_graph *graph, struct gpr_pkt *pk
}
EXPORT_SYMBOL_GPL(audioreach_graph_send_cmd_sync);
+static int audioreach_display_port_set_media_format(struct q6apm_graph *graph,
+ struct audioreach_module *module,
+ struct audioreach_module_config *cfg)
+{
+ struct apm_display_port_module_intf_cfg *intf_cfg;
+ struct apm_module_frame_size_factor_cfg *fs_cfg;
+ struct apm_module_param_data *param_data;
+ struct apm_module_hw_ep_mf_cfg *hw_cfg;
+ int ic_sz = APM_DP_INTF_CFG_PSIZE;
+ int ep_sz = APM_HW_EP_CFG_PSIZE;
+ int fs_sz = APM_FS_CFG_PSIZE;
+ int size = ic_sz + ep_sz + fs_sz;
+ void *p;
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
+ if (IS_ERR(pkt))
+ return PTR_ERR(pkt);
+
+ p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
+
+ hw_cfg = p;
+ param_data = &hw_cfg->param_data;
+ param_data->module_instance_id = module->instance_id;
+ param_data->error_code = 0;
+ param_data->param_id = PARAM_ID_HW_EP_MF_CFG;
+ param_data->param_size = ep_sz - APM_MODULE_PARAM_DATA_SIZE;
+
+ hw_cfg->mf.sample_rate = cfg->sample_rate;
+ hw_cfg->mf.bit_width = cfg->bit_width;
+ hw_cfg->mf.num_channels = cfg->num_channels;
+ hw_cfg->mf.data_format = module->data_format;
+ p += ep_sz;
+
+ fs_cfg = p;
+ param_data = &fs_cfg->param_data;
+ param_data->module_instance_id = module->instance_id;
+ param_data->error_code = 0;
+ param_data->param_id = PARAM_ID_HW_EP_FRAME_SIZE_FACTOR;
+ param_data->param_size = fs_sz - APM_MODULE_PARAM_DATA_SIZE;
+ fs_cfg->frame_size_factor = 1;
+ p += fs_sz;
+
+ intf_cfg = p;
+ param_data = &intf_cfg->param_data;
+ param_data->module_instance_id = module->instance_id;
+ param_data->error_code = 0;
+ param_data->param_id = PARAM_ID_DISPLAY_PORT_INTF_CFG;
+ param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
+
+ intf_cfg->cfg.channel_allocation = cfg->channel_allocation;
+ intf_cfg->cfg.mst_idx = 0;
+ intf_cfg->cfg.dptx_idx = cfg->dp_idx;
+
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
+}
+
/* LPASS Codec DMA port Module Media Format Setup */
static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
struct audioreach_module *module,
@@ -592,20 +669,13 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
struct apm_module_hw_ep_power_mode_cfg *pm_cfg;
struct apm_module_param_data *param_data;
struct apm_module_hw_ep_mf_cfg *hw_cfg;
- int ic_sz, ep_sz, fs_sz, pm_sz, dl_sz;
- int rc, payload_size;
- struct gpr_pkt *pkt;
+ int ic_sz = APM_CDMA_INTF_CFG_PSIZE;
+ int ep_sz = APM_HW_EP_CFG_PSIZE;
+ int fs_sz = APM_FS_CFG_PSIZE;
+ int pm_sz = APM_HW_EP_PMODE_CFG_PSIZE;
+ int size = ic_sz + ep_sz + fs_sz + pm_sz;
void *p;
-
- ic_sz = APM_CDMA_INTF_CFG_PSIZE;
- ep_sz = APM_HW_EP_CFG_PSIZE;
- fs_sz = APM_FS_CFG_PSIZE;
- pm_sz = APM_HW_EP_PMODE_CFG_PSIZE;
- dl_sz = 0;
-
- payload_size = ic_sz + ep_sz + fs_sz + pm_sz + dl_sz;
-
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -653,118 +723,80 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
param_data->param_size = pm_sz - APM_MODULE_PARAM_DATA_SIZE;
pm_cfg->power_mode.power_mode = 0;
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
-static int audioreach_sal_limiter_enable(struct q6apm_graph *graph,
- struct audioreach_module *module, bool enable)
+int audioreach_send_u32_param(struct q6apm_graph *graph, struct audioreach_module *module,
+ uint32_t param_id, uint32_t param_val)
{
struct apm_module_param_data *param_data;
- struct param_id_sal_limiter_enable *limiter_enable;
- int payload_size;
- struct gpr_pkt *pkt;
- int rc;
- void *p;
-
- payload_size = sizeof(*limiter_enable) + APM_MODULE_PARAM_DATA_SIZE;
+ struct gpr_pkt *pkt __free(kfree) = NULL;
+ uint32_t *param;
+ int payload_size = sizeof(uint32_t) + APM_MODULE_PARAM_DATA_SIZE;
+ void *p = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ if (IS_ERR(p))
+ return -ENOMEM;
- 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;
+ 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_SAL_LIMITER_ENABLE;
- param_data->param_size = sizeof(*limiter_enable);
- p = p + APM_MODULE_PARAM_DATA_SIZE;
- limiter_enable = p;
+ param_data->param_id = param_id;
+ param_data->param_size = sizeof(uint32_t);
- limiter_enable->enable_lim = enable;
-
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
+ p = p + APM_MODULE_PARAM_DATA_SIZE;
+ param = p;
+ *param = param_val;
- kfree(pkt);
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
+}
+EXPORT_SYMBOL_GPL(audioreach_send_u32_param);
- return rc;
+static int audioreach_sal_limiter_enable(struct q6apm_graph *graph,
+ struct audioreach_module *module, bool enable)
+{
+ return audioreach_send_u32_param(graph, module, PARAM_ID_SAL_LIMITER_ENABLE, enable);
}
static int audioreach_sal_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_sal_output_config *media_format;
- int payload_size;
- struct gpr_pkt *pkt;
- int rc;
- void *p;
-
- payload_size = sizeof(*media_format) + 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_SAL_OUTPUT_CFG;
- param_data->param_size = sizeof(*media_format);
- p = p + APM_MODULE_PARAM_DATA_SIZE;
- media_format = p;
-
- media_format->bits_per_sample = cfg->bit_width;
-
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return audioreach_send_u32_param(graph, module, PARAM_ID_SAL_OUTPUT_CFG, cfg->bit_width);
}
static int audioreach_module_enable(struct q6apm_graph *graph,
struct audioreach_module *module,
bool enable)
{
- struct apm_module_param_data *param_data;
- struct param_id_module_enable *param;
- int payload_size;
- struct gpr_pkt *pkt;
- int rc;
- void *p;
+ return audioreach_send_u32_param(graph, module, PARAM_ID_MODULE_ENABLE, enable);
+}
- payload_size = sizeof(*param) + APM_MODULE_PARAM_DATA_SIZE;
+static int audioreach_gapless_set_media_format(struct q6apm_graph *graph,
+ struct audioreach_module *module,
+ struct audioreach_module_config *cfg)
+{
+ return audioreach_send_u32_param(graph, module, PARAM_ID_EARLY_EOS_DELAY,
+ EARLY_EOS_DELAY_MS);
+}
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+static int audioreach_set_module_config(struct q6apm_graph *graph,
+ struct audioreach_module *module,
+ struct audioreach_module_config *cfg)
+{
+ int size = le32_to_cpu(module->data->size);
+ void *p;
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(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_MODULE_ENABLE;
- param_data->param_size = sizeof(*param);
- p = p + APM_MODULE_PARAM_DATA_SIZE;
- param = p;
-
- param->enable = enable;
-
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
+ memcpy(p, module->data->data, size);
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
@@ -774,15 +806,11 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
struct apm_module_param_data *param_data;
struct param_id_mfc_media_format *media_format;
uint32_t num_channels = cfg->num_channels;
- int payload_size;
- struct gpr_pkt *pkt;
- int rc;
+ int payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
+ APM_MODULE_PARAM_DATA_SIZE;
+ int i;
void *p;
-
- payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
- APM_MODULE_PARAM_DATA_SIZE;
-
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -799,20 +827,117 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
media_format->sample_rate = cfg->sample_rate;
media_format->bit_width = cfg->bit_width;
media_format->num_channels = cfg->num_channels;
+ for (i = 0; i < num_channels; i++)
+ media_format->channel_mapping[i] = cfg->channel_map[i];
- if (num_channels == 1) {
- media_format->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (num_channels == 2) {
- media_format->channel_mapping[0] = PCM_CHANNEL_L;
- media_format->channel_mapping[1] = PCM_CHANNEL_R;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
+}
+
+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;
+ struct payload_media_fmt_opus_t *opus_cfg;
+
+ 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;
+ 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;
+ case SND_AUDIOCODEC_OPUS_RAW:
+ media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
+ media_fmt_hdr->fmt_id = MEDIA_FMT_ID_OPUS;
+ media_fmt_hdr->payload_size = sizeof(*opus_cfg);
+ p = p + sizeof(*media_fmt_hdr);
+ opus_cfg = p;
+ /* raw opus packets prepended with 4 bytes of length */
+ opus_cfg->bitstream_format = 1;
+ /*
+ * payload_type:
+ * 0 -- read metadata from opus stream;
+ * 1 -- metadata is provided by filling in the struct here.
+ */
+ opus_cfg->payload_type = 1;
+ opus_cfg->version = mcfg->codec.options.opus_d.version;
+ opus_cfg->num_channels = mcfg->codec.options.opus_d.num_channels;
+ opus_cfg->pre_skip = mcfg->codec.options.opus_d.pre_skip;
+ opus_cfg->sample_rate = mcfg->codec.options.opus_d.sample_rate;
+ opus_cfg->output_gain = mcfg->codec.options.opus_d.output_gain;
+ opus_cfg->mapping_family = mcfg->codec.options.opus_d.mapping_family;
+ opus_cfg->stream_count = mcfg->codec.options.opus_d.chan_map.stream_count;
+ opus_cfg->coupled_count = mcfg->codec.options.opus_d.chan_map.coupled_count;
+ memcpy(opus_cfg->channel_mapping, mcfg->codec.options.opus_d.chan_map.channel_map,
+ sizeof(opus_cfg->channel_mapping));
+ opus_cfg->reserved[0] = opus_cfg->reserved[1] = opus_cfg->reserved[2] = 0;
+ break;
+ default:
+ return -EINVAL;
}
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
+ return 0;
+}
+
+int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg)
+{
+ struct media_format *header;
+ int rc;
+ void *p;
+ int iid = q6apm_graph_get_rx_shmem_module_iid(graph);
+ int payload_size = sizeof(struct apm_sh_module_media_fmt_cmd);
+ struct gpr_pkt *pkt __free(kfree) = 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;
- kfree(pkt);
- return rc;
+ p = (void *)pkt + GPR_HDR_SIZE;
+ header = p;
+ rc = audioreach_set_compr_media_format(header, p, mcfg);
+ if (rc)
+ return rc;
+
+ return gpr_send_port_pkt(graph->port, pkt);
}
+EXPORT_SYMBOL_GPL(audioreach_compr_set_param);
static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
struct audioreach_module *module,
@@ -822,18 +947,12 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
struct apm_module_param_data *param_data;
struct apm_i2s_module_intf_cfg *intf_cfg;
struct apm_module_hw_ep_mf_cfg *hw_cfg;
- int ic_sz, ep_sz, fs_sz;
- int rc, payload_size;
- struct gpr_pkt *pkt;
+ int ic_sz = APM_I2S_INTF_CFG_PSIZE;
+ int ep_sz = APM_HW_EP_CFG_PSIZE;
+ int fs_sz = APM_FS_CFG_PSIZE;
+ int size = ic_sz + ep_sz + fs_sz;
void *p;
-
- ic_sz = APM_I2S_INTF_CFG_PSIZE;
- ep_sz = APM_HW_EP_CFG_PSIZE;
- fs_sz = APM_FS_CFG_PSIZE;
-
- payload_size = ic_sz + ep_sz + fs_sz;
-
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -846,6 +965,7 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
param_data->param_id = PARAM_ID_I2S_INTF_CFG;
param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
+ intf_cfg->cfg.lpaif_type = module->hw_interface_type;
intf_cfg->cfg.intf_idx = module->hw_interface_idx;
intf_cfg->cfg.sd_line_idx = module->sd_line_idx;
@@ -883,11 +1003,7 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
param_data->param_size = fs_sz - APM_MODULE_PARAM_DATA_SIZE;
fs_cfg->frame_size_factor = 1;
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
static int audioreach_logging_set_media_format(struct q6apm_graph *graph,
@@ -895,12 +1011,9 @@ static int audioreach_logging_set_media_format(struct q6apm_graph *graph,
{
struct apm_module_param_data *param_data;
struct data_logging_config *cfg;
- int rc, payload_size;
- struct gpr_pkt *pkt;
+ int size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
void *p;
-
- payload_size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -910,7 +1023,7 @@ static int audioreach_logging_set_media_format(struct q6apm_graph *graph,
param_data->module_instance_id = module->instance_id;
param_data->error_code = 0;
param_data->param_id = PARAM_ID_DATA_LOGGING_CONFIG;
- param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
+ param_data->param_size = size - APM_MODULE_PARAM_DATA_SIZE;
p = p + APM_MODULE_PARAM_DATA_SIZE;
cfg = p;
@@ -918,11 +1031,7 @@ static int audioreach_logging_set_media_format(struct q6apm_graph *graph,
cfg->log_tap_point_id = module->log_tap_point_id;
cfg->mode = module->log_mode;
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
@@ -933,10 +1042,10 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
uint32_t num_channels = mcfg->num_channels;
struct apm_pcm_module_media_fmt_cmd *cfg;
struct apm_module_param_data *param_data;
- int rc, payload_size;
- struct gpr_pkt *pkt;
+ int payload_size;
+ struct gpr_pkt *pkt __free(kfree) = NULL;
- if (num_channels > 2) {
+ if (num_channels > 4) {
dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
return -EINVAL;
}
@@ -967,20 +1076,9 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
media_cfg->num_channels = mcfg->num_channels;
media_cfg->q_factor = mcfg->bit_width - 1;
media_cfg->bits_per_sample = mcfg->bit_width;
+ memcpy(media_cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
- if (num_channels == 1) {
- media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (num_channels == 2) {
- media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- media_cfg->channel_mapping[1] = PCM_CHANNEL_R;
-
- }
-
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
@@ -992,10 +1090,10 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
struct payload_media_fmt_pcm *cfg;
struct media_format *header;
int rc, payload_size;
- struct gpr_pkt *pkt;
+ struct gpr_pkt *pkt __free(kfree) = NULL;
void *p;
- if (num_channels > 2) {
+ if (num_channels > 4) {
dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
return -EINVAL;
}
@@ -1017,44 +1115,37 @@ 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);
-
- 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;
+ 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;
+ memcpy(cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
+ } else {
+ rc = audioreach_set_compr_media_format(header, p, mcfg);
+ if (rc)
+ return rc;
}
- rc = audioreach_graph_send_cmd_sync(graph, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return audioreach_graph_send_cmd_sync(graph, pkt, 0);
}
int audioreach_gain_set_vol_ctrl(struct q6apm *apm, struct audioreach_module *module, int vol)
{
struct param_id_vol_ctrl_master_gain *cfg;
struct apm_module_param_data *param_data;
- int rc, payload_size;
- struct gpr_pkt *pkt;
+ int size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
void *p;
-
- payload_size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -1064,16 +1155,12 @@ int audioreach_gain_set_vol_ctrl(struct q6apm *apm, struct audioreach_module *mo
param_data->module_instance_id = module->instance_id;
param_data->error_code = 0;
param_data->param_id = PARAM_ID_VOL_CTRL_MASTER_GAIN;
- param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
+ param_data->param_size = size - APM_MODULE_PARAM_DATA_SIZE;
p = p + APM_MODULE_PARAM_DATA_SIZE;
cfg = p;
cfg->master_gain = vol;
- rc = q6apm_send_cmd_sync(apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(apm, pkt, 0);
}
EXPORT_SYMBOL_GPL(audioreach_gain_set_vol_ctrl);
@@ -1081,11 +1168,8 @@ static int audioreach_gain_set(struct q6apm_graph *graph, struct audioreach_modu
{
struct apm_module_param_data *param_data;
struct apm_gain_module_cfg *cfg;
- int rc, payload_size;
- struct gpr_pkt *pkt;
-
- payload_size = APM_GAIN_CFG_PSIZE;
- pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
+ int size = APM_GAIN_CFG_PSIZE;
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -1095,15 +1179,11 @@ static int audioreach_gain_set(struct q6apm_graph *graph, struct audioreach_modu
param_data->module_instance_id = module->instance_id;
param_data->error_code = 0;
param_data->param_id = APM_PARAM_ID_GAIN;
- param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
+ param_data->param_size = size - APM_MODULE_PARAM_DATA_SIZE;
cfg->gain_cfg.gain = module->gain;
- rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
-
- kfree(pkt);
-
- return rc;
+ return q6apm_send_cmd_sync(graph->apm, pkt, 0);
}
int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_module *module,
@@ -1120,8 +1200,16 @@ 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_DISPLAY_PORT_SINK:
+ rc = audioreach_display_port_set_media_format(graph, module, cfg);
+ break;
+ case MODULE_ID_SMECNS_V2:
+ rc = audioreach_set_module_config(graph, module, cfg);
+ break;
case MODULE_ID_I2S_SOURCE:
case MODULE_ID_I2S_SINK:
rc = audioreach_i2s_set_media_format(graph, module, cfg);
@@ -1144,6 +1232,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;
}
@@ -1177,9 +1268,9 @@ int audioreach_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, s
struct apm_cmd_shared_mem_map_regions *cmd;
uint32_t num_regions, buf_sz, payload_size;
struct audioreach_graph_data *data;
- struct gpr_pkt *pkt;
+ struct gpr_pkt *pkt __free(kfree) = NULL;
void *p;
- int rc, i;
+ int i;
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
data = &graph->rx_data;
@@ -1226,23 +1317,16 @@ int audioreach_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, s
}
mutex_unlock(&graph->lock);
- rc = audioreach_graph_send_cmd_sync(graph, pkt, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS);
-
- kfree(pkt);
-
- return rc;
+ return audioreach_graph_send_cmd_sync(graph, pkt, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS);
}
EXPORT_SYMBOL_GPL(audioreach_map_memory_regions);
int audioreach_shared_memory_send_eos(struct q6apm_graph *graph)
{
struct data_cmd_wr_sh_mem_ep_eos *eos;
- struct gpr_pkt *pkt;
- int rc = 0, iid;
-
- iid = q6apm_graph_get_rx_shmem_module_iid(graph);
- pkt = audioreach_alloc_cmd_pkt(sizeof(*eos), DATA_CMD_WR_SH_MEM_EP_EOS, 0,
- graph->port->id, iid);
+ int iid = q6apm_graph_get_rx_shmem_module_iid(graph);
+ struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_cmd_pkt(sizeof(*eos),
+ DATA_CMD_WR_SH_MEM_EP_EOS, 0, graph->port->id, iid);
if (IS_ERR(pkt))
return PTR_ERR(pkt);
@@ -1250,9 +1334,6 @@ int audioreach_shared_memory_send_eos(struct q6apm_graph *graph)
eos->policy = WR_SH_MEM_EP_EOS_POLICY_LAST;
- rc = gpr_send_port_pkt(graph->port, pkt);
- kfree(pkt);
-
- return rc;
+ return gpr_send_port_pkt(graph->port, pkt);
}
EXPORT_SYMBOL_GPL(audioreach_shared_memory_send_eos);