// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation
/*
* sof_sdw - ASOC Machine driver for Intel SoundWire platforms
*/
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1;
#define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0)
static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
{
sof_sdw_quirk = (unsigned long)id->driver_data;
return 1;
}
static const struct dmi_system_id sof_sdw_quirk_table[] = {
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX),
},
{
/* early version of SKU 09C6 */
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME,
"Tiger Lake Client Platform"),
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC |
SOF_SSP_PORT(SOF_I2S_SSP2)),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
},
.driver_data = (void *)SOF_SDW_PCH_DMIC,
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"),
},
.driver_data = (void *)SOF_SDW_PCH_DMIC,
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC),
},
{}
};
static struct snd_soc_codec_conf codec_conf[] = {
{
.dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"),
.name_prefix = "rt711",
},
/* rt1308 w/ I2S connection */
{
.dlc = COMP_CODEC_CONF("i2c-10EC1308:00"),
.name_prefix = "rt1308-1",
},
/* rt1308 left on link 1 */
{
.dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0"),
.name_prefix = "rt1308-1",
},
/* two 1308s on link1 with different unique id */
{
.dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:0"),
.name_prefix = "rt1308-1",
},
{
.dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:2"),
.name_prefix = "rt1308-2",
},
/* rt1308 right on link 2 */
{
.dlc = COMP_CODEC_CONF("sdw:2:25d:1308:0"),
.name_prefix = "rt1308-2",
},
{
.dlc = COMP_CODEC_CONF("sdw:3:25d:715:0"),
.name_prefix = "rt715",
},
{
.dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"),
.name_prefix = "rt5682",
},
};
static struct snd_soc_dai_link_component dmic_component[] = {
{
.name = "dmic-codec",
.dai_name = "dmic-hifi",
}
};
static struct snd_soc_dai_link_component platform_component[] = {
{
/* name might be overridden during probe */
.name = "0000:00:1f.3"
}
};
/* these wrappers are only needed to avoid typecast compilation errors */
static int sdw_startup(struct snd_pcm_substream *substream)
{
return sdw_startup_stream(substream);
}
static void sdw_shutdown(struct snd_pcm_substream *substream)
{
sdw_shutdown_stream(substream);
}
static const struct snd_soc_ops sdw_ops = {
.