Browse Source

Merge "asoc: waipio: Parse and Set reg info for UPD."

qctecmdr 3 years ago
parent
commit
316b9557b3
5 changed files with 357 additions and 1 deletions
  1. 23 0
      asoc/codecs/wcd938x/wcd938x.c
  2. 5 0
      asoc/codecs/wcd938x/wcd938x.h
  3. 177 0
      asoc/waipio.c
  4. 91 0
      dsp/audio_prm.c
  5. 61 1
      include/dsp/audio_prm.h

+ 23 - 0
asoc/codecs/wcd938x/wcd938x.c

@@ -2739,6 +2739,29 @@ static int wcd938x_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+/* wcd938x_codec_get_dev_num - returns swr device number
+ * @component: Codec instance
+ *
+ * Return: swr device number on success or negative error
+ * code on failure.
+ */
+int wcd938x_codec_get_dev_num(struct snd_soc_component *component)
+{
+	struct wcd938x_priv *wcd938x;
+
+	if (!component)
+		return -EINVAL;
+
+	wcd938x = snd_soc_component_get_drvdata(component);
+	if (!wcd938x || !wcd938x->rx_swr_dev) {
+		pr_err("%s: wcd938x component is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	return wcd938x->rx_swr_dev->dev_num;
+}
+EXPORT_SYMBOL(wcd938x_codec_get_dev_num);
+
 static int wcd938x_get_compander(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {

+ 5 - 0
asoc/codecs/wcd938x/wcd938x.h

@@ -71,6 +71,7 @@ int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x,
 int wcd938x_swr_dmic_register_notifier(struct snd_soc_component *wcd938x,
                                         struct notifier_block *nblock,
                                         bool enable);
+int wcd938x_codec_get_dev_num(struct snd_soc_component *component);
 
 static inline int wcd938x_slave_get_master_ch_val(int ch)
 {
@@ -127,5 +128,9 @@ static inline int wcd938x_slave_get_slave_ch_val(int ch)
 {
 	return 0;
 }
+static int wcd938x_codec_get_dev_num(struct snd_soc_component *component)
+{
+	return 0;
+}
 #endif /* CONFIG_SND_SOC_WCD938X */
 #endif /* _WCD938X_H */

+ 177 - 0
asoc/waipio.c

@@ -76,6 +76,9 @@ struct msm_asoc_mach_data {
 	int core_audio_vote_count;
 	u32 wsa_max_devs;
 	int wcd_disabled;
+	int (*get_dev_num)(struct snd_soc_component *);
+	int backend_used;
+	struct prm_earpa_hw_intf_config upd_config;
 };
 
 static bool is_initial_boot;
@@ -176,6 +179,134 @@ static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool acti
 	return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP);
 }
 
+static void msm_parse_upd_configuration(struct platform_device *pdev,
+					struct msm_asoc_mach_data *pdata)
+{
+	int ret = 0;
+	u32 dt_values[2];
+
+	if (!pdev || !pdata)
+		return;
+
+	ret = of_property_read_string(pdev->dev.of_node,
+		"qcom,upd_backends_used", &pdata->upd_config.backend_used);
+	if (ret) {
+		pr_debug("%s:could not find %s entry in dt\n",
+			__func__, "qcom,upd_backends_used");
+		return;
+	}
+
+	if (!strcmp(pdata->upd_config.backend_used, "wsa"))
+		pdata->get_dev_num = wsa883x_codec_get_dev_num;
+	else
+		pdata->get_dev_num = wcd938x_codec_get_dev_num;
+
+	ret = of_property_read_u32_array(pdev->dev.of_node,
+			"qcom,upd_lpass_reg_addr", dt_values, MAX_EARPA_REG);
+	if (ret) {
+		pr_debug("%s: could not find %s entry in dt\n",
+				__func__, "qcom,upd_lpass_reg_addr");
+		return;
+	} else {
+		pdata->upd_config.ear_pa_hw_reg_cfg.lpass_cdc_rx0_rx_path_ctl_phy_addr =
+									dt_values[0];
+		pdata->upd_config.ear_pa_hw_reg_cfg.lpass_wr_fifo_reg_phy_addr =
+								dt_values[1];
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node,
+			"qcom,upd_ear_pa_reg_addr", &pdata->upd_config.ear_pa_pkd_reg_addr);
+	if (ret) {
+		pr_debug("%s: could not find %s entry in dt\n",
+			__func__, "qcom,upd_ear_pa_reg_addr");
+	}
+}
+
+static void msm_set_upd_config(struct snd_soc_pcm_runtime *rtd)
+{
+	int val1 = 0, val2 = 0, ret = 0;
+	u8  dev_num = 0;
+	char cdc_name[DEV_NAME_STR_LEN];
+	struct snd_soc_component *component = NULL;
+	struct msm_asoc_mach_data *pdata = NULL;
+
+	if (!rtd) {
+		pr_err("%s: rtd is NULL\n", __func__);
+		return;
+	}
+
+	pdata = snd_soc_card_get_drvdata(rtd->card);
+	if (!pdata) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		return;
+	}
+	if (!pdata->get_dev_num) {
+		pr_err("%s: get_dev_num is NULL\n", __func__);
+		return;
+	}
+
+	if (!pdata->upd_config.ear_pa_hw_reg_cfg.lpass_cdc_rx0_rx_path_ctl_phy_addr ||
+		!pdata->upd_config.ear_pa_hw_reg_cfg.lpass_wr_fifo_reg_phy_addr ||
+                !pdata->upd_config.ear_pa_pkd_reg_addr) {
+		pr_err("%s: upd static configuration is not set\n", __func__);
+		return;
+	}
+
+	memset(cdc_name, '\0', DEV_NAME_STR_LEN);
+	if (!strcmp(pdata->upd_config.backend_used, "wsa")) {
+		if (pdata->wsa_max_devs > 0)
+			memcpy(cdc_name, "wsa-codec.1", strlen("wsa-codec.1"));
+	}
+	else
+		memcpy(cdc_name, WCD938X_DRV_NAME, sizeof(WCD938X_DRV_NAME));
+
+	component = snd_soc_rtdcom_lookup(rtd, cdc_name);
+	if (!component) {
+		pr_err("%s: %s component is NULL\n", __func__,
+			cdc_name);
+		return;
+	}
+
+	dev_num = pdata->get_dev_num(component);
+	if (dev_num < 0 || dev_num > 6) {
+		pr_err("%s: invalid slave dev num : %d\n", __func__,
+							dev_num);
+		return;
+	}
+
+	pdata->upd_config.ear_pa_pkd_cfg.ear_pa_enable_pkd_reg_addr =
+				pdata->upd_config.ear_pa_pkd_reg_addr & 0xFFFF;
+	pdata->upd_config.ear_pa_pkd_cfg.ear_pa_disable_pkd_reg_addr =
+				pdata->upd_config.ear_pa_pkd_reg_addr & 0xFFFF;
+
+	val1 = val2 = 0;
+
+	/* bits 16:19 carry command id */
+	val1 |= 1 << 16;
+
+	/* bits 20:23 carry swr device number */
+	val1 |= dev_num << 20;
+
+	/*
+	 * bits 24:31 carry 8 bit data to disable or enable ear pa
+	 * for wcd 7bit is global enable bit - 1 -enable. 0 - disable
+	 * for wsa 0bit is global enable bit - 1 -enable, 0 - disable
+	*/
+	val2 = val1;
+
+	if (!strcmp(pdata->upd_config.backend_used, "wsa"))
+		val1 |= 1 << 24;
+	else
+		val1 |= 1 << 31;
+
+	pdata->upd_config.ear_pa_pkd_cfg.ear_pa_enable_pkd_reg_addr |= val1;
+	pdata->upd_config.ear_pa_pkd_cfg.ear_pa_disable_pkd_reg_addr |= val2;
+
+	ret = audio_prm_set_cdc_earpa_duty_cycling_req(&pdata->upd_config, 1);
+	if (ret < 0)
+		pr_err("%s: upd cdc duty cycling registration failed\n", __func__);
+}
+
 static struct snd_soc_ops msm_common_be_ops = {
 	.hw_params = msm_common_snd_hw_params,
 	.startup = msm_common_snd_startup,
@@ -1492,6 +1623,8 @@ static int waipio_ssr_enable(struct device *dev, void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct snd_soc_pcm_runtime *rtd, *rtd_wcd, *rtd_wsa;
+	struct msm_asoc_mach_data *pdata;
 	int ret = 0;
 
 	if (!card) {
@@ -1508,6 +1641,47 @@ static int waipio_ssr_enable(struct device *dev, void *data)
 	snd_card_notify_user(SND_CARD_STATUS_ONLINE);
 	dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__);
 
+	pdata = snd_soc_card_get_drvdata(card);
+	rtd_wcd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
+	if (!rtd_wcd) {
+		dev_dbg(dev,
+			"%s: snd_soc_get_pcm_runtime for %s failed!\n",
+			__func__, card->dai_link[0]);
+	}
+
+	if (pdata->wsa_max_devs > 0) {
+		rtd_wsa = snd_soc_get_pcm_runtime(card,
+			&card->dai_link[ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links)]);
+		if (!rtd_wsa) {
+			dev_dbg(dev,
+			"%s: snd_soc_get_pcm_runtime for %s failed!\n",
+			__func__, card->dai_link[ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links)]);
+		}
+	}
+	/* set UPD configuration */
+	if(!pdata->upd_config.backend_used) {
+		dev_dbg(dev,
+		"%s: upd- backend_used is NULL\n", __func__);
+		goto err;
+	}
+	if (!strcmp(pdata->upd_config.backend_used, "wsa")) {
+		if (!rtd_wsa)
+			goto err;
+		else
+			rtd = rtd_wsa;
+	} else if(!strcmp(pdata->upd_config.backend_used, "wcd")) {
+		if (!rtd_wcd &&!pdata->wcd_disabled)
+			goto err;
+		else
+			rtd = rtd_wcd;
+	} else {
+		dev_err(card->dev, "%s: Invalid backend to set UPD config\n",
+			__func__);
+		goto err;
+	}
+
+	msm_set_upd_config(rtd);
+
 err:
 	return ret;
 }
@@ -1651,6 +1825,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	/* parse upd configuration */
+	msm_parse_upd_configuration(pdev, pdata);
+
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
 	if (ret == -EPROBE_DEFER) {
 		if (codec_reg_done)

+ 91 - 0
dsp/audio_prm.c

@@ -296,6 +296,97 @@ static int audio_prm_set_lpass_clk_cfg_rel(struct clk_cfg *cfg)
         return ret;
 }
 
+/**
+ * audio_prm_set_cdc_earpa_duty_cycling_req() - send codec reg values
+ * for codec duty cycling.
+ *
+ * Return: 0 if reg passing is success.
+ */
+int audio_prm_set_cdc_earpa_duty_cycling_req(struct prm_earpa_hw_intf_config *earpa_config,
+								uint32_t enable)
+{
+	struct gpr_pkt *pkt;
+	prm_cmd_request_cdc_duty_cycling_t prm_rsc_request_reg_info;
+	int ret = 0;
+	uint32_t size;
+
+	size = GPR_HDR_SIZE + sizeof(prm_cmd_request_cdc_duty_cycling_t);
+	pkt = kzalloc(size,  GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+	pkt->hdr.header = GPR_SET_FIELD(GPR_PKT_VERSION, GPR_PKT_VER) |
+			GPR_SET_FIELD(GPR_PKT_HEADER_SIZE, GPR_PKT_HEADER_WORD_SIZE_V) |
+			GPR_SET_FIELD(GPR_PKT_PACKET_SIZE, size);
+
+	pkt->hdr.src_port = GPR_SVC_ASM;
+	pkt->hdr.dst_port = PRM_MODULE_INSTANCE_ID;
+	pkt->hdr.dst_domain_id = GPR_IDS_DOMAIN_ID_ADSP_V;
+	pkt->hdr.src_domain_id = GPR_IDS_DOMAIN_ID_APPS_V;
+	pkt->hdr.token = 0;
+	if (enable)
+		pkt->hdr.opcode = PRM_CMD_REQUEST_HW_RSC;
+	else
+		pkt->hdr.opcode = PRM_CMD_RELEASE_HW_RSC;
+
+	memset(&prm_rsc_request_reg_info, 0, sizeof(prm_cmd_request_cdc_duty_cycling_t));
+	prm_rsc_request_reg_info.payload_header.payload_address_lsw = 0;
+	prm_rsc_request_reg_info.payload_header.payload_address_msw = 0;
+	prm_rsc_request_reg_info.payload_header.mem_map_handle = 0;
+	prm_rsc_request_reg_info.payload_header.payload_size =
+			sizeof(prm_cmd_request_cdc_duty_cycling_t) - sizeof(apm_cmd_header_t);
+
+	/* Populate the param payload */
+	prm_rsc_request_reg_info.module_payload_0.module_instance_id =
+							PRM_MODULE_INSTANCE_ID;
+	prm_rsc_request_reg_info.module_payload_0.error_code = 0;
+	prm_rsc_request_reg_info.module_payload_0.param_id =
+						PARAM_ID_RSC_HW_CODEC_REG_INFO;
+	prm_rsc_request_reg_info.module_payload_0.param_size =
+			sizeof(prm_cmd_request_cdc_duty_cycling_t) -
+			sizeof(apm_cmd_header_t) - sizeof(apm_module_param_data_t);
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.num_reg_info_t = MAX_EARPA_REG;
+	/* Setting up DIGITAL Mute register value */
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_reg_id =
+							HW_CODEC_DIG_REG_ID_MUTE_CTRL;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_reg_addr_msw = 0;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_reg_addr_lsw =
+			earpa_config->ear_pa_hw_reg_cfg.lpass_cdc_rx0_rx_path_ctl_phy_addr;
+
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].num_ops =
+							MAX_EARPA_CDC_DUTY_CYC_OPERATION;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_op[0].hw_codec_op_id =
+								HW_CODEC_OP_DIG_MUTE_ENABLE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_op[0].hw_codec_op_value =
+								DIG_MUTE_ENABLE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_op[1].hw_codec_op_id =
+								HW_CODEC_OP_DIG_MUTE_DISABLE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[0].hw_codec_op[1].hw_codec_op_value =
+								DIG_MUTE_DISABLE;
+	/* Setting up LPASS_PA_REG Values */
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_reg_id =
+						HW_CODEC_ANALOG_REG_ID_CMD_FIFO_WRITE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_reg_addr_msw = 0;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_reg_addr_lsw =
+					earpa_config->ear_pa_hw_reg_cfg.lpass_wr_fifo_reg_phy_addr;
+
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].num_ops =
+							MAX_EARPA_CDC_DUTY_CYC_OPERATION;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_op[0].hw_codec_op_id =
+							HW_CODEC_OP_ANA_PGA_ENABLE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_op[0].hw_codec_op_value =
+					earpa_config->ear_pa_pkd_cfg.ear_pa_enable_pkd_reg_addr;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_op[1].hw_codec_op_id =
+							HW_CODEC_OP_ANA_PGA_DISABLE;
+	prm_rsc_request_reg_info.hw_codec_reg_info_t.hw_codec_reg[1].hw_codec_op[1].hw_codec_op_value =
+					earpa_config->ear_pa_pkd_cfg.ear_pa_disable_pkd_reg_addr;
+
+	memcpy(&pkt->payload, &prm_rsc_request_reg_info, sizeof(prm_cmd_request_cdc_duty_cycling_t));
+	ret = prm_gpr_send_pkt(pkt, &g_prm.wait);
+	kfree(pkt);
+	return ret;
+}
+EXPORT_SYMBOL(audio_prm_set_cdc_earpa_duty_cycling_req);
+
 int audio_prm_set_lpass_clk_cfg (struct clk_cfg *clk, uint8_t enable)
 {
 	int ret = 0;

+ 61 - 1
include/dsp/audio_prm.h

@@ -1,4 +1,4 @@
-/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -208,6 +208,64 @@ typedef struct prm_cmd_request_hw_core_t
 
 #define HW_RSC_ID_AUDIO_HW_CLK 0x0800102C
 
+#define MAX_EARPA_REG 2
+#define MAX_EARPA_CDC_DUTY_CYC_OPERATION 2
+
+typedef struct audio_hw_codec_op_info_t {
+	uint32_t hw_codec_op_id;
+	uint32_t hw_codec_op_value;
+} audio_hw_codec_op_info_t;
+
+typedef struct audio_hw_codec_reg_op_info_t {
+	uint32_t hw_codec_reg_id;
+	uint32_t hw_codec_reg_addr_msw;
+	uint32_t hw_codec_reg_addr_lsw;
+	uint32_t num_ops;
+	audio_hw_codec_op_info_t hw_codec_op[MAX_EARPA_REG];
+} audio_hw_codec_reg_op_info_t;
+
+typedef struct audio_hw_codec_reg_info_t {
+	uint32_t num_reg_info_t;
+	audio_hw_codec_reg_op_info_t hw_codec_reg[MAX_EARPA_REG];
+} audio_hw_codec_reg_info_t;
+
+typedef struct prm_cmd_request_cdc_duty_cycling_t {
+	apm_cmd_header_t payload_header;
+	apm_module_param_data_t module_payload_0;
+	audio_hw_codec_reg_info_t   hw_codec_reg_info_t;
+} prm_cmd_request_cdc_duty_cycling_t;
+
+/* earpa_register config */
+#define DIG_MUTE_ENABLE 0x34
+#define DIG_MUTE_DISABLE 0x24
+
+struct lpass_swr_ear_pa_dep_cfg_t {
+	uint32_t ear_pa_enable_pkd_reg_addr;
+	uint32_t ear_pa_disable_pkd_reg_addr;
+} __packed;
+
+struct lpass_swr_ear_pa_reg_cfg_t {
+	uint32_t lpass_cdc_rx0_rx_path_ctl_phy_addr;
+	uint32_t lpass_wr_fifo_reg_phy_addr;
+} __packed;
+
+struct prm_earpa_hw_intf_config {
+	struct lpass_swr_ear_pa_reg_cfg_t ear_pa_hw_reg_cfg;
+	struct lpass_swr_ear_pa_dep_cfg_t ear_pa_pkd_cfg;
+	uint32_t ear_pa_pkd_reg_addr;
+	const char  *backend_used;
+} __packed;
+
+#define PARAM_ID_RSC_HW_CODEC_REG_INFO 0x0800131B
+
+#define HW_CODEC_DIG_REG_ID_MUTE_CTRL 0x1
+#define HW_CODEC_OP_DIG_MUTE_ENABLE 0x1
+#define HW_CODEC_OP_DIG_MUTE_DISABLE 0x2
+
+#define HW_CODEC_ANALOG_REG_ID_CMD_FIFO_WRITE 0x2
+#define HW_CODEC_OP_ANA_PGA_ENABLE 0x3
+#define HW_CODEC_OP_ANA_PGA_DISABLE 0x4
+
 /* Supported OSR clock values */
 #define OSR_CLOCK_12_P288_MHZ	0xBB8000
 #define OSR_CLOCK_11_P2896_MHZ	0xAC4400
@@ -522,5 +580,7 @@ typedef struct prm_cmd_request_hw_core_t
 
 int audio_prm_set_lpass_clk_cfg(struct clk_cfg *cfg, uint8_t enable);
 int audio_prm_set_lpass_hw_core_req(struct clk_cfg *cfg, uint32_t hw_core_id, uint8_t enable);
+int audio_prm_set_cdc_earpa_duty_cycling_req(struct prm_earpa_hw_intf_config *earpa_config,
+									uint32_t enable);
 
 #endif