~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to sound/soc/tegra/tegra_das.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
36
static struct tegra_das *das;
 
37
 
 
38
static inline void tegra_das_write(u32 reg, u32 val)
 
39
{
 
40
        __raw_writel(val, das->regs + reg);
 
41
}
 
42
 
 
43
static inline u32 tegra_das_read(u32 reg)
 
44
{
 
45
        return __raw_readl(das->regs + reg);
 
46
}
 
47
 
 
48
int 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
}
 
64
EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
 
65
 
 
66
int 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
}
 
86
EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
 
87
 
 
88
int 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
}
 
106
EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
 
107
 
 
108
#ifdef CONFIG_DEBUG_FS
 
109
static 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
 
 
133
static 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
 
 
138
static 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
 
 
145
static 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
 
 
152
static void tegra_das_debug_remove(struct tegra_das *das)
 
153
{
 
154
        if (das->debug)
 
155
                debugfs_remove(das->debug);
 
156
}
 
157
#else
 
158
static inline void tegra_das_debug_add(struct tegra_das *das)
 
159
{
 
160
}
 
161
 
 
162
static inline void tegra_das_debug_remove(struct tegra_das *das)
 
163
{
 
164
}
 
165
#endif
 
166
 
 
167
static 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 = kzalloc(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 exit;
 
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_free;
 
188
        }
 
189
 
 
190
        region = request_mem_region(res->start, resource_size(res),
 
191
                                        pdev->name);
 
192
        if (!region) {
 
193
                dev_err(&pdev->dev, "Memory region already claimed\n");
 
194
                ret = -EBUSY;
 
195
                goto err_free;
 
196
        }
 
197
 
 
198
        das->regs = ioremap(res->start, resource_size(res));
 
199
        if (!das->regs) {
 
200
                dev_err(&pdev->dev, "ioremap failed\n");
 
201
                ret = -ENOMEM;
 
202
                goto err_release;
 
203
        }
 
204
 
 
205
        tegra_das_debug_add(das);
 
206
 
 
207
        platform_set_drvdata(pdev, das);
 
208
 
 
209
        return 0;
 
210
 
 
211
err_release:
 
212
        release_mem_region(res->start, resource_size(res));
 
213
err_free:
 
214
        kfree(das);
 
215
        das = NULL;
 
216
exit:
 
217
        return ret;
 
218
}
 
219
 
 
220
static int __devexit tegra_das_remove(struct platform_device *pdev)
 
221
{
 
222
        struct resource *res;
 
223
 
 
224
        if (!das)
 
225
                return -ENODEV;
 
226
 
 
227
        platform_set_drvdata(pdev, NULL);
 
228
 
 
229
        tegra_das_debug_remove(das);
 
230
 
 
231
        iounmap(das->regs);
 
232
 
 
233
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
234
        release_mem_region(res->start, resource_size(res));
 
235
 
 
236
        kfree(das);
 
237
        das = NULL;
 
238
 
 
239
        return 0;
 
240
}
 
241
 
 
242
static struct platform_driver tegra_das_driver = {
 
243
        .probe = tegra_das_probe,
 
244
        .remove = __devexit_p(tegra_das_remove),
 
245
        .driver = {
 
246
                .name = DRV_NAME,
 
247
        },
 
248
};
 
249
 
 
250
static int __init tegra_das_modinit(void)
 
251
{
 
252
        return platform_driver_register(&tegra_das_driver);
 
253
}
 
254
module_init(tegra_das_modinit);
 
255
 
 
256
static void __exit tegra_das_modexit(void)
 
257
{
 
258
        platform_driver_unregister(&tegra_das_driver);
 
259
}
 
260
module_exit(tegra_das_modexit);
 
261
 
 
262
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 
263
MODULE_DESCRIPTION("Tegra DAS driver");
 
264
MODULE_LICENSE("GPL");
 
265
MODULE_ALIAS("platform:" DRV_NAME);