From patchwork Wed Dec 12 09:25:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 1011708 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43FBJg42X5z9sMQ; Wed, 12 Dec 2018 20:26:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1gX0mb-0000Op-0v; Wed, 12 Dec 2018 09:26:21 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1gX0mW-0000Kz-Nt for kernel-team@lists.ubuntu.com; Wed, 12 Dec 2018 09:26:16 +0000 Received: from [125.35.49.90] (helo=hwang4-Lenovo-V480c.bluefin) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gX0mV-0002iI-RG for kernel-team@lists.ubuntu.com; Wed, 12 Dec 2018 09:26:16 +0000 From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic/OEM-B][PATCH 5/6] UBUNTU: SAUCE: ASoC: Intel: (no-up) Update Skylake/Kabylake alc3277 i2s machine driver Date: Wed, 12 Dec 2018 17:25:58 +0800 Message-Id: <20181212092600.4505-6-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181212092600.4505-1-hui.wang@canonical.com> References: <20181212092600.4505-1-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" 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 --- sound/soc/intel/boards/kbl_rt5660.c | 146 ++++++++++++++-------------- 1 file changed, 74 insertions(+), 72 deletions(-) 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 */