changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1304--Acceleration-threshold-configuration-lis302dl-con.patch
1 From 35d910f40ce2c7c959edfbaa671f88e8da5fa6b1 Mon Sep 17 00:00:00 2001
2 From: Simon Kagstrom <simon.kagstrom@gmail.com>
3 Date: Mon, 13 Oct 2008 12:47:12 +0100
4 Subject: [PATCH] : Acceleration threshold configuration: lis302dl-configure-threshold-on-bitbang.patch
5
6 Configure threshold for accelerometer input
7
8 From: Simon Kagstrom <simon.kagstrom@gmail.com>
9
10 This patch, based on bitbang-all-the-way from the andy branch,
11 implements a configurable acceleration threshold that need to be
12 exceeded for the accelerometer to generate input data. The threshold can
13 be set in sysfs:
14
15    cd /sys/devices/.../lis302dl.1/
16    echo 10 > threshold
17
18 A value of 10 (180 mg, from the lis302dl application note) seems
19 empirically good to keep the accelerometers quiet while riding a (calm)
20 train.
21
22
23 The patch moves the sample reading for the accelerometers from
24 mach-gta02.c to lis302dl.c and instead exports the generic
25 lis302dl_bitbang function. This is to easier support both "raw" data
26 reading and reading with a threshold in the future (not yet implemented).
27
28 Signed-off-by: Simon Kagstrom <simon.kagstrom@gmail.com>
29 ---
30  arch/arm/mach-s3c2440/mach-gta02.c |   35 ++-------------
31  drivers/input/misc/lis302dl.c      |   83 ++++++++++++++++++++++++++++++++++--
32  include/linux/lis302dl.h           |    3 +
33  3 files changed, 87 insertions(+), 34 deletions(-)
34
35 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
36 index b19632c..1a9d823 100644
37 --- a/arch/arm/mach-s3c2440/mach-gta02.c
38 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
39 @@ -1050,7 +1050,6 @@ static struct platform_device gta02_vibrator_dev = {
40   */
41  
42  /* #define DEBUG_SPEW_MS */
43 -#define MG_PER_SAMPLE 18
44  
45  struct lis302dl_platform_data lis302_pdata_top;
46  struct lis302dl_platform_data lis302_pdata_bottom;
47 @@ -1060,7 +1059,7 @@ struct lis302dl_platform_data lis302_pdata_bottom;
48   * only call with interrupts off!
49   */
50  
51 -static void __gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx,
52 +static void gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx,
53                                              int tx_bytes, u8 *rx, int rx_bytes)
54  {
55         struct lis302dl_platform_data *pdata = lis->pdata;
56 @@ -1124,7 +1123,7 @@ static int gta02_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg)
57  
58         local_irq_save(flags);
59  
60 -       __gta02_lis302dl_bitbang(lis, &data, 1, &data, 1);
61 +       gta02_lis302dl_bitbang(lis, &data, 1, &data, 1);
62  
63         local_irq_restore(flags);
64  
65 @@ -1139,37 +1138,13 @@ static void gta02_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg,
66  
67         local_irq_save(flags);
68  
69 -       __gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0);
70 +       gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0);
71  
72         local_irq_restore(flags);
73  
74  }
75  
76  
77 -static void gta02_lis302dl_bitbang_sample(struct lis302dl_info *lis)
78 -{
79 -       u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
80 -       u8 read[5];
81 -       unsigned long flags;
82 -
83 -       local_irq_save(flags);
84 -
85 -       __gta02_lis302dl_bitbang(lis, &data, 1, &read[0], 5);
86 -
87 -       local_irq_restore(flags);
88 -
89 -       input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]);
90 -       input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]);
91 -       input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]);
92 -
93 -       input_sync(lis->input_dev);
94 -#ifdef DEBUG_SPEW_MS
95 -       printk(KERN_INFO "%s: %d %d %d\n", pdata->name, read[0], read[2],
96 -                                                                      read[4]);
97 -#endif
98 -}
99 -
100 -
101  void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume)
102  {
103         struct lis302dl_platform_data *pdata = lis->pdata;
104 @@ -1210,7 +1185,7 @@ struct lis302dl_platform_data lis302_pdata_top = {
105                 .pin_miso       = S3C2410_GPG5,
106                 .interrupt      = GTA02_IRQ_GSENSOR_1,
107                 .open_drain     = 1, /* altered at runtime by PCB rev */
108 -               .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample,
109 +               .lis302dl_bitbang = gta02_lis302dl_bitbang,
110                 .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
111                 .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
112                 .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
113 @@ -1224,7 +1199,7 @@ struct lis302dl_platform_data lis302_pdata_bottom = {
114                 .pin_miso       = S3C2410_GPG5,
115                 .interrupt      = GTA02_IRQ_GSENSOR_2,
116                 .open_drain     = 1, /* altered at runtime by PCB rev */
117 -               .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample,
118 +               .lis302dl_bitbang = gta02_lis302dl_bitbang,
119                 .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg,
120                 .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg,
121                 .lis302dl_suspend_io = gta02_lis302dl_suspend_io,
122 diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
123 index 1d5781d..1013f4a 100644
124 --- a/drivers/input/misc/lis302dl.c
125 +++ b/drivers/input/misc/lis302dl.c
126 @@ -4,6 +4,8 @@
127   * Author: Harald Welte <laforge@openmoko.org>
128   *         converted to private bitbang by:
129   *         Andy Green <andy@openmoko.com>
130 + *         ability to set acceleration threshold added by:
131 + *         Simon Kagstrom <simon.kagstrom@gmail.com>
132   * All rights reserved.
133   *
134   * This program is free software; you can redistribute it and/or
135 @@ -67,6 +69,31 @@ enum lis302dl_intmode {
136         LIS302DL_INTMODE_CLICK          = 0x07,
137  };
138  
139 +#define MG_PER_SAMPLE 18
140 +
141 +static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis)
142 +{
143 +       u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */
144 +       u8 read[5];
145 +       unsigned long flags;
146 +
147 +       local_irq_save(flags);
148 +
149 +       (lis->pdata->lis302dl_bitbang)(lis, &data, 1, &read[0], 5);
150 +
151 +       local_irq_restore(flags);
152 +
153 +       input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]);
154 +       input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]);
155 +       input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]);
156 +
157 +       input_sync(lis->input_dev);
158 +
159 +       /* Reset the HP filter */
160 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis,
161 +                       LIS302DL_REG_HP_FILTER_RESET);
162 +}
163 +
164  static void __lis302dl_int_mode(struct device *dev, int int_pin,
165                               enum lis302dl_intmode mode)
166  {
167 @@ -108,7 +135,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *_lis)
168  {
169         struct lis302dl_info *lis = _lis;
170  
171 -       (lis->pdata->lis302dl_bitbang_read_sample)(lis);
172 +       lis302dl_bitbang_read_sample(lis);
173         return IRQ_HANDLED;
174  }
175  
176 @@ -187,6 +214,36 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr,
177  
178  static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale);
179  
180 +static ssize_t show_threshold(struct device *dev, struct device_attribute *attr,
181 +                char *buf)
182 +{
183 +       struct lis302dl_info *lis = dev_get_drvdata(dev);
184 +
185 +       return sprintf(buf, "%d\n", lis->threshold);
186 +}
187 +
188 +static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
189 +                const char *buf, size_t count)
190 +{
191 +       struct lis302dl_info *lis = dev_get_drvdata(dev);
192 +       u32 val;
193 +
194 +       if (sscanf(buf, "%d\n", &val) != 1)
195 +               return -EINVAL;
196 +       if (val < 0 || val > 255)
197 +               return -ERANGE;
198 +
199 +       /* Set the threshold and write it out if the device is used */
200 +       lis->threshold = val;
201 +       if (lis->flags & LIS302DL_F_INPUT_OPEN)
202 +               (lis->pdata->lis302dl_bitbang_reg_write)(lis,
203 +                               LIS302DL_REG_FF_WU_THS_1, lis->threshold);
204 +
205 +       return count;
206 +}
207 +
208 +static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold);
209 +
210  static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
211                                                                       char *buf)
212  {
213 @@ -436,6 +493,7 @@ static DEVICE_ATTR(freefall_wakeup_2, S_IRUGO | S_IWUSR, show_freefall_2,
214  static struct attribute *lis302dl_sysfs_entries[] = {
215         &dev_attr_sample_rate.attr,
216         &dev_attr_full_scale.attr,
217 +       &dev_attr_threshold.attr,
218         &dev_attr_dump.attr,
219         &dev_attr_freefall_wakeup_1.attr,
220         &dev_attr_freefall_wakeup_2.attr,
221 @@ -454,17 +512,32 @@ static int lis302dl_input_open(struct input_dev *inp)
222         struct lis302dl_info *lis = inp->private;
223         u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen |
224                          LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen;
225 +       u_int8_t ctrl2 = LIS302DL_CTRL2_HPFF1;
226         unsigned long flags;
227  
228         local_irq_save(flags);
229         /* make sure we're powered up and generate data ready */
230         __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1);
231  
232 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2,
233 +                       ctrl2);
234 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
235 +                       LIS302DL_REG_FF_WU_THS_1, lis->threshold);
236 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
237 +                       LIS302DL_REG_FF_WU_DURATION_1, 0);
238 +
239 +       /* Clear the HP filter "starting point" */
240 +       (lis->pdata->lis302dl_bitbang_reg_read)(lis,
241 +                       LIS302DL_REG_HP_FILTER_RESET);
242 +       (lis->pdata->lis302dl_bitbang_reg_write)(lis,
243 +                       LIS302DL_REG_FF_WU_CFG_1, LIS302DL_FFWUCFG_XHIE |
244 +                       LIS302DL_FFWUCFG_YHIE | LIS302DL_FFWUCFG_ZHIE);
245 +
246         lis->flags |= LIS302DL_F_INPUT_OPEN;
247  
248         /* kick it off -- since we are edge triggered, if we missed the edge
249          * permanent low interrupt is death for us */
250 -       (lis->pdata->lis302dl_bitbang_read_sample)(lis);
251 +       lis302dl_bitbang_read_sample(lis);
252  
253         local_irq_restore(flags);
254  
255 @@ -567,6 +640,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
256         set_bit(BTN_Y, lis->input_dev->keybit);
257         set_bit(BTN_Z, lis->input_dev->keybit);
258  */
259 +       lis->threshold = 1;
260 +
261         lis->input_dev->private = lis;
262         lis->input_dev->name = pdata->name;
263          /* SPI Bus not defined as a valid bus for input subsystem*/
264 @@ -617,8 +692,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
265                 (lis->pdata->lis302dl_bitbang_reg_write)(lis,
266                                         LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL);
267  
268 -       __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY);
269 -       __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY);
270 +       __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12);
271 +       __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12);
272  
273         (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_STATUS);
274         (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_1);
275 diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
276 index 4578db4..f3f994d 100644
277 --- a/include/linux/lis302dl.h
278 +++ b/include/linux/lis302dl.h
279 @@ -16,6 +16,8 @@ struct lis302dl_platform_data {
280         unsigned long pin_miso;
281         int open_drain;
282         int interrupt;
283 +       void (*lis302dl_bitbang)(struct lis302dl_info *lis, u8 *tx,
284 +                       int tx_bytes, u8 *rx, int rx_bytes);
285         void (*lis302dl_bitbang_read_sample)(struct lis302dl_info *);
286         void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming);
287         int (*lis302dl_bitbang_reg_read)(struct lis302dl_info *, u8 reg);
288 @@ -28,6 +30,7 @@ struct lis302dl_info {
289         struct device *dev;
290         struct input_dev *input_dev;
291         unsigned int flags;
292 +       unsigned int threshold;
293         u_int8_t regs[0x40];
294  };
295  
296 -- 
297 1.5.6.5
298