diff options
Diffstat (limited to 'sound/soc/qcom/qdsp6/audioreach.c')
| -rw-r--r-- | sound/soc/qcom/qdsp6/audioreach.c | 515 |
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); |
