diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-04-13 14:14:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-13 14:16:53 -0400 |
commit | c1607416aa59b8bc78445f8ac3de559ed68864a2 (patch) | |
tree | a72b1be9bb3b61501399831b3a54c650e8097aa3 /sound/soc/tegra | |
parent | d19e779b8454781afdfdb17357d5961f76961b03 (diff) |
ASoC: convert Tegra20 I2S 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_i2s.c | 145 | ||||
-rw-r--r-- | sound/soc/tegra/tegra20_i2s.h | 3 |
2 files changed, 72 insertions, 76 deletions
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index b598ebdefdee..0c7af63d444b 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -29,14 +29,13 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/debugfs.h> | ||
33 | #include <linux/device.h> | 32 | #include <linux/device.h> |
34 | #include <linux/io.h> | 33 | #include <linux/io.h> |
35 | #include <linux/module.h> | 34 | #include <linux/module.h> |
36 | #include <linux/of.h> | 35 | #include <linux/of.h> |
37 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
38 | #include <linux/pm_runtime.h> | 37 | #include <linux/pm_runtime.h> |
39 | #include <linux/seq_file.h> | 38 | #include <linux/regmap.h> |
40 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
41 | #include <sound/core.h> | 40 | #include <sound/core.h> |
42 | #include <sound/pcm.h> | 41 | #include <sound/pcm.h> |
@@ -49,12 +48,14 @@ | |||
49 | 48 | ||
50 | static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) | 49 | static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) |
51 | { | 50 | { |
52 | __raw_writel(val, i2s->regs + reg); | 51 | regmap_write(i2s->regmap, reg, val); |
53 | } | 52 | } |
54 | 53 | ||
55 | static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) | 54 | static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) |
56 | { | 55 | { |
57 | return __raw_readl(i2s->regs + reg); | 56 | u32 val; |
57 | regmap_read(i2s->regmap, reg, &val); | ||
58 | return val; | ||
58 | } | 59 | } |
59 | 60 | ||
60 | static int tegra20_i2s_runtime_suspend(struct device *dev) | 61 | static int tegra20_i2s_runtime_suspend(struct device *dev) |
@@ -80,70 +81,6 @@ static int tegra20_i2s_runtime_resume(struct device *dev) | |||
80 | return 0; | 81 | return 0; |
81 | } | 82 | } |
82 | 83 | ||
83 | #ifdef CONFIG_DEBUG_FS | ||
84 | static int tegra20_i2s_show(struct seq_file *s, void *unused) | ||
85 | { | ||
86 | #define REG(r) { r, #r } | ||
87 | static const struct { | ||
88 | int offset; | ||
89 | const char *name; | ||
90 | } regs[] = { | ||
91 | REG(TEGRA20_I2S_CTRL), | ||
92 | REG(TEGRA20_I2S_STATUS), | ||
93 | REG(TEGRA20_I2S_TIMING), | ||
94 | REG(TEGRA20_I2S_FIFO_SCR), | ||
95 | REG(TEGRA20_I2S_PCM_CTRL), | ||
96 | REG(TEGRA20_I2S_NW_CTRL), | ||
97 | REG(TEGRA20_I2S_TDM_CTRL), | ||
98 | REG(TEGRA20_I2S_TDM_TX_RX_CTRL), | ||
99 | }; | ||
100 | #undef REG | ||
101 | |||
102 | struct tegra20_i2s *i2s = s->private; | ||
103 | int i; | ||
104 | |||
105 | for (i = 0; i < ARRAY_SIZE(regs); i++) { | ||
106 | u32 val = tegra20_i2s_read(i2s, regs[i].offset); | ||
107 | seq_printf(s, "%s = %08x\n", regs[i].name, val); | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int tegra20_i2s_debug_open(struct inode *inode, struct file *file) | ||
114 | { | ||
115 | return single_open(file, tegra20_i2s_show, inode->i_private); | ||
116 | } | ||
117 | |||
118 | static const struct file_operations tegra20_i2s_debug_fops = { | ||
119 | .open = tegra20_i2s_debug_open, | ||
120 | .read = seq_read, | ||
121 | .llseek = seq_lseek, | ||
122 | .release = single_release, | ||
123 | }; | ||
124 | |||
125 | static void tegra20_i2s_debug_add(struct tegra20_i2s *i2s) | ||
126 | { | ||
127 | i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO, | ||
128 | snd_soc_debugfs_root, i2s, | ||
129 | &tegra20_i2s_debug_fops); | ||
130 | } | ||
131 | |||
132 | static void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s) | ||
133 | { | ||
134 | if (i2s->debug) | ||
135 | debugfs_remove(i2s->debug); | ||
136 | } | ||
137 | #else | ||
138 | static inline void tegra20_i2s_debug_add(struct tegra20_i2s *i2s, int id) | ||
139 | { | ||
140 | } | ||
141 | |||
142 | static inline void tegra20_i2s_debug_remove(struct tegra20_i2s *i2s) | ||
143 | { | ||
144 | } | ||
145 | #endif | ||
146 | |||
147 | static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | 84 | static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, |
148 | unsigned int fmt) | 85 | unsigned int fmt) |
149 | { | 86 | { |
@@ -339,12 +276,68 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { | |||
339 | .symmetric_rates = 1, | 276 | .symmetric_rates = 1, |
340 | }; | 277 | }; |
341 | 278 | ||
279 | static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) | ||
280 | { | ||
281 | switch (reg) { | ||
282 | case TEGRA20_I2S_CTRL: | ||
283 | case TEGRA20_I2S_STATUS: | ||
284 | case TEGRA20_I2S_TIMING: | ||
285 | case TEGRA20_I2S_FIFO_SCR: | ||
286 | case TEGRA20_I2S_PCM_CTRL: | ||
287 | case TEGRA20_I2S_NW_CTRL: | ||
288 | case TEGRA20_I2S_TDM_CTRL: | ||
289 | case TEGRA20_I2S_TDM_TX_RX_CTRL: | ||
290 | case TEGRA20_I2S_FIFO1: | ||
291 | case TEGRA20_I2S_FIFO2: | ||
292 | return true; | ||
293 | default: | ||
294 | return false; | ||
295 | }; | ||
296 | } | ||
297 | |||
298 | static bool tegra20_i2s_volatile_reg(struct device *dev, unsigned int reg) | ||
299 | { | ||
300 | switch (reg) { | ||
301 | case TEGRA20_I2S_STATUS: | ||
302 | case TEGRA20_I2S_FIFO_SCR: | ||
303 | case TEGRA20_I2S_FIFO1: | ||
304 | case TEGRA20_I2S_FIFO2: | ||
305 | return true; | ||
306 | default: | ||
307 | return false; | ||
308 | }; | ||
309 | } | ||
310 | |||
311 | static bool tegra20_i2s_precious_reg(struct device *dev, unsigned int reg) | ||
312 | { | ||
313 | switch (reg) { | ||
314 | case TEGRA20_I2S_FIFO1: | ||
315 | case TEGRA20_I2S_FIFO2: | ||
316 | return true; | ||
317 | default: | ||
318 | return false; | ||
319 | }; | ||
320 | } | ||
321 | |||
322 | static const struct regmap_config tegra20_i2s_regmap_config = { | ||
323 | .reg_bits = 32, | ||
324 | .reg_stride = 4, | ||
325 | .val_bits = 32, | ||
326 | .max_register = TEGRA20_I2S_FIFO2, | ||
327 | .writeable_reg = tegra20_i2s_wr_rd_reg, | ||
328 | .readable_reg = tegra20_i2s_wr_rd_reg, | ||
329 | .volatile_reg = tegra20_i2s_volatile_reg, | ||
330 | .precious_reg = tegra20_i2s_precious_reg, | ||
331 | .cache_type = REGCACHE_RBTREE, | ||
332 | }; | ||
333 | |||
342 | static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) | 334 | static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) |
343 | { | 335 | { |
344 | struct tegra20_i2s *i2s; | 336 | struct tegra20_i2s *i2s; |
345 | struct resource *mem, *memregion, *dmareq; | 337 | struct resource *mem, *memregion, *dmareq; |
346 | u32 of_dma[2]; | 338 | u32 of_dma[2]; |
347 | u32 dma_ch; | 339 | u32 dma_ch; |
340 | void __iomem *regs; | ||
348 | int ret; | 341 | int ret; |
349 | 342 | ||
350 | i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL); | 343 | i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL); |
@@ -394,13 +387,21 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
394 | goto err_clk_put; | 387 | goto err_clk_put; |
395 | } | 388 | } |
396 | 389 | ||
397 | i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 390 | regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
398 | if (!i2s->regs) { | 391 | if (!regs) { |
399 | dev_err(&pdev->dev, "ioremap failed\n"); | 392 | dev_err(&pdev->dev, "ioremap failed\n"); |
400 | ret = -ENOMEM; | 393 | ret = -ENOMEM; |
401 | goto err_clk_put; | 394 | goto err_clk_put; |
402 | } | 395 | } |
403 | 396 | ||
397 | i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, | ||
398 | &tegra20_i2s_regmap_config); | ||
399 | if (IS_ERR(i2s->regmap)) { | ||
400 | dev_err(&pdev->dev, "regmap init failed\n"); | ||
401 | ret = PTR_ERR(i2s->regmap); | ||
402 | goto err_clk_put; | ||
403 | } | ||
404 | |||
404 | i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; | 405 | i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; |
405 | i2s->capture_dma_data.wrap = 4; | 406 | i2s->capture_dma_data.wrap = 4; |
406 | i2s->capture_dma_data.width = 32; | 407 | i2s->capture_dma_data.width = 32; |
@@ -433,8 +434,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
433 | goto err_unregister_dai; | 434 | goto err_unregister_dai; |
434 | } | 435 | } |
435 | 436 | ||
436 | tegra20_i2s_debug_add(i2s); | ||
437 | |||
438 | return 0; | 437 | return 0; |
439 | 438 | ||
440 | err_unregister_dai: | 439 | err_unregister_dai: |
@@ -461,8 +460,6 @@ static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev) | |||
461 | tegra_pcm_platform_unregister(&pdev->dev); | 460 | tegra_pcm_platform_unregister(&pdev->dev); |
462 | snd_soc_unregister_dai(&pdev->dev); | 461 | snd_soc_unregister_dai(&pdev->dev); |
463 | 462 | ||
464 | tegra20_i2s_debug_remove(i2s); | ||
465 | |||
466 | clk_put(i2s->clk_i2s); | 463 | clk_put(i2s->clk_i2s); |
467 | 464 | ||
468 | return 0; | 465 | return 0; |
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index 86ab327dbd26..a57efc6a597e 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h | |||
@@ -157,8 +157,7 @@ struct tegra20_i2s { | |||
157 | struct clk *clk_i2s; | 157 | struct clk *clk_i2s; |
158 | struct tegra_pcm_dma_params capture_dma_data; | 158 | struct tegra_pcm_dma_params capture_dma_data; |
159 | struct tegra_pcm_dma_params playback_dma_data; | 159 | struct tegra_pcm_dma_params playback_dma_data; |
160 | void __iomem *regs; | 160 | struct regmap *regmap; |
161 | struct dentry *debug; | ||
162 | u32 reg_ctrl; | 161 | u32 reg_ctrl; |
163 | }; | 162 | }; |
164 | 163 | ||