[bionic][PATCH 0/4] Add support for RT5660 codec based sound cards on Baytrail

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[bionic][PATCH 0/4] Add support for RT5660 codec based sound cards on Baytrail

Shrirang Bagul
BugLink: http://bugs.launchpad.net/bugs/1657674

This work is based on bionic/master-next (tag: Ubuntu-4.15.0-15.16)

Dell Caracalla IoT gateways have RT5660 codec (HID: 10EC3277) connected to
Baytrail SoC over I2S. The hardware supports line-in and line-out ports.

This patch set adds a new plafrom sound card driver bytcr_rt5660 to connect
RT5660 codec FE DAI's to Intel SST audio BE DAI's. It also adds ACPI
support to RT5660 codec driver.

Multiple attempts have been made to upstream this driver-

1. http://mailman.alsa-project.org/pipermail/alsa-devel/2016-December/115928.html
2. http://mailman.alsa-project.org/pipermail/alsa-devel/2017-January/116510.html

but without much success. HWE will continue to get this driver upstreamed,
till then we'll have to carry it as sauce patches to meet project release
schedule.

Luis Henriques (1):
  UBUNTU: [Config] CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH=m, CONFIG_SND_SOC_RT5660=m

Shrirang Bagul (3):
  UBUNTU: SAUCE: (no-up) ASoC: Intel: Support machine driver for RT5660 on Baytrail
  UBUNTU: SAUCE: (no-up) ASoC: rt5660: Add ACPI support
  UBUNTU: SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Add MCLK, quirks

 debian.master/config/config.common.ubuntu         |   2 +
 sound/soc/codecs/rt5660.c                         |  26 ++
 sound/soc/intel/boards/Kconfig                    |  12 +
 sound/soc/intel/boards/Makefile                   |   2 +
 sound/soc/intel/boards/bytcr_rt5660.c             | 429 ++++++++++++++++++++++
 sound/soc/intel/common/soc-acpi-intel-byt-match.c |   9 +
 6 files changed, 480 insertions(+)
 create mode 100644 sound/soc/intel/boards/bytcr_rt5660.c

--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[bionic][PATCH 1/4] UBUNTU: SAUCE: (no-up) ASoC: Intel: Support machine driver for RT5660 on Baytrail

Shrirang Bagul
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 <[hidden email]>
Acked-by: Tim Gardner <[hidden email]>
Acked-by: Brad Figg <[hidden email]>
Signed-off-by: Luis Henriques <[hidden email]>
(backported from commit 7d3d1a863e73ff832f633e8f497a9adcee228fd0)
(source: git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 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 <[hidden email]>
+ *
+ *  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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/platform_sst_audio.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/soc-acpi.h>
+#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",
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[bionic][PATCH 2/4] UBUNTU: SAUCE: (no-up) ASoC: rt5660: Add ACPI support

Shrirang Bagul
In reply to this post by Shrirang Bagul
BugLink: http://bugs.launchpad.net/bugs/1657674

On Dell IoT Gateways, RT5660 codec is available with ACPI ID 10EC3277.
Also, GPIO's are only available by index, so we register mappings to allow
machine drivers to access them by name.

Signed-off-by: Shrirang Bagul <[hidden email]>
Acked-by: Tim Gardner <[hidden email]>
Acked-by: Brad Figg <[hidden email]>
Signed-off-by: Luis Henriques <[hidden email]>
(cherry picked from commit 08b421848245f749d449f8db4d664e377f8100e3)
(source: git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 sound/soc/codecs/rt5660.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c
index d22ef00e0d96..39dc2289d651 100644
--- a/sound/soc/codecs/rt5660.c
+++ b/sound/soc/codecs/rt5660.c
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -1245,10 +1246,31 @@ MODULE_DEVICE_TABLE(of, rt5660_of_match);
 
 static const struct acpi_device_id rt5660_acpi_match[] = {
  { "10EC5660", 0 },
+ { "10EC3277", 0 },
  { },
 };
 MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match);
 
+static const struct acpi_gpio_params audio_wake_intr_gpio = { 0, 0, false };
+static const struct acpi_gpio_params lineout_mute_gpio = { 1, 0, true };
+
+static const struct acpi_gpio_mapping byt_rt5660_gpios[] = {
+ { "audio-wake-intr-gpios", &audio_wake_intr_gpio, 1 },
+ { "lineout-mute-gpios", &lineout_mute_gpio , 1 },
+ { NULL },
+};
+
+static void rt5660_read_acpi_properties(struct rt5660_priv *rt5660,
+ struct device *dev)
+{
+ int ret;
+
+ ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
+ byt_rt5660_gpios);
+ if (ret)
+ dev_warn(dev, "Failed to add driver gpios\n");
+}
+
 static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev)
 {
  rt5660->pdata.in1_diff = device_property_read_bool(dev,
@@ -1288,6 +1310,10 @@ static int rt5660_i2c_probe(struct i2c_client *i2c,
  rt5660->pdata = *pdata;
  else if (i2c->dev.of_node)
  rt5660_parse_dt(rt5660, &i2c->dev);
+ else if (ACPI_HANDLE(&i2c->dev))
+ rt5660_read_acpi_properties(rt5660, &i2c->dev);
+ else
+ return -EINVAL;
 
  rt5660->regmap = devm_regmap_init_i2c(i2c, &rt5660_regmap);
  if (IS_ERR(rt5660->regmap)) {
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[bionic][PATCH 3/4] UBUNTU: SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Add MCLK, quirks

Shrirang Bagul
In reply to this post by Shrirang Bagul
BugLink: http://bugs.launchpad.net/bugs/1657674

This patch adds support for using pmc_plt_clk_3 on Baytrail SoC to be
used as source of MCLK for RT5660 codec.

Signed-off-by: Shrirang Bagul <[hidden email]>
---
 sound/soc/intel/boards/bytcr_rt5660.c | 148 ++++++++++++++++++++++++++++++++--
 1 file changed, 142 insertions(+), 6 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5660.c b/sound/soc/intel/boards/bytcr_rt5660.c
index fb628894d9ba..f0e3e4125f07 100644
--- a/sound/soc/intel/boards/bytcr_rt5660.c
+++ b/sound/soc/intel/boards/bytcr_rt5660.c
@@ -34,10 +34,24 @@
 #include "../atom/sst-atom-controls.h"
 #include "../common/sst-dsp.h"
 
+#define BYT_RT5660_MCLK_EN BIT(17)
+#define BYT_RT5660_MCLK_25MHZ BIT(18)
+
 struct byt_rt5660_private {
+ struct clk *mclk;
  struct gpio_desc *gpio_lo_mute;
 };
 
+static unsigned long byt_rt5660_quirk = BYT_RT5660_MCLK_EN;
+
+static void log_quirks(struct device *dev)
+{
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_EN)
+ dev_info(dev, "quirk MCLK_EN enabled");
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_25MHZ)
+ dev_info(dev, "quirk MCLK_25MHZ enabled");
+}
+
 static int byt_rt5660_event_lineout(struct snd_soc_dapm_widget *w,
  struct snd_kcontrol *k, int event)
 {
@@ -51,12 +65,71 @@ static int byt_rt5660_event_lineout(struct snd_soc_dapm_widget *w,
  return 0;
 }
 
+#define BYT_CODEC_DAI1 "rt5660-aif1"
+
+static int platform_clock_control(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 snd_soc_dai *codec_dai;
+ struct byt_rt5660_private *priv = snd_soc_card_get_drvdata(card);
+ int ret;
+
+ codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+ if (!codec_dai) {
+ dev_err(card->dev,
+ "Codec dai not found; Unable to set platform clock\n");
+ return -EIO;
+ }
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_EN) {
+ ret = clk_prepare_enable(priv->mclk);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "could not configure MCLK state");
+ return ret;
+ }
+ }
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5660_SCLK_S_PLL1,
+     48000 * 512,
+     SND_SOC_CLOCK_IN);
+ } else {
+ /*
+ * Set codec clock source to internal clock before
+ * turning off the platform clock. Codec needs clock
+ * for Jack detection and button press
+ */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5660_SCLK_S_RCCLK,
+     48000 * 512,
+     SND_SOC_CLOCK_IN);
+ if (!ret)
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_EN)
+ clk_disable_unprepare(priv->mclk);
+ }
+
+ if (ret < 0) {
+ dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
+ return ret;
+ }
+
+ 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),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+    platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+    SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route byt_rt5660_audio_map[] = {
+ {"IN1P", NULL, "Platform Clock"},
+ {"IN2P", NULL, "Platform Clock"},
+ {"Line Out", NULL, "Platform Clock"},
+
  {"IN1P", NULL, "Line In"},
  {"IN2P", NULL, "Line In"},
  {"Line Out", NULL, "LOUTR"},
@@ -92,11 +165,25 @@ static int byt_rt5660_aif1_hw_params(struct snd_pcm_substream *substream,
  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 (!(byt_rt5660_quirk & BYT_RT5660_MCLK_EN)) {
+ /* 2x25 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);
+ } else {
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_25MHZ) {
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
+ RT5660_PLL1_S_MCLK,
+ 25000000,
+ params_rate(params) * 512);
+ } else {
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
+ RT5660_PLL1_S_MCLK,
+ 19200000,
+ params_rate(params) * 512);
+ }
+ }
 
  if (ret < 0) {
  dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
@@ -111,6 +198,7 @@ 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;
+ int ret;
 
  /* Request rt5660 GPIO for lineout mute control */
  priv->gpio_lo_mute = devm_gpiod_get_index(codec->dev,
@@ -120,7 +208,35 @@ static int byt_rt5660_init(struct snd_soc_pcm_runtime *runtime)
  return PTR_ERR(priv->gpio_lo_mute);
  }
 
- return gpiod_direction_output(priv->gpio_lo_mute, 1);
+ ret = gpiod_direction_output(priv->gpio_lo_mute, 1);
+ if (ret)
+ return ret;
+
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_EN) {
+ /*
+ * The firmware might enable the clock at
+ * boot (this information may or may not
+ * be reflected in the enable clock register).
+ * To change the rate we must disable the clock
+ * first to cover these cases. Due to common
+ * clock framework restrictions that do not allow
+ * to disable a clock that has not been enabled,
+ * we need to enable the clock first.
+ */
+ ret = clk_prepare_enable(priv->mclk);
+ if (!ret)
+ clk_disable_unprepare(priv->mclk);
+
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_25MHZ)
+ ret = clk_set_rate(priv->mclk, 25000000);
+ else
+ ret = clk_set_rate(priv->mclk, 19200000);
+
+ if (ret)
+ dev_err(card->dev, "unable to set MCLK rate\n");
+ }
+
+ return ret;
 }
 
 static const struct snd_soc_pcm_stream byt_rt5660_dai_params = {
@@ -257,6 +373,26 @@ static int byt_rt5660_probe(struct platform_device *pdev)
 
  byt_rt5660_card.dev = &pdev->dev;
  snd_soc_card_set_drvdata(&byt_rt5660_card, priv);
+
+ log_quirks(&pdev->dev);
+
+ if (byt_rt5660_quirk & BYT_RT5660_MCLK_EN) {
+ priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+ if (IS_ERR(priv->mclk)) {
+ dev_err(&pdev->dev,
+ "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
+ PTR_ERR(priv->mclk));
+ /*
+ * Fall back to bit clock usage for -ENOENT (clock not
+ * available likely due to missing dependencies), bail
+ * for all other errors, including -EPROBE_DEFER
+ */
+ if (ret_val != -ENOENT)
+ return ret_val;
+ byt_rt5660_quirk &= ~BYT_RT5660_MCLK_EN;
+ }
+ }
+
  ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5660_card);
 
  if (ret_val) {
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[bionic][PATCH 4/4] UBUNTU: [Config] CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH=m, CONFIG_SND_SOC_RT5660=m

Shrirang Bagul
In reply to this post by Shrirang Bagul
From: Luis Henriques <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1657674

Signed-off-by: Luis Henriques <[hidden email]>
(backported from commit 10c060402a75cb0edc1c66b93aed3cf1da1a4af5)
(source: git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 debian.master/config/config.common.ubuntu | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index 7ff46e6c6542..d1db3c2383f0 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -8501,6 +8501,7 @@ CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH=m
 CONFIG_SND_SOC_INTEL_BXT_RT298_MACH=m
 CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH=m
 CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH=m
+CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH=m
 CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
 CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m
 # CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set
@@ -8573,6 +8574,7 @@ CONFIG_SND_SOC_RT5631=m
 CONFIG_SND_SOC_RT5640=m
 CONFIG_SND_SOC_RT5645=m
 CONFIG_SND_SOC_RT5651=m
+CONFIG_SND_SOC_RT5660=m
 CONFIG_SND_SOC_RT5663=m
 CONFIG_SND_SOC_RT5670=m
 CONFIG_SND_SOC_RT5677=m
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED: [bionic][PATCH 0/4] Add support for RT5660 codec based sound cards on Baytrail

Seth Forshee
In reply to this post by Shrirang Bagul
On Wed, Apr 11, 2018 at 03:18:27PM +0800, Shrirang Bagul wrote:

> BugLink: http://bugs.launchpad.net/bugs/1657674
>
> This work is based on bionic/master-next (tag: Ubuntu-4.15.0-15.16)
>
> Dell Caracalla IoT gateways have RT5660 codec (HID: 10EC3277) connected to
> Baytrail SoC over I2S. The hardware supports line-in and line-out ports.
>
> This patch set adds a new plafrom sound card driver bytcr_rt5660 to connect
> RT5660 codec FE DAI's to Intel SST audio BE DAI's. It also adds ACPI
> support to RT5660 codec driver.
>
> Multiple attempts have been made to upstream this driver-
>
> 1. http://mailman.alsa-project.org/pipermail/alsa-devel/2016-December/115928.html
> 2. http://mailman.alsa-project.org/pipermail/alsa-devel/2017-January/116510.html
>
> but without much success. HWE will continue to get this driver upstreamed,
> till then we'll have to carry it as sauce patches to meet project release
> schedule.

Impact looks reasonably limited to specific hardware. Applied to
bionic/master-next and unstable/master, thanks!

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team