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