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
132
133
134
135
136
137
138
|
From ca57dbb5effd245e2619f4b730f8247f7279f954 Mon Sep 17 00:00:00 2001
From: Simon Kagstrom <simon.kagstrom@gmail.com>
Date: Thu, 16 Oct 2008 01:19:47 +0100
Subject: [PATCH] : lis302dl-open-floodgates-on-zero-threshold.patch
Generate data ready interrupts if threshold is zero
From: Simon Kagstrom <simon.kagstrom@gmail.com>
If the threshold is set to zero, enable the data ready interrupt
(generated one interrupt per datum). Otherwise use the freefall
interrupt as source.
Signed-off-by: Simon Kagstrom <simon.kagstrom@gmail.com>
---
drivers/input/misc/lis302dl.c | 64 +++++++++++++++++++++++++++-------------
1 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
index d738199..e404a45 100644
--- a/drivers/input/misc/lis302dl.c
+++ b/drivers/input/misc/lis302dl.c
@@ -44,6 +44,7 @@
#include <linux/lis302dl.h>
/* Utility functions */
+
static u8 __reg_read(struct lis302dl_info *lis, u8 reg)
{
return (lis->pdata->lis302dl_bitbang_reg_read)(lis, reg);
@@ -132,6 +133,36 @@ static void __lis302dl_int_mode(struct device *dev, int int_pin,
}
}
+static void __enable_data_collection(struct lis302dl_info *lis)
+{
+ u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen |
+ LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen;
+
+ /* make sure we're powered up and generate data ready */
+ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
+
+ /* If the threshold is zero, let the device generated an interrupt
+ * on each datum */
+ if (lis->threshold == 0) {
+ __reg_write(lis, LIS302DL_REG_CTRL2, 0);
+ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY);
+ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY);
+ } 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);
+
+ /* Clear the HP filter "starting point" */
+ __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
+ __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1,
+ LIS302DL_FFWUCFG_XHIE | LIS302DL_FFWUCFG_YHIE |
+ LIS302DL_FFWUCFG_ZHIE);
+ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12);
+ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12);
+ }
+}
+
#if 0
static void _report_btn_single(struct input_dev *inp, int btn)
{
@@ -263,7 +294,7 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
/* 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);
+ __enable_data_collection(lis);
local_irq_restore(flags);
@@ -294,8 +325,14 @@ static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
/* Set the threshold and write it out if the device is used */
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);
+
+ if (lis->flags & LIS302DL_F_INPUT_OPEN) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __enable_data_collection(lis);
+ local_irq_restore(flags);
+ }
return count;
}
@@ -562,29 +599,14 @@ static struct attribute_group lis302dl_attr_group = {
};
/* input device handling and driver core interaction */
-
static int lis302dl_input_open(struct input_dev *inp)
{
struct lis302dl_info *lis = inp->private;
- u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen |
- LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen;
- u_int8_t ctrl2 = LIS302DL_CTRL2_HPFF1;
unsigned long flags;
local_irq_save(flags);
- /* make sure we're powered up and generate data ready */
- __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
-
- __reg_write(lis, LIS302DL_REG_CTRL2,
- ctrl2);
- __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, lis->threshold);
- __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
-
- /* Clear the HP filter "starting point" */
- __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
- __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, LIS302DL_FFWUCFG_XHIE |
- LIS302DL_FFWUCFG_YHIE | LIS302DL_FFWUCFG_ZHIE);
+ __enable_data_collection(lis);
lis->flags |= LIS302DL_F_INPUT_OPEN;
/* kick it off -- since we are edge triggered, if we missed the edge
@@ -736,8 +758,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
/* push-pull, active-low */
__reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);
- __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12);
- __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12);
+ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_GND);
+ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_GND);
__reg_read(lis, LIS302DL_REG_STATUS);
__reg_read(lis, LIS302DL_REG_FF_WU_SRC_1);
--
1.5.6.5
|