aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1307--lis302dl-threshold-configuration-in-mg.patch.patch
blob: 9aa9a3a7d489595ae7e701d8ea2f5a5ffd82abc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From 5e2b5ddaf95985744e0e0c28ba6dac83c093fd15 Mon Sep 17 00:00:00 2001
From: Simon Kagstrom <simon.kagstrom@gmail.com>
Date: Thu, 16 Oct 2008 01:19:29 +0100
Subject: [PATCH] : lis302dl-threshold-configuration-in-mg.patch

Change the threshold configuration to be set in mg instead

From: Simon Kagstrom <simon.kagstrom@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@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);
 
-- 
1.5.6.5