From b55a7d14a043758c0c7d76eb6375206925f130a7 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Mon, 24 Feb 2020 23:45:59 +0100 Subject: [PATCH 1/3] dai: add dir arg to get_hw_params function in dai_ops Hardware stream parameters can be different for PLAYBACK and CAPTURE direction. get_hw_params() should return parameters correctly depending on the stream direction. Signed-off-by: Bartosz Kokoszko --- src/drivers/intel/baytrail/ssp.c | 2 +- src/drivers/intel/cavs/alh.c | 2 +- src/drivers/intel/cavs/dmic.c | 2 +- src/drivers/intel/cavs/hda.c | 2 +- src/drivers/intel/cavs/ssp.c | 2 +- src/drivers/intel/haswell/ssp.c | 2 +- src/include/sof/lib/dai.h | 7 ++++--- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/drivers/intel/baytrail/ssp.c b/src/drivers/intel/baytrail/ssp.c index aeaa3b97309f..d04095ae20ca 100644 --- a/src/drivers/intel/baytrail/ssp.c +++ b/src/drivers/intel/baytrail/ssp.c @@ -482,7 +482,7 @@ static int ssp_set_config(struct dai *dai, /* get SSP hw params */ static int ssp_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { struct ssp_pdata *ssp = dai_get_drvdata(dai); diff --git a/src/drivers/intel/cavs/alh.c b/src/drivers/intel/cavs/alh.c index 05e538474e0f..22c4eaebb095 100644 --- a/src/drivers/intel/cavs/alh.c +++ b/src/drivers/intel/cavs/alh.c @@ -32,7 +32,7 @@ static int alh_set_config(struct dai *dai, struct sof_ipc_dai_config *config) /* get ALH hw params */ static int alh_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { /* 0 means variable */ params->rate = 0; diff --git a/src/drivers/intel/cavs/dmic.c b/src/drivers/intel/cavs/dmic.c index 2983809b47ea..0351bf6f4720 100644 --- a/src/drivers/intel/cavs/dmic.c +++ b/src/drivers/intel/cavs/dmic.c @@ -1048,7 +1048,7 @@ static int configure_registers(struct dai *dai, /* get DMIC hw params */ static int dmic_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { int di = dai->index; diff --git a/src/drivers/intel/cavs/hda.c b/src/drivers/intel/cavs/hda.c index 0a3ad19b9c15..666de5ba2aa6 100644 --- a/src/drivers/intel/cavs/hda.c +++ b/src/drivers/intel/cavs/hda.c @@ -25,7 +25,7 @@ static int hda_set_config(struct dai *dai, /* get HDA hw params */ static int hda_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { /* 0 means variable */ params->rate = 0; diff --git a/src/drivers/intel/cavs/ssp.c b/src/drivers/intel/cavs/ssp.c index 78b9aa612963..6dcefd3b33a5 100644 --- a/src/drivers/intel/cavs/ssp.c +++ b/src/drivers/intel/cavs/ssp.c @@ -619,7 +619,7 @@ static int ssp_set_config(struct dai *dai, /* get SSP hw params */ static int ssp_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { struct ssp_pdata *ssp = dai_get_drvdata(dai); diff --git a/src/drivers/intel/haswell/ssp.c b/src/drivers/intel/haswell/ssp.c index 2f75e2f844e1..913ed5d73a22 100644 --- a/src/drivers/intel/haswell/ssp.c +++ b/src/drivers/intel/haswell/ssp.c @@ -390,7 +390,7 @@ static int ssp_set_config(struct dai *dai, /* get SSP hw params */ static int ssp_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { struct ssp_pdata *ssp = dai_get_drvdata(dai); diff --git a/src/include/sof/lib/dai.h b/src/include/sof/lib/dai.h index ba5947860595..128764455fb0 100644 --- a/src/include/sof/lib/dai.h +++ b/src/include/sof/lib/dai.h @@ -67,7 +67,7 @@ struct dai_ops { int (*pm_context_restore)(struct dai *dai); int (*pm_context_store)(struct dai *dai); int (*get_hw_params)(struct dai *dai, - struct sof_ipc_stream_params *params); + struct sof_ipc_stream_params *params, int dir); int (*get_handshake)(struct dai *dai, int direction, int stream_id); int (*get_fifo)(struct dai *dai, int direction, int stream_id); int (*probe)(struct dai *dai); @@ -275,9 +275,10 @@ static inline int dai_pm_context_restore(struct dai *dai) * \brief Get Digital Audio interface stream parameters */ static inline int dai_get_hw_params(struct dai *dai, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, + int dir) { - int ret = dai->drv->ops.get_hw_params(dai, params); + int ret = dai->drv->ops.get_hw_params(dai, params, dir); platform_shared_commit(dai, sizeof(*dai)); From 3c26e393ab04538edae7080648dafc3d7e207a49 Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Mon, 24 Feb 2020 23:52:46 +0100 Subject: [PATCH 2/3] comp: add dir arg to dai_get_hw_params function in comp_ops Hardware stream parameters can be different for PLAYBACK and CAPTURE direction. dai_get_hw_params() should return parameters corretly depending on the stream direction. Signed-off-by: Bartosz Kokoszko --- src/audio/dai.c | 6 +++--- src/audio/pipeline.c | 2 +- src/include/sof/audio/component.h | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/audio/dai.c b/src/audio/dai.c index 198eb25d6ca1..e73ff828a1a9 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -201,7 +201,7 @@ static void dai_free(struct comp_dev *dev) } static int dai_comp_get_hw_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, int dir) { struct dai_data *dd = comp_get_drvdata(dev); int ret = 0; @@ -209,7 +209,7 @@ static int dai_comp_get_hw_params(struct comp_dev *dev, comp_info(dev, "dai_hw_params()"); /* fetching hw dai stream params */ - ret = dai_get_hw_params(dd->dai, params); + ret = dai_get_hw_params(dd->dai, params, dir); if (ret < 0) { comp_err(dev, "dai_comp_get_hw_params() error: dai_get_hw_params failed"); return ret; @@ -223,7 +223,7 @@ static int dai_verify_params(struct comp_dev *dev, { struct sof_ipc_stream_params hw_params; - dai_comp_get_hw_params(dev, &hw_params); + dai_comp_get_hw_params(dev, &hw_params, params->direction); /* checks whether pcm parameters match hardware DAI parameter set * during dai_set_config(). If hardware parameter is equal to 0, it diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index e66f47c63146..aa4d4c97ddc5 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -282,7 +282,7 @@ static int pipeline_comp_hw_params(struct comp_dev *current, /* Fetch hardware stream parameters from DAI component */ if (dev_comp_type(current) == SOF_COMP_DAI) { ret = comp_dai_get_hw_params(current, - &ppl_data->params->params); + &ppl_data->params->params, dir); if (ret < 0) { pipe_cl_err("pipeline_find_dai_comp(): comp_dai_get_hw_params() error."); return ret; diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index b8dc6821f2b6..d5e4454e90af 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -211,7 +211,7 @@ struct comp_ops { /** get dai hw parameters */ int (*dai_get_hw_params)(struct comp_dev *dev, - struct sof_ipc_stream_params *params); + struct sof_ipc_stream_params *params, int dir); /** set component audio stream parameters */ int (*dai_config)(struct comp_dev *dev, @@ -512,10 +512,11 @@ static inline int comp_params(struct comp_dev *dev, * @return 0 if succeeded, error code otherwise. */ static inline int comp_dai_get_hw_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) + struct sof_ipc_stream_params *params, + int dir) { if (dev->drv->ops.dai_get_hw_params) - return dev->drv->ops.dai_get_hw_params(dev, params); + return dev->drv->ops.dai_get_hw_params(dev, params, dir); return -EINVAL; } From 946cc9d4e7788dda8a7f48895f6af9ff9861ca4b Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Mon, 24 Feb 2020 17:20:23 +0100 Subject: [PATCH 3/3] dai: ssp: refines ssp get_hw_params functions FOR ssp channels parameter can be different for PLAYBACK and CAPTURE and it depends on tx_slots and rx_slots config variables. This commit utilizes those variables in get_hw_params() function in order to return hardware stream parameters correctly. Signed-off-by: Bartosz Kokoszko --- src/drivers/intel/baytrail/ssp.c | 6 +++++- src/drivers/intel/cavs/ssp.c | 6 +++++- src/drivers/intel/haswell/ssp.c | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/drivers/intel/baytrail/ssp.c b/src/drivers/intel/baytrail/ssp.c index d04095ae20ca..b9bb311a91ed 100644 --- a/src/drivers/intel/baytrail/ssp.c +++ b/src/drivers/intel/baytrail/ssp.c @@ -487,9 +487,13 @@ static int ssp_get_hw_params(struct dai *dai, struct ssp_pdata *ssp = dai_get_drvdata(dai); params->rate = ssp->params.fsync_rate; - params->channels = ssp->params.tdm_slots; params->buffer_fmt = 0; + if (dir == SOF_IPC_STREAM_PLAYBACK) + params->channels = popcount(ssp->params.tx_slots); + else + params->channels = popcount(ssp->params.rx_slots); + switch (ssp->params.sample_valid_bits) { case 16: params->frame_fmt = SOF_IPC_FRAME_S16_LE; diff --git a/src/drivers/intel/cavs/ssp.c b/src/drivers/intel/cavs/ssp.c index 6dcefd3b33a5..6110af6c0862 100644 --- a/src/drivers/intel/cavs/ssp.c +++ b/src/drivers/intel/cavs/ssp.c @@ -624,9 +624,13 @@ static int ssp_get_hw_params(struct dai *dai, struct ssp_pdata *ssp = dai_get_drvdata(dai); params->rate = ssp->params.fsync_rate; - params->channels = ssp->params.tdm_slots; params->buffer_fmt = 0; + if (dir == SOF_IPC_STREAM_PLAYBACK) + params->channels = popcount(ssp->params.tx_slots); + else + params->channels = popcount(ssp->params.rx_slots); + switch (ssp->params.sample_valid_bits) { case 16: params->frame_fmt = SOF_IPC_FRAME_S16_LE; diff --git a/src/drivers/intel/haswell/ssp.c b/src/drivers/intel/haswell/ssp.c index 913ed5d73a22..2cb0945e7d17 100644 --- a/src/drivers/intel/haswell/ssp.c +++ b/src/drivers/intel/haswell/ssp.c @@ -395,9 +395,13 @@ static int ssp_get_hw_params(struct dai *dai, struct ssp_pdata *ssp = dai_get_drvdata(dai); params->rate = ssp->params.fsync_rate; - params->channels = ssp->params.tdm_slots; params->buffer_fmt = 0; + if (dir == SOF_IPC_STREAM_PLAYBACK) + params->channels = popcount(ssp->params.tx_slots); + else + params->channels = popcount(ssp->params.rx_slots); + switch (ssp->params.sample_valid_bits) { case 16: params->frame_fmt = SOF_IPC_FRAME_S16_LE;