summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/boards
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c69
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c332
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c17
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c34
-rw-r--r--sound/soc/intel/boards/mfld_machine.c16
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c122
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c130
-rw-r--r--sound/soc/intel/boards/skl_rt286.c118
9 files changed, 743 insertions, 97 deletions
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 2485ea9434ad..3310c0f9c356 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -3,6 +3,7 @@ snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
snd-soc-sst-broadwell-objs := broadwell.o
snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
+snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.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
@@ -15,6 +16,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.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_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_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index a81389d10e17..032a2e753f0b 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -30,6 +30,19 @@
#include <sound/jack.h>
#include "../../codecs/rt5640.h"
#include "../atom/sst-atom-controls.h"
+#include "../common/sst-acpi.h"
+
+enum {
+ BYT_RT5640_DMIC1_MAP,
+ BYT_RT5640_DMIC2_MAP,
+ BYT_RT5640_IN1_MAP,
+};
+
+#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
+#define BYT_RT5640_DMIC_EN BIT(16)
+
+static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
+ BYT_RT5640_DMIC_EN;
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
@@ -69,18 +82,6 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
{"IN1P", NULL, "Internal Mic"},
};
-enum {
- BYT_RT5640_DMIC1_MAP,
- BYT_RT5640_DMIC2_MAP,
- BYT_RT5640_IN1_MAP,
-};
-
-#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
-#define BYT_RT5640_DMIC_EN BIT(16)
-
-static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
- BYT_RT5640_DMIC_EN;
-
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -140,6 +141,14 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
.driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
BYT_RT5640_DMIC_EN),
},
+ {
+ .callback = byt_rt5640_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
+ },
+ .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
+ },
{}
};
@@ -153,6 +162,11 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
card->dapm.idle_bias_off = true;
+ rt5640_sel_asrc_clk_src(codec,
+ RT5640_DA_STEREO_FILTER |
+ RT5640_AD_STEREO_FILTER,
+ RT5640_CLK_SEL_ASRC);
+
ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
ARRAY_SIZE(byt_rt5640_controls));
if (ret) {
@@ -160,7 +174,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
return ret;
}
- dmi_check_system(byt_rt5640_quirk_table);
switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
case BYT_RT5640_IN1_MAP:
custom_map = byt_rt5640_intmic_in1_map;
@@ -296,7 +309,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "rt5640-aif1",
- .codec_name = "i2c-10EC5640:00",
+ .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = byt_rt5640_codec_fixup,
@@ -321,12 +334,40 @@ static struct snd_soc_card byt_rt5640_card = {
.fully_routed = true,
};
+static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+
static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
{
int ret_val = 0;
+ struct sst_acpi_mach *mach;
+ const char *i2c_name = NULL;
+ int i;
+ int dai_index;
/* register the soc card */
byt_rt5640_card.dev = &pdev->dev;
+ mach = byt_rt5640_card.dev->platform_data;
+
+ /* fix index of codec dai */
+ dai_index = MERR_DPCM_COMPR + 1;
+ for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
+ if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
+ dai_index = i;
+ break;
+ }
+ }
+
+ /* fixup codec name based on HID */
+ i2c_name = sst_acpi_find_name_from_hid(mach->id);
+ if (i2c_name != NULL) {
+ snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
+ "%s%s", "i2c-", i2c_name);
+
+ byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
+ }
+
+ /* check quirks before creating card */
+ dmi_check_system(byt_rt5640_quirk_table);
ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
new file mode 100644
index 000000000000..1c95ccc886c4
--- /dev/null
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -0,0 +1,332 @@
+/*
+ * bytcr_rt5651.c - ASoc Machine driver for Intel Byt CR platform
+ * (derived from bytcr_rt5640.c)
+ *
+ * Copyright (C) 2015 Intel Corp
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include "../../codecs/rt5651.h"
+#include "../atom/sst-atom-controls.h"
+
+static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Internal Mic", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
+ {"AIF1 Playback", NULL, "ssp2 Tx"},
+ {"ssp2 Tx", NULL, "codec_out0"},
+ {"ssp2 Tx", NULL, "codec_out1"},
+ {"codec_in0", NULL, "ssp2 Rx"},
+ {"codec_in1", NULL, "ssp2 Rx"},
+ {"ssp2 Rx", NULL, "AIF1 Capture"},
+
+ {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
+ {"IN2P", NULL, "Headset Mic"},
+ {"Headphone", NULL, "HPOL"},
+ {"Headphone", NULL, "HPOR"},
+ {"Speaker", NULL, "LOUTL"},
+ {"Speaker", NULL, "LOUTR"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic1_map[] = {
+ {"DMIC1", NULL, "Internal Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic2_map[] = {
+ {"DMIC2", NULL, "Internal Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
+ {"Internal Mic", NULL, "micbias1"},
+ {"IN1P", NULL, "Internal Mic"},
+};
+
+enum {
+ BYT_RT5651_DMIC1_MAP,
+ BYT_RT5651_DMIC2_MAP,
+ BYT_RT5651_IN1_MAP,
+};
+
+#define BYT_RT5651_MAP(quirk) ((quirk) & 0xff)
+#define BYT_RT5651_DMIC_EN BIT(16)
+
+static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC1_MAP |
+ BYT_RT5651_DMIC_EN;
+
+static const struct snd_kcontrol_new byt_rt5651_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Internal Mic"),
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+static int byt_rt5651_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, RT5651_SCLK_S_PLL1,
+ params_rate(params) * 512,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec clock %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5651_PLL1_S_BCLK1,
+ params_rate(params) * 50,
+ params_rate(params) * 512);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct dmi_system_id byt_rt5651_quirk_table[] = {
+ {}
+};
+
+static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
+{
+ int ret;
+ struct snd_soc_card *card = runtime->card;
+ const struct snd_soc_dapm_route *custom_map;
+ int num_routes;
+
+ card->dapm.idle_bias_off = true;
+
+ dmi_check_system(byt_rt5651_quirk_table);
+ switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
+ case BYT_RT5651_IN1_MAP:
+ custom_map = byt_rt5651_intmic_in1_map;
+ num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map);
+ break;
+ case BYT_RT5651_DMIC2_MAP:
+ custom_map = byt_rt5651_intmic_dmic2_map;
+ num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic2_map);
+ break;
+ default:
+ custom_map = byt_rt5651_intmic_dmic1_map;
+ num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic1_map);
+ }
+
+ ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
+ ARRAY_SIZE(byt_rt5651_controls));
+ if (ret) {
+ dev_err(card->dev, "unable to add card controls\n");
+ return ret;
+ }
+ snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
+ snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
+
+ return ret;
+}
+
+static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
+ .formats = SNDRV_PCM_FMTBIT_S24_LE,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+};
+
+static int byt_rt5651_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, 24bits */
+ 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_IF |
+ 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 unsigned int rates_48000[] = {
+ 48000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_48000 = {
+ .count = ARRAY_SIZE(rates_48000),
+ .list = rates_48000,
+};
+
+static int byt_rt5651_aif1_startup(struct snd_pcm_substream *substream)
+{
+ return snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &constraints_48000);
+}
+
+static struct snd_soc_ops byt_rt5651_aif1_ops = {
+ .startup = byt_rt5651_aif1_startup,
+};
+
+static struct snd_soc_ops byt_rt5651_be_ssp2_ops = {
+ .hw_params = byt_rt5651_aif1_hw_params,
+};
+
+static struct snd_soc_dai_link byt_rt5651_dais[] = {
+ [MERR_DPCM_AUDIO] = {
+ .name = "Audio Port",
+ .stream_name = "Audio",
+ .cpu_dai_name = "media-cpu-dai",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .platform_name = "sst-mfld-platform",
+ .ignore_suspend = 1,
+ .nonatomic = true,
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ops = &byt_rt5651_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",
+ .ignore_suspend = 1,
+ .nonatomic = true,
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .ops = &byt_rt5651_aif1_ops,
+ },
+ [MERR_DPCM_COMPR] = {
+ .name = "Compressed Port",
+ .stream_name = "Compress",
+ .cpu_dai_name = "compress-cpu-dai",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .platform_name = "sst-mfld-platform",
+ },
+ /* CODEC<->CODEC link */
+ /* back ends */
+ {
+ .name = "SSP2-Codec",
+ .be_id = 1,
+ .cpu_dai_name = "ssp2-port",
+ .platform_name = "sst-mfld-platform",
+ .no_pcm = 1,
+ .codec_dai_name = "rt5651-aif1",
+ .codec_name = "i2c-10EC5651:00",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS,
+ .be_hw_params_fixup = byt_rt5651_codec_fixup,
+ .ignore_suspend = 1,
+ .nonatomic = true,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .init = byt_rt5651_init,
+ .ops = &byt_rt5651_be_ssp2_ops,
+ },
+};
+
+/* SoC card */
+static struct snd_soc_card byt_rt5651_card = {
+ .name = "bytcr-rt5651",
+ .owner = THIS_MODULE,
+ .dai_link = byt_rt5651_dais,
+ .num_links = ARRAY_SIZE(byt_rt5651_dais),
+ .dapm_widgets = byt_rt5651_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(byt_rt5651_widgets),
+ .dapm_routes = byt_rt5651_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(byt_rt5651_audio_map),
+ .fully_routed = true,
+};
+
+static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
+{
+ int ret_val = 0;
+
+ /* register the soc card */
+ byt_rt5651_card.dev = &pdev->dev;
+
+ ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_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_rt5651_card);
+ return ret_val;
+}
+
+static struct platform_driver snd_byt_rt5651_mc_driver = {
+ .driver = {
+ .name = "bytcr_rt5651",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = snd_byt_rt5651_mc_probe,
+};
+
+module_platform_driver(snd_byt_rt5651_mc_driver);
+
+MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver for RT5651");
+MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:bytcr_rt5651");
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 90588d6e64fc..e609f089593a 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -287,33 +287,20 @@ static struct snd_soc_card snd_soc_card_cht = {
.num_controls = ARRAY_SIZE(cht_mc_controls),
};
-static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level,
- void *context, void **ret)
-{
- *(bool *)context = true;
- return AE_OK;
-}
-
static int snd_cht_mc_probe(struct platform_device *pdev)
{
int ret_val = 0;
- bool found = false;
struct cht_mc_private *drv;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
if (!drv)
return -ENOMEM;
- if (ACPI_SUCCESS(acpi_get_devices(
- "104C227E",
- snd_acpi_codec_match,
- &found, NULL)) && found) {
- drv->ts3a227e_present = true;
- } else {
+ drv->ts3a227e_present = acpi_dev_present("104C227E");
+ if (!drv->ts3a227e_present) {
/* no need probe TI jack detection chip */
snd_soc_card_cht.aux_dev = NULL;
snd_soc_card_cht.num_aux_devs = 0;
- drv->ts3a227e_present = false;
}
/* register the soc card */
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 2d3afddb0a2e..2a6f80843bc9 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -147,6 +147,17 @@ static const struct snd_kcontrol_new cht_mc_controls[] = {
SOC_DAPM_PIN_SWITCH("Ext Spk"),
};
+static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
+ {
+ .pin = "Headphone",
+ .mask = SND_JACK_HEADPHONE,
+ },
+ {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+ },
+};
+
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -202,9 +213,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
else
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
- ret = snd_soc_card_jack_new(runtime->card, "Headset Jack",
+ ret = snd_soc_card_jack_new(runtime->card, "Headset",
jack_type, &ctx->jack,
- NULL, 0);
+ cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
if (ret) {
dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
return ret;
@@ -333,20 +344,12 @@ static struct cht_acpi_card snd_soc_cards[] = {
{"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
};
-static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level,
- void *context, void **ret)
-{
- *(bool *)context = true;
- return AE_OK;
-}
-
static int snd_cht_mc_probe(struct platform_device *pdev)
{
int ret_val = 0;
int i;
struct cht_mc_private *drv;
struct snd_soc_card *card = snd_soc_cards[0].soc_card;
- bool found = false;
char codec_name[16];
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
@@ -354,10 +357,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) {
- if (ACPI_SUCCESS(acpi_get_devices(
- snd_soc_cards[i].codec_id,
- snd_acpi_codec_match,
- &found, NULL)) && found) {
+ if (acpi_dev_present(snd_soc_cards[i].codec_id)) {
dev_dbg(&pdev->dev,
"found codec %s\n", snd_soc_cards[i].codec_id);
card = snd_soc_cards[i].soc_card;
@@ -367,8 +367,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
}
card->dev = &pdev->dev;
sprintf(codec_name, "i2c-%s:00", drv->acpi_card->codec_id);
+
/* set correct codec name */
- strcpy((char *)card->dai_link[2].codec_name, codec_name);
+ for (i = 0; i < ARRAY_SIZE(cht_dailink); i++)
+ if (!strcmp(card->dai_link[i].codec_name, "i2c-10EC5645:00"))
+ card->dai_link[i].codec_name = kstrdup(codec_name, GFP_KERNEL);
+
snd_soc_card_set_drvdata(card, drv);
ret_val = devm_snd_soc_register_card(&pdev->dev, card);
if (ret_val) {
diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c
index 49c09a0add79..34f46c72a0e2 100644
--- a/sound/soc/intel/boards/mfld_machine.c
+++ b/sound/soc/intel/boards/mfld_machine.c
@@ -94,7 +94,7 @@ static const struct soc_enum lo_enum =
static int headset_get_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- ucontrol->value.integer.value[0] = hs_switch;
+ ucontrol->value.enumerated.item[0] = hs_switch;
return 0;
}
@@ -104,12 +104,12 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_context *dapm = &card->dapm;
- if (ucontrol->value.integer.value[0] == hs_switch)
+ if (ucontrol->value.enumerated.item[0] == hs_switch)
return 0;
snd_soc_dapm_mutex_lock(dapm);
- if (ucontrol->value.integer.value[0]) {
+ if (ucontrol->value.enumerated.item[0]) {
pr_debug("hs_set HS path\n");
snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
@@ -123,7 +123,7 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
snd_soc_dapm_mutex_unlock(dapm);
- hs_switch = ucontrol->value.integer.value[0];
+ hs_switch = ucontrol->value.enumerated.item[0];
return 0;
}
@@ -148,7 +148,7 @@ static void lo_enable_out_pins(struct snd_soc_dapm_context *dapm)
static int lo_get_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- ucontrol->value.integer.value[0] = lo_dac;
+ ucontrol->value.enumerated.item[0] = lo_dac;
return 0;
}
@@ -158,7 +158,7 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_context *dapm = &card->dapm;
- if (ucontrol->value.integer.value[0] == lo_dac)
+ if (ucontrol->value.enumerated.item[0] == lo_dac)
return 0;
snd_soc_dapm_mutex_lock(dapm);
@@ -168,7 +168,7 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
*/
lo_enable_out_pins(dapm);
- switch (ucontrol->value.integer.value[0]) {
+ switch (ucontrol->value.enumerated.item[0]) {
case 0:
pr_debug("set vibra path\n");
snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
@@ -202,7 +202,7 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
snd_soc_dapm_mutex_unlock(dapm);
- lo_dac = ucontrol->value.integer.value[0];
+ lo_dac = ucontrol->value.enumerated.item[0];
return 0;
}
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index ab7da9c304b2..72176b79a18d 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -22,6 +22,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/nau8825.h"
+#include "../../codecs/hdac_hdmi.h"
#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
#define SKL_MAXIM_CODEC_DAI "HiFi"
@@ -29,6 +30,16 @@
static struct snd_soc_jack skylake_headset;
static struct snd_soc_card skylake_audio_card;
+enum {
+ SKL_DPCM_AUDIO_PB = 0,
+ SKL_DPCM_AUDIO_CP,
+ SKL_DPCM_AUDIO_REF_CP,
+ SKL_DPCM_AUDIO_DMIC_CP,
+ SKL_DPCM_AUDIO_HDMI1_PB,
+ SKL_DPCM_AUDIO_HDMI2_PB,
+ SKL_DPCM_AUDIO_HDMI3_PB,
+};
+
static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
@@ -87,7 +98,6 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_SPK("Spk", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
- SND_SOC_DAPM_SINK("WoV Sink"),
SND_SOC_DAPM_SPK("DP", NULL),
SND_SOC_DAPM_SPK("HDMI", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
@@ -107,7 +117,6 @@ static const struct snd_soc_dapm_route skylake_map[] = {
{ "MIC", NULL, "Headset Mic" },
{ "DMic", NULL, "SoC DMIC" },
- {"WoV Sink", NULL, "hwd_in sink"},
{"HDMI", NULL, "hif5 Output"},
{"DP", NULL, "hif6 Output"},
@@ -124,8 +133,14 @@ static const struct snd_soc_dapm_route skylake_map[] = {
/* DMIC */
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "DMIC AIF" },
- { "hifi1", NULL, "iDisp Tx"},
- { "iDisp Tx", NULL, "iDisp_out"},
+
+ { "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"},
+
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headset Mic", NULL, "Platform Clock" },
};
@@ -171,11 +186,31 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
nau8825_enable_jack_detect(codec, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
- snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
return ret;
}
+static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB);
+}
+
+static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB);
+}
+
+static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB);
+}
+
static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dapm_context *dapm;
@@ -318,7 +353,7 @@ static struct snd_soc_ops skylaye_refcap_ops = {
/* skylake digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link skylake_dais[] = {
/* Front End DAI links */
- {
+ [SKL_DPCM_AUDIO_PB] = {
.name = "Skl Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
@@ -333,7 +368,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dpcm_playback = 1,
.ops = &skylake_nau8825_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_CP] = {
.name = "Skl Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
@@ -347,7 +382,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dpcm_capture = 1,
.ops = &skylake_nau8825_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_REF_CP] = {
.name = "Skl Audio Reference cap",
.stream_name = "Wake on Voice",
.cpu_dai_name = "Reference Pin",
@@ -361,7 +396,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dynamic = 1,
.ops = &skylaye_refcap_ops,
},
- {
+ [SKL_DPCM_AUDIO_DMIC_CP] = {
.name = "Skl Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
@@ -374,15 +409,45 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dynamic = 1,
.ops = &skylake_dmic_ops,
},
- {
- .name = "Skl HDMI Port",
- .stream_name = "Hdmi",
- .cpu_dai_name = "HDMI Pin",
+ [SKL_DPCM_AUDIO_HDMI1_PB] = {
+ .name = "Skl HDMI Port1",
+ .stream_name = "Hdmi1",
+ .cpu_dai_name = "HDMI1 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI2_PB] = {
+ .name = "Skl HDMI Port2",
+ .stream_name = "Hdmi2",
+ .cpu_dai_name = "HDMI2 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
.init = NULL,
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI3_PB] = {
+ .name = "Skl HDMI Port3",
+ .stream_name = "Hdmi3",
+ .cpu_dai_name = "HDMI3 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+ .dpcm_playback = 1,
+ .init = NULL,
.nonatomic = 1,
.dynamic = 1,
},
@@ -407,7 +472,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
{
/* SSP1 - Codec */
.name = "SSP1-Codec",
- .be_id = 0,
+ .be_id = 1,
.cpu_dai_name = "SSP1 Pin",
.platform_name = "0000:00:1f.3",
.no_pcm = 1,
@@ -424,7 +489,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
},
{
.name = "dmic01",
- .be_id = 1,
+ .be_id = 2,
.cpu_dai_name = "DMIC01 Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
@@ -435,13 +500,36 @@ static struct snd_soc_dai_link skylake_dais[] = {
.no_pcm = 1,
},
{
- .name = "iDisp",
+ .name = "iDisp1",
.be_id = 3,
- .cpu_dai_name = "iDisp Pin",
+ .cpu_dai_name = "iDisp1 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi1",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
+ .init = skylake_hdmi1_init,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp2",
+ .be_id = 4,
+ .cpu_dai_name = "iDisp2 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi2",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi2_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp3",
+ .be_id = 5,
+ .cpu_dai_name = "iDisp3 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi3",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi3_init,
+ .dpcm_playback = 1,
.no_pcm = 1,
},
};
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index c071812f31e5..5f1ca99ae9b0 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -26,6 +26,7 @@
#include <sound/jack.h>
#include <sound/pcm_params.h>
#include "../../codecs/nau8825.h"
+#include "../../codecs/hdac_hdmi.h"
#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
@@ -33,6 +34,16 @@
static struct snd_soc_jack skylake_headset;
static struct snd_soc_card skylake_audio_card;
+enum {
+ SKL_DPCM_AUDIO_PB = 0,
+ SKL_DPCM_AUDIO_CP,
+ SKL_DPCM_AUDIO_REF_CP,
+ SKL_DPCM_AUDIO_DMIC_CP,
+ SKL_DPCM_AUDIO_HDMI1_PB,
+ SKL_DPCM_AUDIO_HDMI2_PB,
+ SKL_DPCM_AUDIO_HDMI3_PB,
+};
+
static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
@@ -92,7 +103,6 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
SND_SOC_DAPM_SPK("Left Speaker", NULL),
SND_SOC_DAPM_SPK("Right Speaker", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
- SND_SOC_DAPM_SINK("WoV Sink"),
SND_SOC_DAPM_SPK("DP", NULL),
SND_SOC_DAPM_SPK("HDMI", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
@@ -113,8 +123,6 @@ static const struct snd_soc_dapm_route skylake_map[] = {
{"MIC", NULL, "Headset Mic"},
{"DMic", NULL, "SoC DMIC"},
- {"WoV Sink", NULL, "hwd_in sink"},
-
{"HDMI", NULL, "hif5 Output"},
{"DP", NULL, "hif6 Output"},
/* CODEC BE connections */
@@ -122,6 +130,11 @@ static const struct snd_soc_dapm_route skylake_map[] = {
{ "Right Playback", NULL, "ssp0 Tx"},
{ "ssp0 Tx", NULL, "codec0_out"},
+ /* IV feedback path */
+ { "codec0_lp_in", NULL, "ssp0 Rx"},
+ { "ssp0 Rx", NULL, "Left Capture Sense" },
+ { "ssp0 Rx", NULL, "Right Capture Sense" },
+
{ "Playback", NULL, "ssp1 Tx"},
{ "ssp1 Tx", NULL, "codec1_out"},
@@ -131,8 +144,14 @@ static const struct snd_soc_dapm_route skylake_map[] = {
/* DMIC */
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "DMIC AIF" },
- { "hifi1", NULL, "iDisp Tx"},
- { "iDisp Tx", NULL, "iDisp_out"},
+
+ { "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"},
+
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headset Mic", NULL, "Platform Clock" },
};
@@ -197,11 +216,32 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
nau8825_enable_jack_detect(codec, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
- snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
return ret;
}
+static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB);
+}
+
+static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB);
+}
+
+
+static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB);
+}
+
static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dapm_context *dapm;
@@ -362,7 +402,7 @@ static struct snd_soc_ops skylaye_refcap_ops = {
/* skylake digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link skylake_dais[] = {
/* Front End DAI links */
- {
+ [SKL_DPCM_AUDIO_PB] = {
.name = "Skl Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
@@ -377,7 +417,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dpcm_playback = 1,
.ops = &skylake_nau8825_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_CP] = {
.name = "Skl Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
@@ -391,7 +431,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dpcm_capture = 1,
.ops = &skylake_nau8825_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_REF_CP] = {
.name = "Skl Audio Reference cap",
.stream_name = "Wake on Voice",
.cpu_dai_name = "Reference Pin",
@@ -405,7 +445,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dynamic = 1,
.ops = &skylaye_refcap_ops,
},
- {
+ [SKL_DPCM_AUDIO_DMIC_CP] = {
.name = "Skl Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
@@ -418,13 +458,43 @@ static struct snd_soc_dai_link skylake_dais[] = {
.dynamic = 1,
.ops = &skylake_dmic_ops,
},
- {
- .name = "Skl HDMI Port",
- .stream_name = "Hdmi",
- .cpu_dai_name = "HDMI Pin",
+ [SKL_DPCM_AUDIO_HDMI1_PB] = {
+ .name = "Skl HDMI Port1",
+ .stream_name = "Hdmi1",
+ .cpu_dai_name = "HDMI1 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI2_PB] = {
+ .name = "Skl HDMI Port2",
+ .stream_name = "Hdmi2",
+ .cpu_dai_name = "HDMI2 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI3_PB] = {
+ .name = "Skl HDMI Port3",
+ .stream_name = "Hdmi3",
+ .cpu_dai_name = "HDMI3 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
@@ -448,11 +518,12 @@ static struct snd_soc_dai_link skylake_dais[] = {
.ignore_pmdown_time = 1,
.be_hw_params_fixup = skylake_ssp_fixup,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
},
{
/* SSP1 - Codec */
.name = "SSP1-Codec",
- .be_id = 0,
+ .be_id = 1,
.cpu_dai_name = "SSP1 Pin",
.platform_name = "0000:00:1f.3",
.no_pcm = 1,
@@ -469,7 +540,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
},
{
.name = "dmic01",
- .be_id = 1,
+ .be_id = 2,
.cpu_dai_name = "DMIC01 Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
@@ -480,13 +551,36 @@ static struct snd_soc_dai_link skylake_dais[] = {
.no_pcm = 1,
},
{
- .name = "iDisp",
+ .name = "iDisp1",
.be_id = 3,
- .cpu_dai_name = "iDisp Pin",
+ .cpu_dai_name = "iDisp1 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi1",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
+ .init = skylake_hdmi1_init,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp2",
+ .be_id = 4,
+ .cpu_dai_name = "iDisp2 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi2",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi2_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp3",
+ .be_id = 5,
+ .cpu_dai_name = "iDisp3 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi3",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi3_init,
+ .dpcm_playback = 1,
.no_pcm = 1,
},
};
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 7396ddb427d8..2016397a8e75 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -26,8 +26,20 @@
#include <sound/jack.h>
#include <sound/pcm_params.h>
#include "../../codecs/rt286.h"
+#include "../../codecs/hdac_hdmi.h"
static struct snd_soc_jack skylake_headset;
+
+enum {
+ SKL_DPCM_AUDIO_PB = 0,
+ SKL_DPCM_AUDIO_CP,
+ SKL_DPCM_AUDIO_REF_CP,
+ SKL_DPCM_AUDIO_DMIC_CP,
+ SKL_DPCM_AUDIO_HDMI1_PB,
+ SKL_DPCM_AUDIO_HDMI2_PB,
+ SKL_DPCM_AUDIO_HDMI3_PB,
+};
+
/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin skylake_headset_pins[] = {
{
@@ -52,7 +64,9 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
SND_SOC_DAPM_MIC("Mic Jack", NULL),
SND_SOC_DAPM_MIC("DMIC2", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
- SND_SOC_DAPM_SINK("WoV Sink"),
+ SND_SOC_DAPM_SPK("HDMI1", NULL),
+ SND_SOC_DAPM_SPK("HDMI2", NULL),
+ SND_SOC_DAPM_SPK("HDMI3", NULL),
};
static const struct snd_soc_dapm_route skylake_rt286_map[] = {
@@ -70,7 +84,9 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
{"DMIC1 Pin", NULL, "DMIC2"},
{"DMic", NULL, "SoC DMIC"},
- {"WoV Sink", NULL, "hwd_in sink"},
+ {"HDMI1", NULL, "hif5 Output"},
+ {"HDMI2", NULL, "hif6 Output"},
+ {"HDMI3", NULL, "hif7 Output"},
/* CODEC BE connections */
{ "AIF1 Playback", NULL, "ssp0 Tx"},
@@ -84,8 +100,12 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "DMIC AIF" },
- { "hif1", NULL, "iDisp Tx"},
- { "iDisp Tx", NULL, "iDisp_out"},
+ { "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"},
};
@@ -116,11 +136,17 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
rt286_mic_detect(codec, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
- snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
return 0;
}
+static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+
+ return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB + dai->id);
+}
+
static unsigned int rates[] = {
48000,
};
@@ -212,7 +238,10 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
- channels->min = channels->max = 4;
+ if (params_channels(params) == 2)
+ channels->min = channels->max = 2;
+ else
+ channels->min = channels->max = 4;
return 0;
}
@@ -246,7 +275,7 @@ static struct snd_soc_ops skylake_dmic_ops = {
/* skylake digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link skylake_rt286_dais[] = {
/* Front End DAI links */
- {
+ [SKL_DPCM_AUDIO_PB] = {
.name = "Skl Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
@@ -263,7 +292,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.dpcm_playback = 1,
.ops = &skylake_rt286_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_CP] = {
.name = "Skl Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
@@ -279,7 +308,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.dpcm_capture = 1,
.ops = &skylake_rt286_fe_ops,
},
- {
+ [SKL_DPCM_AUDIO_REF_CP] = {
.name = "Skl Audio Reference cap",
.stream_name = "refcap",
.cpu_dai_name = "Reference Pin",
@@ -292,7 +321,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.nonatomic = 1,
.dynamic = 1,
},
- {
+ [SKL_DPCM_AUDIO_DMIC_CP] = {
.name = "Skl Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
@@ -305,6 +334,42 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.dynamic = 1,
.ops = &skylake_dmic_ops,
},
+ [SKL_DPCM_AUDIO_HDMI1_PB] = {
+ .name = "Skl HDMI Port1",
+ .stream_name = "Hdmi1",
+ .cpu_dai_name = "HDMI1 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI2_PB] = {
+ .name = "Skl HDMI Port2",
+ .stream_name = "Hdmi2",
+ .cpu_dai_name = "HDMI2 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
+ [SKL_DPCM_AUDIO_HDMI3_PB] = {
+ .name = "Skl HDMI Port3",
+ .stream_name = "Hdmi3",
+ .cpu_dai_name = "HDMI3 Pin",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .platform_name = "0000:00:1f.3",
+ .dpcm_playback = 1,
+ .init = NULL,
+ .nonatomic = 1,
+ .dynamic = 1,
+ },
/* Back End DAI links */
{
@@ -338,6 +403,39 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
.dpcm_capture = 1,
.no_pcm = 1,
},
+ {
+ .name = "iDisp1",
+ .be_id = 2,
+ .cpu_dai_name = "iDisp1 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi1",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp2",
+ .be_id = 3,
+ .cpu_dai_name = "iDisp2 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi2",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ },
+ {
+ .name = "iDisp3",
+ .be_id = 4,
+ .cpu_dai_name = "iDisp3 Pin",
+ .codec_name = "ehdaudio0D2",
+ .codec_dai_name = "intel-hdmi-hifi3",
+ .platform_name = "0000:00:1f.3",
+ .init = skylake_hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ },
};
/* skylake audio machine driver for SPT + RT286S */
OpenPOWER on IntegriCloud