[PATCH v3 4/5] SFH: Add debugfs support to AMD Sensor Fusion Hub

From: Sandeep Singh
Date: Tue Feb 11 2020 - 21:57:18 EST


From: Sandeep Singh <sandeep.singh@xxxxxxx>

This part would give access to internals of
AMD Sensor Fusion Hub through debugfs. it provide raw values in debugfs

Signed-off-by: Sandeep Singh <sandeep.singh@xxxxxxx>
Signed-off-by: Nehal Shah <Nehal-bakulchandra.Shah@xxxxxxx>
---
drivers/hid/amd-sfh-hid/amdsfh-debugfs.c | 250 +++++++++++++++++++++++++++++++
drivers/hid/amd-sfh-hid/amdsfh-debugfs.h | 14 ++
2 files changed, 264 insertions(+)
create mode 100644 drivers/hid/amd-sfh-hid/amdsfh-debugfs.c
create mode 100644 drivers/hid/amd-sfh-hid/amdsfh-debugfs.h

diff --git a/drivers/hid/amd-sfh-hid/amdsfh-debugfs.c b/drivers/hid/amd-sfh-hid/amdsfh-debugfs.c
new file mode 100644
index 0000000..15aeef8
--- /dev/null
+++ b/drivers/hid/amd-sfh-hid/amdsfh-debugfs.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD SFH Debugfs
+ * This part would access MP2 registers through debugfs
+ * for AMD SFH debugging.
+ * Author: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@xxxxxxx>
+ */
+
+#include <linux/slab.h>
+#include "amd_mp2_pcie.h"
+#include "amdsfh-debugfs.h"
+
+/* DebugFS helpers */
+#define OBUFP (obuf + oboff)
+#define OBUFLEN 512
+#define OBUFSPC (OBUFLEN - oboff)
+#define OSCNPRINTF(fmt, ...) \
+ scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+static ssize_t amdsfh_debugfs_accel_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+ unsigned int oboff = 0, i;
+ struct amdtp_cl_data *cl_data = filp->private_data;
+ bool found = false;
+ ssize_t ret;
+ char *obuf;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_idx[i] == ACCEL_IDX) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return -1;
+
+ obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+ if (!obuf)
+ return -ENOMEM;
+
+ oboff += OSCNPRINTF("Accel_X_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][0]);
+ oboff += OSCNPRINTF("Accel_Y_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][1]);
+ oboff += OSCNPRINTF("Accel_Z_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][2]);
+ ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+
+ kfree(obuf);
+
+ return ret;
+}
+
+static ssize_t amdsfh_debugfs_gyro_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+ unsigned int oboff = 0, i;
+ bool found = false;
+ struct amdtp_cl_data *cl_data = filp->private_data;
+ ssize_t ret;
+ char *obuf;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_idx[i] == GYRO_IDX) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return -1;
+
+ obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+ if (!obuf)
+ return -ENOMEM;
+
+ oboff += OSCNPRINTF("Gyro_X_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][0]);
+ oboff += OSCNPRINTF("Gyro_Y_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][1]);
+ oboff += OSCNPRINTF("Gyro_Z_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][2]);
+ ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+
+ kfree(obuf);
+
+ return ret;
+}
+
+static ssize_t amdsfh_debugfs_mag_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+ unsigned int oboff = 0, i;
+ bool found = false;
+ ssize_t ret;
+ char *obuf;
+ struct amdtp_cl_data *cl_data = filp->private_data;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_idx[i] == MAG_IDX) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return -1;
+
+ obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+ if (!obuf)
+ return -ENOMEM;
+
+ oboff += OSCNPRINTF("Mag_X_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][0]);
+ oboff += OSCNPRINTF("Mag_Y_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][1]);
+ oboff += OSCNPRINTF("Mag_Z_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][2]);
+ ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+
+ kfree(obuf);
+
+ return ret;
+}
+
+static ssize_t amdsfh_debugfs_als_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+ unsigned int oboff = 0, i;
+ bool found = false;
+ ssize_t ret;
+ char *obuf;
+ struct amdtp_cl_data *cl_data = filp->private_data;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_idx[i] == AMBIENT_LIGHT_IDX) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return -1;
+
+ obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+ if (!obuf)
+ return -ENOMEM;
+
+ oboff += OSCNPRINTF("Gyro_X_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][0]);
+ oboff += OSCNPRINTF("Gyro_Y_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][1]);
+ oboff += OSCNPRINTF("Gyro_Z_Raw:%d\n",
+ (int)cl_data->sensor_virt_addr[i][2]);
+ ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+
+ kfree(obuf);
+
+ return ret;
+}
+
+static const struct file_operations amdsfh_debugfs_accel_ops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = amdsfh_debugfs_accel_read,
+};
+
+static const struct file_operations amdsfh_debugfs_gyro_ops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = amdsfh_debugfs_gyro_read,
+};
+
+static const struct file_operations amdsfh_debugfs_mag_ops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = amdsfh_debugfs_mag_read,
+};
+
+static const struct file_operations amdsfh_debugfs_als_ops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = amdsfh_debugfs_als_read,
+};
+
+int amdsfh_debugfs_setup(struct amdtp_cl_data *cl_data)
+{
+ /* DebugFS info */
+ struct dentry *dbgfs;
+ int i;
+
+ if (!debugfs_initialized())
+ return -1;
+
+ if (!cl_data->amd_debugfs_dir)
+ cl_data->amd_debugfs_dir = debugfs_create_dir
+ (KBUILD_MODNAME, NULL);
+
+ if (!cl_data->amd_debugfs_dir)
+ return -1;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ switch (cl_data->sensor_idx[i]) {
+ case ACCEL_IDX:
+ dbgfs = debugfs_create_dir("accel",
+ cl_data->amd_debugfs_dir);
+ debugfs_create_file("raw_value", 0400,
+ dbgfs, cl_data,
+ &amdsfh_debugfs_accel_ops);
+ break;
+
+ case GYRO_IDX:
+ dbgfs = debugfs_create_dir("gyro",
+ cl_data->amd_debugfs_dir);
+ debugfs_create_file("raw_value", 0400,
+ dbgfs, cl_data,
+ &amdsfh_debugfs_gyro_ops);
+ break;
+
+ case MAG_IDX:
+ dbgfs = debugfs_create_dir("magnetometer",
+ cl_data->amd_debugfs_dir);
+ debugfs_create_file("raw_value", 0400,
+ dbgfs, cl_data,
+ &amdsfh_debugfs_mag_ops);
+ break;
+
+ case AMBIENT_LIGHT_IDX:
+ dbgfs = debugfs_create_dir("als",
+ cl_data->amd_debugfs_dir);
+ debugfs_create_file("raw_value", 0400,
+ dbgfs, cl_data,
+ &amdsfh_debugfs_als_ops);
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(amdsfh_debugfs_setup);
+
+void amdsfh_debugfs_destroy(struct amdtp_cl_data *cl_data)
+{
+ debugfs_remove_recursive(cl_data->amd_debugfs_dir);
+}
+EXPORT_SYMBOL(amdsfh_debugfs_destroy);
diff --git a/drivers/hid/amd-sfh-hid/amdsfh-debugfs.h b/drivers/hid/amd-sfh-hid/amdsfh-debugfs.h
new file mode 100644
index 0000000..470f1f12
--- /dev/null
+++ b/drivers/hid/amd-sfh-hid/amdsfh-debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * AMD SFH DebugFS
+ * Author: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@xxxxxxx>
+ */
+#include "amdsfh-hid.h"
+
+#ifndef AMDSFH_DEBUGFS_H
+#define AMDSFH_DEBUGFS_H
+
+int amdsfh_debugfs_setup(struct amdtp_cl_data *cl_data);
+void amdsfh_debugfs_destroy(struct amdtp_cl_data *cl_data);
+
+#endif
--
2.7.4