summaryrefslogtreecommitdiff
path: root/sound/soc/starfive/spdif.h
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/starfive/spdif.h')
-rw-r--r--sound/soc/starfive/spdif.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/sound/soc/starfive/spdif.h b/sound/soc/starfive/spdif.h
new file mode 100644
index 000000000000..b9b856db701b
--- /dev/null
+++ b/sound/soc/starfive/spdif.h
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef __SND_SOC_STARFIVE_SPDIF_H
+#define __SND_SOC_STARFIVE_SPDIF_H
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm.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_PARITY_MASK (1<<21)
+#define SPDIF_UNDERR_MASK (1<<22)
+#define SPDIF_OVRERR_MASK (1<<23)
+#define SPDIF_EMPTY_MASK (1<<24)
+#define SPDIF_AEMPTY_MASK (1<<25)
+#define SPDIF_FULL_MASK (1<<26)
+#define SPDIF_AFULL_MASK (1<<27)
+#define SPDIF_SYNCERR_MASK (1<<28)
+#define SPDIF_LOCK_MASK (1<<29)
+#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_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_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
+
+///FIFO_CTRL
+#define SPDIF_AEMPTY_THRESHOLD 0 // [depth-1:0]
+#define SPDIF_AFULL_THRESHOLD 16 // [depth+15:16]
+
+///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)
+struct sf_spdif_dev {
+ void __iomem *spdif_base;
+ struct regmap *regmap;
+ struct device *dev;
+ u32 fifo_th;
+ int active;
+
+ /* data related to DMA transfers b/w i2s and DMAC */
+ struct snd_dmaengine_dai_dma_data play_dma_data;
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
+
+ bool use_pio;
+ struct snd_pcm_substream __rcu *tx_substream;
+ struct snd_pcm_substream __rcu *rx_substream;
+
+ unsigned int (*tx_fn)(struct sf_spdif_dev *dev,
+ struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
+ bool *period_elapsed, snd_pcm_format_t format);
+ unsigned int (*rx_fn)(struct sf_spdif_dev *dev,
+ struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
+ 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 snd_dmaengine_dai_dma_data dma_data;
+};
+
+#if IS_ENABLED(CONFIG_SND_STARFIVE_SPDIF_PCM)
+void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev);
+void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev);
+int sf_spdif_pcm_register(struct platform_device *pdev);
+#else
+static inline void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev) { }
+static inline void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev) { }
+static inline int sf_spdif_pcm_register(struct platform_device *pdev)
+{
+ return -EINVAL;
+}
+#endif
+
+
+#endif /* __SND_SOC_STARFIVE_SPDIF_H */