[PATCH 2/5]: lis302dl-threshold-configuration-in-mg.patch

Simon Kagstrom simon.kagstrom at gmail.com
Wed Oct 15 20:12:25 CEST 2008


Change the threshold configuration to be set in mg instead

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

This patch changes the threshold sysfs file to handle values in mg
instead of the device-values. Overrun values have also been corrected
and the sampler function now honors the FS bit.

Signed-off-by: Simon Kagstrom <simon.kagstrom at gmail.com>
---

 drivers/input/misc/lis302dl.c |   49 +++++++++++++++++++++++++++++++++--------
 1 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
index 300918d..c1b1d67 100644
--- a/drivers/input/misc/lis302dl.c
+++ b/drivers/input/misc/lis302dl.c
@@ -97,6 +97,24 @@ static int __duration_to_ms(struct lis302dl_info *lis, int duration)
 	return duration * 10;
 }
 
+static u8 __mg_to_threshold(struct lis302dl_info *lis, int mg)
+{
+	/* If FS is set each bit is 71mg, otherwise 18mg. The THS register
+	 * has 7 bits for the threshold value */
+	if (lis->flags & LIS302DL_F_FS)
+		return min(mg / 71, 127);
+
+	return min(mg / 18, 127);
+}
+
+static int __threshold_to_mg(struct lis302dl_info *lis, u8 threshold)
+{
+	if (lis->flags & LIS302DL_F_FS)
+		return threshold * 71;
+
+	return threshold * 18;
+}
+
 /* interrupt handling related */
 
 enum lis302dl_intmode {
@@ -146,23 +164,24 @@ static void _report_btn_double(struct input_dev *inp, int btn)
 }
 #endif
 
-#define MG_PER_SAMPLE 18
 
 static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis)
 {
 	u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
 	u8 read[5];
 	unsigned long flags;
+	int mg_per_sample;
 
 	local_irq_save(flags);
+	mg_per_sample = __threshold_to_mg(lis, 1);
 
 	(lis->pdata->lis302dl_bitbang)(lis, &data, 1, &read[0], 5);
 
 	local_irq_restore(flags);
 
-	input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]);
-	input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]);
-	input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]);
+	input_report_rel(lis->input_dev, REL_X, mg_per_sample * (s8)read[0]);
+	input_report_rel(lis->input_dev, REL_Y, mg_per_sample * (s8)read[2]);
+	input_report_rel(lis->input_dev, REL_Z, mg_per_sample * (s8)read[4]);
 
 	input_sync(lis->input_dev);
 
@@ -234,15 +253,24 @@ 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);
 
-	if (!strcmp(buf, "9.2\n"))
+	if (!strcmp(buf, "9.2\n")) {
 		__reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
 				 LIS302DL_CTRL1_FS);
-	else
+		lis->flags |= LIS302DL_F_FS;
+	} else {
 		__reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS,
-									     0);
+				0);
+		lis->flags &= ~LIS302DL_F_FS;
+	}
+
+	/* Adjust the threshold */
+	lis->threshold = __mg_to_threshold(lis, threshold_mg);
+	if (lis->flags & LIS302DL_F_INPUT_OPEN)
+		__reg_write(lis, LIS302DL_REG_FF_WU_THS_1, lis->threshold);
 
 	local_irq_restore(flags);
 
@@ -256,7 +284,7 @@ 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", lis->threshold);
+	return sprintf(buf, "%d\n", __threshold_to_mg(lis, lis->threshold));
 }
 
 static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
@@ -267,11 +295,12 @@ static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
 
 	if (sscanf(buf, "%d\n", &val) != 1)
 		return -EINVAL;
-	if (val < 0 || val > 255)
+	/* 8g is the maximum if FS is 1 */
+	if (val < 0 || val > 8000)
 		return -ERANGE;
 
 	/* Set the threshold and write it out if the device is used */
-	lis->threshold = val;
+	lis->threshold = __mg_to_threshold(lis, val);
 	if (lis->flags & LIS302DL_F_INPUT_OPEN)
 		__reg_write(lis, LIS302DL_REG_FF_WU_THS_1, lis->threshold);
 



More information about the openmoko-kernel mailing list