Keep the threshold and duration in mg/ms until write

From: Simon Kagstrom <[EMAIL PROTECTED]>

Keep the duration and threshold in human-readable values until written
to the device. This avoids precision loss when changing scale and rate.
Also fix sscanf for these.

Signed-off-by: Simon Kagstrom <[EMAIL PROTECTED]>
---

 drivers/input/misc/lis302dl.c |   51 +++++++++++++++++++++--------------------
 include/linux/lis302dl.h      |    4 ++-
 2 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
index 7b60e59..fa3dc15 100644
--- a/drivers/input/misc/lis302dl.c
+++ b/drivers/input/misc/lis302dl.c
@@ -140,9 +140,9 @@ static void __enable_wakeup(struct lis302dl_info *lis)
        __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1,
                        lis->wakeup.cfg);
        __reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
-                       lis->wakeup.threshold);
+                       __mg_to_threshold(lis, lis->wakeup.threshold));
        __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
-                       lis->wakeup.duration);
+                       __ms_to_duration(lis, lis->wakeup.duration));
 
        /* Route the interrupt for wakeup */
        __lis302dl_int_mode(lis->dev, 1,
@@ -168,8 +168,10 @@ static void __enable_data_collection(struct lis302dl_info 
*lis)
        } else {
                __reg_write(lis, LIS302DL_REG_CTRL2,
                                LIS302DL_CTRL2_HPFF1);
-               __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, lis->threshold);
-               __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
+               __reg_write(lis, LIS302DL_REG_FF_WU_THS_1,
+                               __mg_to_threshold(lis, lis->threshold));
+               __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
+                               __ms_to_duration(lis, lis->duration));
 
                /* Clear the HP filter "starting point" */
                __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
@@ -255,7 +257,6 @@ static ssize_t set_rate(struct device *dev, struct 
device_attribute *attr,
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
        unsigned long flags;
-       int duration_ms = __duration_to_ms(lis, lis->duration);
 
        local_irq_save(flags);
 
@@ -268,7 +269,6 @@ static ssize_t set_rate(struct device *dev, struct 
device_attribute *attr,
                                0);
                lis->flags &= ~LIS302DL_F_DR;
        }
-       lis->duration = __ms_to_duration(lis, duration_ms);
        local_irq_restore(flags);
 
        return count;
@@ -295,7 +295,6 @@ static ssize_t set_scale(struct device *dev, struct 
device_attribute *attr,
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
        unsigned long flags;
-       int threshold_mg = __threshold_to_mg(lis, lis->threshold);
 
        local_irq_save(flags);
 
@@ -309,8 +308,6 @@ static ssize_t set_scale(struct device *dev, struct 
device_attribute *attr,
                lis->flags &= ~LIS302DL_F_FS;
        }
 
-       /* Adjust the threshold */
-       lis->threshold = __mg_to_threshold(lis, threshold_mg);
        if (lis->flags & LIS302DL_F_INPUT_OPEN)
                __enable_data_collection(lis);
 
@@ -326,23 +323,25 @@ static ssize_t show_threshold(struct device *dev, struct 
device_attribute *attr,
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
 
-       return sprintf(buf, "%d\n", __threshold_to_mg(lis, lis->threshold));
+       /* Display the device view of the threshold setting */
+       return sprintf(buf, "%d\n", __threshold_to_mg(lis,
+                       __mg_to_threshold(lis, lis->threshold)));
 }
 
 static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
                 const char *buf, size_t count)
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
-       u32 val;
+       unsigned int val;
 
-       if (sscanf(buf, "%d\n", &val) != 1)
+       if (sscanf(buf, "%u\n", &val) != 1)
                return -EINVAL;
        /* 8g is the maximum if FS is 1 */
-       if (val < 0 || val > 8000)
+       if (val > 8000)
                return -ERANGE;
 
        /* Set the threshold and write it out if the device is used */
-       lis->threshold = __mg_to_threshold(lis, val);
+       lis->threshold = val;
 
        if (lis->flags & LIS302DL_F_INPUT_OPEN) {
                unsigned long flags;
@@ -362,23 +361,25 @@ static ssize_t show_duration(struct device *dev, struct 
device_attribute *attr,
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
 
-       return sprintf(buf, "%d\n", __duration_to_ms(lis, lis->duration));
+       return sprintf(buf, "%d\n", __duration_to_ms(lis,
+                       __ms_to_duration(lis, lis->duration)));
 }
 
 static ssize_t set_duration(struct device *dev, struct device_attribute *attr,
                 const char *buf, size_t count)
 {
        struct lis302dl_info *lis = dev_get_drvdata(dev);
-       u32 val;
+       unsigned int val;
 
-       if (sscanf(buf, "%d\n", &val) != 1)
+       if (sscanf(buf, "%u\n", &val) != 1)
                return -EINVAL;
-       if (val < 0 || val > 2550)
+       if (val > 2550)
                return -ERANGE;
 
-       lis->duration = __ms_to_duration(lis, val);
+       lis->duration = val;
        if (lis->flags & LIS302DL_F_INPUT_OPEN)
-               __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
+               __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1,
+                               __ms_to_duration(lis, lis->duration));
 
        return count;
 }
@@ -450,8 +451,8 @@ static ssize_t set_wakeup(struct device *dev, struct 
device_attribute *attr,
        y_hi = y > 0 ? LIS302DL_FFWUCFG_YHIE : 0;
        z_hi = z > 0 ? LIS302DL_FFWUCFG_ZHIE : 0;
 
-       lis->wakeup.duration = __ms_to_duration(lis, duration);
-       lis->wakeup.threshold = __mg_to_threshold(lis, threshold);
+       lis->wakeup.duration = lis->duration;
+       lis->wakeup.threshold = lis->threshold;
        lis->wakeup.cfg = (and_events ? LIS302DL_FFWUCFG_AOI : 0) |
                x_lo | x_hi | y_lo | y_hi | z_lo | z_hi;
 
@@ -480,8 +481,8 @@ static ssize_t show_wakeup(struct device *dev,
                        "%s events, duration %d, threshold %d, "
                        "enabled: %s %s %s %s %s %s\n",
                        (config & LIS302DL_FFWUCFG_AOI) == 0 ? "or" : "and",
-                       __duration_to_ms(lis, lis->wakeup.duration),
-                       __threshold_to_mg(lis, lis->wakeup.threshold),
+                       lis->wakeup.duration,
+                       lis->wakeup.threshold,
                        (config & LIS302DL_FFWUCFG_XLIE) == 0 ? "---" : "xlo",
                        (config & LIS302DL_FFWUCFG_XHIE) == 0 ? "---" : "xhi",
                        (config & LIS302DL_FFWUCFG_YLIE) == 0 ? "---" : "ylo",
@@ -622,7 +623,7 @@ static int __devinit lis302dl_probe(struct platform_device 
*pdev)
        set_bit(BTN_Y, lis->input_dev->keybit);
        set_bit(BTN_Z, lis->input_dev->keybit);
 */
-       lis->threshold = 1;
+       lis->threshold = __threshold_to_mg(lis, 1);
        lis->duration = 0;
        memset(&lis->wakeup, 0, sizeof(lis->wakeup));
 
diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
index 723722b..a255c76 100644
--- a/include/linux/lis302dl.h
+++ b/include/linux/lis302dl.h
@@ -34,8 +34,8 @@ struct lis302dl_info {
        unsigned int duration;
        struct {
                u8 cfg;
-               u8 threshold;
-               u8 duration;
+               unsigned int threshold; /* mg */
+               unsigned int duration;  /* ms */
                int active;
        } wakeup;
        u_int8_t regs[0x40];

Reply via email to