diff --git a/src/platform/apollolake/dai.c b/src/platform/apollolake/dai.c index 446310374..fea9faf4e 100644 --- a/src/platform/apollolake/dai.c +++ b/src/platform/apollolake/dai.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -146,6 +147,55 @@ static struct dai ssp[PLATFORM_NUM_SSP] = { .ops = &ssp_ops, },}; +#if defined CONFIG_DMIC + +static struct dai dmic[2] = { + /* Testing idea if DMIC FIFOs A and B to access the same microphones + * with two different sample rate and PCM format could be presented + * similarly as SSP0..N. The difference however is that the DMIC + * programming is global and not per FIFO. + */ + + /* Primary FIFO A */ + { + .type = SOF_DAI_INTEL_DMIC, + .index = 0, + .plat_data = { + .base = DMIC_BASE, + .irq = IRQ_EXT_DMIC_LVL5(0), + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = 0, /* No playback */ + .handshake = 0, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DMIC_BASE + OUTDATA0, + .handshake = DMA_HANDSHAKE_DMIC_CH0, + } + }, + .ops = &dmic_ops, + }, + /* Secondary FIFO B */ + { + .type = SOF_DAI_INTEL_DMIC, + .index = 1, + .plat_data = { + .base = DMIC_BASE, + .irq = IRQ_EXT_DMIC_LVL5(0), + .fifo[SOF_IPC_STREAM_PLAYBACK] = { + .offset = 0, /* No playback */ + .handshake = 0, + }, + .fifo[SOF_IPC_STREAM_CAPTURE] = { + .offset = DMIC_BASE + OUTDATA1, + .handshake = DMA_HANDSHAKE_DMIC_CH1, + } + }, + .ops = &dmic_ops, + } +}; + +#endif + struct dai *dai_get(uint32_t type, uint32_t index) { int i; @@ -157,5 +207,14 @@ struct dai *dai_get(uint32_t type, uint32_t index) } } +#if defined CONFIG_DMIC + if (type == SOF_DAI_INTEL_DMIC) { + for (i = 0; i < ARRAY_SIZE(dmic); i++) { + if (dmic[i].type == type && dmic[i].index == index) + return &dmic[i]; + } + } +#endif + return NULL; } diff --git a/src/platform/apollolake/include/platform/memory.h b/src/platform/apollolake/include/platform/memory.h index 6b3f21f49..e7f3ee3b3 100644 --- a/src/platform/apollolake/include/platform/memory.h +++ b/src/platform/apollolake/include/platform/memory.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2016, Intel Corporation * All rights reserved. @@ -171,7 +172,11 @@ #define SOF_TEXT_SIZE 0x19000 /* initialized data */ +#if defined CONFIG_DMIC +#define SOF_DATA_SIZE 0x1a000 +#else #define SOF_DATA_SIZE 0x19000 +#endif /* bss data */ #define SOF_BSS_DATA_SIZE 0x2800 diff --git a/src/platform/apollolake/platform.c b/src/platform/apollolake/platform.c index d24a44004..0b26ae5d6 100644 --- a/src/platform/apollolake/platform.c +++ b/src/platform/apollolake/platform.c @@ -188,6 +188,7 @@ int platform_init(struct sof *sof) { struct dma *dmac; struct dai *ssp; + struct dai *dmic0; int i; platform_interrupt_init(); @@ -230,6 +231,7 @@ int platform_init(struct sof *sof) SHIM_CLKCTL_I2SFDCGB(2) | SHIM_CLKCTL_I2SFDCGB(1) | SHIM_CLKCTL_I2SFDCGB(0) | + SHIM_CLKCTL_DMICFDCGB | SHIM_CLKCTL_I2SEFDCGB(1) | SHIM_CLKCTL_I2SEFDCGB(0) | SHIM_CLKCTL_TCPAPLLS | @@ -271,6 +273,16 @@ int platform_init(struct sof *sof) dai_probe(ssp); } + /* Init DMIC. Note that the two PDM controllers and four microphones + * supported max. those are available in platform are handled by dmic0. + */ + trace_point(TRACE_BOOT_PLATFORM_DMIC); + dmic0 = dai_get(SOF_DAI_INTEL_DMIC, 0); + if (!dmic0) + return -ENODEV; + + dai_probe(dmic0); + /* Initialize DMA for Trace*/ dma_trace_init_complete(sof->dmat);