1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // // Renesas R-Car debugfs support
4 //
5 // Copyright (c) 2021 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 //
7 //	> mount -t debugfs none /sys/kernel/debug
8 //	> cd /sys/kernel/debug/asoc/rcar-sound/ec500000.sound/rdai{N}/
9 //	> cat playback/xxx
10 //	> cat capture/xxx
11 //
12 #ifdef CONFIG_DEBUG_FS
13 
14 #include <linux/debugfs.h>
15 #include "rsnd.h"
16 
rsnd_debugfs_show(struct seq_file * m,void * v)17 static int rsnd_debugfs_show(struct seq_file *m, void *v)
18 {
19 	struct rsnd_dai_stream *io = m->private;
20 	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
21 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
22 	int i;
23 
24 	/* adg is out of mods */
25 	rsnd_adg_clk_dbg_info(priv, m);
26 
27 	for_each_rsnd_mod(i, mod, io) {
28 		u32 *status = mod->ops->get_status(mod, io, mod->type);
29 
30 		seq_printf(m, "name: %s\n", rsnd_mod_name(mod));
31 		seq_printf(m, "status: %08x\n", *status);
32 
33 		if (mod->ops->debug_info)
34 			mod->ops->debug_info(m, io, mod);
35 	}
36 
37 	return 0;
38 }
39 DEFINE_SHOW_ATTRIBUTE(rsnd_debugfs);
40 
rsnd_debugfs_reg_show(struct seq_file * m,phys_addr_t _addr,void __iomem * base,int offset,int size)41 void rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr,
42 			   void __iomem *base, int offset, int size)
43 {
44 	int i, j;
45 
46 	for (i = 0; i < size; i += 0x10) {
47 		phys_addr_t addr = _addr + offset + i;
48 
49 		seq_printf(m, "%pa:", &addr);
50 		for (j = 0; j < 0x10; j += 0x4)
51 			seq_printf(m, " %08x", __raw_readl(base + offset + i + j));
52 		seq_puts(m, "\n");
53 	}
54 }
55 
rsnd_debugfs_mod_reg_show(struct seq_file * m,struct rsnd_mod * mod,int reg_id,int offset,int size)56 void rsnd_debugfs_mod_reg_show(struct seq_file *m, struct rsnd_mod *mod,
57 			       int reg_id, int offset, int size)
58 {
59 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
60 
61 	rsnd_debugfs_reg_show(m,
62 			      rsnd_gen_get_phy_addr(priv, reg_id),
63 			      rsnd_gen_get_base_addr(priv, reg_id),
64 			      offset, size);
65 }
66 
rsnd_debugfs_probe(struct snd_soc_component * component)67 int rsnd_debugfs_probe(struct snd_soc_component *component)
68 {
69 	struct rsnd_priv *priv = dev_get_drvdata(component->dev);
70 	struct rsnd_dai *rdai;
71 	struct dentry *dir;
72 	char name[64];
73 	int i;
74 
75 	/* Gen1 is not supported */
76 	if (rsnd_is_gen1(priv))
77 		return 0;
78 
79 	for_each_rsnd_dai(rdai, priv, i) {
80 		/*
81 		 * created debugfs will be automatically
82 		 * removed, nothing to do for _remove.
83 		 * see
84 		 *	soc_cleanup_component_debugfs()
85 		 */
86 		snprintf(name, sizeof(name), "rdai%d", i);
87 		dir = debugfs_create_dir(name, component->debugfs_root);
88 
89 		debugfs_create_file("playback", 0444, dir, &rdai->playback, &rsnd_debugfs_fops);
90 		debugfs_create_file("capture",  0444, dir, &rdai->capture,  &rsnd_debugfs_fops);
91 	}
92 
93 	return 0;
94 }
95 
96 #endif /* CONFIG_DEBUG_FS */
97