From: lee.jones@linaro.org (Lee Jones)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 17/24] ab8500-fg-deepdebug: Create Deep Debug interface
Date: Mon, 21 Jan 2013 12:03:53 +0000 [thread overview]
Message-ID: <1358769840-4763-18-git-send-email-lee.jones@linaro.org> (raw)
In-Reply-To: <1358769840-4763-1-git-send-email-lee.jones@linaro.org>
From: Michel JAOUEN <michel.jaouen@stericsson.com>
This patch creates "fg" debugfs directory under existing ab8500
directory to access fuel gauge test services from userspace
(HATS framework).
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Loic Pallardy <loic.pallardy@stericsson.com>
Signed-off-by: Cedric Madianga <cedric.madianga@stericsson.com>
Reviewed-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Reviewed-by: Marcus COOPER <marcus.xm.cooper@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Tested-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Tested-by: Jonas ABERG <jonas.aberg@stericsson.com>
---
drivers/power/ab8500_fg_deepdebug.c | 873 ++++++++++++++++++++++++++++++++++-
1 file changed, 871 insertions(+), 2 deletions(-)
diff --git a/drivers/power/ab8500_fg_deepdebug.c b/drivers/power/ab8500_fg_deepdebug.c
index 8845de6..37c5f12 100644
--- a/drivers/power/ab8500_fg_deepdebug.c
+++ b/drivers/power/ab8500_fg_deepdebug.c
@@ -11,13 +11,28 @@
*/
#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <linux/power_supply.h>
+#include <linux/kobject.h>
#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
+#include <linux/slab.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/delay.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
+#include <linux/mfd/abx500.h>
#include <linux/time.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/ux500_deepdebug.h>
+#include <linux/uaccess.h>
#include "ab8500_fg.h"
@@ -725,8 +740,8 @@ int ab8500_fg_test_get_nconv_accu_nb_sample(struct ab8500_fg *di, u8 *val)
*/
int ab8500_fg_test_read_nconv_accu_sample(struct ab8500_fg *di)
{
- int ret;
- int nb_sample;
+ int ret = 0;
+ u8 nb_sample;
u8 low_data, med_data, high_data;
/* Get nb sample to average */
@@ -807,6 +822,858 @@ int ab8500_fg_test_read_nconv_accu_sample_to_uA(struct ab8500_fg *di, int val)
return val * QLSB_NANO_AMP_HOURS_X10;
}
+/*
+ * DebugFS interface
+ */
+
+#define AB8500_FG_NAME_STRING "fg"
+
+static int ab8500_fg_test_algorithm_en_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ bool status;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ status = ab8500_fg_test_is_algorithm_en(di);
+
+ return seq_printf(s, "%d\n", status);
+}
+
+static int ab8500_fg_test_algorithm_en_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_algorithm_en_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_algorithm_en_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev;
+ struct ab8500_fg *di;
+ unsigned long user_enable;
+ bool enable;
+ int err;
+
+ dev = ((struct seq_file *)(file->private_data))->private;
+ if (!dev)
+ return -ENOMEM;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ err = kstrtoul_from_user(user_buf, count, 0, &user_enable);
+ if (err)
+ return -EINVAL;
+
+ if ((user_enable == 0) || (user_enable == 1)) {
+ enable = (bool) user_enable;
+ err = ab8500_fg_test_algorithm_en(di, enable);
+ if (err)
+ return err;
+ } else {
+ dev_err(di->dev, "Wrong input\n"
+ "Enter 0 => Disable Gas Gauge test mode\n"
+ "Enter 1 => Enable Gas Gauge test mode\n");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static const struct file_operations ab8500_fg_test_algorithm_en_fops = {
+ .open = ab8500_fg_test_algorithm_en_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_algorithm_en_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_en_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ bool status;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ status = ab8500_fg_test_is_en(di);
+
+ return seq_printf(s, "%d\n", status);
+}
+
+static int ab8500_fg_test_en_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_fg_test_en_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_en_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev;
+ struct ab8500_fg *di;
+ unsigned long user_enable;
+ bool enable;
+ int err;
+
+ dev = ((struct seq_file *)(file->private_data))->private;
+ if (!dev)
+ return -ENOMEM;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ err = kstrtoul_from_user(user_buf, count, 0, &user_enable);
+ if (err)
+ return -EINVAL;
+
+ if ((user_enable == 0) || (user_enable == 1)) {
+ enable = (bool) user_enable;
+ err = ab8500_fg_test_en(di, enable);
+ if (err)
+ return err;
+ } else {
+ dev_err(di->dev, "Wrong input\n"
+ "Enter 0 => Disable Gas Gauge\n"
+ "Enter 1 => Enable Gas Gauge\n");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static const struct file_operations ab8500_fg_test_en_fops = {
+ .open = ab8500_fg_test_en_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_en_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_cc_int_n_avg_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_get_cc_int_n_avg(di);
+ if (result < 0)
+ return result;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_cc_int_n_avg_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_cc_int_n_avg_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_cc_int_n_avg_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_cc_int_n_avg;
+ u8 cc_int_n_avg;
+ int err;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_cc_int_n_avg);
+ if (err)
+ return -EINVAL;
+
+ cc_int_n_avg = (u8) user_cc_int_n_avg;
+ err = ab8500_fg_test_set_cc_int_n_avg(di, cc_int_n_avg);
+ if (err)
+ return err;
+
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_cc_int_n_avg_fops = {
+ .open = ab8500_fg_test_cc_int_n_avg_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_cc_int_n_avg_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_int_calib_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_int_calib(di);
+ if (result < 0)
+ return result;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_int_calib_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_fg_test_int_calib_print,
+ inode->i_private);
+}
+
+static const struct file_operations ab8500_fg_test_int_calib_fops = {
+ .open = ab8500_fg_test_int_calib_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_soft_calib_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_soft_calib(di);
+ if (result < 0)
+ return result;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_soft_calib_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_soft_calib_print,
+ inode->i_private);
+}
+
+static const struct file_operations ab8500_fg_test_soft_calib_fops = {
+ .open = ab8500_fg_test_soft_calib_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_soft_offset_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int ret;
+ u8 result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ ret = ab8500_fg_test_get_cc_soft_offset(di, &result);
+ if (ret < 0)
+ return ret;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_soft_offset_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_soft_offset_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_soft_offset_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_val;
+ u8 val;
+ int err;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_val);
+ if (err)
+ return -EINVAL;
+
+ val = (u8) user_val;
+ err = ab8500_fg_test_set_cc_soft_offset(di, val);
+ if (err)
+ return err;
+
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_soft_offset_fops = {
+ .open = ab8500_fg_test_soft_offset_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_soft_offset_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+
+static int ab8500_fg_test_rst_accu_sample_counter_print(struct seq_file *s,
+ void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_get_rst_accu_sample_counter(di);
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_rst_accu_sample_counter_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_rst_accu_sample_counter_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_rst_accu_sample_counter_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev;
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_enable;
+ bool enable;
+ int err;
+
+ dev = ((struct seq_file *)(file->private_data))->private;
+ if (!dev)
+ return -ENOMEM;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_enable);
+ if (err)
+ return -EINVAL;
+ if ((user_enable == 0) || (user_enable == 1)) {
+ enable = (bool) user_enable;
+ err = ab8500_fg_test_set_rst_accu_sample_counter(di, enable);
+ if (err)
+ return err;
+ } else {
+ dev_err(di->dev, "Wrong input\n"
+ "Enter 0. => Disable Reset Acc\n"
+ "Enter 1. => Enable Reset Acc\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_rst_accu_sample_fops = {
+ .open = ab8500_fg_test_rst_accu_sample_counter_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_rst_accu_sample_counter_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_cc_mux_offset_print(struct seq_file *s,
+ void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_get_cc_mux_offset(di);
+ if (result < 0)
+ return result;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_cc_mux_offset_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_cc_mux_offset_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_cc_mux_offset_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev;
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_enable;
+ bool enable;
+ int err;
+
+ dev = ((struct seq_file *)(file->private_data))->private;
+ if (!dev)
+ return -ENOMEM;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_enable);
+ if (err)
+ return -EINVAL;
+ if ((user_enable == 0) || (user_enable == 1)) {
+ enable = (bool) user_enable;
+ err = ab8500_fg_test_set_cc_mux_offset(di, enable);
+ if (err)
+ return err;
+ } else {
+ dev_err(di->dev, "Wrong input\n"
+ "Enter 0. => Manual offset\n"
+ "Enter 1. => Internal offset\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_cc_mux_offset_fops = {
+ .open = ab8500_fg_test_cc_mux_offset_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_cc_mux_offset_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_read_sample_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int result, cc_sample_calibrate, cc_sample_calibrate_uA;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_read_sample(di);
+ if (result < 0)
+ return result;
+
+ cc_sample_calibrate = ab8500_fg_test_sample_calibrate(di, result);
+ if (cc_sample_calibrate < 0)
+ return cc_sample_calibrate;
+
+ cc_sample_calibrate_uA = ab8500_fg_test_sample_calibrate_to_uA(di,
+ cc_sample_calibrate);
+
+ return seq_printf(s, "0x%X,%d,%d\n", result, cc_sample_calibrate,
+ cc_sample_calibrate_uA);
+}
+
+static int ab8500_fg_test_read_sample_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_read_sample_print,
+ inode->i_private);
+}
+
+static const struct file_operations ab8500_fg_test_read_sample_fops = {
+ .open = ab8500_fg_test_read_sample_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_get_nconv_accu_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int ret, nconv_accu_uA;
+ u8 val;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ ret = ab8500_fg_test_get_nconv_accu(di, &val);
+ if (ret < 0)
+ return ret;
+
+ nconv_accu_uA = ab8500_fg_test_get_nconv_accu_to_uA(di, (int)val);
+
+ return seq_printf(s, "%d,%d\n", val, nconv_accu_uA);
+}
+
+static int ab8500_fg_test_get_nconv_accu_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_get_nconv_accu_print,
+ inode->i_private);
+}
+
+static const struct file_operations ab8500_fg_test_get_nconv_accu_fops = {
+ .open = ab8500_fg_test_get_nconv_accu_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_rst_nconv_accu_print(struct seq_file *s,
+ void *p)
+{
+ struct ab8500_fg *di;
+ int result;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_get_rst_nconv_accu(di);
+ if (result < 0)
+ return result;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_rst_nconv_accu_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_rst_nconv_accu_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_rst_nconv_accu_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev;
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_enable;
+ bool enable;
+ int err;
+
+ dev = ((struct seq_file *)(file->private_data))->private;
+ if (!dev)
+ return -ENOMEM;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_enable);
+ if (err)
+ return -EINVAL;
+ if ((user_enable == 0) || (user_enable == 1)) {
+ enable = (bool) user_enable;
+ err = ab8500_fg_test_set_rst_nconv_accu(di, enable);
+ if (err)
+ return err;
+ } else {
+ dev_err(di->dev, "Wrong input\n"
+ "Enter 0. => Disable Reset Acc\n"
+ "Enter 1. => Enable Reset Acc\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_rst_nconv_accu_fops = {
+ .open = ab8500_fg_test_rst_nconv_accu_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_rst_nconv_accu_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_nconv_accu_nb_sample_print(struct seq_file *s,
+ void *p)
+{
+ struct ab8500_fg *di;
+ u8 result;
+ int ret;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ ret = ab8500_fg_test_get_nconv_accu_nb_sample(di, &result);
+ if (ret < 0)
+ return ret;
+
+ return seq_printf(s, "%d\n", result);
+}
+
+static int ab8500_fg_test_nconv_accu_nb_sample_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_nconv_accu_nb_sample_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_fg_test_nconv_accu_nb_sample_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ab8500_fg *di;
+ char buf[32];
+ int buf_size;
+ unsigned long user_nb_sample;
+ u8 nb_sample;
+ int err;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_nb_sample);
+ if (err)
+ return -EINVAL;
+
+ nb_sample = (u8) user_nb_sample;
+ err = ab8500_fg_test_set_nconv_accu_nb_sample(di, nb_sample);
+ if (err)
+ return err;
+
+ return buf_size;
+}
+
+static const struct file_operations ab8500_fg_test_nconv_accu_nb_sample_fops = {
+ .open = ab8500_fg_test_nconv_accu_nb_sample_open,
+ .read = seq_read,
+ .write = ab8500_fg_test_nconv_accu_nb_sample_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_fg_test_nconv_accu_sample_print(struct seq_file *s, void *p)
+{
+ struct ab8500_fg *di;
+ int result, nconv_accu_sample_uA;
+
+ di = ab8500_fg_get();
+ if (!di)
+ return -ENOMEM;
+
+ result = ab8500_fg_test_read_nconv_accu_sample(di);
+ if (result < 0)
+ return result;
+
+ nconv_accu_sample_uA = ab8500_fg_test_read_nconv_accu_sample_to_uA(di,
+ result);
+
+ return seq_printf(s, "0x%X,%d\n", result, nconv_accu_sample_uA);
+}
+
+static int ab8500_fg_test_nconv_accu_sample_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, ab8500_fg_test_nconv_accu_sample_print,
+ inode->i_private);
+}
+
+static const struct file_operations ab8500_fg_test_nconv_accu_sample_fops = {
+ .open = ab8500_fg_test_nconv_accu_sample_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static struct dentry *ab8500_fg_dir;
+
+int ab8500_bm_deepdebug_probe(struct ddbg_service *data,
+ struct dentry *parent)
+{
+ struct dentry *file;
+ struct dentry *dir;
+ int ret = -ENOMEM;
+
+ ab8500_fg_dir = debugfs_create_dir(AB8500_FG_NAME_STRING,
+ parent);
+ if (!ab8500_fg_dir)
+ goto err;
+
+ file = debugfs_create_file("fg_algo_enable", (S_IRUGO | S_IWUGO),
+ ab8500_fg_dir, data, &ab8500_fg_test_algorithm_en_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("fg_enable", (S_IRUGO | S_IWUGO),
+ ab8500_fg_dir, data, &ab8500_fg_test_en_fops);
+ if (!file)
+ goto err;
+
+ dir = debugfs_create_dir("internal_calibration", ab8500_fg_dir);
+ if (!dir)
+ goto err;
+
+ file = debugfs_create_file("cc_int_n_avg", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_cc_int_n_avg_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_int_offset", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_int_calib_fops);
+ if (!file)
+ goto err;
+
+ dir = debugfs_create_dir("software_calibration", ab8500_fg_dir);
+ if (!dir)
+ goto err;
+
+ file = debugfs_create_file("cc_sample_conv", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_soft_calib_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_soft_offset", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_soft_offset_fops);
+ if (!file)
+ goto err;
+
+ dir = debugfs_create_dir("cc_one_sample", ab8500_fg_dir);
+ if (!dir)
+ goto err;
+
+ file = debugfs_create_file("cc_rst_accu_sample", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_rst_accu_sample_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_mux_offset", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_cc_mux_offset_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_one_sample", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_read_sample_fops);
+ if (!file)
+ goto err;
+ file = debugfs_create_file("cc_nconv_accu", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_get_nconv_accu_fops);
+ if (!file)
+ goto err;
+
+ dir = debugfs_create_dir("read_n_samples", ab8500_fg_dir);
+ if (!dir)
+ goto err;
+
+ file = debugfs_create_file("cc_rst_nconv_accu", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_rst_nconv_accu_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_mux_offset", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_cc_mux_offset_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_nb_samples_to_average",
+ (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_nconv_accu_nb_sample_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("cc_retrieve_samples", (S_IRUGO | S_IWUGO),
+ dir, data, &ab8500_fg_test_nconv_accu_sample_fops);
+ if (!file)
+ goto err;
+
+ return 0;
+
+err:
+ if (ab8500_fg_dir)
+ debugfs_remove_recursive(ab8500_fg_dir);
+ pr_err("failed to create debugfs entries.\n");
+
+ return ret;
+}
+
+static struct ddbg_service ab8500_fg_ddbg_services = {
+ .name = AB8500_FG_NAME_STRING,
+ .probe = ab8500_bm_deepdebug_probe,
+};
+
+/*
+ * Initialization
+ */
+
void __devinit ab8500_fg_test_init(struct ab8500_fg *di)
{
/* Initialize objects need for test purpose. */
@@ -819,5 +1686,7 @@ void __devinit ab8500_fg_test_init(struct ab8500_fg *di)
init_completion(&di->test.nconv_accu_complete);
init_completion(&di->test.cc_int_calib_complete);
mutex_init(&di->test.lock);
+
+ deep_debug_service_access_register(&ab8500_fg_ddbg_services);
}
--
1.7.9.5
next prev parent reply other threads:[~2013-01-21 12:03 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-21 12:03 [PATCH 00/24] Power: Next batch of AB8500 Battery Management patches Lee Jones
2013-01-21 12:03 ` [PATCH 01/24] pm2301: Provide u9540 support for the pm2301 charger Lee Jones
2013-01-21 12:03 ` [PATCH 02/24] ab8500-charger: AB workaround for invalid charger Lee Jones
2013-01-21 12:03 ` [PATCH 03/24] ab8500-fg: Adjust for RF bursts voltage drops Lee Jones
2013-01-21 12:03 ` [PATCH 04/24] ab8500-btemp: Adaptation to AB8505 and AB9540 platforms Lee Jones
2013-01-21 12:03 ` [PATCH 05/24] ab8500-charger: Kick watchdog Lee Jones
2013-01-21 12:03 ` [PATCH 06/24] ab8500-chargalg: Update battery health on safety timer exp Lee Jones
2013-01-21 12:03 ` [PATCH 07/24] pm2301: Add deep debug Lee Jones
2013-01-21 12:03 ` [PATCH 08/24] pm2301: Clean-up PM2301 interrupt management Lee Jones
2013-01-21 12:03 ` [PATCH 09/24] pm2301: Remove volt_now & curr_now properties Lee Jones
2013-01-21 12:03 ` [PATCH 10/24] ab8500-chargalg: Only root should have write permission on sysfs file Lee Jones
2013-01-21 19:17 ` Anton Vorontsov
2013-01-21 12:03 ` [PATCH 11/24] pm2301: Update watchdog for pm2xxx support Lee Jones
2013-01-21 12:03 ` [PATCH 12/24] ab8500-fg: Add test interface for u9540 Lee Jones
2013-01-21 12:03 ` [PATCH 13/24] abx500-chargalg: Add new sysfs interface to get current charge status Lee Jones
2013-01-21 12:03 ` [PATCH 14/24] ab8500-charger: Add support for autopower on AB8505 and AB9540 Lee Jones
2013-01-21 12:03 ` [PATCH 15/24] ab8500-fg: Go to INIT_RECOVERY when charger removed Lee Jones
2013-01-21 12:03 ` [PATCH 16/24] ab8500-bm: Flush all work queues before suspending Lee Jones
2013-01-21 19:14 ` Anton Vorontsov
2013-01-22 8:43 ` Lee Jones
2013-01-21 12:03 ` Lee Jones [this message]
2013-01-21 12:03 ` [PATCH 18/24] pm2301: Enable vbat low monitoring Lee Jones
2013-01-21 12:03 ` [PATCH 19/24] pm2301: LPN mode control support Lee Jones
2013-01-21 12:03 ` [PATCH 20/24] ab8500-fg: Use correct battery charge full design Lee Jones
2013-01-21 12:03 ` [PATCH 21/24] ab8500-charger: Do not touch VBUSOVV bits Lee Jones
2013-01-21 12:03 ` [PATCH 22/24] ab8500-bm: Remove individual [charger|btemp|fg|chargalg] pdata structures Lee Jones
2013-01-21 12:03 ` [PATCH 23/24] ab8500-bm: Fix minor niggles experienced during testing Lee Jones
2013-01-21 19:13 ` Anton Vorontsov
2013-01-22 8:44 ` Lee Jones
2013-01-22 9:27 ` Lee Jones
2013-01-23 6:25 ` Anton Vorontsov
2013-01-23 8:16 ` Lee Jones
2013-01-21 12:04 ` [PATCH 24/24] u8500-charger: Delay for USB enumeration Lee Jones
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=1358769840-4763-18-git-send-email-lee.jones@linaro.org \
--to=lee.jones@linaro.org \
--cc=linux-arm-kernel@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).