aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-04-13 14:14:07 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-13 14:16:53 -0400
commit5939ae74753ceda976732899bef71f99ffea6ea5 (patch)
tree8226f5a9a601ae1fd86a37be1f6f720974e92e53 /sound/soc/tegra
parentc1607416aa59b8bc78445f8ac3de559ed68864a2 (diff)
ASoC: convert Tegra20 SPDIF driver to regmap
Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r--sound/soc/tegra/tegra20_spdif.c173
-rw-r--r--sound/soc/tegra/tegra20_spdif.h3
2 files changed, 92 insertions, 84 deletions
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 9efd71e13a0a..f9b57418bd08 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -21,13 +21,12 @@
21 */ 21 */
22 22
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/debugfs.h>
25#include <linux/device.h> 24#include <linux/device.h>
26#include <linux/io.h> 25#include <linux/io.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/platform_device.h> 27#include <linux/platform_device.h>
29#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
30#include <linux/seq_file.h> 29#include <linux/regmap.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <sound/core.h> 31#include <sound/core.h>
33#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -41,12 +40,14 @@
41static inline void tegra20_spdif_write(struct tegra20_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 regmap_write(spdif->regmap, reg, val);
45} 44}
46 45
47static inline u32 tegra20_spdif_read(struct tegra20_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 u32 val;
49 regmap_read(spdif->regmap, reg, &val);
50 return val;
50} 51}
51 52
52static int tegra20_spdif_runtime_suspend(struct device *dev) 53static int tegra20_spdif_runtime_suspend(struct device *dev)
@@ -72,78 +73,6 @@ static int tegra20_spdif_runtime_resume(struct device *dev)
72 return 0; 73 return 0;
73} 74}
74 75
75#ifdef CONFIG_DEBUG_FS
76static int tegra20_spdif_show(struct seq_file *s, void *unused)
77{
78#define REG(r) { r, #r }
79 static const struct {
80 int offset;
81 const char *name;
82 } regs[] = {
83 REG(TEGRA20_SPDIF_CTRL),
84 REG(TEGRA20_SPDIF_STATUS),
85 REG(TEGRA20_SPDIF_STROBE_CTRL),
86 REG(TEGRA20_SPDIF_DATA_FIFO_CSR),
87 REG(TEGRA20_SPDIF_CH_STA_RX_A),
88 REG(TEGRA20_SPDIF_CH_STA_RX_B),
89 REG(TEGRA20_SPDIF_CH_STA_RX_C),
90 REG(TEGRA20_SPDIF_CH_STA_RX_D),
91 REG(TEGRA20_SPDIF_CH_STA_RX_E),
92 REG(TEGRA20_SPDIF_CH_STA_RX_F),
93 REG(TEGRA20_SPDIF_CH_STA_TX_A),
94 REG(TEGRA20_SPDIF_CH_STA_TX_B),
95 REG(TEGRA20_SPDIF_CH_STA_TX_C),
96 REG(TEGRA20_SPDIF_CH_STA_TX_D),
97 REG(TEGRA20_SPDIF_CH_STA_TX_E),
98 REG(TEGRA20_SPDIF_CH_STA_TX_F),
99 };
100#undef REG
101
102 struct tegra20_spdif *spdif = s->private;
103 int i;
104
105 for (i = 0; i < ARRAY_SIZE(regs); i++) {
106 u32 val = tegra20_spdif_read(spdif, regs[i].offset);
107 seq_printf(s, "%s = %08x\n", regs[i].name, val);
108 }
109
110 return 0;
111}
112
113static int tegra20_spdif_debug_open(struct inode *inode, struct file *file)
114{
115 return single_open(file, tegra20_spdif_show, inode->i_private);
116}
117
118static const struct file_operations tegra20_spdif_debug_fops = {
119 .open = tegra20_spdif_debug_open,
120 .read = seq_read,
121 .llseek = seq_lseek,
122 .release = single_release,
123};
124
125static void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
126{
127 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
128 snd_soc_debugfs_root, spdif,
129 &tegra20_spdif_debug_fops);
130}
131
132static void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
133{
134 if (spdif->debug)
135 debugfs_remove(spdif->debug);
136}
137#else
138static inline void tegra20_spdif_debug_add(struct tegra20_spdif *spdif)
139{
140}
141
142static inline void tegra20_spdif_debug_remove(struct tegra20_spdif *spdif)
143{
144}
145#endif
146
147static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, 76static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params, 77 struct snd_pcm_hw_params *params,
149 struct snd_soc_dai *dai) 78 struct snd_soc_dai *dai)
@@ -261,10 +190,86 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = {
261 .ops = &tegra20_spdif_dai_ops, 190 .ops = &tegra20_spdif_dai_ops,
262}; 191};
263 192
193static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg)
194{
195 switch (reg) {
196 case TEGRA20_SPDIF_CTRL:
197 case TEGRA20_SPDIF_STATUS:
198 case TEGRA20_SPDIF_STROBE_CTRL:
199 case TEGRA20_SPDIF_DATA_FIFO_CSR:
200 case TEGRA20_SPDIF_DATA_OUT:
201 case TEGRA20_SPDIF_DATA_IN:
202 case TEGRA20_SPDIF_CH_STA_RX_A:
203 case TEGRA20_SPDIF_CH_STA_RX_B:
204 case TEGRA20_SPDIF_CH_STA_RX_C:
205 case TEGRA20_SPDIF_CH_STA_RX_D:
206 case TEGRA20_SPDIF_CH_STA_RX_E:
207 case TEGRA20_SPDIF_CH_STA_RX_F:
208 case TEGRA20_SPDIF_CH_STA_TX_A:
209 case TEGRA20_SPDIF_CH_STA_TX_B:
210 case TEGRA20_SPDIF_CH_STA_TX_C:
211 case TEGRA20_SPDIF_CH_STA_TX_D:
212 case TEGRA20_SPDIF_CH_STA_TX_E:
213 case TEGRA20_SPDIF_CH_STA_TX_F:
214 case TEGRA20_SPDIF_USR_STA_RX_A:
215 case TEGRA20_SPDIF_USR_DAT_TX_A:
216 return true;
217 default:
218 return false;
219 };
220}
221
222static bool tegra20_spdif_volatile_reg(struct device *dev, unsigned int reg)
223{
224 switch (reg) {
225 case TEGRA20_SPDIF_STATUS:
226 case TEGRA20_SPDIF_DATA_FIFO_CSR:
227 case TEGRA20_SPDIF_DATA_OUT:
228 case TEGRA20_SPDIF_DATA_IN:
229 case TEGRA20_SPDIF_CH_STA_RX_A:
230 case TEGRA20_SPDIF_CH_STA_RX_B:
231 case TEGRA20_SPDIF_CH_STA_RX_C:
232 case TEGRA20_SPDIF_CH_STA_RX_D:
233 case TEGRA20_SPDIF_CH_STA_RX_E:
234 case TEGRA20_SPDIF_CH_STA_RX_F:
235 case TEGRA20_SPDIF_USR_STA_RX_A:
236 case TEGRA20_SPDIF_USR_DAT_TX_A:
237 return true;
238 default:
239 return false;
240 };
241}
242
243static bool tegra20_spdif_precious_reg(struct device *dev, unsigned int reg)
244{
245 switch (reg) {
246 case TEGRA20_SPDIF_DATA_OUT:
247 case TEGRA20_SPDIF_DATA_IN:
248 case TEGRA20_SPDIF_USR_STA_RX_A:
249 case TEGRA20_SPDIF_USR_DAT_TX_A:
250 return true;
251 default:
252 return false;
253 };
254}
255
256static const struct regmap_config tegra20_spdif_regmap_config = {
257 .reg_bits = 32,
258 .reg_stride = 4,
259 .val_bits = 32,
260 .max_register = TEGRA20_SPDIF_USR_DAT_TX_A,
261 .writeable_reg = tegra20_spdif_wr_rd_reg,
262 .readable_reg = tegra20_spdif_wr_rd_reg,
263 .volatile_reg = tegra20_spdif_volatile_reg,
264 .precious_reg = tegra20_spdif_precious_reg,
265 .cache_type = REGCACHE_RBTREE,
266};
267
264static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) 268static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
265{ 269{
266 struct tegra20_spdif *spdif; 270 struct tegra20_spdif *spdif;
267 struct resource *mem, *memregion, *dmareq; 271 struct resource *mem, *memregion, *dmareq;
272 void __iomem *regs;
268 int ret; 273 int ret;
269 274
270 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif), 275 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
@@ -305,13 +310,21 @@ static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
305 goto err_clk_put; 310 goto err_clk_put;
306 } 311 }
307 312
308 spdif->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 313 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
309 if (!spdif->regs) { 314 if (!regs) {
310 dev_err(&pdev->dev, "ioremap failed\n"); 315 dev_err(&pdev->dev, "ioremap failed\n");
311 ret = -ENOMEM; 316 ret = -ENOMEM;
312 goto err_clk_put; 317 goto err_clk_put;
313 } 318 }
314 319
320 spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
321 &tegra20_spdif_regmap_config);
322 if (IS_ERR(spdif->regmap)) {
323 dev_err(&pdev->dev, "regmap init failed\n");
324 ret = PTR_ERR(spdif->regmap);
325 goto err_clk_put;
326 }
327
315 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; 328 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
316 spdif->playback_dma_data.wrap = 4; 329 spdif->playback_dma_data.wrap = 4;
317 spdif->playback_dma_data.width = 32; 330 spdif->playback_dma_data.width = 32;
@@ -337,8 +350,6 @@ static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
337 goto err_unregister_dai; 350 goto err_unregister_dai;
338 } 351 }
339 352
340 tegra20_spdif_debug_add(spdif);
341
342 return 0; 353 return 0;
343 354
344err_unregister_dai: 355err_unregister_dai:
@@ -365,8 +376,6 @@ static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev)
365 tegra_pcm_platform_unregister(&pdev->dev); 376 tegra_pcm_platform_unregister(&pdev->dev);
366 snd_soc_unregister_dai(&pdev->dev); 377 snd_soc_unregister_dai(&pdev->dev);
367 378
368 tegra20_spdif_debug_remove(spdif);
369
370 clk_put(spdif->clk_spdif_out); 379 clk_put(spdif->clk_spdif_out);
371 380
372 return 0; 381 return 0;
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index 823af4c6bb7c..ed756527efea 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -464,8 +464,7 @@ struct tegra20_spdif {
464 struct clk *clk_spdif_out; 464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct tegra_pcm_dma_params playback_dma_data;
467 void __iomem *regs; 467 struct regmap *regmap;
468 struct dentry *debug;
469 u32 reg_ctrl; 468 u32 reg_ctrl;
470}; 469};
471 470