mfd: ab8500-gpadc: Add gpadc hw conversion
Add the support of gpacd hw conversion and make the number of
sample configurable.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Mattias WALLIN <mattias.wallin@stericsson.com>
Tested-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 45fe3c5..59ecd8c 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -101,6 +101,11 @@
static struct device_attribute **dev_attr;
static char **event_name;
+static u8 avg_sample = SAMPLE_16;
+static u8 trig_edge = RISING_EDGE;
+static u8 conv_type = ADC_SW;
+static u8 trig_timer;
+
/**
* struct ab8500_reg_range
* @first: the first address of the range
@@ -808,9 +813,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL);
+ bat_ctrl_raw = ab8500_gpadc_read_raw(gpadc, BAT_CTRL,
+ avg_sample, trig_edge, trig_timer, conv_type);
bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- BAT_CTRL, bat_ctrl_raw);
+ BAT_CTRL, bat_ctrl_raw);
return seq_printf(s, "%d,0x%X\n",
bat_ctrl_convert, bat_ctrl_raw);
@@ -836,9 +842,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL);
+ btemp_ball_raw = ab8500_gpadc_read_raw(gpadc, BTEMP_BALL,
+ avg_sample, trig_edge, trig_timer, conv_type);
btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
- btemp_ball_raw);
+ btemp_ball_raw);
return seq_printf(s,
"%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
@@ -865,9 +872,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V);
+ main_charger_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_V,
+ avg_sample, trig_edge, trig_timer, conv_type);
main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- MAIN_CHARGER_V, main_charger_v_raw);
+ MAIN_CHARGER_V, main_charger_v_raw);
return seq_printf(s, "%d,0x%X\n",
main_charger_v_convert, main_charger_v_raw);
@@ -895,9 +903,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1);
+ acc_detect1_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT1,
+ avg_sample, trig_edge, trig_timer, conv_type);
acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1,
- acc_detect1_raw);
+ acc_detect1_raw);
return seq_printf(s, "%d,0x%X\n",
acc_detect1_convert, acc_detect1_raw);
@@ -925,9 +934,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2);
+ acc_detect2_raw = ab8500_gpadc_read_raw(gpadc, ACC_DETECT2,
+ avg_sample, trig_edge, trig_timer, conv_type);
acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- ACC_DETECT2, acc_detect2_raw);
+ ACC_DETECT2, acc_detect2_raw);
return seq_printf(s, "%d,0x%X\n",
acc_detect2_convert, acc_detect2_raw);
@@ -955,9 +965,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1);
+ aux1_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX1,
+ avg_sample, trig_edge, trig_timer, conv_type);
aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1,
- aux1_raw);
+ aux1_raw);
return seq_printf(s, "%d,0x%X\n",
aux1_convert, aux1_raw);
@@ -983,9 +994,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2);
+ aux2_raw = ab8500_gpadc_read_raw(gpadc, ADC_AUX2,
+ avg_sample, trig_edge, trig_timer, conv_type);
aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2,
- aux2_raw);
+ aux2_raw);
return seq_printf(s, "%d,0x%X\n",
aux2_convert, aux2_raw);
@@ -1011,9 +1023,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V);
+ main_bat_v_raw = ab8500_gpadc_read_raw(gpadc, MAIN_BAT_V,
+ avg_sample, trig_edge, trig_timer, conv_type);
main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
- main_bat_v_raw);
+ main_bat_v_raw);
return seq_printf(s, "%d,0x%X\n",
main_bat_v_convert, main_bat_v_raw);
@@ -1040,9 +1053,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V);
+ vbus_v_raw = ab8500_gpadc_read_raw(gpadc, VBUS_V,
+ avg_sample, trig_edge, trig_timer, conv_type);
vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V,
- vbus_v_raw);
+ vbus_v_raw);
return seq_printf(s, "%d,0x%X\n",
vbus_v_convert, vbus_v_raw);
@@ -1068,9 +1082,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C);
+ main_charger_c_raw = ab8500_gpadc_read_raw(gpadc, MAIN_CHARGER_C,
+ avg_sample, trig_edge, trig_timer, conv_type);
main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- MAIN_CHARGER_C, main_charger_c_raw);
+ MAIN_CHARGER_C, main_charger_c_raw);
return seq_printf(s, "%d,0x%X\n",
main_charger_c_convert, main_charger_c_raw);
@@ -1098,9 +1113,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C);
+ usb_charger_c_raw = ab8500_gpadc_read_raw(gpadc, USB_CHARGER_C,
+ avg_sample, trig_edge, trig_timer, conv_type);
usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- USB_CHARGER_C, usb_charger_c_raw);
+ USB_CHARGER_C, usb_charger_c_raw);
return seq_printf(s, "%d,0x%X\n",
usb_charger_c_convert, usb_charger_c_raw);
@@ -1128,9 +1144,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V);
+ bk_bat_v_raw = ab8500_gpadc_read_raw(gpadc, BK_BAT_V,
+ avg_sample, trig_edge, trig_timer, conv_type);
bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
- BK_BAT_V, bk_bat_v_raw);
+ BK_BAT_V, bk_bat_v_raw);
return seq_printf(s, "%d,0x%X\n",
bk_bat_v_convert, bk_bat_v_raw);
@@ -1156,9 +1173,10 @@
struct ab8500_gpadc *gpadc;
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP);
+ die_temp_raw = ab8500_gpadc_read_raw(gpadc, DIE_TEMP,
+ avg_sample, trig_edge, trig_timer, conv_type);
die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP,
- die_temp_raw);
+ die_temp_raw);
return seq_printf(s, "%d,0x%X\n",
die_temp_convert, die_temp_raw);
@@ -1177,6 +1195,208 @@
.owner = THIS_MODULE,
};
+static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "%d\n", avg_sample);
+}
+
+static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_gpadc_avg_sample_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_avg_sample;
+ int err;
+
+ /* 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_avg_sample);
+ if (err)
+ return -EINVAL;
+ if ((user_avg_sample == SAMPLE_1) || (user_avg_sample == SAMPLE_4)
+ || (user_avg_sample == SAMPLE_8)
+ || (user_avg_sample == SAMPLE_16)) {
+ avg_sample = (u8) user_avg_sample;
+ } else {
+ dev_err(dev, "debugfs error input: "
+ "should be egal to 1, 4, 8 or 16\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_gpadc_avg_sample_fops = {
+ .open = ab8500_gpadc_avg_sample_open,
+ .read = seq_read,
+ .write = ab8500_gpadc_avg_sample_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "%d\n", trig_edge);
+}
+
+static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_gpadc_trig_edge_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_gpadc_trig_edge_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_trig_edge;
+ int err;
+
+ /* 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_trig_edge);
+ if (err)
+ return -EINVAL;
+ if ((user_trig_edge == RISING_EDGE)
+ || (user_trig_edge == FALLING_EDGE)) {
+ trig_edge = (u8) user_trig_edge;
+ } else {
+ dev_err(dev, "Wrong input:\n"
+ "Enter 0. Rising edge\n"
+ "Enter 1. Falling edge\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_gpadc_trig_edge_fops = {
+ .open = ab8500_gpadc_trig_edge_open,
+ .read = seq_read,
+ .write = ab8500_gpadc_trig_edge_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "%d\n", trig_timer);
+}
+
+static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_gpadc_trig_timer_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_trig_timer;
+ int err;
+
+ /* 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_trig_timer);
+ if (err)
+ return -EINVAL;
+ if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) {
+ trig_timer = (u8) user_trig_timer;
+ } else {
+ dev_err(dev, "debugfs error input: "
+ "should be beetween 0 to 255\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_gpadc_trig_timer_fops = {
+ .open = ab8500_gpadc_trig_timer_open,
+ .read = seq_read,
+ .write = ab8500_gpadc_trig_timer_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "%d\n", conv_type);
+}
+
+static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_gpadc_conv_type_print,
+ inode->i_private);
+}
+
+static ssize_t ab8500_gpadc_conv_type_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_conv_type;
+ int err;
+
+ /* 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_conv_type);
+ if (err)
+ return -EINVAL;
+ if ((user_conv_type == ADC_SW)
+ || (user_conv_type == ADC_HW)) {
+ conv_type = (u8) user_conv_type;
+ } else {
+ dev_err(dev, "Wrong input:\n"
+ "Enter 0. ADC SW conversion\n"
+ "Enter 1. ADC HW conversion\n");
+ return -EINVAL;
+ }
+ return buf_size;
+}
+
+static const struct file_operations ab8500_gpadc_conv_type_fops = {
+ .open = ab8500_gpadc_conv_type_open,
+ .read = seq_read,
+ .write = ab8500_gpadc_conv_type_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
/*
* return length of an ASCII numerical value, 0 is string is not a
* numerical value.
@@ -1722,6 +1942,26 @@
if (!file)
goto err;
+ file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops);
+ if (!file)
+ goto err;
+
+ file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops);
+ if (!file)
+ goto err;
+
return 0;
err: