aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r--sound/soc/tegra/Kconfig39
-rw-r--r--sound/soc/tegra/Makefile14
-rw-r--r--sound/soc/tegra/tegra20_das.c260
-rw-r--r--sound/soc/tegra/tegra20_das.h135
-rw-r--r--sound/soc/tegra/tegra20_i2s.c (renamed from sound/soc/tegra/tegra_i2s.c)242
-rw-r--r--sound/soc/tegra/tegra20_i2s.h165
-rw-r--r--sound/soc/tegra/tegra20_spdif.c (renamed from sound/soc/tegra/tegra_spdif.c)199
-rw-r--r--sound/soc/tegra/tegra20_spdif.h472
-rw-r--r--sound/soc/tegra/tegra_alc5632.c48
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c35
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h9
-rw-r--r--sound/soc/tegra/tegra_das.c261
-rw-r--r--sound/soc/tegra/tegra_das.h135
-rw-r--r--sound/soc/tegra/tegra_i2s.h166
-rw-r--r--sound/soc/tegra/tegra_pcm.c28
-rw-r--r--sound/soc/tegra/tegra_pcm.h5
-rw-r--r--sound/soc/tegra/tegra_spdif.h473
-rw-r--r--sound/soc/tegra/tegra_wm8903.c29
-rw-r--r--sound/soc/tegra/trimslice.c7
19 files changed, 1353 insertions, 1369 deletions
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index ce1b773c351f..556cac29ea15 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -4,20 +4,29 @@ config SND_SOC_TEGRA
4 help 4 help
5 Say Y or M here if you want support for SoC audio on Tegra. 5 Say Y or M here if you want support for SoC audio on Tegra.
6 6
7config SND_SOC_TEGRA_I2S 7config SND_SOC_TEGRA20_DAS
8 tristate 8 tristate
9 depends on SND_SOC_TEGRA 9 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
10 help
11 Say Y or M if you want to add support for the Tegra20 DAS module.
12 You will also need to select the individual machine drivers to
13 support below.
14
15config SND_SOC_TEGRA20_I2S
16 tristate
17 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
18 select SND_SOC_TEGRA20_DAS
10 help 19 help
11 Say Y or M if you want to add support for codecs attached to the 20 Say Y or M if you want to add support for codecs attached to the
12 Tegra I2S interface. You will also need to select the individual 21 Tegra20 I2S interface. You will also need to select the individual
13 machine drivers to support below. 22 machine drivers to support below.
14 23
15config SND_SOC_TEGRA_SPDIF 24config SND_SOC_TEGRA20_SPDIF
16 tristate 25 tristate
17 depends on SND_SOC_TEGRA 26 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
18 default m 27 default m
19 help 28 help
20 Say Y or M if you want to add support for the SPDIF interface. 29 Say Y or M if you want to add support for the Tegra20 SPDIF interface.
21 You will also need to select the individual machine drivers to support 30 You will also need to select the individual machine drivers to support
22 below. 31 below.
23 32
@@ -32,7 +41,7 @@ config SND_SOC_TEGRA_WM8903
32 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 41 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
33 depends on SND_SOC_TEGRA && I2C 42 depends on SND_SOC_TEGRA && I2C
34 depends on MACH_HAS_SND_SOC_TEGRA_WM8903 43 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
35 select SND_SOC_TEGRA_I2S 44 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
36 select SND_SOC_WM8903 45 select SND_SOC_WM8903
37 help 46 help
38 Say Y or M here if you want to add support for SoC audio on Tegra 47 Say Y or M here if you want to add support for SoC audio on Tegra
@@ -42,17 +51,17 @@ config SND_SOC_TEGRA_WM8903
42config SND_SOC_TEGRA_TRIMSLICE 51config SND_SOC_TEGRA_TRIMSLICE
43 tristate "SoC Audio support for TrimSlice board" 52 tristate "SoC Audio support for TrimSlice board"
44 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C 53 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
45 select SND_SOC_TEGRA_I2S 54 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
46 select SND_SOC_TLV320AIC23 55 select SND_SOC_TLV320AIC23
47 help 56 help
48 Say Y or M here if you want to add support for SoC audio on the 57 Say Y or M here if you want to add support for SoC audio on the
49 TrimSlice platform. 58 TrimSlice platform.
50 59
51config SND_SOC_TEGRA_ALC5632 60config SND_SOC_TEGRA_ALC5632
52 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" 61 tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
53 depends on SND_SOC_TEGRA && I2C 62 depends on SND_SOC_TEGRA && I2C
54 select SND_SOC_TEGRA_I2S 63 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
55 select SND_SOC_ALC5632 64 select SND_SOC_ALC5632
56 help 65 help
57 Say Y or M here if you want to add support for SoC audio on the 66 Say Y or M here if you want to add support for SoC audio on the
58 Toshiba AC100 netbook. 67 Toshiba AC100 netbook.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 8e584b8fcfba..4726b909664d 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,15 +1,15 @@
1# Tegra platform Support 1# Tegra platform Support
2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o 2snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-spdif-objs := tegra_spdif.o
6snd-soc-tegra-utils-objs += tegra_asoc_utils.o 3snd-soc-tegra-utils-objs += tegra_asoc_utils.o
4snd-soc-tegra20-das-objs := tegra20_das.o
5snd-soc-tegra20-i2s-objs := tegra20_i2s.o
6snd-soc-tegra20-spdif-objs := tegra20_spdif.o
7 7
8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o 8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
11obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o 9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
12obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o 10obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o
11obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o
12obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o
13 13
14# Tegra machine Support 14# Tegra machine Support
15snd-soc-tegra-wm8903-objs := tegra_wm8903.o 15snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
new file mode 100644
index 000000000000..812696d9c863
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.c
@@ -0,0 +1,260 @@
1/*
2 * tegra20_das.c - Tegra20 DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - 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/debugfs.h>
24#include <linux/device.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30#include <sound/soc.h>
31#include "tegra20_das.h"
32
33#define DRV_NAME "tegra20-das"
34
35static struct tegra20_das *das;
36
37static inline void tegra20_das_write(u32 reg, u32 val)
38{
39 __raw_writel(val, das->regs + reg);
40}
41
42static inline u32 tegra20_das_read(u32 reg)
43{
44 return __raw_readl(das->regs + reg);
45}
46
47int tegra20_das_connect_dap_to_dac(int dap, int dac)
48{
49 u32 addr;
50 u32 reg;
51
52 if (!das)
53 return -ENODEV;
54
55 addr = TEGRA20_DAS_DAP_CTRL_SEL +
56 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
57 reg = dac << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
58
59 tegra20_das_write(addr, reg);
60
61 return 0;
62}
63EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dac);
64
65int tegra20_das_connect_dap_to_dap(int dap, int otherdap, int master,
66 int sdata1rx, int sdata2rx)
67{
68 u32 addr;
69 u32 reg;
70
71 if (!das)
72 return -ENODEV;
73
74 addr = TEGRA20_DAS_DAP_CTRL_SEL +
75 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
76 reg = otherdap << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
77 !!sdata2rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
78 !!sdata1rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
79 !!master << TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
80
81 tegra20_das_write(addr, reg);
82
83 return 0;
84}
85EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dap);
86
87int tegra20_das_connect_dac_to_dap(int dac, int dap)
88{
89 u32 addr;
90 u32 reg;
91
92 if (!das)
93 return -ENODEV;
94
95 addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL +
96 (dac * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
97 reg = dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
98 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
99 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
100
101 tegra20_das_write(addr, reg);
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap);
106
107#ifdef CONFIG_DEBUG_FS
108static int tegra20_das_show(struct seq_file *s, void *unused)
109{
110 int i;
111 u32 addr;
112 u32 reg;
113
114 for (i = 0; i < TEGRA20_DAS_DAP_CTRL_SEL_COUNT; i++) {
115 addr = TEGRA20_DAS_DAP_CTRL_SEL +
116 (i * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
117 reg = tegra20_das_read(addr);
118 seq_printf(s, "TEGRA20_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
119 }
120
121 for (i = 0; i < TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
122 addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL +
123 (i * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
124 reg = tegra20_das_read(addr);
125 seq_printf(s, "TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
126 i, reg);
127 }
128
129 return 0;
130}
131
132static int tegra20_das_debug_open(struct inode *inode, struct file *file)
133{
134 return single_open(file, tegra20_das_show, inode->i_private);
135}
136
137static const struct file_operations tegra20_das_debug_fops = {
138 .open = tegra20_das_debug_open,
139 .read = seq_read,
140 .llseek = seq_lseek,
141 .release = single_release,
142};
143
144static void tegra20_das_debug_add(struct tegra20_das *das)
145{
146 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
147 snd_soc_debugfs_root, das,
148 &tegra20_das_debug_fops);
149}
150
151static void tegra20_das_debug_remove(struct tegra20_das *das)
152{
153 if (das->debug)
154 debugfs_remove(das->debug);
155}
156#else
157static inline void tegra20_das_debug_add(struct tegra20_das *das)
158{
159}
160
161static inline void tegra20_das_debug_remove(struct tegra20_das *das)
162{
163}
164#endif
165
166static int __devinit tegra20_das_probe(struct platform_device *pdev)
167{
168 struct resource *res, *region;
169 int ret = 0;
170
171 if (das)
172 return -ENODEV;
173
174 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL);
175 if (!das) {
176 dev_err(&pdev->dev, "Can't allocate tegra20_das\n");
177 ret = -ENOMEM;
178 goto err;
179 }
180 das->dev = &pdev->dev;
181
182 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
183 if (!res) {
184 dev_err(&pdev->dev, "No memory resource\n");
185 ret = -ENODEV;
186 goto err;
187 }
188
189 region = devm_request_mem_region(&pdev->dev, res->start,
190 resource_size(res), pdev->name);
191 if (!region) {
192 dev_err(&pdev->dev, "Memory region already claimed\n");
193 ret = -EBUSY;
194 goto err;
195 }
196
197 das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
198 if (!das->regs) {
199 dev_err(&pdev->dev, "ioremap failed\n");
200 ret = -ENOMEM;
201 goto err;
202 }
203
204 ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
205 TEGRA20_DAS_DAP_SEL_DAC1);
206 if (ret) {
207 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
208 goto err;
209 }
210 ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_1,
211 TEGRA20_DAS_DAC_SEL_DAP1);
212 if (ret) {
213 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
214 goto err;
215 }
216
217 tegra20_das_debug_add(das);
218
219 platform_set_drvdata(pdev, das);
220
221 return 0;
222
223err:
224 das = NULL;
225 return ret;
226}
227
228static int __devexit tegra20_das_remove(struct platform_device *pdev)
229{
230 if (!das)
231 return -ENODEV;
232
233 tegra20_das_debug_remove(das);
234
235 das = NULL;
236
237 return 0;
238}
239
240static const struct of_device_id tegra20_das_of_match[] __devinitconst = {
241 { .compatible = "nvidia,tegra20-das", },
242 {},
243};
244
245static struct platform_driver tegra20_das_driver = {
246 .probe = tegra20_das_probe,
247 .remove = __devexit_p(tegra20_das_remove),
248 .driver = {
249 .name = DRV_NAME,
250 .owner = THIS_MODULE,
251 .of_match_table = tegra20_das_of_match,
252 },
253};
254module_platform_driver(tegra20_das_driver);
255
256MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
257MODULE_DESCRIPTION("Tegra20 DAS driver");
258MODULE_LICENSE("GPL");
259MODULE_ALIAS("platform:" DRV_NAME);
260MODULE_DEVICE_TABLE(of, tegra20_das_of_match);
diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h
new file mode 100644
index 000000000000..ade4fe080c45
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.h
@@ -0,0 +1,135 @@
1/*
2 * tegra20_das.h - Definitions for Tegra20 DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - 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#ifndef __TEGRA20_DAS_H__
24#define __TEGRA20_DAS_H__
25
26/* Register TEGRA20_DAS_DAP_CTRL_SEL */
27#define TEGRA20_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA20_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA20_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA20_DAS_DAP_SEL_DAC1 0
41#define TEGRA20_DAS_DAP_SEL_DAC2 1
42#define TEGRA20_DAS_DAP_SEL_DAC3 2
43#define TEGRA20_DAS_DAP_SEL_DAP1 16
44#define TEGRA20_DAS_DAP_SEL_DAP2 17
45#define TEGRA20_DAS_DAP_SEL_DAP3 18
46#define TEGRA20_DAS_DAP_SEL_DAP4 19
47#define TEGRA20_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA20_DAS_DAC_SEL_DAP1 0
67#define TEGRA20_DAS_DAC_SEL_DAP2 1
68#define TEGRA20_DAS_DAC_SEL_DAP3 2
69#define TEGRA20_DAS_DAC_SEL_DAP4 3
70#define TEGRA20_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA20_DAS_DAP_ID_1 0
77#define TEGRA20_DAS_DAP_ID_2 1
78#define TEGRA20_DAS_DAP_ID_3 2
79#define TEGRA20_DAS_DAP_ID_4 3
80#define TEGRA20_DAS_DAP_ID_5 4
81
82#define TEGRA20_DAS_DAC_ID_1 0
83#define TEGRA20_DAS_DAC_ID_2 1
84#define TEGRA20_DAS_DAC_ID_3 2
85
86struct tegra20_das {
87 struct device *dev;
88 void __iomem *regs;
89 struct dentry *debug;
90};
91
92/*
93 * Terminology:
94 * DAS: Digital audio switch (HW module controlled by this driver)
95 * DAP: Digital audio port (port/pins on Tegra device)
96 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
97 *
98 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
99 * DAC, or another DAP. When DAPs are connected, one must be the master and
100 * one the slave. Each DAC allows selection of a specific DAP for input, to
101 * cater for the case where N DAPs are connected to 1 DAC for broadcast
102 * output.
103 *
104 * This driver is dumb; no attempt is made to ensure that a valid routing
105 * configuration is programmed.
106 */
107
108/*
109 * Connect a DAP to to a DAC
110 * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA20_DAS_DAP_SEL_DAC*
112 */
113extern int tegra20_das_connect_dap_to_dac(int dap_id, int dac_sel);
114
115/*
116 * Connect a DAP to to another DAP
117 * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA20_DAS_DAP_SEL_DAP*
119 * master: Is this DAP the master (1) or slave (0)
120 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
121 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
122 */
123extern int tegra20_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
124 int master, int sdata1rx,
125 int sdata2rx);
126
127/*
128 * Connect a DAC's input to a DAP
129 * (DAC outputs are selected by the DAP)
130 * dac_id: DAC ID to connect: TEGRA20_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA20_DAS_DAC_SEL_DAP*
132 */
133extern int tegra20_das_connect_dac_to_dap(int dac_id, int dap_sel);
134
135#endif
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 33509de52540..9427f36e6a25 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * tegra_i2s.c - Tegra I2S driver 2 * tegra20_i2s.c - Tegra20 I2S driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,102 +29,101 @@
29 */ 29 */
30 30
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h> 32#include <linux/debugfs.h>
34#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/io.h>
35#include <linux/module.h>
36#include <linux/of.h>
35#include <linux/platform_device.h> 37#include <linux/platform_device.h>
36#include <linux/seq_file.h> 38#include <linux/seq_file.h>
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/io.h>
39#include <linux/of.h>
40#include <mach/iomap.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/pcm.h> 41#include <sound/pcm.h>
43#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
44#include <sound/soc.h> 43#include <sound/soc.h>
45 44
46#include "tegra_i2s.h" 45#include "tegra20_i2s.h"
47 46
48#define DRV_NAME "tegra-i2s" 47#define DRV_NAME "tegra20-i2s"
49 48
50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val) 49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
51{ 50{
52 __raw_writel(val, i2s->regs + reg); 51 __raw_writel(val, i2s->regs + reg);
53} 52}
54 53
55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg) 54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
56{ 55{
57 return __raw_readl(i2s->regs + reg); 56 return __raw_readl(i2s->regs + reg);
58} 57}
59 58
60#ifdef CONFIG_DEBUG_FS 59#ifdef CONFIG_DEBUG_FS
61static int tegra_i2s_show(struct seq_file *s, void *unused) 60static int tegra20_i2s_show(struct seq_file *s, void *unused)
62{ 61{
63#define REG(r) { r, #r } 62#define REG(r) { r, #r }
64 static const struct { 63 static const struct {
65 int offset; 64 int offset;
66 const char *name; 65 const char *name;
67 } regs[] = { 66 } regs[] = {
68 REG(TEGRA_I2S_CTRL), 67 REG(TEGRA20_I2S_CTRL),
69 REG(TEGRA_I2S_STATUS), 68 REG(TEGRA20_I2S_STATUS),
70 REG(TEGRA_I2S_TIMING), 69 REG(TEGRA20_I2S_TIMING),
71 REG(TEGRA_I2S_FIFO_SCR), 70 REG(TEGRA20_I2S_FIFO_SCR),
72 REG(TEGRA_I2S_PCM_CTRL), 71 REG(TEGRA20_I2S_PCM_CTRL),
73 REG(TEGRA_I2S_NW_CTRL), 72 REG(TEGRA20_I2S_NW_CTRL),
74 REG(TEGRA_I2S_TDM_CTRL), 73 REG(TEGRA20_I2S_TDM_CTRL),
75 REG(TEGRA_I2S_TDM_TX_RX_CTRL), 74 REG(TEGRA20_I2S_TDM_TX_RX_CTRL),
76 }; 75 };
77#undef REG 76#undef REG
78 77
79 struct tegra_i2s *i2s = s->private; 78 struct tegra20_i2s *i2s = s->private;
80 int i; 79 int i;
81 80
82 for (i = 0; i < ARRAY_SIZE(regs); i++) { 81 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_i2s_read(i2s, regs[i].offset); 82 u32 val = tegra20_i2s_read(i2s, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val); 83 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 } 84 }
86 85
87 return 0; 86 return 0;
88} 87}
89 88
90static int tegra_i2s_debug_open(struct inode *inode, struct file *file) 89static int tegra20_i2s_debug_open(struct inode *inode, struct file *file)
91{ 90{
92 return single_open(file, tegra_i2s_show, inode->i_private); 91 return single_open(file, tegra20_i2s_show, inode->i_private);
93} 92}
94 93
95static const struct file_operations tegra_i2s_debug_fops = { 94static const struct file_operations tegra20_i2s_debug_fops = {
96 .open = tegra_i2s_debug_open, 95 .open = tegra20_i2s_debug_open,
97 .read = seq_read, 96 .read = seq_read,
98 .llseek = seq_lseek, 97 .llseek = seq_lseek,
99 .release = single_release, 98 .release = single_release,
100}; 99};
101 100
102static void tegra_i2s_debug_add(struct tegra_i2s *i2s) 101static void tegra20_i2s_debug_add(struct tegra20_i2s *i2s)
103{ 102{
104 i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO, 103 i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
105 snd_soc_debugfs_root, i2s, 104 snd_soc_debugfs_root, i2s,
106 &tegra_i2s_debug_fops); 105 &tegra20_i2s_debug_fops);
107} 106}
108 107
109static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) 108static void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s)
110{ 109{
111 if (i2s->debug) 110 if (i2s->debug)
112 debugfs_remove(i2s->debug); 111 debugfs_remove(i2s->debug);
113} 112}
114#else 113#else
115static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) 114static inline void tegra20_i2s_debug_add(struct tegra20_i2s *i2s, int id)
116{ 115{
117} 116}
118 117
119static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s) 118static inline void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s)
120{ 119{
121} 120}
122#endif 121#endif
123 122
124static int tegra_i2s_set_fmt(struct snd_soc_dai *dai, 123static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
125 unsigned int fmt) 124 unsigned int fmt)
126{ 125{
127 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 126 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
128 127
129 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 128 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
130 case SND_SOC_DAIFMT_NB_NF: 129 case SND_SOC_DAIFMT_NB_NF:
@@ -133,10 +132,10 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
133 return -EINVAL; 132 return -EINVAL;
134 } 133 }
135 134
136 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE; 135 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE;
137 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 136 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
138 case SND_SOC_DAIFMT_CBS_CFS: 137 case SND_SOC_DAIFMT_CBS_CFS:
139 i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE; 138 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
140 break; 139 break;
141 case SND_SOC_DAIFMT_CBM_CFM: 140 case SND_SOC_DAIFMT_CBM_CFM:
142 break; 141 break;
@@ -144,28 +143,28 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
144 return -EINVAL; 143 return -EINVAL;
145 } 144 }
146 145
147 i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK | 146 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
148 TEGRA_I2S_CTRL_LRCK_MASK); 147 TEGRA20_I2S_CTRL_LRCK_MASK);
149 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 148 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
150 case SND_SOC_DAIFMT_DSP_A: 149 case SND_SOC_DAIFMT_DSP_A:
151 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP; 150 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
152 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 151 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
153 break; 152 break;
154 case SND_SOC_DAIFMT_DSP_B: 153 case SND_SOC_DAIFMT_DSP_B:
155 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP; 154 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
156 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW; 155 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
157 break; 156 break;
158 case SND_SOC_DAIFMT_I2S: 157 case SND_SOC_DAIFMT_I2S:
159 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S; 158 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
160 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 159 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
161 break; 160 break;
162 case SND_SOC_DAIFMT_RIGHT_J: 161 case SND_SOC_DAIFMT_RIGHT_J:
163 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM; 162 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
164 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 163 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
165 break; 164 break;
166 case SND_SOC_DAIFMT_LEFT_J: 165 case SND_SOC_DAIFMT_LEFT_J:
167 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM; 166 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
168 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW; 167 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
169 break; 168 break;
170 default: 169 default:
171 return -EINVAL; 170 return -EINVAL;
@@ -174,27 +173,27 @@ static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
174 return 0; 173 return 0;
175} 174}
176 175
177static int tegra_i2s_hw_params(struct snd_pcm_substream *substream, 176static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
178 struct snd_pcm_hw_params *params, 177 struct snd_pcm_hw_params *params,
179 struct snd_soc_dai *dai) 178 struct snd_soc_dai *dai)
180{ 179{
181 struct device *dev = substream->pcm->card->dev; 180 struct device *dev = substream->pcm->card->dev;
182 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 181 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
183 u32 reg; 182 u32 reg;
184 int ret, sample_size, srate, i2sclock, bitcnt; 183 int ret, sample_size, srate, i2sclock, bitcnt;
185 184
186 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK; 185 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
187 switch (params_format(params)) { 186 switch (params_format(params)) {
188 case SNDRV_PCM_FORMAT_S16_LE: 187 case SNDRV_PCM_FORMAT_S16_LE:
189 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16; 188 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16;
190 sample_size = 16; 189 sample_size = 16;
191 break; 190 break;
192 case SNDRV_PCM_FORMAT_S24_LE: 191 case SNDRV_PCM_FORMAT_S24_LE:
193 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24; 192 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24;
194 sample_size = 24; 193 sample_size = 24;
195 break; 194 break;
196 case SNDRV_PCM_FORMAT_S32_LE: 195 case SNDRV_PCM_FORMAT_S32_LE:
197 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32; 196 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32;
198 sample_size = 32; 197 sample_size = 32;
199 break; 198 break;
200 default: 199 default:
@@ -213,79 +212,73 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
213 } 212 }
214 213
215 bitcnt = (i2sclock / (2 * srate)) - 1; 214 bitcnt = (i2sclock / (2 * srate)) - 1;
216 if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 215 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
217 return -EINVAL; 216 return -EINVAL;
218 reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 217 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
219 218
220 if (i2sclock % (2 * srate)) 219 if (i2sclock % (2 * srate))
221 reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE; 220 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
222 221
223 if (!i2s->clk_refs) 222 clk_enable(i2s->clk_i2s);
224 clk_enable(i2s->clk_i2s);
225 223
226 tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg); 224 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg);
227 225
228 tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR, 226 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR,
229 TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | 227 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
230 TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); 228 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
231 229
232 if (!i2s->clk_refs) 230 clk_disable(i2s->clk_i2s);
233 clk_disable(i2s->clk_i2s);
234 231
235 return 0; 232 return 0;
236} 233}
237 234
238static void tegra_i2s_start_playback(struct tegra_i2s *i2s) 235static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
239{ 236{
240 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE; 237 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE;
241 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 238 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
242} 239}
243 240
244static void tegra_i2s_stop_playback(struct tegra_i2s *i2s) 241static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
245{ 242{
246 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE; 243 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE;
247 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 244 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
248} 245}
249 246
250static void tegra_i2s_start_capture(struct tegra_i2s *i2s) 247static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
251{ 248{
252 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE; 249 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE;
253 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 250 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
254} 251}
255 252
256static void tegra_i2s_stop_capture(struct tegra_i2s *i2s) 253static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
257{ 254{
258 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE; 255 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE;
259 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl); 256 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
260} 257}
261 258
262static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 259static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
263 struct snd_soc_dai *dai) 260 struct snd_soc_dai *dai)
264{ 261{
265 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai); 262 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
266 263
267 switch (cmd) { 264 switch (cmd) {
268 case SNDRV_PCM_TRIGGER_START: 265 case SNDRV_PCM_TRIGGER_START:
269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 266 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
270 case SNDRV_PCM_TRIGGER_RESUME: 267 case SNDRV_PCM_TRIGGER_RESUME:
271 if (!i2s->clk_refs) 268 clk_enable(i2s->clk_i2s);
272 clk_enable(i2s->clk_i2s);
273 i2s->clk_refs++;
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
275 tegra_i2s_start_playback(i2s); 270 tegra20_i2s_start_playback(i2s);
276 else 271 else
277 tegra_i2s_start_capture(i2s); 272 tegra20_i2s_start_capture(i2s);
278 break; 273 break;
279 case SNDRV_PCM_TRIGGER_STOP: 274 case SNDRV_PCM_TRIGGER_STOP:
280 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 275 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
281 case SNDRV_PCM_TRIGGER_SUSPEND: 276 case SNDRV_PCM_TRIGGER_SUSPEND:
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 277 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
283 tegra_i2s_stop_playback(i2s); 278 tegra20_i2s_stop_playback(i2s);
284 else 279 else
285 tegra_i2s_stop_capture(i2s); 280 tegra20_i2s_stop_capture(i2s);
286 i2s->clk_refs--; 281 clk_disable(i2s->clk_i2s);
287 if (!i2s->clk_refs)
288 clk_disable(i2s->clk_i2s);
289 break; 282 break;
290 default: 283 default:
291 return -EINVAL; 284 return -EINVAL;
@@ -294,9 +287,9 @@ static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
294 return 0; 287 return 0;
295} 288}
296 289
297static int tegra_i2s_probe(struct snd_soc_dai *dai) 290static int tegra20_i2s_probe(struct snd_soc_dai *dai)
298{ 291{
299 struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai); 292 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
300 293
301 dai->capture_dma_data = &i2s->capture_dma_data; 294 dai->capture_dma_data = &i2s->capture_dma_data;
302 dai->playback_dma_data = &i2s->playback_dma_data; 295 dai->playback_dma_data = &i2s->playback_dma_data;
@@ -304,14 +297,14 @@ static int tegra_i2s_probe(struct snd_soc_dai *dai)
304 return 0; 297 return 0;
305} 298}
306 299
307static const struct snd_soc_dai_ops tegra_i2s_dai_ops = { 300static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
308 .set_fmt = tegra_i2s_set_fmt, 301 .set_fmt = tegra20_i2s_set_fmt,
309 .hw_params = tegra_i2s_hw_params, 302 .hw_params = tegra20_i2s_hw_params,
310 .trigger = tegra_i2s_trigger, 303 .trigger = tegra20_i2s_trigger,
311}; 304};
312 305
313static const struct snd_soc_dai_driver tegra_i2s_dai_template = { 306static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
314 .probe = tegra_i2s_probe, 307 .probe = tegra20_i2s_probe,
315 .playback = { 308 .playback = {
316 .channels_min = 2, 309 .channels_min = 2,
317 .channels_max = 2, 310 .channels_max = 2,
@@ -324,27 +317,27 @@ static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
324 .rates = SNDRV_PCM_RATE_8000_96000, 317 .rates = SNDRV_PCM_RATE_8000_96000,
325 .formats = SNDRV_PCM_FMTBIT_S16_LE, 318 .formats = SNDRV_PCM_FMTBIT_S16_LE,
326 }, 319 },
327 .ops = &tegra_i2s_dai_ops, 320 .ops = &tegra20_i2s_dai_ops,
328 .symmetric_rates = 1, 321 .symmetric_rates = 1,
329}; 322};
330 323
331static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) 324static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
332{ 325{
333 struct tegra_i2s * i2s; 326 struct tegra20_i2s *i2s;
334 struct resource *mem, *memregion, *dmareq; 327 struct resource *mem, *memregion, *dmareq;
335 u32 of_dma[2]; 328 u32 of_dma[2];
336 u32 dma_ch; 329 u32 dma_ch;
337 int ret; 330 int ret;
338 331
339 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL); 332 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
340 if (!i2s) { 333 if (!i2s) {
341 dev_err(&pdev->dev, "Can't allocate tegra_i2s\n"); 334 dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
342 ret = -ENOMEM; 335 ret = -ENOMEM;
343 goto err; 336 goto err;
344 } 337 }
345 dev_set_drvdata(&pdev->dev, i2s); 338 dev_set_drvdata(&pdev->dev, i2s);
346 339
347 i2s->dai = tegra_i2s_dai_template; 340 i2s->dai = tegra20_i2s_dai_template;
348 i2s->dai.name = dev_name(&pdev->dev); 341 i2s->dai.name = dev_name(&pdev->dev);
349 342
350 i2s->clk_i2s = clk_get(&pdev->dev, NULL); 343 i2s->clk_i2s = clk_get(&pdev->dev, NULL);
@@ -390,17 +383,17 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
390 goto err_clk_put; 383 goto err_clk_put;
391 } 384 }
392 385
393 i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2; 386 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
394 i2s->capture_dma_data.wrap = 4; 387 i2s->capture_dma_data.wrap = 4;
395 i2s->capture_dma_data.width = 32; 388 i2s->capture_dma_data.width = 32;
396 i2s->capture_dma_data.req_sel = dma_ch; 389 i2s->capture_dma_data.req_sel = dma_ch;
397 390
398 i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1; 391 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
399 i2s->playback_dma_data.wrap = 4; 392 i2s->playback_dma_data.wrap = 4;
400 i2s->playback_dma_data.width = 32; 393 i2s->playback_dma_data.width = 32;
401 i2s->playback_dma_data.req_sel = dma_ch; 394 i2s->playback_dma_data.req_sel = dma_ch;
402 395
403 i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED; 396 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
404 397
405 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); 398 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
406 if (ret) { 399 if (ret) {
@@ -409,47 +402,56 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
409 goto err_clk_put; 402 goto err_clk_put;
410 } 403 }
411 404
412 tegra_i2s_debug_add(i2s); 405 ret = tegra_pcm_platform_register(&pdev->dev);
406 if (ret) {
407 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
408 goto err_unregister_dai;
409 }
410
411 tegra20_i2s_debug_add(i2s);
413 412
414 return 0; 413 return 0;
415 414
415err_unregister_dai:
416 snd_soc_unregister_dai(&pdev->dev);
416err_clk_put: 417err_clk_put:
417 clk_put(i2s->clk_i2s); 418 clk_put(i2s->clk_i2s);
418err: 419err:
419 return ret; 420 return ret;
420} 421}
421 422
422static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev) 423static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev)
423{ 424{
424 struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev); 425 struct tegra20_i2s *i2s = dev_get_drvdata(&pdev->dev);
425 426
427 tegra_pcm_platform_unregister(&pdev->dev);
426 snd_soc_unregister_dai(&pdev->dev); 428 snd_soc_unregister_dai(&pdev->dev);
427 429
428 tegra_i2s_debug_remove(i2s); 430 tegra20_i2s_debug_remove(i2s);
429 431
430 clk_put(i2s->clk_i2s); 432 clk_put(i2s->clk_i2s);
431 433
432 return 0; 434 return 0;
433} 435}
434 436
435static const struct of_device_id tegra_i2s_of_match[] __devinitconst = { 437static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = {
436 { .compatible = "nvidia,tegra20-i2s", }, 438 { .compatible = "nvidia,tegra20-i2s", },
437 {}, 439 {},
438}; 440};
439 441
440static struct platform_driver tegra_i2s_driver = { 442static struct platform_driver tegra20_i2s_driver = {
441 .driver = { 443 .driver = {
442 .name = DRV_NAME, 444 .name = DRV_NAME,
443 .owner = THIS_MODULE, 445 .owner = THIS_MODULE,
444 .of_match_table = tegra_i2s_of_match, 446 .of_match_table = tegra20_i2s_of_match,
445 }, 447 },
446 .probe = tegra_i2s_platform_probe, 448 .probe = tegra20_i2s_platform_probe,
447 .remove = __devexit_p(tegra_i2s_platform_remove), 449 .remove = __devexit_p(tegra20_i2s_platform_remove),
448}; 450};
449module_platform_driver(tegra_i2s_driver); 451module_platform_driver(tegra20_i2s_driver);
450 452
451MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 453MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
452MODULE_DESCRIPTION("Tegra I2S ASoC driver"); 454MODULE_DESCRIPTION("Tegra20 I2S ASoC driver");
453MODULE_LICENSE("GPL"); 455MODULE_LICENSE("GPL");
454MODULE_ALIAS("platform:" DRV_NAME); 456MODULE_ALIAS("platform:" DRV_NAME);
455MODULE_DEVICE_TABLE(of, tegra_i2s_of_match); 457MODULE_DEVICE_TABLE(of, tegra20_i2s_of_match);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
new file mode 100644
index 000000000000..86ab327dbd26
--- /dev/null
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -0,0 +1,165 @@
1/*
2 * tegra20_i2s.h - Definitions for Tegra20 I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA20_I2S_H__
32#define __TEGRA20_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA20_I2S1_BASE and TEGRA20_I2S2_BASE */
37
38#define TEGRA20_I2S_CTRL 0x00
39#define TEGRA20_I2S_STATUS 0x04
40#define TEGRA20_I2S_TIMING 0x08
41#define TEGRA20_I2S_FIFO_SCR 0x0c
42#define TEGRA20_I2S_PCM_CTRL 0x10
43#define TEGRA20_I2S_NW_CTRL 0x14
44#define TEGRA20_I2S_TDM_CTRL 0x20
45#define TEGRA20_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA20_I2S_FIFO1 0x40
47#define TEGRA20_I2S_FIFO2 0x80
48
49/* Fields in TEGRA20_I2S_CTRL */
50
51#define TEGRA20_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA20_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA20_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA20_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA20_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA20_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA20_I2S_LRCK_LEFT_LOW 0
59#define TEGRA20_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA20_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA20_I2S_CTRL_LRCK_MASK (1 << TEGRA20_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA20_I2S_CTRL_LRCK_L_LOW (TEGRA20_I2S_LRCK_LEFT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA20_I2S_CTRL_LRCK_R_LOW (TEGRA20_I2S_LRCK_RIGHT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA20_I2S_BIT_FORMAT_I2S 0
67#define TEGRA20_I2S_BIT_FORMAT_RJM 1
68#define TEGRA20_I2S_BIT_FORMAT_LJM 2
69#define TEGRA20_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA20_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA20_I2S_CTRL_BIT_FORMAT_I2S (TEGRA20_I2S_BIT_FORMAT_I2S << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA20_I2S_CTRL_BIT_FORMAT_RJM (TEGRA20_I2S_BIT_FORMAT_RJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA20_I2S_CTRL_BIT_FORMAT_LJM (TEGRA20_I2S_BIT_FORMAT_LJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA20_I2S_CTRL_BIT_FORMAT_DSP (TEGRA20_I2S_BIT_FORMAT_DSP << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA20_I2S_BIT_SIZE_16 0
79#define TEGRA20_I2S_BIT_SIZE_20 1
80#define TEGRA20_I2S_BIT_SIZE_24 2
81#define TEGRA20_I2S_BIT_SIZE_32 3
82
83#define TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA20_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA20_I2S_CTRL_BIT_SIZE_16 (TEGRA20_I2S_BIT_SIZE_16 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA20_I2S_CTRL_BIT_SIZE_20 (TEGRA20_I2S_BIT_SIZE_20 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA20_I2S_CTRL_BIT_SIZE_24 (TEGRA20_I2S_BIT_SIZE_24 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA20_I2S_CTRL_BIT_SIZE_32 (TEGRA20_I2S_BIT_SIZE_32 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA20_I2S_FIFO_16_LSB 0
91#define TEGRA20_I2S_FIFO_20_LSB 1
92#define TEGRA20_I2S_FIFO_24_LSB 2
93#define TEGRA20_I2S_FIFO_32 3
94#define TEGRA20_I2S_FIFO_PACKED 7
95
96#define TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA20_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA20_I2S_FIFO_16_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA20_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA20_I2S_FIFO_20_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA20_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA20_I2S_FIFO_24_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA20_I2S_CTRL_FIFO_FORMAT_32 (TEGRA20_I2S_FIFO_32 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA20_I2S_FIFO_PACKED << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA20_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA20_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA20_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA20_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA20_I2S_STATUS */
110
111#define TEGRA20_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA20_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA20_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA20_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA20_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA20_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA20_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA20_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA20_I2S_TIMING */
121
122#define TEGRA20_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA20_I2S_FIFO_SCR */
128
129#define TEGRA20_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA20_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA20_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA20_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA20_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra20_i2s {
156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data;
160 void __iomem *regs;
161 struct dentry *debug;
162 u32 reg_ctrl;
163};
164
165#endif
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 475428cf270e..ef5d49ed5658 100644
--- a/sound/soc/tegra/tegra_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * tegra_spdif.c - Tegra SPDIF driver 2 * tegra20_spdif.c - Tegra20 SPDIF driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc. 5 * Copyright (C) 2011-2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -21,120 +21,119 @@
21 */ 21 */
22 22
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/module.h>
25#include <linux/debugfs.h> 24#include <linux/debugfs.h>
26#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/io.h>
27#include <linux/module.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/seq_file.h> 29#include <linux/seq_file.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/io.h>
31#include <mach/iomap.h>
32#include <sound/core.h> 31#include <sound/core.h>
33#include <sound/pcm.h> 32#include <sound/pcm.h>
34#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
35#include <sound/soc.h> 34#include <sound/soc.h>
36 35
37#include "tegra_spdif.h" 36#include "tegra20_spdif.h"
38 37
39#define DRV_NAME "tegra-spdif" 38#define DRV_NAME "tegra20-spdif"
40 39
41static inline void tegra_spdif_write(struct tegra_spdif *spdif, u32 reg, 40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
42 u32 val) 41 u32 val)
43{ 42{
44 __raw_writel(val, spdif->regs + reg); 43 __raw_writel(val, spdif->regs + reg);
45} 44}
46 45
47static inline u32 tegra_spdif_read(struct tegra_spdif *spdif, u32 reg) 46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
48{ 47{
49 return __raw_readl(spdif->regs + reg); 48 return __raw_readl(spdif->regs + reg);
50} 49}
51 50
52#ifdef CONFIG_DEBUG_FS 51#ifdef CONFIG_DEBUG_FS
53static int tegra_spdif_show(struct seq_file *s, void *unused) 52static int tegra20_spdif_show(struct seq_file *s, void *unused)
54{ 53{
55#define REG(r) { r, #r } 54#define REG(r) { r, #r }
56 static const struct { 55 static const struct {
57 int offset; 56 int offset;
58 const char *name; 57 const char *name;
59 } regs[] = { 58 } regs[] = {
60 REG(TEGRA_SPDIF_CTRL), 59 REG(TEGRA20_SPDIF_CTRL),
61 REG(TEGRA_SPDIF_STATUS), 60 REG(TEGRA20_SPDIF_STATUS),
62 REG(TEGRA_SPDIF_STROBE_CTRL), 61 REG(TEGRA20_SPDIF_STROBE_CTRL),
63 REG(TEGRA_SPDIF_DATA_FIFO_CSR), 62 REG(TEGRA20_SPDIF_DATA_FIFO_CSR),
64 REG(TEGRA_SPDIF_CH_STA_RX_A), 63 REG(TEGRA20_SPDIF_CH_STA_RX_A),
65 REG(TEGRA_SPDIF_CH_STA_RX_B), 64 REG(TEGRA20_SPDIF_CH_STA_RX_B),
66 REG(TEGRA_SPDIF_CH_STA_RX_C), 65 REG(TEGRA20_SPDIF_CH_STA_RX_C),
67 REG(TEGRA_SPDIF_CH_STA_RX_D), 66 REG(TEGRA20_SPDIF_CH_STA_RX_D),
68 REG(TEGRA_SPDIF_CH_STA_RX_E), 67 REG(TEGRA20_SPDIF_CH_STA_RX_E),
69 REG(TEGRA_SPDIF_CH_STA_RX_F), 68 REG(TEGRA20_SPDIF_CH_STA_RX_F),
70 REG(TEGRA_SPDIF_CH_STA_TX_A), 69 REG(TEGRA20_SPDIF_CH_STA_TX_A),
71 REG(TEGRA_SPDIF_CH_STA_TX_B), 70 REG(TEGRA20_SPDIF_CH_STA_TX_B),
72 REG(TEGRA_SPDIF_CH_STA_TX_C), 71 REG(TEGRA20_SPDIF_CH_STA_TX_C),
73 REG(TEGRA_SPDIF_CH_STA_TX_D), 72 REG(TEGRA20_SPDIF_CH_STA_TX_D),
74 REG(TEGRA_SPDIF_CH_STA_TX_E), 73 REG(TEGRA20_SPDIF_CH_STA_TX_E),
75 REG(TEGRA_SPDIF_CH_STA_TX_F), 74 REG(TEGRA20_SPDIF_CH_STA_TX_F),
76 }; 75 };
77#undef REG 76#undef REG
78 77
79 struct tegra_spdif *spdif = s->private; 78 struct tegra20_spdif *spdif = s->private;
80 int i; 79 int i;
81 80
82 for (i = 0; i < ARRAY_SIZE(regs); i++) { 81 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_spdif_read(spdif, regs[i].offset); 82 u32 val = tegra20_spdif_read(spdif, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val); 83 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 } 84 }
86 85
87 return 0; 86 return 0;
88} 87}
89 88
90static int tegra_spdif_debug_open(struct inode *inode, struct file *file) 89static int tegra20_spdif_debug_open(struct inode *inode, struct file *file)
91{ 90{
92 return single_open(file, tegra_spdif_show, inode->i_private); 91 return single_open(file, tegra20_spdif_show, inode->i_private);
93} 92}
94 93
95static const struct file_operations tegra_spdif_debug_fops = { 94static const struct file_operations tegra20_spdif_debug_fops = {
96 .open = tegra_spdif_debug_open, 95 .open = tegra20_spdif_debug_open,
97 .read = seq_read, 96 .read = seq_read,
98 .llseek = seq_lseek, 97 .llseek = seq_lseek,
99 .release = single_release, 98 .release = single_release,
100}; 99};
101 100
102static void tegra_spdif_debug_add(struct tegra_spdif *spdif) 101static void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
103{ 102{
104 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO, 103 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
105 snd_soc_debugfs_root, spdif, 104 snd_soc_debugfs_root, spdif,
106 &tegra_spdif_debug_fops); 105 &tegra20_spdif_debug_fops);
107} 106}
108 107
109static void tegra_spdif_debug_remove(struct tegra_spdif *spdif) 108static void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
110{ 109{
111 if (spdif->debug) 110 if (spdif->debug)
112 debugfs_remove(spdif->debug); 111 debugfs_remove(spdif->debug);
113} 112}
114#else 113#else
115static inline void tegra_spdif_debug_add(struct tegra_spdif *spdif) 114static inline void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
116{ 115{
117} 116}
118 117
119static inline void tegra_spdif_debug_remove(struct tegra_spdif *spdif) 118static inline void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
120{ 119{
121} 120}
122#endif 121#endif
123 122
124static int tegra_spdif_hw_params(struct snd_pcm_substream *substream, 123static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 124 struct snd_pcm_hw_params *params,
126 struct snd_soc_dai *dai) 125 struct snd_soc_dai *dai)
127{ 126{
128 struct device *dev = substream->pcm->card->dev; 127 struct device *dev = substream->pcm->card->dev;
129 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 128 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
130 int ret, spdifclock; 129 int ret, spdifclock;
131 130
132 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; 131 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK;
133 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; 132 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
134 switch (params_format(params)) { 133 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE: 134 case SNDRV_PCM_FORMAT_S16_LE:
136 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_PACK; 135 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK;
137 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_BIT_MODE_16BIT; 136 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
138 break; 137 break;
139 default: 138 default:
140 return -EINVAL; 139 return -EINVAL;
@@ -175,39 +174,35 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
175 return 0; 174 return 0;
176} 175}
177 176
178static void tegra_spdif_start_playback(struct tegra_spdif *spdif) 177static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
179{ 178{
180 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_TX_EN; 179 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN;
181 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl); 180 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
182} 181}
183 182
184static void tegra_spdif_stop_playback(struct tegra_spdif *spdif) 183static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
185{ 184{
186 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_TX_EN; 185 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN;
187 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl); 186 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
188} 187}
189 188
190static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 189static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
191 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
192{ 191{
193 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 192 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
194 193
195 switch (cmd) { 194 switch (cmd) {
196 case SNDRV_PCM_TRIGGER_START: 195 case SNDRV_PCM_TRIGGER_START:
197 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 196 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
198 case SNDRV_PCM_TRIGGER_RESUME: 197 case SNDRV_PCM_TRIGGER_RESUME:
199 if (!spdif->clk_refs) 198 clk_enable(spdif->clk_spdif_out);
200 clk_enable(spdif->clk_spdif_out); 199 tegra20_spdif_start_playback(spdif);
201 spdif->clk_refs++;
202 tegra_spdif_start_playback(spdif);
203 break; 200 break;
204 case SNDRV_PCM_TRIGGER_STOP: 201 case SNDRV_PCM_TRIGGER_STOP:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 202 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 case SNDRV_PCM_TRIGGER_SUSPEND: 203 case SNDRV_PCM_TRIGGER_SUSPEND:
207 tegra_spdif_stop_playback(spdif); 204 tegra20_spdif_stop_playback(spdif);
208 spdif->clk_refs--; 205 clk_disable(spdif->clk_spdif_out);
209 if (!spdif->clk_refs)
210 clk_disable(spdif->clk_spdif_out);
211 break; 206 break;
212 default: 207 default:
213 return -EINVAL; 208 return -EINVAL;
@@ -216,9 +211,9 @@ static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
216 return 0; 211 return 0;
217} 212}
218 213
219static int tegra_spdif_probe(struct snd_soc_dai *dai) 214static int tegra20_spdif_probe(struct snd_soc_dai *dai)
220{ 215{
221 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); 216 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
222 217
223 dai->capture_dma_data = NULL; 218 dai->capture_dma_data = NULL;
224 dai->playback_dma_data = &spdif->playback_dma_data; 219 dai->playback_dma_data = &spdif->playback_dma_data;
@@ -226,14 +221,14 @@ static int tegra_spdif_probe(struct snd_soc_dai *dai)
226 return 0; 221 return 0;
227} 222}
228 223
229static const struct snd_soc_dai_ops tegra_spdif_dai_ops = { 224static const struct snd_soc_dai_ops tegra20_spdif_dai_ops = {
230 .hw_params = tegra_spdif_hw_params, 225 .hw_params = tegra20_spdif_hw_params,
231 .trigger = tegra_spdif_trigger, 226 .trigger = tegra20_spdif_trigger,
232}; 227};
233 228
234static struct snd_soc_dai_driver tegra_spdif_dai = { 229static struct snd_soc_dai_driver tegra20_spdif_dai = {
235 .name = DRV_NAME, 230 .name = DRV_NAME,
236 .probe = tegra_spdif_probe, 231 .probe = tegra20_spdif_probe,
237 .playback = { 232 .playback = {
238 .channels_min = 2, 233 .channels_min = 2,
239 .channels_max = 2, 234 .channels_max = 2,
@@ -241,20 +236,21 @@ static struct snd_soc_dai_driver tegra_spdif_dai = {
241 SNDRV_PCM_RATE_48000, 236 SNDRV_PCM_RATE_48000,
242 .formats = SNDRV_PCM_FMTBIT_S16_LE, 237 .formats = SNDRV_PCM_FMTBIT_S16_LE,
243 }, 238 },
244 .ops = &tegra_spdif_dai_ops, 239 .ops = &tegra20_spdif_dai_ops,
245}; 240};
246 241
247static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev) 242static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
248{ 243{
249 struct tegra_spdif *spdif; 244 struct tegra20_spdif *spdif;
250 struct resource *mem, *memregion, *dmareq; 245 struct resource *mem, *memregion, *dmareq;
251 int ret; 246 int ret;
252 247
253 spdif = kzalloc(sizeof(struct tegra_spdif), GFP_KERNEL); 248 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
249 GFP_KERNEL);
254 if (!spdif) { 250 if (!spdif) {
255 dev_err(&pdev->dev, "Can't allocate tegra_spdif\n"); 251 dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
256 ret = -ENOMEM; 252 ret = -ENOMEM;
257 goto exit; 253 goto err;
258 } 254 }
259 dev_set_drvdata(&pdev->dev, spdif); 255 dev_set_drvdata(&pdev->dev, spdif);
260 256
@@ -262,7 +258,7 @@ static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
262 if (IS_ERR(spdif->clk_spdif_out)) { 258 if (IS_ERR(spdif->clk_spdif_out)) {
263 pr_err("Can't retrieve spdif clock\n"); 259 pr_err("Can't retrieve spdif clock\n");
264 ret = PTR_ERR(spdif->clk_spdif_out); 260 ret = PTR_ERR(spdif->clk_spdif_out);
265 goto err_free; 261 goto err;
266 } 262 }
267 263
268 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 264 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -279,82 +275,77 @@ static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
279 goto err_clk_put; 275 goto err_clk_put;
280 } 276 }
281 277
282 memregion = request_mem_region(mem->start, resource_size(mem), 278 memregion = devm_request_mem_region(&pdev->dev, mem->start,
283 DRV_NAME); 279 resource_size(mem), DRV_NAME);
284 if (!memregion) { 280 if (!memregion) {
285 dev_err(&pdev->dev, "Memory region already claimed\n"); 281 dev_err(&pdev->dev, "Memory region already claimed\n");
286 ret = -EBUSY; 282 ret = -EBUSY;
287 goto err_clk_put; 283 goto err_clk_put;
288 } 284 }
289 285
290 spdif->regs = ioremap(mem->start, resource_size(mem)); 286 spdif->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
291 if (!spdif->regs) { 287 if (!spdif->regs) {
292 dev_err(&pdev->dev, "ioremap failed\n"); 288 dev_err(&pdev->dev, "ioremap failed\n");
293 ret = -ENOMEM; 289 ret = -ENOMEM;
294 goto err_release; 290 goto err_clk_put;
295 } 291 }
296 292
297 spdif->playback_dma_data.addr = mem->start + TEGRA_SPDIF_DATA_OUT; 293 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
298 spdif->playback_dma_data.wrap = 4; 294 spdif->playback_dma_data.wrap = 4;
299 spdif->playback_dma_data.width = 32; 295 spdif->playback_dma_data.width = 32;
300 spdif->playback_dma_data.req_sel = dmareq->start; 296 spdif->playback_dma_data.req_sel = dmareq->start;
301 297
302 ret = snd_soc_register_dai(&pdev->dev, &tegra_spdif_dai); 298 ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai);
303 if (ret) { 299 if (ret) {
304 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 300 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
305 ret = -ENOMEM; 301 ret = -ENOMEM;
306 goto err_unmap; 302 goto err_clk_put;
307 } 303 }
308 304
309 tegra_spdif_debug_add(spdif); 305 ret = tegra_pcm_platform_register(&pdev->dev);
306 if (ret) {
307 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
308 goto err_unregister_dai;
309 }
310
311 tegra20_spdif_debug_add(spdif);
310 312
311 return 0; 313 return 0;
312 314
313err_unmap: 315err_unregister_dai:
314 iounmap(spdif->regs); 316 snd_soc_unregister_dai(&pdev->dev);
315err_release:
316 release_mem_region(mem->start, resource_size(mem));
317err_clk_put: 317err_clk_put:
318 clk_put(spdif->clk_spdif_out); 318 clk_put(spdif->clk_spdif_out);
319err_free: 319err:
320 kfree(spdif);
321exit:
322 return ret; 320 return ret;
323} 321}
324 322
325static int __devexit tegra_spdif_platform_remove(struct platform_device *pdev) 323static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev)
326{ 324{
327 struct tegra_spdif *spdif = dev_get_drvdata(&pdev->dev); 325 struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev);
328 struct resource *res;
329 326
327 tegra_pcm_platform_unregister(&pdev->dev);
330 snd_soc_unregister_dai(&pdev->dev); 328 snd_soc_unregister_dai(&pdev->dev);
331 329
332 tegra_spdif_debug_remove(spdif); 330 tegra20_spdif_debug_remove(spdif);
333
334 iounmap(spdif->regs);
335
336 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 release_mem_region(res->start, resource_size(res));
338 331
339 clk_put(spdif->clk_spdif_out); 332 clk_put(spdif->clk_spdif_out);
340 333
341 kfree(spdif);
342
343 return 0; 334 return 0;
344} 335}
345 336
346static struct platform_driver tegra_spdif_driver = { 337static struct platform_driver tegra20_spdif_driver = {
347 .driver = { 338 .driver = {
348 .name = DRV_NAME, 339 .name = DRV_NAME,
349 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
350 }, 341 },
351 .probe = tegra_spdif_platform_probe, 342 .probe = tegra20_spdif_platform_probe,
352 .remove = __devexit_p(tegra_spdif_platform_remove), 343 .remove = __devexit_p(tegra20_spdif_platform_remove),
353}; 344};
354 345
355module_platform_driver(tegra_spdif_driver); 346module_platform_driver(tegra20_spdif_driver);
356 347
357MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 348MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
358MODULE_DESCRIPTION("Tegra SPDIF ASoC driver"); 349MODULE_DESCRIPTION("Tegra20 SPDIF ASoC driver");
359MODULE_LICENSE("GPL"); 350MODULE_LICENSE("GPL");
360MODULE_ALIAS("platform:" DRV_NAME); 351MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
new file mode 100644
index 000000000000..823af4c6bb7c
--- /dev/null
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -0,0 +1,472 @@
1/*
2 * tegra20_spdif.h - Definitions for Tegra20 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 __TEGRA20_SPDIF_H__
27#define __TEGRA20_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA20_SPDIF_BASE */
32
33#define TEGRA20_SPDIF_CTRL 0x0
34#define TEGRA20_SPDIF_STATUS 0x4
35#define TEGRA20_SPDIF_STROBE_CTRL 0x8
36#define TEGRA20_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA20_SPDIF_DATA_OUT 0x40
38#define TEGRA20_SPDIF_DATA_IN 0x80
39#define TEGRA20_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA20_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA20_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA20_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA20_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA20_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA20_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA20_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA20_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA20_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA20_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA20_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA20_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA20_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA20_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA20_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA20_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA20_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA20_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA20_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA20_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA20_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA20_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA20_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA20_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA20_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA20_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA20_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA20_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA20_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA20_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 TEGRA20_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 TEGRA20_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA20_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA20_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA20_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA20_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA20_SPDIF_BIT_MODE_16BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA20_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA20_SPDIF_BIT_MODE_20BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA20_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA20_SPDIF_BIT_MODE_24BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA20_SPDIF_CTRL_BIT_MODE_RAW (TEGRA20_SPDIF_BIT_MODE_RAW << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA20_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 TEGRA20_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 TEGRA20_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 TEGRA20_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 TEGRA20_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA20_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA20_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA20_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA20_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 TEGRA20_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA20_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 TEGRA20_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 TEGRA20_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 TEGRA20_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 TEGRA20_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA20_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA20_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 TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA20_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 TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA20_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 TEGRA20_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA20_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 TEGRA20_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA20_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 TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA20_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA20_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA20_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA20_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 TEGRA20_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA20_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA20_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA20_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA20_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA20_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA20_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA20_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA20_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA20_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA20_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA20_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA20_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 TEGRA20_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA20_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA20_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA20_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA20_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA20_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 TEGRA20_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 TEGRA20_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 tegra20_spdif {
464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data;
467 void __iomem *regs;
468 struct dentry *debug;
469 u32 reg_ctrl;
470};
471
472#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index e45ccd851f6a..32de7006daf0 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,16 +1,17 @@
1/* 1/*
2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3* 3 *
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5* 5 * Copyright (C) 2012 - NVIDIA, Inc.
6* Authors: Leon Romanovsky <leon@leon.nu> 6 *
7* Andrey Danin <danindrey@mail.ru> 7 * Authors: Leon Romanovsky <leon@leon.nu>
8* Marc Dietrich <marvin24@gmx.de> 8 * Andrey Danin <danindrey@mail.ru>
9* 9 * Marc Dietrich <marvin24@gmx.de>
10* This program is free software; you can redistribute it and/or modify 10 *
11* it under the terms of the GNU General Public License version 2 as 11 * This program is free software; you can redistribute it and/or modify
12* published by the Free Software Foundation. 12 * it under the terms of the GNU General Public License version 2 as
13*/ 13 * published by the Free Software Foundation.
14 */
14 15
15#include <asm/mach-types.h> 16#include <asm/mach-types.h>
16 17
@@ -28,9 +29,6 @@
28 29
29#include "../codecs/alc5632.h" 30#include "../codecs/alc5632.h"
30 31
31#include "tegra_das.h"
32#include "tegra_i2s.h"
33#include "tegra_pcm.h"
34#include "tegra_asoc_utils.h" 32#include "tegra_asoc_utils.h"
35 33
36#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
@@ -39,7 +37,6 @@
39 37
40struct tegra_alc5632 { 38struct tegra_alc5632 {
41 struct tegra_asoc_utils_data util_data; 39 struct tegra_asoc_utils_data util_data;
42 struct platform_device *pcm_dev;
43 int gpio_requested; 40 int gpio_requested;
44 int gpio_hp_det; 41 int gpio_hp_det;
45}; 42};
@@ -140,7 +137,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
140static struct snd_soc_dai_link tegra_alc5632_dai = { 137static struct snd_soc_dai_link tegra_alc5632_dai = {
141 .name = "ALC5632", 138 .name = "ALC5632",
142 .stream_name = "ALC5632 PCM", 139 .stream_name = "ALC5632 PCM",
143 .platform_name = "tegra-pcm-audio",
144 .codec_dai_name = "alc5632-hifi", 140 .codec_dai_name = "alc5632-hifi",
145 .init = tegra_alc5632_asoc_init, 141 .init = tegra_alc5632_asoc_init,
146 .ops = &tegra_alc5632_asoc_ops, 142 .ops = &tegra_alc5632_asoc_ops,
@@ -179,8 +175,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
179 platform_set_drvdata(pdev, card); 175 platform_set_drvdata(pdev, card);
180 snd_soc_card_set_drvdata(card, alc5632); 176 snd_soc_card_set_drvdata(card, alc5632);
181 177
182 alc5632->pcm_dev = ERR_PTR(-EINVAL);
183
184 if (!(pdev->dev.of_node)) { 178 if (!(pdev->dev.of_node)) {
185 dev_err(&pdev->dev, "Must be instantiated using device tree\n"); 179 dev_err(&pdev->dev, "Must be instantiated using device tree\n");
186 ret = -EINVAL; 180 ret = -EINVAL;
@@ -214,18 +208,11 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
214 goto err; 208 goto err;
215 } 209 }
216 210
217 alc5632->pcm_dev = platform_device_register_simple( 211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node;
218 "tegra-pcm-audio", -1, NULL, 0);
219 if (IS_ERR(alc5632->pcm_dev)) {
220 dev_err(&pdev->dev,
221 "Can't instantiate tegra-pcm-audio\n");
222 ret = PTR_ERR(alc5632->pcm_dev);
223 goto err;
224 }
225 212
226 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
227 if (ret) 214 if (ret)
228 goto err_unregister; 215 goto err;
229 216
230 ret = snd_soc_register_card(card); 217 ret = snd_soc_register_card(card);
231 if (ret) { 218 if (ret) {
@@ -238,9 +225,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
238 225
239err_fini_utils: 226err_fini_utils:
240 tegra_asoc_utils_fini(&alc5632->util_data); 227 tegra_asoc_utils_fini(&alc5632->util_data);
241err_unregister:
242 if (!IS_ERR(alc5632->pcm_dev))
243 platform_device_unregister(alc5632->pcm_dev);
244err: 228err:
245 return ret; 229 return ret;
246} 230}
@@ -259,8 +243,6 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
259 snd_soc_unregister_card(card); 243 snd_soc_unregister_card(card);
260 244
261 tegra_asoc_utils_fini(&machine->util_data); 245 tegra_asoc_utils_fini(&machine->util_data);
262 if (!IS_ERR(machine->pcm_dev))
263 platform_device_unregister(machine->pcm_dev);
264 246
265 return 0; 247 return 0;
266} 248}
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index f8428e410e05..266189d4ff13 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.c - Harmony machine ASoC driver 2 * tegra_asoc_utils.c - Harmony machine ASoC driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
28 29
29#include "tegra_asoc_utils.h" 30#include "tegra_asoc_utils.h"
30 31
@@ -40,7 +41,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
40 case 22050: 41 case 22050:
41 case 44100: 42 case 44100:
42 case 88200: 43 case 88200:
43 new_baseclock = 56448000; 44 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
45 new_baseclock = 56448000;
46 else
47 new_baseclock = 564480000;
44 break; 48 break;
45 case 8000: 49 case 8000:
46 case 16000: 50 case 16000:
@@ -48,7 +52,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
48 case 48000: 52 case 48000:
49 case 64000: 53 case 64000:
50 case 96000: 54 case 96000:
51 new_baseclock = 73728000; 55 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
56 new_baseclock = 73728000;
57 else
58 new_baseclock = 552960000;
52 break; 59 break;
53 default: 60 default:
54 return -EINVAL; 61 return -EINVAL;
@@ -78,7 +85,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
78 return err; 85 return err;
79 } 86 }
80 87
81 /* Don't set cdev1 rate; its locked to pll_a_out0 */ 88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
82 89
83 err = clk_enable(data->clk_pll_a); 90 err = clk_enable(data->clk_pll_a);
84 if (err) { 91 if (err) {
@@ -112,6 +119,15 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
112 119
113 data->dev = dev; 120 data->dev = dev;
114 121
122 if (!of_have_populated_dt())
123 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
124 else if (of_machine_is_compatible("nvidia,tegra20"))
125 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
126 else if (of_machine_is_compatible("nvidia,tegra30"))
127 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
128 else
129 return -EINVAL;
130
115 data->clk_pll_a = clk_get_sys(NULL, "pll_a"); 131 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
116 if (IS_ERR(data->clk_pll_a)) { 132 if (IS_ERR(data->clk_pll_a)) {
117 dev_err(data->dev, "Can't retrieve clk pll_a\n"); 133 dev_err(data->dev, "Can't retrieve clk pll_a\n");
@@ -126,15 +142,24 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
126 goto err_put_pll_a; 142 goto err_put_pll_a;
127 } 143 }
128 144
129 data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); 145 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
146 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
147 else
148 data->clk_cdev1 = clk_get_sys("extern1", NULL);
130 if (IS_ERR(data->clk_cdev1)) { 149 if (IS_ERR(data->clk_cdev1)) {
131 dev_err(data->dev, "Can't retrieve clk cdev1\n"); 150 dev_err(data->dev, "Can't retrieve clk cdev1\n");
132 ret = PTR_ERR(data->clk_cdev1); 151 ret = PTR_ERR(data->clk_cdev1);
133 goto err_put_pll_a_out0; 152 goto err_put_pll_a_out0;
134 } 153 }
135 154
155 ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100);
156 if (ret)
157 goto err_put_cdev1;
158
136 return 0; 159 return 0;
137 160
161err_put_cdev1:
162 clk_put(data->clk_cdev1);
138err_put_pll_a_out0: 163err_put_pll_a_out0:
139 clk_put(data->clk_pll_a_out0); 164 clk_put(data->clk_pll_a_out0);
140err_put_pll_a: 165err_put_pll_a:
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 4818195da25c..44db1dbb8f21 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver 2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -26,8 +26,14 @@
26struct clk; 26struct clk;
27struct device; 27struct device;
28 28
29enum tegra_asoc_utils_soc {
30 TEGRA_ASOC_UTILS_SOC_TEGRA20,
31 TEGRA_ASOC_UTILS_SOC_TEGRA30,
32};
33
29struct tegra_asoc_utils_data { 34struct tegra_asoc_utils_data {
30 struct device *dev; 35 struct device *dev;
36 enum tegra_asoc_utils_soc soc;
31 struct clk *clk_pll_a; 37 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0; 38 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1; 39 struct clk *clk_cdev1;
@@ -42,4 +48,3 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 48void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
43 49
44#endif 50#endif
45
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
deleted file mode 100644
index 3b3c1ba4d235..000000000000
--- a/sound/soc/tegra/tegra_das.c
+++ /dev/null
@@ -1,261 +0,0 @@
1/*
2 * tegra_das.c - Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - 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/module.h>
24#include <linux/debugfs.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/seq_file.h>
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <mach/iomap.h>
31#include <sound/soc.h>
32#include "tegra_das.h"
33
34#define DRV_NAME "tegra-das"
35
36static struct tegra_das *das;
37
38static inline void tegra_das_write(u32 reg, u32 val)
39{
40 __raw_writel(val, das->regs + reg);
41}
42
43static inline u32 tegra_das_read(u32 reg)
44{
45 return __raw_readl(das->regs + reg);
46}
47
48int tegra_das_connect_dap_to_dac(int dap, int dac)
49{
50 u32 addr;
51 u32 reg;
52
53 if (!das)
54 return -ENODEV;
55
56 addr = TEGRA_DAS_DAP_CTRL_SEL +
57 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
58 reg = dac << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
59
60 tegra_das_write(addr, reg);
61
62 return 0;
63}
64EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
65
66int tegra_das_connect_dap_to_dap(int dap, int otherdap, int master,
67 int sdata1rx, int sdata2rx)
68{
69 u32 addr;
70 u32 reg;
71
72 if (!das)
73 return -ENODEV;
74
75 addr = TEGRA_DAS_DAP_CTRL_SEL +
76 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
77 reg = otherdap << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
78 !!sdata2rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
79 !!sdata1rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
80 !!master << TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
81
82 tegra_das_write(addr, reg);
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
87
88int tegra_das_connect_dac_to_dap(int dac, int dap)
89{
90 u32 addr;
91 u32 reg;
92
93 if (!das)
94 return -ENODEV;
95
96 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
97 (dac * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
98 reg = dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
99 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
100 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
101
102 tegra_das_write(addr, reg);
103
104 return 0;
105}
106EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
107
108#ifdef CONFIG_DEBUG_FS
109static int tegra_das_show(struct seq_file *s, void *unused)
110{
111 int i;
112 u32 addr;
113 u32 reg;
114
115 for (i = 0; i < TEGRA_DAS_DAP_CTRL_SEL_COUNT; i++) {
116 addr = TEGRA_DAS_DAP_CTRL_SEL +
117 (i * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
118 reg = tegra_das_read(addr);
119 seq_printf(s, "TEGRA_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
120 }
121
122 for (i = 0; i < TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
123 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
124 (i * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
125 reg = tegra_das_read(addr);
126 seq_printf(s, "TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
127 i, reg);
128 }
129
130 return 0;
131}
132
133static int tegra_das_debug_open(struct inode *inode, struct file *file)
134{
135 return single_open(file, tegra_das_show, inode->i_private);
136}
137
138static const struct file_operations tegra_das_debug_fops = {
139 .open = tegra_das_debug_open,
140 .read = seq_read,
141 .llseek = seq_lseek,
142 .release = single_release,
143};
144
145static void tegra_das_debug_add(struct tegra_das *das)
146{
147 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
148 snd_soc_debugfs_root, das,
149 &tegra_das_debug_fops);
150}
151
152static void tegra_das_debug_remove(struct tegra_das *das)
153{
154 if (das->debug)
155 debugfs_remove(das->debug);
156}
157#else
158static inline void tegra_das_debug_add(struct tegra_das *das)
159{
160}
161
162static inline void tegra_das_debug_remove(struct tegra_das *das)
163{
164}
165#endif
166
167static int __devinit tegra_das_probe(struct platform_device *pdev)
168{
169 struct resource *res, *region;
170 int ret = 0;
171
172 if (das)
173 return -ENODEV;
174
175 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL);
176 if (!das) {
177 dev_err(&pdev->dev, "Can't allocate tegra_das\n");
178 ret = -ENOMEM;
179 goto err;
180 }
181 das->dev = &pdev->dev;
182
183 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 if (!res) {
185 dev_err(&pdev->dev, "No memory resource\n");
186 ret = -ENODEV;
187 goto err;
188 }
189
190 region = devm_request_mem_region(&pdev->dev, res->start,
191 resource_size(res), pdev->name);
192 if (!region) {
193 dev_err(&pdev->dev, "Memory region already claimed\n");
194 ret = -EBUSY;
195 goto err;
196 }
197
198 das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
199 if (!das->regs) {
200 dev_err(&pdev->dev, "ioremap failed\n");
201 ret = -ENOMEM;
202 goto err;
203 }
204
205 ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
206 TEGRA_DAS_DAP_SEL_DAC1);
207 if (ret) {
208 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
209 goto err;
210 }
211 ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
212 TEGRA_DAS_DAC_SEL_DAP1);
213 if (ret) {
214 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
215 goto err;
216 }
217
218 tegra_das_debug_add(das);
219
220 platform_set_drvdata(pdev, das);
221
222 return 0;
223
224err:
225 das = NULL;
226 return ret;
227}
228
229static int __devexit tegra_das_remove(struct platform_device *pdev)
230{
231 if (!das)
232 return -ENODEV;
233
234 tegra_das_debug_remove(das);
235
236 das = NULL;
237
238 return 0;
239}
240
241static const struct of_device_id tegra_das_of_match[] __devinitconst = {
242 { .compatible = "nvidia,tegra20-das", },
243 {},
244};
245
246static struct platform_driver tegra_das_driver = {
247 .probe = tegra_das_probe,
248 .remove = __devexit_p(tegra_das_remove),
249 .driver = {
250 .name = DRV_NAME,
251 .owner = THIS_MODULE,
252 .of_match_table = tegra_das_of_match,
253 },
254};
255module_platform_driver(tegra_das_driver);
256
257MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
258MODULE_DESCRIPTION("Tegra DAS driver");
259MODULE_LICENSE("GPL");
260MODULE_ALIAS("platform:" DRV_NAME);
261MODULE_DEVICE_TABLE(of, tegra_das_of_match);
diff --git a/sound/soc/tegra/tegra_das.h b/sound/soc/tegra/tegra_das.h
deleted file mode 100644
index 2c96c7b3c459..000000000000
--- a/sound/soc/tegra/tegra_das.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * tegra_das.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - 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#ifndef __TEGRA_DAS_H__
24#define __TEGRA_DAS_H__
25
26/* Register TEGRA_DAS_DAP_CTRL_SEL */
27#define TEGRA_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA_DAS_DAP_SEL_DAC1 0
41#define TEGRA_DAS_DAP_SEL_DAC2 1
42#define TEGRA_DAS_DAP_SEL_DAC3 2
43#define TEGRA_DAS_DAP_SEL_DAP1 16
44#define TEGRA_DAS_DAP_SEL_DAP2 17
45#define TEGRA_DAS_DAP_SEL_DAP3 18
46#define TEGRA_DAS_DAP_SEL_DAP4 19
47#define TEGRA_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA_DAS_DAC_SEL_DAP1 0
67#define TEGRA_DAS_DAC_SEL_DAP2 1
68#define TEGRA_DAS_DAC_SEL_DAP3 2
69#define TEGRA_DAS_DAC_SEL_DAP4 3
70#define TEGRA_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA_DAS_DAP_ID_1 0
77#define TEGRA_DAS_DAP_ID_2 1
78#define TEGRA_DAS_DAP_ID_3 2
79#define TEGRA_DAS_DAP_ID_4 3
80#define TEGRA_DAS_DAP_ID_5 4
81
82#define TEGRA_DAS_DAC_ID_1 0
83#define TEGRA_DAS_DAC_ID_2 1
84#define TEGRA_DAS_DAC_ID_3 2
85
86struct tegra_das {
87 struct device *dev;
88 void __iomem *regs;
89 struct dentry *debug;
90};
91
92/*
93 * Terminology:
94 * DAS: Digital audio switch (HW module controlled by this driver)
95 * DAP: Digital audio port (port/pins on Tegra device)
96 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
97 *
98 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
99 * DAC, or another DAP. When DAPs are connected, one must be the master and
100 * one the slave. Each DAC allows selection of a specific DAP for input, to
101 * cater for the case where N DAPs are connected to 1 DAC for broadcast
102 * output.
103 *
104 * This driver is dumb; no attempt is made to ensure that a valid routing
105 * configuration is programmed.
106 */
107
108/*
109 * Connect a DAP to to a DAC
110 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA_DAS_DAP_SEL_DAC*
112 */
113extern int tegra_das_connect_dap_to_dac(int dap_id, int dac_sel);
114
115/*
116 * Connect a DAP to to another DAP
117 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA_DAS_DAP_SEL_DAP*
119 * master: Is this DAP the master (1) or slave (0)
120 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
121 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
122 */
123extern int tegra_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
124 int master, int sdata1rx,
125 int sdata2rx);
126
127/*
128 * Connect a DAC's input to a DAP
129 * (DAC outputs are selected by the DAP)
130 * dac_id: DAC ID to connect: TEGRA_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA_DAS_DAC_SEL_DAP*
132 */
133extern int tegra_das_connect_dac_to_dap(int dac_id, int dap_sel);
134
135#endif
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h
deleted file mode 100644
index 15ce1e2e8bde..000000000000
--- a/sound/soc/tegra/tegra_i2s.h
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * tegra_i2s.h - Definitions for Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA_I2S_H__
32#define __TEGRA_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
37
38#define TEGRA_I2S_CTRL 0x00
39#define TEGRA_I2S_STATUS 0x04
40#define TEGRA_I2S_TIMING 0x08
41#define TEGRA_I2S_FIFO_SCR 0x0c
42#define TEGRA_I2S_PCM_CTRL 0x10
43#define TEGRA_I2S_NW_CTRL 0x14
44#define TEGRA_I2S_TDM_CTRL 0x20
45#define TEGRA_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA_I2S_FIFO1 0x40
47#define TEGRA_I2S_FIFO2 0x80
48
49/* Fields in TEGRA_I2S_CTRL */
50
51#define TEGRA_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA_I2S_LRCK_LEFT_LOW 0
59#define TEGRA_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA_I2S_CTRL_LRCK_MASK (1 << TEGRA_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA_I2S_CTRL_LRCK_L_LOW (TEGRA_I2S_LRCK_LEFT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA_I2S_CTRL_LRCK_R_LOW (TEGRA_I2S_LRCK_RIGHT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA_I2S_BIT_FORMAT_I2S 0
67#define TEGRA_I2S_BIT_FORMAT_RJM 1
68#define TEGRA_I2S_BIT_FORMAT_LJM 2
69#define TEGRA_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA_I2S_CTRL_BIT_FORMAT_I2S (TEGRA_I2S_BIT_FORMAT_I2S << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA_I2S_CTRL_BIT_FORMAT_RJM (TEGRA_I2S_BIT_FORMAT_RJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA_I2S_CTRL_BIT_FORMAT_LJM (TEGRA_I2S_BIT_FORMAT_LJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA_I2S_CTRL_BIT_FORMAT_DSP (TEGRA_I2S_BIT_FORMAT_DSP << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA_I2S_BIT_SIZE_16 0
79#define TEGRA_I2S_BIT_SIZE_20 1
80#define TEGRA_I2S_BIT_SIZE_24 2
81#define TEGRA_I2S_BIT_SIZE_32 3
82
83#define TEGRA_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA_I2S_CTRL_BIT_SIZE_16 (TEGRA_I2S_BIT_SIZE_16 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA_I2S_CTRL_BIT_SIZE_20 (TEGRA_I2S_BIT_SIZE_20 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA_I2S_CTRL_BIT_SIZE_24 (TEGRA_I2S_BIT_SIZE_24 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA_I2S_CTRL_BIT_SIZE_32 (TEGRA_I2S_BIT_SIZE_32 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA_I2S_FIFO_16_LSB 0
91#define TEGRA_I2S_FIFO_20_LSB 1
92#define TEGRA_I2S_FIFO_24_LSB 2
93#define TEGRA_I2S_FIFO_32 3
94#define TEGRA_I2S_FIFO_PACKED 7
95
96#define TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA_I2S_FIFO_16_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA_I2S_FIFO_20_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA_I2S_FIFO_24_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA_I2S_CTRL_FIFO_FORMAT_32 (TEGRA_I2S_FIFO_32 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA_I2S_FIFO_PACKED << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA_I2S_STATUS */
110
111#define TEGRA_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA_I2S_TIMING */
121
122#define TEGRA_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA_I2S_FIFO_SCR */
128
129#define TEGRA_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra_i2s {
156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
158 int clk_refs;
159 struct tegra_pcm_dma_params capture_dma_data;
160 struct tegra_pcm_dma_params playback_dma_data;
161 void __iomem *regs;
162 struct dentry *debug;
163 u32 reg_ctrl;
164};
165
166#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 8b4457137c7c..127348dc09b1 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -2,7 +2,7 @@
2 * tegra_pcm.c - Tegra PCM driver 2 * tegra_pcm.c - Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,8 +29,8 @@
29 * 29 *
30 */ 30 */
31 31
32#include <linux/module.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/module.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
@@ -39,8 +39,6 @@
39 39
40#include "tegra_pcm.h" 40#include "tegra_pcm.h"
41 41
42#define DRV_NAME "tegra-pcm-audio"
43
44static const struct snd_pcm_hardware tegra_pcm_hardware = { 42static const struct snd_pcm_hardware tegra_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP | 43 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
@@ -372,28 +370,18 @@ static struct snd_soc_platform_driver tegra_pcm_platform = {
372 .pcm_free = tegra_pcm_free, 370 .pcm_free = tegra_pcm_free,
373}; 371};
374 372
375static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev) 373int __devinit tegra_pcm_platform_register(struct device *dev)
376{ 374{
377 return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform); 375 return snd_soc_register_platform(dev, &tegra_pcm_platform);
378} 376}
377EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
379 378
380static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev) 379void __devexit tegra_pcm_platform_unregister(struct device *dev)
381{ 380{
382 snd_soc_unregister_platform(&pdev->dev); 381 snd_soc_unregister_platform(dev);
383 return 0;
384} 382}
385 383EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister);
386static struct platform_driver tegra_pcm_driver = {
387 .driver = {
388 .name = DRV_NAME,
389 .owner = THIS_MODULE,
390 },
391 .probe = tegra_pcm_platform_probe,
392 .remove = __devexit_p(tegra_pcm_platform_remove),
393};
394module_platform_driver(tegra_pcm_driver);
395 384
396MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 385MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
397MODULE_DESCRIPTION("Tegra PCM ASoC driver"); 386MODULE_DESCRIPTION("Tegra PCM ASoC driver");
398MODULE_LICENSE("GPL"); 387MODULE_LICENSE("GPL");
399MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index dbb90339fe0d..985d418a35e7 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -2,7 +2,7 @@
2 * tegra_pcm.h - Definitions for Tegra PCM driver 2 * tegra_pcm.h - Definitions for Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -52,4 +52,7 @@ struct tegra_runtime_data {
52 struct tegra_dma_channel *dma_chan; 52 struct tegra_dma_channel *dma_chan;
53}; 53};
54 54
55int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev);
57
55#endif 58#endif
diff --git a/sound/soc/tegra/tegra_spdif.h b/sound/soc/tegra/tegra_spdif.h
deleted file mode 100644
index 2e03db430279..000000000000
--- a/sound/soc/tegra/tegra_spdif.h
+++ /dev/null
@@ -1,473 +0,0 @@
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
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 566655e23b7d..0b0df49d9d33 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -2,7 +2,7 @@
2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec. 2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc. 5 * Copyright (C) 2010-2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -46,9 +46,6 @@
46 46
47#include "../codecs/wm8903.h" 47#include "../codecs/wm8903.h"
48 48
49#include "tegra_das.h"
50#include "tegra_i2s.h"
51#include "tegra_pcm.h"
52#include "tegra_asoc_utils.h" 49#include "tegra_asoc_utils.h"
53 50
54#define DRV_NAME "tegra-snd-wm8903" 51#define DRV_NAME "tegra-snd-wm8903"
@@ -61,7 +58,6 @@
61 58
62struct tegra_wm8903 { 59struct tegra_wm8903 {
63 struct tegra_wm8903_platform_data pdata; 60 struct tegra_wm8903_platform_data pdata;
64 struct platform_device *pcm_dev;
65 struct tegra_asoc_utils_data util_data; 61 struct tegra_asoc_utils_data util_data;
66 int gpio_requested; 62 int gpio_requested;
67}; 63};
@@ -354,8 +350,8 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
354 .name = "WM8903", 350 .name = "WM8903",
355 .stream_name = "WM8903 PCM", 351 .stream_name = "WM8903 PCM",
356 .codec_name = "wm8903.0-001a", 352 .codec_name = "wm8903.0-001a",
357 .platform_name = "tegra-pcm-audio", 353 .platform_name = "tegra20-i2s.0",
358 .cpu_dai_name = "tegra-i2s.0", 354 .cpu_dai_name = "tegra20-i2s.0",
359 .codec_dai_name = "wm8903-hifi", 355 .codec_dai_name = "wm8903-hifi",
360 .init = tegra_wm8903_init, 356 .init = tegra_wm8903_init,
361 .ops = &tegra_wm8903_ops, 357 .ops = &tegra_wm8903_ops,
@@ -392,7 +388,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
392 ret = -ENOMEM; 388 ret = -ENOMEM;
393 goto err; 389 goto err;
394 } 390 }
395 machine->pcm_dev = ERR_PTR(-EINVAL);
396 391
397 card->dev = &pdev->dev; 392 card->dev = &pdev->dev;
398 platform_set_drvdata(pdev, card); 393 platform_set_drvdata(pdev, card);
@@ -428,14 +423,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
428 goto err; 423 goto err;
429 } 424 }
430 425
431 machine->pcm_dev = platform_device_register_simple( 426 tegra_wm8903_dai.platform_name = NULL;
432 "tegra-pcm-audio", -1, NULL, 0); 427 tegra_wm8903_dai.platform_of_node =
433 if (IS_ERR(machine->pcm_dev)) { 428 tegra_wm8903_dai.cpu_dai_of_node;
434 dev_err(&pdev->dev,
435 "Can't instantiate tegra-pcm-audio\n");
436 ret = PTR_ERR(machine->pcm_dev);
437 goto err;
438 }
439 } else { 429 } else {
440 if (machine_is_harmony()) { 430 if (machine_is_harmony()) {
441 card->dapm_routes = harmony_audio_map; 431 card->dapm_routes = harmony_audio_map;
@@ -454,7 +444,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
454 444
455 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 445 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
456 if (ret) 446 if (ret)
457 goto err_unregister; 447 goto err;
458 448
459 ret = snd_soc_register_card(card); 449 ret = snd_soc_register_card(card);
460 if (ret) { 450 if (ret) {
@@ -467,9 +457,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
467 457
468err_fini_utils: 458err_fini_utils:
469 tegra_asoc_utils_fini(&machine->util_data); 459 tegra_asoc_utils_fini(&machine->util_data);
470err_unregister:
471 if (!IS_ERR(machine->pcm_dev))
472 platform_device_unregister(machine->pcm_dev);
473err: 460err:
474 return ret; 461 return ret;
475} 462}
@@ -497,8 +484,6 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
497 snd_soc_unregister_card(card); 484 snd_soc_unregister_card(card);
498 485
499 tegra_asoc_utils_fini(&machine->util_data); 486 tegra_asoc_utils_fini(&machine->util_data);
500 if (!IS_ERR(machine->pcm_dev))
501 platform_device_unregister(machine->pcm_dev);
502 487
503 return 0; 488 return 0;
504} 489}
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 2bdfc550cff8..0fd115e69a8a 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -38,9 +38,6 @@
38 38
39#include "../codecs/tlv320aic23.h" 39#include "../codecs/tlv320aic23.h"
40 40
41#include "tegra_das.h"
42#include "tegra_i2s.h"
43#include "tegra_pcm.h"
44#include "tegra_asoc_utils.h" 41#include "tegra_asoc_utils.h"
45 42
46#define DRV_NAME "tegra-snd-trimslice" 43#define DRV_NAME "tegra-snd-trimslice"
@@ -119,8 +116,8 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
119 .name = "TLV320AIC23", 116 .name = "TLV320AIC23",
120 .stream_name = "AIC23", 117 .stream_name = "AIC23",
121 .codec_name = "tlv320aic23-codec.2-001a", 118 .codec_name = "tlv320aic23-codec.2-001a",
122 .platform_name = "tegra-pcm-audio", 119 .platform_name = "tegra20-i2s.0",
123 .cpu_dai_name = "tegra-i2s.0", 120 .cpu_dai_name = "tegra20-i2s.0",
124 .codec_dai_name = "tlv320aic23-hifi", 121 .codec_dai_name = "tlv320aic23-hifi",
125 .ops = &trimslice_asoc_ops, 122 .ops = &trimslice_asoc_ops,
126}; 123};