1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/* 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/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 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 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;
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;
bool channels;
unsigned int tx_ptr;
unsigned int rx_ptr;
struct clk *spdif_apb;
struct clk *spdif_core;
struct clk *audio_root;
struct clk *mclk_inner;
struct clk *mclk;
struct clk *mclk_ext;
struct reset_control *rst_apb;
unsigned int reg_spdif_ctrl;
unsigned int reg_spdif_int;
unsigned int reg_spdif_fifo_ctrl;
struct snd_dmaengine_dai_dma_data dma_data;
};
#if IS_ENABLED(CONFIG_SND_SOC_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
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)
{
return -EINVAL;
}
#endif
#endif /* __SND_SOC_STARFIVE_SPDIF_H */
|