diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 324a2083b..dbdc88c90 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -1244,7 +1244,7 @@ static int do_endpoint_copy(struct comp_dev *dev) return ret; } else { if (dev->ipc_config.type == SOF_COMP_HOST && !cd->ipc_gtw) - return host_zephyr_copy(cd->hd, cd->endpoint[0]); + return host_zephyr_copy(cd->hd, dev); return cd->endpoint[0]->drv->ops.copy(cd->endpoint[0]); } @@ -1307,6 +1307,9 @@ static int copier_copy(struct comp_dev *dev) comp_dbg(dev, "copier_copy()"); + if (dev->ipc_config.type == SOF_COMP_HOST && !cd->ipc_gtw) + return do_endpoint_copy(dev); + processed_data.source_bytes = 0; if (cd->endpoint_num && !cd->bsource_buffer) { @@ -1413,7 +1416,9 @@ static void copier_dma_cb(void *arg, enum notify_id type, void *data) struct dma_cb_data *next = data; struct comp_dev *dev = arg; struct copier_data *cd = comp_get_drvdata(dev); + struct comp_buffer __sparse_cache *sink; uint32_t bytes = next->elem.size; + int ret, frames; comp_dbg(dev, "copier_dma_cb() %p", dev); @@ -1423,6 +1428,24 @@ static void copier_dma_cb(void *arg, enum notify_id type, void *data) /* callback for one shot copy */ if (cd->hd->copy_type == COMP_COPY_ONE_SHOT) host_one_shot_cb(cd->hd, bytes); + + /* apply attenuation since copier copy missed this with host device remove */ + if (cd->attenuation) { + if (dev->direction == SOF_IPC_STREAM_PLAYBACK) + sink = buffer_acquire(cd->hd->local_buffer); + else + sink = buffer_acquire(cd->hd->dma_buffer); + + frames = bytes / get_sample_bytes(sink->stream.frame_fmt); + frames = frames / sink->stream.channels; + + ret = apply_attenuation(dev, cd, sink, frames); + if (ret < 0) + comp_dbg(dev, "copier_dma_cb() apply attenuation failed! %d", ret); + + buffer_stream_writeback(sink, bytes); + buffer_release(sink); + } } /* configure the DMA params */ @@ -1432,10 +1455,8 @@ static int copier_params(struct comp_dev *dev, struct sof_ipc_stream_params *par struct comp_buffer *sink, *source; struct comp_buffer __sparse_cache *sink_c, *source_c; struct list_item *sink_list; - struct comp_dev *child_dev; int ret = 0; int i; - bool is_scheduling_source; comp_dbg(dev, "copier_params()"); @@ -1468,22 +1489,17 @@ static int copier_params(struct comp_dev *dev, struct sof_ipc_stream_params *par buffer_release(sink_c); } - /* update the source format - * used only for rare cases where two pipelines are connected by a shared - * buffer and 2 copiers, this will set source format only for shared buffers - * for a short time when the second pipeline already started - * and the first one is not ready yet along with sink buffers params + /* + * force update the source buffer format to cover cases where the source module + * fails to set the sink buffer params */ if (!list_is_empty(&dev->bsource_list)) { + struct ipc4_audio_format *in_fmt; source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); source_c = buffer_acquire(source); - if (!source_c->hw_params_configured) { - struct ipc4_audio_format *in_fmt; - - in_fmt = &cd->config.base.audio_fmt; - update_buffer_format(source_c, in_fmt); - } + in_fmt = &cd->config.base.audio_fmt; + update_buffer_format(source_c, in_fmt); buffer_release(source_c); } @@ -1507,26 +1523,21 @@ static int copier_params(struct comp_dev *dev, struct sof_ipc_stream_params *par &demuxed_params); } else { if (dev->ipc_config.type == SOF_COMP_HOST && !cd->ipc_gtw) { - child_dev = cd->endpoint[i]; - ret = comp_verify_params(child_dev, 0, params); - if (ret < 0) { - comp_err(dev, "copier_params(): pcm params verification failed."); - return -EINVAL; + component_set_nearest_period_frames(dev, params->rate); + if (params->direction == SOF_IPC_STREAM_CAPTURE) { + params->buffer.size = cd->config.base.obs; + params->sample_container_bytes = cd->out_fmt->depth / 8; + params->sample_valid_bytes = + cd->out_fmt->valid_bit_depth / 8; } - is_scheduling_source = - child_dev == child_dev->pipeline->sched_comp; - /* copier dev only used for log print */ - ret = host_zephyr_params(cd->hd, dev, params, - &child_dev->bsink_list, - &child_dev->bsource_list, - dev->pipeline, - child_dev->frames, - is_scheduling_source); + ret = host_zephyr_params(cd->hd, dev, params); if (ret >= 0) /* set up callback */ notifier_register(dev, cd->hd->chan, NOTIFIER_ID_DMA_COPY, copier_dma_cb, 0); + + cd->hd->process = cd->converter[IPC4_COPIER_GATEWAY_PIN]; } else { ret = cd->endpoint[i]->drv->ops.params(cd->endpoint[i], params); diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index f41ecf66f..78c016341 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -710,9 +710,7 @@ static int host_verify_params(struct comp_dev *dev, } int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, - struct sof_ipc_stream_params *params, struct list_item *sink_list, - struct list_item *source_list, struct pipeline *pipeline, - uint32_t frames, bool is_scheduling_source) + struct sof_ipc_stream_params *params) { struct dma_sg_config *config = &hd->config; struct dma_sg_elem *sg_elem; @@ -726,6 +724,7 @@ int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, uint32_t addr_align; uint32_t align; int i, channel, err; + bool is_scheduling_source = dev == dev->pipeline->sched_comp; /* host params always installed by pipeline IPC */ hd->host_size = params->buffer.size; @@ -759,17 +758,16 @@ int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, } if (params->direction == SOF_IPC_STREAM_PLAYBACK) - hd->local_buffer = list_first_item(sink_list, + hd->local_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); else - hd->local_buffer = list_first_item(source_list, + hd->local_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); host_buf_c = buffer_acquire(hd->local_buffer); - period_bytes = frames * - audio_stream_frame_bytes(&host_buf_c->stream); + period_bytes = dev->frames * get_frame_bytes(params->frame_fmt, params->channels); if (!period_bytes) { comp_err(dev, "host_params(): invalid period_bytes"); @@ -823,6 +821,17 @@ int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, dma_buf_c = buffer_acquire(hd->dma_buffer); buffer_set_params(dma_buf_c, params, BUFFER_UPDATE_FORCE); + + /* set processing function */ + if (params->direction == SOF_IPC_STREAM_CAPTURE) + hd->process = pcm_get_conversion_function(host_buf_c->stream.frame_fmt, + dma_buf_c->stream.frame_fmt); + else + hd->process = pcm_get_conversion_function(dma_buf_c->stream.frame_fmt, + host_buf_c->stream.frame_fmt); + + config->src_width = audio_stream_sample_bytes(&dma_buf_c->stream); + config->dest_width = config->src_width; buffer_release(dma_buf_c); } @@ -833,12 +842,10 @@ int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, goto out; /* set up DMA configuration - copy in sample bytes. */ - config->src_width = audio_stream_sample_bytes(&host_buf_c->stream); - config->dest_width = audio_stream_sample_bytes(&host_buf_c->stream); config->cyclic = 0; - config->irq_disabled = pipeline_is_timer_driven(pipeline); + config->irq_disabled = pipeline_is_timer_driven(dev->pipeline); config->is_scheduling_source = is_scheduling_source; - config->period = pipeline->period; + config->period = dev->pipeline->period; host_elements_reset(hd, params->direction); @@ -923,10 +930,6 @@ int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, hd->copy = hd->copy_type == COMP_COPY_ONE_SHOT ? host_copy_one_shot : host_copy_normal; - /* set processing function */ - hd->process = pcm_get_conversion_function(host_buf_c->stream.frame_fmt, - host_buf_c->stream.frame_fmt); - out: buffer_release(host_buf_c); return err; @@ -947,8 +950,7 @@ static int host_params(struct comp_dev *dev, return err; } - err = host_zephyr_params(hd, dev, params, &dev->bsink_list, &dev->bsource_list, - dev->pipeline, dev->frames, dev == dev->pipeline->sched_comp); + err = host_zephyr_params(hd, dev, params); if (err >= 0) /* set up callback */ notifier_register(dev, hd->chan, NOTIFIER_ID_DMA_COPY, host_dma_cb, 0); diff --git a/src/include/sof/audio/host_copier.h b/src/include/sof/audio/host_copier.h index b277db44c..d05be07ec 100644 --- a/src/include/sof/audio/host_copier.h +++ b/src/include/sof/audio/host_copier.h @@ -104,9 +104,7 @@ void host_zephyr_reset(struct host_data *hd, uint16_t state); int host_zephyr_trigger(struct host_data *hd, struct comp_dev *dev, int cmd); int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, - struct sof_ipc_stream_params *params, struct list_item *sink_list, - struct list_item *source_list, struct pipeline *pipeline, - uint32_t frames, bool is_scheduling_source); + struct sof_ipc_stream_params *params); int host_zephyr_copy(struct host_data *hd, struct comp_dev *dev); @@ -136,10 +134,7 @@ static inline int host_zephyr_trigger(struct host_data *hd, struct comp_dev *dev } static inline int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, - struct sof_ipc_stream_params *params, - struct list_item *sink_list, - struct list_item *source_list, struct pipeline *pipeline, - uint32_t frames, bool is_scheduling_source) + struct sof_ipc_stream_params *params) { return 0; }