Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c3705e9 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 346468d5 on remote branch

Change-Id: Iaedf2dbfd70ab13f3c86c946438e39719efd0790
parents 3b7c3af9 346468d5
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -234,11 +234,11 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv,
		}
		bolero_clk_rsc_fs_gen_request(tx_priv->dev,
					true);
		if (tx_priv->tx_mclk_users == 0) {
		regcache_mark_dirty(regmap);
		regcache_sync_region(regmap,
				TX_START_OFFSET,
				TX_MAX_OFFSET);
		if (tx_priv->tx_mclk_users == 0) {
			/* 9.6MHz MCLK, set value 0x00 if other frequency */
			regmap_update_bits(regmap,
				BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
@@ -2445,11 +2445,7 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
			ret = swrm_wcd_notify(
				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
				SWR_REGISTER_WAKEUP, NULL);
			msm_cdc_pinctrl_set_wakeup_capable(
					tx_priv->tx_swr_gpio_p, false);
		} else {
			msm_cdc_pinctrl_set_wakeup_capable(
					tx_priv->tx_swr_gpio_p, true);
			ret = swrm_wcd_notify(
				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
				SWR_DEREGISTER_WAKEUP, NULL);
@@ -2484,6 +2480,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
					__func__);
				goto exit;
			}
			msm_cdc_pinctrl_set_wakeup_capable(
					tx_priv->tx_swr_gpio_p, false);
		}

		clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
@@ -2612,6 +2610,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
						   TX_CORE_CLK,
						   false);
		if (tx_priv->swr_clk_users == 0) {
			msm_cdc_pinctrl_set_wakeup_capable(
					tx_priv->tx_swr_gpio_p, true);
			ret = msm_cdc_pinctrl_select_sleep_state(
						tx_priv->tx_swr_gpio_p);
			if (ret < 0) {
+8 −6
Original line number Diff line number Diff line
@@ -399,12 +399,8 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
				dev_dbg(va_dev, "%s: clock switch failed\n",
					__func__);
		}
		msm_cdc_pinctrl_set_wakeup_capable(
				va_priv->va_swr_gpio_p, false);
		break;
	case SND_SOC_DAPM_POST_PMD:
		msm_cdc_pinctrl_set_wakeup_capable(
				va_priv->va_swr_gpio_p, true);
		if (va_priv->swr_ctrl_data) {
			clk_src = CLK_SRC_TX_RCG;
			ret = swrm_wcd_notify(
@@ -557,9 +553,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,
		(enable ? "enable" : "disable"), va_priv->va_mclk_users);

	if (enable) {
		if (va_priv->swr_clk_users == 0)
		if (va_priv->swr_clk_users == 0) {
			msm_cdc_pinctrl_select_active_state(
						va_priv->va_swr_gpio_p);
			msm_cdc_pinctrl_set_wakeup_capable(
					va_priv->va_swr_gpio_p, false);
		}
		clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev,
						   TX_CORE_CLK,
						   TX_CORE_CLK,
@@ -652,10 +651,13 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,
						   TX_CORE_CLK,
						   TX_CORE_CLK,
						   false);
		if (va_priv->swr_clk_users == 0)
		if (va_priv->swr_clk_users == 0) {
			msm_cdc_pinctrl_set_wakeup_capable(
					va_priv->va_swr_gpio_p, true);
			msm_cdc_pinctrl_select_sleep_state(
						va_priv->va_swr_gpio_p);
		}
	}
	return 0;

done:
+36 −0
Original line number Diff line number Diff line
@@ -770,6 +770,30 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
}
EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry);

/*
 * wsa883x_codec_get_dev_num - returns swr device number
 * @component: Codec instance
 *
 * Return: swr device number on success or negative error
 * code on failure.
 */
int wsa883x_codec_get_dev_num(struct snd_soc_component *component)
{
	struct wsa883x_priv *wsa883x;

	if (!component)
		return -EINVAL;

	wsa883x = snd_soc_component_get_drvdata(component);
	if (!wsa883x) {
		pr_err("%s: wsa883x component is NULL\n", __func__);
		return -EINVAL;
	}

	return wsa883x->swr_slave->dev_num;
}
EXPORT_SYMBOL(wsa883x_codec_get_dev_num);

static int wsa883x_get_compander(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
@@ -996,6 +1020,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
		/* Force remove group */
		swr_remove_from_group(wsa883x->swr_slave,
				      wsa883x->swr_slave->dev_num);
		snd_soc_component_update_bits(component,
				WSA883X_VBAT_ADC_FLT_CTL,
				0x0E, 0x06);
		snd_soc_component_update_bits(component,
				WSA883X_VBAT_ADC_FLT_CTL,
				0x01, 0x01);
		if (test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
			snd_soc_component_update_bits(component,
				WSA883X_PA_FSM_CTL, 0x01, 0x01);
@@ -1004,6 +1034,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,
		if (!test_bit(SPKR_ADIE_LB, &wsa883x->status_mask))
			wcd_disable_irq(&wsa883x->irq_info,
					WSA883X_IRQ_INT_PDM_WD);
		snd_soc_component_update_bits(component,
				WSA883X_VBAT_ADC_FLT_CTL,
				0x01, 0x00);
		snd_soc_component_update_bits(component,
				WSA883X_VBAT_ADC_FLT_CTL,
				0x0E, 0x00);
		snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
				0x01, 0x00);
		snd_soc_component_update_bits(wsa883x->component,
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ int wsa883x_set_channel_map(struct snd_soc_component *component,
int wsa883x_codec_info_create_codec_entry(
					struct snd_info_entry *codec_root,
					struct snd_soc_component *component);
int wsa883x_codec_get_dev_num(struct snd_soc_component *component);
#else
static int wsa883x_set_channel_map(struct snd_soc_component *component,
				   u8 *port, u8 num_port, unsigned int *ch_mask,
@@ -36,6 +37,10 @@ static int wsa883x_codec_info_create_codec_entry(
	return 0;
}

static int wsa883x_codec_get_dev_num(struct snd_soc_component *component)
{
	return 0;
}
#endif

#endif /* _WSA883X_H */
+253 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@
#define WCN_CDC_SLIM_TX_CH_MAX 2
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3

#define SWR_MAX_SLAVE_DEVICES 6

enum {
	RX_PATH = 0,
	TX_PATH,
@@ -195,7 +197,10 @@ struct msm_asoc_mach_data {
	struct device_node *fsa_handle;
	struct clk *lpass_audio_hw_vote;
	int core_audio_vote_count;
	u32 wsa_max_devs;
	u32 tdm_max_slots; /* Max TDM slots used */
	int (*get_wsa_dev_num)(struct snd_soc_component*);
	struct afe_cps_hw_intf_cfg cps_config;
};

struct tdm_port {
@@ -2691,6 +2696,12 @@ static int msm_get_port_id(int be_id)
	case MSM_BACKEND_DAI_SENARY_MI2S_TX:
		afe_port_id = AFE_PORT_ID_SENARY_MI2S_TX;
		break;
	case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0:
		afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0;
		break;
	case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0:
		afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0;
		break;
	case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
		afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0;
		break;
@@ -4902,6 +4913,121 @@ static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream)
	return ret;
}

static void set_cps_config(struct snd_soc_pcm_runtime *rtd,
				u32 num_ch, u32 ch_mask)
{
	int i = 0;
	int val = 0;
	u8 dev_num = 0;
	int ch_configured = 0;
	int j = 0;
	int n = 0;
	char wsa_cdc_name[DEV_NAME_STR_LEN];
	struct snd_soc_component *component = NULL;
	struct snd_soc_dai_link *dai_link = rtd->dai_link;
        struct msm_asoc_mach_data *pdata =
			snd_soc_card_get_drvdata(rtd->card);

	if (!pdata) {
		pr_err("%s: pdata is NULL\n", __func__);
		return;
	}

	if (!num_ch) {
		pr_err("%s: channel count is 0\n", __func__);
		return;
	}

	if (!pdata->get_wsa_dev_num) {
		pr_err("%s: get_wsa_dev_num is NULL\n", __func__);
		return;
	}

	if (!pdata->cps_config.spkr_dep_cfg) {
		pr_debug("%s: spkr_dep_cfg is NULL\n", __func__);
		return;
	}

	if (!pdata->cps_config.hw_reg_cfg.lpass_wr_cmd_reg_phy_addr ||
	   !pdata->cps_config.hw_reg_cfg.lpass_rd_cmd_reg_phy_addr ||
	   !pdata->cps_config.hw_reg_cfg.lpass_rd_fifo_reg_phy_addr) {
		pr_err("%s: cps static configuration is not set\n", __func__);
		return;
	}

	pdata->cps_config.lpass_hw_intf_cfg_mode = 1;

	while (ch_configured < num_ch) {
		if (!(ch_mask & (1 << i))) {
			i++;
			continue;
		}

		snprintf(wsa_cdc_name, sizeof(wsa_cdc_name), "wsa-codec.%d",
			 i+1);

		/* Use n to make sure both WSA components are retrieved */
		/* When first WSA component is retrieved adjust looping
		   variable such that the next time only the remaining part
		   of the array is traversed */
		for (j = n; j < rtd->card->num_aux_devs; j++)
		{
			if (msm_codec_conf[j].name_prefix != NULL ) {
				if (strstr(msm_codec_conf[j].name_prefix,
					"Left")) {
					component = soc_find_component_locked(
						msm_aux_dev[j].codec_of_node,
						NULL);
					n = j+1;
					break;
				}
				else if (strstr(msm_codec_conf[j].name_prefix,
					"Right")) {
					component = soc_find_component_locked(
						msm_aux_dev[j].codec_of_node,
						NULL);
					n = j+1;
					break;
				}
			}
		}

		if (!component) {
			pr_err("%s: %s component is NULL\n", __func__,
				wsa_cdc_name);
			return;
		}

		dev_num = pdata->get_wsa_dev_num(component);
		if (dev_num < 0 || dev_num > SWR_MAX_SLAVE_DEVICES) {
			pr_err("%s: invalid slave dev num : %d\n", __func__,
				dev_num);
			return;
		}

		/* Clear stale dev num info */
		pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr &= 0xFFFF;
		pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr &= 0xFFFF;

		val = 0;

		/* bits 20:23 carry swr device number */
		val |= dev_num << 20;

		/* bits 24:27 carry read length in bytes */
		val |= 1 << 24;

		/* Update dev num in packed reg addr */
		pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr |= val;
		pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr |= val;
		i++;
		ch_configured++;
	}

	afe_set_cps_config(msm_get_port_id(dai_link->id),
					&pdata->cps_config, ch_mask);
}

static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params)
{
@@ -4949,6 +5075,11 @@ static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream,
				goto err;
			}

			if (dai_link->id == MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0 ||
			    dai_link->id == MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1) {
				set_cps_config(rtd, user_set_rx_ch,
						rx_ch_cdc_dma);
			}
		}
		break;
		}
@@ -8236,6 +8367,115 @@ static int msm_audio_ssr_register(struct device *dev)
	return ret;
}

static void parse_cps_configuration(struct platform_device *pdev,
			struct msm_asoc_mach_data *pdata)
{
	int ret = 0;
	int i = 0, j = 0;
	u32 dt_values[MAX_CPS_LEVELS];

	if (!pdev || !pdata || !pdata->wsa_max_devs)
		return;

	pdata->get_wsa_dev_num = wsa883x_codec_get_dev_num;
	pdata->cps_config.hw_reg_cfg.num_spkr = pdata->wsa_max_devs;

	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_reg_phy_addr", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]));
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_reg_phy_addr");
	} else {
		pdata->cps_config.hw_reg_cfg.lpass_wr_cmd_reg_phy_addr =
								dt_values[0];
		pdata->cps_config.hw_reg_cfg.lpass_rd_cmd_reg_phy_addr =
								dt_values[1];
		pdata->cps_config.hw_reg_cfg.lpass_rd_fifo_reg_phy_addr =
								dt_values[2];
	}

	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_threshold_levels", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]) - 1);
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_threshold_levels");
	} else {
		pdata->cps_config.hw_reg_cfg.vbatt_lower2_threshold =
								dt_values[0];
		pdata->cps_config.hw_reg_cfg.vbatt_lower1_threshold =
								dt_values[1];
	}

	pdata->cps_config.spkr_dep_cfg = devm_kzalloc(&pdev->dev,
				    sizeof(struct lpass_swr_spkr_dep_cfg_t)
				    * pdata->wsa_max_devs, GFP_KERNEL);
	if (!pdata->cps_config.spkr_dep_cfg) {
		dev_err(&pdev->dev, "%s: spkr dep cfg alloc failed\n", __func__);
		return;
	}
	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_wsa_vbatt_temp_reg_addr", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]) - 1);
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_wsa_vbatt_temp_reg_addr");
	} else {
		for (i = 0; i < pdata->wsa_max_devs; i++) {
			pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr =
								dt_values[0];
			pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr =
								dt_values[1];
		}
	}

	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_normal_values", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]));
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_normal_values");
	} else {
		for (i = 0; i < pdata->wsa_max_devs; i++) {
			for (j = 0; j < MAX_CPS_LEVELS; j++) {
				pdata->cps_config.spkr_dep_cfg[i].
					value_normal_thrsd[j] = dt_values[j];
			}
		}
	}

	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_lower1_values", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]));
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_lower1_values");
	} else {
		for (i = 0; i < pdata->wsa_max_devs; i++) {
			for (j = 0; j < MAX_CPS_LEVELS; j++) {
				pdata->cps_config.spkr_dep_cfg[i].
					value_low1_thrsd[j] = dt_values[j];
			}
		}
	}

	ret = of_property_read_u32_array(pdev->dev.of_node,
				"qcom,cps_lower2_values", dt_values,
				sizeof(dt_values)/sizeof(dt_values[0]));
	if (ret) {
		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, "qcom,cps_lower2_values");
	} else {
		for (i = 0; i < pdata->wsa_max_devs; i++) {
			for (j = 0; j < MAX_CPS_LEVELS; j++) {
				pdata->cps_config.spkr_dep_cfg[i].
					value_low2_thrsd[j] = dt_values[j];
			}
		}
	}
}

static int msm_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = NULL;
@@ -8307,6 +8547,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
	dev_info(&pdev->dev, "%s: Sound card %s registered\n",
		 __func__, card->name);

	/* Get maximum WSA device count for this platform */
	ret = of_property_read_u32(pdev->dev.of_node,
				   "qcom,wsa-max-devs", &pdata->wsa_max_devs);
	if (ret) {
		dev_err(&pdev->dev, "%s: No DT match for wsa max devs\n",
				__func__);
		pdata->wsa_max_devs = 0;
	}

	ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots",
				   &pdata->tdm_max_slots);
	if (ret) {
@@ -8419,6 +8668,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
		atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0);
	}

	/* parse cps configuration from dt */
	if (of_property_read_bool(pdev->dev.of_node, "qcom,cps_reg_phy_addr"))
		parse_cps_configuration(pdev, pdata);

	/* Register LPASS audio hw vote */
	lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote");
	if (IS_ERR(lpass_audio_hw_vote)) {
Loading