[SRU,Bionic/OEM-B,5/6] UBUNTU: SAUCE: ASoC: Intel: (no-up) Update Skylake/Kabylake alc3277 i2s machine driver
diff mbox series

Message ID 20181212092600.4505-6-hui.wang@canonical.com
State New
Headers show
Series
  • Add support for ALC3277 codec on new Dell edge gateways
Related show

Commit Message

Hui Wang Dec. 12, 2018, 9:25 a.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1807334

Add jack detection GPIO and change to use BCLK rather than MCLK for codec.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 sound/soc/intel/boards/kbl_rt5660.c | 146 ++++++++++++++--------------
 1 file changed, 74 insertions(+), 72 deletions(-)

Patch
diff mbox series

diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
index b0c6383d77ba..9e5498885c3a 100644
--- a/sound/soc/intel/boards/kbl_rt5660.c
+++ b/sound/soc/intel/boards/kbl_rt5660.c
@@ -85,39 +85,66 @@  static const struct snd_soc_dapm_route kabylake_5660_map[] = {
 	{"Line Out", NULL, "LOUTR"},
 	{"Line Out", NULL, "LOUTL"},
 
-
-	{ "HDMI", NULL, "hif5 Output" },
-	{ "DP", NULL, "hif6 Output" },
-
 	/* CODEC BE connections */
 	{ "AIF1 Playback", NULL, "ssp0 Tx"},
 	{ "ssp0 Tx", NULL, "codec0_out"},
-	{ "ssp0 Tx", NULL, "codec1_out"},
 
 	{ "codec0_in", NULL, "ssp0 Rx" },
-	{ "codec1_in", NULL, "ssp0 Rx" },
+
 	{ "ssp0 Rx", NULL, "AIF1 Capture" },
 
-	{ "hifi3", NULL, "iDisp3 Tx"},
-	{ "iDisp3 Tx", NULL, "iDisp3_out"},
 	{ "hifi2", NULL, "iDisp2 Tx"},
 	{ "iDisp2 Tx", NULL, "iDisp2_out"},
 	{ "hifi1", NULL, "iDisp1 Tx"},
 	{ "iDisp1 Tx", NULL, "iDisp1_out"},
 };
 
-static const struct acpi_gpio_params lineout_mute_gpio = { 0, 0, true };
+#define GPIO_LINEOUT_MUTE_INDEX 0
+#define GPIO_LINEOUT_DET_INDEX 3
+#define GPIO_LINEIN_DET_INDEX 4
+
+static const struct acpi_gpio_params lineout_mute_gpio = { GPIO_LINEOUT_MUTE_INDEX, 0, true };
+static const struct acpi_gpio_params lineout_det_gpio = { GPIO_LINEOUT_DET_INDEX, 0, false };
+static const struct acpi_gpio_params mic_det_gpio = { GPIO_LINEIN_DET_INDEX, 0, false };
 
 static const struct acpi_gpio_mapping acpi_rt5660_gpios[] = {
 	{ "lineout-mute-gpios", &lineout_mute_gpio , 1 },
+	{ "lineout-det-gpios", &lineout_det_gpio, 1 },
+	{ "mic-det-gpios", &mic_det_gpio, 1 },
 	{ NULL },
 };
 
+static struct snd_soc_jack lineout_jack;
+static struct snd_soc_jack mic_jack;
+
+static struct snd_soc_jack_pin lineout_jack_pin = {
+	.pin	= "Line Out",
+	.mask	= SND_JACK_LINEOUT,
+};
+
+static struct snd_soc_jack_pin mic_jack_pin = {
+	.pin	= "Line In",
+	.mask	= SND_JACK_MICROPHONE,
+};
+
+static struct snd_soc_jack_gpio lineout_jack_gpio = {
+	.name			= "lineout-det",
+	.report			= SND_JACK_LINEOUT,
+	.debounce_time		= 200,
+};
+
+static struct snd_soc_jack_gpio mic_jack_gpio = {
+	.name			= "mic-det",
+	.report			= SND_JACK_MICROPHONE,
+	.debounce_time		= 200,
+};
+
 static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct kbl_rt5660_private *ctx = snd_soc_card_get_drvdata(rtd->card);
 	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 
 	ret = devm_acpi_dev_add_driver_gpios(codec->dev, acpi_rt5660_gpios);
 	if (ret)
@@ -131,6 +158,33 @@  static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
 		return PTR_ERR(ctx->gpio_lo_mute);
 	}
 
+	/* Create and initialize headphone jack */
+	if (!snd_soc_card_jack_new(rtd->card, "Lineout Jack",
+			SND_JACK_LINEOUT, &lineout_jack,
+			&lineout_jack_pin, 1)) {
+		lineout_jack_gpio.gpiod_dev = codec->dev;
+		if (snd_soc_jack_add_gpios(&lineout_jack, 1,
+				&lineout_jack_gpio))
+			dev_err(codec->dev, "Can't add Lineout jack gpio\n");
+	} else {
+		dev_err(codec->dev, "Can't create Lineout jack\n");
+	}
+
+	/* Create and initialize mic jack */
+	if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
+			SND_JACK_MICROPHONE, &mic_jack,
+			&mic_jack_pin, 1)) {
+		mic_jack_gpio.gpiod_dev = codec->dev;
+		if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
+			dev_err(codec->dev, "Can't add mic jack gpio\n");
+	} else {
+		dev_err(codec->dev, "Can't create mic jack\n");
+	}
+
+	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
+	snd_soc_dapm_force_enable_pin(dapm, "BST1");
+	snd_soc_dapm_force_enable_pin(dapm, "BST2");
+
 	return ret;
 }
 
@@ -226,25 +280,17 @@  static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
 	struct snd_soc_dpcm *dpcm = container_of(
 			params, struct snd_soc_dpcm, hw_params);
 	struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
-	struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
 
 	/*
 	 * The ADSP will convert the FE rate to 48k, stereo, 24 bit
 	 */
 	if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
-	    !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
 	    !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
 		rate->min = rate->max = 48000;
 		channels->min = channels->max = 2;
 		snd_mask_none(fmt);
 		snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
 	}
-	/*
-	 * The speaker on the SSP0 supports S16_LE and not S24_LE.
-	 * thus changing the mask here
-	 */
-	if (!strcmp(be_dai_link->name, "SSP0-Codec"))
-		snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE);
 
 	return 0;
 }
@@ -257,68 +303,24 @@  static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream,
 	int ret;
 
 	ret = snd_soc_dai_set_sysclk(codec_dai,
-			RT5660_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
-	if (ret < 0)
-		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
-
-	return ret;
-}
-
-static struct snd_soc_ops kabylake_rt5660_ops = {
-	.hw_params = kabylake_rt5660_hw_params,
-};
-
-static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
-					struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	int ret = 0;
-
-	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+			RT5660_SCLK_S_PLL1, params_rate(params) * 512, SND_SOC_CLOCK_IN);
 	if (ret < 0) {
-		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
+		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
 		return ret;
 	}
 
-	return ret;
-}
-
-static struct snd_soc_ops kabylake_ssp0_ops = {
-	.hw_params = kabylake_ssp0_hw_params,
-};
-
-static unsigned int rates_16000[] = {
-	16000,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_16000 = {
-	.count = ARRAY_SIZE(rates_16000),
-	.list  = rates_16000,
-};
-
-static const unsigned int ch_mono[] = {
-	1,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_refcap = {
-	.count = ARRAY_SIZE(ch_mono),
-	.list  = ch_mono,
-};
+	ret = snd_soc_dai_set_pll(codec_dai, 0,
+				RT5660_PLL1_S_BCLK,
+				params_rate(params) * 50,
+				params_rate(params) * 512);
+	if (ret < 0)
+		dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
 
-static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
-{
-	substream->runtime->hw.channels_max = 1;
-	snd_pcm_hw_constraint_list(substream->runtime, 0,
-					SNDRV_PCM_HW_PARAM_CHANNELS,
-					&constraints_refcap);
-
-	return snd_pcm_hw_constraint_list(substream->runtime, 0,
-				SNDRV_PCM_HW_PARAM_RATE,
-				&constraints_16000);
+	return ret;
 }
 
-static struct snd_soc_ops skylaye_refcap_ops = {
-	.startup = kabylake_refcap_startup,
+static struct snd_soc_ops kabylake_rt5660_ops = {
+	.hw_params = kabylake_rt5660_hw_params,
 };
 
 /* kabylake digital audio interface glue - connects codec <--> CPU */