[Sound-open-firmware] [PATCH] dai: config: Use a generic structure for DAI configuration
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Use a generic structure containing common DAI settings for configuration. This structure also contains a tail of DAI specific data that can also be used by DAI drivers.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 31 +++++++-------- src/drivers/ssp.c | 52 ++++++++++++------------- src/include/reef/audio/component.h | 7 ++-- src/include/reef/dai.h | 16 ++------ src/include/reef/ipc.h | 2 +- src/include/reef/ssp.h | 1 + src/include/uapi/ipc.h | 77 ++++++++++++++++++++++++-------------- src/ipc/intel-ipc.c | 31 ++++++--------- src/ipc/ipc.c | 2 +- 9 files changed, 110 insertions(+), 109 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 4464398..c89103d 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -544,26 +544,23 @@ static int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn) return 0; }
-static int dai_config(struct comp_dev *dev, struct dai_config *dai_config) +static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) { - struct dai_data *dd = comp_get_drvdata(dev); - - switch (dai_config->type) { - case DAI_TYPE_INTEL_SSP: - switch (dai_config->ssp->frame_width) { - case 16: - dd->sample_width = 2; - break; - case 17 ... 32: - dd->sample_width = 4; - break; - default: - trace_dai_error("eft"); - return -EINVAL; - } + /* calc frame bytes */ + switch (config->sample_valid_bits) { + case 16: + dev->frame_bytes = 2 * config->num_slots; + break; + case 17 ... 32: + dev->frame_bytes = 4 * config->num_slots; break; default: - dd->sample_width = 2; + break; + } + + if (dev->frame_bytes == 0) { + trace_dai_error("de1"); + return -EINVAL; }
return 0; diff --git a/src/drivers/ssp.c b/src/drivers/ssp.c index 2146f83..1a1000a 100644 --- a/src/drivers/ssp.c +++ b/src/drivers/ssp.c @@ -65,12 +65,12 @@ static int ssp_context_restore(struct dai *dai) }
/* Digital Audio interface formatting */ -static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) +static inline int ssp_set_config(struct dai *dai, + struct sof_ipc_dai_config *config) { struct ssp_pdata *ssp = dai_get_drvdata(dai); - struct sof_ipc_dai_ssp_params *params = &ssp->params; uint32_t sscr0, sscr1, sspsp, sfifott, mdiv, bdiv; - uint32_t stop_size, phy_frame_size, data_size; + uint32_t stop_size, data_size; int ret = 0;
spin_lock(&ssp->lock); @@ -88,10 +88,15 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) sscr0 = 0; sscr1 = 0; sspsp = 0; - ssp->params = *dai_config->ssp; + + ssp->config = *config; + ssp->params = config->ssp[0]; + + /* TODO: allow topology to define SSP clock type */ + config->ssp[0].clk_id = SSP_CLK_EXT;
/* clock masters */ - switch (params->format & SOF_DAI_FMT_MASTER_MASK) { + switch (config->format & SOF_DAI_FMT_MASTER_MASK) { case SOF_DAI_FMT_CBM_CFM: sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR; break; @@ -112,7 +117,7 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) }
/* clock signal polarity */ - switch (params->format & SOF_DAI_FMT_INV_MASK) { + switch (config->format & SOF_DAI_FMT_INV_MASK) { case SOF_DAI_FMT_NB_NF: break; case SOF_DAI_FMT_NB_IF: @@ -129,7 +134,7 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) }
/* clock source */ - switch (params->clk_id) { + switch (config->ssp[0].clk_id) { case SSP_CLK_AUDIO: sscr0 |= SSCR0_ACS; break; @@ -148,14 +153,14 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) }
/* BCLK is generated from MCLK - must be divisable */ - if (params->mclk % params->bclk) { + if (config->mclk % config->bclk) { trace_ssp_error("ec1"); ret = -EINVAL; goto out; }
/* divisor must be within SCR range */ - mdiv = (params->mclk / params->bclk)- 1; + mdiv = (config->mclk / config->bclk)- 1; if (mdiv > (SSCR0_SCR_MASK >> 8)) { trace_ssp_error("ec2"); ret = -EINVAL; @@ -166,23 +171,22 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) sscr0 |= SSCR0_SCR(mdiv);
/* calc frame width based on BCLK and rate - must be divisable */ - if (params->bclk % params->fclk) { + if (config->bclk % config->fclk) { trace_ssp_error("ec3"); ret = -EINVAL; goto out; }
/* must be enouch BCLKs for data */ - bdiv = params->bclk / params->fclk; - if (bdiv < params->frame_width * params->num_slots) { + bdiv = config->bclk / config->fclk; + if (bdiv < config->sample_container_bits * config->num_slots) { trace_ssp_error("ec4"); ret = -EINVAL; goto out; }
- /* physical frame size must be <= 38 */ - phy_frame_size = bdiv / params->num_slots; - if (phy_frame_size > 38) { + /* sample_container_bits must be <= 38 for SSP */ + if (config->sample_container_bits > 38) { trace_ssp_error("ec5"); ret = -EINVAL; goto out; @@ -190,14 +194,14 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config)
trace_value(mdiv); trace_value(bdiv); - trace_value(phy_frame_size);
/* format */ - switch (params->format & SOF_DAI_FMT_FORMAT_MASK) { + switch (config->format & SOF_DAI_FMT_FORMAT_MASK) { case SOF_DAI_FMT_I2S:
/* calculate dummy stop size and include dummy start */ - stop_size = phy_frame_size - params->frame_width - 1; + stop_size = config->sample_container_bits - + (config->sample_valid_bits) - 1; trace_value(stop_size); if (stop_size > 3) { trace_ssp_error("ec6"); @@ -207,9 +211,9 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config)
sscr0 |= SSCR0_PSP; sscr1 |= SSCR1_TRAIL; - sspsp |= SSPSP_SFRMWDTH(phy_frame_size); + sspsp |= SSPSP_SFRMWDTH(config->sample_container_bits); /* subtract 1 for I2S start delay */ - sspsp |= SSPSP_SFRMDLY((phy_frame_size - 1) * 2); + sspsp |= SSPSP_SFRMDLY((config->sample_container_bits - 1) * 2); sspsp |= SSPSP_DMYSTRT(1); sspsp |= SSPSP_DMYSTOP(stop_size); break; @@ -225,16 +229,12 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) }
/* sample data size on SSP FIFO */ - switch (params->frame_width) { + switch (config->sample_valid_bits) { case 16: /* 2 * 16bit packed into 32bit FIFO */ - case 24: /* 1 * 24bit in 32bit FIFO (8 MSBs not used) */ - case 32: /* 1 * 32bit packed into 32bit FIFO */ data_size = 32; break; default: - trace_ssp_error("ec7"); - ret = -EINVAL; - goto out; + data_size = config->sample_valid_bits; }
if (data_size > 16) diff --git a/src/include/reef/audio/component.h b/src/include/reef/audio/component.h index a74395c..260fbda 100644 --- a/src/include/reef/audio/component.h +++ b/src/include/reef/audio/component.h @@ -122,7 +122,8 @@ struct comp_ops { int (*preload)(struct comp_dev *dev);
/* set component audio stream paramters */ - int (*dai_config)(struct comp_dev *dev, struct dai_config *dai_config); + int (*dai_config)(struct comp_dev *dev, + struct sof_ipc_dai_config *dai_config);
/* used to pass standard and bespoke commands (with data) to component */ int (*cmd)(struct comp_dev *dev, int cmd, void *data); @@ -261,10 +262,10 @@ static inline int comp_reset(struct comp_dev *dev)
/* DAI configuration - only mandatory for DAI components */ static inline int comp_dai_config(struct comp_dev *dev, - struct dai_config *dai_config) + struct sof_ipc_dai_config *config) { if (dev->drv->ops.dai_config) - return dev->drv->ops.dai_config(dev, dai_config); + return dev->drv->ops.dai_config(dev, config); return 0; }
diff --git a/src/include/reef/dai.h b/src/include/reef/dai.h index 258b016..75eabce 100644 --- a/src/include/reef/dai.h +++ b/src/include/reef/dai.h @@ -58,7 +58,7 @@ struct dai;
/* DAI operations - all optional */ struct dai_ops { - int (*set_config)(struct dai *dai, struct dai_config *dai_config); + int (*set_config)(struct dai *dai, struct sof_ipc_dai_config *config); int (*trigger)(struct dai *dai, int cmd, int direction); int (*pm_context_restore)(struct dai *dai); int (*pm_context_store)(struct dai *dai); @@ -78,15 +78,6 @@ enum dai_type { DAI_TYPE_INTEL_DMIC, };
-/* DAI runtime hardware configuration */ -struct dai_config { - enum dai_type type; - union { - struct sof_ipc_dai_ssp_params *ssp; - struct sof_ipc_dai_hda_params *hda; - struct sof_ipc_dai_dmic_params *dmic; - }; -};
struct dai_plat_fifo_data { uint32_t offset; @@ -126,9 +117,10 @@ struct dai *dai_get(uint32_t type, uint32_t index); dai->plat_data.fifo[direction].offset
/* Digital Audio interface formatting */ -static inline int dai_set_config(struct dai *dai, struct dai_config *dai_config) +static inline int dai_set_config(struct dai *dai, + struct sof_ipc_dai_config *config) { - return dai->ops->set_config(dai, dai_config); + return dai->ops->set_config(dai, config); }
/* Digital Audio interface formatting */ diff --git a/src/include/reef/ipc.h b/src/include/reef/ipc.h index 96f2924..253f4f4 100644 --- a/src/include/reef/ipc.h +++ b/src/include/reef/ipc.h @@ -157,6 +157,6 @@ struct ipc_comp_dev *ipc_get_comp(struct ipc *ipc, uint32_t id); /* * Configure all DAI components attached to DAI. */ -int ipc_comp_dai_config(struct ipc *ipc, struct dai_config *config); +int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config);
#endif diff --git a/src/include/reef/ssp.h b/src/include/reef/ssp.h index 77d7b2e..7e557ed 100644 --- a/src/include/reef/ssp.h +++ b/src/include/reef/ssp.h @@ -153,6 +153,7 @@ struct ssp_pdata { spinlock_t lock; uint32_t state[2]; /* SSP_STATE_ for each direction */ completion_t drain_complete; + struct sof_ipc_dai_config config; struct sof_ipc_dai_ssp_params params; };
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index 19ee898..ddca551 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -99,10 +99,8 @@ #define SOF_IPC_COMP_GET_SRC SOF_CMD_TYPE(0x007)
/* DAI messages */ -#define SOF_IPC_COMP_SSP_CONFIG SOF_CMD_TYPE(0x000) -#define SOF_IPC_COMP_HDA_CONFIG SOF_CMD_TYPE(0x001) -#define SOF_IPC_COMP_DMIC_CONFIG SOF_CMD_TYPE(0x002) -#define SOF_IPC_COMP_LOOPBACK SOF_CMD_TYPE(0x003) +#define SOF_IPC_DAI_CONFIG SOF_CMD_TYPE(0x001) +#define SOF_IPC_DAI_LOOPBACK SOF_CMD_TYPE(0x002)
/* stream */ #define SOF_IPC_STREAM_PCM_PARAMS SOF_CMD_TYPE(0x001) @@ -193,37 +191,68 @@ struct sof_ipc_compound_hdr { #define SOF_DAI_FMT_INV_MASK 0x0f00 #define SOF_DAI_FMT_MASTER_MASK 0xf000
+/* types of DAI */ +enum sof_ipc_dai_type { + SOF_DAI_INTEL_NONE = 0, + SOF_DAI_INTEL_SSP, + SOF_DAI_INTEL_DMIC, + SOF_DAI_INTEL_HDA, +}; + /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */ struct sof_ipc_dai_ssp_params { struct sof_ipc_hdr hdr; - uint32_t mclk; - uint32_t bclk; - uint32_t fclk; - uint16_t ssp_id; uint16_t mode; - uint16_t num_slots; - uint16_t frame_width; uint16_t clk_id; - uint16_t format; /* SOF_DAI_FMT_ */ - uint16_t mclk_master; } __attribute__((packed));
/* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ struct sof_ipc_dai_hda_params { struct sof_ipc_hdr hdr; - uint32_t hda_id; - uint32_t mclk; /* TODO */ } __attribute__((packed));
/* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */ struct sof_ipc_dai_dmic_params { struct sof_ipc_hdr hdr; - uint32_t dmic_id; - uint32_t mclk; /* TODO */ } __attribute__((packed));
+ +/* general purpose DAI configuration */ +struct sof_ipc_dai_config { + struct sof_ipc_hdr hdr; + enum sof_ipc_dai_type type; + uint32_t id; /* physical number if more than 1 of this type */ + + /* physical protocol and clocking */ + uint16_t format; /* SOF_DAI_FMT_ */ + uint16_t reserved; /* alignment */ + uint32_t mclk; /* mclk frequency in Hz */ + uint32_t bclk; /* bclk frequency in Hz */ + uint32_t fclk; /* cclk frequency in Hz */ + + /* TDM */ + uint32_t num_slots; + uint32_t rx_slot_mask; + uint32_t tx_slot_mask; + + /* data */ + uint16_t sample_valid_bits; + uint16_t sample_container_bits; + + /* MCLK */ + uint16_t mclk_always_run; + uint16_t mclk_master; + + /* HW specific data */ + union { + struct sof_ipc_dai_ssp_params ssp[0]; + struct sof_ipc_dai_hda_params hda[0]; + struct sof_ipc_dai_dmic_params dmic[0]; + }; +}; + /* * Stream configuration. */ @@ -325,9 +354,11 @@ struct sof_ipc_stream_params { enum sof_ipc_buffer_format buffer_fmt; uint32_t rate; uint32_t channels; - uint32_t sample_size; + uint32_t sample_valid_bytes; + uint32_t sample_container_bytes; /* for notifying host period has completed - 0 means no period IRQ */ uint32_t host_period_bytes; + enum sof_ipc_chmap chmap[SOF_IPC_MAX_CHANNELS]; /* channel map */ } __attribute__((packed));
/* PCM params info - SOF_IPC_STREAM_PCM_PARAMS */ @@ -454,25 +485,13 @@ struct sof_ipc_buffer { uint32_t size; /* buffer size in bytes */ } __attribute__((packed));
-/* types of DAI */ -enum sof_ipc_dai_type { - SOF_DAI_INTEL_NONE = 0, - SOF_DAI_INTEL_SSP, - SOF_DAI_INTEL_DMIC, - SOF_DAI_INTEL_HDA, -};
/* generic component config data */ struct sof_ipc_comp_config { - uint32_t format; /* data format */ - uint32_t frames; /* number of frames to process, 0 is variable */ - uint32_t channels; /* max number of channels */ - uint32_t frame_size; /* sample size in bytes */ uint32_t periods_sink; /* 0 means variable */ uint32_t periods_source; /* 0 means variable */ uint32_t preload_count; /* how many periods to preload */ enum sof_ipc_frame frame_fmt; - enum sof_ipc_chmap chmap[SOF_IPC_MAX_CHANNELS]; /* channel map */ } __attribute__((packed));
/* generic host component */ diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 2d73fbb..81b30b5 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -400,39 +400,32 @@ static int ipc_glb_stream_message(uint32_t header) * DAI IPC Operations. */
-static int ipc_dai_ssp_config(uint32_t header) +static int ipc_dai_config(uint32_t header) { - struct sof_ipc_dai_ssp_params *ssp = _ipc->comp_data; - struct dai_config dai_config; + struct sof_ipc_dai_config *config = _ipc->comp_data; struct dai *dai; int ret;
trace_ipc("DsF");
- /* TODO: set type in topology */ - dai_config.type = DAI_TYPE_INTEL_SSP; - dai_config.ssp = ssp; - - /* TODO: allow topology to define SSP clock type */ - dai_config.ssp->clk_id = SSP_CLK_EXT; - /* get DAI */ - dai = dai_get(SOF_DAI_INTEL_SSP, ssp->ssp_id); + dai = dai_get(config->type, config->id); if (dai == NULL) { trace_ipc_error("eDi"); - trace_value(ssp->ssp_id); + trace_value(config->type); + trace_value(config->id); return -ENODEV; }
/* configure DAI */ - ret = dai_set_config(dai, &dai_config); + ret = dai_set_config(dai, config); if (ret < 0) { trace_ipc_error("eDC"); return ret; }
- /* now send params to all components who use that DAI */ - return ipc_comp_dai_config(_ipc, &dai_config); + /* now send params to all DAI components who use that physical DAI */ + return ipc_comp_dai_config(_ipc, config); }
static int ipc_glb_dai_message(uint32_t header) @@ -440,12 +433,10 @@ static int ipc_glb_dai_message(uint32_t header) uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;
switch (cmd) { - case iCS(SOF_IPC_COMP_SSP_CONFIG): - return ipc_dai_ssp_config(header); - case iCS(SOF_IPC_COMP_LOOPBACK): + case iCS(SOF_IPC_DAI_CONFIG): + return ipc_dai_config(header); + case iCS(SOF_IPC_DAI_LOOPBACK): //return ipc_comp_set_value(header, COMP_CMD_LOOPBACK); - case iCS(SOF_IPC_COMP_HDA_CONFIG): - case iCS(SOF_IPC_COMP_DMIC_CONFIG): default: trace_ipc_error("eDc"); trace_value(header); diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 530fee9..323468b 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -307,7 +307,7 @@ void ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) pipeline_complete(ipc_pipe->pipeline); }
-int ipc_comp_dai_config(struct ipc *ipc, struct dai_config *config) +int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config) { struct ipc_comp_dev *icd; struct list_item *clist;
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Remove the unused pointer to host parameters in params(). This was only useful to the host component. Provide some component frame configuration variables to give more flaxability than host params.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 21 ++++++---------- src/audio/eq_fir.c | 12 ++++------ src/audio/eq_iir.c | 12 ++++------ src/audio/host.c | 25 +++++++++---------- src/audio/mixer.c | 17 ++++--------- src/audio/mux.c | 2 +- src/audio/pipeline.c | 11 ++++----- src/audio/src.c | 21 +++++++--------- src/audio/switch.c | 2 +- src/audio/tone.c | 12 ++++------ src/audio/volume.c | 49 ++++++++++++++++++++++---------------- src/include/reef/audio/component.h | 28 +++++++++++++++++----- src/include/reef/audio/pipeline.h | 2 +- src/ipc/intel-ipc.c | 13 ++++++---- 14 files changed, 111 insertions(+), 116 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index c89103d..bacb0d9 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -62,7 +62,6 @@ struct dai_data { struct dai *dai; struct dma *dma; uint32_t period_bytes; - uint32_t sample_width;
uint32_t last_bytes; /* the last bytes(<period size) it copies. */ uint32_t dai_pos_blks; /* position in bytes (nearest block) */ @@ -228,8 +227,7 @@ static void dai_free(struct comp_dev *dev) }
/* set component audio SSP and DMA configuration */ -static int dai_playback_params(struct comp_dev *dev, - struct stream_params *params) +static int dai_playback_params(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); struct dma_sg_config *config = &dd->config; @@ -293,8 +291,7 @@ err_unwind: return -ENOMEM; }
-static int dai_capture_params(struct comp_dev *dev, - struct stream_params *params) +static int dai_capture_params(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); struct dma_sg_config *config = &dd->config; @@ -356,12 +353,10 @@ err_unwind: return -ENOMEM; }
-static int dai_params(struct comp_dev *dev, - struct stream_params *host_params) +static int dai_params(struct comp_dev *dev) { struct dai_data *dd = comp_get_drvdata(dev); struct comp_buffer *dma_buffer; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_dai("par");
@@ -371,24 +366,22 @@ static int dai_params(struct comp_dev *dev, return -EINVAL; }
- comp_install_params(dev, host_params); - /* calculate period size based on config */ - config->frame_size = dd->sample_width * dev->params.channels; - dd->period_bytes = config->frames * config->frame_size; + dev->frame_bytes = comp_frame_bytes(dev); + dd->period_bytes = dev->frames * dev->frame_bytes;
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) { dma_buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); dma_buffer->r_ptr = dma_buffer->addr;
- return dai_playback_params(dev, host_params); + return dai_playback_params(dev); } else { dma_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); dma_buffer->w_ptr = dma_buffer->addr;
- return dai_capture_params(dev, host_params); + return dai_capture_params(dev); } }
diff --git a/src/audio/eq_fir.c b/src/audio/eq_fir.c index 9532b63..534a4a1 100644 --- a/src/audio/eq_fir.c +++ b/src/audio/eq_fir.c @@ -282,18 +282,15 @@ static void eq_fir_free(struct comp_dev *dev) }
/* set component audio stream parameters */ -static int eq_fir_params(struct comp_dev *dev, - struct stream_params *host_params) +static int eq_fir_params(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_src("par");
- comp_install_params(dev, host_params); - /* calculate period size based on config */ - cd->period_bytes = config->frames * config->frame_size; + cd->period_bytes = dev->frames * dev->frame_bytes;
/* EQ supports only S32_LE PCM format */ if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) @@ -401,7 +398,6 @@ static int eq_fir_cmd(struct comp_dev *dev, int cmd, void *data) static int eq_fir_copy(struct comp_dev *dev) { struct comp_data *sd = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct comp_buffer *source, *sink; uint32_t copy_bytes;
@@ -422,13 +418,13 @@ static int eq_fir_copy(struct comp_dev *dev) if (copy_bytes < sd->period_bytes) return 0;
- sd->eq_fir_func(dev, source, sink, config->frames); + sd->eq_fir_func(dev, source, sink, dev->frames);
/* calc new free and available */ comp_update_buffer_consume(source, copy_bytes); comp_update_buffer_produce(sink, copy_bytes);
- return config->frames; + return dev->frames; }
static int eq_fir_prepare(struct comp_dev *dev) diff --git a/src/audio/eq_iir.c b/src/audio/eq_iir.c index e819903..0ac2ef9 100644 --- a/src/audio/eq_iir.c +++ b/src/audio/eq_iir.c @@ -286,18 +286,15 @@ static void eq_iir_free(struct comp_dev *dev) }
/* set component audio stream parameters */ -static int eq_iir_params(struct comp_dev *dev, - struct stream_params *host_params) +static int eq_iir_params(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_eq_iir("par");
- comp_install_params(dev, host_params); - /* calculate period size based on config */ - cd->period_bytes = config->frames * config->frame_size; + cd->period_bytes = dev->frames * dev->frame_bytes;
/* EQ supports only S32_LE PCM format */ if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) @@ -411,7 +408,6 @@ static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data) static int eq_iir_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct comp_buffer *source, *sink; uint32_t copy_bytes;
@@ -432,13 +428,13 @@ static int eq_iir_copy(struct comp_dev *dev) if (copy_bytes < cd->period_bytes) return 0;
- cd->eq_iir_func(dev, source, sink, config->frames); + cd->eq_iir_func(dev, source, sink, dev->frames);
/* calc new free and available */ comp_update_buffer_consume(source, copy_bytes); comp_update_buffer_produce(sink, copy_bytes);
- return config->frames; + return dev->frames; }
static int eq_iir_prepare(struct comp_dev *dev) diff --git a/src/audio/host.c b/src/audio/host.c index 27b5418..c95a957 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -304,8 +304,7 @@ static void host_free(struct comp_dev *dev) rfree(dev); }
-static int create_local_elems(struct comp_dev *dev, - struct stream_params *params) +static int create_local_elems(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); struct dma_sg_elem *e; @@ -320,13 +319,13 @@ static int create_local_elems(struct comp_dev *dev,
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) e->dest = (uint32_t)(hd->dma_buffer->addr) + - i * hd->period_bytes; + i * hd->period_bytes; else e->src = (uint32_t)(hd->dma_buffer->addr) + - i * hd->period_bytes; + i * hd->period_bytes;
e->size = hd->period_bytes; -; + list_item_append(&e->list, &hd->local.elem_list); }
@@ -371,12 +370,12 @@ static int host_elements_reset(struct comp_dev *dev) }
/* configure the DMA params and descriptors for host buffer IO */ -static int host_params(struct comp_dev *dev, struct stream_params *params) +static int host_params(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); struct sof_ipc_comp_config *cconfig = COMP_GET_CONFIG(dev); struct dma_sg_config *config = &hd->config; - uint32_t buffer_size ; + uint32_t buffer_size; int err;
trace_host("par"); @@ -405,8 +404,11 @@ static int host_params(struct comp_dev *dev, struct stream_params *params) }
/* calculate period size based on config */ - hd->period_bytes = cconfig->frames * dev->params.sample_size * - dev->params.channels; + hd->period_bytes = dev->frames * comp_frame_bytes(dev); + if (hd->period_bytes == 0) { + trace_host_error("eS1"); + return -EINVAL; + }
/* resize the buffer if space is available to align with period size */ buffer_size = hd->period_count * hd->period_bytes; @@ -426,7 +428,7 @@ static int host_params(struct comp_dev *dev, struct stream_params *params) }
/* create SG DMA elems for local DMA buffer */ - err = create_local_elems(dev, params); + err = create_local_elems(dev); if (err < 0) return err;
@@ -634,7 +636,6 @@ static int host_reset(struct comp_dev *dev) static int host_copy(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
tracev_host("cpy");
@@ -645,7 +646,7 @@ static int host_copy(struct comp_dev *dev) dma_set_config(hd->dma, hd->chan, &hd->config); dma_start(hd->dma, hd->chan);
- return config->frames; + return dev->frames; }
struct comp_driver comp_host = { diff --git a/src/audio/mixer.c b/src/audio/mixer.c index 74c0ffb..372d59f 100644 --- a/src/audio/mixer.c +++ b/src/audio/mixer.c @@ -121,22 +121,14 @@ static void mixer_free(struct comp_dev *dev) }
/* set component audio stream parameters */ -static int mixer_params(struct comp_dev *dev, - struct stream_params *host_params) +static int mixer_params(struct comp_dev *dev) { struct mixer_data *md = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_mixer("par");
- /* dont do any params downstream setting for running mixer stream */ - if (dev->state == COMP_STATE_RUNNING) - return 1; - - comp_install_params(dev, host_params); - /* calculate period size based on config */ - md->period_bytes = config->frames * config->frame_size; + md->period_bytes = dev->frames * dev->frame_bytes;
return 0; } @@ -199,7 +191,6 @@ static int mixer_copy(struct comp_dev *dev) { struct mixer_data *md = comp_get_drvdata(dev); struct comp_buffer *sink, *sources[PLATFORM_MAX_STREAMS], *source; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct list_item *blist; int32_t i = 0, num_mix_sources = 0;
@@ -236,7 +227,7 @@ static int mixer_copy(struct comp_dev *dev) }
/* mix streams */ - md->mix_func(dev, sink, sources, i, config->frames); + md->mix_func(dev, sink, sources, i, dev->frames);
/* update source buffer pointers for overflow */ for (i = --num_mix_sources; i >= 0; i--) @@ -246,7 +237,7 @@ static int mixer_copy(struct comp_dev *dev) comp_update_buffer_produce(sink, md->period_bytes);
/* number of frames sent downstream */ - return config->frames; + return dev->frames; }
static int mixer_reset(struct comp_dev *dev) diff --git a/src/audio/mux.c b/src/audio/mux.c index 63e3035..f420bd3 100644 --- a/src/audio/mux.c +++ b/src/audio/mux.c @@ -53,7 +53,7 @@ static void mux_free(struct comp_dev *dev) }
/* set component audio stream paramters */ -static int mux_params(struct comp_dev *dev, struct stream_params *params) +static int mux_params(struct comp_dev *dev) {
return 0; diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 817ff08..3bc1f68 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -65,13 +65,12 @@ static void connect_upstream(struct pipeline *p, struct comp_dev *start, struct comp_dev *current) { struct list_item *clist; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(current);
tracev_value(current->comp.id);
/* complete component init */ current->pipeline = p; - config->frames = p->ipc_pipe.frames_per_sched; + current->frames = p->ipc_pipe.frames_per_sched;
/* we are an endpoint if we have 0 source components */ if (list_is_empty(¤t->bsource_list)) { @@ -98,13 +97,12 @@ static void connect_downstream(struct pipeline *p, struct comp_dev *start, struct comp_dev *current) { struct list_item *clist; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(current);
tracev_value(current->comp.id);
/* complete component init */ current->pipeline = p; - config->frames = p->ipc_pipe.frames_per_sched; + current->frames = p->ipc_pipe.frames_per_sched;
/* we are an endpoint if we have 0 sink components */ if (list_is_empty(¤t->bsink_list)) { @@ -547,7 +545,7 @@ int pipeline_cmd(struct pipeline *p, struct comp_dev *host, int cmd, * Params are always modified in the direction of host PCM to DAI. */ int pipeline_params(struct pipeline *p, struct comp_dev *host, - struct stream_params *params) + struct sof_ipc_pcm_params *params) { struct op_data op_data; int ret; @@ -556,10 +554,11 @@ int pipeline_params(struct pipeline *p, struct comp_dev *host,
op_data.p = p; op_data.op = COMP_OPS_PARAMS; - op_data.params = params;
spin_lock(&p->lock);
+ host->params = params->params; + if (host->params.direction == SOF_IPC_STREAM_PLAYBACK) { /* send params downstream from host to DAI */ ret = component_op_downstream(&op_data, host, host); diff --git a/src/audio/src.c b/src/audio/src.c index 1b5d1c9..074c041 100644 --- a/src/audio/src.c +++ b/src/audio/src.c @@ -298,7 +298,7 @@ static void src_free(struct comp_dev *dev) }
/* set component audio stream parameters */ -static int src_params(struct comp_dev *dev, struct stream_params *host_params) +static int src_params(struct comp_dev *dev) { struct sof_ipc_stream_params *params = &dev->params; struct sof_ipc_comp_src *src = COMP_GET_IPC(dev, sof_ipc_comp_src); @@ -312,8 +312,6 @@ static int src_params(struct comp_dev *dev, struct stream_params *host_params)
trace_src("par");
- comp_install_params(dev, host_params); - /* EQ supports only S32_LE PCM format */ if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) return -EINVAL; @@ -377,10 +375,10 @@ static int src_params(struct comp_dev *dev, struct stream_params *host_params) /* Check that src blk_in and blk_out are less than params.period_frames. * Return an error if the period is too short. */ - if (src_polyphase_get_blk_in(&cd->src[0]) > config->frames) + if (src_polyphase_get_blk_in(&cd->src[0]) > dev->frames) return -EINVAL;
- if (src_polyphase_get_blk_out(&cd->src[0]) > config->frames) + if (src_polyphase_get_blk_out(&cd->src[0]) > dev->frames) return -EINVAL;
return 0; @@ -449,7 +447,6 @@ static int src_cmd(struct comp_dev *dev, int cmd, void *data) static int src_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct comp_buffer *source; struct comp_buffer *sink; uint32_t frames_source; @@ -467,23 +464,23 @@ static int src_copy(struct comp_dev *dev) /* Check that source has enough frames available and sink enough * frames free. */ - frames_source = config->frames; - frames_sink = config->frames; + frames_source = dev->frames; + frames_sink = dev->frames;
min_frames = src_polyphase_get_blk_in(&cd->src[0]); if (frames_source > min_frames) - need_source = frames_source * config->frame_size; + need_source = frames_source * dev->frame_bytes; else { frames_source = min_frames; - need_source = min_frames * config->frame_size; + need_source = min_frames * dev->frame_bytes; }
min_frames = src_polyphase_get_blk_out(&cd->src[0]); if (frames_sink > min_frames) - need_sink = frames_sink * config->frame_size; + need_sink = frames_sink * dev->frame_bytes; else { frames_sink = min_frames; - need_sink = min_frames * config->frame_size; + need_sink = min_frames * dev->frame_bytes; }
/* Run as many times as buffers allow */ diff --git a/src/audio/switch.c b/src/audio/switch.c index 63a0d68..7149b61 100644 --- a/src/audio/switch.c +++ b/src/audio/switch.c @@ -53,7 +53,7 @@ static void switch_free(struct comp_dev *dev) }
/* set component audio stream paramters */ -static int switch_params(struct comp_dev *dev, struct stream_params *params) +static int switch_params(struct comp_dev *dev) {
return 0; diff --git a/src/audio/tone.c b/src/audio/tone.c index 11f63dc..777846b 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -403,18 +403,15 @@ static void tone_free(struct comp_dev *dev) }
/* set component audio stream parameters */ -static int tone_params(struct comp_dev *dev, struct stream_params *host_params) +static int tone_params(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct sof_ipc_stream_params *params = &dev->params; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_tone("par");
- comp_install_params(dev, host_params); - /* calculate period size based on config */ - cd->period_bytes = config->frames * config->frame_size; + cd->period_bytes = dev->frames * dev->frame_bytes;
/* EQ supports only S32_LE PCM format */ if (params->frame_fmt != SOF_IPC_FRAME_S32_LE) @@ -489,7 +486,6 @@ static int tone_copy(struct comp_dev *dev) struct comp_buffer *sink; struct comp_buffer *source = NULL; struct comp_data *cd = comp_get_drvdata(dev); - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
trace_comp("cpy");
@@ -502,12 +498,12 @@ static int tone_copy(struct comp_dev *dev) */ if (sink->free >= cd->period_bytes) { /* create tone */ - cd->tone_func(dev, sink, source, config->frames); + cd->tone_func(dev, sink, source, dev->frames); }
comp_update_buffer_produce(sink, cd->period_bytes);
- return config->frames; + return dev->frames; }
static int tone_prepare(struct comp_dev *dev) diff --git a/src/audio/volume.c b/src/audio/volume.c index 33ac07d..c770e70 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -370,14 +370,13 @@ static void volume_free(struct comp_dev *dev) }
/* - * Set volume component audio stream paramters. + * Set volume component audio stream paramters - All done in prepare() since + * wee need to know source and sink component params. */ -static int volume_params(struct comp_dev *dev, struct stream_params *host_params) +static int volume_params(struct comp_dev *dev) { trace_volume("par");
- comp_install_params(dev, host_params); - return 0; }
@@ -480,7 +479,6 @@ static int volume_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sink, *source; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); uint32_t copy_bytes;
tracev_volume("cpy"); @@ -505,13 +503,13 @@ static int volume_copy(struct comp_dev *dev) }
/* copy and scale volume */ - cd->scale_vol(dev, sink, source, config->frames); + cd->scale_vol(dev, sink, source, dev->frames);
/* calc new free and available */ comp_update_buffer_produce(sink, cd->sink_period_bytes); comp_update_buffer_consume(source, cd->source_period_bytes);
- return config->frames; + return dev->frames; }
/* @@ -522,7 +520,6 @@ static int volume_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sinkb, *sourceb; - struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct sof_ipc_comp_config *sconfig; int i;
@@ -533,14 +530,13 @@ static int volume_prepare(struct comp_dev *dev) sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
/* get source data format */ - switch (sourceb->source->comp.id) { + switch (sourceb->source->comp.type) { case SOF_COMP_HOST: case SOF_COMP_SG_HOST: - /* source format come from IPC params */ + /* source format comes from IPC params */ cd->source_format = sourceb->source->params.frame_fmt; - cd->source_period_bytes = config->frames * - sourceb->source->params.channels * - sourceb->source->params.sample_size; + cd->source_period_bytes = dev->frames * + comp_frame_bytes(sourceb->source); break; case SOF_COMP_DAI: case SOF_COMP_SG_DAI: @@ -548,20 +544,19 @@ static int volume_prepare(struct comp_dev *dev) /* source format comes from DAI/comp config */ sconfig = COMP_GET_CONFIG(sourceb->source); cd->source_format = sconfig->frame_fmt; - cd->source_period_bytes = config->frames * - sconfig->channels * sconfig->frame_size; + cd->source_period_bytes = dev->frames * + sourceb->source->frame_bytes; break; }
/* get sink data format */ - switch (sinkb->sink->comp.id) { + switch (sinkb->sink->comp.type) { case SOF_COMP_HOST: case SOF_COMP_SG_HOST: /* sink format come from IPC params */ cd->sink_format = sinkb->sink->params.frame_fmt; - cd->sink_period_bytes = config->frames * - sinkb->sink->params.channels * - sinkb->sink->params.sample_size; + cd->sink_period_bytes = dev->frames * + comp_frame_bytes(sinkb->sink); break; case SOF_COMP_DAI: case SOF_COMP_SG_DAI: @@ -569,11 +564,23 @@ static int volume_prepare(struct comp_dev *dev) /* sink format comes from DAI/comp config */ sconfig = COMP_GET_CONFIG(sinkb->sink); cd->sink_format = sconfig->frame_fmt; - cd->sink_period_bytes = config->frames * - sconfig->channels * sconfig->frame_size; + cd->sink_period_bytes = dev->frames * + sinkb->sink->frame_bytes; break; }
+ dev->frame_bytes = cd->sink_period_bytes; + + /* validate */ + if (cd->sink_period_bytes == 0) { + trace_volume_error("vp1"); + return -EINVAL; + } + if (cd->source_period_bytes == 0) { + trace_volume_error("vp2"); + return -EINVAL; + } + /* map the volume function for source and sink buffers */ for (i = 0; i < ARRAY_SIZE(func_map); i++) {
diff --git a/src/include/reef/audio/component.h b/src/include/reef/audio/component.h index 260fbda..a8db2ec 100644 --- a/src/include/reef/audio/component.h +++ b/src/include/reef/audio/component.h @@ -116,7 +116,7 @@ struct comp_ops { void (*free)(struct comp_dev *dev);
/* set component audio stream paramters */ - int (*params)(struct comp_dev *dev, struct stream_params *host_params); + int (*params)(struct comp_dev *dev);
/* preload buffers */ int (*preload)(struct comp_dev *dev); @@ -165,6 +165,8 @@ struct comp_dev { uint16_t is_endpoint; /* component is end point in pipeline */ spinlock_t lock; /* lock for this component */ uint64_t position; /* component rendering position */ + uint32_t frames; /* number of frames we copy to sink */ + uint32_t frame_bytes; /* frames size copied to sink in bytes */ struct pipeline *pipeline; /* pipeline we belong to */
/* common runtime configuration for downstream/upstream */ @@ -213,10 +215,9 @@ static inline void comp_free(struct comp_dev *dev) }
/* component parameter init - mandatory */ -static inline int comp_params(struct comp_dev *dev, - struct stream_params *params) +static inline int comp_params(struct comp_dev *dev) { - return dev->drv->ops.params(dev, params); + return dev->drv->ops.params(dev); }
/* component host buffer config @@ -325,11 +326,11 @@ static inline int comp_buffer_reset(struct comp_dev *dev) * playback and upstream on capture. */ static inline void comp_install_params(struct comp_dev *dev, - struct stream_params *host_params) + enum sof_ipc_stream_direction direction) { struct comp_buffer *buffer;
- if (host_params->pcm->params.direction == SOF_IPC_STREAM_PLAYBACK) { + if (direction == SOF_IPC_STREAM_PLAYBACK) { buffer = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); dev->params = buffer->source->params; @@ -340,4 +341,19 @@ static inline void comp_install_params(struct comp_dev *dev, } }
+static inline uint32_t comp_frame_bytes(struct comp_dev *dev) +{ + /* calculate period size based on params */ + switch (dev->params.frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + return 2 * dev->params.channels; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S32_LE: + case SOF_IPC_FRAME_FLOAT: + return 4 * dev->params.channels; + default: + return 0; + } +} + #endif diff --git a/src/include/reef/audio/pipeline.h b/src/include/reef/audio/pipeline.h index ca1947a..17e8a34 100644 --- a/src/include/reef/audio/pipeline.h +++ b/src/include/reef/audio/pipeline.h @@ -87,7 +87,7 @@ void pipeline_complete(struct pipeline *p);
/* pipeline parameters */ int pipeline_params(struct pipeline *p, struct comp_dev *cd, - struct stream_params *params); + struct sof_ipc_pcm_params *params);
/* prepare the pipeline for usage */ int pipeline_prepare(struct pipeline *p, struct comp_dev *cd); diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 81b30b5..bd3b21d 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -200,16 +200,12 @@ static int ipc_stream_pcm_params(uint32_t stream) { struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc); struct sof_ipc_pcm_params *pcm_params = _ipc->comp_data; - struct stream_params params; struct ipc_comp_dev *pcm_dev; struct comp_dev *cd; int err;
trace_ipc("SAl");
- params.type = STREAM_TYPE_PCM; - params.pcm = pcm_params; - /* get the pcm_dev */ pcm_dev = ipc_get_comp(_ipc, pcm_params->comp_id); if (pcm_dev == NULL) { @@ -218,6 +214,13 @@ static int ipc_stream_pcm_params(uint32_t stream) return -EINVAL; }
+ /* sanity check comp */ + if (pcm_dev->cd->pipeline == NULL) { + trace_ipc_error("eA1"); + trace_value(pcm_params->comp_id); + return -EINVAL; + } + /* set params component params */ cd = pcm_dev->cd; cd->params = pcm_params->params; @@ -238,7 +241,7 @@ static int ipc_stream_pcm_params(uint32_t stream) }
/* configure pipeline audio params */ - err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, ¶ms); + err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params); if (err < 0) { trace_ipc_error("eAa"); goto error;
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Make sure we return an error or 0 after component creation.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/ipc/intel-ipc.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index bd3b21d..681bf64 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -622,11 +622,15 @@ static int ipc_glb_tplg_comp_new(uint32_t header) /* register component */ ret = ipc_comp_new(_ipc, comp); if (ret < 0) { - trace_ipc_error("etc"); + trace_ipc_error("cn1"); return ret; }
/* write component values to the outbox */ + reply.rhdr.hdr.size = sizeof(reply); + reply.rhdr.hdr.cmd = header; + reply.rhdr.error = 0; + reply.offset = 0; /* TODO: set this up for mmaped components */ mailbox_outbox_write(0, &reply, sizeof(reply)); return 0; } @@ -634,19 +638,47 @@ static int ipc_glb_tplg_comp_new(uint32_t header) static int ipc_glb_tplg_buffer_new(uint32_t header) { struct sof_ipc_buffer *ipc_buffer = _ipc->comp_data; + struct sof_ipc_comp_reply reply; + int ret;
trace_ipc("Ibn");
- return ipc_buffer_new(_ipc, ipc_buffer); + ret = ipc_buffer_new(_ipc, ipc_buffer); + if (ret < 0) { + trace_ipc_error("bn1"); + return ret; + } + + /* write component values to the outbox */ + reply.rhdr.hdr.size = sizeof(reply); + reply.rhdr.hdr.cmd = header; + reply.rhdr.error = 0; + reply.offset = 0; /* TODO: set this up for mmaped components */ + mailbox_outbox_write(0, &reply, sizeof(reply)); + return 0; }
static int ipc_glb_tplg_pipe_new(uint32_t header) { struct sof_ipc_pipe_new *ipc_pipeline = _ipc->comp_data; + struct sof_ipc_comp_reply reply; + int ret;
trace_ipc("Ipn");
- return ipc_pipeline_new(_ipc, ipc_pipeline); + ret = ipc_pipeline_new(_ipc, ipc_pipeline); + if (ret < 0) { + trace_ipc_error("pn1"); + return ret; + } + + /* write component values to the outbox */ + reply.rhdr.hdr.size = sizeof(reply); + reply.rhdr.hdr.cmd = header; + reply.rhdr.error = 0; + reply.offset = 0; /* TODO: set this up for mmaped components */ + mailbox_outbox_write(0, &reply, sizeof(reply)); + return 0; }
static int ipc_glb_tplg_pipe_complete(uint32_t header)
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Position was being calculated in twice in the copy funcs.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/volume.c | 24 ------------------------ 1 file changed, 24 deletions(-)
diff --git a/src/audio/volume.c b/src/audio/volume.c index c770e70..1ceab4f 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -102,9 +102,6 @@ static void vol_s16_to_s32(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = (int32_t)src[i] * cd->volume[0]; dest[i + 1] = (int32_t)src[i + 1] * cd->volume[1]; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 32 bit source buffer to 16 bit dest buffer */ @@ -120,9 +117,6 @@ static void vol_s32_to_s16(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = (((int32_t)src[i] >> 16) * cd->volume[0]) >> 16; dest[i + 1] = (((int32_t)src[i + 1] >> 16) * cd->volume[1]) >> 16; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 32 bit source buffer to 32 bit dest buffer */ @@ -138,9 +132,6 @@ static void vol_s32_to_s32(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = ((int64_t)src[i] * cd->volume[0]) >> 16; dest[i + 1] = ((int64_t)src[i + 1] * cd->volume[1]) >> 16; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 16 bit source buffer to 16 bit dest buffer */ @@ -157,9 +148,6 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = ((int32_t)src[i] * cd->volume[0]) >> 16; dest[i + 1] = ((int32_t)src[i + 1] * cd->volume[1]) >> 16; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ @@ -175,9 +163,6 @@ static void vol_s16_to_s24(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = ((int32_t)src[i] * cd->volume[0]) >> 8; dest[i + 1] = ((int32_t)src[i + 1] * cd->volume[1]) >> 8; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ @@ -195,9 +180,6 @@ static void vol_s24_to_s16(struct comp_dev *dev, struct comp_buffer *sink, dest[i + 1] = (int16_t)((((int32_t)src[i + 1] >> 8) * cd->volume[1]) >> 16); } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 32 bit source buffer to 24 bit on 32 bit boundary dest buffer */ @@ -213,9 +195,6 @@ static void vol_s32_to_s24(struct comp_dev *dev, struct comp_buffer *sink, dest[i] = ((int64_t)src[i] * cd->volume[0]) >> 24; dest[i + 1] = ((int64_t)src[i + 1] * cd->volume[1]) >> 24; } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ @@ -233,9 +212,6 @@ static void vol_s24_to_s32(struct comp_dev *dev, struct comp_buffer *sink, dest[i + 1] = (int32_t)(((int64_t)src[i + 1] * cd->volume[1]) >> 8); } - - source->r_ptr = src + i; - sink->w_ptr = dest + i; }
/* map of source and sink buffer formats to volume function */
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Make sure the preloader can detect when all buffers are loaded prior to trigger and add a limiter to make sure we dont pre-load forever.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/host.c | 4 +-- src/audio/pipeline.c | 43 ++++++++++++++++------- src/audio/volume.c | 11 ++++++ src/platform/baytrail/include/platform/platform.h | 3 ++ 4 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c index c95a957..b467036 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -471,11 +471,11 @@ static int host_preload(struct comp_dev *dev) ret = wait_for_completion_timeout(&hd->complete); if (ret < 0) { trace_comp_error("eHp"); - return 0; + return -EIO; }
/* one period copied */ - return 1; + return hd->period_bytes; }
static int host_prepare(struct comp_dev *dev) diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 3bc1f68..1b421da 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -300,8 +300,15 @@ static int component_op_downstream(struct op_data *op_data, /* do operation on this component */ switch (op_data->op) { case COMP_OPS_PARAMS: + + /* dont do any params downstream if current is running */ + if (current->state == COMP_STATE_RUNNING) + return 0; + /* send params to the component */ - err = comp_params(current, op_data->params); + if (current != start) + comp_install_params(current, SOF_IPC_STREAM_PLAYBACK); + err = comp_params(current); break; case COMP_OPS_CMD: /* send command to the component */ @@ -365,8 +372,15 @@ static int component_op_upstream(struct op_data *op_data, /* do operation on this component */ switch (op_data->op) { case COMP_OPS_PARAMS: + + /* dont do any params upstream if current is running */ + if (current->state == COMP_STATE_RUNNING) + return 0; + /* send params to the component */ - err = comp_params(current, op_data->params); + if (current != start) + comp_install_params(current, SOF_IPC_STREAM_CAPTURE); + err = comp_params(current); break; case COMP_OPS_CMD: /* send command to the component */ @@ -419,7 +433,7 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current) { struct sof_ipc_comp_config *config = COMP_GET_CONFIG(current); struct list_item *clist; - int i, count = 0; + int i, total = 0, count = 0;
trace_pipe("PR-"); tracev_value(current->comp.id); @@ -429,12 +443,13 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current) return 0;
/* now preload the buffers */ - for (i = 0; i < config->preload_count; i++) - count += comp_preload(current); + for (i = 0; i < config->preload_count; i++) { + count = comp_preload(current);
- /* finished at this level and downstream if no data is preloaded */ - if (count == 0) - return count; + if (count < 0) + return count; + total += count; + }
/* now run this operation downstream */ list_for_item(clist, ¤t->bsink_list) { @@ -446,14 +461,16 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current) if (!buffer->connected) continue;
- count += preload_downstream(start, buffer->sink); + count = preload_downstream(start, buffer->sink); + if (count < 0) + return count; + + total += count; }
- return count; + return total; }
-#define MAX_PRELOAD_SIZE 3 - /* prepare the pipeline for usage - preload host buffers here */ int pipeline_prepare(struct pipeline *p, struct comp_dev *dev) { @@ -483,7 +500,7 @@ int pipeline_prepare(struct pipeline *p, struct comp_dev *dev) count = preload_downstream(dev, dev);
/* complete ? */ - if (count == 0) + if (count <= 0) goto out; }
diff --git a/src/audio/volume.c b/src/audio/volume.c index 1ceab4f..4728d91 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -583,6 +583,17 @@ found:
static int volume_preload(struct comp_dev *dev) { + struct comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer *sink; + + trace_volume("PrL"); + + /* make sure there is enough space in sink buffer */ + sink = list_first_item(&dev->bsink_list, struct comp_buffer, + source_list); + if (sink->free < cd->sink_period_bytes) + return 0; + return volume_copy(dev); }
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index d083479..1ad0a22 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -54,6 +54,9 @@ struct reef;
#define PLATFORM_SCHEDULE_COST 200
+/* maximum preload pipeline depth */ +#define MAX_PRELOAD_SIZE 20 + /* DMA treats PHY addresses as host address unless within DSP region */ #define PLATFORM_HOST_DMA_MASK 0xFF000000
![](https://secure.gravatar.com/avatar/24e6a8158be3c9b52253d878d1487123.jpg?s=120&d=mm&r=g)
Simple cleanup of some trace calls.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/pipeline.c | 2 +- src/audio/volume.c | 5 ----- src/ipc/byt-ipc.c | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 1b421da..282bec5 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -239,7 +239,7 @@ void pipeline_complete(struct pipeline *p) complete component task and pipeline init */
trace_pipe("com"); - tracev_value( p->ipc_pipe.pipeline_id); + tracev_value(p->ipc_pipe.pipeline_id);
connect_downstream(p, p->sched_comp, p->sched_comp); connect_upstream(p, p->sched_comp, p->sched_comp); diff --git a/src/audio/volume.c b/src/audio/volume.c index 4728d91..c81fd33 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -463,11 +463,6 @@ static int volume_copy(struct comp_dev *dev) source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
-#if 0 - trace_value((uint32_t)(source->r_ptr - source->addr)); - trace_value((uint32_t)(sink->w_ptr - sink->addr)); -#endif - /* get max number of bytes that can be copied */ copy_bytes = comp_buffer_get_copy_bytes(dev, source, sink);
diff --git a/src/ipc/byt-ipc.c b/src/ipc/byt-ipc.c index 4fd5d62..1483804 100644 --- a/src/ipc/byt-ipc.c +++ b/src/ipc/byt-ipc.c @@ -126,7 +126,7 @@ void ipc_platform_do_cmd(struct ipc *ipc) uint32_t ipcxh; int32_t err;
- trace_ipc("Cmd"); + tracev_ipc("Cmd");
/* clear old mailbox return values */ reply.hdr.cmd = SOF_IPC_GLB_REPLY; @@ -163,7 +163,7 @@ void ipc_platform_do_cmd(struct ipc *ipc) } }
- trace_ipc("CmD"); + tracev_ipc("CmD"); }
void ipc_platform_send_msg(struct ipc *ipc)
participants (1)
-
Liam Girdwood