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

Commit 5cd13034 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: msm: add support for MIC-GND swap switch"

parents 5cc49c21 6380abb4
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -504,9 +504,17 @@ normally open.
switch type on target typically the switch type will be normally open or
normally close, value for this property 0 for normally close and 1 for
normally open.
- pinctrl-names : Pincntrl entries to configure the PDM gpio lines accordingly
- pinctrl-0 : This exoplains the active state of the PDM gpio lines
- pinctrl-1 : This exoplains the suspend state of the PDM gpio lines
- pinctrl-names : Pincntrl entries to configure the PDM gpio lines and
		  cross connection switch gpio accordingly
- pinctrl-0 : This explains the active state of the PDM gpio lines
- pinctrl-1 : This explains the suspend state of the PDM gpio lines
- pinctrl-2 : This explains the active state of the cross connection
	      gpio lines
- pinctrl-3 : This explains the suspend state of the cross connection
              gpio lines

Optional Properties:
- qcom,us-euro-gpios : GPIO on which gnd/mic swap signal is coming.

Example:

@@ -517,6 +525,7 @@ Example:
		qcom,msm-codec-type = "internal";
		qcom,msm-mbhc-hphl-swh = <0>;
		qcom,msm-mbhc-gnd-swh = <0>;
		qcom,cdc-us-euro-gpios = <&msmgpio 120 0>;
		qcom,audio-routing =
			"RX_BIAS", "MCLK",
			"INT_LDO_H", "MCLK",
@@ -527,9 +536,13 @@ Example:
			"AMIC2", "MIC BIAS Internal2",
			"AMIC3", "MIC BIAS External";
		pinctrl-names = "cdc_pdm_lines_act",
				"cdc_pdm_lines_sus";
				"cdc_pdm_lines_sus",
				"cross_conn_det_act",
				"cross_conn_det_sus";
		pinctrl-0 = <&cdc_pdm_lines_act>;
		pinctrl-1 = <&cdc_pdm_lines_sus>;
		pinctrl-2 = <&cross_conn_det_act>;
		pinctrl-3 = <&cross_conn_det_sus>;
	};

* MSM8974 ASoC Machine driver
+1 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ struct msm8x16_wcd_regulator {

struct msm8916_asoc_mach_data {
	int codec_type;
	int us_euro_gpio;
	atomic_t mclk_rsc_ref;
	atomic_t dis_work_mclk;
	struct mutex cdc_mclk_mutex;
+20 −0
Original line number Diff line number Diff line
@@ -441,6 +441,7 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
		if (!result1 && !(swap_res & 0x04)) {
			plug_type = PLUG_TYPE_GND_MIC_SWAP;
			pr_debug("%s: Cross connection identified", __func__);
			goto eu_us_switch;
		} else {
			pr_debug("%s: No Cross connection found", __func__);
		}
@@ -468,6 +469,25 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
			goto exit;
		}
	}

eu_us_switch:
	if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
		pr_debug("%s: cross connection found\n", __func__);
		if (mbhc->mbhc_cfg->swap_gnd_mic) {
			pr_debug("%s: US_EU gpio present, flip switch\n",
				__func__);
			if (mbhc->mbhc_cfg->swap_gnd_mic(codec))
				plug_type = PLUG_TYPE_HEADSET;
		}
		/* Disable micbias and schmitt trigger */
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2,
			0x6, 0x0);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MICB_2_EN,
			0x80, 0x00);
	}

	pr_debug("%s: Valid plug found, plug type is %d\n",
			 __func__, plug_type);
	wcd_mbhc_find_plug_and_report(mbhc, plug_type);
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct wcd_mbhc_config {
	void *calibration;
	bool detect_extn_cable;
	bool mono_stero_detection;
	bool (*swap_gnd_mic) (struct snd_soc_codec *codec);
};

struct wcd_mbhc_intr {
+71 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ static struct wcd_mbhc_config mbhc_cfg = {
	.calibration = NULL,
	.detect_extn_cable = true,
	.mono_stero_detection = false,
	.swap_gnd_mic = NULL,
};

static struct afe_clk_cfg mi2s_rx_clk = {
@@ -82,6 +83,8 @@ struct cdc_pdm_pinctrl_info {
	struct pinctrl *pinctrl;
	struct pinctrl_state *cdc_pdm_sus;
	struct pinctrl_state *cdc_pdm_act;
	struct pinctrl_state *cross_conn_det_sus;
	struct pinctrl_state *cross_conn_det_act;
};

static struct cdc_pdm_pinctrl_info pinctrl_info;
@@ -970,7 +973,29 @@ static int cdc_pdm_get_pinctrl(struct platform_device *pdev)
		pr_err("%s: Failed to disable the TLMM pins\n", __func__);
		return -EIO;
	}
	/* get pinctrl handle for cross det pin*/
	pinctrl_info.cross_conn_det_sus = pinctrl_lookup_state(pinctrl,
							"cross_conn_det_sus");
	if (IS_ERR(pinctrl_info.cross_conn_det_sus)) {
		pr_err("%s: Unable to get pinctrl disable state handle\n",
								__func__);
		return -EINVAL;
	}

	pinctrl_info.cross_conn_det_act = pinctrl_lookup_state(pinctrl,
							"cross_conn_det_act");
	if (IS_ERR(pinctrl_info.cross_conn_det_act)) {
		pr_err("%s: Unable to get pinctrl active state handle\n",
								 __func__);
		return -EINVAL;
	}
	/* Reset cross conn det pins to default state*/
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
					pinctrl_info.cross_conn_det_sus);
	if (ret != 0) {
		pr_err("%s: Failed to disable cross conn det pins\n", __func__);
		return -EIO;
	}
	return 0;
}

@@ -998,6 +1023,50 @@ void enable_mclk(struct work_struct *work)
	mutex_unlock(&pdata->cdc_mclk_mutex);
}

static bool msm8x16_swap_gnd_mic(struct snd_soc_codec *codec)
{
	struct snd_soc_card *card = codec->card;
	struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	int value, ret;

	if (!gpio_is_valid(pdata->us_euro_gpio)) {
		pr_debug("%s: Invalid gpio: %d", __func__, pdata->us_euro_gpio);
		return false;
	}
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
				pinctrl_info.cross_conn_det_act);
	if (ret < 0) {
		pr_err("failed to configure the gpio\n");
		return ret;
	}
	value = gpio_get_value_cansleep(pdata->us_euro_gpio);
	gpio_direction_output(pdata->us_euro_gpio, !value);
	pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
				pinctrl_info.cross_conn_det_sus);
	if (ret < 0) {
		pr_err("failed to configure the gpio\n");
		return ret;
	}

	return true;
}

static void msm8x16_setup_hs_jack(struct platform_device *pdev,
			struct msm8916_asoc_mach_data *pdata)
{
	pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node,
					"qcom,cdc-us-euro-gpios", 0);
	if (pdata->us_euro_gpio < 0) {
		dev_dbg(&pdev->dev,
			"property %s in node %s not found %d\n",
			"qcom,cdc-us-euro-gpios", pdev->dev.of_node->full_name,
			pdata->us_euro_gpio);
	} else {
		mbhc_cfg.swap_gnd_mic = msm8x16_swap_gnd_mic;
	}
}

static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card;
@@ -1065,6 +1134,8 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
	}
	card = &bear_cards[pdev->id];

	msm8x16_setup_hs_jack(pdev, pdata);

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, pdata);