From patchwork Wed Apr 11 07:18:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shrirang Bagul X-Patchwork-Id: 897056 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]) by ozlabs.org (Postfix) with ESMTP id 40Lb4R3JXpz9s47; Wed, 11 Apr 2018 17:18:47 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1f6A1h-0007GS-QS; Wed, 11 Apr 2018 07:18:41 +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 1f6A1f-0007G7-Qh for kernel-team@lists.ubuntu.com; Wed, 11 Apr 2018 07:18:39 +0000 Received: from 1.general.shrirang--bagul.uk.vpn ([10.172.198.4] helo=snb-ubuntu.taipei) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1f6A1e-0003oM-LH for kernel-team@lists.ubuntu.com; Wed, 11 Apr 2018 07:18:39 +0000 From: Shrirang Bagul To: kernel-team@lists.ubuntu.com Subject: [bionic][PATCH 1/4] UBUNTU: SAUCE: (no-up) ASoC: Intel: Support machine driver for RT5660 on Baytrail Date: Wed, 11 Apr 2018 15:18:28 +0800 Message-Id: <20180411071831.23472-2-shrirang.bagul@canonical.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180411071831.23472-1-shrirang.bagul@canonical.com> References: <20180411071831.23472-1-shrirang.bagul@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: http://bugs.launchpad.net/bugs/1657674 Dell Caracalla IoT gateways sport an RT5660 codec with HID 10EC3277. This patch adds the machine driver required to support RT5660 codec on Baytrail based systems. Signed-off-by: Shrirang Bagul Acked-by: Tim Gardner Acked-by: Brad Figg Signed-off-by: Luis Henriques (backported from commit 7d3d1a863e73ff832f633e8f497a9adcee228fd0) (source: git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git) Signed-off-by: Shrirang Bagul --- sound/soc/intel/boards/Kconfig | 12 + sound/soc/intel/boards/Makefile | 2 + sound/soc/intel/boards/bytcr_rt5660.c | 293 ++++++++++++++++++++++ sound/soc/intel/common/soc-acpi-intel-byt-match.c | 9 + 4 files changed, 316 insertions(+) create mode 100644 sound/soc/intel/boards/bytcr_rt5660.c diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 6f754708a48c..afe8c3514c5e 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -93,6 +93,18 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH Say Y if you have such a device. If unsure select "N". +config SND_SOC_INTEL_BYTCR_RT5660_MACH + tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5660 codec" + depends on X86 && I2C && ACPI + select SND_SOC_RT5660 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR + platforms with RT5660 audio codec. + Say Y if you have such a device. + If unsure select "N". + config SND_SOC_INTEL_CHT_BSW_RT5672_MACH tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" depends on X86_INTEL_LPSS && I2C && ACPI diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 69d2dfaeb00c..b803c5148a0b 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -8,6 +8,7 @@ snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o snd-soc-sst-bxt-rt298-objs := bxt_rt298.o snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o +snd-soc-sst-bytcr-rt5660-objs := bytcr_rt5660.o snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o @@ -29,6 +30,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o +obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH) += snd-soc-sst-bytcr-rt5660.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o diff --git a/sound/soc/intel/boards/bytcr_rt5660.c b/sound/soc/intel/boards/bytcr_rt5660.c new file mode 100644 index 000000000000..fb628894d9ba --- /dev/null +++ b/sound/soc/intel/boards/bytcr_rt5660.c @@ -0,0 +1,293 @@ +/* + * Intel Baytrail SST RT5660 machine driver + * Copyright (C) 2016 Shrirang Bagul + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../codecs/rt5660.h" +#include "../atom/sst-atom-controls.h" +#include "../common/sst-dsp.h" + +struct byt_rt5660_private { + struct gpio_desc *gpio_lo_mute; +}; + +static int byt_rt5660_event_lineout(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct byt_rt5660_private *priv = snd_soc_card_get_drvdata(card); + + gpiod_set_value_cansleep(priv->gpio_lo_mute, + !(SND_SOC_DAPM_EVENT_ON(event))); + + return 0; +} + +static const struct snd_soc_dapm_widget byt_rt5660_widgets[] = { + SND_SOC_DAPM_MIC("Line In", NULL), + SND_SOC_DAPM_LINE("Line Out", byt_rt5660_event_lineout), +}; + +static const struct snd_soc_dapm_route byt_rt5660_audio_map[] = { + {"IN1P", NULL, "Line In"}, + {"IN2P", NULL, "Line In"}, + {"Line Out", NULL, "LOUTR"}, + {"Line Out", NULL, "LOUTL"}, + + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_kcontrol_new byt_rt5660_controls[] = { + SOC_DAPM_PIN_SWITCH("Line In"), + SOC_DAPM_PIN_SWITCH("Line Out"), +}; + +static int byt_rt5660_aif1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + snd_soc_dai_set_bclk_ratio(codec_dai, 50); + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5660_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set codec clock %d\n", ret); + return ret; + } + + /* use bitclock as PLL input */ + /* 2x15 bit slots on SSP2 */ + 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); + return ret; + } + + return 0; +} + +static int byt_rt5660_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_card *card = runtime->card; + struct byt_rt5660_private *priv = snd_soc_card_get_drvdata(card); + struct snd_soc_codec *codec = runtime->codec; + + /* Request rt5660 GPIO for lineout mute control */ + priv->gpio_lo_mute = devm_gpiod_get_index(codec->dev, + "lineout-mute", 0, 0); + if (IS_ERR(priv->gpio_lo_mute)) { + dev_err(card->dev, "Can't find GPIO_MUTE# gpio\n"); + return PTR_ERR(priv->gpio_lo_mute); + } + + return gpiod_direction_output(priv->gpio_lo_mute, 1); +} + +static const struct snd_soc_pcm_stream byt_rt5660_dai_params = { + .formats = SNDRV_PCM_FMTBIT_S24_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, +}; + +static int byt_rt5660_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int ret; + + /* The DSP will covert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + /* + * Default mode for SSP configuration is TDM 4 slot, override config + * with explicit setting to I2S 2ch 24-bit. The word length is set with + * dai_set_tdm_slot() since there is no other API exposed + */ + ret = snd_soc_dai_set_fmt(rtd->cpu_dai, + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS + ); + if (ret < 0) { + dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); + if (ret < 0) { + dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); + return ret; + } + + return 0; +} + +static int byt_rt5660_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, 48000); +} + +static struct snd_soc_ops byt_rt5660_aif1_ops = { + .startup = byt_rt5660_aif1_startup, +}; + +static struct snd_soc_ops byt_rt5660_be_ssp2_ops = { + .hw_params = byt_rt5660_aif1_hw_params, +}; + +static struct snd_soc_dai_link byt_rt5660_dais[] = { + [MERR_DPCM_AUDIO] = { + .name = "Baytrail Audio Port", + .stream_name = "Baytrail Audio", + .cpu_dai_name = "media-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_rt5660_aif1_ops, + }, + [MERR_DPCM_DEEP_BUFFER] = { + .name = "Deep-Buffer Audio Port", + .stream_name = "Deep-Buffer Audio", + .cpu_dai_name = "deepbuffer-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &byt_rt5660_aif1_ops, + }, + /* back ends */ + { + .name = "SSP2-Codec", + .id = 0, + .cpu_dai_name = "ssp2-port", + .platform_name = "sst-mfld-platform", + .no_pcm = 1, + .codec_dai_name = "rt5660-aif1", + .codec_name = "i2c-10EC3277:00", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_rt5660_codec_fixup, + .ignore_suspend = 1, + .nonatomic = true, + .dpcm_playback = 1, + .dpcm_capture = 1, + .init = byt_rt5660_init, + .ops = &byt_rt5660_be_ssp2_ops, + }, +}; + +static struct snd_soc_card byt_rt5660_card = { + .name = "baytrailcraudio", + .owner = THIS_MODULE, + .dai_link = byt_rt5660_dais, + .num_links = ARRAY_SIZE(byt_rt5660_dais), + .dapm_widgets = byt_rt5660_widgets, + .num_dapm_widgets = ARRAY_SIZE(byt_rt5660_widgets), + .dapm_routes = byt_rt5660_audio_map, + .num_dapm_routes = ARRAY_SIZE(byt_rt5660_audio_map), + .controls = byt_rt5660_controls, + .num_controls = ARRAY_SIZE(byt_rt5660_controls), + .fully_routed = true, +}; + +static int byt_rt5660_probe(struct platform_device *pdev) +{ + int ret_val = 0; + struct byt_rt5660_private *priv; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); + if (!priv) + return -ENOMEM; + + byt_rt5660_card.dev = &pdev->dev; + snd_soc_card_set_drvdata(&byt_rt5660_card, priv); + ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5660_card); + + if (ret_val) { + dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", + ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &byt_rt5660_card); + return ret_val; +} + +static int byt_rt5660_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct byt_rt5660_private *priv = snd_soc_card_get_drvdata(card); + + devm_gpiod_put(&pdev->dev, priv->gpio_lo_mute); + + return 0; +} + +static struct platform_driver byt_rt5660_audio = { + .probe = byt_rt5660_probe, + .remove = byt_rt5660_remove, + .driver = { + .name = "bytcr_rt5660", + }, +}; +module_platform_driver(byt_rt5660_audio) + +MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); +MODULE_AUTHOR("Shrirang Bagul"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:bytcr_rt5660"); diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c index bfe1ca68a542..c3a6e6361331 100644 --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c @@ -129,6 +129,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = { .sof_tplg_filename = "intel/reef-byt-rt5651.tplg", .asoc_plat_name = "sst-mfld-platform", }, + { + .id = "10EC3277", + .drv_name = "bytcr_rt5660", + .fw_filename = "intel/fw_sst_0f28.bin", + .board = "bytcr_rt5660", + .sof_fw_filename = "intel/reef-byt.ri", + .sof_tplg_filename = "intel/reef-byt-rt5660.tplg", + .asoc_plat_name = "sst-mfld-platform", + }, { .id = "DLGS7212", .drv_name = "bytcht_da7213",