Commit 3d2cdb85 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: Intel: add SoundWire machine driver" from Pierre-Louis...

Merge series "ASoC: Intel: add SoundWire machine driver" from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

To handle multiple hardware combinations, this patchset suggests a
single machine driver which will create and initialize dailinks
dynamically. This allows us to support new configurations easily, as
shown with the TigerLake rt5682 example.

Each configuration updates the card component string, and UCM can test
for the presence of components to configure them as needed.

Since we use a single the machine driver name, all previous ACPI
tables need to be updated. That should have no impact since the
machine drivers listed at the time were not upstreamed and are no
longer maintained.

Naveen Manohar (2):
  ASoC: Intel: common: add match table for TGL RT5682 SoundWire driver
  ASoC: Intel: sof_sdw: Add Volteer support with RT5682 SNDW helper
    function

Pierre-Louis Bossart (1):
  ASoC: Intel: boards: add sof_sdw machine driver

Rander Wang (1):
  ASoC: Intel: soc-acpi: update topology and driver name for SoundWire
    platforms

 sound/soc/intel/boards/Kconfig                |  24 +
 sound/soc/intel/boards/Makefile               |   8 +-
 sound/soc/intel/boards/sof_sdw.c              | 962 ++++++++++++++++++
 sound/soc/intel/boards/sof_sdw_common.h       | 114 +++
 sound/soc/intel/boards/sof_sdw_dmic.c         |  42 +
 sound/soc/intel/boards/sof_sdw_hdmi.c         |  97 ++
 sound/soc/intel/boards/sof_sdw_rt1308.c       | 151 +++
 sound/soc/intel/boards/sof_sdw_rt5682.c       | 126 +++
 sound/soc/intel/boards/sof_sdw_rt700.c        | 125 +++
 sound/soc/intel/boards/sof_sdw_rt711.c        | 156 +++
 sound/soc/intel/boards/sof_sdw_rt715.c        |  42 +
 .../intel/common/soc-acpi-intel-cml-match.c   |  24 +-
 .../intel/common/soc-acpi-intel-icl-match.c   |   6 +-
 .../intel/common/soc-acpi-intel-tgl-match.c   |  30 +-
 14 files changed, 1896 insertions(+), 11 deletions(-)
 create mode 100644 sound/soc/intel/boards/sof_sdw.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_common.h
 create mode 100644 sound/soc/intel/boards/sof_sdw_dmic.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_hdmi.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_rt1308.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_rt5682.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_rt700.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_rt711.c
 create mode 100644 sound/soc/intel/boards/sof_sdw_rt715.c

--
2.20.1
parents acd4946f 798313f2
......@@ -524,4 +524,28 @@ config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
endif ## SND_SOC_SOF_JASPERLAKE
if SND_SOC_SOF_INTEL_SOUNDWIRE
config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
tristate "SoundWire generic machine driver"
depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST
depends on SOUNDWIRE
depends on SND_HDA_CODEC_HDMI
select SND_SOC_RT700_SDW
select SND_SOC_RT711_SDW
select SND_SOC_RT1308_SDW
select SND_SOC_RT1308
select SND_SOC_RT715_SDW
select SND_SOC_RT5682_SDW
select SND_SOC_DMIC
help
Add support for Intel SoundWire-based platforms connected to
RT700, RT711, RT1308 and RT715
If unsure select "N".
endif
endif ## SND_SOC_INTEL_MACH
......@@ -31,7 +31,11 @@ snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o hda_dsp_c
snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o hda_dsp_common.o
snd-soc-sof-sdw-objs += sof_sdw.o \
sof_sdw_rt711.o sof_sdw_rt700.o \
sof_sdw_rt1308.o sof_sdw_rt715.o \
sof_sdw_rt5682.o \
sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o
obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
......@@ -64,4 +68,4 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max9
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o
obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0
* Copyright (c) 2020 Intel Corporation
*/
/*
* sof_sdw_common.h - prototypes for common helpers
*/
#ifndef SND_SOC_SOF_SDW_COMMON_H
#define SND_SOC_SOF_SDW_COMMON_H
#include <linux/bits.h>
#include <linux/types.h>
#define MAX_NO_PROPS 2
#define MAX_HDMI_NUM 4
#define SDW_DMIC_DAI_ID 4
#define SDW_MAX_CPU_DAIS 16
#define SDW_INTEL_BIDIR_PDI_BASE 2
/* 8 combinations with 4 links + unused group 0 */
#define SDW_MAX_GROUPS 9
enum {
SOF_RT711_JD_SRC_JD1 = 1,
SOF_RT711_JD_SRC_JD2 = 2,
};
enum {
SOF_PRE_TGL_HDMI_COUNT = 3,
SOF_TGL_HDMI_COUNT = 4,
};
enum {
SOF_I2S_SSP0 = BIT(0),
SOF_I2S_SSP1 = BIT(1),
SOF_I2S_SSP2 = BIT(2),
SOF_I2S_SSP3 = BIT(3),
SOF_I2S_SSP4 = BIT(4),
SOF_I2S_SSP5 = BIT(5),
};
#define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(1, 0))
#define SOF_SDW_FOUR_SPK BIT(2)
#define SOF_SDW_TGL_HDMI BIT(3)
#define SOF_SDW_PCH_DMIC BIT(4)
#define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 5)
#define SOF_SSP_GET_PORT(quirk) (((quirk) >> 5) & GENMASK(5, 0))
#define SOF_RT715_DAI_ID_FIX BIT(11)
#define SOF_SDW_NO_AGGREGATION BIT(12)
struct sof_sdw_codec_info {
const int id;
int amp_num;
const u8 acpi_id[ACPI_ID_LEN];
const bool direction[2]; // playback & capture support
const char *dai_name;
const struct snd_soc_ops *ops;
int (*init)(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
};
struct mc_private {
struct list_head hdmi_pcm_list;
bool common_hdmi_codec_drv;
struct snd_soc_jack sdw_headset;
};
extern unsigned long sof_sdw_quirk;
/* generic HDMI support */
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd);
int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card);
/* DMIC support */
int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
/* RT711 support */
int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT700 support */
int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT1308 support */
extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops;
int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT715 support */
int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
/* RT5682 support */
int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
#endif
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_dmic - Helpers to handle dmic from generic machine driver
*/
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
static const struct snd_soc_dapm_widget dmic_widgets[] = {
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
};
static const struct snd_soc_dapm_route dmic_map[] = {
/* digital mics */
{"DMic", NULL, "SoC DMIC"},
};
int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
ARRAY_SIZE(dmic_widgets));
if (ret) {
dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
/* Don't need to add routes if widget addition failed */
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
ARRAY_SIZE(dmic_map));
if (ret)
dev_err(card->dev, "DMic map addition failed: %d\n", ret);
return ret;
}
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_hdmi - Helpers to handle HDMI from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/jack.h>
#include "sof_sdw_common.h"
#include "../../codecs/hdac_hdmi.h"
#include "hda_dsp_common.h"
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
static struct snd_soc_jack hdmi[MAX_HDMI_NUM];
struct hdmi_pcm {
struct list_head head;
struct snd_soc_dai *codec_dai;
int device;
};
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd)
{
struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *dai = rtd->codec_dai;
struct hdmi_pcm *pcm;
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
if (!pcm)
return -ENOMEM;
/* dai_link id is 1:1 mapped to the PCM device */
pcm->device = rtd->dai_link->id;
pcm->codec_dai = dai;
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
return 0;
}
#define NAME_SIZE 32
int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card)
{
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct hdmi_pcm *pcm;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
head);
component = pcm->codec_dai->component;
if (ctx->common_hdmi_codec_drv)
return hda_dsp_hdmi_build_controls(card, component);
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
SND_JACK_AVOUT, &hdmi[i],
NULL, 0);
if (err)
return err;
err = snd_jack_add_new_kctl(hdmi[i].jack,
jack_name, SND_JACK_AVOUT);
if (err)
dev_warn(component->dev, "failed creating Jack kctl\n");
err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
&hdmi[i]);
if (err < 0)
return err;
i++;
}
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
#else
int hdmi_card_late_probe(struct snd_soc_card *card)
{
return 0;
}
#endif
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_rt1308 - Helpers to handle RT1308 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
#include "../../codecs/rt1308.h"
static const struct snd_soc_dapm_widget rt1308_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", NULL),
};
/*
* dapm routes for rt1308 will be registered dynamically according
* to the number of rt1308 used. The first two entries will be registered
* for one codec case, and the last two entries are also registered
* if two 1308s are used.
*/
static const struct snd_soc_dapm_route rt1308_map[] = {
{ "Speaker", NULL, "rt1308-1 SPOL" },
{ "Speaker", NULL, "rt1308-1 SPOR" },
{ "Speaker", NULL, "rt1308-2 SPOL" },
{ "Speaker", NULL, "rt1308-2 SPOR" },
};
static const struct snd_kcontrol_new rt1308_controls[] = {
SOC_DAPM_PIN_SWITCH("Speaker"),
};
static int first_spk_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s spk:rt1308",
card->components);
if (!card->components)
return -ENOMEM;
ret = snd_soc_add_card_controls(card, rt1308_controls,
ARRAY_SIZE(rt1308_controls));
if (ret) {
dev_err(card->dev, "rt1308 controls addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_widgets,
ARRAY_SIZE(rt1308_widgets));
if (ret) {
dev_err(card->dev, "rt1308 widgets addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map, 2);
if (ret)
dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret);
return ret;
}
static int second_spk_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map + 2, 2);
if (ret)
dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret);
return ret;
}
static int all_spk_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
ret = first_spk_init(rtd);
if (ret)
return ret;
return second_spk_init(rtd);
}
static int rt1308_i2s_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_card *card = rtd->card;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int clk_id, clk_freq, pll_out;
int err;
clk_id = RT1308_PLL_S_MCLK;
clk_freq = 38400000;
pll_out = params_rate(params) * 512;
/* Set rt1308 pll */
err = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
if (err < 0) {
dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", err);
return err;
}
/* Set rt1308 sysclk */
err = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", err);
return err;
}
return 0;
}
/* machine stream operations */
struct snd_soc_ops sof_sdw_rt1308_i2s_ops = {
.hw_params = rt1308_i2s_hw_params,
};
int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
info->amp_num++;
if (info->amp_num == 1)
dai_links->init = first_spk_init;
if (info->amp_num == 2) {
/*
* if two 1308s are in one dai link, the init function
* in this dai link will be first set for the first speaker,
* and it should be reset to initialize all speakers when
* the second speaker is found.
*/
if (dai_links->init)
dai_links->init = all_spk_init;
else
dai_links->init = second_spk_init;
}
return 0;
}
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_rt5682 - Helpers to handle RT5682 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/jack.h>
#include "sof_sdw_common.h"
static const struct snd_soc_dapm_widget rt5682_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
};
static const struct snd_soc_dapm_route rt5682_map[] = {
/*Headphones*/
{ "Headphone", NULL, "rt5682 HPOL" },
{ "Headphone", NULL, "rt5682 HPOR" },
{ "rt5682 IN1P", NULL, "Headset Mic" },
};
static const struct snd_kcontrol_new rt5682_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
};
static struct snd_soc_jack_pin rt5682_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
int ret;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s hs:rt5682",
card->components);
if (!card->components)
return -ENOMEM;
ret = snd_soc_add_card_controls(card, rt5682_controls,
ARRAY_SIZE(rt5682_controls));
if (ret) {
dev_err(card->dev, "rt5682 control addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets,
ARRAY_SIZE(rt5682_widgets));
if (ret) {
dev_err(card->dev, "rt5682 widgets addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt5682_map,
ARRAY_SIZE(rt5682_map));
if (ret) {
dev_err(card->dev, "rt5682 map addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_BTN_0 |
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
SND_JACK_BTN_3,
&ctx->sdw_headset,
rt5682_jack_pins,
ARRAY_SIZE(rt5682_jack_pins));
if (ret) {
dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n",
ret);
return ret;
}
jack = &ctx->sdw_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
ret = snd_soc_component_set_jack(component, jack, NULL);
if (ret)
dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
ret);
return ret;
}
int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
/*
* headset should be initialized once.
* Do it with dai link for playback.
*/
if (!playback)
return 0;
dai_links->init = rt5682_rtd_init;
return 0;
}
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/jack.h>
#include "sof_sdw_common.h"
static const struct snd_soc_dapm_widget rt700_widgets[] = {
SND_SOC_DAPM_HP("Headphones", NULL),
SND_SOC_DAPM_MIC("AMIC", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL),
};
static const struct snd_soc_dapm_route rt700_map[] = {
/* Headphones */
{ "Headphones", NULL, "HP" },
{ "Speaker", NULL, "SPK" },
{ "MIC2", NULL, "AMIC" },
};
static const struct snd_kcontrol_new rt700_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphones"),
SOC_DAPM_PIN_SWITCH("AMIC"),
SOC_DAPM_PIN_SWITCH("Speaker"),
};
static struct snd_soc_jack_pin rt700_jack_pins[] = {
{
.pin = "Headphones",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "AMIC",
.mask = SND_JACK_MICROPHONE,
},
};
static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
int ret;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s hs:rt700",
card->components);
if (!card->components)
return -ENOMEM;
ret = snd_soc_add_card_controls(card, rt700_controls,
ARRAY_SIZE(rt700_controls));
if (ret) {
dev_err(card->dev, "rt700 controls addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_new_controls(&card->dapm, rt700_widgets,
ARRAY_SIZE(rt700_widgets));
if (ret) {
dev_err(card->dev, "rt700 widgets addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map,
ARRAY_SIZE(rt700_map));
if (ret) {
dev_err(card->dev, "rt700 map addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_BTN_0 |
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
SND_JACK_BTN_3,
&ctx->sdw_headset,
rt700_jack_pins,
ARRAY_SIZE(rt700_jack_pins));
if (ret) {
dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n",
ret);
return ret;
}
jack = &ctx->sdw_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_PLAYPAUSE);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
ret = snd_soc_component_set_jack(component, jack, NULL);
if (ret)
dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
ret);
return ret;
}
int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
/*
* headset should be initialized once.
* Do it with dai link for playback.
*/
if (!playback)
return 0;
dai_links->init = rt700_rtd_init;
return 0;
}
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_rt711 - Helpers to handle RT711 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/jack.h>
#include "sof_sdw_common.h"
/*
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
static int rt711_add_codec_device_props(const char *sdw_dev_name)
{
struct property_entry props[MAX_NO_PROPS] = {};
struct device *sdw_dev;
int ret;
sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name);
if (!sdw_dev)
return -EPROBE_DEFER;
if (SOF_RT711_JDSRC(sof_sdw_quirk)) {
props[0] = PROPERTY_ENTRY_U32("realtek,jd-src",
SOF_RT711_JDSRC(sof_sdw_quirk));
}
ret = device_add_properties(sdw_dev, props);
put_device(sdw_dev);
return ret;
}
static const struct snd_soc_dapm_widget rt711_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
};
static const struct snd_soc_dapm_route rt711_map[] = {
/* Headphones */
{ "Headphone", NULL, "rt711 HP" },
{ "rt711 MIC2", NULL, "Headset Mic" },
};
static const struct snd_kcontrol_new rt711_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
};
static struct snd_soc_jack_pin rt711_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
int ret;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s hs:rt711",
card->components);
if (!card->components)
return -ENOMEM;
ret = snd_soc_add_card_controls(card, rt711_controls,
ARRAY_SIZE(rt711_controls));
if (ret) {
dev_err(card->dev, "rt711 controls addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_new_controls(&card->dapm, rt711_widgets,
ARRAY_SIZE(rt711_widgets));
if (ret) {
dev_err(card->dev, "rt711 widgets addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt711_map,
ARRAY_SIZE(rt711_map));
if (ret) {
dev_err(card->dev, "rt711 map addition failed: %d\n", ret);
return ret;
}
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_BTN_0 |
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
SND_JACK_BTN_3,
&ctx->sdw_headset,
rt711_jack_pins,
ARRAY_SIZE(rt711_jack_pins));
if (ret) {
dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n",
ret);
return ret;
}
jack = &ctx->sdw_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_PLAYPAUSE);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
ret = snd_soc_component_set_jack(component, jack, NULL);
if (ret)
dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
ret);
return ret;
}
int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
int ret;
/*
* headset should be initialized once.
* Do it with dai link for playback.
*/
if (!playback)
return 0;
ret = rt711_add_codec_device_props("sdw:0:25d:711:0");
if (ret < 0)
return ret;
dai_links->init = rt711_rtd_init;
return 0;
}
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw_rt715 - Helpers to handle RT715 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
static int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:rt715",
card->components);
if (!card->components)
return -ENOMEM;
return 0;
}
int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
/*
* DAI ID is fixed at SDW_DMIC_DAI_ID for 715 to
* keep sdw DMIC and HDMI setting static in UCM
*/
if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX)
dai_links->id = SDW_DMIC_DAI_ID;
dai_links->init = rt715_rtd_init;
return 0;
}
......@@ -80,6 +80,23 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
static const struct snd_soc_acpi_adr_device rt700_1_adr[] = {
{
.adr = 0x000110025D070000,
.num_endpoints = 1,
.endpoints = &single_endpoint,
}
};
static const struct snd_soc_acpi_link_adr cml_rvp[] = {
{
.mask = BIT(1),
.num_adr = ARRAY_SIZE(rt700_1_adr),
.adr_d = rt700_1_adr,
},
{}
};
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000010025D071100,
......@@ -175,7 +192,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = {
{
.link_mask = 0xF, /* 4 active links required */
.links = cml_3_in_1_default,
.drv_name = "sdw_rt711_rt1308_rt715",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-cml.ri",
.sof_tplg_filename = "sof-cml-rt711-rt1308-rt715.tplg",
},
......@@ -187,13 +204,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = {
*/
.link_mask = 0xF,
.links = cml_3_in_1_mono_amp,
.drv_name = "sdw_rt711_rt1308_rt715",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-cml.ri",
.sof_tplg_filename = "sof-cml-rt711-rt1308-mono-rt715.tplg",
},
{
.link_mask = 0x2, /* RT700 connected on Link1 */
.drv_name = "sdw_rt700",
.links = cml_rvp,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-cml.ri",
.sof_tplg_filename = "sof-cml-rt700.tplg",
},
......
......@@ -166,21 +166,21 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[] = {
{
.link_mask = 0xF, /* 4 active links required */
.links = icl_3_in_1_default,
.drv_name = "sdw_rt711_rt1308_rt715",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-icl.ri",
.sof_tplg_filename = "sof-icl-rt711-rt1308-rt715.tplg",
},
{
.link_mask = 0xB, /* 3 active links required */
.links = icl_3_in_1_mono_amp,
.drv_name = "sdw_rt711_rt1308_rt715",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-icl.ri",
.sof_tplg_filename = "sof-icl-rt711-rt1308-rt715-mono.tplg",
},
{
.link_mask = 0x1, /* rt700 connected on link0 */
.links = icl_rvp,
.drv_name = "sdw_rt700",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-icl.ri",
.sof_tplg_filename = "sof-icl-rt700.tplg",
},
......
......@@ -56,6 +56,14 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
}
};
static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = {
{
.adr = 0x000021025D568200,
.num_endpoints = 1,
.endpoints = &single_endpoint,
}
};
static const struct snd_soc_acpi_link_adr tgl_i2s_rt1308[] = {
{
.mask = BIT(0),
......@@ -79,6 +87,15 @@ static const struct snd_soc_acpi_link_adr tgl_rvp[] = {
{}
};
static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(rt5682_0_adr),
.adr_d = rt5682_0_adr,
},
{}
};
static struct snd_soc_acpi_codecs tgl_max98373_amp = {
.num_codecs = 1,
.codecs = {"MX98373"}
......@@ -87,11 +104,11 @@ static struct snd_soc_acpi_codecs tgl_max98373_amp = {
struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
{
.id = "10EC1308",
.drv_name = "rt711_rt1308",
.drv_name = "sof_sdw",
.link_mask = 0x1, /* RT711 on SoundWire link0 */
.links = tgl_i2s_rt1308,
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg",
.sof_tplg_filename = "sof-tgl-rt711-i2s-rt1308.tplg",
},
{
.id = "10EC5682",
......@@ -118,10 +135,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
{
.link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */
.links = tgl_rvp,
.drv_name = "sdw_rt711_rt1308_rt715",
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg",
},
{
.link_mask = 0x1, /* this will only enable rt5682 for now */
.links = tgl_chromebook_base,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt5682.tplg",
},
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment