summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/Kconfig20
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c54
-rw-r--r--sound/soc/intel/atom/sst/sst.c1
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c10
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.c65
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c65
-rw-r--r--sound/soc/intel/boards/Kconfig175
-rw-r--r--sound/soc/intel/boards/Makefile19
-rw-r--r--sound/soc/intel/boards/bdw-rt5650.c327
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c67
-rw-r--r--sound/soc/intel/boards/broadwell.c16
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c58
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c25
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c1
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c24
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c130
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c72
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c102
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c52
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c1
-rw-r--r--sound/soc/intel/boards/cml_rt1011_rt5682.c487
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c37
-rw-r--r--sound/soc/intel/boards/haswell.c6
-rw-r--r--sound/soc/intel/boards/hda_dsp_common.c85
-rw-r--r--sound/soc/intel/boards/hda_dsp_common.h32
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98357a.c23
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98927.c27
-rw-r--r--sound/soc/intel/boards/kbl_rt5660.c4
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c14
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c161
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.c32
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.h27
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_generic.c15
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c10
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c14
-rw-r--r--sound/soc/intel/boards/skl_rt286.c10
-rw-r--r--sound/soc/intel/boards/sof_da7219_max98373.c371
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c124
-rw-r--r--sound/soc/intel/common/Makefile5
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cfl-match.c23
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cml-match.c152
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cnl-match.c24
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ehl-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c7
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-icl-match.c98
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-jsl-match.c25
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-tgl-match.c84
-rw-r--r--sound/soc/intel/common/soc-intel-quirks.h5
-rw-r--r--sound/soc/intel/common/sst-acpi.c3
-rw-r--r--sound/soc/intel/common/sst-ipc.c71
-rw-r--r--sound/soc/intel/common/sst-ipc.h28
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c164
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c60
-rw-r--r--sound/soc/intel/skylake/Makefile12
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c50
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.h7
-rw-r--r--sound/soc/intel/skylake/cnl-sst.c43
-rw-r--r--sound/soc/intel/skylake/skl-debug.c44
-rw-r--r--sound/soc/intel/skylake/skl-messages.c264
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c109
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.h119
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c152
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c5
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c1
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c10
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h29
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c160
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h55
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c37
-rw-r--r--sound/soc/intel/skylake/skl-sst.c54
-rw-r--r--sound/soc/intel/skylake/skl-topology.c494
-rw-r--r--sound/soc/intel/skylake/skl-topology.h43
-rw-r--r--sound/soc/intel/skylake/skl.c97
-rw-r--r--sound/soc/intel/skylake/skl.h105
74 files changed, 3596 insertions, 1824 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 96a00a9d4cf8..c8de0bb5bed9 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -59,10 +59,13 @@ config SND_SOC_INTEL_HASWELL
If you have a Intel Haswell or Broadwell platform connected to
an I2S codec, then enable this option by saying Y or m. This is
typically used for Chromebooks. This is a recommended option.
+ This option is mutually exclusive with the SOF support on
+ Broadwell. If you want to enable SOF on Broadwell, you need to
+ deselect this option first.
config SND_SOC_INTEL_BAYTRAIL
tristate "Baytrail (legacy) Platforms"
- depends on DMADEVICES && ACPI && SND_SST_ATOM_HIFI2_PLATFORM=n
+ depends on DMADEVICES && ACPI && SND_SST_ATOM_HIFI2_PLATFORM=n && SND_SOC_SOF_BAYTRAIL=n
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST_ACPI
select SND_SOC_INTEL_SST_FIRMWARE
@@ -101,6 +104,9 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
If you have a Intel Baytrail or Cherrytrail platform with an I2S
codec, then enable this option by saying Y or m. This is a
recommended option
+ This option is mutually exclusive with the SOF support on
+ Baytrail/Cherrytrail. If you want to enable SOF on
+ Baytrail/Cherrytrail, you need to deselect this option first.
config SND_SOC_INTEL_SKYLAKE
tristate "All Skylake/SST Platforms"
@@ -113,7 +119,7 @@ config SND_SOC_INTEL_SKYLAKE
select SND_SOC_INTEL_CNL
select SND_SOC_INTEL_CFL
help
- This is a backwards-compatible option to select all devices
+ This is a backwards-compatible option to select all devices
supported by the Intel SST/Skylake driver. This option is no
longer recommended and will be deprecated when the SOF
driver is introduced. Distributions should explicitly
@@ -203,9 +209,12 @@ config SND_SOC_INTEL_SKYLAKE_SSP_CLK
config SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
bool "HDAudio codec support"
help
- If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
- GeminiLake or CannonLake platform with an HDaudio codec
- then enable this option by saying Y
+ This option broke audio on Linus' Skylake laptop in December 2018
+ and the race conditions during the probe were not fixed since.
+ This option is DEPRECATED, all HDaudio codec support needs
+ to be handled by the SOF driver.
+ Distributions should not enable this option and there are no known
+ users of this capability.
config SND_SOC_INTEL_SKYLAKE_COMMON
tristate
@@ -215,6 +224,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON
select SND_SOC_INTEL_SST
select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
select SND_SOC_ACPI_INTEL_MATCH
+ select SND_INTEL_DSP_CONFIG
help
If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
GeminiLake or CannonLake platform with the DSP enabled in the BIOS
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 8cc3cc363eb0..340bd2be39a7 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -387,27 +387,6 @@ static int sst_media_prepare(struct snd_pcm_substream *substream,
return ret_val;
}
-static int sst_media_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int ret;
-
- ret =
- snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(params));
- if (ret)
- return ret;
- memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
- return 0;
-}
-
-static int sst_media_hw_free(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
static int sst_enable_ssp(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -473,8 +452,6 @@ static const struct snd_soc_dai_ops sst_media_dai_ops = {
.startup = sst_media_open,
.shutdown = sst_media_close,
.prepare = sst_media_prepare,
- .hw_params = sst_media_hw_params,
- .hw_free = sst_media_hw_free,
.mute_stream = sst_media_digital_mute,
};
@@ -586,7 +563,8 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
},
};
-static int sst_platform_open(struct snd_pcm_substream *substream)
+static int sst_soc_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
@@ -598,15 +576,15 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
return 0;
}
-static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
+static int sst_soc_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd)
{
int ret_val = 0, str_id;
struct sst_runtime_stream *stream;
int status;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- dev_dbg(rtd->dev, "sst_platform_pcm_trigger called\n");
+ dev_dbg(rtd->dev, "%s called\n", __func__);
if (substream->pcm->internal)
return 0;
stream = substream->runtime->private_data;
@@ -646,8 +624,8 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
}
-static snd_pcm_uframes_t sst_platform_pcm_pointer
- (struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t sst_soc_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct sst_runtime_stream *stream;
int ret_val, status;
@@ -668,21 +646,15 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
return str_info->buffer_ptr;
}
-static const struct snd_pcm_ops sst_platform_ops = {
- .open = sst_platform_open,
- .ioctl = snd_pcm_lib_ioctl,
- .trigger = sst_platform_pcm_trigger,
- .pointer = sst_platform_pcm_pointer,
-};
-
-static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int sst_soc_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
if (dai->driver->playback.channels_min ||
dai->driver->capture.channels_min) {
- snd_pcm_lib_preallocate_pages_for_all(pcm,
+ snd_pcm_set_managed_buffer_all(pcm,
SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_DMA),
SST_MIN_BUFFER, SST_MAX_BUFFER);
@@ -709,9 +681,11 @@ static const struct snd_soc_component_driver sst_soc_platform_drv = {
.name = DRV_NAME,
.probe = sst_soc_probe,
.remove = sst_soc_remove,
- .ops = &sst_platform_ops,
+ .open = sst_soc_open,
+ .trigger = sst_soc_trigger,
+ .pointer = sst_soc_pointer,
.compr_ops = &sst_platform_compr_ops,
- .pcm_new = sst_pcm_new,
+ .pcm_construct = sst_soc_pcm_new,
};
static int sst_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index fbecbb74350b..68bcec5241f7 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include <linux/pm_qos.h>
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index b728fb56ea4d..f3cfe83b9ac6 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -165,7 +165,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
ctx->iram_base = rsrc->start + ctx->pdata->res_info->iram_offset;
ctx->iram_end = ctx->iram_base + ctx->pdata->res_info->iram_size - 1;
dev_info(ctx->dev, "IRAM base: %#x", ctx->iram_base);
- ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base,
+ ctx->iram = devm_ioremap(ctx->dev, ctx->iram_base,
ctx->pdata->res_info->iram_size);
if (!ctx->iram) {
dev_err(ctx->dev, "unable to map IRAM\n");
@@ -175,7 +175,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
ctx->dram_base = rsrc->start + ctx->pdata->res_info->dram_offset;
ctx->dram_end = ctx->dram_base + ctx->pdata->res_info->dram_size - 1;
dev_info(ctx->dev, "DRAM base: %#x", ctx->dram_base);
- ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base,
+ ctx->dram = devm_ioremap(ctx->dev, ctx->dram_base,
ctx->pdata->res_info->dram_size);
if (!ctx->dram) {
dev_err(ctx->dev, "unable to map DRAM\n");
@@ -184,7 +184,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
ctx->shim_phy_add = rsrc->start + ctx->pdata->res_info->shim_offset;
dev_info(ctx->dev, "SHIM base: %#x", ctx->shim_phy_add);
- ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add,
+ ctx->shim = devm_ioremap(ctx->dev, ctx->shim_phy_add,
ctx->pdata->res_info->shim_size);
if (!ctx->shim) {
dev_err(ctx->dev, "unable to map SHIM\n");
@@ -197,7 +197,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
/* Get mailbox addr */
ctx->mailbox_add = rsrc->start + ctx->pdata->res_info->mbox_offset;
dev_info(ctx->dev, "Mailbox base: %#x", ctx->mailbox_add);
- ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add,
+ ctx->mailbox = devm_ioremap(ctx->dev, ctx->mailbox_add,
ctx->pdata->res_info->mbox_size);
if (!ctx->mailbox) {
dev_err(ctx->dev, "unable to map mailbox\n");
@@ -216,7 +216,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
ctx->ddr_base = rsrc->start;
ctx->ddr_end = rsrc->end;
dev_info(ctx->dev, "DDR base: %#x", ctx->ddr_base);
- ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base,
+ ctx->ddr = devm_ioremap(ctx->dev, ctx->ddr_base,
resource_size(rsrc));
if (!ctx->ddr) {
dev_err(ctx->dev, "unable to map DDR\n");
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
index 8bd1eddcc091..74274bd38f7a 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
@@ -211,7 +211,7 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
{
struct sst_byt_stream *stream;
- u64 header = msg->header;
+ u64 header = msg->tx.header;
u8 stream_id = sst_byt_header_str_id(header);
u8 stream_msg = sst_byt_header_msg_id(header);
@@ -240,9 +240,10 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
if (msg == NULL)
return 1;
+ msg->rx.header = header;
if (header & IPC_HEADER_LARGE(true)) {
- msg->rx_size = sst_byt_header_data(header);
- sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size);
+ msg->rx.size = sst_byt_header_data(header);
+ sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size);
}
/* update any stream states */
@@ -407,17 +408,18 @@ int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
{
- struct sst_byt_alloc_params *str_req = &stream->request;
- struct sst_byt_alloc_response *reply = &stream->reply;
- u64 header;
+ struct sst_ipc_message request, reply = {0};
int ret;
- header = sst_byt_header(IPC_IA_ALLOC_STREAM,
- sizeof(*str_req) + sizeof(u32),
+ request.header = sst_byt_header(IPC_IA_ALLOC_STREAM,
+ sizeof(stream->request) + sizeof(u32),
true, stream->str_id);
- ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req,
- sizeof(*str_req),
- reply, sizeof(*reply));
+ request.data = &stream->request;
+ request.size = sizeof(stream->request);
+ reply.data = &stream->reply;
+ reply.size = sizeof(stream->reply);
+
+ ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply);
if (ret < 0) {
dev_err(byt->dev, "ipc: error stream commit failed\n");
return ret;
@@ -430,7 +432,7 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
{
- u64 header;
+ struct sst_ipc_message request = {0};
int ret = 0;
struct sst_dsp *sst = byt->dsp;
unsigned long flags;
@@ -438,8 +440,9 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
if (!stream->commited)
goto out;
- header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
- ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0);
+ request.header = sst_byt_header(IPC_IA_FREE_STREAM,
+ 0, false, stream->str_id);
+ ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
if (ret < 0) {
dev_err(byt->dev, "ipc: free stream %d failed\n",
stream->str_id);
@@ -459,15 +462,13 @@ out:
static int sst_byt_stream_operations(struct sst_byt *byt, int type,
int stream_id, int wait)
{
- u64 header;
+ struct sst_ipc_message request = {0};
- header = sst_byt_header(type, 0, false, stream_id);
+ request.header = sst_byt_header(type, 0, false, stream_id);
if (wait)
- return sst_ipc_tx_message_wait(&byt->ipc, header, NULL,
- 0, NULL, 0);
+ return sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
else
- return sst_ipc_tx_message_nowait(&byt->ipc, header,
- NULL, 0);
+ return sst_ipc_tx_message_nowait(&byt->ipc, request);
}
/* stream ALSA trigger operations */
@@ -475,19 +476,17 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
u32 start_offset)
{
struct sst_byt_start_stream_params start_stream;
- void *tx_msg;
- size_t size;
- u64 header;
+ struct sst_ipc_message request;
int ret;
start_stream.byte_offset = start_offset;
- header = sst_byt_header(IPC_IA_START_STREAM,
+ request.header = sst_byt_header(IPC_IA_START_STREAM,
sizeof(start_stream) + sizeof(u32),
true, stream->str_id);
- tx_msg = &start_stream;
- size = sizeof(start_stream);
+ request.data = &start_stream;
+ request.size = sizeof(start_stream);
- ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size);
+ ret = sst_ipc_tx_message_nowait(&byt->ipc, request);
if (ret < 0)
dev_err(byt->dev, "ipc: error failed to start stream %d\n",
stream->str_id);
@@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{
- if (msg->header & IPC_HEADER_LARGE(true))
- sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+ if (msg->tx.header & IPC_HEADER_LARGE(true))
+ sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
- sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header);
+ sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header);
}
static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
@@ -648,9 +647,9 @@ static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size)
{
/* msg content = lower 32-bit of the header + data */
- *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1);
- memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size);
- msg->tx_size += sizeof(u32);
+ *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1);
+ memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size);
+ msg->tx.size += sizeof(u32);
}
static u64 byt_reply_msg_match(u64 header, u64 *mask)
diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index 9cbc982d46a9..53383055c8dc 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -58,11 +58,11 @@ struct sst_byt_priv_data {
};
/* this may get called several times by oss emulation */
-static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
+static int sst_byt_pcm_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
struct sst_byt *byt = pdata->byt;
@@ -102,8 +102,6 @@ static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
-
ret = sst_byt_stream_buffer(byt, pcm_data->stream,
substream->dma_buffer.addr,
params_buffer_bytes(params));
@@ -121,16 +119,6 @@ static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int sst_byt_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- dev_dbg(rtd->dev, "PCM: hw_free\n");
- snd_pcm_lib_free_pages(substream);
-
- return 0;
-}
-
static int sst_byt_pcm_restore_stream_context(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -164,10 +152,10 @@ static void sst_byt_pcm_work(struct work_struct *work)
sst_byt_pcm_restore_stream_context(pcm_data->substream);
}
-static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+static int sst_byt_pcm_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
struct sst_byt *byt = pdata->byt;
@@ -193,6 +181,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
pdata->restore_stream = false;
+ /* fallthrough */
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
sst_byt_stream_pause(byt, pcm_data->stream);
break;
@@ -227,11 +216,11 @@ static u32 byt_notify_pointer(struct sst_byt_stream *stream, void *data)
return pos;
}
-static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
@@ -240,10 +229,10 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream
return bytes_to_frames(runtime, pcm_data->hw_ptr);
}
-static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
+static int sst_byt_pcm_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
struct sst_byt *byt = pdata->byt;
@@ -268,10 +257,10 @@ static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
return 0;
}
-static int sst_byt_pcm_close(struct snd_pcm_substream *substream)
+static int sst_byt_pcm_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
struct sst_byt *byt = pdata->byt;
@@ -293,7 +282,8 @@ out:
return ret;
}
-static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
+static int sst_byt_pcm_mmap(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -302,30 +292,18 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream,
return snd_pcm_lib_default_mmap(substream, vma);
}
-static const struct snd_pcm_ops sst_byt_pcm_ops = {
- .open = sst_byt_pcm_open,
- .close = sst_byt_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = sst_byt_pcm_hw_params,
- .hw_free = sst_byt_pcm_hw_free,
- .trigger = sst_byt_pcm_trigger,
- .pointer = sst_byt_pcm_pointer,
- .mmap = sst_byt_pcm_mmap,
-};
-
-static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int sst_byt_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm = rtd->pcm;
size_t size;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_pdata *pdata = dev_get_platdata(component->dev);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
size = sst_byt_pcm_hardware.buffer_bytes_max;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- pdata->dma_dev,
- size, size);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
+ pdata->dma_dev, size, size);
}
return 0;
@@ -379,8 +357,13 @@ static int sst_byt_pcm_probe(struct snd_soc_component *component)
static const struct snd_soc_component_driver byt_dai_component = {
.name = DRV_NAME,
.probe = sst_byt_pcm_probe,
- .ops = &sst_byt_pcm_ops,
- .pcm_new = sst_byt_pcm_new,
+ .open = sst_byt_pcm_open,
+ .close = sst_byt_pcm_close,
+ .hw_params = sst_byt_pcm_hw_params,
+ .trigger = sst_byt_pcm_trigger,
+ .pointer = sst_byt_pcm_pointer,
+ .mmap = sst_byt_pcm_mmap,
+ .pcm_construct = sst_byt_pcm_new,
};
#ifdef CONFIG_PM
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 50bf149818b5..9ca2567d0059 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -3,16 +3,29 @@ menuconfig SND_SOC_INTEL_MACH
bool "Intel Machine drivers"
depends on SND_SOC_INTEL_SST_TOPLEVEL || SND_SOC_SOF_INTEL_TOPLEVEL
help
- Intel ASoC Machine Drivers. If you have a Intel machine that
- has an audio controller with a DSP and I2S or DMIC port, then
- enable this option by saying Y
+ Intel ASoC Machine Drivers. If you have a Intel machine that
+ has an audio controller with a DSP and I2S or DMIC port, then
+ enable this option by saying Y
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about Intel ASoC machine drivers.
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Intel ASoC machine drivers.
if SND_SOC_INTEL_MACH
+config SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES
+ bool "Use more user friendly long card names"
+ help
+ Some drivers report the I/O configuration to userspace through the
+ soundcard's long card name in the control user space AP. An unfortunate
+ side effect is that this long name may also be used by the GUI,
+ confusing users with information they don't need.
+ This option prevents the long name from being modified, and the I/O
+ configuration will be provided through a different component interface.
+ Select Y if userspace like UCM (Use Case Manager) uses the component
+ interface.
+ If unsure select N.
+
if SND_SOC_INTEL_HASWELL
config SND_SOC_INTEL_HASWELL_MACH
@@ -31,12 +44,27 @@ endif ## SND_SOC_INTEL_HASWELL
if SND_SOC_INTEL_HASWELL || SND_SOC_SOF_BROADWELL
+config SND_SOC_INTEL_BDW_RT5650_MACH
+ tristate "Broadwell with RT5650 codec"
+ depends on I2C
+ depends on I2C_DESIGNWARE_PLATFORM || COMPILE_TEST
+ depends on X86_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_RT5645
+ help
+ This adds the ASoC machine driver for Intel Broadwell platforms with
+ the RT5650 codec.
+ Say Y if you have such a device.
+ If unsure select "N".
+
config SND_SOC_INTEL_BDW_RT5677_MACH
tristate "Broadwell with RT5677 codec"
depends on I2C
depends on I2C_DESIGNWARE_PLATFORM || COMPILE_TEST
depends on GPIOLIB || COMPILE_TEST
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on SPI_MASTER
+ select SPI_PXA2XX
+ select SND_SOC_RT5677_SPI
select SND_SOC_RT5677
help
This adds support for Intel Broadwell platform based boards with
@@ -114,11 +142,11 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
depends on X86_INTEL_LPSS || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_RT5670
- help
- This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
- platforms with RT5672 audio codec.
- Say Y or m if you have such a device. This is a recommended option.
- If unsure select "N".
+ help
+ This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+ platforms with RT5672 audio codec.
+ Say Y or m if you have such a device. This is a recommended option.
+ If unsure select "N".
config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
tristate "Cherrytrail & Braswell with RT5645/5650 codec"
@@ -256,17 +284,25 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
endif ## SND_SOC_INTEL_SKL
+config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
+ tristate
+ select SND_SOC_DA7219
+ select SND_SOC_MAX98357A
+ select SND_SOC_DMIC
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
+ select SND_SOC_HDAC_HDMI
+
+config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
+ tristate
+ select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
+
if SND_SOC_INTEL_APL
config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
tristate "Broxton with DA7219 and MAX98357A in I2S Mode"
depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
- select SND_SOC_DA7219
- select SND_SOC_MAX98357A
- select SND_SOC_DMIC
- select SND_SOC_HDAC_HDMI
- select SND_HDA_DSP_LOADER
+ select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
help
This adds support for ASoC machine driver for Broxton-P platforms
with DA7219 + MAX98357A I2S audio codec.
@@ -280,7 +316,6 @@ config SND_SOC_INTEL_BXT_RT298_MACH
select SND_SOC_RT298
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
- select SND_HDA_DSP_LOADER
help
This adds support for ASoC machine driver for Broxton platforms
with RT286 I2S audio codec.
@@ -307,29 +342,27 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
- tristate "KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
+ tristate "KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
- depends on SPI
- select SND_SOC_RT5663
- select SND_SOC_RT5514
- select SND_SOC_RT5514_SPI
- select SND_SOC_MAX98927
- select SND_SOC_HDAC_HDMI
- help
- This adds support for ASoC Onboard Codec I2S machine driver. This will
- create an alsa sound card for RT5663 + RT5514 + MAX98927.
- Say Y or m if you have such a device. This is a recommended option.
- If unsure select "N".
+ depends on SPI
+ select SND_SOC_RT5663
+ select SND_SOC_RT5514
+ select SND_SOC_RT5514_SPI
+ select SND_SOC_MAX98927
+ select SND_SOC_HDAC_HDMI
+ select SND_SOC_INTEL_SKYLAKE_SSP_CLK
+ help
+ This adds support for ASoC Onboard Codec I2S machine driver. This will
+ create an alsa sound card for RT5663 + RT5514 + MAX98927.
+ Say Y or m if you have such a device. This is a recommended option.
+ If unsure select "N".
config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
tristate "KBL with DA7219 and MAX98357A in I2S Mode"
depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
- select SND_SOC_DA7219
- select SND_SOC_MAX98357A
- select SND_SOC_DMIC
- select SND_SOC_HDAC_HDMI
+ select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for DA7219 + MAX98357A I2S audio codec.
@@ -363,7 +396,18 @@ config SND_SOC_INTEL_KBL_RT5660_MACH
endif ## SND_SOC_INTEL_KBL
-if SND_SOC_INTEL_GLK || (SND_SOC_SOF_GEMINILAKE && SND_SOC_SOF_HDA_LINK)
+if SND_SOC_SOF_GEMINILAKE && SND_SOC_SOF_HDA_LINK
+
+config SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH
+ tristate "GLK with DA7219 and MAX98357A in I2S Mode"
+ depends on I2C && ACPI
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
+ help
+ This adds support for ASoC machine driver for Geminilake platforms
+ with DA7219 + MAX98357A I2S audio codec.
+ Say Y or m if you have such a device. This is a recommended option.
+ If unsure select "N".
config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
tristate "GLK with RT5682 and MAX98357A in I2S Mode"
@@ -372,44 +416,95 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
select SND_SOC_RT5682
select SND_SOC_MAX98357A
select SND_SOC_DMIC
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_HDAC_HDMI
- select SND_HDA_DSP_LOADER
help
This adds support for ASoC machine driver for Geminilake platforms
with RT5682 + MAX98357A I2S audio codec.
Say Y if you have such a device.
If unsure select "N".
-endif ## SND_SOC_INTEL_GLK || (SND_SOC_SOF_GEMINILAKE && SND_SOC_SOF_HDA_LINK)
+endif ## SND_SOC_SOF_GEMINILAKE && SND_SOC_SOF_HDA_LINK
if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC
config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
tristate "SKL/KBL/BXT/APL with HDA Codecs"
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_HDAC_HDMI
+ select SND_SOC_DMIC
# SND_SOC_HDAC_HDA is already selected
help
This adds support for ASoC machine driver for Intel platforms
SKL/KBL/BXT/APL with iDisp, HDA audio codecs.
- Say Y or m if you have such a device. This is a recommended option.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC
-if SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL
+if SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL
config SND_SOC_INTEL_SOF_RT5682_MACH
tristate "SOF with rt5682 codec in I2S Mode"
depends on I2C && ACPI
- depends on (SND_SOC_SOF_HDA_COMMON && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\
+ depends on (SND_SOC_SOF_HDA_LINK && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\
(SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST))
select SND_SOC_RT5682
select SND_SOC_DMIC
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC machine driver for SOF platforms
with rt5682 codec.
Say Y if you have such a device.
If unsure select "N".
-endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL
+endif ## SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL
+
+if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK)
+
+config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH
+ tristate "CML_LP with DA7219 and MAX98357A in I2S Mode"
+ depends on I2C && ACPI
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
+ help
+ This adds support for ASoC machine driver for Cometlake platforms
+ with DA7219 + MAX98357A I2S audio codec.
+ Say Y or m if you have such a device. This is a recommended option.
+ If unsure select "N".
+
+config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH
+ tristate "CML with RT1011 and RT5682 in I2S Mode"
+ depends on I2C && ACPI
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_RT1011
+ select SND_SOC_RT5682
+ select SND_SOC_DMIC
+ select SND_SOC_HDAC_HDMI
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
+ help
+ This adds support for ASoC machine driver for SOF platform with
+ RT1011 + RT5682 I2S codec.
+ Say Y if you have such a device.
+ If unsure select "N".
+
+endif ## SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK
+
+if SND_SOC_SOF_JASPERLAKE
+
+config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
+ tristate "SOF with DA7219 and MAX98373 in I2S Mode"
+ depends on I2C && ACPI
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_DA7219
+ select SND_SOC_MAX98373
+ select SND_SOC_DMIC
+ select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC
+ help
+ This adds support for ASoC machine driver for SOF platforms
+ with DA7219 + MAX98373 I2S audio codec.
+ Say Y if you have such a device.
+ If unsure select "N".
+
+endif ## SND_SOC_SOF_JASPERLAKE
endif ## SND_SOC_INTEL_MACH
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 6445f90ea542..b74ddd49bd39 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -2,11 +2,12 @@
snd-soc-sst-haswell-objs := haswell.o
snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
+snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o
snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o
snd-soc-sst-broadwell-objs := broadwell.o
-snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o
-snd-soc-sst-bxt-rt298-objs := bxt_rt298.o
-snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o
+snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o hda_dsp_common.o
+snd-soc-sst-bxt-rt298-objs := bxt_rt298.o hda_dsp_common.o
+snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o
snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
@@ -17,25 +18,28 @@ snd-soc-sst-byt-cht-cx2072x-objs := bytcht_cx2072x.o
snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
-snd-soc-sof_rt5682-objs := sof_rt5682.o
+snd-soc-sof_rt5682-objs := sof_rt5682.o hda_dsp_common.o
+snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o hda_dsp_common.o
snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o
snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
snd-soc-kbl_rt5660-objs := kbl_rt5660.o
snd-soc-skl_rt286-objs := skl_rt286.o
-snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o
+snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o hda_dsp_common.o
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
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
obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
-obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o
+obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
obj-$(CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH) += snd-soc-sst-glk-rt5682_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
+obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH) += snd-soc-sst-bdw-rt5650-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
@@ -47,6 +51,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH) += snd-soc-sst-byt-cht-cx2072x.
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
+obj-$(CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH) += snd-soc-cml_rt1011_rt5682.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH) += snd-soc-kbl_da7219_max98927.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o
@@ -56,3 +61,5 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
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
+
diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c
new file mode 100644
index 000000000000..1a302436d450
--- /dev/null
+++ b/sound/soc/intel/boards/bdw-rt5650.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ASoC machine driver for Intel Broadwell platforms with RT5650 codec
+ *
+ * Copyright 2019, The Chromium OS Authors. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+
+#include "../common/sst-dsp.h"
+#include "../haswell/sst-haswell-ipc.h"
+
+#include "../../codecs/rt5645.h"
+
+struct bdw_rt5650_priv {
+ struct gpio_desc *gpio_hp_en;
+ struct snd_soc_component *component;
+};
+
+static const struct snd_soc_dapm_widget bdw_rt5650_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("DMIC Pair1", NULL),
+ SND_SOC_DAPM_MIC("DMIC Pair2", NULL),
+};
+
+static const struct snd_soc_dapm_route bdw_rt5650_map[] = {
+ /* Speakers */
+ {"Speaker", NULL, "SPOL"},
+ {"Speaker", NULL, "SPOR"},
+
+ /* Headset jack connectors */
+ {"Headphone", NULL, "HPOL"},
+ {"Headphone", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"IN1N", NULL, "Headset Mic"},
+
+ /* Digital MICs
+ * DMIC Pair1 are the two DMICs connected on the DMICN1 connector.
+ * DMIC Pair2 are the two DMICs connected on the DMICN2 connector.
+ * Facing the camera, DMIC Pair1 are on the left side, DMIC Pair2
+ * are on the right side.
+ */
+ {"DMIC L1", NULL, "DMIC Pair1"},
+ {"DMIC R1", NULL, "DMIC Pair1"},
+ {"DMIC L2", NULL, "DMIC Pair2"},
+ {"DMIC R2", NULL, "DMIC Pair2"},
+
+ /* CODEC BE connections */
+ {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
+ {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
+};
+
+static const struct snd_kcontrol_new bdw_rt5650_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("DMIC Pair1"),
+ SOC_DAPM_PIN_SWITCH("DMIC Pair2"),
+};
+
+
+static struct snd_soc_jack headphone_jack;
+static struct snd_soc_jack mic_jack;
+
+static struct snd_soc_jack_pin headphone_jack_pin = {
+ .pin = "Headphone",
+ .mask = SND_JACK_HEADPHONE,
+};
+
+static struct snd_soc_jack_pin mic_jack_pin = {
+ .pin = "Headset Mic",
+ .mask = SND_JACK_MICROPHONE,
+};
+
+static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ /* The ADSP will covert the FE rate to 48k, max 4-channels */
+ rate->min = rate->max = 48000;
+ channels->min = 2;
+ channels->max = 4;
+
+ /* set SSP0 to 24 bit */
+ snd_mask_set_format(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+ SNDRV_PCM_FORMAT_S24_LE);
+
+ return 0;
+}
+
+static int bdw_rt5650_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+
+ /* Workaround: set codec PLL to 19.2MHz that PLL source is
+ * from MCLK(24MHz) to conform 2.4MHz DMIC clock.
+ */
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
+ 24000000, 19200000);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ return ret;
+ }
+
+ /* The actual MCLK freq is 24MHz. The codec is told that MCLK is
+ * 24.576MHz to satisfy the requirement of rl6231_get_clk_info.
+ * ASRC is enabled on AD and DA filters to ensure good audio quality.
+ */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1, 24576000,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec sysclk configuration\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static struct snd_soc_ops bdw_rt5650_ops = {
+ .hw_params = bdw_rt5650_hw_params,
+};
+
+#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+static int bdw_rt5650_rtd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component =
+ snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+ struct sst_pdata *pdata = dev_get_platdata(component->dev);
+ struct sst_hsw *broadwell = pdata->dsp;
+ int ret;
+
+ /* Set ADSP SSP port settings
+ * clock_divider = 4 means BCLK = MCLK/5 = 24MHz/5 = 4.8MHz
+ */
+ ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
+ SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
+ SST_HSW_DEVICE_TDM_CLOCK_MASTER, 4);
+ if (ret < 0) {
+ dev_err(rtd->dev, "error: failed to set device config\n");
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+static int bdw_rt5650_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct bdw_rt5650_priv *bdw_rt5650 =
+ snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *component = rtd->codec_dai->component;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+
+ /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
+ * The ASRC clock source is clk_i2s1_asrc.
+ */
+ rt5645_sel_asrc_clk_src(component,
+ RT5645_DA_STEREO_FILTER |
+ RT5645_DA_MONO_L_FILTER |
+ RT5645_DA_MONO_R_FILTER |
+ RT5645_AD_STEREO_FILTER |
+ RT5645_AD_MONO_L_FILTER |
+ RT5645_AD_MONO_R_FILTER,
+ RT5645_CLK_SEL_I2S1_ASRC);
+
+ /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
+
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret);
+ return ret;
+ }
+
+ /* Create and initialize headphone jack */
+ if (snd_soc_card_jack_new(rtd->card, "Headphone Jack",
+ SND_JACK_HEADPHONE, &headphone_jack,
+ &headphone_jack_pin, 1)) {
+ dev_err(component->dev, "Can't create headphone jack\n");
+ }
+
+ /* Create and initialize mic jack */
+ if (snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE,
+ &mic_jack, &mic_jack_pin, 1)) {
+ dev_err(component->dev, "Can't create mic jack\n");
+ }
+
+ rt5645_set_jack_detect(component, &headphone_jack, &mic_jack, NULL);
+
+ bdw_rt5650->component = component;
+
+ return 0;
+}
+
+/* broadwell digital audio interface glue - connects codec <--> CPU */
+SND_SOC_DAILINK_DEF(dummy,
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
+
+SND_SOC_DAILINK_DEF(fe,
+ DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));
+
+SND_SOC_DAILINK_DEF(be,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5650:00", "rt5645-aif1")));
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));
+#else
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
+#endif
+
+static struct snd_soc_dai_link bdw_rt5650_dais[] = {
+ /* Front End DAI links */
+ {
+ .name = "System PCM",
+ .stream_name = "System Playback",
+ .dynamic = 1,
+#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+ .init = bdw_rt5650_rtd_init,
+#endif
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST
+ },
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(fe, dummy, platform),
+ },
+
+ /* Back End DAI links */
+ {
+ /* SSP0 - Codec */
+ .name = "Codec",
+ .id = 0,
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_hw_params_fixup = broadwell_ssp0_fixup,
+ .ops = &bdw_rt5650_ops,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .init = bdw_rt5650_init,
+ SND_SOC_DAILINK_REG(ssp0_port, be, platform),
+ },
+};
+
+/* ASoC machine driver for Broadwell DSP + RT5650 */
+static struct snd_soc_card bdw_rt5650_card = {
+ .name = "bdw-rt5650",
+ .owner = THIS_MODULE,
+ .dai_link = bdw_rt5650_dais,
+ .num_links = ARRAY_SIZE(bdw_rt5650_dais),
+ .dapm_widgets = bdw_rt5650_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(bdw_rt5650_widgets),
+ .dapm_routes = bdw_rt5650_map,
+ .num_dapm_routes = ARRAY_SIZE(bdw_rt5650_map),
+ .controls = bdw_rt5650_controls,
+ .num_controls = ARRAY_SIZE(bdw_rt5650_controls),
+ .fully_routed = true,
+};
+
+static int bdw_rt5650_probe(struct platform_device *pdev)
+{
+ struct bdw_rt5650_priv *bdw_rt5650;
+ struct snd_soc_acpi_mach *mach;
+ int ret;
+
+ bdw_rt5650_card.dev = &pdev->dev;
+
+ /* Allocate driver private struct */
+ bdw_rt5650 = devm_kzalloc(&pdev->dev, sizeof(struct bdw_rt5650_priv),
+ GFP_KERNEL);
+ if (!bdw_rt5650)
+ return -ENOMEM;
+
+ /* override plaform name, if required */
+ mach = (&pdev->dev)->platform_data;
+ ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5650_card,
+ mach->mach_params.platform);
+
+ if (ret)
+ return ret;
+
+ snd_soc_card_set_drvdata(&bdw_rt5650_card, bdw_rt5650);
+
+ return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5650_card);
+}
+
+static struct platform_driver bdw_rt5650_audio = {
+ .probe = bdw_rt5650_probe,
+ .driver = {
+ .name = "bdw-rt5650",
+ .pm = &snd_soc_pm_ops,
+ },
+};
+
+module_platform_driver(bdw_rt5650_audio)
+
+/* Module information */
+MODULE_AUTHOR("Ben Zhang <benzh@chromium.org>");
+MODULE_DESCRIPTION("Intel Broadwell RT5650 machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:bdw-rt5650");
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index e8e9c3dc82a5..bb643c99069d 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -74,6 +74,11 @@ static const struct snd_soc_dapm_route bdw_rt5677_map[] = {
/* CODEC BE connections */
{"SSP0 CODEC IN", NULL, "AIF1 Capture"},
{"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
+ {"DSP Capture", NULL, "DSP Buffer"},
+
+ /* DSP Clock Connections */
+ { "DSP Buffer", NULL, "SSP0 CODEC IN" },
+ { "SSP0 CODEC IN", NULL, "DSPTX" },
};
static const struct snd_kcontrol_new bdw_rt5677_controls[] = {
@@ -165,10 +170,37 @@ static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec sysclk configuration\n");
+ return ret;
+ }
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK,
+ 24000000, 24576000);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll configuration\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_ops bdw_rt5677_ops = {
.hw_params = bdw_rt5677_hw_params,
};
+static const struct snd_soc_ops bdw_rt5677_dsp_ops = {
+ .hw_params = bdw_rt5677_dsp_hw_params,
+};
+
#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
{
@@ -208,6 +240,11 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER |
RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
RT5677_CLK_SEL_I2S1_ASRC);
+ /* Enable codec ASRC function for Mono ADC L.
+ * The ASRC clock source is clk_sys2_asrc.
+ */
+ rt5677_sel_asrc_clk_src(component, RT5677_AD_MONO_L_FILTER,
+ RT5677_CLK_SEL_SYS2);
/* Request rt5677 GPIO for headphone amp control */
bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
@@ -258,6 +295,20 @@ SND_SOC_DAILINK_DEF(platform,
SND_SOC_DAILINK_DEF(be,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-aif1")));
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));
+#else
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
+#endif
+
+/* Wake on voice interface */
+SND_SOC_DAILINK_DEFS(dsp,
+ DAILINK_COMP_ARRAY(COMP_CPU("spi-RT5677AA:00")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-dspbuffer")),
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("spi-RT5677AA:00")));
+
static struct snd_soc_dai_link bdw_rt5677_dais[] = {
/* Front End DAI links */
{
@@ -276,6 +327,14 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
SND_SOC_DAILINK_REG(fe, dummy, platform),
},
+ /* Non-DPCM links */
+ {
+ .name = "Codec DSP",
+ .stream_name = "Wake on Voice",
+ .ops = &bdw_rt5677_dsp_ops,
+ SND_SOC_DAILINK_REG(dsp),
+ },
+
/* Back End DAI links */
{
/* SSP0 - Codec */
@@ -291,7 +350,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = bdw_rt5677_init,
- SND_SOC_DAILINK_REG(dummy, be, dummy),
+ SND_SOC_DAILINK_REG(ssp0_port, be, platform),
},
};
@@ -340,7 +399,6 @@ static int bdw_rt5677_probe(struct platform_device *pdev)
{
struct bdw_rt5677_priv *bdw_rt5677;
struct snd_soc_acpi_mach *mach;
- const char *platform_name = NULL;
int ret;
bdw_rt5677_card.dev = &pdev->dev;
@@ -355,11 +413,8 @@ static int bdw_rt5677_probe(struct platform_device *pdev)
/* override plaform name, if required */
mach = (&pdev->dev)->platform_data;
- if (mach) /* extra check since legacy does not pass parameters */
- platform_name = mach->mach_params.platform;
-
ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card,
- platform_name);
+ mach->mach_params.platform);
if (ret)
return ret;
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index ab38ef30dfff..b9c12e24c70b 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -164,6 +164,14 @@ SND_SOC_DAILINK_DEF(platform,
SND_SOC_DAILINK_DEF(codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1")));
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));
+#else
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
+#endif
+
/* broadwell digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link broadwell_rt286_dais[] = {
/* Front End DAI links */
@@ -218,7 +226,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
.ops = &broadwell_rt286_ops,
.dpcm_playback = 1,
.dpcm_capture = 1,
- SND_SOC_DAILINK_REG(dummy, codec, dummy),
+ SND_SOC_DAILINK_REG(ssp0_port, codec, platform),
},
};
@@ -270,18 +278,14 @@ static struct snd_soc_card broadwell_rt286 = {
static int broadwell_audio_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach;
- const char *platform_name = NULL;
int ret;
broadwell_rt286.dev = &pdev->dev;
/* override plaform name, if required */
mach = (&pdev->dev)->platform_data;
- if (mach) /* extra check since legacy does not pass parameters */
- platform_name = mach->mach_params.platform;
-
ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286,
- platform_name);
+ mach->mach_params.platform);
if (ret)
return ret;
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index c0d865a940dc..9177401c37a5 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -21,6 +21,7 @@
#include "../../codecs/da7219.h"
#include "../../codecs/da7219-aad.h"
#include "../common/soc-intel-quirks.h"
+#include "hda_dsp_common.h"
#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
#define BXT_MAXIM_CODEC_DAI "HiFi"
@@ -38,6 +39,7 @@ struct bxt_hdmi_pcm {
struct bxt_card_private {
struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
};
enum {
@@ -159,13 +161,13 @@ static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = DUAL_CHANNEL;
+ chan->min = chan->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
@@ -179,10 +181,17 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
int ret;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_component *component = rtd->codec_dai->component;
+ int clk_freq;
/* Configure sysclk for codec */
- ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000,
+ if (soc_intel_is_cml())
+ clk_freq = 24000000;
+ else
+ clk_freq = 19200000;
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq,
SND_SOC_CLOCK_IN);
+
if (ret) {
dev_err(rtd->dev, "can't set codec sysclk configuration\n");
return ret;
@@ -304,12 +313,12 @@ static const struct snd_soc_ops broxton_da7219_fe_ops = {
static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
if (params_channels(params) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
@@ -608,6 +617,16 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
snd_soc_dapm_add_routes(&card->dapm, broxton_map,
ARRAY_SIZE(broxton_map));
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ 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),
@@ -627,9 +646,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++;
}
- if (!component)
- return -EINVAL;
-
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
@@ -683,6 +699,25 @@ static int broxton_audio_probe(struct platform_device *pdev)
broxton_dais[i].cpus->dai_name = "SSP2 Pin";
}
}
+ } else if (soc_intel_is_cml()) {
+ unsigned int i;
+
+ broxton_audio_card.name = "cmlda7219max";
+
+ for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
+ /* MAXIM_CODEC is connected to SSP1. */
+ if (!strcmp(broxton_dais[i].codecs->dai_name,
+ BXT_MAXIM_CODEC_DAI)) {
+ broxton_dais[i].name = "SSP1-Codec";
+ broxton_dais[i].cpus->dai_name = "SSP1 Pin";
+ }
+ /* DIALOG_CODEC is connected to SSP0 */
+ else if (!strcmp(broxton_dais[i].codecs->dai_name,
+ BXT_DIALOG_CODEC_DAI)) {
+ broxton_dais[i].name = "SSP0-Codec";
+ broxton_dais[i].cpus->dai_name = "SSP0 Pin";
+ }
+ }
}
/* override plaform name, if required */
@@ -694,12 +729,15 @@ static int broxton_audio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card);
}
static const struct platform_device_id bxt_board_ids[] = {
{ .name = "bxt_da7219_max98357a" },
{ .name = "glk_da7219_max98357a" },
+ { .name = "cml_da7219_max98357a" },
{ }
};
@@ -720,6 +758,8 @@ MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
+MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bxt_da7219_max98357a");
MODULE_ALIAS("platform:glk_da7219_max98357a");
+MODULE_ALIAS("platform:cml_da7219_max98357a");
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index adf416a49b48..4b67f261377c 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -18,6 +18,7 @@
#include <sound/pcm_params.h>
#include "../../codecs/hdac_hdmi.h"
#include "../../codecs/rt298.h"
+#include "hda_dsp_common.h"
/* Headset jack detection DAPM pins */
static struct snd_soc_jack broxton_headset;
@@ -31,6 +32,7 @@ struct bxt_hdmi_pcm {
struct bxt_rt286_private {
struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
};
enum {
@@ -204,13 +206,13 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
/* set SSP5 to 24 bit */
snd_mask_none(fmt);
@@ -253,9 +255,9 @@ static const struct snd_pcm_hw_constraint_list constraints_rates = {
static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
@@ -527,6 +529,16 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
int err, i = 0;
char jack_name[NAME_SIZE];
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ 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),
@@ -546,9 +558,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++;
}
- if (!component)
- return -EINVAL;
-
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
@@ -626,6 +635,8 @@ static int broxton_audio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
return devm_snd_soc_register_card(&pdev->dev, card);
}
diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c
index 54ac2fd41925..67f06c95eec5 100644
--- a/sound/soc/intel/boards/bytcht_cx2072x.c
+++ b/sound/soc/intel/boards/bytcht_cx2072x.c
@@ -6,6 +6,7 @@
#include <linux/acpi.h>
#include <linux/device.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 46612331f5ea..0adc5a5e134a 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -234,14 +234,6 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
return 0;
}
-static const struct snd_soc_pcm_stream byt_cht_es8316_dai_params = {
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
-};
-
static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -360,7 +352,10 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
/* SoC card */
static char codec_name[SND_ACPI_I2C_ID_LEN];
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
static char long_name[50]; /* = "bytcht-es8316-*-spk-*-mic" */
+#endif
+static char components_string[32]; /* = "cfg-spk:* cfg-mic:* */
static int byt_cht_es8316_suspend(struct snd_soc_card *card)
{
@@ -442,7 +437,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
DMI_MATCH(DMI_PRODUCT_NAME, "NB41"),
},
- .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP
+ .driver_data = (void *)(BYT_CHT_ES8316_SSP0
+ | BYT_CHT_ES8316_INTMIC_IN2_MAP
| BYT_CHT_ES8316_JD_INVERTED),
},
{ /* Teclast X98 Plus II */
@@ -572,11 +568,19 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
}
}
- /* register the soc card */
+ snprintf(components_string, sizeof(components_string),
+ "cfg-spk:%s cfg-mic:%s",
+ (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "1" : "2",
+ mic_name[BYT_CHT_ES8316_MAP(quirk)]);
+ byt_cht_es8316_card.components = components_string;
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
snprintf(long_name, sizeof(long_name), "bytcht-es8316-%s-spk-%s-mic",
(quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo",
mic_name[BYT_CHT_ES8316_MAP(quirk)]);
byt_cht_es8316_card.long_name = long_name;
+#endif
+
+ /* register the soc card */
snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 9c1aa4ec9cba..6bd9ae813be2 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -405,10 +405,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
},
- .driver_data = (void *)(BYT_RT5640_IN1_MAP |
- BYT_RT5640_MCLK_EN |
- BYT_RT5640_SSP0_AIF1),
-
+ .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+ BYT_RT5640_JD_SRC_JD2_IN4N |
+ BYT_RT5640_OVCD_TH_2000UA |
+ BYT_RT5640_OVCD_SF_0P75 |
+ BYT_RT5640_SSP0_AIF1 |
+ BYT_RT5640_MCLK_EN),
},
{
.matches = {
@@ -705,13 +707,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_MCLK_EN),
},
{
+ /* Teclast X89 */
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
},
.driver_data = (void *)(BYT_RT5640_IN3_MAP |
- BYT_RT5640_MCLK_EN |
- BYT_RT5640_SSP0_AIF1),
+ BYT_RT5640_JD_SRC_JD1_IN4P |
+ BYT_RT5640_OVCD_TH_2000UA |
+ BYT_RT5640_OVCD_SF_1P0 |
+ BYT_RT5640_SSP0_AIF1 |
+ BYT_RT5640_MCLK_EN),
},
{ /* Toshiba Satellite Click Mini L9W-B */
.matches = {
@@ -927,14 +933,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
return 0;
}
-static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
-};
-
static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -942,65 +940,43 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
- int ret;
+ int ret, bits;
/* The DSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
- (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
/* set SSP0 to 16-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
-
- /*
- * Default mode for SSP configuration is TDM 4 slot, override config
- * with explicit setting to I2S 2ch 16-bit. The word length is set with
- * dai_set_tdm_slot() since there is no other API exposed
- */
- ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS
- );
- if (ret < 0) {
- dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
- if (ret < 0) {
- dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
- return ret;
- }
-
+ bits = 16;
} else {
-
/* set SSP2 to 24-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+ bits = 24;
+ }
- /*
- * Default mode for SSP configuration is TDM 4 slot, override config
- * with explicit setting to I2S 2ch 24-bit. The word length is set with
- * dai_set_tdm_slot() since there is no other API exposed
- */
- ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS
- );
- if (ret < 0) {
- dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
- return ret;
- }
+ /*
+ * Default mode for SSP configuration is TDM 4 slot, override config
+ * with explicit setting to I2S 2ch. The word length is set with
+ * dai_set_tdm_slot() since there is no other API exposed
+ */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
+ return ret;
+ }
- ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
- if (ret < 0) {
- dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
- return ret;
- }
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
+ return ret;
}
+
return 0;
}
@@ -1078,9 +1054,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
/* SoC card */
static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
-static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
-static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
+#endif
+static char byt_rt5640_components[32]; /* = "cfg-spk:* cfg-mic:*" */
static int byt_rt5640_suspend(struct snd_soc_card *card)
{
@@ -1260,28 +1237,12 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
log_quirks(&pdev->dev);
if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
- (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
- /* fixup codec aif name */
- snprintf(byt_rt5640_codec_aif_name,
- sizeof(byt_rt5640_codec_aif_name),
- "%s", "rt5640-aif2");
-
- byt_rt5640_dais[dai_index].codecs->dai_name =
- byt_rt5640_codec_aif_name;
- }
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
+ byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2";
if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
- (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
- /* fixup cpu dai name name */
- snprintf(byt_rt5640_cpu_dai_name,
- sizeof(byt_rt5640_cpu_dai_name),
- "%s", "ssp0-port");
-
- byt_rt5640_dais[dai_index].cpus->dai_name =
- byt_rt5640_cpu_dai_name;
- }
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
+ byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port";
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
@@ -1303,12 +1264,19 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
}
}
+ snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
+ "cfg-spk:%s cfg-mic:%s",
+ (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? "1" : "2",
+ map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
+ byt_rt5640_card.components = byt_rt5640_components;
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
"bytcr-rt5640-%s-spk-%s-mic",
(byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
"mono" : "stereo",
map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
byt_rt5640_card.long_name = byt_rt5640_long_name;
+#endif
/* override plaform name, if required */
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 4606f6f582d6..5074bb53f98e 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -656,14 +656,6 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
return 0;
}
-static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
-};
-
static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -795,9 +787,10 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
/* SoC card */
static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
-static char byt_rt5651_codec_aif_name[12]; /* = "rt5651-aif[1|2]" */
-static char byt_rt5651_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
static char byt_rt5651_long_name[50]; /* = "bytcr-rt5651-*-spk-*-mic[-swapped-hp]" */
+#endif
+static char byt_rt5651_components[50]; /* = "cfg-spk:* cfg-mic:*" */
static int byt_rt5651_suspend(struct snd_soc_card *card)
{
@@ -876,7 +869,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
const char *platform_name;
struct acpi_device *adev;
struct device *codec_dev;
- const char *hp_swapped;
bool is_bytcr = false;
int ret_val = 0;
int dai_index = 0;
@@ -996,10 +988,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (byt_rt5651_gpios) {
devm_acpi_dev_add_driver_gpios(codec_dev, byt_rt5651_gpios);
- priv->ext_amp_gpio = devm_fwnode_get_index_gpiod_from_child(
- &pdev->dev, "ext-amp-enable", 0,
- codec_dev->fwnode,
- GPIOD_OUT_LOW, "speaker-amp");
+ priv->ext_amp_gpio = devm_fwnode_gpiod_get(&pdev->dev,
+ codec_dev->fwnode,
+ "ext-amp-enable",
+ GPIOD_OUT_LOW,
+ "speaker-amp");
if (IS_ERR(priv->ext_amp_gpio)) {
ret_val = PTR_ERR(priv->ext_amp_gpio);
switch (ret_val) {
@@ -1015,10 +1008,11 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
return ret_val;
}
}
- priv->hp_detect = devm_fwnode_get_index_gpiod_from_child(
- &pdev->dev, "hp-detect", 0,
- codec_dev->fwnode,
- GPIOD_IN, "hp-detect");
+ priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev,
+ codec_dev->fwnode,
+ "hp-detect",
+ GPIOD_IN,
+ "hp-detect");
if (IS_ERR(priv->hp_detect)) {
ret_val = PTR_ERR(priv->hp_detect);
switch (ret_val) {
@@ -1041,26 +1035,12 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
log_quirks(&pdev->dev);
if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
- (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
- /* fixup codec aif name */
- snprintf(byt_rt5651_codec_aif_name,
- sizeof(byt_rt5651_codec_aif_name),
- "%s", "rt5651-aif2");
-
- byt_rt5651_dais[dai_index].codecs->dai_name =
- byt_rt5651_codec_aif_name;
- }
+ (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2))
+ byt_rt5651_dais[dai_index].codecs->dai_name = "rt5651-aif2";
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
- (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
- /* fixup cpu dai name name */
- snprintf(byt_rt5651_cpu_dai_name,
- sizeof(byt_rt5651_cpu_dai_name),
- "%s", "ssp0-port");
-
- byt_rt5651_dais[dai_index].cpus->dai_name =
- byt_rt5651_cpu_dai_name;
- }
+ (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2))
+ byt_rt5651_dais[dai_index].cpus->dai_name = "ssp0-port";
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
@@ -1080,17 +1060,23 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
}
}
- if (byt_rt5651_quirk & BYT_RT5651_HP_LR_SWAPPED)
- hp_swapped = "-hp-swapped";
- else
- hp_swapped = "";
-
+ snprintf(byt_rt5651_components, sizeof(byt_rt5651_components),
+ "cfg-spk:%s cfg-mic:%s%s",
+ (byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER) ? "1" : "2",
+ mic_name[BYT_RT5651_MAP(byt_rt5651_quirk)],
+ (byt_rt5651_quirk & BYT_RT5651_HP_LR_SWAPPED) ?
+ " cfg-hp:lrswap" : "");
+ byt_rt5651_card.components = byt_rt5651_components;
+#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
snprintf(byt_rt5651_long_name, sizeof(byt_rt5651_long_name),
"bytcr-rt5651-%s-spk-%s-mic%s",
(byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER) ?
"mono" : "stereo",
- mic_name[BYT_RT5651_MAP(byt_rt5651_quirk)], hp_swapped);
+ mic_name[BYT_RT5651_MAP(byt_rt5651_quirk)],
+ (byt_rt5651_quirk & BYT_RT5651_HP_LR_SWAPPED) ?
+ "-hp-swapped" : "");
byt_rt5651_card.long_name = byt_rt5651_long_name;
+#endif
/* override plaform name, if required */
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 33eb72545be6..70bb86f3342f 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -12,6 +12,7 @@
*/
#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -324,9 +325,8 @@ static const struct snd_soc_ops cht_be_ssp2_ops = {
};
static struct snd_soc_aux_dev cht_max98090_headset_dev = {
- .name = "Headset Chip",
+ .dlc = COMP_AUX("i2c-104C227E:00"),
.init = cht_max98090_headset_init,
- .codec_name = "i2c-104C227E:00",
};
SND_SOC_DAILINK_DEF(dummy,
@@ -400,6 +400,20 @@ static struct snd_soc_card snd_soc_card_cht = {
static const struct dmi_system_id cht_max98090_quirk_table[] = {
{
+ /* Banjo model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Banjo"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Candy model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Candy"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
/* Clapper model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Clapper"),
@@ -407,6 +421,27 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = {
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
+ /* Cyan model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Enguarde model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Enguarde"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Glimmer model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Glimmer"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
/* Gnawty model Chromebook (Acer Chromebook CB3-111) */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Gnawty"),
@@ -414,12 +449,75 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = {
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
+ /* Heli model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Heli"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Kip model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Kip"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Ninja model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Ninja"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Orco model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Orco"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Quawks model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Quawks"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Rambi model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Rambi"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Squawks model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Squawks"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
+ /* Sumo model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Sumo"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
+ {
/* Swanky model Chromebook (Toshiba Chromebook 2) */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
+ {
+ /* Winky model Chromebook */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Winky"),
+ },
+ .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
+ },
{}
};
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 8879c3be29d5..b5b016d493f1 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -48,6 +48,7 @@ struct cht_mc_private {
#define CHT_RT5645_SSP2_AIF2 BIT(16) /* default is using AIF1 */
#define CHT_RT5645_SSP0_AIF1 BIT(17)
#define CHT_RT5645_SSP0_AIF2 BIT(18)
+#define CHT_RT5645_PMC_PLT_CLK_0 BIT(19)
static unsigned long cht_rt5645_quirk = 0;
@@ -59,6 +60,8 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk SSP0_AIF1 enabled");
if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)
dev_info(dev, "quirk SSP0_AIF2 enabled");
+ if (cht_rt5645_quirk & CHT_RT5645_PMC_PLT_CLK_0)
+ dev_info(dev, "quirk PMC_PLT_CLK_0 enabled");
}
static int platform_clock_control(struct snd_soc_dapm_widget *w,
@@ -226,16 +229,22 @@ static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-/* uncomment when we have a real quirk
static int cht_rt5645_quirk_cb(const struct dmi_system_id *id)
{
cht_rt5645_quirk = (unsigned long)id->driver_data;
return 1;
}
-*/
static const struct dmi_system_id cht_rt5645_quirk_table[] = {
{
+ /* Strago family Chromebooks */
+ .callback = cht_rt5645_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"),
+ },
+ .driver_data = (void *)CHT_RT5645_PMC_PLT_CLK_0,
+ },
+ {
},
};
@@ -506,8 +515,6 @@ static struct cht_acpi_card snd_soc_cards[] = {
};
static char cht_rt5645_codec_name[SND_ACPI_I2C_ID_LEN];
-static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */
-static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
u64 aif_value; /* 1: AIF1, 2: AIF2 */
@@ -526,6 +533,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
int dai_index = 0;
int ret_val = 0;
int i;
+ const char *mclk_name;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
@@ -631,28 +639,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
log_quirks(&pdev->dev);
if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
- (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
-
- /* fixup codec aif name */
- snprintf(cht_rt5645_codec_aif_name,
- sizeof(cht_rt5645_codec_aif_name),
- "%s", "rt5645-aif2");
-
- cht_dailink[dai_index].codecs->dai_name =
- cht_rt5645_codec_aif_name;
- }
+ (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2))
+ cht_dailink[dai_index].codecs->dai_name = "rt5645-aif2";
if ((cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) ||
- (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
-
- /* fixup cpu dai name name */
- snprintf(cht_rt5645_cpu_dai_name,
- sizeof(cht_rt5645_cpu_dai_name),
- "%s", "ssp0-port");
-
- cht_dailink[dai_index].cpus->dai_name =
- cht_rt5645_cpu_dai_name;
- }
+ (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2))
+ cht_dailink[dai_index].cpus->dai_name = "ssp0-port";
/* override plaform name, if required */
platform_name = mach->mach_params.platform;
@@ -662,11 +654,15 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
if (ret_val)
return ret_val;
- drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+ if (cht_rt5645_quirk & CHT_RT5645_PMC_PLT_CLK_0)
+ mclk_name = "pmc_plt_clk_0";
+ else
+ mclk_name = "pmc_plt_clk_3";
+
+ drv->mclk = devm_clk_get(&pdev->dev, mclk_name);
if (IS_ERR(drv->mclk)) {
- dev_err(&pdev->dev,
- "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
- PTR_ERR(drv->mclk));
+ dev_err(&pdev->dev, "Failed to get MCLK from %s: %ld\n",
+ mclk_name, PTR_ERR(drv->mclk));
return PTR_ERR(drv->mclk);
}
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 4977b5a65eb8..9d657421730a 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -8,6 +8,7 @@
* Mengdong Lin <mengdong.lin@intel.com>
*/
+#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c
new file mode 100644
index 000000000000..dd80d0186a6c
--- /dev/null
+++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2019 Intel Corporation.
+
+/*
+ * Intel Cometlake I2S Machine driver for RT1011 + RT5682 codec
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/rt5682.h>
+#include <sound/soc-acpi.h>
+#include "../../codecs/rt1011.h"
+#include "../../codecs/rt5682.h"
+#include "../../codecs/hdac_hdmi.h"
+#include "hda_dsp_common.h"
+
+/* The platform clock outputs 24Mhz clock to codec as I2S MCLK */
+#define CML_PLAT_CLK 24000000
+#define CML_RT1011_CODEC_DAI "rt1011-aif"
+#define CML_RT5682_CODEC_DAI "rt5682-aif1"
+#define NAME_SIZE 32
+
+static struct snd_soc_jack hdmi_jack[3];
+
+struct hdmi_pcm {
+ struct list_head head;
+ struct snd_soc_dai *codec_dai;
+ int device;
+};
+
+struct card_private {
+ char codec_name[SND_ACPI_I2C_ID_LEN];
+ struct snd_soc_jack headset;
+ struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
+};
+
+static const struct snd_kcontrol_new cml_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
+ SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
+ SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
+ SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
+};
+
+static const struct snd_soc_dapm_widget cml_rt1011_rt5682_widgets[] = {
+ SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
+ SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
+ SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
+ SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_route cml_rt1011_rt5682_map[] = {
+ /*speaker*/
+ {"TL Ext Spk", NULL, "TL SPO"},
+ {"TR Ext Spk", NULL, "TR SPO"},
+ {"WL Ext Spk", NULL, "WL SPO"},
+ {"WR Ext Spk", NULL, "WR SPO"},
+
+ /* HP jack connectors - unknown if we have jack detection */
+ { "Headphone Jack", NULL, "HPOL" },
+ { "Headphone Jack", NULL, "HPOR" },
+
+ /* other jacks */
+ { "IN1P", NULL, "Headset Mic" },
+
+ /* DMIC */
+ {"DMic", NULL, "SoC DMIC"},
+};
+
+static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *component = rtd->codec_dai->component;
+ struct snd_soc_jack *jack;
+ int ret;
+
+ /* need to enable ASRC function for 24MHz mclk rate */
+ rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER |
+ RT5682_AD_STEREO1_FILTER,
+ RT5682_CLK_SEL_I2S1_ASRC);
+
+ /*
+ * Headset buttons map to the google Reference headset.
+ * These can be configured by userspace.
+ */
+ 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->headset, NULL, 0);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+ return ret;
+ }
+
+ jack = &ctx->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->dev, "Headset Jack call-back failed: %d\n", ret);
+
+ return ret;
+};
+
+static int cml_rt5682_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int clk_id, clk_freq, pll_out, ret;
+
+ clk_id = RT5682_PLL1_S_MCLK;
+ clk_freq = CML_PLAT_CLK;
+
+ pll_out = params_rate(params) * 512;
+
+ ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
+ if (ret < 0)
+ dev_warn(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
+
+ /* Configure sysclk for codec */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
+ pll_out, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_warn(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
+
+ /*
+ * slot_width should be equal or large than data length, set them
+ * be the same
+ */
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2,
+ params_width(params));
+ if (ret < 0)
+ dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
+ return ret;
+}
+
+static int cml_rt1011_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai;
+ struct snd_soc_card *card = rtd->card;
+ int srate, i, ret = 0;
+
+ srate = params_rate(params);
+
+ for (i = 0; i < rtd->num_codecs; i++) {
+ codec_dai = rtd->codec_dais[i];
+
+ /* 100 Fs to drive 24 bit data */
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK,
+ 100 * srate, 256 * srate);
+ if (ret < 0) {
+ dev_err(card->dev, "codec_dai clock not set\n");
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ RT1011_FS_SYS_PRE_S_PLL1,
+ 256 * srate, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(card->dev, "codec_dai clock not set\n");
+ return ret;
+ }
+
+ /*
+ * Codec TDM is configured as 24 bit capture/ playback.
+ * 2 CH PB is done over 4 codecs - 2 Woofers and 2 Tweeters.
+ * The Left woofer and tweeter plays the Left playback data
+ * and similar by the Right.
+ * Hence 2 codecs (1 T and 1 W pair) share same Rx slot.
+ * The feedback is captured for each codec individually.
+ * Hence all 4 codecs use 1 Tx slot each for feedback.
+ */
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1011:00")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ 0x4, 0x1, 4, 24);
+ if (ret < 0)
+ break;
+ }
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1011:02")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ 0x1, 0x1, 4, 24);
+ if (ret < 0)
+ break;
+ }
+ /* TDM Rx slot 2 is used for Right Woofer & Tweeters pair */
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1011:01")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ 0x8, 0x2, 4, 24);
+ if (ret < 0)
+ break;
+ }
+ if (!strcmp(codec_dai->component->name, "i2c-10EC1011:03")) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai,
+ 0x2, 0x2, 4, 24);
+ if (ret < 0)
+ break;
+ }
+ }
+ if (ret < 0)
+ dev_err(rtd->dev,
+ "set codec TDM slot for %s failed with error %d\n",
+ codec_dai->component->name, ret);
+ return ret;
+}
+
+static struct snd_soc_ops cml_rt5682_ops = {
+ .hw_params = cml_rt5682_hw_params,
+};
+
+static const struct snd_soc_ops cml_rt1011_ops = {
+ .hw_params = cml_rt1011_hw_params,
+};
+
+static int sof_card_late_probe(struct snd_soc_card *card)
+{
+ struct card_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_component *component = NULL;
+ char jack_name[NAME_SIZE];
+ struct hdmi_pcm *pcm;
+ int ret, i = 0;
+
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ 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);
+ ret = snd_soc_card_jack_new(card, jack_name,
+ SND_JACK_AVOUT, &hdmi_jack[i],
+ NULL, 0);
+ if (ret)
+ return ret;
+
+ ret = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+ &hdmi_jack[i]);
+ if (ret < 0)
+ return ret;
+
+ i++;
+ }
+
+ return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+
+static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct card_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;
+
+ pcm->device = dai->id;
+ pcm->codec_dai = dai;
+
+ list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+ return 0;
+}
+
+/* Cometlake digital audio interface glue - connects codec <--> CPU */
+
+SND_SOC_DAILINK_DEF(ssp0_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin")));
+SND_SOC_DAILINK_DEF(ssp0_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00",
+ CML_RT5682_CODEC_DAI)));
+
+SND_SOC_DAILINK_DEF(ssp1_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
+SND_SOC_DAILINK_DEF(ssp1_codec,
+ DAILINK_COMP_ARRAY(
+ /* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
+ /* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI),
+ /* TL */ COMP_CODEC("i2c-10EC1011:02", CML_RT1011_CODEC_DAI),
+ /* TR */ COMP_CODEC("i2c-10EC1011:03", CML_RT1011_CODEC_DAI)));
+
+SND_SOC_DAILINK_DEF(dmic_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
+
+SND_SOC_DAILINK_DEF(dmic16k_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
+
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(idisp1_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
+SND_SOC_DAILINK_DEF(idisp1_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
+
+SND_SOC_DAILINK_DEF(idisp2_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
+SND_SOC_DAILINK_DEF(idisp2_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2")));
+
+SND_SOC_DAILINK_DEF(idisp3_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
+SND_SOC_DAILINK_DEF(idisp3_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3")));
+
+static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = {
+ /* Back End DAI links */
+ {
+ /* SSP0 - Codec */
+ .name = "SSP0-Codec",
+ .id = 0,
+ .init = cml_rt5682_codec_init,
+ .ignore_pmdown_time = 1,
+ .ops = &cml_rt5682_ops,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform),
+ },
+ {
+ .name = "dmic01",
+ .id = 1,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
+ },
+ {
+ .name = "dmic16k",
+ .id = 2,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform),
+ },
+ {
+ .name = "iDisp1",
+ .id = 3,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
+ },
+ {
+ .name = "iDisp2",
+ .id = 4,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
+ },
+ {
+ .name = "iDisp3",
+ .id = 5,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
+ },
+ {
+ /*
+ * SSP1 - Codec : added to end of list ensuring
+ * reuse of common topologies for other end points
+ * and changing only SSP1's codec
+ */
+ .name = "SSP1-Codec",
+ .id = 6,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1, /* Capture stream provides Feedback */
+ .no_pcm = 1,
+ .ops = &cml_rt1011_ops,
+ SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
+ },
+};
+
+static struct snd_soc_codec_conf rt1011_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:00"),
+ .name_prefix = "WL",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:01"),
+ .name_prefix = "WR",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:02"),
+ .name_prefix = "TL",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:03"),
+ .name_prefix = "TR",
+ },
+};
+
+/* Cometlake audio machine driver for RT1011 and RT5682 */
+static struct snd_soc_card snd_soc_card_cml = {
+ .name = "cml_rt1011_rt5682",
+ .dai_link = cml_rt1011_rt5682_dailink,
+ .num_links = ARRAY_SIZE(cml_rt1011_rt5682_dailink),
+ .codec_conf = rt1011_conf,
+ .num_configs = ARRAY_SIZE(rt1011_conf),
+ .dapm_widgets = cml_rt1011_rt5682_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cml_rt1011_rt5682_widgets),
+ .dapm_routes = cml_rt1011_rt5682_map,
+ .num_dapm_routes = ARRAY_SIZE(cml_rt1011_rt5682_map),
+ .controls = cml_controls,
+ .num_controls = ARRAY_SIZE(cml_controls),
+ .fully_routed = true,
+ .late_probe = sof_card_late_probe,
+};
+
+static int snd_cml_rt1011_probe(struct platform_device *pdev)
+{
+ struct card_private *ctx;
+ struct snd_soc_acpi_mach *mach;
+ const char *platform_name;
+ int ret;
+
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
+ if (!ctx)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+ mach = (&pdev->dev)->platform_data;
+ snd_soc_card_cml.dev = &pdev->dev;
+ platform_name = mach->mach_params.platform;
+
+ /* set platform name for each dailink */
+ ret = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cml,
+ platform_name);
+ if (ret)
+ return ret;
+
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
+ snd_soc_card_set_drvdata(&snd_soc_card_cml, ctx);
+
+ return devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cml);
+}
+
+static struct platform_driver snd_cml_rt1011_rt5682_driver = {
+ .probe = snd_cml_rt1011_probe,
+ .driver = {
+ .name = "cml_rt1011_rt5682",
+ .pm = &snd_soc_pm_ops,
+ },
+};
+module_platform_driver(snd_cml_rt1011_rt5682_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("Cometlake Audio Machine driver - RT1011 and RT5682 in I2S mode");
+MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
+MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
+MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cml_rt1011_rt5682");
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
index bd2d371f2acd..8e947bad143c 100644
--- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
+++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
@@ -19,6 +19,7 @@
#include <sound/soc-acpi.h>
#include "../../codecs/rt5682.h"
#include "../../codecs/hdac_hdmi.h"
+#include "hda_dsp_common.h"
/* The platform clock outputs 19.2Mhz clock to codec as I2S MCLK */
#define GLK_PLAT_CLK_FREQ 19200000
@@ -41,6 +42,7 @@ struct glk_hdmi_pcm {
struct glk_card_private {
struct snd_soc_jack geminilake_headset;
struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
};
enum {
@@ -116,13 +118,13 @@ static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = DUAL_CHANNEL;
+ chan->min = chan->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
@@ -247,16 +249,6 @@ static const struct snd_pcm_hw_constraint_list constraints_rates = {
.mask = 0,
};
-static const unsigned int channels[] = {
- DUAL_CHANNEL,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_channels = {
- .count = ARRAY_SIZE(channels),
- .list = channels,
- .mask = 0,
-};
-
static unsigned int channels_quad[] = {
QUAD_CHANNEL,
};
@@ -270,13 +262,13 @@ static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
static int geminilake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
/*
* set BE channel constraint as user FE channels
*/
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
@@ -542,9 +534,19 @@ static int glk_card_late_probe(struct snd_soc_card *card)
struct snd_soc_component *component = NULL;
char jack_name[NAME_SIZE];
struct glk_hdmi_pcm *pcm;
- int err = 0;
+ int err;
int i = 0;
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct glk_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ 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),
@@ -564,9 +566,6 @@ static int glk_card_late_probe(struct snd_soc_card *card)
i++;
}
- if (!component)
- return -EINVAL;
-
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
@@ -612,6 +611,8 @@ static int geminilake_audio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
return devm_snd_soc_register_card(&pdev->dev, card);
}
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 4d3822cff98c..3dadf9bff796 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -188,18 +188,14 @@ static struct snd_soc_card haswell_rt5640 = {
static int haswell_audio_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach;
- const char *platform_name = NULL;
int ret;
haswell_rt5640.dev = &pdev->dev;
/* override plaform name, if required */
mach = (&pdev->dev)->platform_data;
- if (mach) /* extra check since legacy does not pass parameters */
- platform_name = mach->mach_params.platform;
-
ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640,
- platform_name);
+ mach->mach_params.platform);
if (ret)
return ret;
diff --git a/sound/soc/intel/boards/hda_dsp_common.c b/sound/soc/intel/boards/hda_dsp_common.c
new file mode 100644
index 000000000000..9179f07f9ee4
--- /dev/null
+++ b/sound/soc/intel/boards/hda_dsp_common.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright(c) 2019 Intel Corporation. All rights reserved.
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/hda_codec.h>
+#include <sound/hda_i915.h>
+#include "../../codecs/hdac_hda.h"
+
+#include "hda_dsp_common.h"
+
+/*
+ * Search card topology and return PCM device number
+ * matching Nth HDMI device (zero-based index).
+ */
+struct snd_pcm *hda_dsp_hdmi_pcm_handle(struct snd_soc_card *card,
+ int hdmi_idx)
+{
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_pcm *spcm;
+ int i = 0;
+
+ for_each_card_rtds(card, rtd) {
+ spcm = rtd->pcm ?
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].pcm : NULL;
+ if (spcm && strstr(spcm->id, "HDMI")) {
+ if (i == hdmi_idx)
+ return rtd->pcm;
+ ++i;
+ }
+ }
+
+ return NULL;
+}
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
+/*
+ * Search card topology and register HDMI PCM related controls
+ * to codec driver.
+ */
+int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
+ struct snd_soc_component *comp)
+{
+ struct hdac_hda_priv *hda_pvt;
+ struct hda_codec *hcodec;
+ struct snd_pcm *spcm;
+ struct hda_pcm *hpcm;
+ int err = 0, i = 0;
+
+ if (!comp)
+ return -EINVAL;
+
+ hda_pvt = snd_soc_component_get_drvdata(comp);
+ hcodec = &hda_pvt->codec;
+
+ list_for_each_entry(hpcm, &hcodec->pcm_list_head, list) {
+ spcm = hda_dsp_hdmi_pcm_handle(card, i);
+ if (spcm) {
+ hpcm->pcm = spcm;
+ hpcm->device = spcm->device;
+ dev_dbg(card->dev,
+ "%s: mapping HDMI converter %d to PCM %d (%p)\n",
+ __func__, i, hpcm->device, spcm);
+ } else {
+ hpcm->pcm = NULL;
+ hpcm->device = SNDRV_PCM_INVALID_DEVICE;
+ dev_warn(card->dev,
+ "%s: no PCM in topology for HDMI converter %d\n\n",
+ __func__, i);
+ }
+ i++;
+ }
+ snd_hdac_display_power(hcodec->core.bus,
+ HDA_CODEC_IDX_CONTROLLER, true);
+ err = snd_hda_codec_build_controls(hcodec);
+ if (err < 0)
+ dev_err(card->dev, "unable to create controls %d\n", err);
+ snd_hdac_display_power(hcodec->core.bus,
+ HDA_CODEC_IDX_CONTROLLER, false);
+
+ return err;
+}
+
+#endif
diff --git a/sound/soc/intel/boards/hda_dsp_common.h b/sound/soc/intel/boards/hda_dsp_common.h
new file mode 100644
index 000000000000..431f7f09dccb
--- /dev/null
+++ b/sound/soc/intel/boards/hda_dsp_common.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+/*
+ * This file defines helper functions used by multiple
+ * Intel HDA based machine drivers.
+ */
+
+#ifndef __HDA_DSP_COMMON_H
+#define __HDA_DSP_COMMON_H
+
+#include <sound/hda_codec.h>
+#include <sound/hda_i915.h>
+#include "../../codecs/hdac_hda.h"
+
+struct snd_pcm *hda_dsp_hdmi_pcm_handle(struct snd_soc_card *card,
+ int hdmi_idx);
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
+int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
+ struct snd_soc_component *comp);
+#else
+static inline int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
+ struct snd_soc_component *comp)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif /* __HDA_DSP_COMMON_H */
diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
index 537a88932bb6..bc7f9a9ce9af 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
@@ -141,13 +141,13 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = DUAL_CHANNEL;
+ chan->min = chan->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
@@ -305,7 +305,7 @@ static const struct snd_soc_ops kabylake_da7219_fe_ops = {
static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
/*
@@ -313,9 +313,9 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
*/
if (params_channels(params) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
@@ -336,19 +336,6 @@ static struct snd_soc_ops kabylake_dmic_ops = {
.startup = kabylake_dmic_startup,
};
-static const unsigned int rates_16000[] = {
- 16000,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_16000 = {
- .count = ARRAY_SIZE(rates_16000),
- .list = rates_16000,
-};
-
-static const unsigned int ch_mono[] = {
- 1,
-};
-
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
index 829f95fc4179..7a13e9b35187 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
@@ -176,7 +176,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *runtime = substream->private_data;
- int ret = 0, j;
+ int ret, j;
for (j = 0; j < runtime->num_codecs; j++) {
struct snd_soc_dai *codec_dai = runtime->codec_dais[j];
@@ -279,7 +279,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
struct snd_soc_dpcm *dpcm = container_of(
@@ -298,7 +298,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
!strcmp(rtd->card->name, "kblmax98373")) {
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = DUAL_CHANNEL;
+ chan->min = chan->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
@@ -313,7 +313,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
!strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
!strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
snd_mask_none(fmt);
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
}
@@ -341,6 +341,9 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
kabylake_ssp1_map,
ARRAY_SIZE(kabylake_ssp1_map));
+ if (ret)
+ return ret;
+
/*
* Headset buttons map to the google Reference headset.
* These can be configured by userspace.
@@ -491,7 +494,7 @@ static const struct snd_soc_ops kabylake_da7219_fe_ops = {
static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
/*
@@ -499,9 +502,9 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
*/
if (params_channels(params) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
@@ -571,12 +574,12 @@ static struct snd_soc_ops skylake_refcap_ops = {
static struct snd_soc_codec_conf max98927_codec_conf[] = {
{
- .dev_name = MAX98927_DEV0_NAME,
+ .dlc = COMP_CODEC_CONF(MAX98927_DEV0_NAME),
.name_prefix = "Right",
},
{
- .dev_name = MAX98927_DEV1_NAME,
+ .dlc = COMP_CODEC_CONF(MAX98927_DEV1_NAME),
.name_prefix = "Left",
},
};
@@ -584,12 +587,12 @@ static struct snd_soc_codec_conf max98927_codec_conf[] = {
static struct snd_soc_codec_conf max98373_codec_conf[] = {
{
- .dev_name = MAX98373_DEV0_NAME,
+ .dlc = COMP_CODEC_CONF(MAX98373_DEV0_NAME),
.name_prefix = "Right",
},
{
- .dev_name = MAX98373_DEV1_NAME,
+ .dlc = COMP_CODEC_CONF(MAX98373_DEV1_NAME),
.name_prefix = "Left",
},
};
@@ -1092,7 +1095,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
struct kbl_codec_private *ctx;
struct snd_soc_dai_link *kbl_dai_link;
struct snd_soc_dai_link_component **codecs;
- int i = 0;
+ int i;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
index 74fe1f3a5479..e23dea9ab79a 100644
--- a/sound/soc/intel/boards/kbl_rt5660.c
+++ b/sound/soc/intel/boards/kbl_rt5660.c
@@ -138,13 +138,13 @@ static int kabylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = DUAL_CHANNEL;
+ chan->min = chan->max = DUAL_CHANNEL;
/* set SSP0 to 24 bit */
snd_mask_none(fmt);
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index 7cefda341fbf..d8f2ff7139a9 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -229,11 +229,11 @@ static const struct snd_soc_dapm_route kabylake_5663_map[] = {
static struct snd_soc_codec_conf max98927_codec_conf[] = {
{
- .dev_name = MAXIM_DEV0_NAME,
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME),
.name_prefix = "Right",
},
{
- .dev_name = MAXIM_DEV1_NAME,
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME),
.name_prefix = "Left",
},
};
@@ -398,7 +398,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
struct snd_soc_dpcm *dpcm = container_of(
@@ -413,7 +413,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
!strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
!strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
snd_mask_none(fmt);
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
}
@@ -454,13 +454,13 @@ static struct snd_soc_ops kabylake_rt5663_ops = {
static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 74dda8784f1a..96c814f36458 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -22,6 +22,9 @@
#include "../../codecs/rt5514.h"
#include "../../codecs/rt5663.h"
#include "../../codecs/hdac_hdmi.h"
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
#define KBL_REALTEK_DMIC_CODEC_DAI "rt5514-aif1"
@@ -50,6 +53,8 @@ struct kbl_codec_private {
struct snd_soc_jack kabylake_headset;
struct list_head hdmi_pcm_list;
struct snd_soc_jack kabylake_hdmi[2];
+ struct clk *mclk;
+ struct clk *sclk;
};
enum {
@@ -71,6 +76,61 @@ static const struct snd_kcontrol_new kabylake_controls[] = {
SOC_DAPM_PIN_SWITCH("DMIC"),
};
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct kbl_codec_private *priv = snd_soc_card_get_drvdata(card);
+ int ret = 0;
+
+ /*
+ * MCLK/SCLK need to be ON early for a successful synchronization of
+ * codec internal clock. And the clocks are turned off during
+ * POST_PMD after the stream is stopped.
+ */
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable MCLK */
+ ret = clk_set_rate(priv->mclk, 24000000);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't set rate for mclk, err: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->mclk);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't enable mclk, err: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable SCLK */
+ ret = clk_set_rate(priv->sclk, 3072000);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't set rate for sclk, err: %d\n",
+ ret);
+ clk_disable_unprepare(priv->mclk);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->sclk);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't enable sclk, err: %d\n", ret);
+ clk_disable_unprepare(priv->mclk);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ clk_disable_unprepare(priv->mclk);
+ clk_disable_unprepare(priv->sclk);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -79,11 +139,15 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_MIC("DMIC", NULL),
SND_SOC_DAPM_SPK("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI2", NULL),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route kabylake_map[] = {
/* Headphones */
+ { "Headphone Jack", NULL, "Platform Clock" },
{ "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" },
@@ -92,6 +156,7 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{ "Right Spk", NULL, "Right BE_OUT" },
/* other jacks */
+ { "Headset Mic", NULL, "Platform Clock" },
{ "IN1P", NULL, "Headset Mic" },
{ "IN1N", NULL, "Headset Mic" },
@@ -128,11 +193,11 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
static struct snd_soc_codec_conf max98927_codec_conf[] = {
{
- .dev_name = MAXIM_DEV0_NAME,
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME),
.name_prefix = "Right",
},
{
- .dev_name = MAXIM_DEV1_NAME,
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME),
.name_prefix = "Left",
},
};
@@ -268,7 +333,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
struct snd_soc_dpcm *dpcm = container_of(
@@ -283,15 +348,15 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
!strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
!strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
snd_mask_none(fmt);
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
} else if (!strcmp(fe_dai_link->name, "Kbl Audio DMIC cap")) {
if (params_channels(params) == 2 ||
DMIC_CH(dmic_constraints) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
}
/*
* The speaker on the SSP0 supports S16_LE and not S24_LE.
@@ -400,6 +465,9 @@ static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
dmic_constraints);
+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+ snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
+
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
}
@@ -588,6 +656,55 @@ static struct snd_soc_dai_link kabylake_dais[] = {
},
};
+static int kabylake_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
+{
+ struct snd_soc_component *component = dapm->component;
+ struct kbl_codec_private *priv = snd_soc_card_get_drvdata(card);
+ int ret = 0;
+
+ if (!component || strcmp(component->name, RT5514_DEV_NAME))
+ return 0;
+
+ if (IS_ERR(priv->mclk))
+ return 0;
+
+ /*
+ * It's required to control mclk directly in the set_bias_level
+ * function for rt5514 codec or the recording function could
+ * break.
+ */
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (dapm->bias_level == SND_SOC_BIAS_ON) {
+ dev_dbg(card->dev, "Disable mclk");
+ clk_disable_unprepare(priv->mclk);
+ } else {
+ dev_dbg(card->dev, "Enable mclk");
+ ret = clk_set_rate(priv->mclk, 24000000);
+ if (ret) {
+ dev_err(card->dev, "Can't set rate for mclk, err: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->mclk);
+ if (ret) {
+ dev_err(card->dev, "Can't enable mclk, err: %d\n",
+ ret);
+
+ /* mclk is already enabled in FW */
+ ret = 0;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static int kabylake_card_late_probe(struct snd_soc_card *card)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
@@ -623,10 +740,11 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
* kabylake audio machine driver for MAX98927 + RT5514 + RT5663
*/
static struct snd_soc_card kabylake_audio_card = {
- .name = "kbl_r5514_5663_max",
+ .name = "kbl-r5514-5663-max",
.owner = THIS_MODULE,
.dai_link = kabylake_dais,
.num_links = ARRAY_SIZE(kabylake_dais),
+ .set_bias_level = kabylake_set_bias_level,
.controls = kabylake_controls,
.num_controls = ARRAY_SIZE(kabylake_controls),
.dapm_widgets = kabylake_widgets,
@@ -643,6 +761,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
{
struct kbl_codec_private *ctx;
struct snd_soc_acpi_mach *mach;
+ int ret;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -658,6 +777,34 @@ static int kabylake_audio_probe(struct platform_device *pdev)
dmic_constraints = mach->mach_params.dmic_num == 2 ?
&constraints_dmic_2ch : &constraints_dmic_channels;
+ ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk");
+ if (IS_ERR(ctx->mclk)) {
+ ret = PTR_ERR(ctx->mclk);
+ if (ret == -ENOENT) {
+ dev_info(&pdev->dev,
+ "Failed to get ssp1_mclk, defer probe\n");
+ return -EPROBE_DEFER;
+ }
+
+ dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n",
+ ret);
+ return ret;
+ }
+
+ ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk");
+ if (IS_ERR(ctx->sclk)) {
+ ret = PTR_ERR(ctx->sclk);
+ if (ret == -ENOENT) {
+ dev_info(&pdev->dev,
+ "Failed to get ssp1_sclk, defer probe\n");
+ return -EPROBE_DEFER;
+ }
+
+ dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n",
+ ret);
+ return ret;
+ }
+
return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card);
}
diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c b/sound/soc/intel/boards/skl_hda_dsp_common.c
index 55fd82e05e2c..78ff5f24c40e 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_common.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
@@ -14,6 +14,9 @@
#include "../../codecs/hdac_hdmi.h"
#include "skl_hda_dsp_common.h"
+#include <sound/hda_codec.h>
+#include "../../codecs/hdac_hda.h"
+
#define NAME_SIZE 32
int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device)
@@ -38,16 +41,19 @@ int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device)
return 0;
}
-SND_SOC_DAILINK_DEFS(idisp1,
- DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")),
+SND_SOC_DAILINK_DEF(idisp1_cpu,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
+SND_SOC_DAILINK_DEF(idisp1_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
-SND_SOC_DAILINK_DEFS(idisp2,
- DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")),
+SND_SOC_DAILINK_DEF(idisp2_cpu,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
+SND_SOC_DAILINK_DEF(idisp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2")));
-SND_SOC_DAILINK_DEFS(idisp3,
- DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")),
+SND_SOC_DAILINK_DEF(idisp3_cpu,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
+SND_SOC_DAILINK_DEF(idisp3_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
SND_SOC_DAILINK_DEF(analog_cpu,
@@ -80,21 +86,21 @@ struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS] = {
.id = 1,
.dpcm_playback = 1,
.no_pcm = 1,
- SND_SOC_DAILINK_REG(idisp1),
+ SND_SOC_DAILINK_REG(idisp1_cpu, idisp1_codec, platform),
},
{
.name = "iDisp2",
.id = 2,
.dpcm_playback = 1,
.no_pcm = 1,
- SND_SOC_DAILINK_REG(idisp2),
+ SND_SOC_DAILINK_REG(idisp2_cpu, idisp2_codec, platform),
},
{
.name = "iDisp3",
.id = 3,
.dpcm_playback = 1,
.no_pcm = 1,
- SND_SOC_DAILINK_REG(idisp3),
+ SND_SOC_DAILINK_REG(idisp3_cpu, idisp3_codec, platform),
},
{
.name = "Analog Playback and Capture",
@@ -136,6 +142,9 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
char jack_name[NAME_SIZE];
int err;
+ if (ctx->common_hdmi_codec_drv)
+ return skl_hda_hdmi_build_controls(card);
+
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
@@ -147,6 +156,11 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
if (err)
return err;
+ err = snd_jack_add_new_kctl(pcm->hdmi_jack.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,
&pcm->hdmi_jack);
if (err < 0)
diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.h b/sound/soc/intel/boards/skl_hda_dsp_common.h
index daa582e513b2..d6150670ca05 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_common.h
+++ b/sound/soc/intel/boards/skl_hda_dsp_common.h
@@ -8,12 +8,15 @@
* platforms with HDA Codecs.
*/
-#ifndef __SOUND_SOC_HDA_DSP_COMMON_H
-#define __SOUND_SOC_HDA_DSP_COMMON_H
+#ifndef __SKL_HDA_DSP_COMMON_H
+#define __SKL_HDA_DSP_COMMON_H
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
+#include <sound/hda_codec.h>
+#include "../../codecs/hdac_hda.h"
+#include "hda_dsp_common.h"
#define HDA_DSP_MAX_BE_DAI_LINKS 7
@@ -29,10 +32,30 @@ struct skl_hda_private {
int pcm_count;
int dai_index;
const char *platform_name;
+ bool common_hdmi_codec_drv;
};
extern struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS];
int skl_hda_hdmi_jack_init(struct snd_soc_card *card);
int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device);
+/*
+ * Search card topology and register HDMI PCM related controls
+ * to codec driver.
+ */
+static inline int skl_hda_hdmi_build_controls(struct snd_soc_card *card)
+{
+ struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_component *component;
+ struct skl_hda_hdmi_pcm *pcm;
+
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ if (!component)
+ return -EINVAL;
+
+ return hda_dsp_hdmi_build_controls(card, component);
+}
+
#endif /* __SOUND_SOC_HDA_DSP_COMMON_H */
diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c
index 9ed68eb4f058..11eaee9ae41f 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_generic.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c
@@ -23,6 +23,7 @@ static const struct snd_soc_dapm_widget skl_hda_widgets[] = {
SND_SOC_DAPM_MIC("Alt Analog In", NULL),
SND_SOC_DAPM_SPK("Digital Out", NULL),
SND_SOC_DAPM_MIC("Digital In", NULL),
+ SND_SOC_DAPM_MIC("SoC DMIC", NULL),
};
static const struct snd_soc_dapm_route skl_hda_map[] = {
@@ -41,6 +42,9 @@ static const struct snd_soc_dapm_route skl_hda_map[] = {
{ "Codec Input Pin2", NULL, "Digital In" },
{ "Codec Input Pin3", NULL, "Alt Analog In" },
+ /* digital mics */
+ {"DMic", NULL, "SoC DMIC"},
+
/* CODEC BE connections */
{ "Analog Codec Playback", NULL, "Analog CPU Playback" },
{ "Analog CPU Playback", NULL, "codec0_out" },
@@ -86,7 +90,7 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
}
static struct snd_soc_card hda_soc_card = {
- .name = "skl_hda_card",
+ .name = "hda-dsp",
.owner = THIS_MODULE,
.dai_link = skl_hda_be_dai_links,
.dapm_widgets = skl_hda_widgets,
@@ -96,6 +100,8 @@ static struct snd_soc_card hda_soc_card = {
.late_probe = skl_hda_card_late_probe,
};
+static char hda_soc_components[30];
+
#define IDISP_DAI_COUNT 3
#define HDAC_DAI_COUNT 2
#define DMIC_DAI_COUNT 2
@@ -174,10 +180,17 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
ctx->pcm_count = hda_soc_card.num_links;
ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */
ctx->platform_name = mach->mach_params.platform;
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
hda_soc_card.dev = &pdev->dev;
snd_soc_card_set_drvdata(&hda_soc_card, ctx);
+ if (mach->mach_params.dmic_num > 0) {
+ snprintf(hda_soc_components, sizeof(hda_soc_components),
+ "cfg-dmics:%d", mach->mach_params.dmic_num);
+ hda_soc_card.components = hda_soc_components;
+ }
+
return devm_snd_soc_register_card(&pdev->dev, &hda_soc_card);
}
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index 3ce8efbeed12..e6de3b28d840 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -139,13 +139,13 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
/* set SSP0 to 24 bit */
snd_mask_none(fmt);
@@ -315,13 +315,13 @@ static const struct snd_soc_ops skylake_nau8825_ops = {
static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 1a7ac8bdf543..c99c8b23e509 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -147,11 +147,11 @@ static const struct snd_soc_dapm_route skylake_map[] = {
static struct snd_soc_codec_conf ssm4567_codec_conf[] = {
{
- .dev_name = "i2c-INT343B:00",
+ .dlc = COMP_CODEC_CONF("i2c-INT343B:00"),
.name_prefix = "Left",
},
{
- .dev_name = "i2c-INT343B:01",
+ .dlc = COMP_CODEC_CONF("i2c-INT343B:01"),
.name_prefix = "Right",
},
};
@@ -317,13 +317,13 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
/* set SSP0 to 24 bit */
snd_mask_none(fmt);
@@ -334,12 +334,12 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 231349a47cc9..a9aec66a2351 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -211,13 +211,13 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The output is 48KHz, stereo, 16bits */
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
/* set SSP0 to 24 bit */
snd_mask_none(fmt);
@@ -247,12 +247,12 @@ static const struct snd_soc_ops skylake_rt286_ops = {
static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *channels = hw_param_interval(params,
+ struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
if (params_channels(params) == 2)
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
else
- channels->min = channels->max = 4;
+ chan->min = chan->max = 4;
return 0;
}
diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219_max98373.c
new file mode 100644
index 000000000000..8f44f13d2848
--- /dev/null
+++ b/sound/soc/intel/boards/sof_da7219_max98373.c
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2019 Intel Corporation.
+
+/*
+ * Intel SOF Machine driver for DA7219 + MAX98373 codec
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/platform_device.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include "../../codecs/da7219.h"
+#include "../../codecs/da7219-aad.h"
+#include "hda_dsp_common.h"
+
+#define DIALOG_CODEC_DAI "da7219-hifi"
+#define MAX98373_CODEC_DAI "max98373-aif1"
+#define MAXIM_DEV0_NAME "i2c-MX98373:00"
+#define MAXIM_DEV1_NAME "i2c-MX98373:01"
+
+struct hdmi_pcm {
+ struct list_head head;
+ struct snd_soc_dai *codec_dai;
+ int device;
+};
+
+struct card_private {
+ struct snd_soc_jack headset;
+ struct list_head hdmi_pcm_list;
+ struct snd_soc_jack hdmi[3];
+};
+
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct snd_soc_dai *codec_dai;
+ int ret = 0;
+
+ codec_dai = snd_soc_card_get_codec_dai(card, DIALOG_CODEC_DAI);
+ if (!codec_dai) {
+ dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
+ return -EIO;
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK,
+ 0, 0);
+ if (ret)
+ dev_err(card->dev, "failed to stop PLL: %d\n", ret);
+ } else if (SND_SOC_DAPM_EVENT_ON(event)) {
+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
+ 0, DA7219_PLL_FREQ_OUT_98304);
+ if (ret)
+ dev_err(card->dev, "failed to start PLL: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static const struct snd_kcontrol_new controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control, SND_SOC_DAPM_POST_PMD |
+ SND_SOC_DAPM_PRE_PMU),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ { "Headphone Jack", NULL, "HPL" },
+ { "Headphone Jack", NULL, "HPR" },
+
+ { "Left Spk", NULL, "Left BE_OUT" },
+ { "Right Spk", NULL, "Right BE_OUT" },
+
+ { "MIC", NULL, "Headset Mic" },
+
+ { "Headphone Jack", NULL, "Platform Clock" },
+ { "Headset Mic", NULL, "Platform Clock" },
+};
+
+static struct snd_soc_jack headset;
+
+static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = rtd->codec_dai->component;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_jack *jack;
+ int ret;
+
+ /* Configure sysclk for codec */
+ ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24000000,
+ SND_SOC_CLOCK_IN);
+ if (ret) {
+ dev_err(rtd->dev, "can't set codec sysclk configuration\n");
+ return ret;
+ }
+
+ /*
+ * Headset buttons map to the google Reference headset.
+ * These can be configured by userspace.
+ */
+ 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 | SND_JACK_LINEOUT,
+ &headset, NULL, 0);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+ return ret;
+ }
+
+ jack = &headset;
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+ da7219_aad_jack_det(component, jack);
+
+ return ret;
+}
+
+static int ssp1_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *runtime = substream->private_data;
+ int ret, j;
+
+ for (j = 0; j < runtime->num_codecs; j++) {
+ struct snd_soc_dai *codec_dai = runtime->codec_dais[j];
+
+ if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) {
+ /* vmon_slot_no = 0 imon_slot_no = 1 for TX slots */
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 3, 4, 16);
+ if (ret < 0) {
+ dev_err(runtime->dev, "DEV0 TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+ if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) {
+ /* vmon_slot_no = 2 imon_slot_no = 3 for TX slots */
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC, 3, 4, 16);
+ if (ret < 0) {
+ dev_err(runtime->dev, "DEV1 TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops ssp1_ops = {
+ .hw_params = ssp1_hw_params,
+};
+
+static struct snd_soc_codec_conf max98373_codec_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME),
+ .name_prefix = "Right",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME),
+ .name_prefix = "Left",
+ },
+};
+
+static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct card_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;
+
+ pcm->device = dai->id;
+ pcm->codec_dai = dai;
+
+ list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+ return 0;
+}
+
+static int card_late_probe(struct snd_soc_card *card)
+{
+ struct card_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_acpi_mach *mach = (card->dev)->platform_data;
+ struct hdmi_pcm *pcm;
+
+ if (mach->mach_params.common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
+ head);
+ return hda_dsp_hdmi_build_controls(card,
+ pcm->codec_dai->component);
+ }
+
+ return -EINVAL;
+}
+
+SND_SOC_DAILINK_DEF(ssp0_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin")));
+SND_SOC_DAILINK_DEF(ssp0_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", DIALOG_CODEC_DAI)));
+
+SND_SOC_DAILINK_DEF(ssp1_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
+SND_SOC_DAILINK_DEF(ssp1_amps,
+ DAILINK_COMP_ARRAY(
+ /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, MAX98373_CODEC_DAI),
+ /* Right */ COMP_CODEC(MAXIM_DEV1_NAME, MAX98373_CODEC_DAI)));
+
+SND_SOC_DAILINK_DEF(dmic_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(idisp1_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
+SND_SOC_DAILINK_DEF(idisp1_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
+
+SND_SOC_DAILINK_DEF(idisp2_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
+SND_SOC_DAILINK_DEF(idisp2_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2")));
+
+SND_SOC_DAILINK_DEF(idisp3_pin,
+ DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
+SND_SOC_DAILINK_DEF(idisp3_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3")));
+
+SND_SOC_DAILINK_DEF(platform, /* subject to be overridden during probe */
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3")));
+
+static struct snd_soc_dai_link dais[] = {
+ /* Back End DAI links */
+ {
+ .name = "SSP1-Codec",
+ .id = 0,
+ .ignore_pmdown_time = 1,
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1, /* IV feedback */
+ .ops = &ssp1_ops,
+ SND_SOC_DAILINK_REG(ssp1_pin, ssp1_amps, platform),
+ },
+ {
+ .name = "SSP0-Codec",
+ .id = 1,
+ .no_pcm = 1,
+ .init = da7219_codec_init,
+ .ignore_pmdown_time = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform),
+ },
+ {
+ .name = "dmic01",
+ .id = 2,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
+ },
+ {
+ .name = "iDisp1",
+ .id = 3,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
+ },
+ {
+ .name = "iDisp2",
+ .id = 4,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
+ },
+ {
+ .name = "iDisp3",
+ .id = 5,
+ .init = hdmi_init,
+ .dpcm_playback = 1,
+ .no_pcm = 1,
+ SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
+ },
+};
+
+static struct snd_soc_card card_da7219_m98373 = {
+ .name = "da7219max",
+ .owner = THIS_MODULE,
+ .dai_link = dais,
+ .num_links = ARRAY_SIZE(dais),
+ .controls = controls,
+ .num_controls = ARRAY_SIZE(controls),
+ .dapm_widgets = widgets,
+ .num_dapm_widgets = ARRAY_SIZE(widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+ .codec_conf = max98373_codec_conf,
+ .num_configs = ARRAY_SIZE(max98373_codec_conf),
+ .fully_routed = true,
+ .late_probe = card_late_probe,
+};
+
+static int audio_probe(struct platform_device *pdev)
+{
+ static struct snd_soc_card *card;
+ struct snd_soc_acpi_mach *mach;
+ struct card_private *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
+ if (!ctx)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+ card = (struct snd_soc_card *)pdev->id_entry->driver_data;
+ card->dev = &pdev->dev;
+
+ mach = (&pdev->dev)->platform_data;
+ ret = snd_soc_fixup_dai_links_platform_name(card,
+ mach->mach_params.platform);
+ if (ret)
+ return ret;
+
+ snd_soc_card_set_drvdata(card, ctx);
+
+ return devm_snd_soc_register_card(&pdev->dev, card);
+}
+
+static const struct platform_device_id board_ids[] = {
+ {
+ .name = "sof_da7219_max98373",
+ .driver_data = (kernel_ulong_t)&card_da7219_m98373,
+ },
+ { }
+};
+
+static struct platform_driver audio = {
+ .probe = audio_probe,
+ .driver = {
+ .name = "sof_da7219_max98373",
+ .pm = &snd_soc_pm_ops,
+ },
+ .id_table = board_ids,
+};
+module_platform_driver(audio)
+
+/* Module information */
+MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver");
+MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sof_da7219_max98373");
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index daeaa396d928..5d878873a8e0 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -21,6 +21,7 @@
#include "../../codecs/rt5682.h"
#include "../../codecs/hdac_hdmi.h"
#include "../common/soc-intel-quirks.h"
+#include "hda_dsp_common.h"
#define NAME_SIZE 32
@@ -34,6 +35,10 @@
#define SOF_RT5682_SSP_AMP(quirk) \
(((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK)
#define SOF_RT5682_MCLK_BYTCHT_EN BIT(9)
+#define SOF_RT5682_NUM_HDMIDEV_SHIFT 10
+#define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10))
+#define SOF_RT5682_NUM_HDMIDEV(quirk) \
+ ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
/* Default: MCLK on, MCLK 19.2M, SSP0 */
static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
@@ -53,6 +58,7 @@ struct sof_card_private {
struct clk *mclk;
struct snd_soc_jack sof_headset;
struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
};
static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
@@ -91,8 +97,7 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
{
.callback = sof_rt5682_quirk_cb,
.matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Google"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Hatch"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
},
.driver_data = (void *)(SOF_RT5682_MCLK_EN |
SOF_RT5682_MCLK_24MHZ |
@@ -268,13 +273,23 @@ static int sof_card_late_probe(struct snd_soc_card *card)
struct snd_soc_component *component = NULL;
char jack_name[NAME_SIZE];
struct sof_hdmi_pcm *pcm;
- int err = 0;
+ int err;
int i = 0;
/* HDMI is not supported by SOF on Baytrail/CherryTrail */
if (is_legacy_cpu)
return 0;
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ 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),
@@ -293,8 +308,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
i++;
}
- if (!component)
- return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
@@ -311,6 +324,10 @@ static const struct snd_soc_dapm_widget sof_widgets[] = {
SND_SOC_DAPM_SPK("Spk", NULL),
};
+static const struct snd_soc_dapm_widget dmic_widgets[] = {
+ SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+};
+
static const struct snd_soc_dapm_route sof_map[] = {
/* HP jack connectors - unknown if we have jack detection */
{ "Headphone Jack", NULL, "HPOL" },
@@ -318,7 +335,6 @@ static const struct snd_soc_dapm_route sof_map[] = {
/* other jacks */
{ "IN1P", NULL, "Headset Mic" },
-
};
static const struct snd_soc_dapm_route speaker_map[] = {
@@ -326,6 +342,11 @@ static const struct snd_soc_dapm_route speaker_map[] = {
{ "Spk", NULL, "Speaker" },
};
+static const struct snd_soc_dapm_route dmic_map[] = {
+ /* digital mics */
+ {"DMic", NULL, "SoC DMIC"},
+};
+
static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
@@ -339,9 +360,31 @@ static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
+static int 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;
+}
+
/* sof audio machine driver for rt5682 codec */
static struct snd_soc_card sof_audio_card_rt5682 = {
- .name = "sof_rt5682",
+ .name = "rt5682", /* the sof- prefix is added by the core */
.owner = THIS_MODULE,
.controls = sof_controls,
.num_controls = ARRAY_SIZE(sof_controls),
@@ -442,6 +485,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].name = "dmic01";
links[id].cpus = &cpus[id];
links[id].cpus->dai_name = "DMIC01 Pin";
+ links[id].init = dmic_init;
if (dmic_be_num > 1) {
/* set up 2 BE links at most */
links[id + 1].name = "dmic16k";
@@ -555,6 +599,19 @@ static int sof_audio_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
+ if (pdev->id_entry && pdev->id_entry->driver_data)
+ sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
+
+ dmi_check_system(sof_rt5682_quirk_table);
+
+ mach = (&pdev->dev)->platform_data;
+
+ /* A speaker amp might not be present when the quirk claims one is.
+ * Detect this via whether the machine driver match includes quirk_data.
+ */
+ if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data)
+ sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT;
+
if (soc_intel_is_byt() || soc_intel_is_cht()) {
is_legacy_cpu = 1;
dmic_be_num = 0;
@@ -565,14 +622,25 @@ static int sof_audio_probe(struct platform_device *pdev)
SOF_RT5682_SSP_CODEC(2);
} else {
dmic_be_num = 2;
- hdmi_num = 3;
+ hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
+ SOF_RT5682_NUM_HDMIDEV_SHIFT;
+ /* default number of HDMI DAI's */
+ if (!hdmi_num)
+ hdmi_num = 3;
}
- dmi_check_system(sof_rt5682_quirk_table);
-
/* need to get main clock from pmc */
if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+ if (IS_ERR(ctx->mclk)) {
+ ret = PTR_ERR(ctx->mclk);
+
+ dev_err(&pdev->dev,
+ "Failed to get MCLK from pmc_plt_clk_3: %d\n",
+ ret);
+ return ret;
+ }
+
ret = clk_prepare_enable(ctx->mclk);
if (ret < 0) {
dev_err(&pdev->dev,
@@ -604,7 +672,6 @@ static int sof_audio_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
sof_audio_card_rt5682.dev = &pdev->dev;
- mach = (&pdev->dev)->platform_data;
/* set platform name for each dailink */
ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
@@ -612,18 +679,52 @@ static int sof_audio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
return devm_snd_soc_register_card(&pdev->dev,
&sof_audio_card_rt5682);
}
+static int sof_rt5682_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct snd_soc_component *component = NULL;
+
+ for_each_card_components(card, component) {
+ if (!strcmp(component->name, rt5682_component[0].name)) {
+ snd_soc_component_set_jack(component, NULL, NULL);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id board_ids[] = {
+ {
+ .name = "sof_rt5682",
+ },
+ {
+ .name = "tgl_max98357a_rt5682",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_RT5682_SSP_AMP(1) |
+ SOF_RT5682_NUM_HDMIDEV(4)),
+ },
+ { }
+};
+
static struct platform_driver sof_audio = {
.probe = sof_audio_probe,
+ .remove = sof_rt5682_remove,
.driver = {
.name = "sof_rt5682",
.pm = &snd_soc_pm_ops,
},
+ .id_table = board_ids,
};
module_platform_driver(sof_audio)
@@ -633,3 +734,4 @@ MODULE_AUTHOR("Bard Liao <bard.liao@intel.com>");
MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:sof_rt5682");
+MODULE_ALIAS("platform:tgl_max98357a_rt5682");
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index 56c81e20b5bf..bd352878f89a 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -7,7 +7,10 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
soc-acpi-intel-hsw-bdw-match.o \
soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \
soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \
- soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \
+ soc-acpi-intel-cnl-match.o soc-acpi-intel-cfl-match.o \
+ soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \
+ soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \
+ soc-acpi-intel-jsl-match.o \
soc-acpi-intel-hda-match.o
obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-cfl-match.c b/sound/soc/intel/common/soc-acpi-intel-cfl-match.c
new file mode 100644
index 000000000000..ff9d6938b9f6
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-cfl-match.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * soc-apci-intel-cfl-match.c - tables and support for CFL ACPI enumeration.
+ *
+ * Copyright (c) 2019, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_machines[] = {
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cfl_machines);
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[] = {
+ {}
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cfl_sdw_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
new file mode 100644
index 000000000000..f55634c4c2e8
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * soc-acpi-intel-cml-match.c - tables and support for CML ACPI enumeration.
+ *
+ * Copyright (c) 2019, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+static struct snd_soc_acpi_codecs rt1011_spk_codecs = {
+ .num_codecs = 1,
+ .codecs = {"10EC1011"}
+};
+
+static struct snd_soc_acpi_codecs max98357a_spk_codecs = {
+ .num_codecs = 1,
+ .codecs = {"MX98357A"}
+};
+
+/*
+ * The order of the three entries with .id = "10EC5682" matters
+ * here, because DSDT tables expose an ACPI HID for the MAX98357A
+ * speaker amplifier which is not populated on the board.
+ */
+struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = {
+ {
+ .id = "10EC5682",
+ .drv_name = "cml_rt1011_rt5682",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &rt1011_spk_codecs,
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg",
+ },
+ {
+ .id = "10EC5682",
+ .drv_name = "sof_rt5682",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &max98357a_spk_codecs,
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg",
+ },
+ {
+ .id = "10EC5682",
+ .drv_name = "sof_rt5682",
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-rt5682.tplg",
+ },
+ {
+ .id = "DLGS7219",
+ .drv_name = "cml_da7219_max98357a",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &max98357a_spk_codecs,
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines);
+
+static const u64 rt711_0_adr[] = {
+ 0x000010025D071100
+};
+
+static const u64 rt1308_1_adr[] = {
+ 0x000110025D130800
+};
+
+static const u64 rt1308_2_adr[] = {
+ 0x000210025D130800
+};
+
+static const u64 rt715_3_adr[] = {
+ 0x000310025D071500
+};
+
+static const struct snd_soc_acpi_link_adr cml_3_in_1_default[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1308_1_adr),
+ .adr = rt1308_1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1308_2_adr),
+ .adr = rt1308_2_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt715_3_adr),
+ .adr = rt715_3_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr cml_3_in_1_mono_amp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1308_1_adr),
+ .adr = rt1308_1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt715_3_adr),
+ .adr = rt715_3_adr,
+ },
+ {}
+};
+
+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",
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-rt711-rt1308-rt715.tplg",
+ },
+ {
+ /*
+ * link_mask should be 0xB, but all links are enabled by BIOS.
+ * This entry will be selected if there is no rt1308 exposed
+ * on link2 since it will fail to match the above entry.
+ */
+ .link_mask = 0xF,
+ .links = cml_3_in_1_mono_amp,
+ .drv_name = "sdw_rt711_rt1308_rt715",
+ .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",
+ .sof_fw_filename = "sof-cml.ri",
+ .sof_tplg_filename = "sof-cml-rt700.tplg",
+ },
+ {}
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_sdw_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
index 771b0ef21051..828980d5630d 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
@@ -14,11 +14,6 @@ static struct skl_machine_pdata cnl_pdata = {
.use_tplg_pcm = true,
};
-static struct snd_soc_acpi_codecs cml_codecs = {
- .num_codecs = 1,
- .codecs = {"10EC5682"}
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = {
{
.id = "INT34C2",
@@ -28,23 +23,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = {
.sof_fw_filename = "sof-cnl.ri",
.sof_tplg_filename = "sof-cnl-rt274.tplg",
},
- {
- .id = "MX98357A",
- .drv_name = "sof_rt5682",
- .quirk_data = &cml_codecs,
- .sof_fw_filename = "sof-cnl.ri",
- .sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg",
- },
- {
- .id = "10EC5682",
- .drv_name = "sof_rt5682",
- .sof_fw_filename = "sof-cnl.ri",
- .sof_tplg_filename = "sof-cml-rt5682.tplg",
- },
-
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_machines);
+struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[] = {
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines);
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
new file mode 100644
index 000000000000..a1290c3fa99f
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * soc-apci-intel-ehl-match.c - tables and support for EHL ACPI enumeration.
+ *
+ * Copyright (c) 2019, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = {
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c
index 34eb0baaa951..35958553652e 100644
--- a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c
@@ -30,6 +30,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = {
.sof_tplg_filename = "sof-bdw-rt286.tplg",
},
{
+ .id = "10EC5650",
+ .drv_name = "bdw-rt5650",
+ .fw_filename = "intel/IntcSST2.bin",
+ .sof_fw_filename = "sof-bdw.ri",
+ .sof_tplg_filename = "sof-bdw-rt5650.tplg",
+ },
+ {
.id = "RT5677CE",
.drv_name = "bdw-rt5677",
.fw_filename = "intel/IntcSST2.bin",
diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
index 38977669b576..752733013d54 100644
--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
@@ -33,5 +33,103 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);
+static const u64 rt700_0_adr[] = {
+ 0x000010025D070000
+};
+
+static const struct snd_soc_acpi_link_adr icl_rvp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt700_0_adr),
+ .adr = rt700_0_adr,
+ },
+ {}
+};
+
+static const u64 rt711_0_adr[] = {
+ 0x000010025D071100
+};
+
+static const u64 rt1308_1_adr[] = {
+ 0x000110025D130800
+};
+
+static const u64 rt1308_2_adr[] = {
+ 0x000210025D130800
+};
+
+static const u64 rt715_3_adr[] = {
+ 0x000310025D071500
+};
+
+static const struct snd_soc_acpi_link_adr icl_3_in_1_default[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1308_1_adr),
+ .adr = rt1308_1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1308_2_adr),
+ .adr = rt1308_2_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt715_3_adr),
+ .adr = rt715_3_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr icl_3_in_1_mono_amp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1308_1_adr),
+ .adr = rt1308_1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt715_3_adr),
+ .adr = rt715_3_adr,
+ },
+ {}
+};
+
+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",
+ .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",
+ .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",
+ .sof_fw_filename = "sof-icl.ri",
+ .sof_tplg_filename = "sof-icl-rt700.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_sdw_machines);
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
new file mode 100644
index 000000000000..ed2b125f6a11
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * soc-apci-intel-jsl-match.c - tables and support for JSL ACPI enumeration.
+ *
+ * Copyright (c) 2019, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
+ {
+ .id = "DLGS7219",
+ .drv_name = "sof_da7219_max98373",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .sof_fw_filename = "sof-jsl.ri",
+ .sof_tplg_filename = "sof-jsl-da7219.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
new file mode 100644
index 000000000000..5984dd151f3e
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * soc-apci-intel-tgl-match.c - tables and support for ICL ACPI enumeration.
+ *
+ * Copyright (c) 2019, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+
+static struct snd_soc_acpi_codecs tgl_codecs = {
+ .num_codecs = 1,
+ .codecs = {"MX98357A"}
+};
+
+static const u64 rt711_0_adr[] = {
+ 0x000010025D071100
+};
+
+static const u64 rt1308_1_adr[] = {
+ 0x000120025D130800,
+ 0x000122025D130800
+};
+
+static const struct snd_soc_acpi_link_adr tgl_i2s_rt1308[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr tgl_rvp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_0_adr),
+ .adr = rt711_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1308_1_adr),
+ .adr = rt1308_1_adr,
+ },
+ {}
+};
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
+ {
+ .id = "10EC1308",
+ .drv_name = "rt711_rt1308",
+ .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",
+ },
+ {
+ .id = "10EC5682",
+ .drv_name = "tgl_max98357a_rt5682",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &tgl_codecs,
+ .sof_fw_filename = "sof-tgl.ri",
+ .sof_tplg_filename = "sof-tgl-max98357a-rt5682.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines);
+
+/* this table is used when there is no I2S codec present */
+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",
+ .sof_fw_filename = "sof-tgl.ri",
+ .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h
index 4718fd3cf636..863a477d3405 100644
--- a/sound/soc/intel/common/soc-intel-quirks.h
+++ b/sound/soc/intel/common/soc-intel-quirks.h
@@ -36,6 +36,7 @@ SOC_INTEL_IS_CPU(byt, INTEL_FAM6_ATOM_SILVERMONT);
SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT);
SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT);
SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS);
+SOC_INTEL_IS_CPU(cml, INTEL_FAM6_KABYLAKE_L);
static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
{
@@ -110,6 +111,10 @@ static inline bool soc_intel_is_glk(void)
return false;
}
+static inline bool soc_intel_is_cml(void)
+{
+ return false;
+}
#endif
#endif /* _SND_SOC_INTEL_QUIRKS_H */
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 0e8e0a7a11df..5854868650b9 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -141,11 +141,12 @@ static int sst_acpi_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, sst_acpi);
+ mach->pdata = sst_pdata;
/* register machine driver */
sst_acpi->pdev_mach =
platform_device_register_data(dev, mach->drv_name, -1,
- sst_pdata, sizeof(*sst_pdata));
+ mach, sizeof(*mach));
if (IS_ERR(sst_acpi->pdev_mach))
return PTR_ERR(sst_acpi->pdev_mach);
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
index ef5b66af1cd2..6068bb697e22 100644
--- a/sound/soc/intel/common/sst-ipc.c
+++ b/sound/soc/intel/common/sst-ipc.c
@@ -43,7 +43,7 @@ static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
}
static int tx_wait_done(struct sst_generic_ipc *ipc,
- struct ipc_message *msg, void *rx_data)
+ struct ipc_message *msg, struct sst_ipc_message *reply)
{
unsigned long flags;
int ret;
@@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
} else {
/* copy the data returned from DSP */
- if (rx_data)
- memcpy(rx_data, msg->rx_data, msg->rx_size);
+ if (reply) {
+ reply->header = msg->rx.header;
+ if (reply->data)
+ memcpy(reply->data, msg->rx.data, msg->rx.size);
+ }
ret = msg->errno;
}
@@ -72,9 +75,9 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
return ret;
}
-static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes, void *rx_data,
- size_t rx_bytes, int wait)
+static int ipc_tx_message(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request,
+ struct sst_ipc_message *reply, int wait)
{
struct ipc_message *msg;
unsigned long flags;
@@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
return -EBUSY;
}
- msg->header = header;
- msg->tx_size = tx_bytes;
- msg->rx_size = rx_bytes;
+ msg->tx.header = request.header;
+ msg->tx.size = request.size;
+ msg->rx.header = 0;
+ msg->rx.size = reply ? reply->size : 0;
msg->wait = wait;
msg->errno = 0;
msg->pending = false;
msg->complete = false;
- if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL))
- ipc->ops.tx_data_copy(msg, tx_data, tx_bytes);
+ if ((request.size) && (ipc->ops.tx_data_copy != NULL))
+ ipc->ops.tx_data_copy(msg, request.data, request.size);
list_add_tail(&msg->list, &ipc->tx_list);
schedule_work(&ipc->kwork);
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
if (wait)
- return tx_wait_done(ipc, msg, rx_data);
+ return tx_wait_done(ipc, msg, reply);
else
return 0;
}
@@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
return -ENOMEM;
for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
- ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
- if (ipc->msg[i].tx_data == NULL)
+ ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
+ if (ipc->msg[i].tx.data == NULL)
goto free_mem;
- ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
- if (ipc->msg[i].rx_data == NULL) {
- kfree(ipc->msg[i].tx_data);
+ ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
+ if (ipc->msg[i].rx.data == NULL) {
+ kfree(ipc->msg[i].tx.data);
goto free_mem;
}
@@ -136,8 +140,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
free_mem:
while (i > 0) {
- kfree(ipc->msg[i-1].tx_data);
- kfree(ipc->msg[i-1].rx_data);
+ kfree(ipc->msg[i-1].tx.data);
+ kfree(ipc->msg[i-1].rx.data);
--i;
}
kfree(ipc->msg);
@@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work)
spin_unlock_irq(&ipc->dsp->spinlock);
}
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
+int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request, struct sst_ipc_message *reply)
{
int ret;
@@ -187,8 +191,7 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
if (ipc->ops.check_dsp_lp_on(ipc->dsp, true))
return -EIO;
- ret = ipc_tx_message(ipc, header, tx_data, tx_bytes,
- rx_data, rx_bytes, 1);
+ ret = ipc_tx_message(ipc, request, reply, 1);
if (ipc->ops.check_dsp_lp_on)
if (ipc->ops.check_dsp_lp_on(ipc->dsp, false))
@@ -198,19 +201,17 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
}
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes)
+int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request)
{
- return ipc_tx_message(ipc, header, tx_data, tx_bytes,
- NULL, 0, 0);
+ return ipc_tx_message(ipc, request, NULL, 0);
}
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
+int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request, struct sst_ipc_message *reply)
{
- return ipc_tx_message(ipc, header, tx_data, tx_bytes,
- rx_data, rx_bytes, 1);
+ return ipc_tx_message(ipc, request, reply, 1);
}
EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm);
@@ -222,6 +223,8 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
if (ipc->ops.reply_msg_match != NULL)
header = ipc->ops.reply_msg_match(header, &mask);
+ else
+ mask = (u64)-1;
if (list_empty(&ipc->rx_list)) {
dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n",
@@ -230,7 +233,7 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
}
list_for_each_entry(msg, &ipc->rx_list, list) {
- if ((msg->header & mask) == header)
+ if ((msg->tx.header & mask) == header)
return msg;
}
@@ -304,8 +307,8 @@ void sst_ipc_fini(struct sst_generic_ipc *ipc)
if (ipc->msg) {
for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
- kfree(ipc->msg[i].tx_data);
- kfree(ipc->msg[i].rx_data);
+ kfree(ipc->msg[i].tx.data);
+ kfree(ipc->msg[i].rx.data);
}
kfree(ipc->msg);
}
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
index c6779e2ac830..08c4831b2664 100644
--- a/sound/soc/intel/common/sst-ipc.h
+++ b/sound/soc/intel/common/sst-ipc.h
@@ -17,15 +17,16 @@
#define IPC_MAX_MAILBOX_BYTES 256
-struct ipc_message {
- struct list_head list;
+struct sst_ipc_message {
u64 header;
+ void *data;
+ size_t size;
+};
- /* direction wrt host CPU */
- char *tx_data;
- size_t tx_size;
- char *rx_data;
- size_t rx_size;
+struct ipc_message {
+ struct list_head list;
+ struct sst_ipc_message tx;
+ struct sst_ipc_message rx;
wait_queue_head_t waitq;
bool pending;
@@ -35,6 +36,7 @@ struct ipc_message {
};
struct sst_generic_ipc;
+struct sst_dsp;
struct sst_plat_ipc_ops {
void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
@@ -65,14 +67,14 @@ struct sst_generic_ipc {
struct sst_plat_ipc_ops ops;
};
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
+int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request, struct sst_ipc_message *reply);
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes);
+int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request);
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header,
- void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
+int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
+ struct sst_ipc_message request, struct sst_ipc_message *reply);
struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
u64 header);
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index a83b92d6bea8..0ff89ea96ccf 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work)
static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
{
struct sst_hsw_stream *stream;
- u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
+ u32 header = msg->tx.header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
u32 stream_id = msg_get_stream_id(header);
u32 stream_msg = msg_get_stream_type(header);
@@ -552,6 +552,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
return -EIO;
}
+ msg->rx.header = header;
/* first process the header */
switch (reply) {
case IPC_GLB_REPLY_PENDING:
@@ -562,13 +563,13 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
case IPC_GLB_REPLY_SUCCESS:
if (msg->pending) {
trace_ipc_pending_reply("completed", header);
- sst_dsp_inbox_read(hsw->dsp, msg->rx_data,
- msg->rx_size);
+ sst_dsp_inbox_read(hsw->dsp, msg->rx.data,
+ msg->rx.size);
hsw->ipc.pending = false;
} else {
/* copy data from the DSP */
- sst_dsp_outbox_read(hsw->dsp, msg->rx_data,
- msg->rx_size);
+ sst_dsp_outbox_read(hsw->dsp, msg->rx.data,
+ msg->rx.size);
}
break;
/* these will be rare - but useful for debug */
@@ -810,11 +811,13 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
int sst_hsw_fw_get_version(struct sst_hsw *hsw,
struct sst_hsw_ipc_fw_version *version)
{
+ struct sst_ipc_message request = {0}, reply = {0};
int ret;
- ret = sst_ipc_tx_message_wait(&hsw->ipc,
- IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION),
- NULL, 0, version, sizeof(*version));
+ request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION);
+ reply.data = version;
+ reply.size = sizeof(*version);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
if (ret < 0)
dev_err(hsw->dev, "error: get version failed\n");
@@ -840,7 +843,7 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
{
struct sst_hsw_ipc_volume_req *req;
- u32 header;
+ struct sst_ipc_message request;
int ret;
trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
@@ -848,11 +851,11 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
return -EINVAL;
- header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
+ request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
- header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
- header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
- header |= (stage_id << IPC_STG_ID_SHIFT);
+ request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
+ request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
+ request.header |= (stage_id << IPC_STG_ID_SHIFT);
req = &stream->vol_req;
req->target_volume = volume;
@@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
req->channel = channel;
}
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req,
- sizeof(*req), NULL, 0);
+ request.data = req;
+ request.size = sizeof(*req);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) {
dev_err(hsw->dev, "error: set stream volume failed\n");
return ret;
@@ -905,7 +909,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
u32 volume)
{
struct sst_hsw_ipc_volume_req req;
- u32 header;
+ struct sst_ipc_message request;
int ret;
trace_ipc_request("set mixer volume", volume);
@@ -933,18 +937,19 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
req.channel = channel;
}
- header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
+ request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
- header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
- header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
- header |= (stage_id << IPC_STG_ID_SHIFT);
+ request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
+ request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
+ request.header |= (stage_id << IPC_STG_ID_SHIFT);
req.curve_duration = hsw->curve_duration;
req.curve_type = hsw->curve_type;
req.target_volume = volume;
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req,
- sizeof(req), NULL, 0);
+ request.data = &req;
+ request.size = sizeof(req);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) {
dev_err(hsw->dev, "error: set mixer volume failed\n");
return ret;
@@ -983,7 +988,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{
- u32 header;
+ struct sst_ipc_message request;
int ret = 0;
struct sst_dsp *sst = hsw->dsp;
unsigned long flags;
@@ -1000,10 +1005,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_ipc_request("stream free", stream->host_id);
stream->free_req.stream_id = stream->reply.stream_hw_id;
- header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
+ request.header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
+ request.data = &stream->free_req;
+ request.size = sizeof(stream->free_req);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req,
- sizeof(stream->free_req), NULL, 0);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0) {
dev_err(hsw->dev, "error: free stream %d failed\n",
stream->free_req.stream_id);
@@ -1175,9 +1181,7 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw,
int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{
- struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request;
- struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply;
- u32 header;
+ struct sst_ipc_message request, reply = {0};
int ret;
if (!stream) {
@@ -1192,10 +1196,13 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_ipc_request("stream alloc", stream->host_id);
- header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
+ request.header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
+ request.data = &stream->request;
+ request.size = sizeof(stream->request);
+ reply.data = &stream->reply;
+ reply.size = sizeof(stream->reply);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req,
- sizeof(*str_req), reply, sizeof(*reply));
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
if (ret < 0) {
dev_err(hsw->dev, "error: stream commit failed\n");
return ret;
@@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw,
ABI to be opaque to client PCM drivers to cope with any future ABI changes */
int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
{
- struct sst_hsw_ipc_stream_info_reply *reply;
- u32 header;
+ struct sst_ipc_message request = {0}, reply = {0};
int ret;
- reply = &hsw->mixer_info;
- header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
+ request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
+ reply.data = &hsw->mixer_info;
+ reply.size = sizeof(hsw->mixer_info);
trace_ipc_request("get global mixer info", 0);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0,
- reply, sizeof(*reply));
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
if (ret < 0) {
dev_err(hsw->dev, "error: get stream info failed\n");
return ret;
}
- trace_hsw_mixer_info_reply(reply);
+ trace_hsw_mixer_info_reply(&hsw->mixer_info);
return 0;
}
@@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
int stream_id, int wait)
{
- u32 header;
+ struct sst_ipc_message request = {0};
- header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type);
- header |= (stream_id << IPC_STR_ID_SHIFT);
+ request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE);
+ request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT);
if (wait)
- return sst_ipc_tx_message_wait(&hsw->ipc, header,
- NULL, 0, NULL, 0);
+ return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
else
- return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0);
+ return sst_ipc_tx_message_nowait(&hsw->ipc, request);
}
/* Stream ALSA trigger operations */
@@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
enum sst_hsw_device_mode mode, u32 clock_divider)
{
+ struct sst_ipc_message request;
struct sst_hsw_ipc_device_config_req config;
- u32 header;
int ret;
trace_ipc_request("set device config", dev);
@@ -1394,10 +1399,11 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
trace_hsw_device_config_req(&config);
- header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
+ request.header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
+ request.data = &config;
+ request.size = sizeof(config);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config,
- sizeof(config), NULL, 0);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0)
dev_err(hsw->dev, "error: set device formats failed\n");
@@ -1409,16 +1415,20 @@ EXPORT_SYMBOL_GPL(sst_hsw_device_set_config);
int sst_hsw_dx_set_state(struct sst_hsw *hsw,
enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
{
- u32 header, state_;
+ struct sst_ipc_message request, reply = {0};
+ u32 state_;
int ret, item;
- header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
state_ = state;
+ request.header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
+ request.data = &state_;
+ request.size = sizeof(state_);
+ reply.data = dx;
+ reply.size = sizeof(*dx);
trace_ipc_request("PM enter Dx state", state);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_,
- sizeof(state_), dx, sizeof(*dx));
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
if (ret < 0) {
dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
return ret;
@@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
u32 module_id, u32 instance_id)
{
int ret;
- u32 header = 0;
+ struct sst_ipc_message request;
struct sst_hsw_ipc_module_config config;
struct sst_module *module;
struct sst_module_runtime *runtime;
@@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
return -ENXIO;
}
- header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+ request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
IPC_MODULE_ID(module_id);
- dev_dbg(dev, "module enable header: %x\n", header);
+ dev_dbg(dev, "module enable header: %x\n", (u32)request.header);
config.map.module_entries_count = 1;
config.map.module_entries[0].module_id = module->id;
@@ -1932,8 +1942,9 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
config.scratch_mem.size, config.scratch_mem.offset,
config.map.module_entries[0].entry_point);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
- &config, sizeof(config), NULL, 0);
+ request.data = &config;
+ request.size = sizeof(config);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0)
dev_err(dev, "ipc: module enable failed - %d\n", ret);
else
@@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
u32 module_id, u32 instance_id)
{
int ret;
- u32 header;
+ struct sst_ipc_message request = {0};
struct sst_module *module;
struct device *dev = hsw->dev;
struct sst_dsp *dsp = hsw->dsp;
@@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
return -ENXIO;
}
- header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+ request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
IPC_MODULE_ID(module_id);
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0)
dev_err(dev, "module disable failed - %d\n", ret);
else
@@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
u32 param_size, char *param)
{
int ret;
- u32 header = 0;
- u32 payload_size = 0, transfer_parameter_size = 0;
+ struct sst_ipc_message request = {0};
+ u32 payload_size = 0;
struct sst_hsw_transfer_parameter *parameter;
struct device *dev = hsw->dev;
- header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+ request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
IPC_MODULE_ID(module_id);
- dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header);
+ dev_dbg(dev, "sst_hsw_module_set_param header=%x\n",
+ (u32)request.header);
payload_size = param_size +
sizeof(struct sst_hsw_transfer_parameter) -
@@ -2003,14 +2015,14 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
/* short parameter, mailbox can contain data */
- dev_dbg(dev, "transfer parameter size : %d\n",
- transfer_parameter_size);
+ dev_dbg(dev, "transfer parameter size : %zu\n",
+ request.size);
- transfer_parameter_size = ALIGN(payload_size, 4);
- dev_dbg(dev, "transfer parameter aligned size : %d\n",
- transfer_parameter_size);
+ request.size = ALIGN(payload_size, 4);
+ dev_dbg(dev, "transfer parameter aligned size : %zu\n",
+ request.size);
- parameter = kzalloc(transfer_parameter_size, GFP_KERNEL);
+ parameter = kzalloc(request.size, GFP_KERNEL);
if (parameter == NULL)
return -ENOMEM;
@@ -2022,9 +2034,9 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
parameter->parameter_id = parameter_id;
parameter->data_size = param_size;
+ request.data = parameter;
- ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
- parameter, transfer_parameter_size , NULL, 0);
+ ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
if (ret < 0)
dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
@@ -2041,8 +2053,8 @@ static struct sst_dsp_device hsw_dev = {
static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{
/* send the message */
- sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
- sst_dsp_ipc_msg_tx(ipc->dsp, msg->header);
+ sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
+ sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header);
}
static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
@@ -2063,7 +2075,7 @@ static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size)
{
- memcpy(msg->tx_data, tx_data, tx_size);
+ memcpy(msg->tx.data, tx_data, tx_size);
}
static u64 hsw_reply_msg_match(u64 header, u64 *mask)
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index 7f4f6b755760..033d7c05d7fb 100644
--- a/sound/soc/intel/haswell/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -458,12 +458,12 @@ static int create_adsp_page_table(struct snd_pcm_substream *substream,
}
/* this may get called several times by oss emulation */
-static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
+static int hsw_pcm_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
@@ -592,13 +592,6 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (ret < 0) {
- dev_err(rtd->dev, "error: could not allocate %d bytes for PCM %d\n",
- params_buffer_bytes(params), ret);
- return ret;
- }
-
dmab = snd_pcm_get_dma_buf(substream);
ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area,
@@ -656,16 +649,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+static int hsw_pcm_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct hsw_pcm_data *pcm_data;
struct sst_hsw_stream *sst_stream;
@@ -770,11 +757,11 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
return pos;
}
-static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
@@ -795,10 +782,10 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
return offset;
}
-static int hsw_pcm_open(struct snd_pcm_substream *substream)
+static int hsw_pcm_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
@@ -828,10 +815,10 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
return 0;
}
-static int hsw_pcm_close(struct snd_pcm_substream *substream)
+static int hsw_pcm_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
struct hsw_pcm_data *pcm_data;
struct sst_hsw *hsw = pdata->hsw;
@@ -862,17 +849,6 @@ out:
return ret;
}
-static const struct snd_pcm_ops hsw_pcm_ops = {
- .open = hsw_pcm_open,
- .close = hsw_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = hsw_pcm_hw_params,
- .hw_free = hsw_pcm_hw_free,
- .trigger = hsw_pcm_trigger,
- .pointer = hsw_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
{
struct sst_hsw *hsw = pdata->hsw;
@@ -930,17 +906,17 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
}
}
-static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int hsw_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm = rtd->pcm;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct sst_pdata *pdata = dev_get_platdata(component->dev);
struct hsw_priv_data *priv_data = dev_get_drvdata(component->dev);
struct device *dev = pdata->dma_dev;
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- snd_pcm_lib_preallocate_pages_for_all(pcm,
+ snd_pcm_set_managed_buffer_all(pcm,
SNDRV_DMA_TYPE_DEV_SG,
dev,
hsw_pcm_hardware.buffer_bytes_max,
@@ -1121,8 +1097,12 @@ static const struct snd_soc_component_driver hsw_dai_component = {
.name = DRV_NAME,
.probe = hsw_pcm_probe,
.remove = hsw_pcm_remove,
- .ops = &hsw_pcm_ops,
- .pcm_new = hsw_pcm_new,
+ .open = hsw_pcm_open,
+ .close = hsw_pcm_close,
+ .hw_params = hsw_pcm_hw_params,
+ .trigger = hsw_pcm_trigger,
+ .pointer = hsw_pcm_pointer,
+ .pcm_construct = hsw_pcm_new,
.controls = hsw_volume_controls,
.num_controls = ARRAY_SIZE(hsw_volume_controls),
.dapm_widgets = widgets,
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index 86f6e1d801af..48544ff1a3e6 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \
-skl-topology.o
+snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o skl-topology.o \
+ skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o skl-sst-cldma.o \
+ skl-sst.o bxt-sst.o cnl-sst.o skl-sst-utils.o
ifdef CONFIG_DEBUG_FS
snd-soc-skl-objs += skl-debug.o
@@ -8,13 +9,6 @@ endif
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
-# Skylake IPC Support
-snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \
- skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \
- skl-sst-utils.o
-
-obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
-
#Skylake Clock device support
snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 46d5159cf905..92a82e6b5fe6 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -14,7 +14,7 @@
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
-#include "skl-sst-ipc.h"
+#include "skl.h"
#define BXT_BASEFW_TIMEOUT 3000
#define BXT_INIT_TIMEOUT 300
@@ -49,7 +49,7 @@ static int
bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
{
struct snd_dma_buffer dmab;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct firmware stripped_fw;
int ret = 0, i, dma_id, stream_tag;
@@ -184,7 +184,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
static int bxt_load_base_firmware(struct sst_dsp *ctx)
{
struct firmware stripped_fw;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int ret, i;
if (ctx->fw == NULL) {
@@ -268,7 +268,7 @@ sst_load_base_firmware_failed:
*/
static int bxt_d0i3_target_state(struct sst_dsp *ctx)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct skl_d0i3_data *d0i3 = &skl->d0i3;
if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING)
@@ -288,8 +288,8 @@ static void bxt_set_dsp_D0i3(struct work_struct *work)
{
int ret;
struct skl_ipc_d0ix_msg msg;
- struct skl_sst *skl = container_of(work,
- struct skl_sst, d0i3.work.work);
+ struct skl_dev *skl = container_of(work,
+ struct skl_dev, d0i3.work.work);
struct sst_dsp *ctx = skl->dsp;
struct skl_d0i3_data *d0i3 = &skl->d0i3;
int target_state;
@@ -331,7 +331,7 @@ static void bxt_set_dsp_D0i3(struct work_struct *work)
static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct skl_d0i3_data *d0i3 = &skl->d0i3;
/* Schedule D0i3 only if the usecase ref counts are appropriate */
@@ -350,7 +350,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
{
int ret;
struct skl_ipc_d0ix_msg msg;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
dev_dbg(ctx->dev, "In %s:\n", __func__);
@@ -389,7 +389,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int ret;
struct skl_ipc_dxstate_info dx;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
@@ -486,7 +486,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
{
int ret;
struct skl_ipc_dxstate_info dx;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
dx.core_mask = core_mask;
@@ -548,9 +548,9 @@ static struct sst_dsp_device skl_dev = {
int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_sst **dsp)
+ struct skl_dev **dsp)
{
- struct skl_sst *skl;
+ struct skl_dev *skl;
struct sst_dsp *sst;
int ret;
@@ -591,10 +591,10 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
}
EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
-int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
+int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl)
{
int ret;
- struct sst_dsp *sst = ctx->dsp;
+ struct sst_dsp *sst = skl->dsp;
ret = sst->fw_ops.load_fw(sst);
if (ret < 0) {
@@ -604,29 +604,29 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
skl_dsp_init_core_state(sst);
- if (ctx->lib_count > 1) {
- ret = sst->fw_ops.load_library(sst, ctx->lib_info,
- ctx->lib_count);
+ if (skl->lib_count > 1) {
+ ret = sst->fw_ops.load_library(sst, skl->lib_info,
+ skl->lib_count);
if (ret < 0) {
dev_err(dev, "Load Library failed : %x\n", ret);
return ret;
}
}
- ctx->is_first_boot = false;
+ skl->is_first_boot = false;
return 0;
}
EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
-void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
+void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
{
- skl_release_library(ctx->lib_info, ctx->lib_count);
- if (ctx->dsp->fw)
- release_firmware(ctx->dsp->fw);
- skl_freeup_uuid_list(ctx);
- skl_ipc_free(&ctx->ipc);
- ctx->dsp->ops->free(ctx->dsp);
+ skl_release_library(skl->lib_info, skl->lib_count);
+ if (skl->dsp->fw)
+ release_firmware(skl->dsp->fw);
+ skl_freeup_uuid_list(skl);
+ skl_ipc_free(&skl->ipc);
+ skl->dsp->ops->free(skl->dsp);
}
EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.h b/sound/soc/intel/skylake/cnl-sst-dsp.h
index 426515faab52..7bd4d2a8fdfa 100644
--- a/sound/soc/intel/skylake/cnl-sst-dsp.h
+++ b/sound/soc/intel/skylake/cnl-sst-dsp.h
@@ -9,7 +9,6 @@
#define __CNL_SST_DSP_H__
struct sst_dsp;
-struct skl_sst;
struct sst_dsp_device;
struct sst_generic_ipc;
@@ -97,8 +96,8 @@ void cnl_ipc_free(struct sst_generic_ipc *ipc);
int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_sst **dsp);
-int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
-void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
+ struct skl_dev **dsp);
+int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl);
+void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
#endif /*__CNL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c
index f2c09fa6ea40..4f64f097e9ae 100644
--- a/sound/soc/intel/skylake/cnl-sst.c
+++ b/sound/soc/intel/skylake/cnl-sst.c
@@ -24,8 +24,7 @@
#include "../common/sst-dsp-priv.h"
#include "../common/sst-ipc.h"
#include "cnl-sst-dsp.h"
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
+#include "skl.h"
#define CNL_FW_ROM_INIT 0x1
#define CNL_FW_INIT 0x5
@@ -109,7 +108,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
static int cnl_load_base_firmware(struct sst_dsp *ctx)
{
struct firmware stripped_fw;
- struct skl_sst *cnl = ctx->thread_context;
+ struct skl_dev *cnl = ctx->thread_context;
int ret;
if (!ctx->fw) {
@@ -167,7 +166,7 @@ cnl_load_base_firmware_failed:
static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
{
- struct skl_sst *cnl = ctx->thread_context;
+ struct skl_dev *cnl = ctx->thread_context;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
struct skl_ipc_dxstate_info dx;
int ret;
@@ -229,7 +228,7 @@ err:
static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
{
- struct skl_sst *cnl = ctx->thread_context;
+ struct skl_dev *cnl = ctx->thread_context;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
struct skl_ipc_dxstate_info dx;
int ret;
@@ -293,7 +292,7 @@ static struct sst_ops cnl_ops = {
static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context)
{
struct sst_dsp *dsp = context;
- struct skl_sst *cnl = sst_dsp_get_thread_context(dsp);
+ struct skl_dev *cnl = sst_dsp_get_thread_context(dsp);
struct sst_generic_ipc *ipc = &cnl->ipc;
struct skl_ipc_header header = {0};
u32 hipcida, hipctdr, hipctdd;
@@ -367,10 +366,10 @@ static struct sst_dsp_device cnl_dev = {
static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{
- struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header);
+ struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
- if (msg->tx_size)
- sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+ if (msg->tx.size)
+ sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD,
header->extension);
sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR,
@@ -386,7 +385,7 @@ static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp)
return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY);
}
-static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl)
+static int cnl_ipc_init(struct device *dev, struct skl_dev *cnl)
{
struct sst_generic_ipc *ipc;
int err;
@@ -415,9 +414,9 @@ static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl)
int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_sst **dsp)
+ struct skl_dev **dsp)
{
- struct skl_sst *cnl;
+ struct skl_dev *cnl;
struct sst_dsp *sst;
int ret;
@@ -454,12 +453,12 @@ int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
}
EXPORT_SYMBOL_GPL(cnl_sst_dsp_init);
-int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
+int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl)
{
int ret;
- struct sst_dsp *sst = ctx->dsp;
+ struct sst_dsp *sst = skl->dsp;
- ret = ctx->dsp->fw_ops.load_fw(sst);
+ ret = skl->dsp->fw_ops.load_fw(sst);
if (ret < 0) {
dev_err(dev, "load base fw failed: %d", ret);
return ret;
@@ -467,21 +466,21 @@ int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
skl_dsp_init_core_state(sst);
- ctx->is_first_boot = false;
+ skl->is_first_boot = false;
return 0;
}
EXPORT_SYMBOL_GPL(cnl_sst_init_fw);
-void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
+void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
{
- if (ctx->dsp->fw)
- release_firmware(ctx->dsp->fw);
+ if (skl->dsp->fw)
+ release_firmware(skl->dsp->fw);
- skl_freeup_uuid_list(ctx);
- cnl_ipc_free(&ctx->ipc);
+ skl_freeup_uuid_list(skl);
+ cnl_ipc_free(&skl->ipc);
- ctx->dsp->ops->free(ctx->dsp);
+ skl->dsp->ops->free(skl->dsp);
}
EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index b9b4a72a4334..3466675f2678 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -20,7 +20,7 @@
#define FW_REG_SIZE 0x60
struct skl_debug {
- struct skl *skl;
+ struct skl_dev *skl;
struct device *dev;
struct dentry *fs;
@@ -66,6 +66,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct skl_module_cfg *mconfig = file->private_data;
+ struct skl_module *module = mconfig->module;
+ struct skl_module_res *res = &module->resources[mconfig->res_idx];
char *buf;
ssize_t ret;
@@ -79,8 +81,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf,
mconfig->id.pvt_id);
ret += snprintf(buf + ret, MOD_BUF - ret,
- "Resources:\n\tMCPS %#x\n\tIBS %#x\n\tOBS %#x\t\n",
- mconfig->mcps, mconfig->ibs, mconfig->obs);
+ "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n",
+ res->cpc, res->ibs, res->obs);
ret += snprintf(buf + ret, MOD_BUF - ret,
"Module data:\n\tCore %d\n\tIn queue %d\n\t"
@@ -162,17 +164,15 @@ void skl_debug_init_module(struct skl_debug *d,
struct snd_soc_dapm_widget *w,
struct skl_module_cfg *mconfig)
{
- if (!debugfs_create_file(w->name, 0444,
- d->modules, mconfig,
- &mcfg_fops))
- dev_err(d->dev, "%s: module debugfs init failed\n", w->name);
+ debugfs_create_file(w->name, 0444, d->modules, mconfig,
+ &mcfg_fops);
}
static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct skl_debug *d = file->private_data;
- struct sst_dsp *sst = d->skl->skl_sst->dsp;
+ struct sst_dsp *sst = d->skl->dsp;
size_t w0_stat_sz = sst->addr.w0_stat_sz;
void __iomem *in_base = sst->mailbox.in_base;
void __iomem *fw_reg_addr;
@@ -188,7 +188,7 @@ static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
memset(d->fw_read_buff, 0, FW_REG_BUF);
if (w0_stat_sz > 0)
- __iowrite32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2);
+ __ioread32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2);
for (offset = 0; offset < FW_REG_SIZE; offset += 16) {
ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset);
@@ -213,7 +213,7 @@ static const struct file_operations soft_regs_ctrl_fops = {
.llseek = default_llseek,
};
-struct skl_debug *skl_debugfs_init(struct skl *skl)
+struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
{
struct skl_debug *d;
@@ -222,37 +222,21 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
return NULL;
/* create the debugfs dir with platform component's debugfs as parent */
- d->fs = debugfs_create_dir("dsp",
- skl->component->debugfs_root);
- if (IS_ERR(d->fs) || !d->fs) {
- dev_err(&skl->pci->dev, "debugfs root creation failed\n");
- return NULL;
- }
+ d->fs = debugfs_create_dir("dsp", skl->component->debugfs_root);
d->skl = skl;
d->dev = &skl->pci->dev;
/* now create the module dir */
d->modules = debugfs_create_dir("modules", d->fs);
- if (IS_ERR(d->modules) || !d->modules) {
- dev_err(&skl->pci->dev, "modules debugfs create failed\n");
- goto err;
- }
- if (!debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d,
- &soft_regs_ctrl_fops)) {
- dev_err(d->dev, "fw soft regs control debugfs init failed\n");
- goto err;
- }
+ debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d,
+ &soft_regs_ctrl_fops);
return d;
-
-err:
- debugfs_remove_recursive(d->fs);
- return NULL;
}
-void skl_debugfs_exit(struct skl *skl)
+void skl_debugfs_exit(struct skl_dev *skl)
{
struct skl_debug *d = skl->debugfs;
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index febc070839e0..476ef1897961 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -25,29 +25,18 @@
static int skl_alloc_dma_buf(struct device *dev,
struct snd_dma_buffer *dmab, size_t size)
{
- struct hdac_bus *bus = dev_get_drvdata(dev);
-
- if (!bus)
- return -ENODEV;
-
- return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab);
+ return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab);
}
static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
{
- struct hdac_bus *bus = dev_get_drvdata(dev);
-
- if (!bus)
- return -ENODEV;
-
- bus->io_ops->dma_free_pages(bus, dmab);
-
+ snd_dma_free_pages(dmab);
return 0;
}
#define SKL_ASTATE_PARAM_ID 4
-void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data)
+void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data)
{
struct skl_ipc_large_config_msg msg = {0};
@@ -55,25 +44,7 @@ void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data)
msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
sizeof(cnt));
- skl_ipc_set_large_config(&ctx->ipc, &msg, data);
-}
-
-#define NOTIFICATION_PARAM_ID 3
-#define NOTIFICATION_MASK 0xf
-
-/* disable notfication for underruns/overruns from firmware module */
-void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
-{
- struct notification_mask mask;
- struct skl_ipc_large_config_msg msg = {0};
-
- mask.notify = NOTIFICATION_MASK;
- mask.enable = enable;
-
- msg.large_param_id = NOTIFICATION_PARAM_ID;
- msg.param_data_size = sizeof(mask);
-
- skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
+ skl_ipc_set_large_config(&skl->ipc, &msg, data);
}
static int skl_dsp_setup_spib(struct device *dev, unsigned int size,
@@ -277,7 +248,7 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
return NULL;
}
-int skl_init_dsp(struct skl *skl)
+int skl_init_dsp(struct skl_dev *skl)
{
void __iomem *mmio_base;
struct hdac_bus *bus = skl_to_bus(skl);
@@ -307,13 +278,13 @@ int skl_init_dsp(struct skl *skl)
loader_ops = ops->loader_ops();
ret = ops->init(bus->dev, mmio_base, irq,
skl->fw_name, loader_ops,
- &skl->skl_sst);
+ &skl);
if (ret < 0)
goto unmap_mmio;
- skl->skl_sst->dsp_ops = ops;
- cores = &skl->skl_sst->cores;
+ skl->dsp_ops = ops;
+ cores = &skl->cores;
cores->count = ops->num_cores;
cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL);
@@ -342,21 +313,20 @@ unmap_mmio:
return ret;
}
-int skl_free_dsp(struct skl *skl)
+int skl_free_dsp(struct skl_dev *skl)
{
struct hdac_bus *bus = skl_to_bus(skl);
- struct skl_sst *ctx = skl->skl_sst;
/* disable ppcap interrupt */
snd_hdac_ext_bus_ppcap_int_enable(bus, false);
- ctx->dsp_ops->cleanup(bus->dev, ctx);
+ skl->dsp_ops->cleanup(bus->dev, skl);
- kfree(ctx->cores.state);
- kfree(ctx->cores.usage_count);
+ kfree(skl->cores.state);
+ kfree(skl->cores.usage_count);
- if (ctx->dsp->addr.lpe)
- iounmap(ctx->dsp->addr.lpe);
+ if (skl->dsp->addr.lpe)
+ iounmap(skl->dsp->addr.lpe);
return 0;
}
@@ -368,15 +338,14 @@ int skl_free_dsp(struct skl *skl)
* mode during system suspend. In the case of normal suspend, cancel
* any pending D0i3 work.
*/
-int skl_suspend_late_dsp(struct skl *skl)
+int skl_suspend_late_dsp(struct skl_dev *skl)
{
- struct skl_sst *ctx = skl->skl_sst;
struct delayed_work *dwork;
- if (!ctx)
+ if (!skl)
return 0;
- dwork = &ctx->d0i3.work;
+ dwork = &skl->d0i3.work;
if (dwork->work.func) {
if (skl->supend_active)
@@ -388,9 +357,8 @@ int skl_suspend_late_dsp(struct skl *skl)
return 0;
}
-int skl_suspend_dsp(struct skl *skl)
+int skl_suspend_dsp(struct skl_dev *skl)
{
- struct skl_sst *ctx = skl->skl_sst;
struct hdac_bus *bus = skl_to_bus(skl);
int ret;
@@ -398,7 +366,7 @@ int skl_suspend_dsp(struct skl *skl)
if (!bus->ppcap)
return 0;
- ret = skl_dsp_sleep(ctx->dsp);
+ ret = skl_dsp_sleep(skl->dsp);
if (ret < 0)
return ret;
@@ -409,9 +377,8 @@ int skl_suspend_dsp(struct skl *skl)
return 0;
}
-int skl_resume_dsp(struct skl *skl)
+int skl_resume_dsp(struct skl_dev *skl)
{
- struct skl_sst *ctx = skl->skl_sst;
struct hdac_bus *bus = skl_to_bus(skl);
int ret;
@@ -424,26 +391,24 @@ int skl_resume_dsp(struct skl *skl)
snd_hdac_ext_bus_ppcap_int_enable(bus, true);
/* check if DSP 1st boot is done */
- if (skl->skl_sst->is_first_boot)
+ if (skl->is_first_boot)
return 0;
/*
* Disable dynamic clock and power gating during firmware
* and library download
*/
- ctx->enable_miscbdcge(ctx->dev, false);
- ctx->clock_power_gating(ctx->dev, false);
+ skl->enable_miscbdcge(skl->dev, false);
+ skl->clock_power_gating(skl->dev, false);
- ret = skl_dsp_wake(ctx->dsp);
- ctx->enable_miscbdcge(ctx->dev, true);
- ctx->clock_power_gating(ctx->dev, true);
+ ret = skl_dsp_wake(skl->dsp);
+ skl->enable_miscbdcge(skl->dev, true);
+ skl->clock_power_gating(skl->dev, true);
if (ret < 0)
return ret;
- skl_dsp_enable_notification(skl->skl_sst, false);
-
if (skl->cfg.astate_cfg != NULL) {
- skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count,
+ skl_dsp_set_astate_cfg(skl, skl->cfg.astate_cfg->count,
skl->cfg.astate_cfg);
}
return ret;
@@ -476,7 +441,7 @@ enum skl_bitdepth skl_get_bit_depth(int params)
* which are read from widget information passed through topology binary
* This is send when we create a module with INIT_INSTANCE IPC msg
*/
-static void skl_set_base_module_format(struct skl_sst *ctx,
+static void skl_set_base_module_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_base_cfg *base_cfg)
{
@@ -493,7 +458,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
base_cfg->audio_fmt.ch_cfg = format->ch_cfg;
base_cfg->audio_fmt.sample_type = format->sample_type;
- dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n",
+ dev_dbg(skl->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n",
format->bit_depth, format->valid_bit_depth,
format->ch_cfg);
@@ -501,7 +466,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
base_cfg->audio_fmt.interleaving = format->interleaving_style;
- base_cfg->cps = res->cps;
+ base_cfg->cpc = res->cpc;
base_cfg->ibs = res->ibs;
base_cfg->obs = res->obs;
base_cfg->is_pages = res->is_pages;
@@ -530,7 +495,7 @@ 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 u32 skl_get_node_id(struct skl_sst *ctx,
+static u32 skl_get_node_id(struct skl_dev *skl,
struct skl_module_cfg *mconfig)
{
union skl_connector_node_id node_id = {0};
@@ -587,16 +552,15 @@ static u32 skl_get_node_id(struct skl_sst *ctx,
return node_id.val;
}
-static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
+static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_cpr_cfg *cpr_mconfig)
{
u32 dma_io_buf;
struct skl_module_res *res;
int res_idx = mconfig->res_idx;
- struct skl *skl = get_skl_ctx(ctx->dev);
- cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig);
+ cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(skl, mconfig);
if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
cpr_mconfig->cpr_feature_mask = 0;
@@ -627,7 +591,7 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
break;
default:
- dev_warn(ctx->dev, "wrong connection type: %d\n",
+ dev_warn(skl->dev, "wrong connection type: %d\n",
mconfig->hw_conn_type);
return;
}
@@ -653,7 +617,7 @@ skip_buf_size_calc:
#define DMA_CONTROL_ID 5
#define DMA_I2S_BLOB_SIZE 21
-int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
u32 caps_size, u32 node_id)
{
struct skl_dma_control *dma_ctrl;
@@ -686,14 +650,14 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
memcpy(dma_ctrl->config_data, caps, caps_size);
- err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
+ err = skl_ipc_set_large_config(&skl->ipc, &msg, (u32 *)dma_ctrl);
kfree(dma_ctrl);
return err;
}
EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
-static void skl_setup_out_format(struct skl_sst *ctx,
+static void skl_setup_out_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_audio_data_format *out_fmt)
{
@@ -711,7 +675,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
out_fmt->interleaving = format->interleaving_style;
out_fmt->sample_type = format->sample_type;
- dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
+ dev_dbg(skl->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
out_fmt->number_of_channels, format->s_freq, format->bit_depth);
}
@@ -720,7 +684,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
* configuration and the target frequency as extra parameter passed as src
* config
*/
-static void skl_set_src_format(struct skl_sst *ctx,
+static void skl_set_src_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_src_module_cfg *src_mconfig)
{
@@ -728,7 +692,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
- skl_set_base_module_format(ctx, mconfig,
+ skl_set_base_module_format(skl, mconfig,
(struct skl_base_cfg *)src_mconfig);
src_mconfig->src_cfg = fmt->s_freq;
@@ -739,7 +703,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
* module configuration and channel configuration
* It also take coefficients and now we have defaults applied here
*/
-static void skl_set_updown_mixer_format(struct skl_sst *ctx,
+static void skl_set_updown_mixer_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_up_down_mixer_cfg *mixer_mconfig)
{
@@ -747,7 +711,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
- skl_set_base_module_format(ctx, mconfig,
+ skl_set_base_module_format(skl, mconfig,
(struct skl_base_cfg *)mixer_mconfig);
mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
mixer_mconfig->ch_map = fmt->ch_map;
@@ -760,17 +724,17 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
* format, gateway settings
* copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg
*/
-static void skl_set_copier_format(struct skl_sst *ctx,
+static void skl_set_copier_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_cpr_cfg *cpr_mconfig)
{
struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt;
struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig;
- skl_set_base_module_format(ctx, mconfig, base_cfg);
+ skl_set_base_module_format(skl, mconfig, base_cfg);
- skl_setup_out_format(ctx, mconfig, out_fmt);
- skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig);
+ skl_setup_out_format(skl, mconfig, out_fmt);
+ skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig);
}
/*
@@ -778,13 +742,13 @@ static void skl_set_copier_format(struct skl_sst *ctx,
* configuration and params
*/
-static void skl_set_algo_format(struct skl_sst *ctx,
+static void skl_set_algo_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_algo_cfg *algo_mcfg)
{
struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
- skl_set_base_module_format(ctx, mconfig, base_cfg);
+ skl_set_base_module_format(skl, mconfig, base_cfg);
if (mconfig->formats_config.caps_size == 0)
return;
@@ -802,7 +766,7 @@ static void skl_set_algo_format(struct skl_sst *ctx,
* Mic select module take base module configuration and out-format
* configuration
*/
-static void skl_set_base_outfmt_format(struct skl_sst *ctx,
+static void skl_set_base_outfmt_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_base_outfmt_cfg *base_outfmt_mcfg)
{
@@ -810,11 +774,11 @@ static void skl_set_base_outfmt_format(struct skl_sst *ctx,
struct skl_base_cfg *base_cfg =
(struct skl_base_cfg *)base_outfmt_mcfg;
- skl_set_base_module_format(ctx, mconfig, base_cfg);
- skl_setup_out_format(ctx, mconfig, out_fmt);
+ skl_set_base_module_format(skl, mconfig, base_cfg);
+ skl_setup_out_format(skl, mconfig, out_fmt);
}
-static u16 skl_get_module_param_size(struct skl_sst *ctx,
+static u16 skl_get_module_param_size(struct skl_dev *skl,
struct skl_module_cfg *mconfig)
{
u16 param_size;
@@ -859,14 +823,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
* base module format configuration
*/
-static int skl_set_module_format(struct skl_sst *ctx,
+static int skl_set_module_format(struct skl_dev *skl,
struct skl_module_cfg *module_config,
u16 *module_config_size,
void **param_data)
{
u16 param_size;
- param_size = skl_get_module_param_size(ctx, module_config);
+ param_size = skl_get_module_param_size(skl, module_config);
*param_data = kzalloc(param_size, GFP_KERNEL);
if (NULL == *param_data)
@@ -876,35 +840,36 @@ static int skl_set_module_format(struct skl_sst *ctx,
switch (module_config->m_type) {
case SKL_MODULE_TYPE_COPIER:
- skl_set_copier_format(ctx, module_config, *param_data);
+ skl_set_copier_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_SRCINT:
- skl_set_src_format(ctx, module_config, *param_data);
+ skl_set_src_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_UPDWMIX:
- skl_set_updown_mixer_format(ctx, module_config, *param_data);
+ skl_set_updown_mixer_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_ALGO:
- skl_set_algo_format(ctx, module_config, *param_data);
+ skl_set_algo_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_BASE_OUTFMT:
case SKL_MODULE_TYPE_MIC_SELECT:
case SKL_MODULE_TYPE_KPB:
- skl_set_base_outfmt_format(ctx, module_config, *param_data);
+ skl_set_base_outfmt_format(skl, module_config, *param_data);
break;
default:
- skl_set_base_module_format(ctx, module_config, *param_data);
+ skl_set_base_module_format(skl, module_config, *param_data);
break;
}
- dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n",
- module_config->id.module_id, param_size);
+ dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
+ module_config->m_type, module_config->id.module_id,
+ param_size);
print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4,
*param_data, param_size, false);
return 0;
@@ -1004,7 +969,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
* We first calculate the module format, based on module type and then
* invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
*/
-int skl_init_module(struct skl_sst *ctx,
+int skl_init_module(struct skl_dev *skl,
struct skl_module_cfg *mconfig)
{
u16 module_config_size = 0;
@@ -1012,19 +977,19 @@ int skl_init_module(struct skl_sst *ctx,
int ret;
struct skl_ipc_init_instance_msg msg;
- dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__,
+ dev_dbg(skl->dev, "%s: module_id = %d instance=%d\n", __func__,
mconfig->id.module_id, mconfig->id.pvt_id);
if (mconfig->pipe->state != SKL_PIPE_CREATED) {
- dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n",
+ dev_err(skl->dev, "Pipe not created state= %d pipe_id= %d\n",
mconfig->pipe->state, mconfig->pipe->ppl_id);
return -EIO;
}
- ret = skl_set_module_format(ctx, mconfig,
+ ret = skl_set_module_format(skl, mconfig,
&module_config_size, &param_data);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret);
+ dev_err(skl->dev, "Failed to set module format ret=%d\n", ret);
return ret;
}
@@ -1035,9 +1000,9 @@ int skl_init_module(struct skl_sst *ctx,
msg.core_id = mconfig->core_id;
msg.domain = mconfig->domain;
- ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
+ ret = skl_ipc_init_instance(&skl->ipc, &msg, param_data);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret);
+ dev_err(skl->dev, "Failed to init instance ret=%d\n", ret);
kfree(param_data);
return ret;
}
@@ -1046,15 +1011,15 @@ int skl_init_module(struct skl_sst *ctx,
return ret;
}
-static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
+static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg
*src_module, struct skl_module_cfg *dst_module)
{
- dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n",
+ dev_dbg(skl->dev, "%s: src module_id = %d src_instance=%d\n",
__func__, src_module->id.module_id, src_module->id.pvt_id);
- dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__,
+ dev_dbg(skl->dev, "%s: dst_module=%d dst_instance=%d\n", __func__,
dst_module->id.module_id, dst_module->id.pvt_id);
- dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n",
+ dev_dbg(skl->dev, "src_module state = %d dst module state = %d\n",
src_module->m_state, dst_module->m_state);
}
@@ -1063,7 +1028,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
* it is already bind.
* Find the pin allocated and unbind then using bind_unbind IPC
*/
-int skl_unbind_modules(struct skl_sst *ctx,
+int skl_unbind_modules(struct skl_dev *skl,
struct skl_module_cfg *src_mcfg,
struct skl_module_cfg *dst_mcfg)
{
@@ -1075,7 +1040,7 @@ int skl_unbind_modules(struct skl_sst *ctx,
int out_max = src_mcfg->module->max_output_pins;
int src_index, dst_index, src_pin_state, dst_pin_state;
- skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
+ skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
/* get src queue index */
src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
@@ -1104,7 +1069,7 @@ int skl_unbind_modules(struct skl_sst *ctx,
msg.dst_instance_id = dst_mcfg->id.pvt_id;
msg.bind = false;
- ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
+ ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
if (!ret) {
/* free queue only if unbind is success */
skl_free_queue(src_mcfg->m_out_pin, src_index);
@@ -1142,7 +1107,7 @@ static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
* This function finds the pins and then sends bund_unbind IPC message to
* DSP using IPC helper
*/
-int skl_bind_modules(struct skl_sst *ctx,
+int skl_bind_modules(struct skl_dev *skl,
struct skl_module_cfg *src_mcfg,
struct skl_module_cfg *dst_mcfg)
{
@@ -1156,7 +1121,7 @@ int skl_bind_modules(struct skl_sst *ctx,
struct skl_module *module;
struct skl_module_iface *fmt;
- skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
+ skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
@@ -1188,7 +1153,7 @@ int skl_bind_modules(struct skl_sst *ctx,
format = &fmt->outputs[src_index].fmt;
fill_pin_params(&(pin_fmt.dst_fmt), format);
- ret = skl_set_module_params(ctx, (void *)&pin_fmt,
+ ret = skl_set_module_params(skl, (void *)&pin_fmt,
sizeof(struct skl_cpr_pin_fmt),
CPR_SINK_FMT_PARAM_ID, src_mcfg);
@@ -1198,7 +1163,7 @@ int skl_bind_modules(struct skl_sst *ctx,
msg.dst_queue = dst_index;
- dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n",
+ dev_dbg(skl->dev, "src queue = %d dst queue =%d\n",
msg.src_queue, msg.dst_queue);
msg.module_id = src_mcfg->id.module_id;
@@ -1207,7 +1172,7 @@ int skl_bind_modules(struct skl_sst *ctx,
msg.dst_instance_id = dst_mcfg->id.pvt_id;
msg.bind = true;
- ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
+ ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
if (!ret) {
src_mcfg->m_state = SKL_MODULE_BIND_DONE;
@@ -1223,12 +1188,12 @@ out:
return ret;
}
-static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
+static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe,
enum skl_ipc_pipeline_state state)
{
- dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state);
+ dev_dbg(skl->dev, "%s: pipe_state = %d\n", __func__, state);
- return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
+ return skl_ipc_set_pipeline_state(&skl->ipc, pipe->ppl_id, state);
}
/*
@@ -1237,17 +1202,17 @@ static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
* This function creates pipeline, by sending create pipeline IPC messages
* to FW
*/
-int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe)
+int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe)
{
int ret;
- dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
+ dev_dbg(skl->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
- ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages,
+ ret = skl_ipc_create_pipeline(&skl->ipc, pipe->memory_pages,
pipe->pipe_priority, pipe->ppl_id,
pipe->lp_mode);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to create pipeline\n");
+ dev_err(skl->dev, "Failed to create pipeline\n");
return ret;
}
@@ -1262,11 +1227,11 @@ int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe)
* reset state. Finish the procedure by sending delete pipeline IPC.
* DSP will stop the DMA engines and release resources
*/
-int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
+int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{
int ret;
- dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
+ dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
/* If pipe was not created in FW, do not try to delete it */
if (pipe->state < SKL_PIPE_CREATED)
@@ -1274,9 +1239,9 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
/* If pipe is started, do stop the pipe in FW. */
if (pipe->state >= SKL_PIPE_STARTED) {
- ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
+ ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to stop pipeline\n");
+ dev_err(skl->dev, "Failed to stop pipeline\n");
return ret;
}
@@ -1284,17 +1249,17 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
}
/* reset pipe state before deletion */
- ret = skl_set_pipe_state(ctx, pipe, PPL_RESET);
+ ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to reset pipe ret=%d\n", ret);
+ dev_err(skl->dev, "Failed to reset pipe ret=%d\n", ret);
return ret;
}
pipe->state = SKL_PIPE_RESET;
- ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id);
+ ret = skl_ipc_delete_pipeline(&skl->ipc, pipe->ppl_id);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to delete pipeline\n");
+ dev_err(skl->dev, "Failed to delete pipeline\n");
return ret;
}
@@ -1308,28 +1273,28 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
* For processing data the pipe need to be run by sending IPC set pipe state
* to DSP
*/
-int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
+int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{
int ret;
- dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
+ dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
/* If pipe was not created in FW, do not try to pause or delete */
if (pipe->state < SKL_PIPE_CREATED)
return 0;
/* Pipe has to be paused before it is started */
- ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
+ ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to pause pipe\n");
+ dev_err(skl->dev, "Failed to pause pipe\n");
return ret;
}
pipe->state = SKL_PIPE_PAUSED;
- ret = skl_set_pipe_state(ctx, pipe, PPL_RUNNING);
+ ret = skl_set_pipe_state(skl, pipe, PPL_RUNNING);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to start pipe\n");
+ dev_err(skl->dev, "Failed to start pipe\n");
return ret;
}
@@ -1342,19 +1307,19 @@ int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
* Stop the pipeline by sending set pipe state IPC
* DSP doesnt implement stop so we always send pause message
*/
-int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
+int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{
int ret;
- dev_dbg(ctx->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id);
+ dev_dbg(skl->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id);
/* If pipe was not created in FW, do not try to pause or delete */
if (pipe->state < SKL_PIPE_PAUSED)
return 0;
- ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
+ ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
if (ret < 0) {
- dev_dbg(ctx->dev, "Failed to stop pipe\n");
+ dev_dbg(skl->dev, "Failed to stop pipe\n");
return ret;
}
@@ -1367,7 +1332,7 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
* Reset the pipeline by sending set pipe state IPC this will reset the DMA
* from the DSP side
*/
-int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
+int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
{
int ret;
@@ -1375,9 +1340,9 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
if (pipe->state < SKL_PIPE_PAUSED)
return 0;
- ret = skl_set_pipe_state(ctx, pipe, PPL_RESET);
+ ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
if (ret < 0) {
- dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret);
+ dev_dbg(skl->dev, "Failed to reset pipe ret=%d\n", ret);
return ret;
}
@@ -1387,7 +1352,7 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
}
/* Algo parameter set helper function */
-int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
+int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
u32 param_id, struct skl_module_cfg *mcfg)
{
struct skl_ipc_large_config_msg msg;
@@ -1397,18 +1362,19 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
msg.param_data_size = size;
msg.large_param_id = param_id;
- return skl_ipc_set_large_config(&ctx->ipc, &msg, params);
+ return skl_ipc_set_large_config(&skl->ipc, &msg, params);
}
-int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
+int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
u32 param_id, struct skl_module_cfg *mcfg)
{
struct skl_ipc_large_config_msg msg;
+ size_t bytes = size;
msg.module_id = mcfg->id.module_id;
msg.instance_id = mcfg->id.pvt_id;
msg.param_data_size = size;
msg.large_param_id = param_id;
- return skl_ipc_get_large_config(&ctx->ipc, &msg, params);
+ return skl_ipc_get_large_config(&skl->ipc, &msg, &params, &bytes);
}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 1132109cb992..19f328d71f24 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -9,57 +9,10 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/pci.h>
+#include <sound/intel-nhlt.h>
#include "skl.h"
#include "skl-i2s.h"
-#define NHLT_ACPI_HEADER_SIG "NHLT"
-
-/* Unique identification for getting NHLT blobs */
-static guid_t osc_guid =
- GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
- 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
-
-
-struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
-{
- acpi_handle handle;
- union acpi_object *obj;
- struct nhlt_resource_desc *nhlt_ptr = NULL;
- struct nhlt_acpi_table *nhlt_table = NULL;
-
- handle = ACPI_HANDLE(dev);
- if (!handle) {
- dev_err(dev, "Didn't find ACPI_HANDLE\n");
- return NULL;
- }
-
- obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL);
- if (obj && obj->type == ACPI_TYPE_BUFFER) {
- nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer;
- if (nhlt_ptr->length)
- nhlt_table = (struct nhlt_acpi_table *)
- memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
- MEMREMAP_WB);
- ACPI_FREE(obj);
- if (nhlt_table && (strncmp(nhlt_table->header.signature,
- NHLT_ACPI_HEADER_SIG,
- strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
- memunmap(nhlt_table);
- dev_err(dev, "NHLT ACPI header signature incorrect\n");
- return NULL;
- }
- return nhlt_table;
- }
-
- dev_err(dev, "device specific method to extract NHLT blob failed\n");
- return NULL;
-}
-
-void skl_nhlt_free(struct nhlt_acpi_table *nhlt)
-{
- memunmap((void *) nhlt);
-}
-
static struct nhlt_specific_cfg *skl_get_specific_cfg(
struct device *dev, struct nhlt_fmt *fmt,
u8 no_ch, u32 rate, u16 bps, u8 linktype)
@@ -126,7 +79,7 @@ static bool skl_check_ep_match(struct device *dev, struct nhlt_endpoint *epnt,
}
struct nhlt_specific_cfg
-*skl_get_ep_blob(struct skl *skl, u32 instance, u8 link_type,
+*skl_get_ep_blob(struct skl_dev *skl, u32 instance, u8 link_type,
u8 s_fmt, u8 num_ch, u32 s_rate,
u8 dirn, u8 dev_type)
{
@@ -162,48 +115,6 @@ struct nhlt_specific_cfg
return NULL;
}
-int skl_get_dmic_geo(struct skl *skl)
-{
- struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
- struct nhlt_endpoint *epnt;
- struct nhlt_dmic_array_config *cfg;
- struct device *dev = &skl->pci->dev;
- unsigned int dmic_geo = 0;
- u8 j;
-
- if (!nhlt)
- return 0;
-
- epnt = (struct nhlt_endpoint *)nhlt->desc;
-
- for (j = 0; j < nhlt->endpoint_count; j++) {
- if (epnt->linktype == NHLT_LINK_DMIC) {
- cfg = (struct nhlt_dmic_array_config *)
- (epnt->config.caps);
- switch (cfg->array_type) {
- case NHLT_MIC_ARRAY_2CH_SMALL:
- case NHLT_MIC_ARRAY_2CH_BIG:
- dmic_geo |= MIC_ARRAY_2CH;
- break;
-
- case NHLT_MIC_ARRAY_4CH_1ST_GEOM:
- case NHLT_MIC_ARRAY_4CH_L_SHAPED:
- case NHLT_MIC_ARRAY_4CH_2ND_GEOM:
- dmic_geo |= MIC_ARRAY_4CH;
- break;
-
- default:
- dev_warn(dev, "undefined DMIC array_type 0x%0x\n",
- cfg->array_type);
-
- }
- }
- epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
- }
-
- return dmic_geo;
-}
-
static void skl_nhlt_trim_space(char *trim)
{
char *s = trim;
@@ -219,13 +130,13 @@ static void skl_nhlt_trim_space(char *trim)
s[cnt] = '\0';
}
-int skl_nhlt_update_topology_bin(struct skl *skl)
+int skl_nhlt_update_topology_bin(struct skl_dev *skl)
{
struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
struct hdac_bus *bus = skl_to_bus(skl);
struct device *dev = bus->dev;
- dev_dbg(dev, "oem_id %.6s, oem_table_id %8s oem_revision %d\n",
+ 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);
@@ -243,7 +154,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev,
{
struct pci_dev *pci = to_pci_dev(dev);
struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
char platform_id[32];
@@ -257,7 +168,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev,
static DEVICE_ATTR(platform_id, 0444, skl_nhlt_platform_id_show, NULL);
-int skl_nhlt_create_sysfs(struct skl *skl)
+int skl_nhlt_create_sysfs(struct skl_dev *skl)
{
struct device *dev = &skl->pci->dev;
@@ -267,7 +178,7 @@ int skl_nhlt_create_sysfs(struct skl *skl)
return 0;
}
-void skl_nhlt_remove_sysfs(struct skl *skl)
+void skl_nhlt_remove_sysfs(struct skl_dev *skl)
{
struct device *dev = &skl->pci->dev;
@@ -279,7 +190,7 @@ void skl_nhlt_remove_sysfs(struct skl *skl)
* stores all possible rates supported in a rate table for the corresponding
* sclk/sclkfs.
*/
-static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
+static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
struct nhlt_fmt *fmt, u8 id)
{
struct skl_i2s_config_blob_ext *i2s_config_ext;
@@ -377,7 +288,7 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
}
}
-static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
+static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk,
struct nhlt_fmt *fmt, u8 id)
{
struct skl_i2s_config_blob_ext *i2s_config_ext;
@@ -421,7 +332,7 @@ static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
mclk[id].parent_name = parent->name;
}
-void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks)
+void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks)
{
struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
struct nhlt_endpoint *epnt;
diff --git a/sound/soc/intel/skylake/skl-nhlt.h b/sound/soc/intel/skylake/skl-nhlt.h
deleted file mode 100644
index f85fbf9c7ce4..000000000000
--- a/sound/soc/intel/skylake/skl-nhlt.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * skl-nhlt.h - Intel HDA Platform NHLT header
- *
- * Copyright (C) 2015 Intel Corp
- * Author: Sanjiv Kumar <sanjiv.kumar@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#ifndef __SKL_NHLT_H__
-#define __SKL_NHLT_H__
-
-#include <linux/acpi.h>
-
-struct wav_fmt {
- u16 fmt_tag;
- u16 channels;
- u32 samples_per_sec;
- u32 avg_bytes_per_sec;
- u16 block_align;
- u16 bits_per_sample;
- u16 cb_size;
-} __packed;
-
-struct wav_fmt_ext {
- struct wav_fmt fmt;
- union samples {
- u16 valid_bits_per_sample;
- u16 samples_per_block;
- u16 reserved;
- } sample;
- u32 channel_mask;
- u8 sub_fmt[16];
-} __packed;
-
-enum nhlt_link_type {
- NHLT_LINK_HDA = 0,
- NHLT_LINK_DSP = 1,
- NHLT_LINK_DMIC = 2,
- NHLT_LINK_SSP = 3,
- NHLT_LINK_INVALID
-};
-
-enum nhlt_device_type {
- NHLT_DEVICE_BT = 0,
- NHLT_DEVICE_DMIC = 1,
- NHLT_DEVICE_I2S = 4,
- NHLT_DEVICE_INVALID
-};
-
-struct nhlt_specific_cfg {
- u32 size;
- u8 caps[0];
-} __packed;
-
-struct nhlt_fmt_cfg {
- struct wav_fmt_ext fmt_ext;
- struct nhlt_specific_cfg config;
-} __packed;
-
-struct nhlt_fmt {
- u8 fmt_count;
- struct nhlt_fmt_cfg fmt_config[0];
-} __packed;
-
-struct nhlt_endpoint {
- u32 length;
- u8 linktype;
- u8 instance_id;
- u16 vendor_id;
- u16 device_id;
- u16 revision_id;
- u32 subsystem_id;
- u8 device_type;
- u8 direction;
- u8 virtual_bus_id;
- struct nhlt_specific_cfg config;
-} __packed;
-
-struct nhlt_acpi_table {
- struct acpi_table_header header;
- u8 endpoint_count;
- struct nhlt_endpoint desc[0];
-} __packed;
-
-struct nhlt_resource_desc {
- u32 extra;
- u16 flags;
- u64 addr_spc_gra;
- u64 min_addr;
- u64 max_addr;
- u64 addr_trans_offset;
- u64 length;
-} __packed;
-
-#define MIC_ARRAY_2CH 2
-#define MIC_ARRAY_4CH 4
-
-struct nhlt_tdm_config {
- u8 virtual_slot;
- u8 config_type;
-} __packed;
-
-struct nhlt_dmic_array_config {
- struct nhlt_tdm_config tdm_config;
- u8 array_type;
-} __packed;
-
-enum {
- NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
- NHLT_MIC_ARRAY_2CH_BIG = 0xb,
- NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc,
- NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd,
- NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe,
- NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
-};
-
-#endif
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 760bbcf9a469..b99509675d29 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -77,13 +77,7 @@ static int skl_substream_alloc_pages(struct hdac_bus *bus,
hdac_stream(stream)->period_bytes = 0;
hdac_stream(stream)->format_val = 0;
- return snd_pcm_lib_malloc_pages(substream, size);
-}
-
-static int skl_substream_free_pages(struct hdac_bus *bus,
- struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
+ return 0;
}
static void skl_set_pcm_constrains(struct hdac_bus *bus,
@@ -116,7 +110,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
{
struct hdac_bus *bus = dev_get_drvdata(dai->dev);
struct snd_soc_dapm_widget *w;
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
w = dai->playback_widget;
@@ -132,7 +126,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
{
struct hdac_bus *bus = dev_get_drvdata(dev);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
unsigned int format_val;
struct hdac_stream *hstream;
struct hdac_ext_stream *stream;
@@ -224,7 +218,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
struct hdac_ext_stream *stream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct skl_dma_params *dma_params;
- struct skl *skl = get_skl_ctx(dai->dev);
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
struct skl_module_cfg *mconfig;
dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -271,7 +265,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
static int skl_pcm_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct skl *skl = get_skl_ctx(dai->dev);
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
struct skl_module_cfg *mconfig;
int ret;
@@ -288,7 +282,7 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
mconfig->pipe->state == SKL_PIPE_CREATED ||
mconfig->pipe->state == SKL_PIPE_PAUSED)) {
- ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
+ ret = skl_reset_pipe(skl, mconfig->pipe);
if (ret < 0)
return ret;
@@ -350,7 +344,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
struct hdac_bus *bus = dev_get_drvdata(dai->dev);
struct skl_dma_params *dma_params = NULL;
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct skl_module_cfg *mconfig;
dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -370,9 +364,9 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
* CGCTL.MISCBDCGE if disabled by driver
*/
if (!strncmp(dai->name, "Reference Pin", 13) &&
- skl->skl_sst->miscbdcg_disabled) {
- skl->skl_sst->enable_miscbdcge(dai->dev, true);
- skl->skl_sst->miscbdcg_disabled = false;
+ skl->miscbdcg_disabled) {
+ skl->enable_miscbdcge(dai->dev, true);
+ skl->miscbdcg_disabled = false;
}
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
@@ -385,9 +379,8 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct skl *skl = get_skl_ctx(dai->dev);
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
struct skl_module_cfg *mconfig;
int ret;
@@ -396,7 +389,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
if (mconfig) {
- ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
+ ret = skl_reset_pipe(skl, mconfig->pipe);
if (ret < 0)
dev_err(dai->dev, "%s:Reset failed ret =%d",
__func__, ret);
@@ -405,7 +398,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
snd_hdac_stream_cleanup(hdac_stream(stream));
hdac_stream(stream)->prepared = 0;
- return skl_substream_free_pages(bus, substream);
+ return 0;
}
static int skl_be_hw_params(struct snd_pcm_substream *substream,
@@ -471,8 +464,7 @@ static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
- struct skl *skl = get_skl_ctx(dai->dev);
- struct skl_sst *ctx = skl->skl_sst;
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
struct skl_module_cfg *mconfig;
struct hdac_bus *bus = get_bus_ctx(substream);
struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
@@ -515,7 +507,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
ret = skl_decoupled_trigger(substream, cmd);
if (ret < 0)
return ret;
- return skl_run_pipe(ctx, mconfig->pipe);
+ return skl_run_pipe(skl, mconfig->pipe);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -526,7 +518,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
* there are no underrun/overrun in the case if there is a delay
* between the two operations.
*/
- ret = skl_stop_pipe(ctx, mconfig->pipe);
+ ret = skl_stop_pipe(skl, mconfig->pipe);
if (ret < 0)
return ret;
@@ -602,14 +594,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct skl *skl = get_skl_ctx(dai->dev);
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
struct skl_module_cfg *mconfig = NULL;
/* In case of XRUN recovery, reset the FW pipe to clean state */
mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
if (mconfig && !mconfig->pipe->passthru &&
(substream->runtime->status->state == SNDRV_PCM_STATE_XRUN))
- skl_reset_pipe(skl->skl_sst, mconfig->pipe);
+ skl_reset_pipe(skl, mconfig->pipe);
return 0;
}
@@ -1082,7 +1074,8 @@ int skl_dai_load(struct snd_soc_component *cmp, int index,
return 0;
}
-static int skl_platform_open(struct snd_pcm_substream *substream)
+static int skl_platform_soc_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai_link = rtd->dai_link;
@@ -1168,8 +1161,9 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream,
return 0;
}
-static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
+static int skl_platform_soc_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ int cmd)
{
struct hdac_bus *bus = get_bus_ctx(substream);
@@ -1179,8 +1173,9 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
return 0;
}
-static snd_pcm_uframes_t skl_platform_pcm_pointer
- (struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t skl_platform_soc_pointer(
+ struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
{
struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
struct hdac_bus *bus = get_bus_ctx(substream);
@@ -1226,6 +1221,13 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer
return bytes_to_frames(substream->runtime, pos);
}
+static int skl_platform_soc_mmap(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct vm_area_struct *area)
+{
+ return snd_pcm_lib_default_mmap(substream, area);
+}
+
static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
u64 nsec)
{
@@ -1246,8 +1248,10 @@ static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
}
-static int skl_get_time_info(struct snd_pcm_substream *substream,
- struct timespec *system_ts, struct timespec *audio_ts,
+static int skl_platform_soc_get_time_info(
+ struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct timespec64 *system_ts, struct timespec64 *audio_ts,
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
{
@@ -1265,7 +1269,7 @@ static int skl_get_time_info(struct snd_pcm_substream *substream,
if (audio_tstamp_config->report_delay)
nsec = skl_adjust_codec_delay(substream, nsec);
- *audio_ts = ns_to_timespec(nsec);
+ *audio_ts = ns_to_timespec64(nsec);
audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */
@@ -1278,30 +1282,16 @@ static int skl_get_time_info(struct snd_pcm_substream *substream,
return 0;
}
-static const struct snd_pcm_ops skl_platform_ops = {
- .open = skl_platform_open,
- .ioctl = snd_pcm_lib_ioctl,
- .trigger = skl_platform_pcm_trigger,
- .pointer = skl_platform_pcm_pointer,
- .get_time_info = skl_get_time_info,
- .mmap = snd_pcm_lib_default_mmap,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static void skl_pcm_free(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
-static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int skl_platform_soc_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->cpu_dai;
struct hdac_bus *bus = dev_get_drvdata(dai->dev);
struct snd_pcm *pcm = rtd->pcm;
unsigned int size;
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
if (dai->driver->playback.channels_min ||
dai->driver->capture.channels_min) {
@@ -1309,18 +1299,18 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
if (size > MAX_PREALLOC_SIZE)
size = MAX_PREALLOC_SIZE;
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(skl->pci),
- size, MAX_PREALLOC_SIZE);
+ snd_pcm_set_managed_buffer_all(pcm,
+ SNDRV_DMA_TYPE_DEV_SG,
+ &skl->pci->dev,
+ size, MAX_PREALLOC_SIZE);
}
return 0;
}
-static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
+static int skl_get_module_info(struct skl_dev *skl,
+ struct skl_module_cfg *mconfig)
{
- struct skl_sst *ctx = skl->skl_sst;
struct skl_module_inst_id *pin_id;
guid_t *uuid_mod, *uuid_tplg;
struct skl_module *skl_module;
@@ -1329,12 +1319,12 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
uuid_mod = (guid_t *)mconfig->guid;
- if (list_empty(&ctx->uuid_list)) {
- dev_err(ctx->dev, "Module list is empty\n");
+ if (list_empty(&skl->uuid_list)) {
+ dev_err(skl->dev, "Module list is empty\n");
return -EIO;
}
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid_mod, &module->uuid)) {
mconfig->id.module_id = module->id;
if (mconfig->module)
@@ -1361,7 +1351,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
if (skl->nr_modules && ret)
return ret;
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
for (i = 0; i < MAX_IN_QUEUE; i++) {
pin_id = &mconfig->m_in_pin[i].id;
if (guid_equal(&pin_id->mod_uuid, &module->uuid))
@@ -1378,7 +1368,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
return 0;
}
-static int skl_populate_modules(struct skl *skl)
+static int skl_populate_modules(struct skl_dev *skl)
{
struct skl_pipeline *p;
struct skl_pipe_module *m;
@@ -1393,7 +1383,7 @@ static int skl_populate_modules(struct skl *skl)
ret = skl_get_module_info(skl, mconfig);
if (ret < 0) {
- dev_err(skl->skl_sst->dev,
+ dev_err(skl->dev,
"query module info failed\n");
return ret;
}
@@ -1408,7 +1398,7 @@ static int skl_populate_modules(struct skl *skl)
static int skl_platform_soc_probe(struct snd_soc_component *component)
{
struct hdac_bus *bus = dev_get_drvdata(component->dev);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
const struct skl_dsp_ops *ops;
int ret;
@@ -1434,22 +1424,21 @@ static int skl_platform_soc_probe(struct snd_soc_component *component)
* Disable dynamic clock and power gating during firmware
* and library download
*/
- skl->skl_sst->enable_miscbdcge(component->dev, false);
- skl->skl_sst->clock_power_gating(component->dev, false);
+ skl->enable_miscbdcge(component->dev, false);
+ skl->clock_power_gating(component->dev, false);
- ret = ops->init_fw(component->dev, skl->skl_sst);
- skl->skl_sst->enable_miscbdcge(component->dev, true);
- skl->skl_sst->clock_power_gating(component->dev, true);
+ ret = ops->init_fw(component->dev, skl);
+ skl->enable_miscbdcge(component->dev, true);
+ skl->clock_power_gating(component->dev, true);
if (ret < 0) {
dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
return ret;
}
skl_populate_modules(skl);
- skl->skl_sst->update_d0i3c = skl_update_d0i3c;
- skl_dsp_enable_notification(skl->skl_sst, false);
+ skl->update_d0i3c = skl_update_d0i3c;
if (skl->cfg.astate_cfg != NULL) {
- skl_dsp_set_astate_cfg(skl->skl_sst,
+ skl_dsp_set_astate_cfg(skl,
skl->cfg.astate_cfg->count,
skl->cfg.astate_cfg);
}
@@ -1460,10 +1449,10 @@ static int skl_platform_soc_probe(struct snd_soc_component *component)
return 0;
}
-static void skl_pcm_remove(struct snd_soc_component *component)
+static void skl_platform_soc_remove(struct snd_soc_component *component)
{
struct hdac_bus *bus = dev_get_drvdata(component->dev);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
skl_tplg_exit(component, bus);
@@ -1473,10 +1462,13 @@ static void skl_pcm_remove(struct snd_soc_component *component)
static const struct snd_soc_component_driver skl_component = {
.name = "pcm",
.probe = skl_platform_soc_probe,
- .remove = skl_pcm_remove,
- .ops = &skl_platform_ops,
- .pcm_new = skl_pcm_new,
- .pcm_free = skl_pcm_free,
+ .remove = skl_platform_soc_remove,
+ .open = skl_platform_soc_open,
+ .trigger = skl_platform_soc_trigger,
+ .pointer = skl_platform_soc_pointer,
+ .get_time_info = skl_platform_soc_get_time_info,
+ .mmap = skl_platform_soc_mmap,
+ .pcm_construct = skl_platform_soc_new,
.module_get_upon_open = 1, /* increment refcount when a pcm is opened */
};
@@ -1486,7 +1478,7 @@ int skl_platform_register(struct device *dev)
struct snd_soc_dai_driver *dais;
int num_dais = ARRAY_SIZE(skl_platform_dai);
struct hdac_bus *bus = dev_get_drvdata(dev);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
GFP_KERNEL);
@@ -1520,7 +1512,7 @@ err:
int skl_platform_unregister(struct device *dev)
{
struct hdac_bus *bus = dev_get_drvdata(dev);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct skl_module_deferred_bind *modules, *tmp;
if (!list_empty(&skl->bind_list)) {
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
index 5bb6e40d4d3e..1c0e5226cb5b 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
+#include <sound/intel-nhlt.h>
#include "skl.h"
#include "skl-ssp-clk.h"
#include "skl-topology.h"
@@ -101,7 +102,7 @@ static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type)
}
/* Sends dma control IPC to turn the clock ON/OFF */
-static int skl_send_clk_dma_control(struct skl *skl,
+static int skl_send_clk_dma_control(struct skl_dev *skl,
struct skl_clk_rate_cfg_table *rcfg,
u32 vbus_id, u8 clk_type,
bool enable)
@@ -152,7 +153,7 @@ static int skl_send_clk_dma_control(struct skl *skl,
memcpy(i2s_config + sp_cfg->size, data, size);
node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4));
- ret = skl_dsp_set_dma_control(skl->skl_sst, (u32 *)i2s_config,
+ ret = skl_dsp_set_dma_control(skl, (u32 *)i2s_config,
i2s_config_size, node_id);
kfree(i2s_config);
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index 5a2c35f58fda..36f697c61074 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -8,6 +8,7 @@
*/
#include <linux/device.h>
+#include <linux/io.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include "../common/sst-dsp.h"
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 36590c5b4673..225706d148d8 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -12,7 +12,7 @@
#include "../common/sst-dsp.h"
#include "../common/sst-ipc.h"
#include "../common/sst-dsp-priv.h"
-#include "skl-sst-ipc.h"
+#include "skl.h"
/* various timeout values */
#define SKL_DSP_PU_TO 50
@@ -33,7 +33,7 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
*/
void skl_dsp_init_core_state(struct sst_dsp *ctx)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int i;
skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
@@ -48,7 +48,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx)
/* Get the mask for all enabled cores */
unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
unsigned int core_mask, en_cores_mask;
u32 val;
@@ -335,7 +335,7 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
*/
int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int ret = 0;
if (core_id >= skl->cores.count) {
@@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(skl_dsp_get_core);
int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int ret = 0;
if (core_id >= skl->cores.count) {
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index a80219562036..cdfec0fca577 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -15,9 +15,9 @@
#include "skl-sst-cldma.h"
struct sst_dsp;
-struct skl_sst;
struct sst_dsp_device;
struct skl_lib_info;
+struct skl_dev;
/* Intel HD Audio General DSP Registers */
#define SKL_ADSP_GEN_BASE 0x0
@@ -222,32 +222,31 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
int skl_dsp_boot(struct sst_dsp *ctx);
int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_sst **dsp);
+ struct skl_dev **dsp);
int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_sst **dsp);
-int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
-int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
-void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
-void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
+ struct skl_dev **dsp);
+int skl_sst_init_fw(struct device *dev, struct skl_dev *skl);
+int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl);
+void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
+void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
unsigned int offset, int index);
-int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id);
-int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id);
-int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
+int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id);
+int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id);
+int skl_get_pvt_instance_id_map(struct skl_dev *skl,
int module_id, int instance_id);
-void skl_freeup_uuid_list(struct skl_sst *ctx);
+void skl_freeup_uuid_list(struct skl_dev *skl);
int skl_dsp_strip_extended_manifest(struct firmware *fw);
-void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable);
-void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data);
+void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data);
int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
- struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
+ struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
struct sst_dsp_device *skl_dev);
-int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
+int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
struct firmware *stripped_fw,
unsigned int hdr_offset, int index);
void skl_release_library(struct skl_lib_info *linfo, int lib_count);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 2cc8f7d2d319..667cdddc289f 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -281,7 +281,7 @@ void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
size_t tx_size)
{
if (tx_size)
- memcpy(msg->tx_data, tx_data, tx_size);
+ memcpy(msg->tx.data, tx_data, tx_size);
}
static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
@@ -295,10 +295,10 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
/* Lock to be held by caller */
static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
{
- struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header);
+ struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
- if (msg->tx_size)
- sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+ if (msg->tx.size)
+ sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
header->extension);
sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
@@ -345,7 +345,7 @@ out:
int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
struct skl_ipc_header header)
{
- struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
+ struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
@@ -436,7 +436,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
struct ipc_message *msg;
u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
u64 *ipc_header = (u64 *)(&header);
- struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
+ struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
unsigned long flags;
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
@@ -447,11 +447,12 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
return;
}
+ msg->rx.header = *ipc_header;
/* first process the header */
if (reply == IPC_GLB_REPLY_SUCCESS) {
dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
/* copy the rx data from the mailbox */
- sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
+ sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
case IPC_GLB_LOAD_MULTIPLE_MODS:
case IPC_GLB_LOAD_LIBRARY:
@@ -488,7 +489,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
{
struct sst_dsp *dsp = context;
- struct skl_sst *skl = sst_dsp_get_thread_context(dsp);
+ struct skl_dev *skl = sst_dsp_get_thread_context(dsp);
struct sst_generic_ipc *ipc = &skl->ipc;
struct skl_ipc_header header = {0};
u32 hipcie, hipct, hipcte;
@@ -595,7 +596,7 @@ bool skl_ipc_int_status(struct sst_dsp *ctx)
SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
}
-int skl_ipc_init(struct device *dev, struct skl_sst *skl)
+int skl_ipc_init(struct device *dev, struct skl_dev *skl)
{
struct sst_generic_ipc *ipc;
int err;
@@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -646,9 +647,10 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
header.extension = IPC_PPL_LP_MODE(lp_mode);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
return ret;
@@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
header.primary |= IPC_INSTANCE_ID(instance_id);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
return ret;
@@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
u8 instance_id, enum skl_ipc_pipeline_state state)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -692,9 +695,10 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
header.primary |= IPC_INSTANCE_ID(instance_id);
header.primary |= IPC_PPL_STATE(state);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
return ret;
@@ -707,7 +711,7 @@ int
skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -716,8 +720,10 @@ skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
header.primary |= IPC_INSTANCE_ID(instance_id);
header.extension = IPC_DMA_ID(dma_id);
+ request.header = *(u64 *)(&header);
+
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
return ret;
@@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
header.primary |= IPC_INSTANCE_ID(instance_id);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret);
return ret;
@@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
u16 module_id, struct skl_ipc_dxstate_info *dx)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request;
int ret;
header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
@@ -762,10 +769,13 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
header.primary |= IPC_MOD_ID(module_id);
+ request.header = *(u64 *)(&header);
+ request.data = dx;
+ request.size = sizeof(*dx);
+
dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
header.primary, header.extension);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
- dx, sizeof(*dx), NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
return ret;
@@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
struct skl_ipc_init_instance_msg *msg, void *param_data)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request;
int ret;
u32 *buffer = (u32 *)param_data;
/* param_block_size must be in dwords */
@@ -799,10 +809,13 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
header.extension |= IPC_DOMAIN(msg->domain);
+ request.header = *(u64 *)(&header);
+ request.data = param_data;
+ request.size = msg->param_data_size;
+
dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
header.primary, header.extension);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data,
- msg->param_data_size, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: init instance failed\n");
@@ -817,7 +830,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
struct skl_ipc_bind_unbind_msg *msg)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
int ret;
@@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
header.extension |= IPC_DST_QUEUE(msg->dst_queue);
header.extension |= IPC_SRC_QUEUE(msg->src_queue);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
header.extension);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev, "ipc: bind/unbind failed\n");
return ret;
@@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
u8 module_cnt, void *data)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request;
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -862,8 +876,11 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
- ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data,
- (sizeof(u16) * module_cnt));
+ request.header = *(u64 *)(&header);
+ request.data = data;
+ request.size = sizeof(u16) * module_cnt;
+
+ ret = sst_ipc_tx_message_nowait(ipc, request);
if (ret < 0)
dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
@@ -875,7 +892,7 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
void *data)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request;
int ret;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -883,8 +900,11 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
- (sizeof(u16) * module_cnt), NULL, 0);
+ request.header = *(u64 *)(&header);
+ request.data = data;
+ request.size = sizeof(u16) * module_cnt;
+
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0)
dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
@@ -896,7 +916,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
struct skl_ipc_large_config_msg *msg, u32 *param)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request;
int ret = 0;
size_t sz_remaining, tx_size, data_offset;
@@ -923,9 +943,11 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
header.primary, header.extension);
dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
(unsigned)data_offset, (unsigned)tx_size);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
- ((char *)param) + data_offset,
- tx_size, NULL, 0);
+
+ request.header = *(u64 *)(&header);
+ request.data = ((char *)param) + data_offset;
+ request.size = tx_size;
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
if (ret < 0) {
dev_err(ipc->dev,
"ipc: set large config fail, err: %d\n", ret);
@@ -947,12 +969,17 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg, u32 *param)
+ struct skl_ipc_large_config_msg *msg,
+ u32 **payload, size_t *bytes)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
- int ret = 0;
- size_t sz_remaining, rx_size, data_offset;
+ struct sst_ipc_message request, reply = {0};
+ unsigned int *buf;
+ int ret;
+
+ reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
+ if (!reply.data)
+ return -ENOMEM;
header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
@@ -965,33 +992,21 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
header.extension |= IPC_FINAL_BLOCK(1);
header.extension |= IPC_INITIAL_BLOCK(1);
- sz_remaining = msg->param_data_size;
- data_offset = 0;
+ request.header = *(u64 *)&header;
+ request.data = *payload;
+ request.size = *bytes;
+ reply.size = SKL_ADSP_W1_SZ;
- while (sz_remaining != 0) {
- rx_size = sz_remaining > SKL_ADSP_W1_SZ
- ? SKL_ADSP_W1_SZ : sz_remaining;
- if (rx_size == sz_remaining)
- header.extension |= IPC_FINAL_BLOCK(1);
-
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
- ((char *)param) + data_offset,
- msg->param_data_size);
- if (ret < 0) {
- dev_err(ipc->dev,
- "ipc: get large config fail, err: %d\n", ret);
- return ret;
- }
- sz_remaining -= rx_size;
- data_offset = msg->param_data_size - sz_remaining;
+ ret = sst_ipc_tx_message_wait(ipc, request, &reply);
+ if (ret < 0)
+ dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
- /* clear the fields */
- header.extension &= IPC_INITIAL_BLOCK_CLEAR;
- header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
- /* fill the fields */
- header.extension |= IPC_INITIAL_BLOCK(1);
- header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
- }
+ reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
+ buf = krealloc(reply.data, reply.size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ *payload = buf;
+ *bytes = reply.size;
return ret;
}
@@ -1001,7 +1016,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
u8 dma_id, u8 table_id, bool wait)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret = 0;
header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -1009,12 +1024,12 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
header.primary |= IPC_MOD_INSTANCE_ID(table_id);
header.primary |= IPC_MOD_ID(dma_id);
+ request.header = *(u64 *)(&header);
if (wait)
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
- NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_wait(ipc, request, NULL);
else
- ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
+ ret = sst_ipc_tx_message_nowait(ipc, request);
if (ret < 0)
dev_err(ipc->dev, "ipc: load lib failed\n");
@@ -1026,7 +1041,7 @@ EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
{
struct skl_ipc_header header = {0};
- u64 *ipc_header = (u64 *)(&header);
+ struct sst_ipc_message request = {0};
int ret;
header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
@@ -1037,6 +1052,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
header.extension = IPC_D0IX_WAKE(msg->wake);
header.extension |= IPC_D0IX_STREAMING(msg->streaming);
+ request.header = *(u64 *)(&header);
dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
header.primary, header.extension);
@@ -1044,7 +1060,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
/*
* Use the nopm IPC here as we dont want it checking for D0iX
*/
- ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0);
+ ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
if (ret < 0)
dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9c31a48e99dd..08ac31778325 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -10,9 +10,9 @@
#include <linux/irqreturn.h>
#include "../common/sst-ipc.h"
+#include "skl-sst-dsp.h"
struct sst_dsp;
-struct skl_sst;
struct sst_generic_ipc;
enum skl_ipc_pipeline_state {
@@ -67,54 +67,6 @@ struct skl_lib_info {
const struct firmware *fw;
};
-struct skl_sst {
- struct device *dev;
- struct sst_dsp *dsp;
-
- /* boot */
- wait_queue_head_t boot_wait;
- bool boot_complete;
-
- /* module load */
- wait_queue_head_t mod_load_wait;
- bool mod_load_complete;
- bool mod_load_status;
-
- /* IPC messaging */
- struct sst_generic_ipc ipc;
-
- /* callback for miscbdge */
- void (*enable_miscbdcge)(struct device *dev, bool enable);
- /* Is CGCTL.MISCBDCGE disabled */
- bool miscbdcg_disabled;
-
- /* Populate module information */
- struct list_head uuid_list;
-
- /* Is firmware loaded */
- bool fw_loaded;
-
- /* first boot ? */
- bool is_first_boot;
-
- /* multi-core */
- struct skl_dsp_cores cores;
-
- /* library info */
- struct skl_lib_info lib_info[SKL_MAX_LIB];
- int lib_count;
-
- /* Callback to update D0i3C register */
- void (*update_d0i3c)(struct device *dev, bool enable);
-
- struct skl_d0i3_data d0i3;
-
- const struct skl_dsp_ops *dsp_ops;
-
- /* Callback to update dynamic clock and power gating registers */
- void (*clock_power_gating)(struct device *dev, bool enable);
-};
-
struct skl_ipc_init_instance_msg {
u32 module_id;
u32 instance_id;
@@ -187,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
struct skl_ipc_large_config_msg *msg, u32 *param);
int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg, u32 *param);
+ struct skl_ipc_large_config_msg *msg,
+ u32 **payload, size_t *bytes);
int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
u8 dma_id, u8 table_id, bool wait);
@@ -204,7 +157,7 @@ void skl_ipc_int_disable(struct sst_dsp *dsp);
bool skl_ipc_int_status(struct sst_dsp *dsp);
void skl_ipc_free(struct sst_generic_ipc *ipc);
-int skl_ipc_init(struct device *dev, struct skl_sst *skl);
+int skl_ipc_init(struct device *dev, struct skl_dev *skl);
void skl_clear_module_cnt(struct sst_dsp *ctx);
void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index 928c677b506c..d43cbf4a71ef 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -8,10 +8,9 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/uuid.h>
-#include "skl-sst-dsp.h"
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
-#include "skl-sst-ipc.h"
+#include "skl.h"
#define DEFAULT_HASH_SHA256_LEN 32
@@ -99,12 +98,12 @@ static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
return -EINVAL;
}
-int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
+int skl_get_pvt_instance_id_map(struct skl_dev *skl,
int module_id, int instance_id)
{
struct uuid_module *module;
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
if (module->id == module_id)
return skl_get_pvtid_map(module, instance_id);
}
@@ -163,19 +162,19 @@ static inline int skl_pvtid_128(struct uuid_module *module)
/**
* skl_get_pvt_id: generate a private id for use as module id
*
- * @ctx: driver context
+ * @skl: driver context
* @uuid_mod: module's uuid
* @instance_id: module's instance id
*
* This generates a 128 bit private unique id for a module TYPE so that
* module instance is unique
*/
-int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id)
+int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id)
{
struct uuid_module *module;
int pvt_id;
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid_mod, &module->uuid)) {
pvt_id = skl_pvtid_128(module);
@@ -194,18 +193,18 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
/**
* skl_put_pvt_id: free up the private id allocated
*
- * @ctx: driver context
+ * @skl: driver context
* @uuid_mod: module's uuid
* @pvt_id: module pvt id
*
* This frees a 128 bit private unique id previously generated
*/
-int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id)
+int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id)
{
int i;
struct uuid_module *module;
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid_mod, &module->uuid)) {
if (*pvt_id != 0)
@@ -234,7 +233,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
struct adsp_module_entry *mod_entry;
int i, num_entry, size;
const char *buf;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct uuid_module *module;
struct firmware stripped_fw;
unsigned int safe_file;
@@ -317,11 +316,11 @@ free_uuid_list:
return ret;
}
-void skl_freeup_uuid_list(struct skl_sst *ctx)
+void skl_freeup_uuid_list(struct skl_dev *skl)
{
struct uuid_module *uuid, *_uuid;
- list_for_each_entry_safe(uuid, _uuid, &ctx->uuid_list, list) {
+ list_for_each_entry_safe(uuid, _uuid, &skl->uuid_list, list) {
list_del(&uuid->list);
kfree(uuid);
}
@@ -355,16 +354,12 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
}
int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
- struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
+ struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
struct sst_dsp_device *skl_dev)
{
- struct skl_sst *skl;
+ struct skl_dev *skl = *dsp;
struct sst_dsp *sst;
- skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
- if (skl == NULL)
- return -ENOMEM;
-
skl->dev = dev;
skl_dev->thread_context = skl;
INIT_LIST_HEAD(&skl->uuid_list);
@@ -381,13 +376,11 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
INIT_LIST_HEAD(&sst->module_list);
skl->is_first_boot = true;
- if (dsp)
- *dsp = skl;
return 0;
}
-int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
+int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
struct firmware *stripped_fw,
unsigned int hdr_offset, int index)
{
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 70c3a604c381..61a8e4756a2b 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -16,7 +16,7 @@
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
#include "../common/sst-ipc.h"
-#include "skl-sst-ipc.h"
+#include "skl.h"
#define SKL_BASEFW_TIMEOUT 300
#define SKL_INIT_TIMEOUT 1000
@@ -66,7 +66,7 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
static int skl_load_base_firmware(struct sst_dsp *ctx)
{
int ret = 0, i;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct firmware stripped_fw;
u32 reg;
@@ -161,7 +161,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
{
int ret;
struct skl_ipc_dxstate_info dx;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
/* If core0 is being turned on, we need to load the FW */
@@ -215,7 +215,7 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
{
int ret;
struct skl_ipc_dxstate_info dx;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
dx.core_mask = core_mask;
@@ -332,7 +332,7 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
u32 size, u16 mod_id, u8 table_id, bool is_module)
{
int ret, bytes_left, curr_pos;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
skl->mod_load_complete = false;
bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false);
@@ -384,7 +384,7 @@ out:
static int
skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
{
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
struct firmware stripped_fw;
int ret, i;
@@ -413,8 +413,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
int ret = 0;
char mod_name[64]; /* guid str = 32 chars + 4 hyphens */
- snprintf(mod_name, sizeof(mod_name), "%s%pUL%s",
- "intel/dsp_fw_", guid, ".bin");
+ snprintf(mod_name, sizeof(mod_name), "intel/dsp_fw_%pUL.bin", guid);
module_entry = skl_module_get_from_id(ctx, mod_id);
if (module_entry == NULL) {
@@ -443,7 +442,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
{
int usage_cnt;
- struct skl_sst *skl = ctx->thread_context;
+ struct skl_dev *skl = ctx->thread_context;
int ret = 0;
usage_cnt = skl_put_module(ctx, mod_id);
@@ -518,9 +517,10 @@ static struct sst_dsp_device skl_dev = {
};
int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp)
+ const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
+ struct skl_dev **dsp)
{
- struct skl_sst *skl;
+ struct skl_dev *skl;
struct sst_dsp *sst;
int ret;
@@ -554,10 +554,10 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
}
EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
-int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
+int skl_sst_init_fw(struct device *dev, struct skl_dev *skl)
{
int ret;
- struct sst_dsp *sst = ctx->dsp;
+ struct sst_dsp *sst = skl->dsp;
ret = sst->fw_ops.load_fw(sst);
if (ret < 0) {
@@ -567,32 +567,32 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
skl_dsp_init_core_state(sst);
- if (ctx->lib_count > 1) {
- ret = sst->fw_ops.load_library(sst, ctx->lib_info,
- ctx->lib_count);
+ if (skl->lib_count > 1) {
+ ret = sst->fw_ops.load_library(sst, skl->lib_info,
+ skl->lib_count);
if (ret < 0) {
dev_err(dev, "Load Library failed : %x\n", ret);
return ret;
}
}
- ctx->is_first_boot = false;
+ skl->is_first_boot = false;
return 0;
}
EXPORT_SYMBOL_GPL(skl_sst_init_fw);
-void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
+void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
{
- if (ctx->dsp->fw)
- release_firmware(ctx->dsp->fw);
- skl_clear_module_table(ctx->dsp);
- skl_freeup_uuid_list(ctx);
- skl_ipc_free(&ctx->ipc);
- ctx->dsp->ops->free(ctx->dsp);
- if (ctx->boot_complete) {
- ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
- skl_cldma_int_disable(ctx->dsp);
+ if (skl->dsp->fw)
+ release_firmware(skl->dsp->fw);
+ skl_clear_module_table(skl->dsp);
+ skl_freeup_uuid_list(skl);
+ skl_ipc_free(&skl->ipc);
+ skl->dsp->ops->free(skl->dsp);
+ if (skl->boot_complete) {
+ skl->dsp->cl_dev.ops.cl_cleanup_controller(skl->dsp);
+ skl_cldma_int_disable(skl->dsp);
}
}
EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 6241e35213af..69cd7a81bf2a 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/firmware.h>
#include <linux/uuid.h>
+#include <sound/intel-nhlt.h>
#include <sound/soc.h>
#include <sound/soc-topology.h>
#include <uapi/sound/snd_sst_tokens.h>
@@ -45,9 +46,9 @@ static const int mic_quatro_list[][SKL_CH_QUATRO] = {
#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \
((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq))
-void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps)
+void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps)
{
- struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3;
+ struct skl_d0i3_data *d0i3 = &skl->d0i3;
switch (caps) {
case SKL_D0I3_NONE:
@@ -64,9 +65,9 @@ void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps)
}
}
-void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
+void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps)
{
- struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3;
+ struct skl_d0i3_data *d0i3 = &skl->d0i3;
switch (caps) {
case SKL_D0I3_NONE:
@@ -109,118 +110,23 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
}
}
-/*
- * Each pipelines needs memory to be allocated. Check if we have free memory
- * from available pool.
- */
-static bool skl_is_pipe_mem_avail(struct skl *skl,
- struct skl_module_cfg *mconfig)
-{
- struct skl_sst *ctx = skl->skl_sst;
-
- if (skl->resource.mem + mconfig->pipe->memory_pages >
- skl->resource.max_mem) {
- dev_err(ctx->dev,
- "%s: module_id %d instance %d\n", __func__,
- mconfig->id.module_id,
- mconfig->id.instance_id);
- dev_err(ctx->dev,
- "exceeds ppl memory available %d mem %d\n",
- skl->resource.max_mem, skl->resource.mem);
- return false;
- } else {
- return true;
- }
-}
-
-/*
- * Add the mem to the mem pool. This is freed when pipe is deleted.
- * Note: DSP does actual memory management we only keep track for complete
- * pool
- */
-static void skl_tplg_alloc_pipe_mem(struct skl *skl,
- struct skl_module_cfg *mconfig)
-{
- skl->resource.mem += mconfig->pipe->memory_pages;
-}
-
-/*
- * Pipeline needs needs DSP CPU resources for computation, this is
- * quantified in MCPS (Million Clocks Per Second) required for module/pipe
- *
- * Each pipelines needs mcps to be allocated. Check if we have mcps for this
- * pipe.
- */
-
-static bool skl_is_pipe_mcps_avail(struct skl *skl,
- struct skl_module_cfg *mconfig)
-{
- struct skl_sst *ctx = skl->skl_sst;
- u8 res_idx = mconfig->res_idx;
- struct skl_module_res *res = &mconfig->module->resources[res_idx];
-
- if (skl->resource.mcps + res->cps > skl->resource.max_mcps) {
- dev_err(ctx->dev,
- "%s: module_id %d instance %d\n", __func__,
- mconfig->id.module_id, mconfig->id.instance_id);
- dev_err(ctx->dev,
- "exceeds ppl mcps available %d > mem %d\n",
- skl->resource.max_mcps, skl->resource.mcps);
- return false;
- } else {
- return true;
- }
-}
-
-static void skl_tplg_alloc_pipe_mcps(struct skl *skl,
- struct skl_module_cfg *mconfig)
-{
- u8 res_idx = mconfig->res_idx;
- struct skl_module_res *res = &mconfig->module->resources[res_idx];
-
- skl->resource.mcps += res->cps;
-}
-
-/*
- * Free the mcps when tearing down
- */
-static void
-skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
-{
- u8 res_idx = mconfig->res_idx;
- struct skl_module_res *res = &mconfig->module->resources[res_idx];
-
- skl->resource.mcps -= res->cps;
-}
-
-/*
- * Free the memory when tearing down
- */
-static void
-skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig)
-{
- skl->resource.mem -= mconfig->pipe->memory_pages;
-}
-
-
-static void skl_dump_mconfig(struct skl_sst *ctx,
- struct skl_module_cfg *mcfg)
+static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg)
{
struct skl_module_iface *iface = &mcfg->module->formats[0];
- dev_dbg(ctx->dev, "Dumping config\n");
- dev_dbg(ctx->dev, "Input Format:\n");
- dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels);
- dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq);
- dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg);
- dev_dbg(ctx->dev, "valid bit depth = %d\n",
+ dev_dbg(skl->dev, "Dumping config\n");
+ dev_dbg(skl->dev, "Input Format:\n");
+ dev_dbg(skl->dev, "channels = %d\n", iface->inputs[0].fmt.channels);
+ dev_dbg(skl->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq);
+ dev_dbg(skl->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg);
+ dev_dbg(skl->dev, "valid bit depth = %d\n",
iface->inputs[0].fmt.valid_bit_depth);
- dev_dbg(ctx->dev, "Output Format:\n");
- dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels);
- dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq);
- dev_dbg(ctx->dev, "valid bit depth = %d\n",
+ dev_dbg(skl->dev, "Output Format:\n");
+ dev_dbg(skl->dev, "channels = %d\n", iface->outputs[0].fmt.channels);
+ dev_dbg(skl->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq);
+ dev_dbg(skl->dev, "valid bit depth = %d\n",
iface->outputs[0].fmt.valid_bit_depth);
- dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg);
+ dev_dbg(skl->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg);
}
static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs)
@@ -322,7 +228,7 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
* params, so once we have calculate params, we need buffer calculation as
* well.
*/
-static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
+static void skl_tplg_update_buffer_size(struct skl_dev *skl,
struct skl_module_cfg *mcfg)
{
int multiplier = 1;
@@ -374,13 +280,12 @@ static u8 skl_tplg_be_dev_type(int dev_type)
}
static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
- struct skl_sst *ctx)
+ struct skl_dev *skl)
{
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);
u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type);
int fmt_idx = m_cfg->fmt_idx;
struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx];
@@ -389,7 +294,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
if (m_cfg->formats_config.caps_size > 0)
return 0;
- dev_dbg(ctx->dev, "Applying default cfg blob\n");
+ dev_dbg(skl->dev, "Applying default cfg blob\n");
switch (m_cfg->dev_type) {
case SKL_DEVICE_DMIC:
link_type = NHLT_LINK_DMIC;
@@ -425,9 +330,9 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
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",
+ dev_err(skl->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",
+ dev_err(skl->dev, "PCM: ch %d, freq %d, fmt %d\n",
ch, s_freq, s_fmt);
return -EIO;
}
@@ -436,7 +341,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
}
static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
- struct skl_sst *ctx)
+ struct skl_dev *skl)
{
struct skl_module_cfg *m_cfg = w->priv;
struct skl_pipe_params *params = m_cfg->pipe->p_params;
@@ -446,10 +351,10 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
if (!m_cfg->params_fixup)
return;
- dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n",
+ dev_dbg(skl->dev, "Mconfig for widget=%s BEFORE updation\n",
w->name);
- skl_dump_mconfig(ctx, m_cfg);
+ skl_dump_mconfig(skl, m_cfg);
if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
is_fe = true;
@@ -457,12 +362,12 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
is_fe = false;
skl_tplg_update_params_fixup(m_cfg, params, is_fe);
- skl_tplg_update_buffer_size(ctx, m_cfg);
+ skl_tplg_update_buffer_size(skl, m_cfg);
- dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n",
+ dev_dbg(skl->dev, "Mconfig for widget=%s AFTER updation\n",
w->name);
- skl_dump_mconfig(ctx, m_cfg);
+ skl_dump_mconfig(skl, m_cfg);
}
/*
@@ -471,7 +376,7 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
* set module params will be done after module is initialised.
*/
static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
- struct skl_sst *ctx)
+ struct skl_dev *skl)
{
int i, ret;
struct skl_module_cfg *mconfig = w->priv;
@@ -483,7 +388,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
if (mconfig->formats_config.caps_size > 0 &&
mconfig->formats_config.set_params == SKL_PARAM_SET) {
sp_cfg = &mconfig->formats_config;
- ret = skl_set_module_params(ctx, sp_cfg->caps,
+ ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size,
sp_cfg->param_id, mconfig);
if (ret < 0)
@@ -497,7 +402,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
bc = (struct skl_algo_data *)sb->dobj.private;
if (bc->set_params == SKL_PARAM_SET) {
- ret = skl_set_module_params(ctx,
+ ret = skl_set_module_params(skl,
(u32 *)bc->params, bc->size,
bc->param_id, mconfig);
if (ret < 0)
@@ -542,15 +447,15 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
return 0;
}
-static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe,
+static int skl_tplg_module_prepare(struct skl_dev *skl, struct skl_pipe *pipe,
struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg)
{
switch (mcfg->dev_type) {
case SKL_DEVICE_HDAHOST:
- return skl_pcm_host_dma_prepare(ctx->dev, pipe->p_params);
+ return skl_pcm_host_dma_prepare(skl->dev, pipe->p_params);
case SKL_DEVICE_HDALINK:
- return skl_pcm_link_dma_prepare(ctx->dev, pipe->p_params);
+ return skl_pcm_link_dma_prepare(skl->dev, pipe->p_params);
}
return 0;
@@ -562,12 +467,11 @@ static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe,
* skl_init_module() routine, so invoke that for all modules in a pipeline
*/
static int
-skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
+skl_tplg_init_pipe_modules(struct skl_dev *skl, struct skl_pipe *pipe)
{
struct skl_pipe_module *w_module;
struct snd_soc_dapm_widget *w;
struct skl_module_cfg *mconfig;
- struct skl_sst *ctx = skl->skl_sst;
u8 cfg_idx;
int ret = 0;
@@ -578,7 +482,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
/* check if module ids are populated */
if (mconfig->id.module_id < 0) {
- dev_err(skl->skl_sst->dev,
+ dev_err(skl->dev,
"module %pUL id not populated\n",
(guid_t *)mconfig->guid);
return -EIO;
@@ -588,12 +492,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx;
mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx;
- /* check resource available */
- if (!skl_is_pipe_mcps_avail(skl, mconfig))
- return -ENOMEM;
-
- if (mconfig->module->loadable && ctx->dsp->fw_ops.load_mod) {
- ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
+ if (mconfig->module->loadable && skl->dsp->fw_ops.load_mod) {
+ ret = skl->dsp->fw_ops.load_mod(skl->dsp,
mconfig->id.module_id, mconfig->guid);
if (ret < 0)
return ret;
@@ -602,50 +502,50 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
}
/* prepare the DMA if the module is gateway cpr */
- ret = skl_tplg_module_prepare(ctx, pipe, w, mconfig);
+ ret = skl_tplg_module_prepare(skl, pipe, w, mconfig);
if (ret < 0)
return ret;
/* update blob if blob is null for be with default value */
- skl_tplg_update_be_blob(w, ctx);
+ skl_tplg_update_be_blob(w, skl);
/*
* apply fix/conversion to module params based on
* FE/BE params
*/
- skl_tplg_update_module_params(w, ctx);
+ skl_tplg_update_module_params(w, skl);
uuid_mod = (guid_t *)mconfig->guid;
- mconfig->id.pvt_id = skl_get_pvt_id(ctx, uuid_mod,
+ mconfig->id.pvt_id = skl_get_pvt_id(skl, uuid_mod,
mconfig->id.instance_id);
if (mconfig->id.pvt_id < 0)
return ret;
skl_tplg_set_module_init_data(w);
- ret = skl_dsp_get_core(ctx->dsp, mconfig->core_id);
+ ret = skl_dsp_get_core(skl->dsp, mconfig->core_id);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to wake up core %d ret=%d\n",
+ dev_err(skl->dev, "Failed to wake up core %d ret=%d\n",
mconfig->core_id, ret);
return ret;
}
- ret = skl_init_module(ctx, mconfig);
+ ret = skl_init_module(skl, mconfig);
if (ret < 0) {
- skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
+ skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
goto err;
}
- skl_tplg_alloc_pipe_mcps(skl, mconfig);
- ret = skl_tplg_set_module_params(w, ctx);
+
+ ret = skl_tplg_set_module_params(w, skl);
if (ret < 0)
goto err;
}
return 0;
err:
- skl_dsp_put_core(ctx->dsp, mconfig->core_id);
+ skl_dsp_put_core(skl->dsp, mconfig->core_id);
return ret;
}
-static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
+static int skl_tplg_unload_pipe_modules(struct skl_dev *skl,
struct skl_pipe *pipe)
{
int ret = 0;
@@ -657,19 +557,19 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
mconfig = w_module->w->priv;
uuid_mod = (guid_t *)mconfig->guid;
- if (mconfig->module->loadable && ctx->dsp->fw_ops.unload_mod &&
+ if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod &&
mconfig->m_state > SKL_MODULE_UNINIT) {
- ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp,
+ ret = skl->dsp->fw_ops.unload_mod(skl->dsp,
mconfig->id.module_id);
if (ret < 0)
return -EIO;
}
- skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
+ skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
- ret = skl_dsp_put_core(ctx->dsp, mconfig->core_id);
+ ret = skl_dsp_put_core(skl->dsp, mconfig->core_id);
if (ret < 0) {
/* don't return; continue with other modules */
- dev_err(ctx->dev, "Failed to sleep core %d ret=%d\n",
+ dev_err(skl->dev, "Failed to sleep core %d ret=%d\n",
mconfig->core_id, ret);
}
}
@@ -686,9 +586,8 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
* 0th configuratation by default for such pipes.
*/
static int
-skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
+skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig)
{
- struct skl_sst *ctx = skl->skl_sst;
struct skl_pipe *pipe = mconfig->pipe;
struct skl_pipe_params *params = pipe->p_params;
struct skl_path_config *pconfig = &pipe->configs[0];
@@ -702,7 +601,7 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
}
if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) {
- dev_dbg(ctx->dev, "No conn_type detected, take 0th config\n");
+ dev_dbg(skl->dev, "No conn_type detected, take 0th config\n");
pipe->cur_config_idx = 0;
pipe->memory_pages = pconfig->mem_pages;
@@ -726,13 +625,13 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
fmt->channels, fmt->freq, fmt->bps)) {
pipe->cur_config_idx = i;
pipe->memory_pages = pconfig->mem_pages;
- dev_dbg(ctx->dev, "Using pipe config: %d\n", i);
+ dev_dbg(skl->dev, "Using pipe config: %d\n", i);
return 0;
}
}
- dev_err(ctx->dev, "Invalid pipe config: %d %d %d for pipe: %d\n",
+ dev_err(skl->dev, "Invalid pipe config: %d %d %d for pipe: %d\n",
params->ch, params->s_freq, params->s_fmt, pipe->ppl_id);
return -EINVAL;
}
@@ -740,44 +639,32 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
/*
* Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
* need create the pipeline. So we do following:
- * - check the resources
* - Create the pipeline
* - Initialize the modules in pipeline
* - finally bind all modules together
*/
static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
int ret;
struct skl_module_cfg *mconfig = w->priv;
struct skl_pipe_module *w_module;
struct skl_pipe *s_pipe = mconfig->pipe;
struct skl_module_cfg *src_module = NULL, *dst_module, *module;
- struct skl_sst *ctx = skl->skl_sst;
struct skl_module_deferred_bind *modules;
ret = skl_tplg_get_pipe_config(skl, mconfig);
if (ret < 0)
return ret;
- /* check resource available */
- if (!skl_is_pipe_mcps_avail(skl, mconfig))
- return -EBUSY;
-
- if (!skl_is_pipe_mem_avail(skl, mconfig))
- return -ENOMEM;
-
/*
* Create a list of modules for pipe.
* This list contains modules from source to sink
*/
- ret = skl_create_pipeline(ctx, mconfig->pipe);
+ ret = skl_create_pipeline(skl, mconfig->pipe);
if (ret < 0)
return ret;
- skl_tplg_alloc_pipe_mem(skl, mconfig);
- skl_tplg_alloc_pipe_mcps(skl, mconfig);
-
/* Init all pipe modules from source to sink */
ret = skl_tplg_init_pipe_modules(skl, s_pipe);
if (ret < 0)
@@ -792,7 +679,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
continue;
}
- ret = skl_bind_modules(ctx, src_module, dst_module);
+ ret = skl_bind_modules(skl, src_module, dst_module);
if (ret < 0)
return ret;
@@ -810,7 +697,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
list_for_each_entry(modules, &skl->bind_list, node) {
module = w_module->w->priv;
if (modules->dst == module)
- skl_bind_modules(ctx, modules->src,
+ skl_bind_modules(skl, modules->src,
modules->dst);
}
}
@@ -818,7 +705,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
return 0;
}
-static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
+static int skl_fill_sink_instance_id(struct skl_dev *skl, u32 *params,
int size, struct skl_module_cfg *mcfg)
{
int i, pvt_id;
@@ -829,7 +716,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
struct skl_mod_inst_map *inst = kpb_params->u.map;
for (i = 0; i < kpb_params->num_modules; i++) {
- pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
+ pvt_id = skl_get_pvt_instance_id_map(skl, inst->mod_id,
inst->inst_id);
if (pvt_id < 0)
return -EINVAL;
@@ -849,7 +736,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
* 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)
+ struct skl_module_cfg *mcfg, struct skl_dev *skl)
{
int i, ret;
struct skl_module_cfg *mconfig = w->priv;
@@ -876,7 +763,7 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
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,
+ ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size,
sp_cfg->param_id, mconfig);
if (ret < 0)
@@ -894,10 +781,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
if (!params)
return -ENOMEM;
- skl_fill_sink_instance_id(ctx, params, bc->max,
+ skl_fill_sink_instance_id(skl, params, bc->max,
mconfig);
- ret = skl_set_module_params(ctx, params,
+ ret = skl_set_module_params(skl, params,
bc->max, bc->param_id, mconfig);
kfree(params);
@@ -910,11 +797,11 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
return 0;
}
-static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid)
+static int skl_get_module_id(struct skl_dev *skl, guid_t *uuid)
{
struct uuid_module *module;
- list_for_each_entry(module, &ctx->uuid_list, list) {
+ list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid, &module->uuid))
return module->id;
}
@@ -922,7 +809,7 @@ static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid)
return -EINVAL;
}
-static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
+static int skl_tplg_find_moduleid_from_uuid(struct skl_dev *skl,
const struct snd_kcontrol_new *k)
{
struct soc_bytes_ext *sb = (void *) k->private_value;
@@ -942,7 +829,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
params->num_modules = uuid_params->num_modules;
for (i = 0; i < uuid_params->num_modules; i++) {
- module_id = skl_get_module_id(skl->skl_sst,
+ module_id = skl_get_module_id(skl,
&uuid_params->u.map_uuid[i].mod_uuid);
if (module_id < 0) {
devm_kfree(bus->dev, params);
@@ -966,7 +853,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
* Retrieve the module id from UUID mentioned in the
* post bind params
*/
-void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
struct snd_soc_dapm_widget *w)
{
struct skl_module_cfg *mconfig = w->priv;
@@ -985,12 +872,12 @@ void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
(skl_tplg_find_moduleid_from_uuid(skl,
&w->kcontrol_news[i]) < 0))
- dev_err(skl->skl_sst->dev,
+ dev_err(skl->dev,
"%s: invalid kpb post bind params\n",
__func__);
}
-static int skl_tplg_module_add_deferred_bind(struct skl *skl,
+static int skl_tplg_module_add_deferred_bind(struct skl_dev *skl,
struct skl_module_cfg *src, struct skl_module_cfg *dst)
{
struct skl_module_deferred_bind *m_list, *modules;
@@ -1028,26 +915,27 @@ static int skl_tplg_module_add_deferred_bind(struct skl *skl,
}
static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
- struct skl *skl,
+ struct skl_dev *skl,
struct snd_soc_dapm_widget *src_w,
struct skl_module_cfg *src_mconfig)
{
struct snd_soc_dapm_path *p;
struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
struct skl_module_cfg *sink_mconfig;
- struct skl_sst *ctx = skl->skl_sst;
int ret;
snd_soc_dapm_widget_for_each_sink_path(w, p) {
if (!p->connect)
continue;
- dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
- dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
+ dev_dbg(skl->dev,
+ "%s: src widget=%s\n", __func__, w->name);
+ dev_dbg(skl->dev,
+ "%s: sink widget=%s\n", __func__, p->sink->name);
next_sink = p->sink;
- if (!is_skl_dsp_widget_type(p->sink, ctx->dev))
+ if (!is_skl_dsp_widget_type(p->sink, skl->dev))
return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
/*
@@ -1056,7 +944,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
* they are ones used for SKL so check that first
*/
if ((p->sink->priv != NULL) &&
- is_skl_dsp_widget_type(p->sink, ctx->dev)) {
+ is_skl_dsp_widget_type(p->sink, skl->dev)) {
sink = p->sink;
sink_mconfig = sink->priv;
@@ -1088,19 +976,21 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
continue;
/* Bind source to sink, mixin is always source */
- ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
+ ret = skl_bind_modules(skl, 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);
+ skl_tplg_set_module_bind_params(src_w,
+ src_mconfig, skl);
+ skl_tplg_set_module_bind_params(sink,
+ sink_mconfig, skl);
/* Start sinks pipe first */
if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
if (sink_mconfig->pipe->conn_type !=
SKL_PIPE_CONN_TYPE_FE)
- ret = skl_run_pipe(ctx,
+ ret = skl_run_pipe(skl,
sink_mconfig->pipe);
if (ret)
return ret;
@@ -1125,10 +1015,9 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
* - Then run current pipe
*/
static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
struct skl_module_cfg *src_mconfig;
- struct skl_sst *ctx = skl->skl_sst;
int ret = 0;
src_mconfig = w->priv;
@@ -1144,25 +1033,24 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
/* Start source pipe last after starting all sinks */
if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
- return skl_run_pipe(ctx, src_mconfig->pipe);
+ return skl_run_pipe(skl, src_mconfig->pipe);
return 0;
}
static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
- struct snd_soc_dapm_widget *w, struct skl *skl)
+ struct snd_soc_dapm_widget *w, struct skl_dev *skl)
{
struct snd_soc_dapm_path *p;
struct snd_soc_dapm_widget *src_w = NULL;
- struct skl_sst *ctx = skl->skl_sst;
snd_soc_dapm_widget_for_each_source_path(w, p) {
src_w = p->source;
if (!p->connect)
continue;
- dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
- dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
+ dev_dbg(skl->dev, "sink widget=%s\n", w->name);
+ dev_dbg(skl->dev, "src widget=%s\n", p->source->name);
/*
* here we will check widgets in sink pipelines, so that can
@@ -1170,7 +1058,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
* ones used for SKL so check that first
*/
if ((p->source->priv != NULL) &&
- is_skl_dsp_widget_type(p->source, ctx->dev)) {
+ is_skl_dsp_widget_type(p->source, skl->dev)) {
return p->source;
}
}
@@ -1191,12 +1079,11 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
* - start this pipeline
*/
static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
int ret = 0;
struct snd_soc_dapm_widget *source, *sink;
struct skl_module_cfg *src_mconfig, *sink_mconfig;
- struct skl_sst *ctx = skl->skl_sst;
int src_pipe_started = 0;
sink = w;
@@ -1222,16 +1109,16 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
}
if (src_pipe_started) {
- ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
+ ret = skl_bind_modules(skl, src_mconfig, sink_mconfig);
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);
+ skl_tplg_set_module_bind_params(source, src_mconfig, skl);
+ skl_tplg_set_module_bind_params(sink, sink_mconfig, skl);
if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
- ret = skl_run_pipe(ctx, sink_mconfig->pipe);
+ ret = skl_run_pipe(skl, sink_mconfig->pipe);
}
return ret;
@@ -1244,16 +1131,15 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
* - unbind with source pipelines if still connected
*/
static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
struct skl_module_cfg *src_mconfig, *sink_mconfig;
int ret = 0, i;
- struct skl_sst *ctx = skl->skl_sst;
sink_mconfig = w->priv;
/* Stop the pipe */
- ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
+ ret = skl_stop_pipe(skl, sink_mconfig->pipe);
if (ret)
return ret;
@@ -1263,7 +1149,7 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
if (!src_mconfig)
continue;
- ret = skl_unbind_modules(ctx,
+ ret = skl_unbind_modules(skl,
src_mconfig, sink_mconfig);
}
}
@@ -1273,28 +1159,22 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
/*
* in the Post-PMD event of mixer we need to do following:
- * - Free the mcps used
- * - Free the mem used
* - Unbind the modules within the pipeline
* - Delete the pipeline (modules are not required to be explicitly
* deleted, pipeline delete is enough here
*/
static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
struct skl_module_cfg *mconfig = w->priv;
struct skl_pipe_module *w_module;
struct skl_module_cfg *src_module = NULL, *dst_module;
- struct skl_sst *ctx = skl->skl_sst;
struct skl_pipe *s_pipe = mconfig->pipe;
struct skl_module_deferred_bind *modules, *tmp;
if (s_pipe->state == SKL_PIPE_INVALID)
return -EINVAL;
- skl_tplg_free_pipe_mcps(skl, mconfig);
- skl_tplg_free_pipe_mem(skl, mconfig);
-
list_for_each_entry(w_module, &s_pipe->w_list, node) {
if (list_empty(&skl->bind_list))
break;
@@ -1307,7 +1187,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
* modules from deferred bind list.
*/
if (modules->dst == src_module) {
- skl_unbind_modules(ctx, modules->src,
+ skl_unbind_modules(skl, modules->src,
modules->dst);
}
@@ -1327,44 +1207,40 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
list_for_each_entry(w_module, &s_pipe->w_list, node) {
dst_module = w_module->w->priv;
- if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
- skl_tplg_free_pipe_mcps(skl, dst_module);
if (src_module == NULL) {
src_module = dst_module;
continue;
}
- skl_unbind_modules(ctx, src_module, dst_module);
+ skl_unbind_modules(skl, src_module, dst_module);
src_module = dst_module;
}
- skl_delete_pipe(ctx, mconfig->pipe);
+ skl_delete_pipe(skl, mconfig->pipe);
list_for_each_entry(w_module, &s_pipe->w_list, node) {
src_module = w_module->w->priv;
src_module->m_state = SKL_MODULE_UNINIT;
}
- return skl_tplg_unload_pipe_modules(ctx, s_pipe);
+ return skl_tplg_unload_pipe_modules(skl, s_pipe);
}
/*
* in the Post-PMD event of PGA we need to do following:
- * - Free the mcps used
* - Stop the pipeline
* - In source pipe is connected, unbind with source pipelines
*/
static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl *skl)
+ struct skl_dev *skl)
{
struct skl_module_cfg *src_mconfig, *sink_mconfig;
int ret = 0, i;
- struct skl_sst *ctx = skl->skl_sst;
src_mconfig = w->priv;
/* Stop the pipe since this is a mixin module */
- ret = skl_stop_pipe(ctx, src_mconfig->pipe);
+ ret = skl_stop_pipe(skl, src_mconfig->pipe);
if (ret)
return ret;
@@ -1377,7 +1253,7 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
* This is a connecter and if path is found that means
* unbind between source and sink has not happened yet
*/
- ret = skl_unbind_modules(ctx, src_mconfig,
+ ret = skl_unbind_modules(skl, src_mconfig,
sink_mconfig);
}
}
@@ -1395,7 +1271,7 @@ static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
- struct skl *skl = get_skl_ctx(dapm->dev);
+ struct skl_dev *skl = get_skl_ctx(dapm->dev);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1425,7 +1301,7 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_dapm_context *dapm = w->dapm;
- struct skl *skl = get_skl_ctx(dapm->dev);
+ struct skl_dev *skl = get_skl_ctx(dapm->dev);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1446,10 +1322,10 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
struct skl_module_cfg *mconfig = w->priv;
- struct skl *skl = get_skl_ctx(w->dapm->dev);
+ struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
if (w->power)
- skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
+ skl_get_module_params(skl, (u32 *)bc->params,
bc->size, bc->param_id, mconfig);
/* decrement size for TLV header */
@@ -1481,7 +1357,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
struct soc_bytes_ext *sb =
(struct soc_bytes_ext *)kcontrol->private_value;
struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
- struct skl *skl = get_skl_ctx(w->dapm->dev);
+ struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
if (ac->params) {
/*
@@ -1498,7 +1374,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
return -EFAULT;
if (w->power)
- return skl_set_module_params(skl->skl_sst,
+ return skl_set_module_params(skl,
(u32 *)ac->params, ac->size,
ac->param_id, mconfig);
}
@@ -1659,7 +1535,7 @@ int skl_tplg_update_pipe_params(struct device *dev,
struct skl_pipe_params *params)
{
struct skl_module_res *res = &mconfig->module->resources[0];
- struct skl *skl = get_skl_ctx(dev);
+ struct skl_dev *skl = get_skl_ctx(dev);
struct skl_module_fmt *format = NULL;
u8 cfg_idx = mconfig->pipe->cur_config_idx;
@@ -1856,7 +1732,7 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
struct skl_pipe_params *params)
{
struct nhlt_specific_cfg *cfg;
- struct skl *skl = get_skl_ctx(dai->dev);
+ struct skl_dev *skl = get_skl_ctx(dai->dev);
int link_type = skl_tplg_be_link_type(mconfig->dev_type);
u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type);
@@ -2070,7 +1946,7 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev,
* Return an existing pipe if the pipe already exists.
*/
static int skl_tplg_add_pipe(struct device *dev,
- struct skl_module_cfg *mconfig, struct skl *skl,
+ struct skl_module_cfg *mconfig, struct skl_dev *skl,
struct snd_soc_tplg_vendor_value_elem *tkn_elem)
{
struct skl_pipeline *ppl;
@@ -2330,10 +2206,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
return -EINVAL;
switch (tkn_elem->token) {
- case SKL_TKN_MM_U32_CPS:
- res->cps = tkn_elem->value;
- break;
-
case SKL_TKN_MM_U32_DMA_SIZE:
res->dma_buffer_size = tkn_elem->value;
break;
@@ -2354,10 +2226,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
res->ibs = tkn_elem->value;
break;
- case SKL_TKN_U32_MAX_MCPS:
- res->cps = tkn_elem->value;
- break;
-
case SKL_TKN_MM_U32_RES_PIN_ID:
case SKL_TKN_MM_U32_PIN_BUF:
ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res,
@@ -2366,6 +2234,11 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
return ret;
break;
+ case SKL_TKN_MM_U32_CPS:
+ case SKL_TKN_U32_MAX_MCPS:
+ /* ignore unused tokens */
+ break;
+
default:
dev_err(dev, "Not a res type token: %d", tkn_elem->token);
return -EINVAL;
@@ -2381,7 +2254,7 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
*/
static int skl_tplg_get_token(struct device *dev,
struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl *skl, struct skl_module_cfg *mconfig)
+ struct skl_dev *skl, struct skl_module_cfg *mconfig)
{
int tkn_count = 0;
int ret;
@@ -2631,7 +2504,7 @@ static int skl_tplg_get_token(struct device *dev,
* module private data
*/
static int skl_tplg_get_tokens(struct device *dev,
- char *pvt_data, struct skl *skl,
+ char *pvt_data, struct skl_dev *skl,
struct skl_module_cfg *mconfig, int block_size)
{
struct snd_soc_tplg_vendor_array *array;
@@ -2727,8 +2600,8 @@ static int skl_tplg_get_desc_blocks(struct device *dev,
* Otherwise we create a new instance and add into driver list
*/
static int skl_tplg_add_pipe_v4(struct device *dev,
- struct skl_module_cfg *mconfig, struct skl *skl,
- struct skl_dfw_v4_pipe *dfw_pipe)
+ struct skl_module_cfg *mconfig, struct skl_dev *skl,
+ struct skl_dfw_v4_pipe *dfw_pipe)
{
struct skl_pipeline *ppl;
struct skl_pipe *pipe;
@@ -2804,7 +2677,7 @@ static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt,
}
static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
- struct skl *skl, struct device *dev,
+ struct skl_dev *skl, struct device *dev,
struct skl_module_cfg *mconfig)
{
struct skl_dfw_v4_module *dfw =
@@ -2818,7 +2691,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
return ret;
mconfig->id.module_id = -1;
mconfig->id.instance_id = dfw->instance_id;
- mconfig->module->resources[0].cps = dfw->max_mcps;
+ mconfig->module->resources[0].cpc = dfw->max_mcps / 1000;
mconfig->module->resources[0].ibs = dfw->ibs;
mconfig->module->resources[0].obs = dfw->obs;
mconfig->core_id = dfw->core_id;
@@ -2886,7 +2759,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
* for the type and size of the suceeding data block.
*/
static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
- struct skl *skl, struct device *dev,
+ struct skl_dev *skl, struct device *dev,
struct skl_module_cfg *mconfig)
{
struct snd_soc_tplg_vendor_array *array;
@@ -2981,9 +2854,8 @@ static void skl_clear_pin_config(struct snd_soc_component *component,
}
}
-void skl_cleanup_resources(struct skl *skl)
+void skl_cleanup_resources(struct skl_dev *skl)
{
- struct skl_sst *ctx = skl->skl_sst;
struct snd_soc_component *soc_component = skl->component;
struct snd_soc_dapm_widget *w;
struct snd_soc_card *card;
@@ -2995,15 +2867,12 @@ void skl_cleanup_resources(struct skl *skl)
if (!card || !card->instantiated)
return;
- skl->resource.mem = 0;
- skl->resource.mcps = 0;
-
list_for_each_entry(w, &card->widgets, list) {
- if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL)
+ if (is_skl_dsp_widget_type(w, skl->dev) && w->priv != NULL)
skl_clear_pin_config(soc_component, w);
}
- skl_clear_module_cnt(ctx->dsp);
+ skl_clear_module_cnt(skl->dsp);
}
/*
@@ -3019,7 +2888,7 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index,
{
int ret;
struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct skl_module_cfg *mconfig;
if (!tplg_w->priv.size)
@@ -3163,21 +3032,21 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
struct snd_soc_tplg_vendor_string_elem *str_elem,
- struct skl *skl)
+ struct skl_dev *skl)
{
int tkn_count = 0;
static int ref_count;
switch (str_elem->token) {
case SKL_TKN_STR_LIB_NAME:
- if (ref_count > skl->skl_sst->lib_count - 1) {
+ if (ref_count > skl->lib_count - 1) {
ref_count = 0;
return -EINVAL;
}
- strncpy(skl->skl_sst->lib_info[ref_count].name,
+ strncpy(skl->lib_info[ref_count].name,
str_elem->string,
- ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name));
+ ARRAY_SIZE(skl->lib_info[ref_count].name));
ref_count++;
break;
@@ -3192,7 +3061,7 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
static int skl_tplg_get_str_tkn(struct device *dev,
struct snd_soc_tplg_vendor_array *array,
- struct skl *skl)
+ struct skl_dev *skl)
{
int tkn_count = 0, ret;
struct snd_soc_tplg_vendor_string_elem *str_elem;
@@ -3299,7 +3168,7 @@ static int skl_tplg_fill_mod_info(struct device *dev,
static int skl_tplg_get_int_tkn(struct device *dev,
struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl *skl)
+ struct skl_dev *skl)
{
int tkn_count = 0, ret;
static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
@@ -3319,7 +3188,7 @@ static int skl_tplg_get_int_tkn(struct device *dev,
switch (tkn_elem->token) {
case SKL_TKN_U32_LIB_COUNT:
- skl->skl_sst->lib_count = tkn_elem->value;
+ skl->lib_count = tkn_elem->value;
break;
case SKL_TKN_U8_NUM_MOD:
@@ -3465,35 +3334,17 @@ static int skl_tplg_get_int_tkn(struct device *dev,
return tkn_count;
}
-static int skl_tplg_get_manifest_uuid(struct device *dev,
- struct skl *skl,
- struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
-{
- static int ref_count;
- struct skl_module *mod;
-
- if (uuid_tkn->token == SKL_TKN_UUID) {
- mod = skl->modules[ref_count];
- guid_copy(&mod->uuid, (guid_t *)&uuid_tkn->uuid);
- ref_count++;
- } else {
- dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
- return -EINVAL;
- }
-
- return 0;
-}
-
/*
* Fill the manifest structure by parsing the tokens based on the
* type.
*/
static int skl_tplg_get_manifest_tkn(struct device *dev,
- char *pvt_data, struct skl *skl,
+ char *pvt_data, struct skl_dev *skl,
int block_size)
{
int tkn_count = 0, ret;
int off = 0, tuple_size = 0;
+ u8 uuid_index = 0;
struct snd_soc_tplg_vendor_array *array;
struct snd_soc_tplg_vendor_value_elem *tkn_elem;
@@ -3516,9 +3367,17 @@ static int skl_tplg_get_manifest_tkn(struct device *dev,
continue;
case SND_SOC_TPLG_TUPLE_TYPE_UUID:
- ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid);
- if (ret < 0)
- return ret;
+ if (array->uuid->token != SKL_TKN_UUID) {
+ dev_err(dev, "Not an UUID token: %d\n",
+ array->uuid->token);
+ return -EINVAL;
+ }
+ if (uuid_index >= skl->nr_modules) {
+ dev_err(dev, "Too many UUID tokens\n");
+ return -EINVAL;
+ }
+ guid_copy(&skl->modules[uuid_index++]->uuid,
+ (guid_t *)&array->uuid->uuid);
tuple_size += sizeof(*array->uuid);
continue;
@@ -3550,7 +3409,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev,
* preceded by descriptors for type and size of data block.
*/
static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
- struct device *dev, struct skl *skl)
+ struct device *dev, struct skl_dev *skl)
{
struct snd_soc_tplg_vendor_array *array;
int num_blocks, block_size = 0, block_type, off = 0;
@@ -3612,7 +3471,7 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
struct snd_soc_tplg_manifest *manifest)
{
struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
/* proceed only if we have private data defined */
if (manifest->priv.size == 0)
@@ -3620,9 +3479,9 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
skl_tplg_get_manifest_data(manifest, bus->dev, skl);
- if (skl->skl_sst->lib_count > SKL_MAX_LIB) {
+ if (skl->lib_count > SKL_MAX_LIB) {
dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
- skl->skl_sst->lib_count);
+ skl->lib_count);
return -EINVAL;
}
@@ -3671,7 +3530,7 @@ static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
return 0;
}
-static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
+static void skl_tplg_set_pipe_type(struct skl_dev *skl, struct skl_pipe *pipe)
{
struct skl_pipe_module *w_module;
struct snd_soc_dapm_widget *w;
@@ -3694,10 +3553,6 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
pipe->passthru = false;
}
-/* This will be read from topology manifest, currently defined here */
-#define SKL_MAX_MCPS 30000000
-#define SKL_FW_MAX_MEM 1000000
-
/*
* SKL topology init routine
*/
@@ -3705,7 +3560,7 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
{
int ret;
const struct firmware *fw;
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct skl_pipeline *ppl;
ret = request_firmware(&fw, skl->tplg_name, bus->dev);
@@ -3724,31 +3579,30 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
* The complete tplg for SKL is loaded as index 0, we don't use
* any other index
*/
- ret = snd_soc_tplg_component_load(component,
- &skl_tplg_ops, fw, 0);
+ ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw, 0);
if (ret < 0) {
dev_err(bus->dev, "tplg component load failed%d\n", ret);
- release_firmware(fw);
- return -EINVAL;
+ goto err;
}
- skl->resource.max_mcps = SKL_MAX_MCPS;
- skl->resource.max_mem = SKL_FW_MAX_MEM;
-
- skl->tplg = fw;
ret = skl_tplg_create_pipe_widget_list(component);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ dev_err(bus->dev, "tplg create pipe widget list failed%d\n",
+ ret);
+ goto err;
+ }
list_for_each_entry(ppl, &skl->ppl_list, node)
skl_tplg_set_pipe_type(skl, ppl->pipe);
- return 0;
+err:
+ release_firmware(fw);
+ return ret;
}
void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct skl_pipeline *ppl, *tmp;
if (!list_empty(&skl->ppl_list))
@@ -3757,6 +3611,4 @@ void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
/* clean up topology */
snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);
-
- release_firmware(skl->tplg);
}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 665e35cee50d..e967800dbb62 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -101,7 +101,7 @@ struct skl_audio_data_format {
} __packed;
struct skl_base_cfg {
- u32 cps;
+ u32 cpc;
u32 ibs;
u32 obs;
u32 is_pages;
@@ -140,11 +140,6 @@ struct skl_src_module_cfg {
enum skl_s_freq src_cfg;
} __packed;
-struct notification_mask {
- u32 notify;
- u32 enable;
-} __packed;
-
struct skl_up_down_mixer_cfg {
struct skl_base_cfg base_cfg;
enum skl_ch_cfg out_ch_cfg;
@@ -348,7 +343,6 @@ struct skl_module_pin_resources {
struct skl_module_res {
u8 id;
u32 is_pages;
- u32 cps;
u32 ibs;
u32 obs;
u32 dma_buffer_size;
@@ -389,9 +383,6 @@ struct skl_module_cfg {
u8 out_queue_mask;
u8 in_queue;
u8 out_queue;
- u32 mcps;
- u32 ibs;
- u32 obs;
u8 is_loadable;
u8 core_id;
u8 dev_type;
@@ -447,7 +438,7 @@ enum skl_channel {
SKL_CH_QUATRO = 4,
};
-static inline struct skl *get_skl_ctx(struct device *dev)
+static inline struct skl_dev *get_skl_ctx(struct device *dev)
{
struct hdac_bus *bus = dev_get_drvdata(dev);
@@ -456,7 +447,7 @@ 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, u32 *caps,
+int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
u32 caps_size, u32 node_id);
void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
struct skl_pipe_params *params, int stream);
@@ -469,32 +460,32 @@ struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
int skl_tplg_update_pipe_params(struct device *dev,
struct skl_module_cfg *mconfig, struct skl_pipe_params *params);
-void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps);
-void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps);
+void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps);
+void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps);
-int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_pause_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_pause_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
+int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config);
+int skl_init_module(struct skl_dev *skl, struct skl_module_cfg *module_config);
-int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
+int skl_bind_modules(struct skl_dev *skl, struct skl_module_cfg
*src_module, struct skl_module_cfg *dst_module);
-int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg
+int skl_unbind_modules(struct skl_dev *skl, struct skl_module_cfg
*src_module, struct skl_module_cfg *dst_module);
-int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
+int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
u32 param_id, struct skl_module_cfg *mcfg);
-int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
+int skl_get_module_params(struct skl_dev *skl, 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,
@@ -508,6 +499,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
int skl_dai_load(struct snd_soc_component *cmp, int index,
struct snd_soc_dai_driver *dai_drv,
struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai);
-void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
struct snd_soc_dapm_widget *w);
#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 3362e71b4563..f755ca2484cf 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -26,9 +26,12 @@
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>
#include <sound/hda_codec.h>
+#include <sound/intel-nhlt.h>
+#include <sound/intel-dsp-config.h>
#include "skl.h"
#include "skl-sst-dsp.h"
#include "skl-sst-ipc.h"
+
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
#include "../../../soc/codecs/hdac_hda.h"
#endif
@@ -50,7 +53,7 @@ static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg,
pci_write_config_byte(pci, reg, data);
}
-static void skl_init_pci(struct skl *skl)
+static void skl_init_pci(struct skl_dev *skl)
{
struct hdac_bus *bus = skl_to_bus(skl);
@@ -132,7 +135,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
/* Reset stream-to-link mapping */
list_for_each_entry(hlink, &bus->hlink_list, list)
- bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
+ writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
skl_enable_miscbdcge(bus->dev, true);
@@ -252,7 +255,7 @@ static irqreturn_t skl_threaded_handler(int irq, void *dev_id)
static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
int ret;
ret = request_threaded_irq(skl->pci->irq, skl_interrupt,
@@ -276,7 +279,7 @@ static int skl_suspend_late(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
return skl_suspend_late_dsp(skl);
}
@@ -284,7 +287,7 @@ static int skl_suspend_late(struct device *dev)
#ifdef CONFIG_PM
static int _skl_suspend(struct hdac_bus *bus)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct pci_dev *pci = to_pci_dev(bus->dev);
int ret;
@@ -307,7 +310,7 @@ static int _skl_suspend(struct hdac_bus *bus)
static int _skl_resume(struct hdac_bus *bus)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
skl_init_pci(skl);
skl_dum_set(bus);
@@ -325,7 +328,7 @@ static int skl_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
int ret;
/*
@@ -345,7 +348,7 @@ static int skl_suspend(struct device *dev)
ret = _skl_suspend(bus);
if (ret < 0)
return ret;
- skl->skl_sst->fw_loaded = false;
+ skl->fw_loaded = false;
}
return 0;
@@ -355,7 +358,7 @@ static int skl_resume(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct hdac_ext_link *hlink = NULL;
int ret;
@@ -430,7 +433,7 @@ static const struct dev_pm_ops skl_pm = {
*/
static int skl_free(struct hdac_bus *bus)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
skl->init_done = 0; /* to be sure */
@@ -475,7 +478,7 @@ static struct skl_ssp_clk skl_ssp_clks[] = {
{.name = "ssp5_sclkfs"},
};
-static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl,
+static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl,
struct snd_soc_acpi_mach *machines)
{
struct hdac_bus *bus = skl_to_bus(skl);
@@ -494,7 +497,7 @@ static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl,
return mach;
}
-static int skl_find_machine(struct skl *skl, void *driver_data)
+static int skl_find_machine(struct skl_dev *skl, void *driver_data)
{
struct hdac_bus *bus = skl_to_bus(skl);
struct snd_soc_acpi_mach *mach = driver_data;
@@ -516,13 +519,15 @@ static int skl_find_machine(struct skl *skl, void *driver_data)
if (pdata) {
skl->use_tplg_pcm = pdata->use_tplg_pcm;
- mach->mach_params.dmic_num = skl_get_dmic_geo(skl);
+ mach->mach_params.dmic_num =
+ intel_nhlt_get_dmic_geo(&skl->pci->dev,
+ skl->nhlt);
}
return 0;
}
-static int skl_machine_device_register(struct skl *skl)
+static int skl_machine_device_register(struct skl_dev *skl)
{
struct snd_soc_acpi_mach *mach = skl->mach;
struct hdac_bus *bus = skl_to_bus(skl);
@@ -558,13 +563,13 @@ static int skl_machine_device_register(struct skl *skl)
return 0;
}
-static void skl_machine_device_unregister(struct skl *skl)
+static void skl_machine_device_unregister(struct skl_dev *skl)
{
if (skl->i2s_dev)
platform_device_unregister(skl->i2s_dev);
}
-static int skl_dmic_device_register(struct skl *skl)
+static int skl_dmic_device_register(struct skl_dev *skl)
{
struct hdac_bus *bus = skl_to_bus(skl);
struct platform_device *pdev;
@@ -588,7 +593,7 @@ static int skl_dmic_device_register(struct skl *skl)
return 0;
}
-static void skl_dmic_device_unregister(struct skl *skl)
+static void skl_dmic_device_unregister(struct skl_dev *skl)
{
if (skl->dmic_dev)
platform_device_unregister(skl->dmic_dev);
@@ -626,7 +631,7 @@ static void init_skl_xtal_rate(int pci_id)
}
}
-static int skl_clock_device_register(struct skl *skl)
+static int skl_clock_device_register(struct skl_dev *skl)
{
struct platform_device_info pdevinfo = {NULL};
struct skl_clk_pdata *clk_pdata;
@@ -656,7 +661,7 @@ static int skl_clock_device_register(struct skl *skl)
return PTR_ERR_OR_ZERO(skl->clk_dev);
}
-static void skl_clock_device_unregister(struct skl *skl)
+static void skl_clock_device_unregister(struct skl_dev *skl)
{
if (skl->clk_dev)
platform_device_unregister(skl->clk_dev);
@@ -692,7 +697,7 @@ static int probe_codec(struct hdac_bus *bus, int addr)
unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
unsigned int res = -1;
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
struct hdac_hda_priv *hda_codec;
int err;
@@ -768,11 +773,6 @@ static void skl_codec_create(struct hdac_bus *bus)
}
}
-static const struct hdac_bus_ops bus_core_ops = {
- .command = snd_hdac_bus_send_cmd,
- .get_response = snd_hdac_bus_get_response,
-};
-
static int skl_i915_init(struct hdac_bus *bus)
{
int err;
@@ -792,7 +792,7 @@ static int skl_i915_init(struct hdac_bus *bus)
static void skl_probe_work(struct work_struct *work)
{
- struct skl *skl = container_of(work, struct skl, probe_work);
+ struct skl_dev *skl = container_of(work, struct skl_dev, probe_work);
struct hdac_bus *bus = skl_to_bus(skl);
struct hdac_ext_link *hlink = NULL;
int err;
@@ -854,11 +854,10 @@ out_err:
* constructor
*/
static int skl_create(struct pci_dev *pci,
- const struct hdac_io_ops *io_ops,
- struct skl **rskl)
+ struct skl_dev **rskl)
{
struct hdac_ext_bus_ops *ext_ops = NULL;
- struct skl *skl;
+ struct skl_dev *skl;
struct hdac_bus *bus;
struct hda_bus *hbus;
int err;
@@ -884,7 +883,7 @@ static int skl_create(struct pci_dev *pci,
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
ext_ops = snd_soc_hdac_hda_get_ops();
#endif
- snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops);
+ snd_hdac_ext_bus_init(bus, &pci->dev, NULL, ext_ops);
bus->use_posbuf = 1;
skl->pci = pci;
INIT_WORK(&skl->probe_work, skl_probe_work);
@@ -902,7 +901,7 @@ static int skl_create(struct pci_dev *pci,
static int skl_first_init(struct hdac_bus *bus)
{
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
struct pci_dev *pci = skl->pci;
int err;
unsigned short gcap;
@@ -978,28 +977,16 @@ static int skl_first_init(struct hdac_bus *bus)
static int skl_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- struct skl *skl;
+ struct skl_dev *skl;
struct hdac_bus *bus = NULL;
int err;
switch (skl_pci_binding) {
case SND_SKL_PCI_BIND_AUTO:
- /*
- * detect DSP by checking class/subclass/prog-id information
- * class=04 subclass 03 prog-if 00: no DSP, use legacy driver
- * class=04 subclass 01 prog-if 00: DSP is present
- * (and may be required e.g. for DMIC or SSP support)
- * class=04 subclass 03 prog-if 80: use DSP or legacy mode
- */
- if (pci->class == 0x040300) {
- dev_info(&pci->dev, "The DSP is not enabled on this platform, aborting probe\n");
- return -ENODEV;
- }
- if (pci->class != 0x040100 && pci->class != 0x040380) {
- dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, aborting probe\n", pci->class);
+ err = snd_intel_dsp_driver_probe(pci);
+ if (err != SND_INTEL_DSP_DRIVER_ANY &&
+ err != SND_INTEL_DSP_DRIVER_SST)
return -ENODEV;
- }
- dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
break;
case SND_SKL_PCI_BIND_LEGACY:
dev_info(&pci->dev, "Module parameter forced binding with HDaudio legacy, aborting probe\n");
@@ -1013,7 +1000,7 @@ static int skl_probe(struct pci_dev *pci,
}
/* we use ext core ops, so provide NULL for ops here */
- err = skl_create(pci, NULL, &skl);
+ err = skl_create(pci, &skl);
if (err < 0)
return err;
@@ -1029,7 +1016,7 @@ static int skl_probe(struct pci_dev *pci,
device_disable_async_suspend(bus->dev);
- skl->nhlt = skl_nhlt_init(bus->dev);
+ skl->nhlt = intel_nhlt_init(bus->dev);
if (skl->nhlt == NULL) {
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
@@ -1071,8 +1058,8 @@ static int skl_probe(struct pci_dev *pci,
dev_dbg(bus->dev, "error failed to register dsp\n");
goto out_nhlt_free;
}
- skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
- skl->skl_sst->clock_power_gating = skl_clock_power_gating;
+ skl->enable_miscbdcge = skl_enable_miscbdcge;
+ skl->clock_power_gating = skl_clock_power_gating;
if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(bus);
@@ -1095,7 +1082,7 @@ out_dsp_free:
out_clk_free:
skl_clock_device_unregister(skl);
out_nhlt_free:
- skl_nhlt_free(skl->nhlt);
+ intel_nhlt_free(skl->nhlt);
out_free:
skl_free(bus);
@@ -1107,7 +1094,7 @@ static void skl_shutdown(struct pci_dev *pci)
struct hdac_bus *bus = pci_get_drvdata(pci);
struct hdac_stream *s;
struct hdac_ext_stream *stream;
- struct skl *skl;
+ struct skl_dev *skl;
if (!bus)
return;
@@ -1129,7 +1116,7 @@ static void skl_shutdown(struct pci_dev *pci)
static void skl_remove(struct pci_dev *pci)
{
struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl *skl = bus_to_skl(bus);
+ struct skl_dev *skl = bus_to_skl(bus);
cancel_work_sync(&skl->probe_work);
@@ -1144,7 +1131,7 @@ static void skl_remove(struct pci_dev *pci)
skl_dmic_device_unregister(skl);
skl_clock_device_unregister(skl);
skl_nhlt_remove_sysfs(skl);
- skl_nhlt_free(skl->nhlt);
+ intel_nhlt_free(skl->nhlt);
skl_free(bus);
dev_set_drvdata(&pci->dev, NULL);
}
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 6070666a6392..2bfbf59277c4 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -16,8 +16,8 @@
#include <sound/hdaudio_ext.h>
#include <sound/hda_codec.h>
#include <sound/soc.h>
-#include "skl-nhlt.h"
#include "skl-ssp-clk.h"
+#include "skl-sst-ipc.h"
#define SKL_SUSPEND_DELAY 2000
@@ -40,13 +40,6 @@
#define AZX_VS_EM2_DUM BIT(23)
#define AZX_REG_VS_EM2_L1SEN BIT(13)
-struct skl_dsp_resource {
- u32 max_mcps;
- u32 max_mem;
- u32 mcps;
- u32 mem;
-};
-
struct skl_debug;
struct skl_astate_param {
@@ -63,7 +56,7 @@ struct skl_fw_config {
struct skl_astate_config *astate_cfg;
};
-struct skl {
+struct skl_dev {
struct hda_bus hbus;
struct pci_dev *pci;
@@ -75,16 +68,13 @@ struct skl {
struct snd_soc_dai_driver *dais;
struct nhlt_acpi_table *nhlt; /* nhlt ptr */
- struct skl_sst *skl_sst; /* sst skl ctx */
- struct skl_dsp_resource resource;
struct list_head ppl_list;
struct list_head bind_list;
const char *fw_name;
char tplg_name[64];
unsigned short pci_id;
- const struct firmware *tplg;
int supend_active;
@@ -96,13 +86,59 @@ struct skl {
bool use_tplg_pcm;
struct skl_fw_config cfg;
struct snd_soc_acpi_mach *mach;
+
+ struct device *dev;
+ struct sst_dsp *dsp;
+
+ /* boot */
+ wait_queue_head_t boot_wait;
+ bool boot_complete;
+
+ /* module load */
+ wait_queue_head_t mod_load_wait;
+ bool mod_load_complete;
+ bool mod_load_status;
+
+ /* IPC messaging */
+ struct sst_generic_ipc ipc;
+
+ /* callback for miscbdge */
+ void (*enable_miscbdcge)(struct device *dev, bool enable);
+ /* Is CGCTL.MISCBDCGE disabled */
+ bool miscbdcg_disabled;
+
+ /* Populate module information */
+ struct list_head uuid_list;
+
+ /* Is firmware loaded */
+ bool fw_loaded;
+
+ /* first boot ? */
+ bool is_first_boot;
+
+ /* multi-core */
+ struct skl_dsp_cores cores;
+
+ /* library info */
+ struct skl_lib_info lib_info[SKL_MAX_LIB];
+ int lib_count;
+
+ /* Callback to update D0i3C register */
+ void (*update_d0i3c)(struct device *dev, bool enable);
+
+ struct skl_d0i3_data d0i3;
+
+ const struct skl_dsp_ops *dsp_ops;
+
+ /* Callback to update dynamic clock and power gating registers */
+ void (*clock_power_gating)(struct device *dev, bool enable);
};
#define skl_to_bus(s) (&(s)->hbus.core)
-#define bus_to_skl(bus) container_of(bus, struct skl, hbus.core)
+#define bus_to_skl(bus) container_of(bus, struct skl_dev, hbus.core)
#define skl_to_hbus(s) (&(s)->hbus)
-#define hbus_to_skl(hbus) container_of((hbus), struct skl, (hbus))
+#define hbus_to_skl(hbus) container_of((hbus), struct skl_dev, (hbus))
/* to pass dai dma data */
struct skl_dma_params {
@@ -121,52 +157,49 @@ struct skl_dsp_ops {
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);
- int (*init_fw)(struct device *dev, struct skl_sst *ctx);
- void (*cleanup)(struct device *dev, struct skl_sst *ctx);
+ struct skl_dev **skl_sst);
+ int (*init_fw)(struct device *dev, struct skl_dev *skl);
+ void (*cleanup)(struct device *dev, struct skl_dev *skl);
};
int skl_platform_unregister(struct device *dev);
int skl_platform_register(struct device *dev);
-struct nhlt_acpi_table *skl_nhlt_init(struct device *dev);
-void skl_nhlt_free(struct nhlt_acpi_table *addr);
-struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
+struct nhlt_specific_cfg *skl_get_ep_blob(struct skl_dev *skl, u32 instance,
u8 link_type, u8 s_fmt, u8 no_ch,
u32 s_rate, u8 dirn, u8 dev_type);
-int skl_get_dmic_geo(struct skl *skl);
-int skl_nhlt_update_topology_bin(struct skl *skl);
-int skl_init_dsp(struct skl *skl);
-int skl_free_dsp(struct skl *skl);
-int skl_suspend_late_dsp(struct skl *skl);
-int skl_suspend_dsp(struct skl *skl);
-int skl_resume_dsp(struct skl *skl);
-void skl_cleanup_resources(struct skl *skl);
+int skl_nhlt_update_topology_bin(struct skl_dev *skl);
+int skl_init_dsp(struct skl_dev *skl);
+int skl_free_dsp(struct skl_dev *skl);
+int skl_suspend_late_dsp(struct skl_dev *skl);
+int skl_suspend_dsp(struct skl_dev *skl);
+int skl_resume_dsp(struct skl_dev *skl);
+void skl_cleanup_resources(struct skl_dev *skl);
const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
void skl_update_d0i3c(struct device *dev, bool enable);
-int skl_nhlt_create_sysfs(struct skl *skl);
-void skl_nhlt_remove_sysfs(struct skl *skl);
-void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks);
+int skl_nhlt_create_sysfs(struct skl_dev *skl);
+void skl_nhlt_remove_sysfs(struct skl_dev *skl);
+void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks);
struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
-int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
u32 caps_size, u32 node_id);
struct skl_module_cfg;
#ifdef CONFIG_DEBUG_FS
-struct skl_debug *skl_debugfs_init(struct skl *skl);
-void skl_debugfs_exit(struct skl *skl);
+struct skl_debug *skl_debugfs_init(struct skl_dev *skl);
+void skl_debugfs_exit(struct skl_dev *skl);
void skl_debug_init_module(struct skl_debug *d,
struct snd_soc_dapm_widget *w,
struct skl_module_cfg *mconfig);
#else
-static inline struct skl_debug *skl_debugfs_init(struct skl *skl)
+static inline struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
{
return NULL;
}
-static inline void skl_debugfs_exit(struct skl *skl)
+static inline void skl_debugfs_exit(struct skl_dev *skl)
{}
static inline void skl_debug_init_module(struct skl_debug *d,
OpenPOWER on IntegriCloud