162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// // Renesas R-Car debugfs support
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (c) 2021 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
662306a36Sopenharmony_ci//
762306a36Sopenharmony_ci//	> mount -t debugfs none /sys/kernel/debug
862306a36Sopenharmony_ci//	> cd /sys/kernel/debug/asoc/rcar-sound/ec500000.sound/rdai{N}/
962306a36Sopenharmony_ci//	> cat playback/xxx
1062306a36Sopenharmony_ci//	> cat capture/xxx
1162306a36Sopenharmony_ci//
1262306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/debugfs.h>
1562306a36Sopenharmony_ci#include "rsnd.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic int rsnd_debugfs_show(struct seq_file *m, void *v)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	struct rsnd_dai_stream *io = m->private;
2062306a36Sopenharmony_ci	struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
2162306a36Sopenharmony_ci	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
2262306a36Sopenharmony_ci	int i;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	/* adg is out of mods */
2562306a36Sopenharmony_ci	rsnd_adg_clk_dbg_info(priv, m);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	for_each_rsnd_mod(i, mod, io) {
2862306a36Sopenharmony_ci		u32 *status = mod->ops->get_status(mod, io, mod->type);
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci		seq_printf(m, "name: %s\n", rsnd_mod_name(mod));
3162306a36Sopenharmony_ci		seq_printf(m, "status: %08x\n", *status);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci		if (mod->ops->debug_info)
3462306a36Sopenharmony_ci			mod->ops->debug_info(m, io, mod);
3562306a36Sopenharmony_ci	}
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	return 0;
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(rsnd_debugfs);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_civoid rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr,
4262306a36Sopenharmony_ci			   void __iomem *base, int offset, int size)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	int i, j;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	for (i = 0; i < size; i += 0x10) {
4762306a36Sopenharmony_ci		phys_addr_t addr = _addr + offset + i;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci		seq_printf(m, "%pa:", &addr);
5062306a36Sopenharmony_ci		for (j = 0; j < 0x10; j += 0x4)
5162306a36Sopenharmony_ci			seq_printf(m, " %08x", __raw_readl(base + offset + i + j));
5262306a36Sopenharmony_ci		seq_puts(m, "\n");
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_civoid rsnd_debugfs_mod_reg_show(struct seq_file *m, struct rsnd_mod *mod,
5762306a36Sopenharmony_ci			       int reg_id, int offset, int size)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	rsnd_debugfs_reg_show(m,
6262306a36Sopenharmony_ci			      rsnd_gen_get_phy_addr(priv, reg_id),
6362306a36Sopenharmony_ci			      rsnd_gen_get_base_addr(priv, reg_id),
6462306a36Sopenharmony_ci			      offset, size);
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciint rsnd_debugfs_probe(struct snd_soc_component *component)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	struct rsnd_priv *priv = dev_get_drvdata(component->dev);
7062306a36Sopenharmony_ci	struct rsnd_dai *rdai;
7162306a36Sopenharmony_ci	struct dentry *dir;
7262306a36Sopenharmony_ci	char name[64];
7362306a36Sopenharmony_ci	int i;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/* Gen1 is not supported */
7662306a36Sopenharmony_ci	if (rsnd_is_gen1(priv))
7762306a36Sopenharmony_ci		return 0;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	for_each_rsnd_dai(rdai, priv, i) {
8062306a36Sopenharmony_ci		/*
8162306a36Sopenharmony_ci		 * created debugfs will be automatically
8262306a36Sopenharmony_ci		 * removed, nothing to do for _remove.
8362306a36Sopenharmony_ci		 * see
8462306a36Sopenharmony_ci		 *	soc_cleanup_component_debugfs()
8562306a36Sopenharmony_ci		 */
8662306a36Sopenharmony_ci		snprintf(name, sizeof(name), "rdai%d", i);
8762306a36Sopenharmony_ci		dir = debugfs_create_dir(name, component->debugfs_root);
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci		debugfs_create_file("playback", 0444, dir, &rdai->playback, &rsnd_debugfs_fops);
9062306a36Sopenharmony_ci		debugfs_create_file("capture",  0444, dir, &rdai->capture,  &rsnd_debugfs_fops);
9162306a36Sopenharmony_ci	}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	return 0;
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#endif /* CONFIG_DEBUG_FS */
97