Alsa-devel
Threads by month
- ----- 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
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
November 2019
- 135 participants
- 359 discussions
[alsa-devel] [PATCH v7 4/6] ASoC: amd: add ACP3x TDM mode support
by Ravulapati Vishnu vardhan rao 18 Nov '19
by Ravulapati Vishnu vardhan rao 18 Nov '19
18 Nov '19
ACP3x I2S (CPU DAI) can act in normal I2S and TDM modes. Added support
for TDM mode. Desired mode can be selected from ASoC machine driver.
Signed-off-by: Ravulapati Vishnu vardhan rao <Vishnuvardhanrao.Ravulapati(a)amd.com>
---
sound/soc/amd/raven/acp3x-i2s.c | 42 +++++++++++++++++++++++++++++++----------
sound/soc/amd/raven/acp3x.h | 2 ++
2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
index e97e602..23e4b01 100644
--- a/sound/soc/amd/raven/acp3x-i2s.c
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -44,8 +44,8 @@ static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
u32 rx_mask, int slots, int slot_width)
{
struct i2s_dev_data *adata;
- u32 val;
u16 slot_len;
+ u32 val, flen, reg_val, frmt_reg;
adata = snd_soc_dai_get_drvdata(cpu_dai);
@@ -68,16 +68,38 @@ static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
return -EINVAL;
}
- val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
- rv_writel(val | 0x2, adata->acp3x_base + mmACP_BTTDM_ITER);
- val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
- rv_writel(val | 0x2, adata->acp3x_base + mmACP_BTTDM_IRER);
-
- val = FRM_LEN | (slots << 15) | (slot_len << 18);
- rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT);
- rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT);
+ /* Enable I2S / BT channels TDM and respective
+ * I2S/BT`s TX/RX Formats frame lengths.
+ */
+ flen = FRM_LEN | (slots << 15) | (slot_len << 18);
- adata->tdm_fmt = val;
+ if (adata->substream_type == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (adata->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ frmt_reg = mmACP_BTTDM_TXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ frmt_reg = mmACP_I2STDM_TXFRMT;
+ }
+ } else {
+ switch (adata->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ frmt_reg = mmACP_BTTDM_RXFRMT;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ frmt_reg = mmACP_I2STDM_RXFRMT;
+ }
+ }
+ val = rv_readl(adata->acp3x_base + reg_val);
+ rv_writel(val | 0x2, adata->acp3x_base + reg_val);
+ rv_writel(flen, adata->acp3x_base + frmt_reg);
+ adata->tdm_fmt = flen;
return 0;
}
diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
index c071477..01b283a 100644
--- a/sound/soc/amd/raven/acp3x.h
+++ b/sound/soc/amd/raven/acp3x.h
@@ -76,6 +76,8 @@ struct i2s_dev_data {
bool tdm_mode;
unsigned int i2s_irq;
u32 tdm_fmt;
+ u16 i2s_instance;
+ u32 substream_type;
void __iomem *acp3x_base;
struct snd_pcm_substream *play_stream;
struct snd_pcm_substream *capture_stream;
--
2.7.4
1
0
[alsa-devel] [PATCH v7 3/6] ASoC: amd: Enabling I2S instance in DMA and DAI
by Ravulapati Vishnu vardhan rao 18 Nov '19
by Ravulapati Vishnu vardhan rao 18 Nov '19
18 Nov '19
This patch adds I2S SP support in ACP PCM DMA and DAI.
Added I2S support in DMA and DAI probe,its hw_params handling
its open and close functionalities.
This enable to open and close on the SP instance for
playback and capture.
Signed-off-by: Ravulapati Vishnu vardhan rao <Vishnuvardhanrao.Ravulapati(a)amd.com>
---
sound/soc/amd/raven/acp3x-i2s.c | 119 ++++++++++++++++++----
sound/soc/amd/raven/acp3x-pcm-dma.c | 193 +++++++++++++++++++++++++-----------
sound/soc/amd/raven/acp3x.h | 74 +++++++++++---
3 files changed, 294 insertions(+), 92 deletions(-)
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
index 602920f..e97e602 100644
--- a/sound/soc/amd/raven/acp3x-i2s.c
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -86,10 +86,22 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
u32 val;
u32 reg_val;
+ prtd = substream->private_data;
rtd = substream->runtime->private_data;
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_U8:
@@ -108,11 +120,25 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
default:
return -EINVAL;
}
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg_val = mmACP_BTTDM_ITER;
- else
- reg_val = mmACP_BTTDM_IRER;
-
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ }
+ }
val = rv_readl(rtd->acp3x_base + reg_val);
val = val | (rtd->xfer_resolution << 3);
rv_writel(val, rtd->acp3x_base + reg_val);
@@ -123,10 +149,21 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct i2s_stream_instance *rtd;
- u32 val, period_bytes;
- int ret, reg_val;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
+ u32 ret, val, period_bytes, reg_val, ier_val, water_val;
+ prtd = substream->private_data;
rtd = substream->runtime->private_data;
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
period_bytes = frames_to_bytes(substream->runtime,
substream->runtime->period_size);
switch (cmd) {
@@ -136,31 +173,75 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
rtd->bytescount = acp_get_byte_count(rtd,
substream->stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- reg_val = mmACP_BTTDM_ITER;
- rv_writel(period_bytes, rtd->acp3x_base +
- mmACP_BT_TX_INTR_WATERMARK_SIZE);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ water_val =
+ mmACP_BT_TX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_BTTDM_ITER;
+ ier_val = mmACP_BTTDM_IER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ mmACP_I2S_TX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_I2STDM_ITER;
+ ier_val = mmACP_I2STDM_IER;
+ }
} else {
- reg_val = mmACP_BTTDM_IRER;
- rv_writel(period_bytes, rtd->acp3x_base +
- mmACP_BT_RX_INTR_WATERMARK_SIZE);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ water_val =
+ mmACP_BT_RX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_BTTDM_IRER;
+ ier_val = mmACP_BTTDM_IER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ water_val =
+ mmACP_I2S_RX_INTR_WATERMARK_SIZE;
+ reg_val = mmACP_I2STDM_IRER;
+ ier_val = mmACP_I2STDM_IER;
+ }
}
+ rv_writel(period_bytes, rtd->acp3x_base + water_val);
val = rv_readl(rtd->acp3x_base + reg_val);
val = val | BIT(0);
rv_writel(val, rtd->acp3x_base + reg_val);
- rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
+ rv_writel(1, rtd->acp3x_base + ier_val);
+ ret = 0;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg_val = mmACP_BTTDM_ITER;
- else
- reg_val = mmACP_BTTDM_IRER;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_ITER;
+ ier_val = mmACP_BTTDM_IER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_ITER;
+ ier_val = mmACP_I2STDM_IER;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_val = mmACP_BTTDM_IRER;
+ ier_val = mmACP_BTTDM_IER;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ reg_val = mmACP_I2STDM_IRER;
+ ier_val = mmACP_I2STDM_IER;
+ }
+ }
val = rv_readl(rtd->acp3x_base + reg_val);
val = val & ~BIT(0);
rv_writel(val, rtd->acp3x_base + reg_val);
- rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+ rv_writel(0, rtd->acp3x_base + ier_val);
+ ret = 0;
break;
default:
ret = -EINVAL;
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index d5f8e24..1b8b10a 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -194,20 +194,36 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
{
u16 page_idx;
- u32 low, high, val, acp_fifo_addr;
- dma_addr_t addr = rtd->dma_addr;
+ uint64_t low, high, val, acp_fifo_addr;
+ uint64_t reg_ringbuf_size, reg_dma_size, reg_fifo_size, reg_fifo_addr;
+ dma_addr_t addr;
- /* 8 scratch registers used to map one 64 bit address */
- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
- val = 0;
- else
- val = rtd->num_pages * 8;
+ addr = rtd->dma_addr;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val = ACP_SRAM_BT_PB_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_PB_PTE_OFFSET;
+ }
+ } else {
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ val = ACP_SRAM_BT_CP_PTE_OFFSET;
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ val = ACP_SRAM_SP_CP_PTE_OFFSET;
+ }
+ }
/* Group Enable */
rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base +
- mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base +
- mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+ mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
/* Load the low address of page int ACP SRAM through SRBM */
@@ -224,38 +240,61 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
}
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
- /* Config ringbuffer */
- rv_writel(MEM_WINDOW_START, rtd->acp3x_base +
- mmACP_BT_TX_RINGBUFADDR);
- rv_writel(MAX_BUFFER, rtd->acp3x_base +
- mmACP_BT_TX_RINGBUFSIZE);
- rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE);
-
- /* Config audio fifo */
- acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8)
- + PLAYBACK_FIFO_ADDR_OFFSET;
- rv_writel(acp_fifo_addr, rtd->acp3x_base +
- mmACP_BT_TX_FIFOADDR);
- rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_TX_FIFOSIZE);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_ringbuf_size = mmACP_BT_TX_RINGBUFSIZE;
+ reg_dma_size = mmACP_BT_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ BT_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_BT_TX_FIFOADDR;
+ reg_fifo_size = mmACP_BT_TX_FIFOSIZE;
+ rv_writel(I2S_BT_TX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_BT_TX_RINGBUFADDR);
+ break;
+
+ case I2S_SP_INSTANCE:
+ default:
+ reg_ringbuf_size = mmACP_I2S_TX_RINGBUFSIZE;
+ reg_dma_size = mmACP_I2S_TX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_PB_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_I2S_TX_FIFOADDR;
+ reg_fifo_size = mmACP_I2S_TX_FIFOSIZE;
+ rv_writel(I2S_SP_TX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_I2S_TX_RINGBUFADDR);
+ }
} else {
- /* Config ringbuffer */
- rv_writel(MEM_WINDOW_START + MAX_BUFFER, rtd->acp3x_base +
- mmACP_BT_RX_RINGBUFADDR);
- rv_writel(MAX_BUFFER, rtd->acp3x_base +
- mmACP_BT_RX_RINGBUFSIZE);
- rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_RX_DMA_SIZE);
-
- /* Config audio fifo */
- acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
- (rtd->num_pages * 8) + CAPTURE_FIFO_ADDR_OFFSET;
- rv_writel(acp_fifo_addr, rtd->acp3x_base +
- mmACP_BT_RX_FIFOADDR);
- rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_RX_FIFOSIZE);
- }
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ reg_ringbuf_size = mmACP_BT_RX_RINGBUFSIZE;
+ reg_dma_size = mmACP_BT_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ BT_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_BT_RX_FIFOADDR;
+ reg_fifo_size = mmACP_BT_RX_FIFOSIZE;
+ rv_writel(I2S_BT_RX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_BT_RX_RINGBUFADDR);
+ break;
- /* Enable watermark/period interrupt to host */
- rv_writel(BIT(BT_TX_THRESHOLD) | BIT(BT_RX_THRESHOLD),
- rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL);
+ case I2S_SP_INSTANCE:
+ default:
+ reg_ringbuf_size = mmACP_I2S_RX_RINGBUFSIZE;
+ reg_dma_size = mmACP_I2S_RX_DMA_SIZE;
+ acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
+ SP_CAPT_FIFO_ADDR_OFFSET;
+ reg_fifo_addr = mmACP_I2S_RX_FIFOADDR;
+ reg_fifo_size = mmACP_I2S_RX_FIFOSIZE;
+ rv_writel(I2S_SP_RX_MEM_WINDOW_START,
+ rtd->acp3x_base + mmACP_I2S_RX_RINGBUFADDR);
+ }
+ }
+ rv_writel(MAX_BUFFER, rtd->acp3x_base + reg_ringbuf_size);
+ rv_writel(DMA_SIZE, rtd->acp3x_base + reg_dma_size);
+ rv_writel(acp_fifo_addr, rtd->acp3x_base + reg_fifo_addr);
+ rv_writel(FIFO_SIZE, rtd->acp3x_base + reg_fifo_size);
+ rv_writel(BIT(I2S_RX_THRESHOLD) | BIT(BT_RX_THRESHOLD)
+ | BIT(I2S_TX_THRESHOLD) | BIT(BT_TX_THRESHOLD),
+ rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL);
}
static int acp3x_dma_open(struct snd_soc_component *component,
@@ -289,17 +328,21 @@ static int acp3x_dma_open(struct snd_soc_component *component,
return ret;
}
- if (!adata->play_stream && !adata->capture_stream)
+ if (!adata->play_stream && !adata->capture_stream &&
+ adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adata->play_stream = substream;
- else
+ adata->i2ssp_play_stream = substream;
+ } else {
adata->capture_stream = substream;
+ adata->i2ssp_capture_stream = substream;
+ }
i2s_data->acp3x_base = adata->acp3x_base;
runtime->private_data = i2s_data;
- return 0;
+ return ret;
}
@@ -307,16 +350,28 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_pcm_runtime *runtime;
struct i2s_stream_instance *rtd;
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
int status;
u64 size;
- runtime = substream->runtime;
- rtd = substream->private_data;
+ prtd = substream->private_data;
+ card = prtd->card;
+ pinfo = snd_soc_card_get_drvdata(card);
+ rtd = substream->runtime->private_data;
if (!rtd)
return -EINVAL;
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ } else
+ pr_err("pinfo failed\n");
+
size = params_buffer_bytes(params);
status = snd_pcm_lib_malloc_pages(substream, size);
if (status < 0)
@@ -337,12 +392,25 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component,
static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
+ struct snd_soc_pcm_runtime *prtd;
+ struct snd_soc_card *card;
+ struct acp3x_platform_info *pinfo;
struct i2s_stream_instance *rtd;
u32 pos;
u32 buffersize;
u64 bytescount;
+ prtd = substream->private_data;
+ card = prtd->card;
rtd = substream->runtime->private_data;
+ pinfo = snd_soc_card_get_drvdata(card);
+ if (pinfo) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->i2s_instance = pinfo->play_i2s_instance;
+ else
+ rtd->i2s_instance = pinfo->cap_i2s_instance;
+ }
+
buffersize = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
bytescount = acp_get_byte_count(rtd, substream->stream);
@@ -387,15 +455,19 @@ static int acp3x_dma_close(struct snd_soc_component *component,
component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
adata = dev_get_drvdata(component->dev);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
adata->play_stream = NULL;
- else
+ adata->i2ssp_play_stream = NULL;
+ } else {
adata->capture_stream = NULL;
+ adata->i2ssp_capture_stream = NULL;
+ }
/* Disable ACP irq, when the current stream is being closed and
* another stream is also not active.
*/
- if (!adata->play_stream && !adata->capture_stream)
+ if (!adata->play_stream && !adata->capture_stream &&
+ !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
return 0;
}
@@ -522,13 +594,16 @@ static int acp3x_resume(struct device *dev)
adata->play_stream->runtime->private_data;
config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
rv_writel((rtd->xfer_resolution << 3),
- rtd->acp3x_base + mmACP_BTTDM_ITER);
+ rtd->acp3x_base + mmACP_BTTDM_ITER);
+ val = rv_readl(rtd->acp3x_base + mmACP_I2STDM_ITER);
+ val = val | (rtd->xfer_resolution << 3);
+ rv_writel(val, rtd->acp3x_base + mmACP_I2STDM_ITER);
if (adata->tdm_mode == true) {
rv_writel(adata->tdm_fmt, adata->acp3x_base +
- mmACP_BTTDM_TXFRMT);
+ mmACP_BTTDM_TXFRMT);
val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
rv_writel((val | 0x2), adata->acp3x_base +
- mmACP_BTTDM_ITER);
+ mmACP_BTTDM_ITER);
}
}
@@ -537,13 +612,17 @@ static int acp3x_resume(struct device *dev)
adata->capture_stream->runtime->private_data;
config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
rv_writel((rtd->xfer_resolution << 3),
- rtd->acp3x_base + mmACP_BTTDM_IRER);
+ rtd->acp3x_base + mmACP_BTTDM_IRER);
+ val = rv_readl(rtd->acp3x_base + mmACP_I2STDM_ITER);
+ val = val | (rtd->xfer_resolution << 3);
+ rv_writel(val, rtd->acp3x_base + mmACP_I2STDM_ITER);
+
if (adata->tdm_mode == true) {
rv_writel(adata->tdm_fmt, adata->acp3x_base +
- mmACP_BTTDM_RXFRMT);
+ mmACP_BTTDM_RXFRMT);
val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
rv_writel((val | 0x2), adata->acp3x_base +
- mmACP_BTTDM_IRER);
+ mmACP_BTTDM_IRER);
}
}
@@ -556,8 +635,8 @@ static int acp3x_pcm_runtime_suspend(struct device *dev)
{
struct i2s_dev_data *adata;
int status;
- adata = dev_get_drvdata(dev);
+ adata = dev_get_drvdata(dev);
status = acp3x_deinit(adata->acp3x_base);
if (status)
dev_err(dev, "ACP de-init failed\n");
@@ -573,8 +652,8 @@ static int acp3x_pcm_runtime_resume(struct device *dev)
{
struct i2s_dev_data *adata;
int status;
- adata = dev_get_drvdata(dev);
+ adata = dev_get_drvdata(dev);
status = acp3x_init(adata->acp3x_base);
if (status)
return -ENODEV;
diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
index 72c1a23..c071477 100644
--- a/sound/soc/amd/raven/acp3x.h
+++ b/sound/soc/amd/raven/acp3x.h
@@ -7,6 +7,9 @@
#include "chip_offset_byte.h"
+#define I2S_SP_INSTANCE 0x01
+#define I2S_BT_INSTANCE 0x02
+
#define ACP3x_DEVS 3
#define ACP3x_PHY_BASE_ADDRESS 0x1240000
#define ACP3x_I2S_MODE 0
@@ -17,8 +20,11 @@
#define ACP3x_BT_TDM_REG_START 0x1242800
#define ACP3x_BT_TDM_REG_END 0x1242810
#define I2S_MODE 0x04
+#define I2S_RX_THRESHOLD 27
+#define I2S_TX_THRESHOLD 28
#define BT_TX_THRESHOLD 26
#define BT_RX_THRESHOLD 25
+#define ACP_ERR_INTR_MASK 29
#define ACP3x_POWER_ON 0x00
#define ACP3x_POWER_ON_IN_PROGRESS 0x01
#define ACP3x_POWER_OFF 0x02
@@ -26,19 +32,28 @@
#define ACP3x_SOFT_RESET__SoftResetAudDone_MASK 0x00010001
#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
+#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
+#define ACP_SRAM_BT_PB_PTE_OFFSET 0x200
+#define ACP_SRAM_BT_CP_PTE_OFFSET 0x300
#define PAGE_SIZE_4K_ENABLE 0x2
-#define MEM_WINDOW_START 0x4000000
-#define PLAYBACK_FIFO_ADDR_OFFSET 0x400
-#define CAPTURE_FIFO_ADDR_OFFSET 0x500
+#define I2S_SP_TX_MEM_WINDOW_START 0x4000000
+#define I2S_SP_RX_MEM_WINDOW_START 0x4020000
+#define I2S_BT_TX_MEM_WINDOW_START 0x4040000
+#define I2S_BT_RX_MEM_WINDOW_START 0x4060000
+#define SP_PB_FIFO_ADDR_OFFSET 0x500
+#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
+#define BT_PB_FIFO_ADDR_OFFSET 0x900
+#define BT_CAPT_FIFO_ADDR_OFFSET 0xB00
#define PLAYBACK_MIN_NUM_PERIODS 2
#define PLAYBACK_MAX_NUM_PERIODS 8
-#define PLAYBACK_MAX_PERIOD_SIZE 16384
-#define PLAYBACK_MIN_PERIOD_SIZE 4096
+#define PLAYBACK_MAX_PERIOD_SIZE 8192
+#define PLAYBACK_MIN_PERIOD_SIZE 1024
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 8
-#define CAPTURE_MAX_PERIOD_SIZE 16384
-#define CAPTURE_MIN_PERIOD_SIZE 4096
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 1024
#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
#define MIN_BUFFER MAX_BUFFER
@@ -64,14 +79,20 @@ struct i2s_dev_data {
void __iomem *acp3x_base;
struct snd_pcm_substream *play_stream;
struct snd_pcm_substream *capture_stream;
+ struct snd_pcm_substream *i2ssp_play_stream;
+ struct snd_pcm_substream *i2ssp_capture_stream;
};
struct i2s_stream_instance {
u16 num_pages;
+ u16 i2s_instance;
+ u16 capture_channel;
+ u16 direction;
u16 channels;
u32 xfer_resolution;
- u64 bytescount;
+ u32 val;
dma_addr_t dma_addr;
+ u64 bytescount;
void __iomem *acp3x_base;
};
@@ -91,15 +112,36 @@ static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
u64 byte_count;
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
- byte_count = rv_readl(rtd->acp3x_base +
- mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
- byte_count |= rv_readl(rtd->acp3x_base +
- mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
+ }
+
} else {
- byte_count = rv_readl(rtd->acp3x_base +
- mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
- byte_count |= rv_readl(rtd->acp3x_base +
- mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
+ switch (rtd->i2s_instance) {
+ case I2S_BT_INSTANCE:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
+ break;
+ case I2S_SP_INSTANCE:
+ default:
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
+ }
}
return byte_count;
}
--
2.7.4
1
0
[alsa-devel] [PATCH v7 2/6] ASoC: amd: Refactoring of DAI from DMA driver
by Ravulapati Vishnu vardhan rao 18 Nov '19
by Ravulapati Vishnu vardhan rao 18 Nov '19
18 Nov '19
Asoc: PCM DMA driver should only have dma ops.
So Removed all DAI related functionality.Refactoring
the PCM DMA diver code.Added new file containing only DAI ops.
Signed-off-by: Ravulapati Vishnu vardhan rao <Vishnuvardhanrao.Ravulapati(a)amd.com>
---
sound/soc/amd/raven/Makefile | 2 +
sound/soc/amd/raven/acp3x-i2s.c | 272 ++++++++++++++++++++++++++++++
sound/soc/amd/raven/acp3x-pcm-dma.c | 319 ++++++++----------------------------
sound/soc/amd/raven/acp3x.h | 42 +++++
4 files changed, 385 insertions(+), 250 deletions(-)
create mode 100644 sound/soc/amd/raven/acp3x-i2s.c
diff --git a/sound/soc/amd/raven/Makefile b/sound/soc/amd/raven/Makefile
index 108d1ac..62c22b6 100644
--- a/sound/soc/amd/raven/Makefile
+++ b/sound/soc/amd/raven/Makefile
@@ -2,5 +2,7 @@
# Raven Ridge platform Support
snd-pci-acp3x-objs := pci-acp3x.o
snd-acp3x-pcm-dma-objs := acp3x-pcm-dma.o
+snd-acp3x-i2s-objs := acp3x-i2s.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-pci-acp3x.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-acp3x-pcm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-acp3x-i2s.o
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
new file mode 100644
index 0000000..602920f
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PCM Driver
+//
+//Copyright 2016 Advanced Micro Devices, Inc.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include <linux/dma-mapping.h>
+
+#include "acp3x.h"
+
+#define DRV_NAME "acp3x-i2s"
+
+static int acp3x_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+ struct i2s_dev_data *adata;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+
+ case SND_SOC_DAIFMT_I2S:
+ adata->tdm_mode = false;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ adata->tdm_mode = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
+ u32 rx_mask, int slots, int slot_width)
+{
+ struct i2s_dev_data *adata;
+ u32 val;
+ u16 slot_len;
+
+ adata = snd_soc_dai_get_drvdata(cpu_dai);
+
+ /* These values are as per Hardware Spec */
+
+ switch (slot_width) {
+ case SLOT_WIDTH_8:
+ slot_len = 8;
+ break;
+ case SLOT_WIDTH_16:
+ slot_len = 16;
+ break;
+ case SLOT_WIDTH_24:
+ slot_len = 24;
+ break;
+ case SLOT_WIDTH_32:
+ slot_len = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
+ rv_writel(val | 0x2, adata->acp3x_base + mmACP_BTTDM_ITER);
+ val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
+ rv_writel(val | 0x2, adata->acp3x_base + mmACP_BTTDM_IRER);
+
+ val = FRM_LEN | (slots << 15) | (slot_len << 18);
+ rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT);
+ rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT);
+
+ adata->tdm_fmt = val;
+ return 0;
+}
+
+static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ u32 val;
+ u32 reg_val;
+
+ rtd = substream->runtime->private_data;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
+ rtd->xfer_resolution = 0x0;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rtd->xfer_resolution = 0x02;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ rtd->xfer_resolution = 0x04;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ rtd->xfer_resolution = 0x05;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ reg_val = mmACP_BTTDM_ITER;
+ else
+ reg_val = mmACP_BTTDM_IRER;
+
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val = val | (rtd->xfer_resolution << 3);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+ return 0;
+}
+
+static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct i2s_stream_instance *rtd;
+ u32 val, period_bytes;
+ int ret, reg_val;
+
+ rtd = substream->runtime->private_data;
+ period_bytes = frames_to_bytes(substream->runtime,
+ substream->runtime->period_size);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rtd->bytescount = acp_get_byte_count(rtd,
+ substream->stream);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ reg_val = mmACP_BTTDM_ITER;
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_TX_INTR_WATERMARK_SIZE);
+ } else {
+ reg_val = mmACP_BTTDM_IRER;
+ rv_writel(period_bytes, rtd->acp3x_base +
+ mmACP_BT_RX_INTR_WATERMARK_SIZE);
+ }
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val = val | BIT(0);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+ rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ reg_val = mmACP_BTTDM_ITER;
+ else
+ reg_val = mmACP_BTTDM_IRER;
+
+ val = rv_readl(rtd->acp3x_base + reg_val);
+ val = val & ~BIT(0);
+ rv_writel(val, rtd->acp3x_base + reg_val);
+ rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static struct snd_soc_dai_ops acp3x_i2s_dai_ops = {
+ .hw_params = acp3x_i2s_hwparams,
+ .trigger = acp3x_i2s_trigger,
+ .set_fmt = acp3x_i2s_set_fmt,
+ .set_tdm_slot = acp3x_i2s_set_tdm_slot,
+};
+
+static const struct snd_soc_component_driver acp3x_dai_component = {
+ .name = "acp3x-i2s",
+};
+
+static struct snd_soc_dai_driver acp3x_i2s_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &acp3x_i2s_dai_ops,
+};
+
+
+static int acp3x_dai_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct i2s_dev_data *adata;
+ int status, ret;
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
+ GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ ret = -ENOMEM;
+ goto dev_err;
+ }
+
+ adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (IS_ERR(adata->acp3x_base))
+ return PTR_ERR(adata->acp3x_base);
+
+ adata->i2s_irq = res->start;
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp3x_dai_component,
+ &acp3x_i2s_dai, 1);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
+ ret = -ENODEV;
+ goto dev_err;
+ }
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 5000);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ return 0;
+dev_err:
+ devm_kfree(&pdev->dev, adata);
+ return ret;
+}
+
+static int acp3x_dai_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+ return 0;
+}
+static struct platform_driver acp3x_dai_driver = {
+ .probe = acp3x_dai_probe,
+ .remove = acp3x_dai_remove,
+ .driver = {
+ .name = "acp3x_i2s_playcap",
+ },
+};
+
+module_platform_driver(acp3x_dai_driver);
+
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati(a)amd.com");
+MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 60709e3..d5f8e24 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -18,24 +18,6 @@
#define DRV_NAME "acp3x-i2s-audio"
-struct i2s_dev_data {
- bool tdm_mode;
- unsigned int i2s_irq;
- u32 tdm_fmt;
- void __iomem *acp3x_base;
- struct snd_pcm_substream *play_stream;
- struct snd_pcm_substream *capture_stream;
-};
-
-struct i2s_stream_instance {
- u16 num_pages;
- u16 channels;
- u32 xfer_resolution;
- u64 bytescount;
- dma_addr_t dma_addr;
- void __iomem *acp3x_base;
-};
-
static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -178,10 +160,11 @@ static int acp3x_deinit(void __iomem *acp3x_base)
static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
{
+ struct i2s_dev_data *rv_i2s_data;
u16 play_flag, cap_flag;
u32 val;
- struct i2s_dev_data *rv_i2s_data = dev_id;
+ rv_i2s_data = dev_id;
if (!rv_i2s_data)
return IRQ_NONE;
@@ -278,11 +261,18 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
static int acp3x_dma_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- int ret = 0;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct i2s_dev_data *adata = dev_get_drvdata(component->dev);
- struct i2s_stream_instance *i2s_data = kzalloc(sizeof(struct i2s_stream_instance),
- GFP_KERNEL);
+ struct snd_pcm_runtime *runtime;
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+ struct i2s_stream_instance *i2s_data;
+ int ret;
+
+ runtime = substream->runtime;
+ prtd = substream->private_data;
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
+ i2s_data = kzalloc(sizeof(struct i2s_stream_instance),
+ GFP_KERNEL);
if (!i2s_data)
return -EINVAL;
@@ -312,33 +302,18 @@ static int acp3x_dma_open(struct snd_soc_component *component,
return 0;
}
-static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction)
-{
- u64 byte_count;
-
- if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
- byte_count = rv_readl(rtd->acp3x_base +
- mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
- byte_count |= rv_readl(rtd->acp3x_base +
- mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
- } else {
- byte_count = rv_readl(rtd->acp3x_base +
- mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
- byte_count |= rv_readl(rtd->acp3x_base +
- mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
- }
- return byte_count;
-}
static int acp3x_dma_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
+ struct snd_pcm_runtime *runtime;
+ struct i2s_stream_instance *rtd;
int status;
u64 size;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct i2s_stream_instance *rtd = runtime->private_data;
+ runtime = substream->runtime;
+ rtd = substream->private_data;
if (!rtd)
return -EINVAL;
@@ -362,12 +337,12 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component,
static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- u32 pos = 0;
- u32 buffersize = 0;
- u64 bytescount = 0;
- struct i2s_stream_instance *rtd =
- substream->runtime->private_data;
+ struct i2s_stream_instance *rtd;
+ u32 pos;
+ u32 buffersize;
+ u64 bytescount;
+ rtd = substream->runtime->private_data;
buffersize = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
bytescount = acp_get_byte_count(rtd, substream->stream);
@@ -380,7 +355,10 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
static int acp3x_dma_new(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd)
{
- struct device *parent = component->dev->parent;
+ struct device *parent;
+
+ component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+ parent = component->dev->parent;
snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
parent, MIN_BUFFER, MAX_BUFFER);
return 0;
@@ -402,8 +380,12 @@ static int acp3x_dma_mmap(struct snd_soc_component *component,
static int acp3x_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct i2s_stream_instance *rtd = substream->runtime->private_data;
- struct i2s_dev_data *adata = dev_get_drvdata(component->dev);
+ struct snd_soc_pcm_runtime *prtd;
+ struct i2s_dev_data *adata;
+
+ prtd = substream->private_data;
+ component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+ adata = dev_get_drvdata(component->dev);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
adata->play_stream = NULL;
@@ -415,186 +397,9 @@ static int acp3x_dma_close(struct snd_soc_component *component,
*/
if (!adata->play_stream && !adata->capture_stream)
rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
- kfree(rtd);
- return 0;
-}
-
-static int acp3x_dai_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
-{
-
- struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- adata->tdm_mode = false;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- adata->tdm_mode = true;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int acp3x_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
- u32 rx_mask, int slots, int slot_width)
-{
- u32 val = 0;
- u16 slot_len;
-
- struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
-
- switch (slot_width) {
- case SLOT_WIDTH_8:
- slot_len = 8;
- break;
- case SLOT_WIDTH_16:
- slot_len = 16;
- break;
- case SLOT_WIDTH_24:
- slot_len = 24;
- break;
- case SLOT_WIDTH_32:
- slot_len = 0;
- break;
- default:
- return -EINVAL;
- }
-
- val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
- rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_ITER);
- val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
- rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_IRER);
-
- val = (FRM_LEN | (slots << 15) | (slot_len << 18));
- rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT);
- rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT);
-
- adata->tdm_fmt = val;
- return 0;
-}
-
-static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- u32 val = 0;
- struct i2s_stream_instance *rtd = substream->runtime->private_data;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_S8:
- rtd->xfer_resolution = 0x0;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- rtd->xfer_resolution = 0x02;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- rtd->xfer_resolution = 0x04;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- rtd->xfer_resolution = 0x05;
- break;
- default:
- return -EINVAL;
- }
- val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
- val = val | (rtd->xfer_resolution << 3);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
- else
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
-
return 0;
}
-static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- int ret = 0;
- struct i2s_stream_instance *rtd = substream->runtime->private_data;
- u32 val, period_bytes;
-
- period_bytes = frames_to_bytes(substream->runtime,
- substream->runtime->period_size);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- rtd->bytescount = acp_get_byte_count(rtd, substream->stream);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- rv_writel(period_bytes, rtd->acp3x_base +
- mmACP_BT_TX_INTR_WATERMARK_SIZE);
- val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
- val = val | BIT(0);
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
- } else {
- rv_writel(period_bytes, rtd->acp3x_base +
- mmACP_BT_RX_INTR_WATERMARK_SIZE);
- val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
- val = val | BIT(0);
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
- }
- rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
- val = val & ~BIT(0);
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
- } else {
- val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
- val = val & ~BIT(0);
- rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
- }
- rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static struct snd_soc_dai_ops acp3x_dai_i2s_ops = {
- .hw_params = acp3x_dai_i2s_hwparams,
- .trigger = acp3x_dai_i2s_trigger,
- .set_fmt = acp3x_dai_i2s_set_fmt,
- .set_tdm_slot = acp3x_dai_set_tdm_slot,
-};
-
-static struct snd_soc_dai_driver acp3x_i2s_dai_driver = {
- .playback = {
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 2,
- .channels_max = 8,
-
- .rate_min = 8000,
- .rate_max = 96000,
- },
- .capture = {
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 2,
- .channels_max = 2,
- .rate_min = 8000,
- .rate_max = 48000,
- },
- .ops = &acp3x_dai_i2s_ops,
-};
-
static const struct snd_soc_component_driver acp3x_i2s_component = {
.name = DRV_NAME,
.open = acp3x_dma_open,
@@ -609,10 +414,10 @@ static const struct snd_soc_component_driver acp3x_i2s_component = {
static int acp3x_audio_probe(struct platform_device *pdev)
{
- int status;
struct resource *res;
struct i2s_dev_data *adata;
unsigned int irqflags;
+ int status, ret;
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "platform_data not retrieved\n");
@@ -622,70 +427,80 @@ static int acp3x_audio_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
return -ENODEV;
}
adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
if (!adata)
return -ENOMEM;
-
adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
-
+ if (!adata->acp3x_base) {
+ ret = -ENOMEM;
+ goto base_err;
+ }
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
- return -ENODEV;
+ ret = -ENOMEM;
+ goto base_err;
}
adata->i2s_irq = res->start;
- adata->play_stream = NULL;
- adata->capture_stream = NULL;
dev_set_drvdata(&pdev->dev, adata);
/* Initialize ACP */
status = acp3x_init(adata->acp3x_base);
- if (status)
- return -ENODEV;
+ if (status) {
+ ret = -ENODEV;
+ goto base_err;
+ }
status = devm_snd_soc_register_component(&pdev->dev,
&acp3x_i2s_component,
- &acp3x_i2s_dai_driver, 1);
+ NULL, 0);
if (status) {
- dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
+ dev_err(&pdev->dev, "Fail to register acp i2s component\n");
+ ret = -ENODEV;
goto dev_err;
}
status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
irqflags, "ACP3x_I2S_IRQ", adata);
if (status) {
dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n");
+ ret = -ENODEV;
goto dev_err;
}
- pm_runtime_set_autosuspend_delay(&pdev->dev, 10000);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 5000);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
return 0;
+
dev_err:
+ devm_kfree(&pdev->dev, adata);
status = acp3x_deinit(adata->acp3x_base);
if (status)
dev_err(&pdev->dev, "ACP de-init failed\n");
else
- dev_info(&pdev->dev, "ACP de-initialized\n");
- /*ignore device status and return driver probe error*/
- return -ENODEV;
+ dev_dbg(&pdev->dev, "ACP de-initialized\n");
+ return ret;
+base_err:
+ devm_kfree(&pdev->dev, adata);
+ return ret;
}
static int acp3x_audio_remove(struct platform_device *pdev)
{
+ struct i2s_dev_data *adata;
int ret;
- struct i2s_dev_data *adata = dev_get_drvdata(&pdev->dev);
+ adata = dev_get_drvdata(&pdev->dev);
ret = acp3x_deinit(adata->acp3x_base);
if (ret)
dev_err(&pdev->dev, "ACP de-init failed\n");
else
- dev_info(&pdev->dev, "ACP de-initialized\n");
+ dev_dbg(&pdev->dev, "ACP de-initialized\n");
pm_runtime_disable(&pdev->dev);
return 0;
@@ -693,10 +508,11 @@ static int acp3x_audio_remove(struct platform_device *pdev)
static int acp3x_resume(struct device *dev)
{
+ struct i2s_dev_data *adata;
int status;
u32 val;
- struct i2s_dev_data *adata = dev_get_drvdata(dev);
+ adata = dev_get_drvdata(dev);
status = acp3x_init(adata->acp3x_base);
if (status)
return -ENODEV;
@@ -738,14 +554,15 @@ static int acp3x_resume(struct device *dev)
static int acp3x_pcm_runtime_suspend(struct device *dev)
{
+ struct i2s_dev_data *adata;
int status;
- struct i2s_dev_data *adata = dev_get_drvdata(dev);
+ adata = dev_get_drvdata(dev);
status = acp3x_deinit(adata->acp3x_base);
if (status)
dev_err(dev, "ACP de-init failed\n");
else
- dev_info(dev, "ACP de-initialized\n");
+ dev_dbg(dev, "ACP de-initialized\n");
rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
@@ -754,8 +571,9 @@ static int acp3x_pcm_runtime_suspend(struct device *dev)
static int acp3x_pcm_runtime_resume(struct device *dev)
{
+ struct i2s_dev_data *adata;
int status;
- struct i2s_dev_data *adata = dev_get_drvdata(dev);
+ adata = dev_get_drvdata(dev);
status = acp3x_init(adata->acp3x_base);
if (status)
@@ -774,13 +592,14 @@ static struct platform_driver acp3x_dma_driver = {
.probe = acp3x_audio_probe,
.remove = acp3x_audio_remove,
.driver = {
- .name = "acp3x_rv_i2s",
+ .name = "acp3x_rv_i2s_dma",
.pm = &acp3x_pm_ops,
},
};
module_platform_driver(acp3x_dma_driver);
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati(a)amd.com");
MODULE_AUTHOR("Maruthi.Bayyavarapu(a)amd.com");
MODULE_AUTHOR("Vijendar.Mukunda(a)amd.com");
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
index 2f15fe1..72c1a23 100644
--- a/sound/soc/amd/raven/acp3x.h
+++ b/sound/soc/amd/raven/acp3x.h
@@ -51,6 +51,29 @@
#define SLOT_WIDTH_24 0x18
#define SLOT_WIDTH_32 0x20
+struct acp3x_platform_info {
+ u16 play_i2s_instance;
+ u16 cap_i2s_instance;
+ u16 capture_channel;
+};
+
+struct i2s_dev_data {
+ bool tdm_mode;
+ unsigned int i2s_irq;
+ u32 tdm_fmt;
+ void __iomem *acp3x_base;
+ struct snd_pcm_substream *play_stream;
+ struct snd_pcm_substream *capture_stream;
+};
+
+struct i2s_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ u32 xfer_resolution;
+ u64 bytescount;
+ dma_addr_t dma_addr;
+ void __iomem *acp3x_base;
+};
static inline u32 rv_readl(void __iomem *base_addr)
{
@@ -61,3 +84,22 @@ static inline void rv_writel(u32 val, void __iomem *base_addr)
{
writel(val, base_addr - ACP3x_PHY_BASE_ADDRESS);
}
+
+static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
+ int direction)
+{
+ u64 byte_count;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
+ } else {
+ byte_count = rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count |= rv_readl(rtd->acp3x_base +
+ mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
+ }
+ return byte_count;
+}
--
2.7.4
1
0
Re: [alsa-devel] [PATCH v5 1/6] ASoC: amd:Create multiple I2S platform device Endpoint (fwd)
by Julia Lawall 18 Nov '19
by Julia Lawall 18 Nov '19
18 Nov '19
On line 70, adata->res is allocated with a devm function, so it shouldn't
be passed to kfree later; that will lead to a double free.
julia
---------- Forwarded message ----------
Date: Sun, 17 Nov 2019 11:44:07 +0800
From: kbuild test robot <lkp(a)intel.com>
To: kbuild(a)lists.01.org
Cc: Julia Lawall <julia.lawall(a)lip6.fr>
Subject: Re: [PATCH v5 1/6] ASoC: amd:Create multiple I2S platform device
Endpoint
In-Reply-To: <1573629249-13272-2-git-send-email-Vishnuvardhanrao.Ravulapati(a)amd.com>
References: <1573629249-13272-2-git-send-email-Vishnuvardhanrao.Ravulapati(a)amd.com>
Hi Ravulapati,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on asoc/for-next]
[cannot apply to v5.4-rc7 next-20191115]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Ravulapati-Vishnu-vardhan-rao/ASoC…
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
:::::: branch date: 4 days ago
:::::: commit date: 4 days ago
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp(a)intel.com>
Reported-by: Julia Lawall <julia.lawall(a)lip6.fr>
>> sound/soc/amd/raven/pci-acp3x.c:142:1-6: WARNING: invalid free of devm_ allocated data
# https://github.com/0day-ci/linux/commit/79701559637a30a0708febfd5119ad05128…
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 79701559637a30a0708febfd5119ad05128b2ba5
vim +142 sound/soc/amd/raven/pci-acp3x.c
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 21
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 22 static int snd_acp3x_probe(struct pci_dev *pci,
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 23 const struct pci_device_id *pci_id)
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 24 {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 25 int ret;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 26 u32 addr, val, i;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 27 struct acp3x_dev_data *adata;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 28 struct platform_device_info pdevinfo[ACP3x_DEVS];
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 29 unsigned int irqflags;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 30
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 31 if (pci_enable_device(pci)) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 32 dev_err(&pci->dev, "pci_enable_device failed\n");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 33 return -ENODEV;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 34 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 35
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 36 ret = pci_request_regions(pci, "AMD ACP3x audio");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 37 if (ret < 0) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 38 dev_err(&pci->dev, "pci_request_regions failed\n");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 39 goto disable_pci;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 40 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 41
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 42 adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 43 GFP_KERNEL);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 44 if (!adata) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 45 ret = -ENOMEM;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 46 goto release_regions;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 47 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 48
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 49 /* check for msi interrupt support */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 50 ret = pci_enable_msi(pci);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 51 if (ret)
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 52 /* msi is not enabled */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 53 irqflags = IRQF_SHARED;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 54 else
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 55 /* msi is enabled */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 56 irqflags = 0;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 57
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 58 addr = pci_resource_start(pci, 0);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 59 adata->acp3x_base = ioremap(addr, pci_resource_len(pci, 0));
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 60 if (!adata->acp3x_base) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 61 ret = -ENOMEM;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 62 goto release_regions;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 63 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 64 pci_set_master(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 65 pci_set_drvdata(pci, adata);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 66
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 67 val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 68 switch (val) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 69 case I2S_MODE:
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 70 adata->res = devm_kzalloc(&pci->dev,
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 71 sizeof(struct resource) * 4,
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 72 GFP_KERNEL);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 73 if (!adata->res) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 74 ret = -ENOMEM;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 75 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 76 }
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 77
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 78 adata->res[0].name = "acp3x_i2s_iomem";
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 79 adata->res[0].flags = IORESOURCE_MEM;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 80 adata->res[0].start = addr;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 81 adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 82
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 83 adata->res[1].name = "acp3x_i2s_sp";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 84 adata->res[1].flags = IORESOURCE_MEM;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 85 adata->res[1].start = addr + ACP3x_I2STDM_REG_START;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 86 adata->res[1].end = addr + ACP3x_I2STDM_REG_END;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 87
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 88 adata->res[2].name = "acp3x_i2s_bt";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 89 adata->res[2].flags = IORESOURCE_MEM;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 90 adata->res[2].start = addr + ACP3x_BT_TDM_REG_START;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 91 adata->res[2].end = addr + ACP3x_BT_TDM_REG_END;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 92
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 93 adata->res[3].name = "acp3x_i2s_irq";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 94 adata->res[3].flags = IORESOURCE_IRQ;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 95 adata->res[3].start = pci->irq;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 96 adata->res[3].end = adata->res[3].start;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 97
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 98 adata->acp3x_audio_mode = ACP3x_I2S_MODE;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 99
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 100 memset(&pdevinfo, 0, sizeof(pdevinfo));
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 101 pdevinfo[0].name = "acp3x_rv_i2s_dma";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 102 pdevinfo[0].id = 0;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 103 pdevinfo[0].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 104 pdevinfo[0].num_res = 4;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 105 pdevinfo[0].res = &adata->res[0];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 106 pdevinfo[0].data = &irqflags;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 107 pdevinfo[0].size_data = sizeof(irqflags);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 108
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 109 pdevinfo[1].name = "acp3x_i2s_playcap";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 110 pdevinfo[1].id = 0;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 111 pdevinfo[1].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 112 pdevinfo[1].num_res = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 113 pdevinfo[1].res = &adata->res[1];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 114
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 115 pdevinfo[2].name = "acp3x_i2s_playcap";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 116 pdevinfo[2].id = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 117 pdevinfo[2].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 118 pdevinfo[2].num_res = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 119 pdevinfo[2].res = &adata->res[2];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 120 for (i = 0; i < ACP3x_DEVS ; i++) {
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 121 adata->pdev[i] =
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 122 platform_device_register_full(&pdevinfo[i]);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 123 if (IS_ERR(adata->pdev[i])) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 124 dev_err(&pci->dev, "cannot register %s device\n",
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 125 pdevinfo[i].name);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 126 ret = PTR_ERR(adata->pdev[i]);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 127 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 128 }
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 129 }
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 130 break;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 131 default:
00347e4ea8ca4c Colin Ian King 2018-11-16 132 dev_err(&pci->dev, "Invalid ACP audio mode : %d\n", val);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 133 ret = -ENODEV;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 134 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 135 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 136 return 0;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 137
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 138 unmap_mmio:
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 139 pci_disable_msi(pci);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 140 for (i = 0 ; i < ACP3x_DEVS ; i++)
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 141 platform_device_unregister(adata->pdev[i]);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 @142 kfree(adata->res);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 143 iounmap(adata->acp3x_base);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 144 release_regions:
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 145 pci_release_regions(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 146 disable_pci:
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 147 pci_disable_device(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 148
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 149 return ret;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 150 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 151
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
3
2
Re: [alsa-devel] [RESEND PATCH v5 6/6] ASoC: amd: Added ACP3x system resume and runtime pm (fwd)
by Julia Lawall 18 Nov '19
by Julia Lawall 18 Nov '19
18 Nov '19
Line 179 needs to cleanup everything that needed to be cleaned up in the
previous error handling code (line 173) as well as adding an iounmap. But
maybe you could have used a devm function to avoid the need for the
iounmap.
Also functions should have blank lines between them. That is why this
report contains lots of function definitions, and not just the one with
the problem.
julia
---------- Forwarded message ----------
Date: Sun, 17 Nov 2019 13:55:47 +0800
From: kbuild test robot <lkp(a)intel.com>
To: kbuild(a)lists.01.org
Cc: Julia Lawall <julia.lawall(a)lip6.fr>
Subject: Re: [RESEND PATCH v5 6/6] ASoC: amd: Added ACP3x system resume and
runtime pm
CC: kbuild-all(a)lists.01.org
In-Reply-To: <1573629249-13272-7-git-send-email-Vishnuvardhanrao.Ravulapati(a)amd.com>
References: <1573629249-13272-7-git-send-email-Vishnuvardhanrao.Ravulapati(a)amd.com>
CC:
Hi Ravulapati,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on asoc/for-next]
[cannot apply to v5.4-rc7 next-20191115]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Ravulapati-Vishnu-vardhan-rao/ASoC…
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
:::::: branch date: 4 days ago
:::::: commit date: 4 days ago
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp(a)intel.com>
Reported-by: Julia Lawall <julia.lawall(a)lip6.fr>
>> sound/soc/amd/raven/pci-acp3x.c:179:2-8: ERROR: missing iounmap; ioremap on line 170 and execution via conditional on line 178
# https://github.com/0day-ci/linux/commit/bfd341330019202bd0a17caa808937c88d5…
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout bfd341330019202bd0a17caa808937c88d536e58
vim +179 sound/soc/amd/raven/pci-acp3x.c
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 24
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 25 static int acp3x_power_on(void __iomem *acp3x_base)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 26 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 27 u32 val;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 28 u32 timeout = 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 29 int ret = 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 30
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 31 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 32
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 33 if (val == 0)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 34 return val;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 35
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 36 if (!((val & ACP_PGFSM_STATUS_MASK) ==
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 37 ACP_POWER_ON_IN_PROGRESS))
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 38 rv_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 39 acp3x_base + mmACP_PGFSM_CONTROL);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 40 while (++timeout < DELAY) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 41 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 42 if (!val)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 43 break;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 44 udelay(1);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 45 if (timeout > 500) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 46 pr_err("ACP is Not Powered ON\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 47 return -ETIMEDOUT;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 48 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 49 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 50 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 51 static int acp3x_power_off(void __iomem *acp3x_base)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 52 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 53 u32 val;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 54 u32 timeout = 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 55
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 56 rv_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 57 acp3x_base + mmACP_PGFSM_CONTROL);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 58 while (++timeout < DELAY) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 59 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 60 if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 61 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 62 udelay(1);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 63 if (timeout > 500) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 64 pr_err("ACP is Not Powered OFF\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 65 return -ETIMEDOUT;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 66 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 67 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 68 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 69 static int acp3x_reset(void __iomem *acp3x_base)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 70 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 71 u32 val, timeout;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 72
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 73 rv_writel(1, acp3x_base + mmACP_SOFT_RESET);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 74 timeout = 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 75 while (++timeout < DELAY) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 76 val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 77 if ((val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK) ||
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 78 timeout > 100) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 79 if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 80 break;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 81 return -ENODEV;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 82 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 83 cpu_relax();
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 84 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 85 rv_writel(0, acp3x_base + mmACP_SOFT_RESET);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 86 timeout = 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 87 while (++timeout < DELAY) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 88 val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 89 if (!val)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 90 break;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 91 if (timeout > 100)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 92 return -ENODEV;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 93 cpu_relax();
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 94 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 95 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 96 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 97 static int acp3x_init(void __iomem *acp3x_base)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 98 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 99 int ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 100
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 101 /* power on */
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 102 ret = acp3x_power_on(acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 103 if (ret) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 104 pr_err("ACP3x power on failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 105 return ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 106 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 107 /* Reset */
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 108 ret = acp3x_reset(acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 109 if (ret) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 110 pr_err("ACP3x reset failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 111 return ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 112 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 113 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 114 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 115 static int acp3x_deinit(void __iomem *acp3x_base)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 116 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 117 int ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 118
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 119 /* Reset */
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 120 ret = acp3x_reset(acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 121 if (ret) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 122 pr_err("ACP3x reset failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 123 return ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 124 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 125 /* power off */
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 126 ret = acp3x_power_off(acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 127 if (ret) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 128 pr_err("ACP3x power off failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 129 return ret;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 130 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 131 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 132 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 133 static int snd_acp3x_probe(struct pci_dev *pci,
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 134 const struct pci_device_id *pci_id)
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 135 {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 136 int ret;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 137 u32 addr, val, i;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 138 struct acp3x_dev_data *adata;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 139 struct platform_device_info pdevinfo[ACP3x_DEVS];
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 140 unsigned int irqflags;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 141
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 142 if (pci_enable_device(pci)) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 143 dev_err(&pci->dev, "pci_enable_device failed\n");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 144 return -ENODEV;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 145 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 146
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 147 ret = pci_request_regions(pci, "AMD ACP3x audio");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 148 if (ret < 0) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 149 dev_err(&pci->dev, "pci_request_regions failed\n");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 150 goto disable_pci;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 151 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 152
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 153 adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 154 GFP_KERNEL);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 155 if (!adata) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 156 ret = -ENOMEM;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 157 goto release_regions;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 158 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 159
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 160 /* check for msi interrupt support */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 161 ret = pci_enable_msi(pci);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 162 if (ret)
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 163 /* msi is not enabled */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 164 irqflags = IRQF_SHARED;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 165 else
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 166 /* msi is enabled */
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 167 irqflags = 0;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 168
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 169 addr = pci_resource_start(pci, 0);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 @170 adata->acp3x_base = ioremap(addr, pci_resource_len(pci, 0));
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 171 if (!adata->acp3x_base) {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 172 ret = -ENOMEM;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 173 goto release_regions;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 174 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 175 pci_set_master(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 176 pci_set_drvdata(pci, adata);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 177 ret = acp3x_init(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 @178 if (ret)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 @179 return -ENODEV;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 180
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 181
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 182 val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 183 switch (val) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 184 case I2S_MODE:
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 185 adata->res = devm_kzalloc(&pci->dev,
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 186 sizeof(struct resource) * 4,
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 187 GFP_KERNEL);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 188 if (!adata->res) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 189 ret = -ENOMEM;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 190 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 191 }
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 192
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 193 adata->res[0].name = "acp3x_i2s_iomem";
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 194 adata->res[0].flags = IORESOURCE_MEM;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 195 adata->res[0].start = addr;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 196 adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 197
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 198 adata->res[1].name = "acp3x_i2s_sp";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 199 adata->res[1].flags = IORESOURCE_MEM;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 200 adata->res[1].start = addr + ACP3x_I2STDM_REG_START;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 201 adata->res[1].end = addr + ACP3x_I2STDM_REG_END;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 202
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 203 adata->res[2].name = "acp3x_i2s_bt";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 204 adata->res[2].flags = IORESOURCE_MEM;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 205 adata->res[2].start = addr + ACP3x_BT_TDM_REG_START;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 206 adata->res[2].end = addr + ACP3x_BT_TDM_REG_END;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 207
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 208 adata->res[3].name = "acp3x_i2s_irq";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 209 adata->res[3].flags = IORESOURCE_IRQ;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 210 adata->res[3].start = pci->irq;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 211 adata->res[3].end = adata->res[3].start;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 212
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 213 adata->acp3x_audio_mode = ACP3x_I2S_MODE;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 214
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 215 memset(&pdevinfo, 0, sizeof(pdevinfo));
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 216 pdevinfo[0].name = "acp3x_rv_i2s_dma";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 217 pdevinfo[0].id = 0;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 218 pdevinfo[0].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 219 pdevinfo[0].num_res = 4;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 220 pdevinfo[0].res = &adata->res[0];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 221 pdevinfo[0].data = &irqflags;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 222 pdevinfo[0].size_data = sizeof(irqflags);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 223
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 224 pdevinfo[1].name = "acp3x_i2s_playcap";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 225 pdevinfo[1].id = 0;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 226 pdevinfo[1].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 227 pdevinfo[1].num_res = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 228 pdevinfo[1].res = &adata->res[1];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 229
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 230 pdevinfo[2].name = "acp3x_i2s_playcap";
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 231 pdevinfo[2].id = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 232 pdevinfo[2].parent = &pci->dev;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 233 pdevinfo[2].num_res = 1;
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 234 pdevinfo[2].res = &adata->res[2];
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 235 for (i = 0; i < ACP3x_DEVS ; i++) {
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 236 adata->pdev[i] =
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 237 platform_device_register_full(&pdevinfo[i]);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 238 if (IS_ERR(adata->pdev[i])) {
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 239 dev_err(&pci->dev, "cannot register %s device\n",
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 240 pdevinfo[i].name);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 241 ret = PTR_ERR(adata->pdev[i]);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 242 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 243 }
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 244 }
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 245 break;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 246 default:
00347e4ea8ca4c Colin Ian King 2018-11-16 247 dev_err(&pci->dev, "Invalid ACP audio mode : %d\n", val);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 248 ret = -ENODEV;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 249 goto unmap_mmio;
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 250 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 251 pm_runtime_set_autosuspend_delay(&pci->dev, 10000);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 252 pm_runtime_use_autosuspend(&pci->dev);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 253 pm_runtime_set_active(&pci->dev);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 254 pm_runtime_put_noidle(&pci->dev);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 255 pm_runtime_enable(&pci->dev);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 256 return 0;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 257
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 258 unmap_mmio:
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 259 ret = acp3x_deinit(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 260 if (ret)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 261 dev_err(&pci->dev, "ACP de-init failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 262 else
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 263 dev_info(&pci->dev, "ACP de-initialized\n");
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 264 pci_disable_msi(pci);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 265 for (i = 0 ; i < ACP3x_DEVS ; i++)
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 266 platform_device_unregister(adata->pdev[i]);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 267 kfree(adata->res);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 268 iounmap(adata->acp3x_base);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 269 release_regions:
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 270 pci_release_regions(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 271 disable_pci:
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 272 pci_disable_device(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 273
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 274 return ret;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 275 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 276 static int snd_acp3x_suspend(struct device *dev)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 277 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 278 int status;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 279 struct acp3x_dev_data *adata = dev_get_drvdata(dev);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 280
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 281 status = acp3x_deinit(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 282 if (status)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 283 dev_err(dev, "ACP de-init failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 284 else
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 285 dev_info(dev, "ACP de-initialized\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 286
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 287 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 288 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 289 static int snd_acp3x_resume(struct device *dev)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 290 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 291 int status;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 292 struct acp3x_dev_data *adata = dev_get_drvdata(dev);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 293
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 294 status = acp3x_init(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 295 if (status) {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 296 dev_err(dev, "ACP init failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 297 return status;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 298 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 299 return 0;
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 300 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 301 static const struct dev_pm_ops acp3x_pm = {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 302 .runtime_suspend = snd_acp3x_suspend,
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 303 .runtime_resume = snd_acp3x_resume,
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 304 .resume = snd_acp3x_resume,
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 305 };
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 306 static void snd_acp3x_remove(struct pci_dev *pci)
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 307 {
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 308 int i, ret;
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 309 struct acp3x_dev_data *adata = pci_get_drvdata(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 310
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 311 if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) {
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 312 for (i = 0 ; i < ACP3x_DEVS ; i++)
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 313 platform_device_unregister(adata->pdev[i]);
79701559637a30 Ravulapati Vishnu vardhan rao 2019-11-13 314 }
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 315 ret = acp3x_deinit(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 316 if (ret)
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 317 dev_err(&pci->dev, "ACP de-init failed\n");
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 318 else
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 319 dev_info(&pci->dev, "ACP de-initialized\n");
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 320 iounmap(adata->acp3x_base);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 321 pm_runtime_disable(&pci->dev);
bfd34133001920 Ravulapati Vishnu vardhan rao 2019-11-13 322 pm_runtime_get_noresume(&pci->dev);
7894a7e7ea3de6 Vijendar Mukunda 2018-11-12 323 pci_disable_msi(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 324 pci_release_regions(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 325 pci_disable_device(pci);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 326 }
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 327 static const struct pci_device_id snd_acp3x_ids[] = {
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 328 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2),
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 329 .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 330 .class_mask = 0xffffff },
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 331 { 0, },
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 332 };
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 333 MODULE_DEVICE_TABLE(pci, snd_acp3x_ids);
e30d9128def6ca Maruthi Srinivas Bayyavarapu 2018-11-12 334
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
3
2
[alsa-devel] [PATCH] ASoC: rt5682: fix the charge pump capacitor discharges
by shumingf@realtek.com 18 Nov '19
by shumingf@realtek.com 18 Nov '19
18 Nov '19
From: Shuming Fan <shumingf(a)realtek.com>
Due to switching the HV to LV mode while stopping playback,
the charge pump capacitor will be discharged to the source of the pump circuit.
Therefore, this patch removed the event control.
Signed-off-by: Shuming Fan <shumingf(a)realtek.com>
---
sound/soc/codecs/rt5682.c | 27 +++------------------------
1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
index 0d8e9866c01a..b1713fffa3eb 100644
--- a/sound/soc/codecs/rt5682.c
+++ b/sound/soc/codecs/rt5682.c
@@ -1464,28 +1464,6 @@ static const struct snd_kcontrol_new hpor_switch =
SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5682_HP_CTRL_1,
RT5682_R_MUTE_SFT, 1, 1);
-static int rt5682_charge_pump_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_component *component =
- snd_soc_dapm_to_component(w->dapm);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_component_update_bits(component,
- RT5682_HP_CHARGE_PUMP_1, RT5682_PM_HP_MASK, RT5682_PM_HP_HV);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_component_update_bits(component,
- RT5682_HP_CHARGE_PUMP_1, RT5682_PM_HP_MASK, RT5682_PM_HP_LV);
- break;
- default:
- return 0;
- }
-
- return 0;
-}
-
static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1769,8 +1747,7 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("HP Amp R", RT5682_PWR_ANLG_1,
RT5682_PWR_HA_R_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RT5682_DEPOP_1,
- RT5682_PUMP_EN_SFT, 0, rt5682_charge_pump_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ RT5682_PUMP_EN_SFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("Capless", 2, RT5682_DEPOP_1,
RT5682_CAPLESS_EN_SFT, 0, NULL, 0),
@@ -2670,6 +2647,8 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
RT5682_HPA_CP_BIAS_CTRL_MASK, RT5682_HPA_CP_BIAS_3UA);
regmap_update_bits(rt5682->regmap, RT5682_CHARGE_PUMP_1,
RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ);
+ regmap_update_bits(rt5682->regmap, RT5682_HP_CHARGE_PUMP_1,
+ RT5682_PM_HP_MASK, RT5682_PM_HP_HV);
INIT_DELAYED_WORK(&rt5682->jack_detect_work,
rt5682_jack_detect_handler);
--
2.24.0
2
1
[alsa-devel] [linux-next:master 10267/11220] sound/soc/codecs/rt5677.c:5246:6: sparse: sparse: symbol 'rt5677_check_hotword' was not declared. Should it be static?
by kbuild test robot 18 Nov '19
by kbuild test robot 18 Nov '19
18 Nov '19
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
head: 4e8f108c3af2d6922a64df9f3d3d488c74f6009d
commit: 21c00e5df4397870ee835c974bf50570f9d24253 [10267/11220] ASoC: rt5677: Enable jack detect while DSP is running
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-31-gfd3528a-dirty
git checkout 21c00e5df4397870ee835c974bf50570f9d24253
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp(a)intel.com>
sparse warnings: (new ones prefixed by >>)
sound/soc/codecs/rt5677.c:4700:17: sparse: sparse: dubious: x | !y
>> sound/soc/codecs/rt5677.c:5246:6: sparse: sparse: symbol 'rt5677_check_hotword' was not declared. Should it be static?
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
3
3
[alsa-devel] [PATCH] ASoC: wm2200: add missed operations in remove and probe failure
by Chuhong Yuan 18 Nov '19
by Chuhong Yuan 18 Nov '19
18 Nov '19
This driver misses calls to pm_runtime_disable and regulator_bulk_disable
in remove and a call to free_irq in probe failure.
Add the calls to fix it.
Signed-off-by: Chuhong Yuan <hslester96(a)gmail.com>
---
sound/soc/codecs/wm2200.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index cf64e109c658..7b087d94141b 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -2410,6 +2410,8 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
err_pm_runtime:
pm_runtime_disable(&i2c->dev);
+ if (i2c->irq)
+ free_irq(i2c->irq, wm2200);
err_reset:
if (wm2200->pdata.reset)
gpio_set_value_cansleep(wm2200->pdata.reset, 0);
@@ -2426,12 +2428,15 @@ static int wm2200_i2c_remove(struct i2c_client *i2c)
{
struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
+ pm_runtime_disable(&i2c->dev);
if (i2c->irq)
free_irq(i2c->irq, wm2200);
if (wm2200->pdata.reset)
gpio_set_value_cansleep(wm2200->pdata.reset, 0);
if (wm2200->pdata.ldo_ena)
gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
+ regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
+ wm2200->core_supplies);
return 0;
}
--
2.24.0
3
2
18 Nov '19
The driver forgets to call pm_runtime_disable in remove and
probe failure.
Add the calls to fix it.
Signed-off-by: Chuhong Yuan <hslester96(a)gmail.com>
---
sound/soc/codecs/wm5100.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 4af0e519e623..91cc63c5a51f 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2617,6 +2617,7 @@ static int wm5100_i2c_probe(struct i2c_client *i2c,
return ret;
err_reset:
+ pm_runtime_disable(&i2c->dev);
if (i2c->irq)
free_irq(i2c->irq, wm5100);
wm5100_free_gpio(i2c);
@@ -2640,6 +2641,7 @@ static int wm5100_i2c_remove(struct i2c_client *i2c)
{
struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
+ pm_runtime_disable(&i2c->dev);
if (i2c->irq)
free_irq(i2c->irq, wm5100);
wm5100_free_gpio(i2c);
--
2.24.0
3
2
[alsa-devel] compression format of alsa-ucm-conf and alsa-topology-conf tarballs
by Lars Wendler 18 Nov '19
by Lars Wendler 18 Nov '19
18 Nov '19
Hello lists,
some shell output says more than any explanation:
lars@abudhabi:~/temp/alsa> wget -q
https://www.alsa-project.org/files/pub/lib/alsa-topology-conf-1.2.1.tar.bz2
lars@abudhabi:~/temp/alsa> wget -q
https://www.alsa-project.org/files/pub/lib/alsa-ucm-conf-1.2.1.tar.bz2
lars@abudhabi:~/temp/alsa> tar -xjf alsa-topology-conf-1.2.1.tar.bz2
bzip2: (stdin) is not a bzip2 file.
tar: Child returned status 2 tar: Error is not recoverable: exiting now
lars@abudhabi:~/temp/alsa(2)> tar -xjf alsa-ucm-conf-1.2.1.tar.bz2
bzip2: (stdin) is not a bzip2 file.
tar: Child returned status 2
tar: Error is not recoverable: exiting now
lars@abudhabi:~/temp/alsa(2)> file alsa-topology-conf-1.2.1.tar.bz2
alsa-topology-conf-1.2.1.tar.bz2: XZ compressed data
lars@abudhabi:~/temp/alsa> file alsa-ucm-conf-1.2.1.tar.bz2
alsa-ucm-conf-1.2.1.tar.bz2: XZ compressed data
lars@abudhabi:~/temp/alsa>
Please rename the tarballs if possible.
Please CC me on replies. I'm not subscribed.
Kind regards
Lars
--
Lars Wendler
Gentoo package maintainer
GPG: 21CC CF02 4586 0A07 ED93 9F68 498F E765 960E 9B39
3
3