Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
This commit is contained in:
commit
df91a2100c
|
@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
|
|||
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_eld_get_conn_type - Get device type hdmi/dp connected
|
||||
* @eld: pointer to an ELD memory structure
|
||||
*
|
||||
* The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
|
||||
* identify the display type connected.
|
||||
*/
|
||||
static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
|
||||
{
|
||||
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
|
||||
}
|
||||
|
||||
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
||||
size_t len),
|
||||
|
|
|
@ -490,6 +490,7 @@ config SND_SOC_GTM601
|
|||
config SND_SOC_HDAC_HDMI
|
||||
tristate
|
||||
select SND_HDA_EXT_CORE
|
||||
select SND_PCM_ELD
|
||||
select HDMI
|
||||
|
||||
config SND_SOC_ICS43432
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
#ifndef __HDAC_HDMI_H__
|
||||
#define __HDAC_HDMI_H__
|
||||
|
||||
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm);
|
||||
|
||||
#endif /* __HDAC_HDMI_H__ */
|
|
@ -163,6 +163,7 @@ config SND_SOC_INTEL_SKYLAKE
|
|||
tristate
|
||||
select SND_HDA_EXT_CORE
|
||||
select SND_SOC_TOPOLOGY
|
||||
select SND_HDA_I915
|
||||
select SND_SOC_INTEL_SST
|
||||
|
||||
config SND_SOC_INTEL_SKL_RT286_MACH
|
||||
|
@ -172,6 +173,7 @@ config SND_SOC_INTEL_SKL_RT286_MACH
|
|||
select SND_SOC_INTEL_SKYLAKE
|
||||
select SND_SOC_RT286
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
help
|
||||
This adds support for ASoC machine driver for Skylake platforms
|
||||
with RT286 I2S audio codec.
|
||||
|
@ -186,6 +188,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
|
|||
select SND_SOC_NAU8825
|
||||
select SND_SOC_SSM4567
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
help
|
||||
This adds support for ASoC Onboard Codec I2S machine driver. This will
|
||||
create an alsa sound card for NAU88L25 + SSM4567.
|
||||
|
@ -200,6 +203,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
|
|||
select SND_SOC_NAU8825
|
||||
select SND_SOC_MAX98357A
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
help
|
||||
This adds support for ASoC Onboard Codec I2S machine driver. This will
|
||||
create an alsa sound card for NAU88L25 + MAX98357A.
|
||||
|
|
|
@ -342,6 +342,10 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
|
|||
&chv_platform_data },
|
||||
{"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
|
||||
&chv_platform_data },
|
||||
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
|
||||
{"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", NULL,
|
||||
&chv_platform_data },
|
||||
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
@ -318,7 +318,6 @@ void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx,
|
|||
union ipc_header_high msg_high;
|
||||
u32 msg_low;
|
||||
struct ipc_dsp_hdr *dsp_hdr;
|
||||
unsigned int cmd_id;
|
||||
|
||||
msg_high = msg->mrfld_header.p.header_high;
|
||||
msg_low = msg->mrfld_header.p.header_low_payload;
|
||||
|
@ -357,7 +356,6 @@ void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx,
|
|||
return;
|
||||
/* Copy command id so that we can use to put sst to reset */
|
||||
dsp_hdr = (struct ipc_dsp_hdr *)data;
|
||||
cmd_id = dsp_hdr->cmd_id;
|
||||
dev_dbg(sst_drv_ctx->dev, "cmd_id %d\n", dsp_hdr->cmd_id);
|
||||
if (sst_wake_up_block(sst_drv_ctx, msg_high.part.result,
|
||||
msg_high.part.drv_id,
|
||||
|
|
|
@ -32,6 +32,18 @@
|
|||
#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),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
|
@ -70,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"),
|
||||
|
@ -174,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;
|
||||
|
@ -341,15 +340,34 @@ 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 */
|
||||
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
|
||||
"%s%s%s", "i2c-", mach->id, ":00");
|
||||
byt_rt5640_dais[MERR_DPCM_COMPR+1].codec_name = byt_rt5640_codec_name;
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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,15 +458,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,
|
||||
},
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -249,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",
|
||||
|
@ -266,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",
|
||||
|
@ -282,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",
|
||||
|
@ -295,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",
|
||||
|
@ -308,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 */
|
||||
{
|
||||
|
@ -341,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 */
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#include <linux/acpi.h>
|
||||
|
||||
/* translation fron HID to I2C name, needed for DAI codec_name */
|
||||
const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
|
||||
|
||||
/* acpi match */
|
||||
struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines);
|
||||
|
||||
|
|
|
@ -317,6 +317,7 @@ struct sst_dsp {
|
|||
struct skl_cl_dev cl_dev;
|
||||
u32 intr_status;
|
||||
const struct firmware *fw;
|
||||
struct snd_dma_buffer dmab;
|
||||
};
|
||||
|
||||
/* Size optimised DRAM/IRAM memcpy */
|
||||
|
|
|
@ -13,17 +13,53 @@
|
|||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "sst-acpi.h"
|
||||
|
||||
static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
|
||||
void *context, void **ret)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
const char *name = NULL;
|
||||
|
||||
if (acpi_bus_get_device(handle, &adev))
|
||||
return AE_OK;
|
||||
|
||||
if (adev->status.present && adev->status.functional) {
|
||||
name = acpi_dev_name(adev);
|
||||
*(const char **)ret = name;
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
|
||||
{
|
||||
const char *name = NULL;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_get_devices(hid, sst_acpi_find_name, NULL,
|
||||
(void **)&name);
|
||||
|
||||
if (ACPI_FAILURE(status) || name[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return name;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sst_acpi_find_name_from_hid);
|
||||
|
||||
static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
|
||||
void *context, void **ret)
|
||||
{
|
||||
unsigned long long sta;
|
||||
acpi_status status;
|
||||
|
||||
*(bool *)context = true;
|
||||
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
|
||||
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
|
||||
*(bool *)context = false;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
|
@ -37,7 +73,6 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
|
|||
sst_acpi_mach_match,
|
||||
&found, NULL)) && found)
|
||||
return mach;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
|
||||
|
|
|
@ -72,17 +72,47 @@ static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
|
|||
skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
|
||||
}
|
||||
|
||||
static struct skl_dsp_loader_ops skl_get_loader_ops(void)
|
||||
{
|
||||
struct skl_dsp_loader_ops loader_ops;
|
||||
|
||||
memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));
|
||||
|
||||
loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
|
||||
loader_ops.free_dma_buf = skl_free_dma_buf;
|
||||
|
||||
return loader_ops;
|
||||
};
|
||||
|
||||
static const struct skl_dsp_ops dsp_ops[] = {
|
||||
{
|
||||
.id = 0x9d70,
|
||||
.loader_ops = skl_get_loader_ops,
|
||||
.init = skl_sst_dsp_init,
|
||||
.cleanup = skl_sst_dsp_cleanup
|
||||
},
|
||||
};
|
||||
|
||||
static int skl_get_dsp_ops(int pci_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
|
||||
if (dsp_ops[i].id == pci_id)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int skl_init_dsp(struct skl *skl)
|
||||
{
|
||||
void __iomem *mmio_base;
|
||||
struct hdac_ext_bus *ebus = &skl->ebus;
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
int irq = bus->irq;
|
||||
struct skl_dsp_loader_ops loader_ops;
|
||||
int ret;
|
||||
|
||||
loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
|
||||
loader_ops.free_dma_buf = skl_free_dma_buf;
|
||||
int irq = bus->irq;
|
||||
int ret, index;
|
||||
|
||||
/* enable ppcap interrupt */
|
||||
snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
|
||||
|
@ -95,8 +125,14 @@ int skl_init_dsp(struct skl *skl)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
|
||||
index = skl_get_dsp_ops(skl->pci->device);
|
||||
if (index < 0)
|
||||
return -EINVAL;
|
||||
|
||||
loader_ops = dsp_ops[index].loader_ops();
|
||||
ret = dsp_ops[index].init(bus->dev, mmio_base, irq,
|
||||
skl->fw_name, loader_ops, &skl->skl_sst);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -106,18 +142,26 @@ int skl_init_dsp(struct skl *skl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void skl_free_dsp(struct skl *skl)
|
||||
int skl_free_dsp(struct skl *skl)
|
||||
{
|
||||
struct hdac_ext_bus *ebus = &skl->ebus;
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
struct skl_sst *ctx = skl->skl_sst;
|
||||
struct skl_sst *ctx = skl->skl_sst;
|
||||
int index;
|
||||
|
||||
/* disable ppcap interrupt */
|
||||
snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
|
||||
|
||||
skl_sst_dsp_cleanup(bus->dev, ctx);
|
||||
index = skl_get_dsp_ops(skl->pci->device);
|
||||
if (index < 0)
|
||||
return -EIO;
|
||||
|
||||
dsp_ops[index].cleanup(bus->dev, ctx);
|
||||
|
||||
if (ctx->dsp->addr.lpe)
|
||||
iounmap(ctx->dsp->addr.lpe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skl_suspend_dsp(struct skl *skl)
|
||||
|
@ -238,9 +282,8 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
|
|||
* Calculate the gatewat settings required for copier module, type of
|
||||
* gateway and index of gateway to use
|
||||
*/
|
||||
static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
|
||||
struct skl_module_cfg *mconfig,
|
||||
struct skl_cpr_cfg *cpr_mconfig)
|
||||
static u32 skl_get_node_id(struct skl_sst *ctx,
|
||||
struct skl_module_cfg *mconfig)
|
||||
{
|
||||
union skl_connector_node_id node_id = {0};
|
||||
union skl_ssp_dma_node ssp_node = {0};
|
||||
|
@ -289,13 +332,24 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
|
|||
break;
|
||||
|
||||
default:
|
||||
cpr_mconfig->gtw_cfg.node_id = SKL_NON_GATEWAY_CPR_NODE_ID;
|
||||
node_id.val = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
return node_id.val;
|
||||
}
|
||||
|
||||
static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
|
||||
struct skl_module_cfg *mconfig,
|
||||
struct skl_cpr_cfg *cpr_mconfig)
|
||||
{
|
||||
cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig);
|
||||
|
||||
if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
|
||||
cpr_mconfig->cpr_feature_mask = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cpr_mconfig->gtw_cfg.node_id = node_id.val;
|
||||
|
||||
if (SKL_CONN_SOURCE == mconfig->hw_conn_type)
|
||||
cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs;
|
||||
else
|
||||
|
@ -307,6 +361,46 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
|
|||
skl_copy_copier_caps(mconfig, cpr_mconfig);
|
||||
}
|
||||
|
||||
#define DMA_CONTROL_ID 5
|
||||
|
||||
int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
|
||||
{
|
||||
struct skl_dma_control *dma_ctrl;
|
||||
struct skl_i2s_config_blob config_blob;
|
||||
struct skl_ipc_large_config_msg msg = {0};
|
||||
int err = 0;
|
||||
|
||||
|
||||
/*
|
||||
* if blob size is same as capablity size, then no dma control
|
||||
* present so return
|
||||
*/
|
||||
if (mconfig->formats_config.caps_size == sizeof(config_blob))
|
||||
return 0;
|
||||
|
||||
msg.large_param_id = DMA_CONTROL_ID;
|
||||
msg.param_data_size = sizeof(struct skl_dma_control) +
|
||||
mconfig->formats_config.caps_size;
|
||||
|
||||
dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
|
||||
if (dma_ctrl == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_ctrl->node_id = skl_get_node_id(ctx, mconfig);
|
||||
|
||||
/* size in dwords */
|
||||
dma_ctrl->config_length = sizeof(config_blob) / 4;
|
||||
|
||||
memcpy(dma_ctrl->config_data, mconfig->formats_config.caps,
|
||||
mconfig->formats_config.caps_size);
|
||||
|
||||
err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
|
||||
|
||||
kfree(dma_ctrl);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void skl_setup_out_format(struct skl_sst *ctx,
|
||||
struct skl_module_cfg *mconfig,
|
||||
struct skl_audio_data_format *out_fmt)
|
||||
|
|
|
@ -145,3 +145,37 @@ struct nhlt_specific_cfg
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void skl_nhlt_trim_space(struct skl *skl)
|
||||
{
|
||||
char *s = skl->tplg_name;
|
||||
int cnt;
|
||||
int i;
|
||||
|
||||
cnt = 0;
|
||||
for (i = 0; s[i]; i++) {
|
||||
if (!isspace(s[i]))
|
||||
s[cnt++] = s[i];
|
||||
}
|
||||
|
||||
s[cnt] = '\0';
|
||||
}
|
||||
|
||||
int skl_nhlt_update_topology_bin(struct skl *skl)
|
||||
{
|
||||
struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
|
||||
struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
|
||||
struct device *dev = bus->dev;
|
||||
|
||||
dev_dbg(dev, "oem_id %.6s, oem_table_id %8s oem_revision %d\n",
|
||||
nhlt->header.oem_id, nhlt->header.oem_table_id,
|
||||
nhlt->header.oem_revision);
|
||||
|
||||
snprintf(skl->tplg_name, sizeof(skl->tplg_name), "%x-%.6s-%.8s-%d%s",
|
||||
skl->pci_id, nhlt->header.oem_id, nhlt->header.oem_table_id,
|
||||
nhlt->header.oem_revision, "-tplg.bin");
|
||||
|
||||
skl_nhlt_trim_space(skl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -206,6 +206,23 @@ static int skl_get_format(struct snd_pcm_substream *substream,
|
|||
return format_val;
|
||||
}
|
||||
|
||||
static int skl_be_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct skl *skl = get_skl_ctx(dai->dev);
|
||||
struct skl_sst *ctx = skl->skl_sst;
|
||||
struct skl_module_cfg *mconfig;
|
||||
|
||||
if ((dai->playback_active > 1) || (dai->capture_active > 1))
|
||||
return 0;
|
||||
|
||||
mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
|
||||
if (mconfig == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return skl_dsp_set_dma_control(ctx, mconfig);
|
||||
}
|
||||
|
||||
static int skl_pcm_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -458,7 +475,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
|
|||
struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
|
||||
struct hdac_ext_stream *link_dev;
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct skl_dma_params *dma_params;
|
||||
struct hdac_ext_dma_params *dma_params;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct skl_pipe_params p_params = {0};
|
||||
|
||||
|
@ -470,11 +487,9 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
|
|||
snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
|
||||
|
||||
/* set the stream tag in the codec dai dma params */
|
||||
dma_params = (struct skl_dma_params *)
|
||||
snd_soc_dai_get_dma_data(codec_dai, substream);
|
||||
dma_params = snd_soc_dai_get_dma_data(codec_dai, substream);
|
||||
if (dma_params)
|
||||
dma_params->stream_tag = hdac_stream(link_dev)->stream_tag;
|
||||
snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params);
|
||||
|
||||
p_params.s_fmt = snd_pcm_format_width(params_format(params));
|
||||
p_params.ch = params_channels(params);
|
||||
|
@ -588,6 +603,7 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = {
|
|||
|
||||
static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
|
||||
.hw_params = skl_be_hw_params,
|
||||
.prepare = skl_be_prepare,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_ops skl_link_dai_ops = {
|
||||
|
@ -660,6 +676,51 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
|
|||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "HDMI1 Pin",
|
||||
.ops = &skl_pcm_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "HDMI1 Playback",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
|
||||
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
|
||||
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
|
||||
SNDRV_PCM_RATE_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "HDMI2 Pin",
|
||||
.ops = &skl_pcm_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "HDMI2 Playback",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
|
||||
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
|
||||
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
|
||||
SNDRV_PCM_RATE_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "HDMI3 Pin",
|
||||
.ops = &skl_pcm_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "HDMI3 Playback",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
|
||||
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
|
||||
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
|
||||
SNDRV_PCM_RATE_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
},
|
||||
|
||||
/* BE CPU Dais */
|
||||
{
|
||||
|
@ -699,14 +760,41 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
|
|||
},
|
||||
},
|
||||
{
|
||||
.name = "iDisp Pin",
|
||||
.name = "iDisp1 Pin",
|
||||
.ops = &skl_link_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "iDisp Tx",
|
||||
.stream_name = "iDisp1 Tx",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "iDisp2 Pin",
|
||||
.ops = &skl_link_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "iDisp2 Tx",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "iDisp3 Pin",
|
||||
.ops = &skl_link_dai_ops,
|
||||
.playback = {
|
||||
.stream_name = "iDisp3 Tx",
|
||||
.channels_min = HDA_STEREO,
|
||||
.channels_max = HDA_STEREO,
|
||||
.rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -863,7 +951,9 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus,
|
|||
else
|
||||
delay += hstream->bufsize;
|
||||
}
|
||||
delay = (hstream->bufsize == delay) ? 0 : delay;
|
||||
|
||||
if (hstream->bufsize == delay)
|
||||
delay = 0;
|
||||
|
||||
if (delay >= hstream->period_bytes) {
|
||||
dev_info(bus->dev,
|
||||
|
|
|
@ -34,7 +34,7 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
|
|||
mutex_unlock(&ctx->mutex);
|
||||
}
|
||||
|
||||
static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx)
|
||||
static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)
|
||||
static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -87,7 +87,7 @@ static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool is_skl_dsp_core_enable(struct sst_dsp *ctx)
|
||||
static bool is_skl_dsp_core_enable(struct sst_dsp *ctx)
|
||||
{
|
||||
int val;
|
||||
bool is_enable;
|
||||
|
@ -140,7 +140,7 @@ static int skl_dsp_start_core(struct sst_dsp *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int skl_dsp_core_power_up(struct sst_dsp *ctx)
|
||||
static int skl_dsp_core_power_up(struct sst_dsp *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -166,7 +166,7 @@ static int skl_dsp_core_power_up(struct sst_dsp *ctx)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int skl_dsp_core_power_down(struct sst_dsp *ctx)
|
||||
static int skl_dsp_core_power_down(struct sst_dsp *ctx)
|
||||
{
|
||||
/* update bits */
|
||||
sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
|
||||
|
@ -181,7 +181,7 @@ static int skl_dsp_core_power_down(struct sst_dsp *ctx)
|
|||
"Power down");
|
||||
}
|
||||
|
||||
static int skl_dsp_enable_core(struct sst_dsp *ctx)
|
||||
int skl_dsp_enable_core(struct sst_dsp *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -195,7 +195,7 @@ static int skl_dsp_enable_core(struct sst_dsp *ctx)
|
|||
return skl_dsp_start_core(ctx);
|
||||
}
|
||||
|
||||
int skl_dsp_disable_core(struct sst_dsp *ctx)
|
||||
int skl_dsp_disable_core(struct sst_dsp *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ struct sst_dsp_device;
|
|||
/* HIPCT */
|
||||
#define SKL_ADSP_REG_HIPCT_BUSY BIT(31)
|
||||
|
||||
/* FW base IDs */
|
||||
#define SKL_INSTANCE_ID 0
|
||||
#define SKL_BASE_FW_MODULE_ID 0
|
||||
|
||||
/* Intel HD Audio SRAM Window 1 */
|
||||
#define SKL_ADSP_SRAM1_BASE 0xA000
|
||||
|
||||
|
@ -144,7 +148,8 @@ int skl_cldma_prepare(struct sst_dsp *ctx);
|
|||
void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
|
||||
struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
|
||||
struct sst_dsp_device *sst_dev, int irq);
|
||||
int skl_dsp_disable_core(struct sst_dsp *ctx);
|
||||
int skl_dsp_enable_core(struct sst_dsp *ctx);
|
||||
int skl_dsp_disable_core(struct sst_dsp *ctx);
|
||||
bool is_skl_dsp_running(struct sst_dsp *ctx);
|
||||
irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
|
||||
int skl_dsp_wake(struct sst_dsp *ctx);
|
||||
|
|
|
@ -35,9 +35,6 @@
|
|||
#define SKL_ADSP_FW_STATUS SKL_ADSP_SRAM0_BASE
|
||||
#define SKL_ADSP_ERROR_CODE (SKL_ADSP_FW_STATUS + 0x4)
|
||||
|
||||
#define SKL_INSTANCE_ID 0
|
||||
#define SKL_BASE_FW_MODULE_ID 0
|
||||
|
||||
#define SKL_NUM_MODULES 1
|
||||
|
||||
static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)
|
||||
|
|
|
@ -260,6 +260,65 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
|
|||
multiplier;
|
||||
}
|
||||
|
||||
static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
|
||||
struct skl_sst *ctx)
|
||||
{
|
||||
struct skl_module_cfg *m_cfg = w->priv;
|
||||
int link_type, dir;
|
||||
u32 ch, s_freq, s_fmt;
|
||||
struct nhlt_specific_cfg *cfg;
|
||||
struct skl *skl = get_skl_ctx(ctx->dev);
|
||||
|
||||
/* check if we already have blob */
|
||||
if (m_cfg->formats_config.caps_size > 0)
|
||||
return 0;
|
||||
|
||||
dev_dbg(ctx->dev, "Applying default cfg blob\n");
|
||||
switch (m_cfg->dev_type) {
|
||||
case SKL_DEVICE_DMIC:
|
||||
link_type = NHLT_LINK_DMIC;
|
||||
dir = SNDRV_PCM_STREAM_CAPTURE;
|
||||
s_freq = m_cfg->in_fmt[0].s_freq;
|
||||
s_fmt = m_cfg->in_fmt[0].bit_depth;
|
||||
ch = m_cfg->in_fmt[0].channels;
|
||||
break;
|
||||
|
||||
case SKL_DEVICE_I2S:
|
||||
link_type = NHLT_LINK_SSP;
|
||||
if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) {
|
||||
dir = SNDRV_PCM_STREAM_PLAYBACK;
|
||||
s_freq = m_cfg->out_fmt[0].s_freq;
|
||||
s_fmt = m_cfg->out_fmt[0].bit_depth;
|
||||
ch = m_cfg->out_fmt[0].channels;
|
||||
} else {
|
||||
dir = SNDRV_PCM_STREAM_CAPTURE;
|
||||
s_freq = m_cfg->in_fmt[0].s_freq;
|
||||
s_fmt = m_cfg->in_fmt[0].bit_depth;
|
||||
ch = m_cfg->in_fmt[0].channels;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* update the blob based on virtual bus_id and default params */
|
||||
cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type,
|
||||
s_fmt, ch, s_freq, dir);
|
||||
if (cfg) {
|
||||
m_cfg->formats_config.caps_size = cfg->size;
|
||||
m_cfg->formats_config.caps = (u32 *) &cfg->caps;
|
||||
} else {
|
||||
dev_err(ctx->dev, "Blob NULL for id %x type %d dirn %d\n",
|
||||
m_cfg->vbus_id, link_type, dir);
|
||||
dev_err(ctx->dev, "PCM: ch %d, freq %d, fmt %d\n",
|
||||
ch, s_freq, s_fmt);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
|
||||
struct skl_sst *ctx)
|
||||
{
|
||||
|
@ -433,6 +492,9 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* update blob if blob is null for be with default value */
|
||||
skl_tplg_update_be_blob(w, ctx);
|
||||
|
||||
/*
|
||||
* apply fix/conversion to module params based on
|
||||
* FE/BE params
|
||||
|
@ -545,6 +607,66 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some modules require params to be set after the module is bound to
|
||||
* all pins connected.
|
||||
*
|
||||
* The module provider initializes set_param flag for such modules and we
|
||||
* send params after binding
|
||||
*/
|
||||
static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
|
||||
struct skl_module_cfg *mcfg, struct skl_sst *ctx)
|
||||
{
|
||||
int i, ret;
|
||||
struct skl_module_cfg *mconfig = w->priv;
|
||||
const struct snd_kcontrol_new *k;
|
||||
struct soc_bytes_ext *sb;
|
||||
struct skl_algo_data *bc;
|
||||
struct skl_specific_cfg *sp_cfg;
|
||||
|
||||
/*
|
||||
* check all out/in pins are in bind state.
|
||||
* if so set the module param
|
||||
*/
|
||||
for (i = 0; i < mcfg->max_out_queue; i++) {
|
||||
if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < mcfg->max_in_queue; i++) {
|
||||
if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mconfig->formats_config.caps_size > 0 &&
|
||||
mconfig->formats_config.set_params == SKL_PARAM_BIND) {
|
||||
sp_cfg = &mconfig->formats_config;
|
||||
ret = skl_set_module_params(ctx, sp_cfg->caps,
|
||||
sp_cfg->caps_size,
|
||||
sp_cfg->param_id, mconfig);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < w->num_kcontrols; i++) {
|
||||
k = &w->kcontrol_news[i];
|
||||
if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
|
||||
sb = (void *) k->private_value;
|
||||
bc = (struct skl_algo_data *)sb->dobj.private;
|
||||
|
||||
if (bc->set_params == SKL_PARAM_BIND) {
|
||||
ret = skl_set_module_params(ctx,
|
||||
(u32 *)bc->params, bc->max,
|
||||
bc->param_id, mconfig);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
||||
struct skl *skl,
|
||||
struct snd_soc_dapm_widget *src_w,
|
||||
|
@ -579,11 +701,19 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
|||
sink = p->sink;
|
||||
sink_mconfig = sink->priv;
|
||||
|
||||
if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
|
||||
sink_mconfig->m_state == SKL_MODULE_UNINIT)
|
||||
continue;
|
||||
|
||||
/* Bind source to sink, mixin is always source */
|
||||
ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set module params after bind */
|
||||
skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx);
|
||||
skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
|
||||
|
||||
/* Start sinks pipe first */
|
||||
if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
|
||||
if (sink_mconfig->pipe->conn_type !=
|
||||
|
@ -714,6 +844,10 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set module params after bind */
|
||||
skl_tplg_set_module_bind_params(source, src_mconfig, ctx);
|
||||
skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
|
||||
|
||||
if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
|
||||
ret = skl_run_pipe(ctx, sink_mconfig->pipe);
|
||||
}
|
||||
|
@ -1091,6 +1225,66 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct skl_module_cfg *skl_get_mconfig_pb_cpr(
|
||||
struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
|
||||
{
|
||||
struct snd_soc_dapm_path *p;
|
||||
struct skl_module_cfg *mconfig = NULL;
|
||||
|
||||
snd_soc_dapm_widget_for_each_source_path(w, p) {
|
||||
if (w->endpoints[SND_SOC_DAPM_DIR_OUT] > 0) {
|
||||
if (p->connect &&
|
||||
(p->sink->id == snd_soc_dapm_aif_out) &&
|
||||
p->source->priv) {
|
||||
mconfig = p->source->priv;
|
||||
return mconfig;
|
||||
}
|
||||
mconfig = skl_get_mconfig_pb_cpr(dai, p->source);
|
||||
if (mconfig)
|
||||
return mconfig;
|
||||
}
|
||||
}
|
||||
return mconfig;
|
||||
}
|
||||
|
||||
static struct skl_module_cfg *skl_get_mconfig_cap_cpr(
|
||||
struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
|
||||
{
|
||||
struct snd_soc_dapm_path *p;
|
||||
struct skl_module_cfg *mconfig = NULL;
|
||||
|
||||
snd_soc_dapm_widget_for_each_sink_path(w, p) {
|
||||
if (w->endpoints[SND_SOC_DAPM_DIR_IN] > 0) {
|
||||
if (p->connect &&
|
||||
(p->source->id == snd_soc_dapm_aif_in) &&
|
||||
p->sink->priv) {
|
||||
mconfig = p->sink->priv;
|
||||
return mconfig;
|
||||
}
|
||||
mconfig = skl_get_mconfig_cap_cpr(dai, p->sink);
|
||||
if (mconfig)
|
||||
return mconfig;
|
||||
}
|
||||
}
|
||||
return mconfig;
|
||||
}
|
||||
|
||||
struct skl_module_cfg *
|
||||
skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
struct snd_soc_dapm_widget *w;
|
||||
struct skl_module_cfg *mconfig;
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
w = dai->playback_widget;
|
||||
mconfig = skl_get_mconfig_pb_cpr(dai, w);
|
||||
} else {
|
||||
w = dai->capture_widget;
|
||||
mconfig = skl_get_mconfig_cap_cpr(dai, w);
|
||||
}
|
||||
return mconfig;
|
||||
}
|
||||
|
||||
static u8 skl_tplg_be_link_type(int dev_type)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1464,8 +1658,7 @@ static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
|
|||
if (!ac->params)
|
||||
return -ENOMEM;
|
||||
|
||||
if (dfw_ac->params)
|
||||
memcpy(ac->params, dfw_ac->params, ac->max);
|
||||
memcpy(ac->params, dfw_ac->params, ac->max);
|
||||
}
|
||||
|
||||
be->dobj.private = ac;
|
||||
|
@ -1523,11 +1716,16 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
|
|||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
struct skl *skl = ebus_to_skl(ebus);
|
||||
|
||||
ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
|
||||
ret = request_firmware(&fw, skl->tplg_name, bus->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "tplg fw %s load failed with %d\n",
|
||||
"dfw_sst.bin", ret);
|
||||
return ret;
|
||||
skl->tplg_name, ret);
|
||||
ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Fallback tplg fw %s load failed with %d\n",
|
||||
"dfw_sst.bin", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -113,6 +113,29 @@ struct skl_cpr_gtw_cfg {
|
|||
u32 config_data[1];
|
||||
} __packed;
|
||||
|
||||
struct skl_i2s_config_blob {
|
||||
u32 gateway_attrib;
|
||||
u32 tdm_ts_group[8];
|
||||
u32 ssc0;
|
||||
u32 ssc1;
|
||||
u32 sscto;
|
||||
u32 sspsp;
|
||||
u32 sstsa;
|
||||
u32 ssrsa;
|
||||
u32 ssc2;
|
||||
u32 sspsp2;
|
||||
u32 ssc3;
|
||||
u32 ssioc;
|
||||
u32 mdivc;
|
||||
u32 mdivr;
|
||||
} __packed;
|
||||
|
||||
struct skl_dma_control {
|
||||
u32 node_id;
|
||||
u32 config_length;
|
||||
u32 config_data[1];
|
||||
} __packed;
|
||||
|
||||
struct skl_cpr_cfg {
|
||||
struct skl_base_cfg base_cfg;
|
||||
struct skl_audio_data_format out_fmt;
|
||||
|
@ -313,6 +336,8 @@ static inline struct skl *get_skl_ctx(struct device *dev)
|
|||
|
||||
int skl_tplg_be_update_params(struct snd_soc_dai *dai,
|
||||
struct skl_pipe_params *params);
|
||||
int skl_dsp_set_dma_control(struct skl_sst *ctx,
|
||||
struct skl_module_cfg *mconfig);
|
||||
void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
|
||||
struct skl_pipe_params *params, int stream);
|
||||
int skl_tplg_init(struct snd_soc_platform *platform,
|
||||
|
@ -345,5 +370,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
|
|||
int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
|
||||
u32 param_id, struct skl_module_cfg *mcfg);
|
||||
|
||||
struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai,
|
||||
int stream);
|
||||
enum skl_bitdepth skl_get_bit_depth(int params);
|
||||
#endif
|
||||
|
|
|
@ -144,7 +144,8 @@ enum module_pin_type {
|
|||
enum skl_module_param_type {
|
||||
SKL_PARAM_DEFAULT = 0,
|
||||
SKL_PARAM_INIT,
|
||||
SKL_PARAM_SET
|
||||
SKL_PARAM_SET,
|
||||
SKL_PARAM_BIND
|
||||
};
|
||||
|
||||
struct skl_dfw_module_pin {
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <sound/pcm.h>
|
||||
#include "../common/sst-acpi.h"
|
||||
#include <sound/hda_register.h>
|
||||
#include <sound/hdaudio.h>
|
||||
#include <sound/hda_i915.h>
|
||||
#include "skl.h"
|
||||
#include "skl-sst-dsp.h"
|
||||
#include "skl-sst-ipc.h"
|
||||
|
@ -243,6 +246,16 @@ static int skl_resume(struct device *dev)
|
|||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
int ret;
|
||||
|
||||
/* Turned OFF in HDMI codec driver after codec reconfiguration */
|
||||
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
|
||||
ret = snd_hdac_display_power(bus, true);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev,
|
||||
"Cannot turn on display power on i915\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* resume only when we are not in suspend active, otherwise need to
|
||||
* restore the device
|
||||
|
@ -481,6 +494,27 @@ static int skl_create(struct pci_dev *pci,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int skl_i915_init(struct hdac_bus *bus)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* The HDMI codec is in GPU so we need to ensure that it is powered
|
||||
* up and ready for probe
|
||||
*/
|
||||
err = snd_hdac_i915_init(bus);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_hdac_display_power(bus, true);
|
||||
if (err < 0) {
|
||||
dev_err(bus->dev, "Cannot turn on display power on i915\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int skl_first_init(struct hdac_ext_bus *ebus)
|
||||
{
|
||||
struct skl *skl = ebus_to_skl(ebus);
|
||||
|
@ -543,6 +577,12 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
|
|||
/* initialize chip */
|
||||
skl_init_pci(skl);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
|
||||
err = skl_i915_init(bus);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
skl_init_chip(bus, true);
|
||||
|
||||
/* codec detection */
|
||||
|
@ -573,11 +613,15 @@ static int skl_probe(struct pci_dev *pci,
|
|||
if (err < 0)
|
||||
goto out_free;
|
||||
|
||||
skl->pci_id = pci->device;
|
||||
|
||||
skl->nhlt = skl_nhlt_init(bus->dev);
|
||||
|
||||
if (skl->nhlt == NULL)
|
||||
goto out_free;
|
||||
|
||||
skl_nhlt_update_topology_bin(skl);
|
||||
|
||||
pci_set_drvdata(skl->pci, ebus);
|
||||
|
||||
/* check if dsp is there */
|
||||
|
@ -613,6 +657,14 @@ static int skl_probe(struct pci_dev *pci,
|
|||
if (err < 0)
|
||||
goto out_unregister;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
|
||||
err = snd_hdac_display_power(bus, false);
|
||||
if (err < 0) {
|
||||
dev_err(bus->dev, "Cannot turn off display power on i915\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/*configure PM */
|
||||
pm_runtime_put_noidle(bus->dev);
|
||||
pm_runtime_allow(bus->dev);
|
||||
|
@ -634,6 +686,31 @@ out_free:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void skl_shutdown(struct pci_dev *pci)
|
||||
{
|
||||
struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
struct hdac_stream *s;
|
||||
struct hdac_ext_stream *stream;
|
||||
struct skl *skl;
|
||||
|
||||
if (ebus == NULL)
|
||||
return;
|
||||
|
||||
skl = ebus_to_skl(ebus);
|
||||
|
||||
if (skl->init_failed)
|
||||
return;
|
||||
|
||||
snd_hdac_ext_stop_streams(ebus);
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
stream = stream_to_hdac_ext_stream(s);
|
||||
snd_hdac_ext_stream_decouple(ebus, stream, false);
|
||||
}
|
||||
|
||||
snd_hdac_bus_stop_chip(bus);
|
||||
}
|
||||
|
||||
static void skl_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
|
||||
|
@ -642,6 +719,9 @@ static void skl_remove(struct pci_dev *pci)
|
|||
if (skl->tplg)
|
||||
release_firmware(skl->tplg);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
|
||||
snd_hdac_i915_exit(&ebus->bus);
|
||||
|
||||
if (pci_dev_run_wake(pci))
|
||||
pm_runtime_get_noresume(&pci->dev);
|
||||
pci_dev_put(pci);
|
||||
|
@ -662,11 +742,18 @@ static struct sst_acpi_mach sst_skl_devdata[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static struct sst_acpi_mach sst_bxtp_devdata[] = {
|
||||
{ "INT343A", "bxt_alc298s_i2s", "intel/dsp_fw_bxtn.bin", NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
/* PCI IDs */
|
||||
static const struct pci_device_id skl_ids[] = {
|
||||
/* Sunrise Point-LP */
|
||||
{ PCI_DEVICE(0x8086, 0x9d70),
|
||||
.driver_data = (unsigned long)&sst_skl_devdata},
|
||||
/* BXT-P */
|
||||
{ PCI_DEVICE(0x8086, 0x5a98),
|
||||
.driver_data = (unsigned long)&sst_bxtp_devdata},
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, skl_ids);
|
||||
|
@ -677,6 +764,7 @@ static struct pci_driver skl_driver = {
|
|||
.id_table = skl_ids,
|
||||
.probe = skl_probe,
|
||||
.remove = skl_remove,
|
||||
.shutdown = skl_shutdown,
|
||||
.driver = {
|
||||
.pm = &skl_pm,
|
||||
},
|
||||
|
|
|
@ -73,6 +73,8 @@ struct skl {
|
|||
struct list_head ppl_list;
|
||||
|
||||
const char *fw_name;
|
||||
char tplg_name[64];
|
||||
unsigned short pci_id;
|
||||
const struct firmware *tplg;
|
||||
|
||||
int supend_active;
|
||||
|
@ -88,6 +90,16 @@ struct skl_dma_params {
|
|||
u8 stream_tag;
|
||||
};
|
||||
|
||||
struct skl_dsp_ops {
|
||||
int id;
|
||||
struct skl_dsp_loader_ops (*loader_ops)(void);
|
||||
int (*init)(struct device *dev, void __iomem *mmio_base,
|
||||
int irq, const char *fw_name,
|
||||
struct skl_dsp_loader_ops loader_ops,
|
||||
struct skl_sst **skl_sst);
|
||||
void (*cleanup)(struct device *dev, struct skl_sst *ctx);
|
||||
};
|
||||
|
||||
int skl_platform_unregister(struct device *dev);
|
||||
int skl_platform_register(struct device *dev);
|
||||
|
||||
|
@ -96,8 +108,9 @@ void skl_nhlt_free(void *addr);
|
|||
struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
|
||||
u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
|
||||
|
||||
int skl_nhlt_update_topology_bin(struct skl *skl);
|
||||
int skl_init_dsp(struct skl *skl);
|
||||
void skl_free_dsp(struct skl *skl);
|
||||
int skl_free_dsp(struct skl *skl);
|
||||
int skl_suspend_dsp(struct skl *skl);
|
||||
int skl_resume_dsp(struct skl *skl);
|
||||
#endif /* __SOUND_SOC_SKL_H */
|
||||
|
|
Loading…
Reference in New Issue