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

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

Merge 79d2ae62 on remote branch

Change-Id: Ie16977ff5c3bc9e5d7a5ea7b2023034599b6296a
parents 64a88913 79d2ae62
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -835,6 +835,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
	int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS;
	struct device *tx_dev = NULL;
	struct tx_macro_priv *tx_priv = NULL;
	u16 adc_mux_reg = 0, adc_reg = 0, adc_n = 0;
	u16 dmic_clk_reg = 0;

	if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
		return -EINVAL;
@@ -855,6 +857,22 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
				TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
		if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
			adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
					TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
			adc_n = snd_soc_component_read32(component, adc_reg) &
					TX_MACRO_SWR_MIC_MUX_SEL_MASK;
			if (adc_n >= BOLERO_ADC_MAX) {
				dmic_clk_reg =
					BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
					((adc_n - 5) / 2) * 4;
				snd_soc_component_update_bits(component,
					dmic_clk_reg,
					0x0E, tx_priv->dmic_clk_div << 0x1);
			}
		}
		snd_soc_component_update_bits(component,
			dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
			TX_MACRO_ADC_MODE_CFG0_SHIFT);
@@ -2312,7 +2330,8 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
			"%s: priv is null for macro!\n", __func__);
		return -EINVAL;
	}
	if (tx_priv->swr_ctrl_data && !tx_priv->tx_swr_clk_cnt) {
	if (tx_priv->swr_ctrl_data &&
		(!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) {
		if (enable) {
			ret = swrm_wcd_notify(
				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
@@ -2693,7 +2712,7 @@ static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
}

static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = {
	{BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x02},
	{BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0A},
};

static int tx_macro_init(struct snd_soc_component *component)
+9 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */
#include <linux/module.h>
#include <linux/init.h>
@@ -732,6 +732,10 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,

		mbhc->hph_status |= jack_type;

		if (jack_type == SND_JACK_HEADPHONE &&
		    mbhc->mbhc_cb->mbhc_micb_ramp_control)
			mbhc->mbhc_cb->mbhc_micb_ramp_control(component, false);

		pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
			 jack_type, mbhc->hph_status);
		wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
@@ -922,6 +926,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
	else
		pr_info("%s: hs_detect_plug work not cancelled\n", __func__);

	/* Enable micbias ramp */
	if (mbhc->mbhc_cb->mbhc_micb_ramp_control)
		mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true);

	if (mbhc->mbhc_cb->micbias_enable_status)
		micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc,
						MIC_BIAS_1);
@@ -1417,9 +1425,6 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
	/* Button Debounce set to 16ms */
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_DBNC, 2);

	/* Enable micbias ramp */
	if (mbhc->mbhc_cb->mbhc_micb_ramp_control)
		mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true);
	/* enable bias */
	mbhc->mbhc_cb->mbhc_bias(component, true);
	/* enable MBHC clock */
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _WCD938X_INTERNAL_H
@@ -70,6 +70,7 @@ struct wcd938x_priv {
	bool comp1_enable;
	bool comp2_enable;
	bool ldoh;
	bool bcs_dis;
	struct irq_domain *virq;
	struct wcd_irq_info irq_info;
	u32 rx_clk_cnt;
+132 −31
Original line number Diff line number Diff line
@@ -69,6 +69,16 @@ enum {
	ADC_MODE_ULP2,
};

static u8 tx_mode_bit[] = {
	[ADC_MODE_INVALID] = 0x00,
	[ADC_MODE_HIFI] = 0x01,
	[ADC_MODE_LO_HIF] = 0x02,
	[ADC_MODE_NORMAL] = 0x04,
	[ADC_MODE_LP] = 0x08,
	[ADC_MODE_ULP1] = 0x10,
	[ADC_MODE_ULP2] = 0x20,
};

static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);

@@ -141,26 +151,56 @@ static int wcd938x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum)
	return ((bank & 0x40) ? 1: 0);
}

static int wcd938x_swr_slv_set_host_clk_div2(struct swr_device *dev,
						u8 devnum, int bank)
static int wcd938x_get_clk_rate(int mode)
{
	u8 val = (bank ? 1 : 0);
	int rate;

	return (swr_write(dev, devnum,
		(SWR_SCP_HOST_CLK_DIV2_CTL_BANK + (0x10 * bank)), &val));
	switch (mode) {
	case ADC_MODE_ULP2:
		rate = SWR_CLK_RATE_0P6MHZ;
		break;
	case ADC_MODE_ULP1:
		rate = SWR_CLK_RATE_1P2MHZ;
		break;
	case ADC_MODE_LP:
		rate = SWR_CLK_RATE_4P8MHZ;
		break;
	case ADC_MODE_NORMAL:
	case ADC_MODE_LO_HIF:
	case ADC_MODE_HIFI:
	case ADC_MODE_INVALID:
	default:
		rate = SWR_CLK_RATE_9P6MHZ;
		break;
	}

	return rate;
}

static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component,
					int mode, int bank)
					int rate, int bank)
{
	u8 mask = (bank ? 0xF0 : 0x0F);
	u8 val = 0;

	if ((mode == ADC_MODE_ULP1) || (mode == ADC_MODE_ULP2))
	switch (rate) {
	case SWR_CLK_RATE_0P6MHZ:
		val = (bank ? 0x60 : 0x06);
	else
		break;
	case SWR_CLK_RATE_1P2MHZ:
		val = (bank ? 0x50 : 0x05);
		break;
	case SWR_CLK_RATE_2P4MHZ:
		val = (bank ? 0x30 : 0x03);
		break;
	case SWR_CLK_RATE_4P8MHZ:
		val = (bank ? 0x10 : 0x01);
		break;
	case SWR_CLK_RATE_9P6MHZ:
	default:
		val = 0x00;

		break;
	}
	snd_soc_component_update_bits(component,
				      WCD938X_DIGITAL_SWR_TX_CLK_RATE,
				      mask, val);
@@ -354,7 +394,8 @@ static int wcd938x_parse_port_mapping(struct device *dev,
}

static int wcd938x_tx_connect_port(struct snd_soc_component *component,
					u8 slv_port_type, u8 enable)
					u8 slv_port_type, int clk_rate,
					u8 enable)
{
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
	u8 port_id, num_ch, ch_mask, port_type;
@@ -365,6 +406,8 @@ static int wcd938x_tx_connect_port(struct snd_soc_component *component,
	ret = wcd938x_set_port_params(component, slv_port_type, &port_id,
				&num_ch, &ch_mask, &ch_rate,
				&port_type, CODEC_TX);
	if (clk_rate)
		ch_rate = clk_rate;

	if (ret)
		return ret;
@@ -1325,10 +1368,12 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
		/* enable clock scaling */
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06);
		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), true);
		wcd938x_tx_connect_port(component, DMIC0 + (w->shift),
					SWR_CLK_RATE_2P4MHZ, true);
		break;
	case SND_SOC_DAPM_POST_PMD:
		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), false);
		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0,
					false);
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_CDC_AMIC_CTL,
				(0x01 << dmic_ctl_shift),
@@ -1449,32 +1494,54 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
	int ret = 0;
	int bank = 0;
	int mode = 0;
	u8 mode = 0;
	int i = 0;
	int rate = 0;

	bank = (wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev,
					wcd938x->tx_swr_dev->dev_num) ? 0 : 1);

	bank = wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev,
						wcd938x->tx_swr_dev->dev_num);
	wcd938x_swr_slv_set_host_clk_div2(wcd938x->tx_swr_dev,
					  wcd938x->tx_swr_dev->dev_num, bank);
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
		    wcd938x->tx_swr_dev->dev_num,
		    true);
		if (strnstr(w->name, "ADC", sizeof("ADC"))) {
			if (test_bit(WCD_ADC1, &wcd938x->status_mask))
			mode |= wcd938x->tx_mode[WCD_ADC1];
				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
			if (test_bit(WCD_ADC2, &wcd938x->status_mask))
			mode |= wcd938x->tx_mode[WCD_ADC2];
				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
			if (test_bit(WCD_ADC3, &wcd938x->status_mask))
			mode |= wcd938x->tx_mode[WCD_ADC3];
				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
			if (test_bit(WCD_ADC4, &wcd938x->status_mask))
			mode |= wcd938x->tx_mode[WCD_ADC4];
		wcd938x_set_swr_clk_rate(component, mode, bank);
				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];

			if (mode != 0) {
				for (i = 0; i < ADC_MODE_ULP2; i++) {
					if (mode & (1 << i)) {
						i++;
						break;
					}
				}
			}
			rate = wcd938x_get_clk_rate(i);
			wcd938x_set_swr_clk_rate(component, rate, bank);
		}
		ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
		    wcd938x->tx_swr_dev->dev_num,
		    true);
		if (strnstr(w->name, "ADC", sizeof("ADC"))) {
			/* Copy clk settings to active bank */
			wcd938x_set_swr_clk_rate(component, rate, !bank);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (strnstr(w->name, "ADC", sizeof("ADC"))) {
			rate = wcd938x_get_clk_rate(ADC_MODE_INVALID);
			wcd938x_set_swr_clk_rate(component, rate, !bank);
		}
		ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev,
		    wcd938x->tx_swr_dev->dev_num,
		    false);
		wcd938x_set_swr_clk_rate(component, ADC_MODE_INVALID, bank);
		if (strnstr(w->name, "ADC", sizeof("ADC")))
			wcd938x_set_swr_clk_rate(component, rate, bank);
		break;
	};

@@ -1521,6 +1588,7 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
	struct snd_soc_component *component =
					snd_soc_dapm_to_component(w->dapm);
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
	int clk_rate = 0;

	dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
		w->name, event);
@@ -1532,19 +1600,25 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
		snd_soc_component_update_bits(component,
				WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
		set_bit(w->shift, &wcd938x->status_mask);
		clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]);
		/* Enable BCS for Headset mic */
		if (w->shift == 1 && !(snd_soc_component_read32(component,
				WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) {
			wcd938x_tx_connect_port(component, MBHC, true);
			if (!wcd938x->bcs_dis)
				wcd938x_tx_connect_port(component, MBHC,
						SWR_CLK_RATE_4P8MHZ, true);
			set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
		}
		wcd938x_tx_connect_port(component, ADC1 + (w->shift), true);
		wcd938x_tx_connect_port(component, ADC1 + (w->shift), clk_rate,
					true);
		break;
	case SND_SOC_DAPM_POST_PMD:
		wcd938x_tx_connect_port(component, ADC1 + (w->shift), false);
		wcd938x_tx_connect_port(component, ADC1 + (w->shift), 0, false);
		if (w->shift == 1 &&
			test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) {
			wcd938x_tx_connect_port(component, MBHC, false);
			if (!wcd938x->bcs_dis)
				wcd938x_tx_connect_port(component, MBHC, 0,
							false);
			clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask);
		}
		snd_soc_component_update_bits(component,
@@ -2305,6 +2379,30 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol,
	return 0;
}

static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component =
				snd_soc_kcontrol_component(kcontrol);
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);

	ucontrol->value.integer.value[0] = wcd938x->bcs_dis;

	return 0;
}

static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component =
			snd_soc_kcontrol_component(kcontrol);
	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);

	wcd938x->bcs_dis = ucontrol->value.integer.value[0];

	return 0;
}

static const char * const tx_mode_mux_text_wcd9380[] = {
	"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
};
@@ -2391,6 +2489,9 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
	SOC_SINGLE_EXT("LDOH Enable", SND_SOC_NOPM, 0, 1, 0,
		wcd938x_ldoh_get, wcd938x_ldoh_put),

	SOC_SINGLE_EXT("ADC2_BCS Disable", SND_SOC_NOPM, 0, 1, 0,
		wcd938x_bcs_get, wcd938x_bcs_put),

	SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 20, 1, line_gain),
	SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 20, 1, line_gain),
	SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0,
+26 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */
#include <linux/init.h>
@@ -5471,6 +5471,10 @@ static int get_ec_ref_port_id(int value, int *index)
		*index = 38;
		port_id = AFE_PORT_ID_SENARY_MI2S_RX;
		break;
	case 39:
		*index = 39;
		port_id = AFE_PORT_ID_SENARY_MI2S_TX;
		break;
	default:
		*index = 0; /* NONE */
		pr_err("%s: Invalid value %d\n", __func__, value);
@@ -5528,7 +5532,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX",
	"WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2",
	"SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2",
	"RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0",
	"DISPLAY_PORT1", "SEN_MI2S_RX",
	"DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX",
};
static const struct soc_enum msm_route_ec_ref_rx_enum[] = {
@@ -5761,7 +5765,7 @@ static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX",
					"SEC_MI2S_TX", "TERT_MI2S_TX",
					"QUAT_MI2S_TX", "QUIN_MI2S_TX",
					"SLIM_1_TX", "PRI_TDM_TX",
					"SEC_TDM_TX"};
					"SEC_TDM_TX", "SENARY_MI2S_TX"};
static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = {
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx),
@@ -22970,6 +22974,9 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = {
		.info   = msm_source_tracking_info,
		.get    = msm_audio_source_tracking_get,
	},
};
static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = {
	{
		.access = SNDRV_CTL_ELEM_ACCESS_READ,
		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -29712,6 +29719,20 @@ static const struct snd_pcm_ops msm_routing_pcm_ops = {
	.prepare        = msm_pcm_routing_prepare,
};
#ifdef CONFIG_DOA_PARAMS_ENABLED
void msm_routing_add_doa_control(struct snd_soc_component *component)
{
	snd_soc_add_component_controls(component,
				msm_source_doa_tracking_controls,
				ARRAY_SIZE(msm_source_doa_tracking_controls));
}
#else
void msm_routing_add_doa_control(struct snd_soc_component *component)
{
	return;
}
#endif
/* Not used but frame seems to require it */
static int msm_routing_probe(struct snd_soc_component *component)
{
@@ -29781,6 +29802,8 @@ static int msm_routing_probe(struct snd_soc_component *component)
		msm_routing_be_dai_name_table_mixer_controls,
		ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls));
	/* Add doa control based on config */
	msm_routing_add_doa_control(component);
	snd_soc_add_component_controls(component, msm_source_tracking_controls,
				ARRAY_SIZE(msm_source_tracking_controls));
	snd_soc_add_component_controls(component, adm_channel_config_controls,
Loading