aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-07-05 12:55:27 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-07-05 15:20:56 -0400
commit774fec338bfc63fe17233feefd9c6b46ce1673e0 (patch)
tree71631c0c06c5a3706f9c4fa7868de13aa69d5dc9 /sound/soc/tegra
parenta82ce2ae0d91cfa261cbe6f27f4031963ace097c (diff)
ASoC: Tegra: Implement SPDIF CPU DAI
This is a minimal driver for the Tegra SPDIF controller. In hardware, the SPDIF output signal is always routed to any active HDMI display controllers, and may also be routed to external pins on Tegra using the pinmux. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r--sound/soc/tegra/Kconfig9
-rw-r--r--sound/soc/tegra/Makefile2
-rw-r--r--sound/soc/tegra/tegra_spdif.c371
-rw-r--r--sound/soc/tegra/tegra_spdif.h473
4 files changed, 855 insertions, 0 deletions
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 035d39a4beb4..c6af1fd707f5 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -12,6 +12,15 @@ config SND_SOC_TEGRA_I2S
12 Tegra I2S interface. You will also need to select the individual 12 Tegra I2S interface. You will also need to select the individual
13 machine drivers to support below. 13 machine drivers to support below.
14 14
15config SND_SOC_TEGRA_SPDIF
16 tristate
17 depends on SND_SOC_TEGRA
18 default m
19 help
20 Say Y or M if you want to add support for the SPDIF interface.
21 You will also need to select the individual machine drivers to support
22 below.
23
15config MACH_HAS_SND_SOC_TEGRA_WM8903 24config MACH_HAS_SND_SOC_TEGRA_WM8903
16 bool 25 bool
17 help 26 help
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index fa6574d92a31..4d943b3fe150 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -2,12 +2,14 @@
2snd-soc-tegra-das-objs := tegra_das.o 2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o 3snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o 4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-spdif-objs := tegra_spdif.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o 6snd-soc-tegra-utils-objs += tegra_asoc_utils.o
6 7
7obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o 8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o 9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o 10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
10obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o 11obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o
12obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o
11 13
12# Tegra machine Support 14# Tegra machine Support
13snd-soc-tegra-wm8903-objs := tegra_wm8903.o 15snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
new file mode 100644
index 000000000000..abe606b0a29e
--- /dev/null
+++ b/sound/soc/tegra/tegra_spdif.c
@@ -0,0 +1,371 @@
1/*
2 * tegra_spdif.c - Tegra SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/module.h>
25#include <linux/debugfs.h>
26#include <linux/device.h>
27#include <linux/platform_device.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31#include <mach/iomap.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36
37#include "tegra_spdif.h"
38
39#define DRV_NAME "tegra-spdif"
40
41static inline void tegra_spdif_write(struct tegra_spdif *spdif, u32 reg,
42 u32 val)
43{
44 __raw_writel(val, spdif->regs + reg);
45}
46
47static inline u32 tegra_spdif_read(struct tegra_spdif *spdif, u32 reg)
48{
49 return __raw_readl(spdif->regs + reg);
50}
51
52#ifdef CONFIG_DEBUG_FS
53static int tegra_spdif_show(struct seq_file *s, void *unused)
54{
55#define REG(r) { r, #r }
56 static const struct {
57 int offset;
58 const char *name;
59 } regs[] = {
60 REG(TEGRA_SPDIF_CTRL),
61 REG(TEGRA_SPDIF_STATUS),
62 REG(TEGRA_SPDIF_STROBE_CTRL),
63 REG(TEGRA_SPDIF_DATA_FIFO_CSR),
64 REG(TEGRA_SPDIF_CH_STA_RX_A),
65 REG(TEGRA_SPDIF_CH_STA_RX_B),
66 REG(TEGRA_SPDIF_CH_STA_RX_C),
67 REG(TEGRA_SPDIF_CH_STA_RX_D),
68 REG(TEGRA_SPDIF_CH_STA_RX_E),
69 REG(TEGRA_SPDIF_CH_STA_RX_F),
70 REG(TEGRA_SPDIF_CH_STA_TX_A),
71 REG(TEGRA_SPDIF_CH_STA_TX_B),
72 REG(TEGRA_SPDIF_CH_STA_TX_C),
73 REG(TEGRA_SPDIF_CH_STA_TX_D),
74 REG(TEGRA_SPDIF_CH_STA_TX_E),
75 REG(TEGRA_SPDIF_CH_STA_TX_F),
76 };
77#undef REG
78
79 struct tegra_spdif *spdif = s->private;
80 int i;
81
82 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_spdif_read(spdif, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 }
86
87 return 0;
88}
89
90static int tegra_spdif_debug_open(struct inode *inode, struct file *file)
91{
92 return single_open(file, tegra_spdif_show, inode->i_private);
93}
94
95static const struct file_operations tegra_spdif_debug_fops = {
96 .open = tegra_spdif_debug_open,
97 .read = seq_read,
98 .llseek = seq_lseek,
99 .release = single_release,
100};
101
102static void tegra_spdif_debug_add(struct tegra_spdif *spdif)
103{
104 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
105 snd_soc_debugfs_root, spdif,
106 &tegra_spdif_debug_fops);
107}
108
109static void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
110{
111 if (spdif->debug)
112 debugfs_remove(spdif->debug);
113}
114#else
115static inline void tegra_spdif_debug_add(struct tegra_spdif *spdif)
116{
117}
118
119static inline void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
120{
121}
122#endif
123
124static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params,
126 struct snd_soc_dai *dai)
127{
128 struct device *dev = substream->pcm->card->dev;
129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
130 int ret, srate, spdifclock;
131
132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK;
133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK;
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE:
136 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_PACK;
137 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_BIT_MODE_16BIT;
138 break;
139 default:
140 return -EINVAL;
141 }
142
143 srate = params_rate(params);
144 switch (params_rate(params)) {
145 case 32000:
146 spdifclock = 4096000;
147 break;
148 case 44100:
149 spdifclock = 5644800;
150 break;
151 case 48000:
152 spdifclock = 6144000;
153 break;
154 case 88200:
155 spdifclock = 11289600;
156 break;
157 case 96000:
158 spdifclock = 12288000;
159 break;
160 case 176400:
161 spdifclock = 22579200;
162 break;
163 case 192000:
164 spdifclock = 24576000;
165 break;
166 default:
167 return -EINVAL;
168 }
169
170 ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
171 if (ret) {
172 dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
173 return ret;
174 }
175
176 return 0;
177}
178
179static void tegra_spdif_start_playback(struct tegra_spdif *spdif)
180{
181 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_TX_EN;
182 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
183}
184
185static void tegra_spdif_stop_playback(struct tegra_spdif *spdif)
186{
187 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_TX_EN;
188 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
189}
190
191static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
192 struct snd_soc_dai *dai)
193{
194 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
195
196 switch (cmd) {
197 case SNDRV_PCM_TRIGGER_START:
198 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
199 case SNDRV_PCM_TRIGGER_RESUME:
200 if (!spdif->clk_refs)
201 clk_enable(spdif->clk_spdif_out);
202 spdif->clk_refs++;
203 tegra_spdif_start_playback(spdif);
204 break;
205 case SNDRV_PCM_TRIGGER_STOP:
206 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
207 case SNDRV_PCM_TRIGGER_SUSPEND:
208 tegra_spdif_stop_playback(spdif);
209 spdif->clk_refs--;
210 if (!spdif->clk_refs)
211 clk_disable(spdif->clk_spdif_out);
212 break;
213 default:
214 return -EINVAL;
215 }
216
217 return 0;
218}
219
220static int tegra_spdif_probe(struct snd_soc_dai *dai)
221{
222 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
223
224 dai->capture_dma_data = NULL;
225 dai->playback_dma_data = &spdif->playback_dma_data;
226
227 return 0;
228}
229
230static struct snd_soc_dai_ops tegra_spdif_dai_ops = {
231 .hw_params = tegra_spdif_hw_params,
232 .trigger = tegra_spdif_trigger,
233};
234
235struct snd_soc_dai_driver tegra_spdif_dai = {
236 .name = DRV_NAME,
237 .probe = tegra_spdif_probe,
238 .playback = {
239 .channels_min = 2,
240 .channels_max = 2,
241 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
242 SNDRV_PCM_RATE_48000,
243 .formats = SNDRV_PCM_FMTBIT_S16_LE,
244 },
245 .ops = &tegra_spdif_dai_ops,
246};
247
248static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
249{
250 struct tegra_spdif *spdif;
251 struct resource *mem, *memregion, *dmareq;
252 int ret;
253
254 spdif = kzalloc(sizeof(struct tegra_spdif), GFP_KERNEL);
255 if (!spdif) {
256 dev_err(&pdev->dev, "Can't allocate tegra_spdif\n");
257 ret = -ENOMEM;
258 goto exit;
259 }
260 dev_set_drvdata(&pdev->dev, spdif);
261
262 spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
263 if (IS_ERR(spdif->clk_spdif_out)) {
264 pr_err("Can't retrieve spdif clock\n");
265 ret = PTR_ERR(spdif->clk_spdif_out);
266 goto err_free;
267 }
268
269 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
270 if (!mem) {
271 dev_err(&pdev->dev, "No memory resource\n");
272 ret = -ENODEV;
273 goto err_clk_put;
274 }
275
276 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
277 if (!dmareq) {
278 dev_err(&pdev->dev, "No DMA resource\n");
279 ret = -ENODEV;
280 goto err_clk_put;
281 }
282
283 memregion = request_mem_region(mem->start, resource_size(mem),
284 DRV_NAME);
285 if (!memregion) {
286 dev_err(&pdev->dev, "Memory region already claimed\n");
287 ret = -EBUSY;
288 goto err_clk_put;
289 }
290
291 spdif->regs = ioremap(mem->start, resource_size(mem));
292 if (!spdif->regs) {
293 dev_err(&pdev->dev, "ioremap failed\n");
294 ret = -ENOMEM;
295 goto err_release;
296 }
297
298 spdif->playback_dma_data.addr = mem->start + TEGRA_SPDIF_DATA_OUT;
299 spdif->playback_dma_data.wrap = 4;
300 spdif->playback_dma_data.width = 32;
301 spdif->playback_dma_data.req_sel = dmareq->start;
302
303 ret = snd_soc_register_dai(&pdev->dev, &tegra_spdif_dai);
304 if (ret) {
305 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
306 ret = -ENOMEM;
307 goto err_unmap;
308 }
309
310 tegra_spdif_debug_add(spdif);
311
312 return 0;
313
314err_unmap:
315 iounmap(spdif->regs);
316err_release:
317 release_mem_region(mem->start, resource_size(mem));
318err_clk_put:
319 clk_put(spdif->clk_spdif_out);
320err_free:
321 kfree(spdif);
322exit:
323 return ret;
324}
325
326static int __devexit tegra_spdif_platform_remove(struct platform_device *pdev)
327{
328 struct tegra_spdif *spdif = dev_get_drvdata(&pdev->dev);
329 struct resource *res;
330
331 snd_soc_unregister_dai(&pdev->dev);
332
333 tegra_spdif_debug_remove(spdif);
334
335 iounmap(spdif->regs);
336
337 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
338 release_mem_region(res->start, resource_size(res));
339
340 clk_put(spdif->clk_spdif_out);
341
342 kfree(spdif);
343
344 return 0;
345}
346
347static struct platform_driver tegra_spdif_driver = {
348 .driver = {
349 .name = DRV_NAME,
350 .owner = THIS_MODULE,
351 },
352 .probe = tegra_spdif_platform_probe,
353 .remove = __devexit_p(tegra_spdif_platform_remove),
354};
355
356static int __init snd_tegra_spdif_init(void)
357{
358 return platform_driver_register(&tegra_spdif_driver);
359}
360module_init(snd_tegra_spdif_init);
361
362static void __exit snd_tegra_spdif_exit(void)
363{
364 platform_driver_unregister(&tegra_spdif_driver);
365}
366module_exit(snd_tegra_spdif_exit);
367
368MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
369MODULE_DESCRIPTION("Tegra SPDIF ASoC driver");
370MODULE_LICENSE("GPL");
371MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_spdif.h b/sound/soc/tegra/tegra_spdif.h
new file mode 100644
index 000000000000..2e03db430279
--- /dev/null
+++ b/sound/soc/tegra/tegra_spdif.h
@@ -0,0 +1,473 @@
1/*
2 * tegra_spdif.h - Definitions for Tegra SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2008-2009, NVIDIA Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#ifndef __TEGRA_SPDIF_H__
27#define __TEGRA_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA_SPDIF_BASE */
32
33#define TEGRA_SPDIF_CTRL 0x0
34#define TEGRA_SPDIF_STATUS 0x4
35#define TEGRA_SPDIF_STROBE_CTRL 0x8
36#define TEGRA_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA_SPDIF_DATA_OUT 0x40
38#define TEGRA_SPDIF_DATA_IN 0x80
39#define TEGRA_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA_SPDIF_CTRL_LBK_EN (1 << 15)
103
104/*
105 * Pack data mode:
106 * 0 = Single data (16 bit needs to be padded to match the
107 * interface data bit size).
108 * 1 = Packeted left/right channel data into a single word.
109 */
110#define TEGRA_SPDIF_CTRL_PACK (1 << 14)
111
112/*
113 * 00 = 16bit data
114 * 01 = 20bit data
115 * 10 = 24bit data
116 * 11 = raw data
117 */
118#define TEGRA_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA_SPDIF_BIT_MODE_16BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA_SPDIF_BIT_MODE_20BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA_SPDIF_BIT_MODE_24BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA_SPDIF_CTRL_BIT_MODE_RAW (TEGRA_SPDIF_BIT_MODE_RAW << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA_SPDIF_STATUS */
131
132/*
133 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
134 * write a 1 to the corresponding bit location to clear the status.
135 */
136
137/*
138 * Receiver(RX) shifter is busy receiving data.
139 * This bit is asserted when the receiver first locked onto the
140 * preamble of the data stream after RX_EN is asserted. This bit is
141 * deasserted when either,
142 * (a) the end of a frame is reached after RX_EN is deeasserted, or
143 * (b) the SPDIF data stream becomes inactive.
144 */
145#define TEGRA_SPDIF_STATUS_RX_BSY (1 << 29)
146
147/*
148 * Transmitter(TX) shifter is busy transmitting data.
149 * This bit is asserted when TX_EN is asserted.
150 * This bit is deasserted when the end of a frame is reached after
151 * TX_EN is deasserted.
152 */
153#define TEGRA_SPDIF_STATUS_TX_BSY (1 << 28)
154
155/*
156 * TX is busy shifting out channel status.
157 * This bit is asserted when both TX_EN and TC_EN are asserted and
158 * data from CH_STA_TX_A register is loaded into the internal shifter.
159 * This bit is deasserted when either,
160 * (a) the end of a frame is reached after TX_EN is deasserted, or
161 * (b) CH_STA_TX_F register is loaded into the internal shifter.
162 */
163#define TEGRA_SPDIF_STATUS_TC_BSY (1 << 27)
164
165/*
166 * TX User data FIFO busy.
167 * This bit is asserted when TX_EN and TXU_EN are asserted and
168 * there's data in the TX user FIFO. This bit is deassert when either,
169 * (a) the end of a frame is reached after TX_EN is deasserted, or
170 * (b) there's no data left in the TX user FIFO.
171 */
172#define TEGRA_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA_SPDIF_STATUS_IS_B (1 << 22)
185
186/*
187 * RX channel block data receive status:
188 * 0=entire block not recieved yet.
189 * 1=received entire block of channel status,
190 */
191#define TEGRA_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA_SPDIF_STATUS_IS_U (1 << 20)
195
196/*
197 * RX User FIFO Status:
198 * 1=attention level reached, 0=attention level not reached.
199 */
200#define TEGRA_SPDIF_STATUS_QS_RU (1 << 19)
201
202/*
203 * TX User FIFO Status:
204 * 1=attention level reached, 0=attention level not reached.
205 */
206#define TEGRA_SPDIF_STATUS_QS_TU (1 << 18)
207
208/*
209 * RX Data FIFO Status:
210 * 1=attention level reached, 0=attention level not reached.
211 */
212#define TEGRA_SPDIF_STATUS_QS_RX (1 << 17)
213
214/*
215 * TX Data FIFO Status:
216 * 1=attention level reached, 0=attention level not reached.
217 */
218#define TEGRA_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA_SPDIF_STROBE_CTRL_STROBE (1 << 15)
231
232/*
233 * Manual data strobe time within the bi-phase clock period (in terms of
234 * the number of over-sampling clocks).
235 */
236#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
238
239/*
240 * Manual SPDIFIN bi-phase clock period (in terms of the number of
241 * over-sampling clocks).
242 */
243#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
245
246/* Fields in SPDIF_DATA_FIFO_CSR */
247
248/* Clear Receiver User FIFO (RX USR.FIFO) */
249#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
292
293/* Clear Receiver Data FIFO (RX DATA.FIFO) */
294#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA_SPDIF_DATA_OUT */
339
340/*
341 * This register has 5 different formats:
342 * 16-bit (BIT_MODE=00, PACK=0)
343 * 20-bit (BIT_MODE=01, PACK=0)
344 * 24-bit (BIT_MODE=10, PACK=0)
345 * raw (BIT_MODE=11, PACK=0)
346 * 16-bit packed (BIT_MODE=00, PACK=1)
347 */
348
349#define TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA_SPDIF_DATA_IN */
379
380/*
381 * This register has 5 different formats:
382 * 16-bit (BIT_MODE=00, PACK=0)
383 * 20-bit (BIT_MODE=01, PACK=0)
384 * 24-bit (BIT_MODE=10, PACK=0)
385 * raw (BIT_MODE=11, PACK=0)
386 * 16-bit packed (BIT_MODE=00, PACK=1)
387 *
388 * Bits 31:24 are common to all modes except 16-bit packed
389 */
390
391#define TEGRA_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA_SPDIF_CH_STA_RX_F */
429
430/*
431 * The 6-word receive channel data page buffer holds a block (192 frames) of
432 * channel status information. The order of receive is from LSB to MSB
433 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
434 */
435
436/* Fields in TEGRA_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA_SPDIF_CH_STA_TX_F */
442
443/*
444 * The 6-word transmit channel data page buffer holds a block (192 frames) of
445 * channel status information. The order of transmission is from LSB to MSB
446 * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
447 */
448
449/* Fields in TEGRA_SPDIF_USR_STA_RX_A */
450
451/*
452 * This 4-word deep FIFO receives user FIFO field information. The order of
453 * receive is from LSB to MSB bit.
454 */
455
456/* Fields in TEGRA_SPDIF_USR_DAT_TX_A */
457
458/*
459 * This 4-word deep FIFO transmits user FIFO field information. The order of
460 * transmission is from LSB to MSB bit.
461 */
462
463struct tegra_spdif {
464 struct clk *clk_spdif_out;
465 int clk_refs;
466 struct tegra_pcm_dma_params capture_dma_data;
467 struct tegra_pcm_dma_params playback_dma_data;
468 void __iomem *regs;
469 struct dentry *debug;
470 u32 reg_ctrl;
471};
472
473#endif