2 * tegra_das.c - Tegra DAS driver
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
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.
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.
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
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>
30 #include <mach/iomap.h>
31 #include <sound/soc.h>
32 #include "tegra_das.h"
34 #define DRV_NAME "tegra-das"
36 static struct tegra_das
*das
;
38 static inline void tegra_das_write(u32 reg
, u32 val
)
40 __raw_writel(val
, das
->regs
+ reg
);
43 static inline u32
tegra_das_read(u32 reg
)
45 return __raw_readl(das
->regs
+ reg
);
48 int tegra_das_connect_dap_to_dac(int dap
, int dac
)
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
;
60 tegra_das_write(addr
, reg
);
64 EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac
);
66 int tegra_das_connect_dap_to_dap(int dap
, int otherdap
, int master
,
67 int sdata1rx
, int sdata2rx
)
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
;
82 tegra_das_write(addr
, reg
);
86 EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap
);
88 int tegra_das_connect_dac_to_dap(int dac
, int dap
)
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
;
102 tegra_das_write(addr
, reg
);
106 EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap
);
108 #ifdef CONFIG_DEBUG_FS
109 static int tegra_das_show(struct seq_file
*s
, void *unused
)
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
);
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",
133 static int tegra_das_debug_open(struct inode
*inode
, struct file
*file
)
135 return single_open(file
, tegra_das_show
, inode
->i_private
);
138 static const struct file_operations tegra_das_debug_fops
= {
139 .open
= tegra_das_debug_open
,
142 .release
= single_release
,
145 static void tegra_das_debug_add(struct tegra_das
*das
)
147 das
->debug
= debugfs_create_file(DRV_NAME
, S_IRUGO
,
148 snd_soc_debugfs_root
, das
,
149 &tegra_das_debug_fops
);
152 static void tegra_das_debug_remove(struct tegra_das
*das
)
155 debugfs_remove(das
->debug
);
158 static inline void tegra_das_debug_add(struct tegra_das
*das
)
162 static inline void tegra_das_debug_remove(struct tegra_das
*das
)
167 static int __devinit
tegra_das_probe(struct platform_device
*pdev
)
169 struct resource
*res
, *region
;
175 das
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra_das
), GFP_KERNEL
);
177 dev_err(&pdev
->dev
, "Can't allocate tegra_das\n");
181 das
->dev
= &pdev
->dev
;
183 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
185 dev_err(&pdev
->dev
, "No memory resource\n");
190 region
= devm_request_mem_region(&pdev
->dev
, res
->start
,
191 resource_size(res
), pdev
->name
);
193 dev_err(&pdev
->dev
, "Memory region already claimed\n");
198 das
->regs
= devm_ioremap(&pdev
->dev
, res
->start
, resource_size(res
));
200 dev_err(&pdev
->dev
, "ioremap failed\n");
205 ret
= tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1
,
206 TEGRA_DAS_DAP_SEL_DAC1
);
208 dev_err(&pdev
->dev
, "Can't set up DAS DAP connection\n");
211 ret
= tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1
,
212 TEGRA_DAS_DAC_SEL_DAP1
);
214 dev_err(&pdev
->dev
, "Can't set up DAS DAC connection\n");
218 tegra_das_debug_add(das
);
220 platform_set_drvdata(pdev
, das
);
229 static int __devexit
tegra_das_remove(struct platform_device
*pdev
)
234 tegra_das_debug_remove(das
);
241 static const struct of_device_id tegra_das_of_match
[] __devinitconst
= {
242 { .compatible
= "nvidia,tegra20-das", },
246 static struct platform_driver tegra_das_driver
= {
247 .probe
= tegra_das_probe
,
248 .remove
= __devexit_p(tegra_das_remove
),
251 .owner
= THIS_MODULE
,
252 .of_match_table
= tegra_das_of_match
,
255 module_platform_driver(tegra_das_driver
);
257 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
258 MODULE_DESCRIPTION("Tegra DAS driver");
259 MODULE_LICENSE("GPL");
260 MODULE_ALIAS("platform:" DRV_NAME
);
261 MODULE_DEVICE_TABLE(of
, tegra_das_of_match
);