Skip to content

Commit 562c0c8

Browse files
committed
i2s regmap and dma setup
1 parent f755c1b commit 562c0c8

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

debug/codec/rk_i2s.c

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,39 @@
1010
#include <linux/platform_device.h>
1111
#include <linux/slab.h>
1212

13+
#include <sound/dmaengine_pcm.h>
14+
1315
#define I2S_DEFAULT_FREQ (11289600)
16+
#define I2S_DMA_BURST_SIZE (16) /* size * width: 16*4 = 64 bytes */
17+
18+
/* I2S regname and offset */
19+
#define I2S_TXCR (0x0000)
20+
#define I2S_RXCR (0x0004)
21+
#define I2S_CKR (0x0008)
22+
#define I2S_FIFOLR (0x000c)
23+
#define I2S_DMACR (0x0010)
24+
#define I2S_INTCR (0x0014)
25+
#define I2S_INTSR (0x0018)
26+
#define I2S_XFER (0x001c)
27+
#define I2S_CLR (0x0020)
28+
#define I2S_TXDR (0x0024)
29+
#define I2S_RXDR (0x0028)
1430

1531
/* 描述I2S控制器的数据结构 */
1632
struct rk_i2s_dev {
1733
struct device *dev;
1834
struct clk *clk; /* bclk */
1935
struct clk *mclk; /*mclk output only */
2036
struct clk *hclk; /*ahb clk */
37+
38+
struct snd_dmaengine_dai_dma_data capture_dma_data;
39+
struct snd_dmaengine_dai_dma_data playback_dma_data;
40+
41+
struct regmap *regmap;
42+
43+
/* 发送和接收数据的标志 */
44+
bool tx_start;
45+
bool rx_start;
2146
};
2247

2348
static const struct of_device_id rockchip_i2s_match[] = {
@@ -76,6 +101,83 @@ void enable_clks(struct rk_i2s_dev *i2s)
76101
clk_prepare_enable(i2s->mclk);
77102
}
78103

104+
/* 可写寄存器 */
105+
static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg)
106+
{
107+
switch (reg) {
108+
case I2S_TXCR:
109+
case I2S_RXCR:
110+
case I2S_CKR:
111+
case I2S_DMACR:
112+
case I2S_INTCR:
113+
case I2S_XFER:
114+
case I2S_CLR:
115+
case I2S_TXDR:
116+
return true;
117+
default:
118+
return false;
119+
}
120+
}
121+
122+
/* 可读寄存器 */
123+
static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
124+
{
125+
switch (reg) {
126+
case I2S_TXCR:
127+
case I2S_RXCR:
128+
case I2S_CKR:
129+
case I2S_DMACR:
130+
case I2S_INTCR:
131+
case I2S_XFER:
132+
case I2S_CLR:
133+
case I2S_RXDR:
134+
case I2S_FIFOLR:
135+
case I2S_INTSR:
136+
return true;
137+
default:
138+
return false;
139+
}
140+
}
141+
142+
/* VOLATILE 寄存器 */
143+
static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
144+
{
145+
switch (reg) {
146+
case I2S_INTSR:
147+
case I2S_CLR:
148+
return true;
149+
default:
150+
return false;
151+
}
152+
}
153+
154+
/* 私有寄存器 */
155+
static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg)
156+
{
157+
switch (reg) {
158+
default:
159+
return false;
160+
}
161+
}
162+
163+
/*
164+
* 从芯片手册可以得到下面信息
165+
* I2S控制器的寄存器是32位的
166+
* 每个寄存器步进大小为4
167+
* 用32位的值来表示
168+
*/
169+
static const struct regmap_config rockchip_i2s_regmap_config = {
170+
.reg_bits = 32,
171+
.reg_stride = 4,
172+
.val_bits = 32,
173+
.max_register = I2S_RXDR,
174+
.writeable_reg = rockchip_i2s_wr_reg,
175+
.readable_reg = rockchip_i2s_rd_reg,
176+
.volatile_reg = rockchip_i2s_volatile_reg,
177+
.precious_reg = rockchip_i2s_precious_reg,
178+
.cache_type = REGCACHE_FLAT,
179+
};
180+
79181
static int rockchip_i2s_probe(struct platform_device *pdev)
80182
{
81183
struct rk_i2s_dev *i2s;
@@ -110,6 +212,37 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
110212
goto EXIT;
111213
}
112214

215+
/* regmap setup */
216+
i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
217+
&rockchip_i2s_regmap_config);
218+
if (IS_ERR(i2s->regmap)) {
219+
dev_err(&pdev->dev,
220+
"Failed to initialise managed register map\n");
221+
ret = PTR_ERR(i2s->regmap);
222+
goto EXIT;
223+
}
224+
225+
/*
226+
* DMA setup for playback and capture
227+
* playback --> i2s tx fifo
228+
* capture --> i2s rx fifo
229+
*/
230+
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
231+
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
232+
i2s->playback_dma_data.maxburst = I2S_DMA_BURST_SIZE;
233+
234+
i2s->capture_dma_data.addr = res->start + I2S_RXDR;
235+
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
236+
i2s->capture_dma_data.maxburst = I2S_DMA_BURST_SIZE;
237+
238+
/* turn off xfer and recv while init */
239+
i2s->tx_start = false;
240+
i2s->rx_start = false;
241+
242+
/* i2s setup */
243+
i2s->dev = &pdev->dev;
244+
dev_set_drvdata(&pdev->dev, i2s);
245+
113246
printk("%s, %d\n", __FUNCTION__, __LINE__);
114247

115248
EXIT:

0 commit comments

Comments
 (0)