Commit 4ef027d5 authored by Paulo Miguel Almeida's avatar Paulo Miguel Almeida Committed by Greg Kroah-Hartman
Browse files

staging: pi433: add debugfs interface



This adds debugfs interface that can be used for debugging possible
hardware/software issues.

It currently exposes the following debugfs entries for each SPI device
probed:

  /sys/kernel/debug/pi433/<DEVICE>/regs
  ...

The 'regs' file contains all rf69 uC registers values that are useful
for troubleshooting misconfigurations between 2 devices. It contains one
register per line so it should be easy to use normal filtering tools to
find the registers of interest if needed.

Reviewed-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarPaulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
Link: https://lore.kernel.org/r/YfzeEHJcd+qvYGZ8@mail.google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 04952a99
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
#endif
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include "pi433_if.h"
#include "rf69.h"
@@ -1098,12 +1100,76 @@ static const struct file_operations pi433_fops = {
	.llseek =	no_llseek,
};

static int pi433_debugfs_regs_show(struct seq_file *m, void *p)
{
	struct pi433_device *dev;
	u8 reg_data[114];
	int i;
	char *fmt = "0x%02x, 0x%02x\n";
	int ret;

	dev = m->private;

	mutex_lock(&dev->tx_fifo_lock);
	mutex_lock(&dev->rx_lock);

	// wait for on-going operations to finish
	ret = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active);
	if (ret)
		goto out_unlock;

	ret = wait_event_interruptible(dev->tx_wait_queue, !dev->rx_active);
	if (ret)
		goto out_unlock;

	// skip FIFO register (0x0) otherwise this can affect some of uC ops
	for (i = 1; i < 0x50; i++)
		reg_data[i] = rf69_read_reg(dev->spi, i);

	reg_data[REG_TESTLNA] = rf69_read_reg(dev->spi, REG_TESTLNA);
	reg_data[REG_TESTPA1] = rf69_read_reg(dev->spi, REG_TESTPA1);
	reg_data[REG_TESTPA2] = rf69_read_reg(dev->spi, REG_TESTPA2);
	reg_data[REG_TESTDAGC] = rf69_read_reg(dev->spi, REG_TESTDAGC);
	reg_data[REG_TESTAFC] = rf69_read_reg(dev->spi, REG_TESTAFC);

	seq_puts(m, "# reg, val\n");

	for (i = 1; i < 0x50; i++)
		seq_printf(m, fmt, i, reg_data[i]);

	seq_printf(m, fmt, REG_TESTLNA, reg_data[REG_TESTLNA]);
	seq_printf(m, fmt, REG_TESTPA1, reg_data[REG_TESTPA1]);
	seq_printf(m, fmt, REG_TESTPA2, reg_data[REG_TESTPA2]);
	seq_printf(m, fmt, REG_TESTDAGC, reg_data[REG_TESTDAGC]);
	seq_printf(m, fmt, REG_TESTAFC, reg_data[REG_TESTAFC]);

out_unlock:
	mutex_unlock(&dev->rx_lock);
	mutex_unlock(&dev->tx_fifo_lock);

	return ret;
}

static int pi433_debugfs_regs_open(struct inode *inode, struct file *filp)
{
	return single_open(filp, pi433_debugfs_regs_show, inode->i_private);
}

static const struct file_operations debugfs_fops = {
	.llseek =	seq_lseek,
	.open =		pi433_debugfs_regs_open,
	.owner =	THIS_MODULE,
	.read =		seq_read,
	.release =	single_release
};

/*-------------------------------------------------------------------------*/

static int pi433_probe(struct spi_device *spi)
{
	struct pi433_device	*device;
	int			retval;
	struct dentry		*entry;

	/* setup spi parameters */
	spi->mode = 0x00;
@@ -1252,6 +1318,10 @@ static int pi433_probe(struct spi_device *spi)
	/* spi setup */
	spi_set_drvdata(spi, device);

	entry = debugfs_create_dir(dev_name(device->dev),
				   debugfs_lookup(KBUILD_MODNAME, NULL));
	debugfs_create_file("regs", 0400, entry, device, &debugfs_fops);

	return 0;

del_cdev:
@@ -1275,6 +1345,9 @@ static int pi433_probe(struct spi_device *spi)
static int pi433_remove(struct spi_device *spi)
{
	struct pi433_device	*device = spi_get_drvdata(spi);
	struct dentry *mod_entry = debugfs_lookup(KBUILD_MODNAME, NULL);

	debugfs_remove(debugfs_lookup(dev_name(device->dev), mod_entry));

	/* free GPIOs */
	free_gpio(device);
@@ -1349,6 +1422,8 @@ static int __init pi433_init(void)
		return PTR_ERR(pi433_class);
	}

	debugfs_create_dir(KBUILD_MODNAME, NULL);

	status = spi_register_driver(&pi433_spi_driver);
	if (status < 0) {
		class_destroy(pi433_class);
@@ -1366,6 +1441,7 @@ static void __exit pi433_exit(void)
	spi_unregister_driver(&pi433_spi_driver);
	class_destroy(pi433_class);
	unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
	debugfs_remove_recursive(debugfs_lookup(KBUILD_MODNAME, NULL));
}
module_exit(pi433_exit);

+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

/*-------------------------------------------------------------------------*/

static u8 rf69_read_reg(struct spi_device *spi, u8 addr)
u8 rf69_read_reg(struct spi_device *spi, u8 addr)
{
	int retval;

+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define FIFO_SIZE	66		/* bytes */
#define FIFO_THRESHOLD	15		/* bytes */

u8 rf69_read_reg(struct spi_device *spi, u8 addr);
int rf69_get_version(struct spi_device *spi);
int rf69_set_mode(struct spi_device *spi, enum mode mode);
int rf69_set_data_mode(struct spi_device *spi, u8 data_mode);