-/**
- ******************************************************************************
- * @file sf_spdif.c
- * @author StarFive Technology
- * @version V1.0
- * @date 05/27/2021
- * @brief
- ******************************************************************************
- * @copy
- *
- * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * <h2><center>© COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
- */
+//SPDX-License-Identifier: GPL-2.0
+/*
+ * SPDIF driver for the StarFive JH7110 SoC
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
#include <linux/init.h>
#include <linux/kernel.h>
regmap_read(dev->regmap, SPDIF_STAT_REG, &stat);
regmap_update_bits(dev->regmap, SPDIF_CTRL,
SPDIF_MASK_ENABLE, 0);
- regmap_update_bits(dev->regmap, SPDIF_INT_REG,
+ regmap_update_bits(dev->regmap, SPDIF_INT_REG,
SPDIF_INT_REG_BIT, 0);
if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
sf_spdif_pcm_push_tx(dev);
irq_valid = true;
- }
-
+ }
+
if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
sf_spdif_pcm_pop_rx(dev);
irq_valid = true;
- }
+ }
- if (stat & SPDIF_PARITY_FLAG) {
+ if (stat & SPDIF_PARITY_FLAG)
irq_valid = true;
- }
-
- if (stat & SPDIF_UNDERR_FLAG) {
+
+ if (stat & SPDIF_UNDERR_FLAG)
irq_valid = true;
- }
-
- if (stat & SPDIF_OVRERR_FLAG) {
+
+ if (stat & SPDIF_OVRERR_FLAG)
irq_valid = true;
- }
-
- if (stat & SPDIF_SYNCERR_FLAG) {
+
+ if (stat & SPDIF_SYNCERR_FLAG)
irq_valid = true;
- }
-
- if (stat & SPDIF_LOCK_FLAG) {
+
+ if (stat & SPDIF_LOCK_FLAG)
irq_valid = true;
- }
-
- if (stat & SPDIF_BEGIN_FLAG) {
+
+ if (stat & SPDIF_BEGIN_FLAG)
irq_valid = true;
- }
- if (stat & SPDIF_RIGHT_LEFT) {
+ if (stat & SPDIF_RIGHT_LEFT)
irq_valid = true;
- }
regmap_update_bits(dev->regmap, SPDIF_CTRL,
SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
/* tx mode */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_TR_MODE, SPDIF_TR_MODE);
-
+
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
} else {
/* rx mode */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_TR_MODE, 0);
-
+
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
}
/* clock recovery form the SPDIF data stream 0:clk_enable */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_CLK_ENABLE, 0);
-
+
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_ENABLE, SPDIF_ENABLE);
break;
/* clock recovery form the SPDIF data stream 1:power save mode */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
-
+
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_ENABLE, 0);
break;
default:
- printk(KERN_ERR "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
+ dev_err(dai->dev, "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
return -EINVAL;
}
unsigned int rate;
unsigned int format;
unsigned int tsamplerate;
+ unsigned int mclk;
+ int ret;
channels = params_channels(params);
rate = params_rate(params);
format = params_format(params);
-
+
switch (channels) {
case 2:
break;
case SNDRV_PCM_FORMAT_S32_LE:
break;
default:
- dev_err(spdif->dev, "invalid format\n");
+ dev_err(dai->dev, "invalid format\n");
return -EINVAL;
}
switch (rate) {
case 8000:
+ mclk = 4096000;
+ break;
case 11025:
+ mclk = 5644800;
+ break;
case 16000:
+ mclk = 8192000;
+ break;
case 22050:
+ mclk = 11289600;
break;
default:
- printk(KERN_ERR "channel:%d sample rate:%d\n", channels, rate);
+ dev_err(dai->dev, "channel:%d sample rate:%d\n", channels, rate);
return -EINVAL;
}
- /* 4096000/128=32000 */
- tsamplerate = (32000 + rate/2)/rate - 1;
-
- if (rate < 3) {
- return -EINVAL;
+ ret = clk_set_rate(spdif->mclk_inner, mclk);
+ if (ret) {
+ dev_err(dai->dev, "failed to set rate for spdif mclk_inner ret=%d\n", ret);
+ return ret;
}
-
+
+ /* (FCLK)4096000/128=32000 */
+ tsamplerate = (32000 + rate/2)/rate - 1;
+
+ if (tsamplerate < 3)
+ tsamplerate = 3;
+
/* transmission sample rate */
regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
static int sf_spdif_clks_get(struct platform_device *pdev,
struct sf_spdif_dev *spdif)
{
-
static struct clk_bulk_data clks[] = {
- { .id = "spdif-apb" }, //clock-names in dts file
- { .id = "spdif-core" },
- { .id = "audioclk" },
+ { .id = "spdif-apb" }, /* clock-names in dts file */
+ { .id = "spdif-core" },
+ { .id = "apb0" },
+ { .id = "audroot" },
+ { .id = "mclk_inner"},
};
int ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
+
spdif->spdif_apb = clks[0].clk;
spdif->spdif_core = clks[1].clk;
- spdif->audioclk = clks[2].clk;
+ spdif->apb0_clk = clks[2].clk;
+ spdif->audio_root = clks[3].clk;
+ spdif->mclk_inner = clks[4].clk;
return ret;
}
ret = clk_prepare_enable(spdif->spdif_apb);
if (ret) {
dev_err(&pdev->dev, "failed to prepare enable spdif_apb\n");
- goto err_clk_spdif;
+ goto disable_apb_clk;
}
ret = clk_prepare_enable(spdif->spdif_core);
if (ret) {
dev_err(&pdev->dev, "failed to prepare enable spdif_core\n");
- goto err_clk_spdif;
+ goto disable_core_clk;
+ }
+
+ ret = clk_prepare_enable(spdif->apb0_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to prepare enable apb0_clk\n");
+ goto disable_apb0_clk;
+ }
+
+ ret = clk_prepare_enable(spdif->audio_root);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to prepare enable spdif->audio_root\n");
+ goto disable_audroot_clk;
}
- ret = clk_prepare_enable(spdif->audioclk);
+ ret = clk_set_rate(spdif->audio_root, 204800000);
if (ret) {
- dev_err(&pdev->dev, "failed to prepare enable audioclk\n");
- goto err_clk_spdif;
+ dev_err(&pdev->dev, "failed to set rate for spdif audroot ret=%d\n", ret);
+ goto disable_audroot_clk;
}
+ ret = clk_prepare_enable(spdif->mclk_inner);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to prepare enable spdif->mclk_inner\n");
+ goto disable_mclk_clk;
+ }
+
+ ret = clk_set_rate(spdif->mclk_inner, 8192000);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to set rate for spdif mclk_inner ret=%d\n", ret);
+ goto disable_mclk_clk;
+ }
+
+ dev_dbg(&pdev->dev, "spdif->spdif_apb = %lu\n", clk_get_rate(spdif->spdif_apb));
+ dev_dbg(&pdev->dev, "spdif->spdif_core = %lu\n", clk_get_rate(spdif->spdif_core));
+ dev_dbg(&pdev->dev, "spdif->apb0_clk = %lu\n", clk_get_rate(spdif->apb0_clk));
+
ret = reset_control_deassert(spdif->rst_apb);
if (ret) {
- printk(KERN_INFO "failed to deassert apb\n");
- goto err_clk_spdif;
+ dev_err(&pdev->dev, "failed to deassert apb\n");
+ goto disable_mclk_clk;
}
- printk(KERN_INFO "Initialize spdif...success\n");
+ return 0;
-err_clk_spdif:
- return ret;
+disable_mclk_clk:
+ clk_disable_unprepare(spdif->mclk_inner);
+disable_audroot_clk:
+ clk_disable_unprepare(spdif->audio_root);
+disable_apb0_clk:
+ clk_disable_unprepare(spdif->apb0_clk);
+disable_core_clk:
+ clk_disable_unprepare(spdif->spdif_core);
+disable_apb_clk:
+ clk_disable_unprepare(spdif->spdif_apb);
+
+ return ret;
}
static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
{
struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
- #if 0
- spdif->play_dma_data.addr = (dma_addr_t)spdif->spdif_base + SPDIF_FIFO_ADDR;
- spdif->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- spdif->play_dma_data.fifo_size = 16;
- spdif->play_dma_data.maxburst = 16;
- spdif->capture_dma_data.addr = (dma_addr_t)spdif->spdif_base + SPDIF_FIFO_ADDR;
- spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- spdif->capture_dma_data.fifo_size = 16;
- spdif->capture_dma_data.maxburst = 16;
- snd_soc_dai_init_dma_data(dai, &spdif->play_dma_data, &spdif->capture_dma_data);
- snd_soc_dai_set_drvdata(dai, spdif);
- #endif
-
/* reset */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
/* clear irq */
regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
- SPDIF_INT_REG_BIT, 0);
+ SPDIF_INT_REG_BIT, 0);
/* power save mode */
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
- 0x1FFF<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
+ BIT8TO20MASK<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
- 0xFFFFFFFF, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
+ ALLBITMASK, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
regmap_update_bits(spdif->regmap, SPDIF_CTRL,
SPDIF_PARITYGEN, SPDIF_PARITYGEN);
};
#define SF_PCM_RATE_44100_192000 (SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_192000)
-
+ SNDRV_PCM_RATE_48000 | \
+ SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_192000)
+
#define SF_PCM_RATE_8000_22050 (SNDRV_PCM_RATE_8000 | \
- SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050)
+ SNDRV_PCM_RATE_11025 | \
+ SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_22050)
static struct snd_soc_dai_driver sf_spdif_dai = {
.name = "spdif",
.channels_min = 2,
.channels_max = 2,
.rates = SF_PCM_RATE_8000_22050,
- .formats = SNDRV_PCM_FMTBIT_S16_LE \
- |SNDRV_PCM_FMTBIT_S24_LE \
- |SNDRV_PCM_FMTBIT_S32_LE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SF_PCM_RATE_8000_22050,
- .formats = SNDRV_PCM_FMTBIT_S16_LE \
- |SNDRV_PCM_FMTBIT_S24_LE \
- |SNDRV_PCM_FMTBIT_S32_LE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE,
},
.ops = &sf_spdif_dai_ops,
.symmetric_rate = 1,
ret = sf_spdif_clks_get(pdev, spdif);
if (ret) {
- dev_err(&pdev->dev, "failed to get audio clock\n");
- return ret;
+ dev_err(&pdev->dev, "failed to get audio clock\n");
+ return ret;
}
ret = sf_spdif_resets_get(pdev, spdif);
if (ret) {
- dev_err(&pdev->dev, "failed to get audio reset controls\n");
- return ret;
+ dev_err(&pdev->dev, "failed to get audio reset controls\n");
+ return ret;
}
ret = sf_spdif_clk_init(pdev, spdif);
if (ret) {
- dev_err(&pdev->dev, "failed to enable audio clock\n");
- return ret;
+ dev_err(&pdev->dev, "failed to enable audio clock\n");
+ return ret;
}
-
+
spdif->dev = &pdev->dev;
spdif->fifo_th = 16;
-
+
irq = platform_get_irq(pdev, 0);
if (irq >= 0) {
ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
&sf_spdif_dai, 1);
if (ret)
goto err_clk_disable;
-
+
if (irq >= 0) {
ret = sf_spdif_pcm_register(pdev);
spdif->use_pio = true;
};
module_platform_driver(sf_spdif_driver);
-MODULE_AUTHOR("curry.zhang <michael.yan@starfive.com>");
+MODULE_AUTHOR("curry.zhang <curry.zhang@starfive.com>");
MODULE_DESCRIPTION("starfive SPDIF driver");
MODULE_LICENSE("GPL v2");
-/**
- ******************************************************************************
- * @file sf_spdif.h
- * @author StarFive Technology
- * @version V1.0
- * @date 05/27/2021
- * @brief
- ******************************************************************************
- * @copy
- *
- * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * <h2><center>© COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
- */
+//SPDX-License-Identifier: GPL-2.0
+/*
+ * SPDIF driver for the StarFive JH7110 SoC
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
#ifndef __SND_SOC_STARFIVE_SPDIF_H
#define __SND_SOC_STARFIVE_SPDIF_H
#include <linux/dmaengine.h>
#include <linux/types.h>
-#define SPDIF_CTRL (0x0)
-#define SPDIF_INT_REG (0x4)
-#define SPDIF_FIFO_CTRL (0x8)
-#define SPDIF_STAT_REG (0xC)
-
-#define SPDIF_FIFO_ADDR (0x100)
-#define DMAC_SPDIF_POLLING_LEN (256)
-
-///ctrl: sampled on the rising clock edge
-#define SPDIF_TSAMPLERATE 0///[SRATEW-1:0]
-#define SPDIF_SFR_ENABLE (1<<8) ///0:SFR reg reset to defualt value; auto set back to '1' after reset
-#define SPDIF_ENABLE (1<<9) ///0:reset of SPDIF block, SRF bits are unchanged; 1:enables SPDIF module
-#define SPDIF_FIFO_ENABLE (1<<10) ///0:FIFO pointers are reset to zero,threshold levels for FIFO are unchaned; auto set back to '1'
-#define SPDIF_CLK_ENABLE (1<<11) ///1:blocked and the modules are in power save mode; 0:block feeds the modules
-#define SPDIF_TR_MODE (1<<12) ///0:rx; 1:tx
-#define SPDIF_PARITCHECK (1<<13) ///0:party bit rx in a sub-frame is repeated on the parity; 1:check on a parity error
-#define SPDIF_PARITYGEN (1<<14) ///0:parity bit from FIFO is transmitted in sub-frame;1:parity bit generated inside the core and added to a transmitted sub-frame
-#define SPDIF_VALIDITYCHECK (1<<15) ///0:validity bit in frame isn't checked and all frame are written; 1:validity bit rx is checked
-#define SPDIF_CHANNEL_MODE (1<<16) ///0:two-channel; 1:single-channel
-#define SPDIF_DUPLICATE (1<<17) ///only tx -single-channel mode; 0:secondary channel; 1: left(primary) channel
-#define SPDIF_SETPREAMBB (1<<18) ///only tx; 0:first preamble B after reset tx valid sub-frame; 1:first preamble B is tx after preambleddel(INT_REG)
-#define SPDIF_USE_FIFO_IF (1<<19) ///0:FIFO disabled ,APB accese FIFO; 1:FIFO enable, APB access to FIFO disable;
-///#define RESERVED (1<<20)
+#define SPDIF_CTRL 0x0
+#define SPDIF_INT_REG 0x4
+#define SPDIF_FIFO_CTRL 0x8
+#define SPDIF_STAT_REG 0xC
+
+#define SPDIF_FIFO_ADDR 0x100
+#define DMAC_SPDIF_POLLING_LEN 256
+
+/* ctrl: sampled on the rising clock edge */
+#define SPDIF_TSAMPLERATE 0 /* [SRATEW-1:0] */
+#define SPDIF_SFR_ENABLE (1<<8) /* 0:SFR reg reset to defualt value; auto set back to '1' after reset */
+#define SPDIF_ENABLE (1<<9) /* 0:reset of SPDIF block, SRF bits are unchanged; 1:enables SPDIF module */
+#define SPDIF_FIFO_ENABLE (1<<10) /* 0:FIFO pointers are reset to zero,threshold levels for FIFO are unchaned; auto set back to '1' */
+#define SPDIF_CLK_ENABLE (1<<11) /* 1:blocked and the modules are in power save mode; 0:block feeds the modules */
+#define SPDIF_TR_MODE (1<<12) /* 0:rx; 1:tx */
+#define SPDIF_PARITCHECK (1<<13) /* 0:party bit rx in a sub-frame is repeated on the parity; 1:check on a parity error */
+#define SPDIF_PARITYGEN (1<<14) /* 0:parity bit from FIFO is transmitted in sub-frame;1:parity bit generated inside the core and added to a transmitted sub-frame */
+#define SPDIF_VALIDITYCHECK (1<<15) /* 0:validity bit in frame isn't checked and all frame are written; 1:validity bit rx is checked */
+#define SPDIF_CHANNEL_MODE (1<<16) /* 0:two-channel; 1:single-channel */
+#define SPDIF_DUPLICATE (1<<17) /* only tx -single-channel mode; 0:secondary channel; 1: left(primary) channel */
+#define SPDIF_SETPREAMBB (1<<18) /* only tx; 0:first preamble B after reset tx valid sub-frame; 1:first preamble B is tx after preambleddel(INT_REG) */
+#define SPDIF_USE_FIFO_IF (1<<19) /* 0:FIFO disabled ,APB accese FIFO; 1:FIFO enable, APB access to FIFO disable; */
#define SPDIF_PARITY_MASK (1<<21)
#define SPDIF_UNDERR_MASK (1<<22)
#define SPDIF_OVRERR_MASK (1<<23)
#define SPDIF_BEGIN_MASK (1<<30)
#define SPDIF_INTEREQ_MAKS (1<<31)
-#define SPDIF_MASK_ENABLE (SPDIF_PARITY_MASK | SPDIF_UNDERR_MASK | SPDIF_OVRERR_MASK | SPDIF_EMPTY_MASK | \
- SPDIF_AEMPTY_MASK | SPDIF_FULL_MASK | SPDIF_AFULL_MASK | SPDIF_SYNCERR_MASK | \
- SPDIF_LOCK_MASK | SPDIF_BEGIN_MASK | SPDIF_INTEREQ_MAKS)
-
-#define SPDIF_MASK_FIFO (SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK | SPDIF_FULL_MASK | SPDIF_AFULL_MASK)
-
-////INT_REG
-#define SPDIF_RSAMPLERATE 0 ///[SRATEW-1:0]
-#define SPDIF_PREAMBLEDEL 8 ///[PDELAYW+7:8] first B delay
-#define SPDIF_PARITYO (1<<21) ///0:clear parity error
-#define SPDIF_TDATA_UNDERR (1<<22) ///tx data underrun error;0:clear
-#define SPDIF_RDATA_OVRERR (1<<23) ///rx data overrun error; 0:clear
-#define SPDIF_FIFO_EMPTY (1<<24) ///empty; 0:clear
-#define SPDIF_FIOF_AEMPTY (1<<25) ///almost empty; 0:clear
-#define SPDIF_FIFO_FULL (1<<26) ///FIFO full; 0:clear
-#define SPDIF_FIFO_AFULL (1<<27) ///FIFO almost full; 0:clear
-#define SPDIF_SYNCERR (1<<28) ///sync error; 0:clear
-#define SPDIF_LOCK (1<<29) ///sync; 0:clear
-#define SPDIF_BLOCK_BEGIN (1<<30) ///new start block rx data
-
-#define SPDIF_INT_REG_BIT (SPDIF_PARITYO | SPDIF_TDATA_UNDERR | SPDIF_RDATA_OVRERR | SPDIF_FIFO_EMPTY | \
- SPDIF_FIOF_AEMPTY | SPDIF_FIFO_FULL | SPDIF_FIFO_AFULL | SPDIF_SYNCERR | \
- SPDIF_LOCK | SPDIF_BLOCK_BEGIN)
+#define SPDIF_MASK_ENABLE (SPDIF_PARITY_MASK | SPDIF_UNDERR_MASK | \
+ SPDIF_OVRERR_MASK | SPDIF_EMPTY_MASK | \
+ SPDIF_AEMPTY_MASK | SPDIF_FULL_MASK | \
+ SPDIF_AFULL_MASK | SPDIF_SYNCERR_MASK | \
+ SPDIF_LOCK_MASK | SPDIF_BEGIN_MASK | \
+ SPDIF_INTEREQ_MAKS)
+
+#define SPDIF_MASK_FIFO (SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK | \
+ SPDIF_FULL_MASK | SPDIF_AFULL_MASK)
+
+/* INT_REG */
+#define SPDIF_RSAMPLERATE 0 /* [SRATEW-1:0] */
+#define SPDIF_PREAMBLEDEL 8 /* [PDELAYW+7:8] first B delay */
+#define SPDIF_PARITYO (1<<21) /* 0:clear parity error */
+#define SPDIF_TDATA_UNDERR (1<<22) /* tx data underrun error;0:clear */
+#define SPDIF_RDATA_OVRERR (1<<23) /* rx data overrun error; 0:clear */
+#define SPDIF_FIFO_EMPTY (1<<24) /* empty; 0:clear */
+#define SPDIF_FIOF_AEMPTY (1<<25) /* almost empty; 0:clear */
+#define SPDIF_FIFO_FULL (1<<26) /* FIFO full; 0:clear */
+#define SPDIF_FIFO_AFULL (1<<27) /* FIFO almost full; 0:clear */
+#define SPDIF_SYNCERR (1<<28) /* sync error; 0:clear */
+#define SPDIF_LOCK (1<<29) /* sync; 0:clear */
+#define SPDIF_BLOCK_BEGIN (1<<30) /* new start block rx data */
+
+#define SPDIF_INT_REG_BIT (SPDIF_PARITYO | SPDIF_TDATA_UNDERR | \
+ SPDIF_RDATA_OVRERR | SPDIF_FIFO_EMPTY | \
+ SPDIF_FIOF_AEMPTY | SPDIF_FIFO_FULL | \
+ SPDIF_FIFO_AFULL | SPDIF_SYNCERR | \
+ SPDIF_LOCK | SPDIF_BLOCK_BEGIN)
-#define SPDIF_ERROR_INT_STATUS (SPDIF_PARITYO | SPDIF_TDATA_UNDERR | SPDIF_RDATA_OVRERR)
-#define SPDIF_FIFO_INT_STATUS (SPDIF_FIFO_EMPTY | SPDIF_FIOF_AEMPTY | SPDIF_FIFO_FULL | SPDIF_FIFO_AFULL)
+#define SPDIF_ERROR_INT_STATUS (SPDIF_PARITYO | \
+ SPDIF_TDATA_UNDERR | SPDIF_RDATA_OVRERR)
+#define SPDIF_FIFO_INT_STATUS (SPDIF_FIFO_EMPTY | SPDIF_FIOF_AEMPTY | \
+ SPDIF_FIFO_FULL | SPDIF_FIFO_AFULL)
#define SPDIF_INT_PARITY_ERROR (-1)
#define SPDIF_INT_TDATA_UNDERR (-2)
#define SPDIF_INT_RDATA_OVRERR (-3)
#define SPDIF_INT_FIFO_EMPTY 1
#define SPDIF_INT_FIFO_AEMPTY 2
-#define SPDIF_INT_FIFO_FULL 3
+#define SPDIF_INT_FIFO_FULL 3
#define SPDIF_INT_FIFO_AFULL 4
-#define SPDIF_INT_SYNCERR (-4)
-#define SPDIF_INT_LOCK 5 ///reciever has become synchronized with input data stream
-#define SPDIF_INT_BLOCK_BEGIN 6 ///start a new block in recieve data, written into FIFO
+#define SPDIF_INT_SYNCERR (-4)
+#define SPDIF_INT_LOCK 5 /* reciever has become synchronized with input data stream */
+#define SPDIF_INT_BLOCK_BEGIN 6 /* start a new block in recieve data, written into FIFO */
-///FIFO_CTRL
-#define SPDIF_AEMPTY_THRESHOLD 0///[depth-1:0]
-#define SPDIF_AFULL_THRESHOLD 16///[depth+15:16]
+/* FIFO_CTRL */
+#define SPDIF_AEMPTY_THRESHOLD 0 /* [depth-1:0] */
+#define SPDIF_AFULL_THRESHOLD 16 /* [depth+15:16] */
-///STAT_REG
+/* STAT_REG */
#define SPDIF_FIFO_LEVEL (1<<0)
-#define SPDIF_PARITY_FLAG (1<<21) ///1:error; 0:repeated
-#define SPDIF_UNDERR_FLAG (1<<22) ///1:error
-#define SPDIF_OVRERR_FLAG (1<<23) ///1:error
-#define SPDIF_EMPTY_FLAG (1<<24) ///1:fifo empty
-#define SPDIF_AEMPTY_FLAG (1<<25) ///1:fifo almost empty
-#define SPDIF_FULL_FLAG (1<<26) ///1:fifo full
-#define SPDIF_AFULL_FLAG (1<<27) ///1:fifo almost full
-#define SPDIF_SYNCERR_FLAG (1<<28) ///1:rx sync error
-#define SPDIF_LOCK_FLAG (1<<29) ///1:RX sync
-#define SPDIF_BEGIN_FLAG (1<<30) ///1:start a new block
-#define SPDIF_RIGHT_LEFT (1<<31) ///1:left channel received and tx into FIFO; 0:right channel received and tx into FIFO
-
-#define SPDIF_STAT (SPDIF_PARITY_FLAG | SPDIF_UNDERR_FLAG | SPDIF_OVRERR_FLAG | SPDIF_EMPTY_FLAG | \
- SPDIF_AEMPTY_FLAG | SPDIF_FULL_FLAG | SPDIF_AFULL_FLAG | SPDIF_SYNCERR_FLAG | \
- SPDIF_LOCK_FLAG | SPDIF_BEGIN_FLAG | SPDIF_RIGHT_LEFT)
+#define SPDIF_PARITY_FLAG (1<<21) /* 1:error; 0:repeated */
+#define SPDIF_UNDERR_FLAG (1<<22) /* 1:error */
+#define SPDIF_OVRERR_FLAG (1<<23) /* 1:error */
+#define SPDIF_EMPTY_FLAG (1<<24) /* 1:fifo empty */
+#define SPDIF_AEMPTY_FLAG (1<<25) /* 1:fifo almost empty */
+#define SPDIF_FULL_FLAG (1<<26) /* 1:fifo full */
+#define SPDIF_AFULL_FLAG (1<<27) /* 1:fifo almost full */
+#define SPDIF_SYNCERR_FLAG (1<<28) /* 1:rx sync error */
+#define SPDIF_LOCK_FLAG (1<<29) /* 1:RX sync */
+#define SPDIF_BEGIN_FLAG (1<<30) /* 1:start a new block */
+#define SPDIF_RIGHT_LEFT (1<<31) /* 1:left channel received and tx into FIFO; 0:right channel received and tx into FIFO */
+
+#define BIT8TO20MASK 0x1FFF
+#define ALLBITMASK 0xFFFFFFFF
+
+#define SPDIF_STAT (SPDIF_PARITY_FLAG | SPDIF_UNDERR_FLAG | \
+ SPDIF_OVRERR_FLAG | SPDIF_EMPTY_FLAG | \
+ SPDIF_AEMPTY_FLAG | SPDIF_FULL_FLAG | \
+ SPDIF_AFULL_FLAG | SPDIF_SYNCERR_FLAG | \
+ SPDIF_LOCK_FLAG | SPDIF_BEGIN_FLAG | \
+ SPDIF_RIGHT_LEFT)
struct sf_spdif_dev {
void __iomem *spdif_base;
struct regmap *regmap;
bool *period_elapsed, snd_pcm_format_t format);
snd_pcm_format_t format;
- //unsigned int sample_bits;
unsigned int tx_ptr;
unsigned int rx_ptr;
struct clk* spdif_apb;
struct clk* spdif_core;
- struct clk* audioclk;
+ struct clk* apb0_clk;
+ struct clk* audio_root;
+ struct clk* mclk_inner;
struct reset_control *rst_apb;
struct snd_dmaengine_dai_dma_data dma_data;