mailman.alsa-project.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Sound-open-firmware

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
sound-open-firmware@alsa-project.org

February 2018

  • 15 participants
  • 58 discussions
[Sound-open-firmware] [PATCH] topology: m4: add default_hw_conf_id
by Xiuli Pan 12 Feb '18

12 Feb '18
From: Pan Xiuli <xiuli.pan(a)linux.intel.com> Add default_hw_conf_id to set the default_hw_config_id value in ASOC and then we can set the dai config. Signed-off-by: Pan Xiuli <xiuli.pan(a)linux.intel.com> --- Test with: Mininow max rt5651 SOF master: 019637ab250daa53c15da0a0a98c54f1c58d8ca3 SOF-Tool master: 33e4b0cc6f6a44e3e7ee849c04c515a5537242c7 https://github.com/plbossart/sound/tree/topic/sof-v4.14: 6fa721a8b7c6567eea0a2181bf9a3d2a12c31b00 Should work with ASOC patch: ASOC: topology: Fix hw_config setting for DAI --- topology/m4/local.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/topology/m4/local.m4 b/topology/m4/local.m4 index ad72a11..bb4a183 100644 --- a/topology/m4/local.m4 +++ b/topology/m4/local.m4 @@ -453,6 +453,7 @@ define(`DAI_CONFIG', `' `SectionBE."'$3`" {' ` index "0"' +` default_hw_conf_id "'$2`"' `' ` hw_configs [' ` "'$1$2`"' -- 2.7.4
1 0
0 0
[Sound-open-firmware] [PATCH] volume: fix logic for volume mute/unmute
by Ranjani Sridharan 10 Feb '18

10 Feb '18
This patch fixes the volume mute/unmute logic in volume to handle cases when volume is already muted/unmuted Signed-off-by: Ranjani Sridharan <ranjani.sridharan(a)linux.intel.com> --- Tested with: Minnowboard Turbot rt5651 SOF master: 1edc69c7c0af4808764590990d37076da80c8627 SOF-Tool master: 57be4f5b8c96ba5839598046be4b4543ce8cf63b https://github.com/plbossart/sound/tree/topic/sof-v4.14: 6fa721a8b7c6567eea0a2181bf9a3d2a12c31b00 --- --- src/audio/volume.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/audio/volume.c b/src/audio/volume.c index 3b3e2aa..8e54607 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -440,7 +440,9 @@ static inline void volume_set_chan_mute(struct comp_dev *dev, int chan) { struct comp_data *cd = comp_get_drvdata(dev); - cd->mvolume[chan] = cd->volume[chan]; + /* Check if not muted already */ + if (cd->volume[chan] != 0) + cd->mvolume[chan] = cd->volume[chan]; cd->tvolume[chan] = 0; } @@ -448,7 +450,9 @@ static inline void volume_set_chan_unmute(struct comp_dev *dev, int chan) { struct comp_data *cd = comp_get_drvdata(dev); - cd->tvolume[chan] = cd->mvolume[chan]; + /* Check if muted */ + if (cd->volume[chan] == 0) + cd->tvolume[chan] = cd->mvolume[chan]; } static int volume_ctrl_set_cmd(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) @@ -521,7 +525,7 @@ static int volume_ctrl_get_cmd(struct comp_dev *dev, struct sof_ipc_ctrl_data *c return -EINVAL; } - if (cdata->cmd == SOF_CTRL_CMD_VOLUME) { + if (cdata->cmd == SOF_CTRL_CMD_VOLUME || SOF_CTRL_CMD_SWITCH) { trace_volume("vgt"); trace_value(cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { -- 2.14.1
1 0
0 0
[Sound-open-firmware] [PATCH_V2] GPDMA: refine GPDMA on CNL
by Rander Wang 09 Feb '18

09 Feb '18
All GPDMA share the same irq on cannonlake, this is different with appololake.The change is:probe GPDMA array when initilized, set the array to the irq function; check the interrupt status of GPDMA array in irq function, process the correct GPDMA that produces interrupt. --- V2: refine it to build for other platform. kernel:Pierre`s branch rimage:embargo-1.0 fw:master Signed-off-by: Rander Wang <rander.wang(a)intel.com> --- src/drivers/dw-dma.c | 43 ++++++++++++++++------ src/platform/cannonlake/dma.c | 2 +- .../cannonlake/include/platform/platform.h | 1 + src/platform/cannonlake/platform.c | 14 ++----- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index 7a1805e..d6e05b9 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -1001,7 +1001,7 @@ static int dw_dma_probe(struct dma *dma) static void dw_dma_irq_handler(void *data) { struct dma *dma = (struct dma *)data; - struct dma_pdata *p = dma_get_drvdata(dma); + struct dma_pdata *p = NULL; struct dma_sg_elem next; uint32_t status_tfr = 0; uint32_t status_block = 0; @@ -1013,11 +1013,21 @@ static void dw_dma_irq_handler(void *data) int i; status_intr = dw_read(dma, DW_INTR_STATUS); - if (!status_intr) + if (!status_intr) { +#ifdef CONFIG_CANNONLAKE + dma++; + status_intr = dw_read(dma, DW_INTR_STATUS); + if (!status_intr) + trace_dma_error("eI0"); +#else trace_dma_error("eI0"); +#endif + } tracev_dma("DIr"); + p = dma_get_drvdata(dma); + /* get the source of our IRQ. */ status_block = dw_read(dma, DW_STATUS_BLOCK); status_tfr = dw_read(dma, DW_STATUS_TFR); @@ -1100,21 +1110,30 @@ static void dw_dma_irq_handler(void *data) static int dw_dma_probe(struct dma *dma) { struct dma_pdata *dw_pdata; + struct dma *dmac = dma; int i; +#ifdef CONFIG_CANNONLAKE + int j; - /* allocate private data */ - dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata)); - dma_set_drvdata(dma, dw_pdata); + for (j = 0; j < MAX_GPDMA_COUNT; j++) +#endif + { + /* allocate private data */ + dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata)); + dma_set_drvdata(dmac, dw_pdata); - spinlock_init(&dma->lock); + spinlock_init(&dmac->lock); - dw_dma_setup(dma); + dw_dma_setup(dmac); - /* init work */ - for (i = 0; i < DW_MAX_CHAN; i++) { - dw_pdata->chan[i].dma = dma; - dw_pdata->chan[i].channel = i; - dw_pdata->chan[i].status = COMP_STATE_INIT; + /* init work */ + for (i = 0; i < DW_MAX_CHAN; i++) { + dw_pdata->chan[i].dma = dmac; + dw_pdata->chan[i].channel = i; + dw_pdata->chan[i].status = COMP_STATE_INIT; + } + + dmac++; } /* register our IRQ handler */ diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 45bdee3..beac6cf 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -124,7 +124,7 @@ static struct dma dma[] = { .id = DMA_GP_LP_DMAC1, .base = LP_GP_DMA_BASE(1), .channels = 8, - .irq = IRQ_EXT_LP_GPDMA1_LVL4(0, 0), + .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0), .drv_plat_data = &dmac1, }, .ops = &dw_dma_ops, diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index 00e0069..f29af95 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -40,6 +40,7 @@ struct reef; #define PLATFORM_SSP_COUNT 3 +#define MAX_GPDMA_COUNT 2 /* Host page size */ #define HOST_PAGE_SIZE 4096 diff --git a/src/platform/cannonlake/platform.c b/src/platform/cannonlake/platform.c index 729364f..f387109 100644 --- a/src/platform/cannonlake/platform.c +++ b/src/platform/cannonlake/platform.c @@ -196,8 +196,7 @@ static struct timer platform_ext_timer = { int platform_init(struct reef *reef) { - struct dma *dmac0; - struct dma *dmac1; + struct dma *dmac; struct dai *ssp; int i; @@ -249,15 +248,10 @@ int platform_init(struct reef *reef) /* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac0 = dma_get(DMA_GP_LP_DMAC0); - if (dmac0 == NULL) + dmac = dma_get(DMA_GP_LP_DMAC0); + if (!dmac) return -ENODEV; - dma_probe(dmac0); - - dmac1 = dma_get(DMA_GP_LP_DMAC1); - if (dmac1 == NULL) - return -ENODEV; - dma_probe(dmac1); + dma_probe(dmac); /* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP); -- 2.14.1
2 1
0 0
[Sound-open-firmware] [PATCH] topology: add toplogy for CNL with RT274 codec
by Rander Wang 09 Feb '18

09 Feb '18
Support playback and capture with volume control at 48KHZ, 24Bit, TDM4 but only 2 channel valid Signed-off-by: Rander Wang <rander.wang(a)intel.com> --- topology/reef-cnl-rt274.m4 | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 topology/reef-cnl-rt274.m4 diff --git a/topology/reef-cnl-rt274.m4 b/topology/reef-cnl-rt274.m4 new file mode 100644 index 0000000..67aab04 --- /dev/null +++ b/topology/reef-cnl-rt274.m4 @@ -0,0 +1,70 @@ +# +# Topology for generic Cannonlake board with RT274 +# + +# Include topology builder +include(`local.m4') +include(`build.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include Apollolake DSP configuration +include(`dsps/bxt.m4') + +# +# Define the pipelines +# +# PCM0 ----> volume -----> volume ----> SSP0 +# +# PCM1 <---- Volume <---- SSP0 +# + +# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s24le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +# Use DMAC 0 channel 1 for PCM audio playback data +PIPELINE_PCM_DAI_ADD(sof/pipe-volume-playback.m4, + 1, 0, 2, s24le, + 48, 1000, 0, 0, 0, 1, SSP, 0, s24le, 2) + +# Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +# Use DMAC 0 channel 2 for PCM audio capture data +PIPELINE_PCM_DAI_ADD(sof/pipe-volume-capture.m4, + 2, 0, 2, s24le, + 48, 1000, 0, 0, 0, 1, SSP, 0, s24le, 2) + +# +# DAI configuration +# +# SSP port 0 is our only pipeline DAI +# + +# playback DAI is SSP0 using 2 periods +# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SSP, 0, + PIPELINE_SOURCE_1, 2, s24le, + 48, 1000, 0, 0) + +# capture DAI is SSP0 using 2 periods +# Buffers use s24le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-capture.m4, + 2, SSP, 0, + PIPELINE_SINK_2, 2, s24le, + 48, 1000, 0, 0) + +# PCM Low Latency +PCM_DUPLEX_ADD(Passthrough, 3, 0, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) + +# +# BE configurations - overrides config in ACPI if present +# +DAI_CONFIG(SSP, 0, SSP0-Codec, DSP_B, 24, + DAI_CLOCK(mclk, 24000000, slave), + DAI_CLOCK(bclk, 4800000, slave), + DAI_CLOCK(fsync, 48000, slave), + DAI_TDM(4, 25, 3, 3)) -- 2.14.1
2 1
0 0
[Sound-open-firmware] [PATCH] ipc: return msg to empty list
by Liam Girdwood 08 Feb '18

08 Feb '18
From: Rander Wang <rander.wang(a)intel.com> DSP and host communicate each other with msg. It would exhausted without return and make ipc failed --- src/ipc/apl-ipc.c | 2 +- src/ipc/byt-ipc.c | 2 ++ src/ipc/cnl-ipc.c | 2 ++ src/ipc/hsw-ipc.c | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ipc/apl-ipc.c b/src/ipc/apl-ipc.c index c779062..1332639 100644 --- a/src/ipc/apl-ipc.c +++ b/src/ipc/apl-ipc.c @@ -168,7 +168,7 @@ void ipc_platform_send_msg(struct ipc *ipc) ipc_write(IPC_DIPCIE, 0); ipc_write(IPC_DIPCI, 0x80000000 | msg->header); -list_item_append(&msg->list, &ipc->empty_list); + list_item_append(&msg->list, &ipc->empty_list); out: spin_unlock_irq(&ipc->lock, flags); diff --git a/src/ipc/byt-ipc.c b/src/ipc/byt-ipc.c index 8897bb9..e7c1d78 100644 --- a/src/ipc/byt-ipc.c +++ b/src/ipc/byt-ipc.c @@ -194,6 +194,8 @@ void ipc_platform_send_msg(struct ipc *ipc) shim_write(SHIM_IPCDL, msg->header); shim_write(SHIM_IPCDH, SHIM_IPCDH_BUSY); + list_item_append(&msg->list, &ipc->empty_list); + out: spin_unlock_irq(&ipc->lock, flags); } diff --git a/src/ipc/cnl-ipc.c b/src/ipc/cnl-ipc.c index cd5e825..5ccc345 100644 --- a/src/ipc/cnl-ipc.c +++ b/src/ipc/cnl-ipc.c @@ -168,6 +168,8 @@ void ipc_platform_send_msg(struct ipc *ipc) ipc_write(IPC_DIPCIDD, 0); ipc_write(IPC_DIPCIDR, 0x80000000 | msg->header); + list_item_append(&msg->list, &ipc->empty_list); + out: spin_unlock_irq(&ipc->lock, flags); } diff --git a/src/ipc/hsw-ipc.c b/src/ipc/hsw-ipc.c index 4a16f41..7a1dd72 100644 --- a/src/ipc/hsw-ipc.c +++ b/src/ipc/hsw-ipc.c @@ -184,6 +184,8 @@ void ipc_platform_send_msg(struct ipc *ipc) /* now interrupt host to tell it we have message sent */ shim_write(SHIM_IPCD, msg->header | SHIM_IPCD_BUSY); + list_item_append(&msg->list, &ipc->empty_list); + out: spin_unlock_irq(&ipc->lock, flags); } -- 2.14.1
1 0
0 0
[Sound-open-firmware] [PATCH] topology: fix typos in capture pipelines
by Ranjani Sridharan 08 Feb '18

08 Feb '18
This patch fixes typos in the capture pipelines to avoid confusion. Signed-off-by: Ranjani Sridharan <ranjani.sridharan(a)linux.intel.com> --- topology/sof/pipe-dai-capture.m4 | 2 +- topology/sof/pipe-src-capture.m4 | 4 ++-- topology/sof/pipe-volume-capture.m4 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/topology/sof/pipe-dai-capture.m4 b/topology/sof/pipe-dai-capture.m4 index ab63efd..e69991e 100644 --- a/topology/sof/pipe-dai-capture.m4 +++ b/topology/sof/pipe-dai-capture.m4 @@ -1,4 +1,4 @@ -# DAI Playback connector +# DAI Capture connector # Include topology builder include(`local.m4') diff --git a/topology/sof/pipe-src-capture.m4 b/topology/sof/pipe-src-capture.m4 index c843a6c..dc55dd2 100644 --- a/topology/sof/pipe-src-capture.m4 +++ b/topology/sof/pipe-src-capture.m4 @@ -12,7 +12,7 @@ include(`local.m4') # Components and Buffers # -# Host "Passthrough Playback" PCM uses pipeline DMAC and channel +# Host "Passthrough Capture" PCM uses pipeline DMAC and channel # with 4 sink and 0 source periods W_PCM_CAPTURE(Passthrough Capture, PIPELINE_DMAC, PIPELINE_DMAC_CHAN, 4, 0, 2) @@ -35,7 +35,7 @@ SectionData."media_src_conf" { # "SRC" has 4 source and 4 sink periods W_SRC(0, PIPELINE_FORMAT, 4, 4, media_src_conf, 2) -# Playback Buffers +# Capture Buffers W_BUFFER(0, COMP_BUFFER_SIZE(4, COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES)) W_BUFFER(1, COMP_BUFFER_SIZE(4, diff --git a/topology/sof/pipe-volume-capture.m4 b/topology/sof/pipe-volume-capture.m4 index 96ca6f9..6d7803f 100644 --- a/topology/sof/pipe-volume-capture.m4 +++ b/topology/sof/pipe-volume-capture.m4 @@ -44,12 +44,12 @@ SectionControlMixer.STR(Master Capture Volume) { # Host "Passthrough Capture" PCM uses pipeline DMAC and channel # with 0 sink and 2 source periods -W_PCM_CAPTURE(Passthrough Playback, PIPELINE_DMAC, PIPELINE_DMAC_CHAN, 0, 2, 2) +W_PCM_CAPTURE(Passthrough Capture, PIPELINE_DMAC, PIPELINE_DMAC_CHAN, 0, 2, 2) # "Volume" has 2 source and 2 sink periods W_PGA(0, PIPELINE_FORMAT, 2, 2, 2, "Master Capture Volume") -# Playback Buffers +# Capture Buffers W_BUFFER(0, COMP_BUFFER_SIZE(2, COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES)) W_BUFFER(1, COMP_BUFFER_SIZE(2, -- 2.14.1
2 1
0 0
[Sound-open-firmware] [PATCH] topology: test: change to use volume topology files for apl at the moment.
by Keyon Jie 08 Feb '18

08 Feb '18
As it doesn't work for pass through at the moment. Signed-off-by: Keyon Jie <yang.jie(a)linux.intel.com> --- topology/test/tplg-build.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/topology/test/tplg-build.sh b/topology/test/tplg-build.sh index d322ce7..047ef6b 100755 --- a/topology/test/tplg-build.sh +++ b/topology/test/tplg-build.sh @@ -70,7 +70,8 @@ simple_test baytrail volume "Baytrail Audio" s24le 2 s24le 25 24 2400000 1920000 simple_test baytrail volume "Baytrail Audio" s16le 2 s24le 25 24 2400000 19200000 simple_test baytrail src "Baytrail Audio" s24le 2 s24le 25 24 2400000 19200000 -simple_test nocodec passthrough "NoCodec" s16le 4 s16le 16 16 1536000 24576000 -simple_test apollolake passthrough "SSP4-Codec" s16le 4 s16le 16 16 1536000 24576000 +# for APL +simple_test nocodec volume "NoCodec" s16le 4 s16le 16 16 1536000 24576000 +simple_test codec volume "SSP4-Codec" s16le 4 s16le 16 16 1536000 24576000 -- 2.11.0
2 1
0 0
[Sound-open-firmware] [PATCH 1/8] core: dma: Add DMA copy API.
by Keyon Jie 08 Feb '18

08 Feb '18
From: Liam Girdwood <liam.r.girdwood(a)linux.intel.com> This API allows clients to manually inform the DMAC when they need more data copied. The DMAC can then copy the desired amount of data. Signed-off-by: Liam Girdwood <liam.r.girdwood(a)linux.intel.com> --- src/include/reef/dma.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/reef/dma.h b/src/include/reef/dma.h index 77f8f71..80ff8d4 100644 --- a/src/include/reef/dma.h +++ b/src/include/reef/dma.h @@ -94,6 +94,7 @@ struct dma_ops { int (*start)(struct dma *dma, int channel); int (*stop)(struct dma *dma, int channel); + int (*copy)(struct dma *dma, int channel, int bytes); int (*pause)(struct dma *dma, int channel); int (*release)(struct dma *dma, int channel); int (*status)(struct dma *dma, int channel, @@ -183,6 +184,11 @@ static inline int dma_stop(struct dma *dma, int channel) return dma->ops->stop(dma, channel); } +static inline int dma_copy(struct dma *dma, int channel, int bytes) +{ + return dma->ops->copy(dma, channel, bytes); +} + static inline int dma_pause(struct dma *dma, int channel) { return dma->ops->pause(dma, channel); -- 2.11.0
2 8
0 0
[Sound-open-firmware] [PATCH_V2] ssp: add ssp support for APL and CNL
by Rander Wang 08 Feb '18

08 Feb '18
Now it supports I2S & TDM4 master mode and no MN devide used. For 19.2M clock, 16bit 48K stream maybe need to pack to 20bit 48K. --- V2: refine signed of Contributor: Rander Wang <rander.wang(a)linux.intel.com> Signed-off-by: Keyon Jie <yang.jie(a)linux.intel.com> --- configure.ac | 1 + src/drivers/Makefile.am | 9 +- src/drivers/apl-ssp.c | 547 ++++++++++++++++++++++++++++++++++++++++++++++++ src/include/reef/ssp.h | 66 +++++- 4 files changed, 612 insertions(+), 11 deletions(-) create mode 100644 src/drivers/apl-ssp.c diff --git a/configure.ac b/configure.ac index 05a3bee..1c84020 100644 --- a/configure.ac +++ b/configure.ac @@ -212,6 +212,7 @@ AM_CONDITIONAL(BUILD_APOLLOLAKE, test "$FW_NAME" = "apl") AM_CONDITIONAL(BUILD_CANNONLAKE, test "$FW_NAME" = "cnl") AM_CONDITIONAL(BUILD_BOOTLOADER, test "$FW_NAME" = "cnl") AM_CONDITIONAL(BUILD_MODULE, test "$FW_NAME" = "apl" -o "$FW_NAME" = "cnl") +AM_CONDITIONAL(BUILD_APL_SSP, test "$FW_NAME" = "apl" -o "$FW_NAME" = "cnl") # DSP core support (Optional) AC_ARG_WITH([dsp-core], diff --git a/src/drivers/Makefile.am b/src/drivers/Makefile.am index 8c507fa..53b52af 100644 --- a/src/drivers/Makefile.am +++ b/src/drivers/Makefile.am @@ -1,9 +1,16 @@ noinst_LIBRARIES = libdrivers.a libdrivers_a_SOURCES = \ - ssp.c \ dw-dma.c +if BUILD_APL_SSP +libdrivers_a_SOURCES += \ + apl-ssp.c +else + libdrivers_a_SOURCES += \ + ssp.c +endif + libdrivers_a_CFLAGS = \ $(ARCH_CFLAGS) \ $(REEF_INCDIR) \ diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c new file mode 100644 index 0000000..09adee2 --- /dev/null +++ b/src/drivers/apl-ssp.c @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Intel Corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Author: Liam Girdwood <liam.r.girdwood(a)linux.intel.com> + * Keyon Jie <yang.jie(a)linux.intel.com> + * Rander Wang <rander.wang(a)linux.intel.com> + */ + +#include <errno.h> +#include <stdbool.h> +#include <reef/stream.h> +#include <reef/ssp.h> +#include <reef/alloc.h> +#include <reef/interrupt.h> + +/* tracing */ +#define trace_ssp(__e) trace_event(TRACE_CLASS_SSP, __e) +#define trace_ssp_error(__e) trace_error(TRACE_CLASS_SSP, __e) +#define tracev_ssp(__e) tracev_event(TRACE_CLASS_SSP, __e) + +/* save SSP context prior to entering D3 */ +static int ssp_context_store(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + ssp->sscr0 = ssp_read(dai, SSCR0); + ssp->sscr1 = ssp_read(dai, SSCR1); + + /* FIXME: need to store sscr2,3,4,5 */ + ssp->psp = ssp_read(dai, SSPSP); + + return 0; +} + +/* restore SSP context after leaving D3 */ +static int ssp_context_restore(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + ssp_write(dai, SSCR0, ssp->sscr0); + ssp_write(dai, SSCR1, ssp->sscr1); + /* FIXME: need to restore sscr2,3,4,5 */ + ssp_write(dai, SSPSP, ssp->psp); + + return 0; +} + +/* Digital Audio interface formatting */ +static inline int ssp_set_config(struct dai *dai, + struct sof_ipc_dai_config *config) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + uint32_t sscr0; + uint32_t sscr1; + uint32_t sscr2; + uint32_t sscr3; + uint32_t sspsp; + uint32_t sspsp2; + uint32_t sstsa; + uint32_t ssrsa; + uint32_t ssto; + uint32_t ssioc; + uint32_t mdiv; + uint32_t bdiv; + uint32_t mdivc; + uint32_t mdivr; + uint32_t i2s_m; + uint32_t i2s_n; + uint32_t data_size; + uint32_t start_delay; + uint32_t frame_len = 0; + bool inverted_frame = false; + int ret = 0; + + spin_lock(&ssp->lock); + + /* is playback/capture already running */ + if (ssp->state[DAI_DIR_PLAYBACK] == COMP_STATE_ACTIVE || + ssp->state[DAI_DIR_CAPTURE] == COMP_STATE_ACTIVE) { + trace_ssp_error("ec1"); + ret = -EINVAL; + goto out; + } + + trace_ssp("cos"); + + /* reset SSP settings */ + /* sscr0 dynamic settings are DSS, EDSS, SCR, FRDC, ECS */ + /* + * FIXME: MOD, ACS, NCS are not set, + * no support for network mode for now + */ + sscr0 = SSCR0_PSP | SSCR0_RIM | SSCR0_TIM; + + /* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR */ + sscr1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_RWOT | SSCR1_TRAIL; +// sscr1 |= SSCR1_TIE | SSCR1_RIE; + + /* sscr2 dynamic setting is LJDFD */ + sscr2 = SSCR2_SDFD | SSCR2_TURM1; + + /* sscr3 dynamic settings are TFT, RFT */ + sscr3 = 0; + + /* sspsp dynamic settings are SCMODE, SFRMP, DMYSTRT, SFRMWDTH */ +// sspsp = SSPSP_ETDS; /* make sure SDO line is tri-stated when inactive */ + sspsp = 0; + + ssp->config = *config; + ssp->params = config->ssp[0]; + + /* sspsp2 no dynamic setting */ + sspsp2 = 0x0; + + /* ssioc dynamic setting is SFCR */ + ssioc = SSIOC_SCOE; + + /* i2s_m M divider setting, default 1 */ + i2s_m = 0x1; + + /* i2s_n N divider setting, default 1 */ + i2s_n = 0x1; + + /* ssto no dynamic setting */ + ssto = 0x0; + + /* sstsa dynamic setting is TTSA, default 2 slots */ + sstsa = config->tx_slot_mask; + + /* ssrsa dynamic setting is RTSA, default 2 slots */ + ssrsa = config->rx_slot_mask; + + /* clock masters */ + sscr1 &= ~SSCR1_SFRMDIR; + + trace_value(config->format); + switch (config->format & SOF_DAI_FMT_MASTER_MASK) { + case SOF_DAI_FMT_CBM_CFM: + sscr0 |= SSCR0_ECS; /* external clock used */ + sscr1 |= SSCR1_SCLKDIR; + /* + * FIXME: does SSRC1.SCFR need to be set + * when codec is master ? + */ + break; + case SOF_DAI_FMT_CBS_CFS: + sscr1 |= SSCR1_SCFR; + ssioc |= SSIOC_SFCR; + break; + case SOF_DAI_FMT_CBM_CFS: + sscr0 |= SSCR0_ECS; /* external clock used */ + sscr1 |= SSCR1_SCLKDIR; + /* + * FIXME: does SSRC1.SCFR need to be set + * when codec is master ? + */ + /* FIXME: this mode has not been tested */ + break; + case SOF_DAI_FMT_CBS_CFM: + sscr1 |= SSCR1_SCFR; + /* FIXME: this mode has not been tested */ + break; + default: + trace_ssp_error("ec2"); + ret = -EINVAL; + goto out; + } + + /* clock signal polarity */ + switch (config->format & SOF_DAI_FMT_INV_MASK) { + case SOF_DAI_FMT_NB_NF: + break; + case SOF_DAI_FMT_NB_IF: + break; + case SOF_DAI_FMT_IB_IF: + sspsp |= SSPSP_SCMODE(2); + inverted_frame = true; /* handled later with format */ + break; + case SOF_DAI_FMT_IB_NF: + sspsp |= SSPSP_SCMODE(2); + inverted_frame = true; /* handled later with format */ + break; + default: + trace_ssp_error("ec3"); + ret = -EINVAL; + goto out; + } + +#ifdef CLK_TYPE /* not enabled, keep the code for reference */ + /* TODO: allow topology to define SSP clock type */ + config->ssp[0].clk_id = SSP_CLK_EXT; + + /* clock source */ + switch (config->ssp[0].clk_id) { + case SSP_CLK_AUDIO: + sscr0 |= SSCR0_ACS; + break; + case SSP_CLK_NET_PLL: + sscr0 |= SSCR0_MOD; + break; + case SSP_CLK_EXT: + sscr0 |= SSCR0_ECS; + break; + case SSP_CLK_NET: + sscr0 |= SSCR0_NCS | SSCR0_MOD; + break; + default: + trace_ssp_error("ec4"); + ret = -EINVAL; + goto out; + } +#else + sscr0 |= SSCR0_MOD | SSCR0_ACS; +#endif + + /* BCLK is generated from MCLK - must be divisable */ + if (config->mclk % config->bclk) { + trace_ssp_error("ec5"); + ret = -EINVAL; + goto out; + } + + /* divisor must be within SCR range */ + mdiv = (config->mclk / config->bclk) - 1; + if (mdiv > (SSCR0_SCR_MASK >> 8)) { + trace_ssp_error("ec6"); + ret = -EINVAL; + goto out; + } + + /* set the SCR divisor */ + sscr0 |= SSCR0_SCR(mdiv); + + /* calc frame width based on BCLK and rate - must be divisable */ + if (config->bclk % config->fclk) { + trace_ssp_error("ec7"); + ret = -EINVAL; + goto out; + } + + /* must be enouch BCLKs for data */ + bdiv = config->bclk / config->fclk; + if (bdiv < config->sample_container_bits * + ((config->rx_slot_mask + 1) / 2)) { + trace_ssp_error("ec8"); + ret = -EINVAL; + goto out; + } + + /* sample_container_bits must be <= 38 for SSP */ + if (config->sample_container_bits > 38) { + trace_ssp_error("ec9"); + ret = -EINVAL; + goto out; + } + + /* format */ + switch (config->format & SOF_DAI_FMT_FORMAT_MASK) { + case SOF_DAI_FMT_I2S: + + start_delay = config->sample_container_bits > + config->sample_valid_bits ? 1 : 0; + + sscr0 |= SSCR0_FRDC(config->num_slots); + + /* set asserted frame length */ + frame_len = config->sample_container_bits; + + /* handle frame polarity, I2S default is falling/active low */ + sspsp |= SSPSP_SFRMP(!inverted_frame); + + break; + + case SOF_DAI_FMT_LEFT_J: + + start_delay = 0; + + sscr0 |= SSCR0_FRDC(config->num_slots); + + /* LJDFD enable */ + sscr2 &= ~SSCR2_LJDFD; + + /* set asserted frame length */ + frame_len = config->sample_container_bits; + + /* LEFT_J default is rising/active high, opposite of I2S */ + sspsp |= SSPSP_SFRMP(inverted_frame); + + break; + case SOF_DAI_FMT_DSP_A: + + start_delay = config->sample_container_bits > + config->sample_valid_bits ? 1 : 0; + + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->num_slots); + + /* set asserted frame length */ + frame_len = config->sample_container_bits; + + /* handle frame polarity, DSP_A default is rising/active high */ + sspsp |= SSPSP_SFRMP(inverted_frame); + + break; + case SOF_DAI_FMT_DSP_B: + + start_delay = 0; + + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->num_slots); + + /* set asserted frame length */ + frame_len = config->sample_container_bits; + + /* handle frame polarity, DSP_A default is rising/active high */ + sspsp |= SSPSP_SFRMP(inverted_frame); + + break; + default: + trace_ssp_error("eca"); + ret = -EINVAL; + goto out; + } + + sspsp |= SSPSP_DMYSTRT(start_delay); + sspsp |= SSPSP_SFRMWDTH(frame_len); + + data_size = config->sample_valid_bits; + + if (data_size > 16) + sscr0 |= (SSCR0_EDSS | SSCR0_DSIZE(data_size - 16)); + else + sscr0 |= SSCR0_DSIZE(data_size); + + mdivc = 0x00100001; + /* bypass divider for MCLK */ + mdivr = 0x00000fff; + + trace_ssp("coe"); + ssp_write(dai, SSCR0, sscr0); + ssp_write(dai, SSCR1, sscr1); + ssp_write(dai, SSCR2, sscr2); + ssp_write(dai, SSCR3, sscr3); + ssp_write(dai, SSPSP, sspsp); + ssp_write(dai, SSPSP2, sspsp2); + ssp_write(dai, SSIOC, ssioc); + ssp_write(dai, SSTO, ssto); + ssp_write(dai, SSTSA, sstsa); + ssp_write(dai, SSRSA, ssrsa); + + trace_value(sscr0); + trace_value(sscr1); + trace_value(ssto); + trace_value(sspsp); + trace_value(sstsa); + trace_value(ssrsa); + trace_value(sscr2); + trace_value(sspsp2); + trace_value(sscr3); + trace_value(ssioc); + + mn_reg_write(0x0, mdivc); + mn_reg_write(0x80, mdivr); + mn_reg_write(0x100 + config->id * 0x8 + 0x0, i2s_m); + mn_reg_write(0x100 + config->id * 0x8 + 0x4, i2s_n); + + ssp->state[DAI_DIR_PLAYBACK] = COMP_STATE_PREPARE; + ssp->state[DAI_DIR_CAPTURE] = COMP_STATE_PREPARE; + +out: + spin_unlock(&ssp->lock); + + return ret; +} + +/* Digital Audio interface formatting */ +static inline int ssp_set_loopback_mode(struct dai *dai, uint32_t lbm) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + trace_ssp("loo"); + spin_lock(&ssp->lock); + + ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); + + spin_unlock(&ssp->lock); + + return 0; +} + +/* start the SSP for either playback or capture */ +static void ssp_start(struct dai *dai, int direction) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + spin_lock(&ssp->lock); + + /* enable port */ + ssp_update_bits(dai, SSCR0, SSCR0_SSE, SSCR0_SSE); + ssp->state[direction] = COMP_STATE_ACTIVE; + + trace_ssp("sta"); + + /* enable DMA */ + if (direction == DAI_DIR_PLAYBACK) { + ssp_update_bits(dai, SSCR1, SSCR1_TSRE, SSCR1_TSRE); + ssp_update_bits(dai, SSTSA, 0x1 << 8, 0x1 << 8); + } else { + ssp_update_bits(dai, SSCR1, SSCR1_RSRE, SSCR1_RSRE); + ssp_update_bits(dai, SSRSA, 0x1 << 8, 0x1 << 8); + } + + spin_unlock(&ssp->lock); +} + +/* stop the SSP for either playback or capture */ +static void ssp_stop(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + spin_lock(&ssp->lock); + + /* stop Rx if we are not capturing */ + if (ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_ACTIVE) { + ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0); + ssp_update_bits(dai, SSTSA, 0x1 << 8, 0x0 << 8); + trace_ssp("Ss0"); + } + + /* stop Tx if we are not playing */ + if (ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_ACTIVE) { + ssp_update_bits(dai, SSCR1, SSCR1_TSRE, 0); + ssp_update_bits(dai, SSRSA, 0x1 << 8, 0x0 << 8); + trace_ssp("Ss1"); + } + + /* disable SSP port if no users */ + if (ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_ACTIVE && + ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_ACTIVE) { + ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0); + ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; + ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; + trace_ssp("Ss2"); + } + + spin_unlock(&ssp->lock); +} + +static int ssp_trigger(struct dai *dai, int cmd, int direction) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + trace_ssp("tri"); + + switch (cmd) { + case COMP_CMD_START: + if (ssp->state[direction] == COMP_STATE_PREPARE || + ssp->state[direction] == COMP_STATE_PAUSED) + ssp_start(dai, direction); + break; + case COMP_CMD_RELEASE: + if (ssp->state[direction] == COMP_STATE_PAUSED || + ssp->state[direction] == COMP_STATE_PREPARE) + ssp_start(dai, direction); + break; + case COMP_CMD_STOP: + case COMP_CMD_PAUSE: + ssp->state[direction] = COMP_STATE_PAUSED; + ssp_stop(dai); + break; + case COMP_CMD_RESUME: + ssp_context_restore(dai); + break; + case COMP_CMD_SUSPEND: + ssp_context_store(dai); + break; + default: + break; + } + + return 0; +} + +/* clear IRQ sources atm */ +static void ssp_irq_handler(void *data) +{ + struct dai *dai = data; + + trace_ssp("irq"); + trace_value(ssp_read(dai, SSSR)); + + /* clear IRQ */ + ssp_write(dai, SSSR, ssp_read(dai, SSSR)); + platform_interrupt_clear(ssp_irq(dai), 1); +} + +static int ssp_probe(struct dai *dai) +{ + struct ssp_pdata *ssp; + + /* allocate private data */ + ssp = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*ssp)); + dai_set_drvdata(dai, ssp); + + spinlock_init(&ssp->lock); + + ssp->state[DAI_DIR_PLAYBACK] = COMP_STATE_READY; + ssp->state[DAI_DIR_CAPTURE] = COMP_STATE_READY; + + /* register our IRQ handler */ + interrupt_register(ssp_irq(dai), ssp_irq_handler, dai); + platform_interrupt_unmask(ssp_irq(dai), 1); + interrupt_enable(ssp_irq(dai)); + + return 0; +} + +const struct dai_ops ssp_ops = { + .trigger = ssp_trigger, + .set_config = ssp_set_config, + .pm_context_store = ssp_context_store, + .pm_context_restore = ssp_context_restore, + .probe = ssp_probe, + .set_loopback_mode = ssp_set_loopback_mode, +}; diff --git a/src/include/reef/ssp.h b/src/include/reef/ssp.h index c00d14c..e041121 100644 --- a/src/include/reef/ssp.h +++ b/src/include/reef/ssp.h @@ -38,6 +38,8 @@ #include <reef/trace.h> #include <reef/wait.h> +#define BIT(x) (1 << (x)) + #define SSP_CLK_AUDIO 0 #define SSP_CLK_NET_PLL 1 #define SSP_CLK_EXT 2 @@ -55,11 +57,17 @@ #define SSTSA 0x30 #define SSRSA 0x34 #define SSTSS 0x38 + +#if defined CONFIG_BAYTRAIL ||\ + defined CONFIG_CHERRYTRAIL ||\ + defined CONFIG_BROADWELL ||\ + defined CONFIG_HASWELL #define SSCR2 0x40 #define SFIFOTT 0x6C #define SSCR3 0x70 #define SSCR4 0x74 #define SSCR5 0x78 +#endif extern const struct dai_ops ssp_ops; @@ -112,17 +120,28 @@ extern const struct dai_ops ssp_ops; #define SSCR1_TTE (1 << 30) #define SSCR1_TTELP (1 << 31) +#if defined CONFIG_BAYTRAIL ||\ + defined CONFIG_CHERRYTRAIL ||\ + defined CONFIG_BROADWELL ||\ + defined CONFIG_HASWELL /* SSCR2 bits */ -#define SSCR2_URUN_FIX0 (1 << 0) -#define SSCR2_URUN_FIX1 (1 << 1) -#define SSCR2_SLV_EXT_CLK_RUN_EN (1 << 2) -#define SSCR2_CLK_DEL_EN (1 << 3) -#define SSCR2_UNDRN_FIX_EN (1 << 6) -#define SSCR2_FIFO_EMPTY_FIX_EN (1 << 7) -#define SSCR2_ASRC_CNTR_EN (1 << 8) -#define SSCR2_ASRC_CNTR_CLR (1 << 9) -#define SSCR2_ASRC_FRM_CNRT_EN (1 << 10) -#define SSCR2_ASRC_INTR_MASK (1 << 11) +#define SSCR2_URUN_FIX0 BIT(0) +#define SSCR2_URUN_FIX1 BIT(1) +#define SSCR2_SLV_EXT_CLK_RUN_EN BIT(2) +#define SSCR2_CLK_DEL_EN BIT(3) +#define SSCR2_UNDRN_FIX_EN BIT(6) +#define SSCR2_FIFO_EMPTY_FIX_EN BIT(7) +#define SSCR2_ASRC_CNTR_EN BIT(8) +#define SSCR2_ASRC_CNTR_CLR BIT(9) +#define SSCR2_ASRC_FRM_CNRT_EN BIT(10) +#define SSCR2_ASRC_INTR_MASK BIT(11) +#elif defined CONFIG_APOLLOLAKE || defined CONFIG_CANNONLAKE +#define SSCR2_TURM1 BIT(1) +#define SSCR2_SDFD BIT(14) +#define SSCR2_SDPM BIT(16) +#define SSCR2_LJDFD BIT(17) +#endif + /* SSR bits */ #define SSSR_TNF (1 << 2) @@ -143,6 +162,17 @@ extern const struct dai_ops ssp_ops; #define SSPSP_DMYSTOP(x) ((x) << 23) #define SSPSP_FSRT (1 << 25) +#if defined CONFIG_APOLLOLAKE || defined CONFIG_CANNONLAKE +#define SSPSP_EDMYSTOP(x) ((x) << 26) +#define SSTSS 0x38 +#define SSCR2 0x40 +#define SSPSP2 0x44 +#define SSCR3 0x48 +#define SSIOC 0x4C + +#define SSP_REG_MAX SSIOC +#endif + /* SSCR3 bits */ #define SSCR3_FRM_MST_EN (1 << 0) #define SSCR3_I2S_MODE_EN (1 << 1) @@ -169,6 +199,22 @@ extern const struct dai_ops ssp_ops; #define SFIFOTT_TX(x) ((x) - 1) #define SFIFOTT_RX(x) (((x) - 1) << 16) +#if defined CONFIG_APOLLOLAKE || defined CONFIG_CANNONLAKE +#define SSTSA_TSEN BIT(8) +#define SSRSA_RSEN BIT(8) + +#define SSCR3_TFL_MASK (0x0000003f) +#define SSCR3_RFL_MASK (0x00003f00) +#define SSCR3_TFT_MASK (0x003f0000) +#define SSCR3_TX(x) (((x) - 1) << 16) +#define SSCR3_RFT_MASK (0x3f000000) +#define SSCR3_RX(x) (((x) - 1) << 24) + +#define SSIOC_TXDPDEB BIT(1) +#define SSIOC_SFCR BIT(4) +#define SSIOC_SCOE BIT(5) +#endif + /* tracing */ #define trace_ssp(__e) trace_event(TRACE_CLASS_SSP, __e) #define trace_ssp_error(__e) trace_error(TRACE_CLASS_SSP, __e) -- 2.14.1
2 1
0 0
[Sound-open-firmware] [PATCH] ASoC: SOF: topology: add handle to buffer type
by Keyon Jie 08 Feb '18

08 Feb '18
Align with SOFT topology and SOF, add handle to buffer type. Signed-off-by: Keyon Jie <yang.jie(a)linux.intel.com> --- include/uapi/sound/sof-ipc.h | 7 +++++++ include/uapi/sound/sof-topology.h | 1 + sound/soc/sof/topology.c | 6 ++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/uapi/sound/sof-ipc.h b/include/uapi/sound/sof-ipc.h index 741b412545b7..9a81896780ba 100644 --- a/include/uapi/sound/sof-ipc.h +++ b/include/uapi/sound/sof-ipc.h @@ -521,10 +521,17 @@ struct sof_ipc_comp { * Component Buffers */ +/* types of buffer */ +enum sof_buffer_type { + SOF_BUFF_GENERAL = 0, + SOF_BUFF_DMA = 1, /* dma buffer */ +}; + /* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */ struct sof_ipc_buffer { struct sof_ipc_comp comp; uint32_t size; /* buffer size in bytes */ + enum sof_buffer_type type; /* buffer type */ } __attribute__((packed)); diff --git a/include/uapi/sound/sof-topology.h b/include/uapi/sound/sof-topology.h index 6fe695c46386..e855ef48fd1a 100644 --- a/include/uapi/sound/sof-topology.h +++ b/include/uapi/sound/sof-topology.h @@ -33,6 +33,7 @@ /* buffers */ #define SOF_TKN_BUF_SIZE 100 +#define SOF_TKN_BUF_TYPE 101 /* DAI */ #define SOF_TKN_DAI_DMAC 151 diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 2d813335f3d2..3f2e9d72fba5 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -150,6 +150,8 @@ static int get_token_dai_type(void *elem ,void *object, u32 offset, u32 size) static const struct sof_topology_token buffer_tokens[] = { {SOF_TKN_BUF_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, offsetof(struct sof_ipc_buffer, size), 0}, + {SOF_TKN_BUF_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_buffer, type), 0}, }; /* DAI */ @@ -554,8 +556,8 @@ static int sof_widget_load_buffer(struct snd_soc_component *scomp, int index, sof_parse_tokens(scomp, &buffer, buffer_tokens, ARRAY_SIZE(buffer_tokens), private->array, private->size); - dev_dbg(sdev->dev, "buffer %s: size %d\n", - swidget->widget->name, buffer.size); + dev_dbg(sdev->dev, "buffer %s: size %d, type %d\n", + swidget->widget->name, buffer.size, buffer.type); return sof_ipc_tx_message(sdev->ipc, buffer.comp.hdr.cmd, &buffer, sizeof(buffer), r, sizeof(*r)); -- 2.11.0
2 9
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • Older →

HyperKitty Powered by HyperKitty version 1.3.8.