[Sound-open-firmware] [PATCH] DMIC: configure DMIC with parameters from ipc instead of hardcoded params

Ranjani Sridharan ranjani.sridharan at linux.intel.com
Sun May 27 08:22:44 CEST 2018


This patch makes the following changes to configure DMIC from ipc params:

1. remove redundant hdr member item from struct sof_ipc_dai_dmic_params
2. Rename number_of_pdm_controllers member in the above structure
to num_pdm_active to be more representative of the active pdm count.
3. Add an "id" member to struct sof_ipc_dai_dmic_pdm_ctrl
4. Remove hardcoded config params from DMIC set_config function
and use ipc params instead.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
---

Notes:
    Tested with:
    
    APL based Up squared board:
    
    SOF Kernel: https://github.com/ranj063/sound branch: topic/dmic
    SOF: master
    SOFT: https://github.com/ranj063/soft.git branch: topic/dmic

 src/drivers/dmic.c     | 97 +++++++++++++++++++++---------------------
 src/include/uapi/ipc.h |  4 +-
 2 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/src/drivers/dmic.c b/src/drivers/dmic.c
index 5c8591c..b66769c 100644
--- a/src/drivers/dmic.c
+++ b/src/drivers/dmic.c
@@ -49,11 +49,6 @@
  */
 #define DMIC_FIR_PIPELINE_OVERHEAD 5
 
-/* Force a 48 kHz config while kernel driver IPC is under construction. Remove
- * or undefine when it's available.
- */
-#define DMIC_FORCE_CONFIG
-
 struct decim_modes {
 	int16_t clkdiv[DMIC_MAX_MODES];
 	int16_t mcic[DMIC_MAX_MODES];
@@ -648,7 +643,7 @@ static inline void ipm_helper(int *ipm, int stereo[], int swap[],
 	 * left (A) or mono right (B) mode. Mono right mode is setup as channel
 	 * swapped mono left.
 	 */
-	for (i = 0; i < dmic->number_of_pdm_controllers; i++) {
+	for (i = 0; i < dmic->num_pdm_active; i++) {
 		cnt = 0;
 		if (dmic->pdm[i].enable_mic_a > 0)
 			cnt++;
@@ -693,7 +688,7 @@ static inline void source_ipm_helper(int source[], int *ipm, int stereo[],
 	 * swapped mono left. The function returns also in array source[] the
 	 * indice of enabled pdm controllers to be used for IPM configuration.
 	 */
-	for (i = 0; i < dmic->number_of_pdm_controllers; i++) {
+	for (i = 0; i < dmic->num_pdm_active; i++) {
 		if (dmic->pdm[i].enable_mic_a > 0 ||
 			dmic->pdm[i].enable_mic_b > 0) {
 			pdm[i] = 1;
@@ -719,7 +714,7 @@ static inline void source_ipm_helper(int source[], int *ipm, int stereo[],
 
 	/* IPM bit field is set to count of active pdm controllers. */
 	*ipm = pdm[0];
-	for (i = 0; i < dmic->number_of_pdm_controllers; i++)
+	for (i = 0; i < dmic->num_pdm_active; i++)
 		*ipm += pdm[i];
 }
 #endif
@@ -782,7 +777,7 @@ static int configure_registers(struct dai *dai, struct dmic_configuration *cfg,
 	}
 
 	/* Sanity checks */
-	if (dmic->number_of_pdm_controllers > DMIC_HW_CONTROLLERS) {
+	if (dmic->num_pdm_active > DMIC_HW_CONTROLLERS) {
 		trace_dmic_error("num");
 		return -EINVAL;
 	}
@@ -1016,45 +1011,40 @@ static int configure_registers(struct dai *dai, struct dmic_configuration *cfg,
 
 static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
 {
-	struct decim_modes modes_a;
-	struct decim_modes modes_b;
+	struct dmic_pdata *dmic = dai_get_drvdata(dai);
+	struct sof_ipc_dai_dmic_params *prm;
 	struct matched_modes modes_ab;
 	struct dmic_configuration cfg;
-	int ret;
-	struct sof_ipc_dai_dmic_params *prm = &config->dmic;
-	struct dmic_pdata *dmic = dai_get_drvdata(dai);
+	struct decim_modes modes_a;
+	struct decim_modes modes_b;
+	int num_pdm_active = config->dmic.num_pdm_active;
+	size_t size;
+	int i, j, ret = 0;
 
 	trace_dmic("dsc");
 
-#if defined DMIC_FORCE_CONFIG
-	/* This is a temporary workaound to set parameters while
-	 * there is no driver and topology scripts support to
-	 * set these. Also the PCM sample format(s) and sample rate(s)
-	 * setting would be better to be common with other DAI types.
+	/*
+	 * "config" might contain pdm controller params for only
+	 * the active controllers
+	 * "prm" is initialized with default params for all HW controllers
 	 */
-	prm->driver_ipc_version = 1;
-	prm->pdmclk_min =  500000; /* Min 500 kHz */
-	prm->pdmclk_max = 4800000; /* Max 4.80 MHz */
-	prm->fifo_fs_a = 48000;
-	prm->fifo_fs_b = 0;
-	prm->fifo_bits_a = 32;
-	prm->fifo_bits_b = 32;
-	prm->duty_min = 40; /* Min. 40% */
-	prm->duty_max = 60; /* Max. 60% */
-	prm->number_of_pdm_controllers = 2;
-	prm->pdm[0].clk_edge = 0;
-	prm->pdm[0].enable_mic_a = 1; /* Left */
-	prm->pdm[0].enable_mic_b = 1; /* Right */
-	prm->pdm[0].polarity_mic_a = 0;
-	prm->pdm[0].polarity_mic_b = 0;
-	prm->pdm[0].skew = 0;
-	prm->pdm[1].clk_edge = 0;
-	prm->pdm[1].enable_mic_a = 0; /* Left */
-	prm->pdm[1].enable_mic_b = 0; /* Right */
-	prm->pdm[1].polarity_mic_a = 0;
-	prm->pdm[1].polarity_mic_b = 0;
-	prm->pdm[1].skew = 0;
-#endif
+	size = sizeof(*prm) + DMIC_HW_CONTROLLERS
+		* sizeof(struct sof_ipc_dai_dmic_pdm_ctrl);
+	prm = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, size);
+
+	/* copy the command DAI config params and DMIC params */
+	memcpy(prm, &config->dmic, sizeof(struct sof_ipc_dai_config));
+
+	/* copy the pdm controller params from ipc */
+	for (i = 0; i < DMIC_HW_CONTROLLERS; i++) {
+		prm->pdm[i].id = i;
+		for (j = 0; j < num_pdm_active; j++) {
+			/* copy the pdm controller params id the id's match */
+			if (prm->pdm[i].id == config->dmic.pdm[j].id)
+				memcpy(&prm->pdm[i], &config->dmic.pdm[j],
+				       sizeof(prm->pdm[i]));
+		}
+	}
 
 	trace_value(prm->driver_ipc_version);
 	trace_value(prm->pdmclk_min);
@@ -1065,11 +1055,12 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
 	trace_value(prm->fifo_bits_b);
 	trace_value(prm->duty_min);
 	trace_value(prm->duty_max);
-	trace_value(prm->number_of_pdm_controllers);
+	trace_value(prm->num_pdm_active);
 
 	if (prm->driver_ipc_version != DMIC_IPC_VERSION) {
 		trace_dmic_error("ver");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto finish;
 	}
 
 	/* Match and select optimal decimators configuration for FIFOs A and B
@@ -1081,20 +1072,23 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
 	find_modes(&modes_a, prm, prm->fifo_fs_a);
 	if (modes_a.num_of_modes == 0 && prm->fifo_fs_a > 0) {
 		trace_dmic_error("amo");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto finish;
 	}
 
 	find_modes(&modes_b, prm, prm->fifo_fs_b);
 	if (modes_b.num_of_modes == 0 && prm->fifo_fs_b > 0) {
 		trace_dmic_error("bmo");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto finish;
 	}
 
 	match_modes(&modes_ab, &modes_a, &modes_b);
 	ret = select_mode(&cfg, &modes_ab);
 	if (ret < 0) {
 		trace_dmic_error("smo");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto finish;
 	}
 
 	trace_dmic("cfg");
@@ -1115,12 +1109,17 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
 	ret = configure_registers(dai, &cfg, prm);
 	if (ret < 0) {
 		trace_dmic_error("cor");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto finish;
 	}
 
 	dmic->state = COMP_STATE_PREPARE;
 
-	return 0;
+finish:
+	/* free config params */
+	rfree(prm);
+
+	return ret;
 }
 
 /* start the DMIC for capture */
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index b32376d..9b1063f 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -292,6 +292,7 @@ struct sof_ipc_dai_hda_params {
  * data integrity problems.
  */
 struct sof_ipc_dai_dmic_pdm_ctrl {
+	uint16_t id; /* PDM controller ID */
 	uint16_t enable_mic_a; /* Use A (left) channel mic (0 or 1)*/
 	uint16_t enable_mic_b; /* Use B (right) channel mic (0 or 1)*/
 	uint16_t polarity_mic_a; /* Optionally invert mic A signal (0 or 1) */
@@ -322,7 +323,6 @@ struct sof_ipc_dai_dmic_pdm_ctrl {
  * somewhat.
  */
 struct sof_ipc_dai_dmic_params {
-	struct sof_ipc_hdr hdr;
 	uint32_t driver_ipc_version; /* Version (1..N) */
 	uint32_t pdmclk_min; /* Minimum microphone clock in Hz (100000..N) */
 	uint32_t pdmclk_max; /* Maximum microphone clock in Hz (min...N) */
@@ -333,7 +333,7 @@ struct sof_ipc_dai_dmic_params {
 	uint16_t fifo_bits_b; /* FIFO B word length (16 or 24) */
 	uint16_t duty_min;    /* Min. mic clock duty cycle in % (20..80) */
 	uint16_t duty_max;    /* Max. mic clock duty cycle in % (min..80) */
-	uint32_t number_of_pdm_controllers; /* Number 2ch controllers (2) */
+	uint32_t num_pdm_active; /* Number of active controllers */
 	struct sof_ipc_dai_dmic_pdm_ctrl pdm[];
 } __attribute__((packed));
 
-- 
2.17.0



More information about the Sound-open-firmware mailing list