PATCH/RFC [2/3]: lis302dl-convert-threshold-and-duration-on-commit.patch

Simon Kagstrom simon.kagstrom at gmail.com
Sat Nov 15 09:52:48 CET 2008


Keep the threshold and duration in mg/ms until write

From: Simon Kagstrom <simon.kagstrom at gmail.com>

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 <simon.kagstrom at gmail.com>
---

 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];



More information about the openmoko-kernel mailing list