[alsa-devel] [PATCH 0/7] Enablement of BT I2S controller instance for AMD APUs
This patch set updates Audio CoProcessor (ACP) audio drivers to enable BT I2S controller instance. In Audio Coprocessor, There are three I2S controllers can be configured/enabled.(I2S SP, I2S MICSP, BT I2S) Default enabled I2S controller instance is I2S SP instance. There is a requirement to enable BT I2S controller Instance along with I2S SP controller instance. This patch set bring up functionality to render & capture on BT I2S controller instance.
The current code is based on asoc-next, but I'm happy to rebase on whatever tree this ends up going through if there are any problems applying.
Vijendar Mukunda (7): ASoC: amd: dma driver changes for BT I2S controller instance ASoC: amd: dma descriptor changes for BT I2S Instance ASoC: amd: Interrupt handler changes for BT I2S instance ASoC: amd: prepare callback modifications for bt i2s instance ASoC: amd: pointer and trigger callback modifications for bt i2s ASoC: amd: 16bit resolution support for bt i2s instance ASoC: amd: enabling bt i2s config after acp reset
sound/soc/amd/acp-pcm-dma.c | 521 +++++++++++++++++++++++++++++++++++--------- sound/soc/amd/acp.h | 52 ++++- 2 files changed, 460 insertions(+), 113 deletions(-)
With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance.
BT I2S is bi-directional dai and same is used for playback and capture. Added condition checks to differentiate I2S instance based on cpu dai name.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Signed-off-by: Akshu Agrawal akshu.agrawal@amd.com --- sound/soc/amd/acp-pcm-dma.c | 112 +++++++++++++++++++++++++++++++++++--------- sound/soc/amd/acp.h | 8 ++++ 2 files changed, 99 insertions(+), 21 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 540088d..4611706 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -710,7 +710,32 @@ static int acp_dma_open(struct snd_pcm_substream *substream) default: runtime->hw = acp_pcm_hardware_playback; } + /* ACP DMA Driver implemented based on ACP 2.x stack. + * It uses Designware I2S controller. + * AMD Gpu Driver creates device instances for playback & capture scenarios + * for both the I2S controller instances.( I2S SP & I2S BT). + * It has fixed mapping as mentioned below. + * designware-i2s.1.auto cpu dai will be used for I2S SP Instance playback device. + * designware-i2s.2.auto cpu dai will be used for I2S SP Instance capture device. + * designware-i2s.3.auto cpu dai will be used for I2S BT Instance playback/capture device. + */ + if (strcmp(prtd->cpu_dai->name, "designware-i2s.1.auto") == 0) { + adata->i2s_play_instance = I2S_SP_INSTANCE; + adata->i2ssp_renderbytescount = 0; + } else if (strcmp(prtd->cpu_dai->name, "designware-i2s.3.auto") == 0) { + adata->i2s_play_instance = I2S_BT_INSTANCE; + adata->i2sbt_renderbytescount = 0; + } else + return -EINVAL; } else { + if (strcmp(prtd->cpu_dai->name, "designware-i2s.2.auto") == 0) { + adata->i2s_capture_instance = I2S_SP_INSTANCE; + adata->i2ssp_capturebytescount = 0; + } else if (strcmp(prtd->cpu_dai->name, "designware-i2s.3.auto") == 0) { + adata->i2s_capture_instance = I2S_BT_INSTANCE; + adata->i2sbt_capturebytescount = 0; + } else + return -EINVAL; switch (intr_data->asic_type) { case CHIP_STONEY: runtime->hw = acp_st_pcm_hardware_capture; @@ -736,11 +761,19 @@ static int acp_dma_open(struct snd_pcm_substream *substream) * This enablement is not required for another stream, if current * stream is not closed */ - if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream) + if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream && + !intr_data->play_i2sbt_stream && !intr_data->capture_i2sbt_stream) acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - intr_data->play_i2ssp_stream = substream; + switch (adata->i2s_play_instance) { + case I2S_BT_INSTANCE: + intr_data->play_i2sbt_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + intr_data->play_i2ssp_stream = substream; + } /* For Stoney, Memory gating is disabled,i.e SRAM Banks * won't be turned off. The default state for SRAM banks is ON. * Setting SRAM bank state code skipped for STONEY platform. @@ -751,7 +784,14 @@ static int acp_dma_open(struct snd_pcm_substream *substream) bank, true); } } else { - intr_data->capture_i2ssp_stream = substream; + switch (adata->i2s_capture_instance) { + case I2S_BT_INSTANCE: + intr_data->capture_i2sbt_stream = substream; + break; + case I2S_SP_INSTANCE: + default: + intr_data->capture_i2ssp_stream = substream; + } if (intr_data->asic_type != CHIP_STONEY) { for (bank = 5; bank <= 8; bank++) acp_set_sram_bank_state(intr_data->acp_mmio, @@ -1010,34 +1050,48 @@ static int acp_dma_close(struct snd_pcm_substream *substream) struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); struct audio_drv_data *adata = dev_get_drvdata(component->dev);
- kfree(rtd); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - adata->play_i2ssp_stream = NULL; - /* For Stoney, Memory gating is disabled,i.e SRAM Banks - * won't be turned off. The default state for SRAM banks is ON. - * Setting SRAM bank state code skipped for STONEY platform. - * added condition checks for Carrizo platform only - */ - if (adata->asic_type != CHIP_STONEY) { - for (bank = 1; bank <= 4; bank++) - acp_set_sram_bank_state(adata->acp_mmio, bank, - false); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + adata->play_i2sbt_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->play_i2ssp_stream = NULL; + /* For Stoney, Memory gating is disabled,i.e SRAM Banks + * won't be turned off. The default state for SRAM banks is ON. + * Setting SRAM bank state code skipped for STONEY platform. + * added condition checks for Carrizo platform only + */ + if (adata->asic_type != CHIP_STONEY) { + for (bank = 1; bank <= 4; bank++) + acp_set_sram_bank_state(adata->acp_mmio, bank, + false); + } } } else { - adata->capture_i2ssp_stream = NULL; - if (adata->asic_type != CHIP_STONEY) { - for (bank = 5; bank <= 8; bank++) - acp_set_sram_bank_state(adata->acp_mmio, bank, - false); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + adata->capture_i2sbt_stream = NULL; + break; + case I2S_SP_INSTANCE: + default: + adata->capture_i2ssp_stream = NULL; + if (adata->asic_type != CHIP_STONEY) { + for (bank = 5; bank <= 8; bank++) + acp_set_sram_bank_state(adata->acp_mmio, + bank, false); + } } }
/* Disable ACP irq, when the current stream is being closed and * another stream is also not active. */ - if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream) + if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream && + !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream) acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); + kfree(rtd);
return 0; } @@ -1089,6 +1143,8 @@ static int acp_audio_probe(struct platform_device *pdev)
audio_drv_data->play_i2ssp_stream = NULL; audio_drv_data->capture_i2ssp_stream = NULL; + audio_drv_data->play_i2sbt_stream = NULL; + audio_drv_data->capture_i2sbt_stream = NULL;
audio_drv_data->asic_type = *pdata;
@@ -1177,6 +1233,20 @@ static int acp_pcm_resume(struct device *dev) adata->capture_i2ssp_stream->runtime->private_data, adata->asic_type); } + if (adata->asic_type != CHIP_CARRIZO) { + if (adata->play_i2sbt_stream && + adata->play_i2sbt_stream->runtime) { + config_acp_dma(adata->acp_mmio, + adata->play_i2sbt_stream->runtime->private_data, + adata->asic_type); + } + if (adata->capture_i2sbt_stream && + adata->capture_i2sbt_stream->runtime) { + config_acp_dma(adata->acp_mmio, + adata->capture_i2sbt_stream->runtime->private_data, + adata->asic_type); + } + } acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); return 0; } diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index ba01510..e8406b9 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -72,6 +72,8 @@ #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 +#define I2S_SP_INSTANCE 1 +#define I2S_BT_INSTANCE 3 enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0, @@ -88,12 +90,18 @@ struct audio_substream_data { uint64_t size; u64 i2ssp_renderbytescount; u64 i2ssp_capturebytescount; + u64 i2sbt_renderbytescount; + u64 i2sbt_capturebytescount; void __iomem *acp_mmio; + u16 i2s_play_instance; + u16 i2s_capture_instance; };
struct audio_drv_data { struct snd_pcm_substream *play_i2ssp_stream; struct snd_pcm_substream *capture_i2ssp_stream; + struct snd_pcm_substream *play_i2sbt_stream; + struct snd_pcm_substream *capture_i2sbt_stream; void __iomem *acp_mmio; u32 asic_type; };
On Mon, Mar 12, 2018 at 12:04:14PM +0530, Vijendar Mukunda wrote:
* It has fixed mapping as mentioned below.
* designware-i2s.1.auto cpu dai will be used for I2S SP Instance playback device.
* designware-i2s.2.auto cpu dai will be used for I2S SP Instance capture device.
* designware-i2s.3.auto cpu dai will be used for I2S BT Instance playback/capture device.
I'm still not thrilled about this. If we're hard coding names they should be explicitly assigned names so that there's less chance that some other change in the subsystem will change things.
Please make some effort to keep the code within 80 columns too.
On Monday 12 March 2018 11:55 PM, Mark Brown wrote:
On Mon, Mar 12, 2018 at 12:04:14PM +0530, Vijendar Mukunda wrote:
* It has fixed mapping as mentioned below.
* designware-i2s.1.auto cpu dai will be used for I2S SP Instance playback device.
* designware-i2s.2.auto cpu dai will be used for I2S SP Instance capture device.
* designware-i2s.3.auto cpu dai will be used for I2S BT Instance playback/capture device.
I'm still not thrilled about this. If we're hard coding names they should be explicitly assigned names so that there's less chance that some other change in the subsystem will change things.
AMD Gpu driver creates devices for Playback and capture devices for both the I2S Controller instances using MFD framework. Designware driver probe call gets invoked for every device creation with resource information and platform data provided by GPU driver. In runtime , it seems exporting the device resource name from dwc driver to acp dma driver is not possible. We understand your concern, but we have made the all necessary checks to avoid any fall-backs due to this. Our design makes sure that the same naming convention is followed in machine driver too and there also we mention cpu dai name in the same way. We explored other options but this seems to be the best which makes acp dma driver compatible with multiple platforms.
Please make some effort to keep the code within 80 columns too.
We will fix it and share updated patch.
On Wed, Mar 14, 2018 at 04:06:15PM +0530, Mukunda,Vijendar wrote:
Please fix your mail client to word wrap within paragraphs at something substantially less than 80 columns. Doing this makes your messages much easier to read and reply to.
On Monday 12 March 2018 11:55 PM, Mark Brown wrote:
I'm still not thrilled about this. If we're hard coding names they should be explicitly assigned names so that there's less chance that some other change in the subsystem will change things.
AMD Gpu driver creates devices for Playback and capture devices for both the I2S Controller instances using MFD framework. Designware driver probe call gets invoked for every device creation with resource information and platform data provided by GPU driver. In runtime , it seems exporting the device resource name from dwc driver to acp dma driver is not possible.
This is not the case, if you are instantiating a platform device you can pass platform data to it when you do so by initializing the dev.platform_data field.
On Wednesday 14 March 2018 09:54 PM, Mark Brown wrote:
On Wed, Mar 14, 2018 at 04:06:15PM +0530, Mukunda,Vijendar wrote:
Please fix your mail client to word wrap within paragraphs at something substantially less than 80 columns. Doing this makes your messages much easier to read and reply to.
On Monday 12 March 2018 11:55 PM, Mark Brown wrote:
I'm still not thrilled about this. If we're hard coding names they should be explicitly assigned names so that there's less chance that some other change in the subsystem will change things.
AMD Gpu driver creates devices for Playback and capture devices for both the I2S Controller instances using MFD framework. Designware driver probe call gets invoked for every device creation with resource information and platform data provided by GPU driver. In runtime , it seems exporting the device resource name from dwc driver to acp dma driver is not possible.
This is not the case, if you are instantiating a platform device you can pass platform data to it when you do so by initializing the dev.platform_data field.
We understood your point. We will implement required code changes and post updated patch.
As Stoney has SRAM memory limitation ,to support playback & capture on both the I2S controller instances audio buffer size is reduced to 8k.
For playback on I2S SP instance sram bank 1 will be used. For capture on I2S SP instance sram bank 2 will be used. For playback on I2S BT instance sram bank 3 will be used. For capture on I2S BT instance sram bank 4 will be used.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 106 ++++++++++++++++++++++++++++++++++---------- sound/soc/amd/acp.h | 41 +++++++++++++++-- 2 files changed, 120 insertions(+), 27 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 4611706..f401006 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -37,7 +37,7 @@ #define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define MIN_BUFFER MAX_BUFFER
-#define ST_PLAYBACK_MAX_PERIOD_SIZE 8192 +#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096 #define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE #define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define ST_MIN_BUFFER ST_MAX_BUFFER @@ -320,42 +320,99 @@ static void config_acp_dma(void __iomem *acp_mmio, u16 ch1, ch2, destination, dma_dscr_idx;
if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { - pte_offset = ACP_PLAYBACK_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; - destination = TO_ACP_I2S_1; - - } else { - pte_offset = ACP_CAPTURE_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - switch (asic_type) { - case CHIP_STONEY: + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + pte_offset = ACP_ST_I2S_BT_PLAYBACK_PTE_OFFSET; + ch1 = SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM; + ch2 = ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM; sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS; + destination = TO_BLUETOOTH; break; + case I2S_SP_INSTANCE: default: - sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; + switch (asic_type) { + case CHIP_STONEY: + pte_offset = ACP_ST_I2S_SP_PLAYBACK_PTE_OFFSET; + break; + default: + pte_offset = ACP_PLAYBACK_PTE_OFFSET; + } + ch1 = SYSRAM_TO_ACP_CH_NUM; + ch2 = ACP_TO_I2S_DMA_CH_NUM; + sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; + destination = TO_ACP_I2S_1; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + pte_offset = ACP_ST_I2S_BT_CAPTURE_PTE_OFFSET; + ch1 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM; + ch2 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM; + sram_bank = ACP_SHARED_RAM_BANK_4_ADDRESS; + destination = FROM_BLUETOOTH; + break; + case I2S_SP_INSTANCE: + default: + pte_offset = ACP_CAPTURE_PTE_OFFSET; + ch1 = SYSRAM_TO_ACP_CH_NUM; + ch2 = ACP_TO_I2S_DMA_CH_NUM; + switch (asic_type) { + case CHIP_STONEY: + sram_bank = ACP_SHARED_RAM_BANK_2_ADDRESS; + break; + default: + sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; + } + destination = FROM_ACP_I2S_1; } - destination = FROM_ACP_I2S_1; }
acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages, pte_offset); - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + } + }
/* Configure System memory <-> ACP SRAM DMA descriptors */ set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size, audio_config->direction, pte_offset, ch1, sram_bank, dma_dscr_idx, asic_type);
- if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { + switch (audio_config->i2s_play_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH9; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; + } + } else { + switch (audio_config->i2s_capture_instance) { + case I2S_BT_INSTANCE: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH11; + break; + case I2S_SP_INSTANCE: + default: + dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + } + } /* Configure ACP SRAM <-> I2S DMA descriptors */ set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size, audio_config->direction, sram_bank, @@ -385,6 +442,9 @@ static void acp_dma_start(void __iomem *acp_mmio, case ACP_TO_I2S_DMA_CH_NUM: case ACP_TO_SYSRAM_CH_NUM: case I2S_TO_ACP_DMA_CH_NUM: + case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM: + case ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM: + case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM: dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK; break; default: diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index e8406b9..d40749a 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -10,17 +10,29 @@ #define ACP_PLAYBACK_PTE_OFFSET 10 #define ACP_CAPTURE_PTE_OFFSET 0
+/* Playback and Capture Offset for Stoney */ +#define ACP_ST_I2S_SP_PLAYBACK_PTE_OFFSET 0x04 +#define ACP_ST_I2S_SP_CAPTURE_PTE_OFFSET 0x00 +#define ACP_ST_I2S_BT_PLAYBACK_PTE_OFFSET 0x08 +#define ACP_ST_I2S_BT_CAPTURE_PTE_OFFSET 0x0c + #define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4 #define ACP_ONION_CNTL_DEFAULT 0x00000FB4
#define ACP_PHYSICAL_BASE 0x14000
-/* Playback SRAM address (as a destination in dma descriptor) */ +/* In case of I2S SP controller instance, Stoney uses SRAM bank 1 for + * playback and SRAM Bank 2 for capture where as in case of BT I2S + * Instance ,Stoney uses SRAM Bank 3 for playback & SRAM Bank 4 will + * be used for capture.Carrizo uses I2S SP controller instance.SRAM Banks + * 1,2,3,4 will be used for playback & SRAM Banks 5,6,7,8 will be used + * for capture scenario. + */ #define ACP_SHARED_RAM_BANK_1_ADDRESS 0x4002000 - -/* Capture SRAM address (as a source in dma descriptor) */ -#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000 +#define ACP_SHARED_RAM_BANK_2_ADDRESS 0x4004000 #define ACP_SHARED_RAM_BANK_3_ADDRESS 0x4006000 +#define ACP_SHARED_RAM_BANK_4_ADDRESS 0x4008000 +#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000
#define ACP_DMA_RESET_TIME 10000 #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF @@ -35,8 +47,10 @@
#define TO_ACP_I2S_1 0x2 #define TO_ACP_I2S_2 0x4 +#define TO_BLUETOOTH 0x3 #define FROM_ACP_I2S_1 0xa #define FROM_ACP_I2S_2 0xb +#define FROM_BLUETOOTH 0xb
#define ACP_TILE_ON_MASK 0x03 #define ACP_TILE_OFF_MASK 0x02 @@ -57,6 +71,14 @@ #define ACP_TO_SYSRAM_CH_NUM 14 #define I2S_TO_ACP_DMA_CH_NUM 15
+/* Playback DMA Channels for I2S BT instance */ +#define SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM 8 +#define ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM 9 + +/* Capture DMA Channels for I2S BT Instance */ +#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 10 +#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 11 + #define NUM_DSCRS_PER_CHANNEL 2
#define PLAYBACK_START_DMA_DESCR_CH12 0 @@ -69,6 +91,17 @@ #define CAPTURE_START_DMA_DESCR_CH15 6 #define CAPTURE_END_DMA_DESCR_CH15 7
+/* I2S BT Instance DMA Descriptors */ +#define PLAYBACK_START_DMA_DESCR_CH8 8 +#define PLAYBACK_END_DMA_DESCR_CH8 9 +#define PLAYBACK_START_DMA_DESCR_CH9 10 +#define PLAYBACK_END_DMA_DESCR_CH9 11 + +#define CAPTURE_START_DMA_DESCR_CH10 12 +#define CAPTURE_END_DMA_DESCR_CH10 13 +#define CAPTURE_START_DMA_DESCR_CH11 14 +#define CAPTURE_END_DMA_DESCR_CH11 15 + #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02
Interrupt handler changes for BT I2S instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index f401006..8660f36 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -721,6 +721,21 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) acp_mmio, mmACP_EXTERNAL_INTR_STAT); }
+ if ((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_9) == + PLAYBACK_START_DMA_DESCR_CH9) + dscr_idx = PLAYBACK_END_DMA_DESCR_CH8; + else + dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, dscr_idx, + 1, 0); + acp_dma_start(acp_mmio, SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, false); + snd_pcm_period_elapsed(irq_data->play_i2sbt_stream); + acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) { valid_irq = true; if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_15) == @@ -743,6 +758,27 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) acp_mmio, mmACP_EXTERNAL_INTR_STAT); }
+ if ((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_11) == + CAPTURE_START_DMA_DESCR_CH11) + dscr_idx = CAPTURE_END_DMA_DESCR_CH10; + else + dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, dscr_idx, + 1, 0); + acp_dma_start(acp_mmio, ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, false); + acp_reg_write((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + + if ((intr_flag & BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + snd_pcm_period_elapsed(irq_data->capture_i2sbt_stream); + acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + if (valid_irq) return IRQ_HANDLED; else
modified prepare callback for configuring dma channels for BT instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 53 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 8660f36..2b6c9ad 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -1014,25 +1014,54 @@ static int acp_dma_mmap(struct snd_pcm_substream *substream,
static int acp_dma_prepare(struct snd_pcm_substream *substream) { + u16 start_dscr_idx; struct snd_pcm_runtime *runtime = substream->runtime; struct audio_substream_data *rtd = runtime->private_data;
if (!rtd) return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, - PLAYBACK_START_DMA_DESCR_CH12, - NUM_DSCRS_PER_CHANNEL, 0); - config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, - PLAYBACK_START_DMA_DESCR_CH13, - NUM_DSCRS_PER_CHANNEL, 0); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + start_dscr_idx = PLAYBACK_START_DMA_DESCR_CH8; + config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + break; + case I2S_SP_INSTANCE: + default: + start_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; + config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + } } else { - config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM, - CAPTURE_START_DMA_DESCR_CH14, - NUM_DSCRS_PER_CHANNEL, 0); - config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM, - CAPTURE_START_DMA_DESCR_CH15, - NUM_DSCRS_PER_CHANNEL, 0); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + start_dscr_idx = CAPTURE_START_DMA_DESCR_CH10; + config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + break; + case I2S_SP_INSTANCE: + default: + start_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; + config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM, + start_dscr_idx, + NUM_DSCRS_PER_CHANNEL, 0); + config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM, + start_dscr_idx + 2, + NUM_DSCRS_PER_CHANNEL, 0); + } } return 0; }
modified trigger and pointer callbacks for bt i2s instance.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 186 ++++++++++++++++++++++++++++++++------------ 1 file changed, 137 insertions(+), 49 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 2b6c9ad..ad46719 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -958,23 +958,43 @@ static int acp_dma_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); }
-static u64 acp_get_byte_count(void __iomem *acp_mmio, int stream) +static u64 acp_get_byte_count(void __iomem *acp_mmio, u16 instance, int stream) { union acp_dma_count playback_dma_count; union acp_dma_count capture_dma_count; u64 bytescount = 0;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - playback_dma_count.bcount.high = acp_reg_read(acp_mmio, - mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH); - playback_dma_count.bcount.low = acp_reg_read(acp_mmio, - mmACP_I2S_TRANSMIT_BYTE_CNT_LOW); + switch (instance) { + case I2S_BT_INSTANCE: + playback_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH); + playback_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW); + break; + case I2S_SP_INSTANCE: + default: + playback_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH); + playback_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_TRANSMIT_BYTE_CNT_LOW); + } bytescount = playback_dma_count.bytescount; } else { - capture_dma_count.bcount.high = acp_reg_read(acp_mmio, - mmACP_I2S_RECEIVED_BYTE_CNT_HIGH); - capture_dma_count.bcount.low = acp_reg_read(acp_mmio, - mmACP_I2S_RECEIVED_BYTE_CNT_LOW); + switch (instance) { + case I2S_BT_INSTANCE: + capture_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH); + capture_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW); + break; + case I2S_SP_INSTANCE: + default: + capture_dma_count.bcount.high = acp_reg_read(acp_mmio, + mmACP_I2S_RECEIVED_BYTE_CNT_HIGH); + capture_dma_count.bcount.low = acp_reg_read(acp_mmio, + mmACP_I2S_RECEIVED_BYTE_CNT_LOW); + } bytescount = capture_dma_count.bytescount; } return bytescount; @@ -993,14 +1013,32 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream) return -EINVAL;
buffersize = frames_to_bytes(runtime, runtime->buffer_size); - bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (bytescount > rtd->i2ssp_renderbytescount) - bytescount = bytescount - rtd->i2ssp_renderbytescount; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_play_instance, substream->stream); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + if (bytescount > rtd->i2sbt_renderbytescount) + bytescount = bytescount - rtd->i2sbt_renderbytescount; + break; + case I2S_SP_INSTANCE: + default: + if (bytescount > rtd->i2ssp_renderbytescount) + bytescount = bytescount - rtd->i2ssp_renderbytescount; + } } else { - if (bytescount > rtd->i2ssp_capturebytescount) - bytescount = bytescount - rtd->i2ssp_capturebytescount; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_capture_instance, substream->stream); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + if (bytescount > rtd->i2sbt_capturebytescount) + bytescount = bytescount - rtd->i2sbt_capturebytescount; + break; + case I2S_SP_INSTANCE: + default: + if (bytescount > rtd->i2ssp_capturebytescount) + bytescount = bytescount - rtd->i2ssp_capturebytescount; + } } pos = do_div(bytescount, buffersize); return bytes_to_frames(runtime, pos); @@ -1083,54 +1121,104 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: - bytescount = acp_get_byte_count(rtd->acp_mmio, - substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (rtd->i2ssp_renderbytescount == 0) - rtd->i2ssp_renderbytescount = bytescount; - acp_dma_start(rtd->acp_mmio, - SYSRAM_TO_ACP_CH_NUM, false); - while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) & - BIT(SYSRAM_TO_ACP_CH_NUM)) { - if (!loops--) { - dev_err(component->dev, - "acp dma start timeout\n"); - return -ETIMEDOUT; + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_play_instance, + substream->stream); + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + if (rtd->i2sbt_renderbytescount == 0) + rtd->i2sbt_renderbytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM, false); + while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) & + BIT(SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM)) { + if (!loops--) { + dev_err(component->dev, + "acp dma start timeout\n"); + return -ETIMEDOUT; + } + cpu_relax(); } - cpu_relax(); - } - - acp_dma_start(rtd->acp_mmio, + acp_dma_start(rtd->acp_mmio, + ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM, true); + break; + case I2S_SP_INSTANCE: + default: + if (rtd->i2ssp_renderbytescount == 0) + rtd->i2ssp_renderbytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + SYSRAM_TO_ACP_CH_NUM, false); + while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) & + BIT(SYSRAM_TO_ACP_CH_NUM)) { + if (!loops--) { + dev_err(component->dev, + "acp dma start timeout\n"); + return -ETIMEDOUT; + } + cpu_relax(); + } + acp_dma_start(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, true); - + } } else { - if (rtd->i2ssp_capturebytescount == 0) - rtd->i2ssp_capturebytescount = bytescount; - acp_dma_start(rtd->acp_mmio, - I2S_TO_ACP_DMA_CH_NUM, true); + bytescount = acp_get_byte_count(rtd->acp_mmio, + rtd->i2s_capture_instance, + substream->stream); + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + if (rtd->i2sbt_capturebytescount == 0) + rtd->i2sbt_capturebytescount = 0; + acp_dma_start(rtd->acp_mmio, + I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM, true); + break; + case I2S_SP_INSTANCE: + default: + if (rtd->i2ssp_capturebytescount == 0) + rtd->i2ssp_capturebytescount = bytescount; + acp_dma_start(rtd->acp_mmio, + I2S_TO_ACP_DMA_CH_NUM, true); + } } ret = 0; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - /* Need to stop only circular DMA channels : - * ACP_TO_I2S_DMA_CH_NUM / I2S_TO_ACP_DMA_CH_NUM. Non-circular - * channels will stopped automatically after its transfer - * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM - */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = acp_dma_stop(rtd->acp_mmio, + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + ret = acp_dma_stop(rtd->acp_mmio, + SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM); + rtd->i2sbt_renderbytescount = 0; + break; + case I2S_SP_INSTANCE: + default: + ret = acp_dma_stop(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM); - ret = acp_dma_stop(rtd->acp_mmio, - ACP_TO_I2S_DMA_CH_NUM); - rtd->i2ssp_renderbytescount = 0; + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_I2S_DMA_CH_NUM); + rtd->i2ssp_renderbytescount = 0; + } } else { - ret = acp_dma_stop(rtd->acp_mmio, - I2S_TO_ACP_DMA_CH_NUM); - ret = acp_dma_stop(rtd->acp_mmio, + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + ret = acp_dma_stop(rtd->acp_mmio, + I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, + ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM); + rtd->i2sbt_capturebytescount = 0; + break; + case I2S_SP_INSTANCE: + default: + ret = acp_dma_stop(rtd->acp_mmio, + I2S_TO_ACP_DMA_CH_NUM); + ret = acp_dma_stop(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM); - rtd->i2ssp_capturebytescount = 0; + rtd->i2ssp_capturebytescount = 0; + } } break; default:
added 16bit resolution support for bt i2s instance for stoney.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/acp-pcm-dma.c | 23 +++++++++++++++++++---- sound/soc/amd/acp.h | 1 + 2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index ad46719..a6787ac 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -919,10 +919,25 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
if (adata->asic_type == CHIP_STONEY) { val = acp_reg_read(adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; - else - val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (rtd->i2s_play_instance) { + case I2S_BT_INSTANCE: + val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; + break; + case I2S_SP_INSTANCE: + default: + val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; + } + } else { + switch (rtd->i2s_capture_instance) { + case I2S_BT_INSTANCE: + val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; + break; + case I2S_SP_INSTANCE: + default: + val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; + } + } acp_reg_write(val, adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); } size = params_buffer_bytes(params); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index d40749a..cd83a03 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -105,6 +105,7 @@ #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 +#define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 #define I2S_SP_INSTANCE 1 #define I2S_BT_INSTANCE 3 enum acp_dma_priority_level {
after acp reset , it requires to reprogram bt i2s config mux pins to enable bt i2s instance. added bt i2s enablement sequence during acp init.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com --- sound/soc/amd/acp-pcm-dma.c | 5 +++++ sound/soc/amd/acp.h | 2 ++ 2 files changed, 7 insertions(+)
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index a6787ac..f7471ae 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -604,6 +604,11 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type) val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
+ /*For BT instance change pins from UART to BT */ + val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL); + val |= ACP_BT_UART_PAD_SELECT_MASK; + acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL); + /* initiailize Onion control DAGB register */ acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio, mmACP_AXI2DAGB_ONION_CNTL); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index cd83a03..84b3850 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -108,6 +108,8 @@ #define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 #define I2S_SP_INSTANCE 1 #define I2S_BT_INSTANCE 3 +#define ACP_BT_UART_PAD_SELECT_MASK 0x1 + enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
participants (3)
-
Mark Brown
-
Mukunda,Vijendar
-
Vijendar Mukunda