All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
To: Jacopo Mondi <jacopo@jmondi.org>, linux-renesas-soc@vger.kernel.org
Subject: [RFC PATCH v6 10/13] media: i2c: max9286: Introduce a debugfs layer
Date: Mon, 16 Dec 2019 10:29:27 +0000	[thread overview]
Message-ID: <20191216102930.5867-11-kieran.bingham+renesas@ideasonboard.com> (raw)
In-Reply-To: <20191216102930.5867-1-kieran.bingham+renesas@ideasonboard.com>

The MAX9286 provides several read-only status registers for observing
the system state of the device.

Provide error statistics and link status through debugfs files.
These files will be free-form and should not be considered as part
of any userspace API

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

---

Please consider this a starting point for adding useful debug. I don't
necessarily expect this code to make it to the final driver, but it
could be very useful to process and expose this information internally
in the driver.

Alternatively - we could move this all to max9286_debugfs.c or such.

Watch out for a lot of the error counters which reset to 0 when read.
We should handle those by adding the value to a local store on every
read.

v2:
 - Cleanup debugfs in error path of probe()

v6:
 - Fix a bogus (h << 0) check
---
 drivers/media/i2c/max9286.c | 127 ++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index df77871e603c..6e1dfc518e03 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -10,6 +10,7 @@
  * Copyright (C) 2015 Cogent Embedded, Inc.
  */
 
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/fwnode.h>
@@ -148,6 +149,7 @@ struct max9286_priv {
 	struct v4l2_subdev sd;
 	struct media_pad pads[MAX9286_N_PADS];
 	struct regulator *regulator;
+	struct dentry *dbgroot;
 	bool poc_enabled;
 
 	struct gpio_chip gpio;
@@ -225,6 +227,124 @@ static int max9286_write(struct max9286_priv *priv, u8 reg, u8 val)
 	return ret;
 }
 
+/* -----------------------------------------------------------------------------
+ * DebugFS
+ */
+
+#define DEBUGFS_RO_ATTR(name)						\
+static int name##_open(struct inode *inode, struct file *file)		\
+{									\
+	return single_open(file, name, inode->i_private);		\
+}									\
+static const struct file_operations name##_fops = {			\
+	.owner = THIS_MODULE,						\
+	.open = name##_open,						\
+	.llseek = seq_lseek,						\
+	.read = seq_read,						\
+	.release = single_release,					\
+}
+
+static int max9286_config_video_detect(struct max9286_priv *priv,
+				       struct seq_file *s)
+{
+	int reg_49 = max9286_read(priv, 0x49);
+	unsigned int i;
+
+	if (reg_49 < 0)
+		return reg_49;
+
+	seq_puts(s, "                  :  0   1   2   3\n");
+	seq_puts(s, "Configuration Link:");
+	for (i = 0; i < 4; i++) {
+		int link = (reg_49 & BIT(i + 4));
+
+		seq_printf(s, " %3s", link ? " O " : "xxx");
+	}
+	seq_puts(s, "\n");
+
+	seq_puts(s, "Video Link        :");
+	for (i = 0; i < 4; i++) {
+		int link = (reg_49 & BIT(i));
+
+		seq_printf(s, " %3s", link ? " O " : "xxx");
+	}
+	seq_puts(s, "\n");
+
+	return 0;
+}
+
+static int max9286_vs_period(struct max9286_priv *priv, struct seq_file *s)
+{
+	int l, m, h;
+	unsigned int frame_length;
+
+	l = max9286_read(priv, 0x5b);
+	m = max9286_read(priv, 0x5c);
+	h = max9286_read(priv, 0x5d);
+
+	if (l < 0 || m < 0 || h < 0)
+		return -ENODEV;
+
+	frame_length = (h << 16) + (m << 8) + l;
+
+	seq_printf(s, "Calculated VS Period (pxclk) : %u\n", frame_length);
+
+	return 0;
+}
+
+static int max9286_master_link(struct max9286_priv *priv, struct seq_file *s)
+{
+	int reg_71 = max9286_read(priv, 0x71);
+	unsigned int link = (reg_71 >> 4) & 0x03;
+
+	if (reg_71 < 0)
+		return reg_71;
+
+	seq_printf(s, "Master link selected : %u\n", link);
+
+	return 0;
+}
+
+static int max9286_debugfs_info(struct seq_file *s, void *p)
+{
+	struct max9286_priv *priv = s->private;
+
+	max9286_config_video_detect(priv, s);
+	max9286_vs_period(priv, s);
+	max9286_master_link(priv, s);
+
+	return 0;
+}
+
+DEBUGFS_RO_ATTR(max9286_debugfs_info);
+
+static int max9286_debugfs_init(struct max9286_priv *priv)
+{
+	char name[32];
+
+	snprintf(name, sizeof(name), "max9286-%s",
+		 dev_name(&priv->client->dev));
+
+	priv->dbgroot = debugfs_create_dir(name, NULL);
+	if (!priv->dbgroot)
+		return -ENOMEM;
+
+	/*
+	 * dentry pointers are discarded, and remove_recursive is used to
+	 * cleanup the tree. DEBUGFS_RO_ATTR defines the file operations with
+	 * the _fops extension to the function name.
+	 */
+	debugfs_create_file("info", 0444, priv->dbgroot, priv,
+			    &max9286_debugfs_info_fops);
+
+	return 0;
+}
+
+static void max9286_debugfs_remove(struct max9286_priv *priv)
+{
+	debugfs_remove_recursive(priv->dbgroot);
+}
+
 /* -----------------------------------------------------------------------------
  * I2C Multiplexer
  */
@@ -1094,6 +1214,9 @@ static int max9286_probe(struct i2c_client *client)
 	 */
 	max9286_configure_i2c(priv, false);
 
+	/* Add any userspace support before we return early. */
+	max9286_debugfs_init(priv);
+
 	ret = max9286_init(&client->dev);
 	if (ret < 0)
 		goto err_regulator;
@@ -1104,6 +1227,7 @@ static int max9286_probe(struct i2c_client *client)
 	regulator_put(priv->regulator);
 	max9286_i2c_mux_close(priv);
 	max9286_configure_i2c(priv, false);
+	max9286_debugfs_remove(priv);
 err_free:
 	max9286_cleanup_dt(priv);
 	kfree(priv);
@@ -1115,6 +1239,9 @@ static int max9286_remove(struct i2c_client *client)
 {
 	struct max9286_priv *priv = i2c_get_clientdata(client);
 
+	/* Remove all Debugfs / sysfs entries */
+	max9286_debugfs_remove(priv);
+
 	i2c_mux_del_adapters(priv->mux);
 
 	fwnode_handle_put(priv->sd.fwnode);
-- 
2.20.1


  parent reply	other threads:[~2019-12-16 10:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-11 12:44 [PATCH v6 0/2] MAX9286 GMSL Support Kieran Bingham
2019-12-11 12:44 ` [PATCH v6 1/2] dt-bindings: media: i2c: Add bindings for Maxim Integrated MAX9286 Kieran Bingham
2019-12-18 18:13   ` Rob Herring
2019-12-19 11:46     ` Kieran Bingham
2019-12-11 12:44 ` [PATCH v6 2/2] media: i2c: Add MAX9286 driver Kieran Bingham
2019-12-16 10:29 ` [RFC PATCH v6 00/13] GMSL Renesas Platform Support Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 01/13] media: i2c: max9286: Add GPIO chip controller Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 02/13] dt-bindings: media: i2c: Add bindings for IMI RDACM20 Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 03/13] media: i2c: Add RDACM20 driver Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 04/13] arm64: dts: renesas: eagle: enable VIN Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 05/13] arm64: dts: renesas: eagle: Provide MAX9286 GMSL deserialiser Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 06/13] arm64: dts: renesas: eagle: Provide Eagle FAKRA dynamic overlay Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 07/13] arm64: dts: renesas: salvator-x: Add MAX9286 expansion board Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 08/13] arm64: dts: renesas: eagle: Include Eagle FAKRA overlay Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 09/13] arm64: dts: renesas: r8a7795-es1-salvator-x: Include MAX9286 8 Camera expansion board Kieran Bingham
2019-12-16 10:29   ` Kieran Bingham [this message]
2019-12-16 10:29   ` [RFC PATCH v6 11/13] [DNI:DEBUG] media: i2c: max9286: Add max9286_check_config_link() Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 12/13] media: i2c: max9286: [Workaround] Hard delay while waiting to enable the V3M cameras Kieran Bingham
2019-12-16 10:29   ` [RFC PATCH v6 13/13] media: i2c: max9286: [Workaround] 'device is bound' Kieran Bingham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191216102930.5867-11-kieran.bingham+renesas@ideasonboard.com \
    --to=kieran.bingham+renesas@ideasonboard.com \
    --cc=jacopo@jmondi.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.