[ar71xx] create firmware image for the Ubiquiti LS-SR71 board
[10.03/openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1308--lis302dl-configure-duration.patch.patch
1 From d3c59382c7e8429e2c86eb92cc2518dce26c4a69 Mon Sep 17 00:00:00 2001
2 From: Simon Kagstrom <simon.kagstrom@gmail.com>
3 Date: Thu, 16 Oct 2008 01:19:39 +0100
4 Subject: [PATCH] : lis302dl-configure-duration.patch
5
6 Allow configuration of the duration for thresholds
7
8 From: Simon Kagstrom <simon.kagstrom@gmail.com>
9
10 This patch allows the configuration of duration used when generating
11 filtered data (see the lis302dl application note). Also set a flag when
12 the DR bit in the ctrl1 register is set to change the data rate and
13 simplify the ms_to_duration utility functions.
14
15 The sysfs 'duration' file is used for this.
16
17 Signed-off-by: Simon Kagstrom <simon.kagstrom@gmail.com>
18 ---
19  drivers/input/misc/lis302dl.c |   63 ++++++++++++++++++++++++++++-------------
20  include/linux/lis302dl.h      |    2 +
21  2 files changed, 45 insertions(+), 20 deletions(-)
22
23 diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
24 index c1b1d67..d738199 100644
25 --- a/drivers/input/misc/lis302dl.c
26 +++ b/drivers/input/misc/lis302dl.c
27 @@ -69,29 +69,17 @@ static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask,
28  
29  static int __ms_to_duration(struct lis302dl_info *lis, int ms)
30  {
31 -       u8 r = __reg_read(lis, LIS302DL_REG_CTRL1);
32 -
33         /* If we have 400 ms sampling rate, the stepping is 2.5 ms,
34          * on 100 ms the stepping is 10ms */
35 -       if (r & LIS302DL_CTRL1_DR) {
36 -               /* Too large */
37 -               if (ms > 637)
38 -                       return -1;
39 -
40 -               return (ms * 10) / 25;
41 -       }
42 +       if (lis->flags & LIS302DL_F_DR)
43 +               return min((ms * 10) / 25, 637);
44  
45 -       /* Too large value */
46 -       if (ms > 2550)
47 -                       return -1;
48 -       return ms / 10;
49 +       return min(ms / 10, 2550);
50  }
51  
52  static int __duration_to_ms(struct lis302dl_info *lis, int duration)
53  {
54 -       u8 r = __reg_read(lis, LIS302DL_REG_CTRL1);
55 -
56 -       if (r & LIS302DL_CTRL1_DR)
57 +       if (lis->flags & LIS302DL_F_DR)
58                 return (duration * 25) / 10;
59  
60         return duration * 10;
61 @@ -218,15 +206,20 @@ static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
62  {
63         struct lis302dl_info *lis = dev_get_drvdata(dev);
64         unsigned long flags;
65 +       int duration_ms = __duration_to_ms(lis, lis->duration);
66  
67         local_irq_save(flags);
68  
69 -       if (!strcmp(buf, "400\n"))
70 +       if (!strcmp(buf, "400\n")) {
71                 __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
72                                  LIS302DL_CTRL1_DR);
73 -       else
74 +               lis->flags |= LIS302DL_F_DR;
75 +       } else {
76                 __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
77 -                                                                            0);
78 +                               0);
79 +               lis->flags &= ~LIS302DL_F_DR;
80 +       }
81 +       lis->duration = __ms_to_duration(lis, duration_ms);
82         local_irq_restore(flags);
83  
84         return count;
85 @@ -309,6 +302,34 @@ static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
86  
87  static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold);
88  
89 +static ssize_t show_duration(struct device *dev, struct device_attribute *attr,
90 +                char *buf)
91 +{
92 +       struct lis302dl_info *lis = dev_get_drvdata(dev);
93 +
94 +       return sprintf(buf, "%d\n", __duration_to_ms(lis, lis->duration));
95 +}
96 +
97 +static ssize_t set_duration(struct device *dev, struct device_attribute *attr,
98 +                const char *buf, size_t count)
99 +{
100 +       struct lis302dl_info *lis = dev_get_drvdata(dev);
101 +       u32 val;
102 +
103 +       if (sscanf(buf, "%d\n", &val) != 1)
104 +               return -EINVAL;
105 +       if (val < 0 || val > 2550)
106 +               return -ERANGE;
107 +
108 +       lis->duration = __ms_to_duration(lis, val);
109 +       if (lis->flags & LIS302DL_F_INPUT_OPEN)
110 +               __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
111 +
112 +       return count;
113 +}
114 +
115 +static DEVICE_ATTR(duration, S_IRUGO | S_IWUSR, show_duration, set_duration);
116 +
117  static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
118                                                                       char *buf)
119  {
120 @@ -528,6 +549,7 @@ static struct attribute *lis302dl_sysfs_entries[] = {
121         &dev_attr_sample_rate.attr,
122         &dev_attr_full_scale.attr,
123         &dev_attr_threshold.attr,
124 +       &dev_attr_duration.attr,
125         &dev_attr_dump.attr,
126         &dev_attr_freefall_wakeup_1.attr,
127         &dev_attr_freefall_wakeup_2.attr,
128 @@ -556,7 +578,7 @@ static int lis302dl_input_open(struct input_dev *inp)
129         __reg_write(lis, LIS302DL_REG_CTRL2,
130                         ctrl2);
131         __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, lis->threshold);
132 -       __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0);
133 +       __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
134  
135         /* Clear the HP filter "starting point" */
136         __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET);
137 @@ -670,6 +692,7 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
138         set_bit(BTN_Z, lis->input_dev->keybit);
139  */
140         lis->threshold = 1;
141 +       lis->duration = 0;
142  
143         lis->input_dev->private = lis;
144         lis->input_dev->name = pdata->name;
145 diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
146 index a756f55..f7aa956 100644
147 --- a/include/linux/lis302dl.h
148 +++ b/include/linux/lis302dl.h
149 @@ -30,6 +30,7 @@ struct lis302dl_info {
150         struct input_dev *input_dev;
151         unsigned int flags;
152         unsigned int threshold;
153 +       unsigned int duration;
154         u_int8_t regs[0x40];
155  };
156  
157 @@ -142,6 +143,7 @@ enum lis302dl_reg_cloik_src {
158  #define LIS302DL_F_FS                  0x0020  /* ADC full scale */
159  #define LIS302DL_F_INPUT_OPEN  0x0040  /* Set if input device is opened */
160  #define LIS302DL_F_IRQ_WAKE    0x0080  /* IRQ is setup in wake mode */
161 +#define LIS302DL_F_DR                  0x0100  /* Data rate, 400Hz/100Hz */
162  
163  
164  #endif /* _LINUX_LIS302DL_H */
165 -- 
166 1.5.6.5
167