mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-29 19:04:36 +02:00
fc54b9bf15
(stable-branch of Openmoko) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13613 3c298f89-4303-0410-b956-a3cf2f4a3e73
168 lines
5.1 KiB
Diff
168 lines
5.1 KiB
Diff
From d3c59382c7e8429e2c86eb92cc2518dce26c4a69 Mon Sep 17 00:00:00 2001
|
|
From: Simon Kagstrom <simon.kagstrom@gmail.com>
|
|
Date: Thu, 16 Oct 2008 01:19:39 +0100
|
|
Subject: [PATCH] : lis302dl-configure-duration.patch
|
|
|
|
Allow configuration of the duration for thresholds
|
|
|
|
From: Simon Kagstrom <simon.kagstrom@gmail.com>
|
|
|
|
This patch allows the configuration of duration used when generating
|
|
filtered data (see the lis302dl application note). Also set a flag when
|
|
the DR bit in the ctrl1 register is set to change the data rate and
|
|
simplify the ms_to_duration utility functions.
|
|
|
|
The sysfs 'duration' file is used for this.
|
|
|
|
Signed-off-by: Simon Kagstrom <simon.kagstrom@gmail.com>
|
|
---
|
|
drivers/input/misc/lis302dl.c | 63 ++++++++++++++++++++++++++++-------------
|
|
include/linux/lis302dl.h | 2 +
|
|
2 files changed, 45 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
|
|
index c1b1d67..d738199 100644
|
|
--- a/drivers/input/misc/lis302dl.c
|
|
+++ b/drivers/input/misc/lis302dl.c
|
|
@@ -69,29 +69,17 @@ static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask,
|
|
|
|
static int __ms_to_duration(struct lis302dl_info *lis, int ms)
|
|
{
|
|
- u8 r = __reg_read(lis, LIS302DL_REG_CTRL1);
|
|
-
|
|
/* If we have 400 ms sampling rate, the stepping is 2.5 ms,
|
|
* on 100 ms the stepping is 10ms */
|
|
- if (r & LIS302DL_CTRL1_DR) {
|
|
- /* Too large */
|
|
- if (ms > 637)
|
|
- return -1;
|
|
-
|
|
- return (ms * 10) / 25;
|
|
- }
|
|
+ if (lis->flags & LIS302DL_F_DR)
|
|
+ return min((ms * 10) / 25, 637);
|
|
|
|
- /* Too large value */
|
|
- if (ms > 2550)
|
|
- return -1;
|
|
- return ms / 10;
|
|
+ return min(ms / 10, 2550);
|
|
}
|
|
|
|
static int __duration_to_ms(struct lis302dl_info *lis, int duration)
|
|
{
|
|
- u8 r = __reg_read(lis, LIS302DL_REG_CTRL1);
|
|
-
|
|
- if (r & LIS302DL_CTRL1_DR)
|
|
+ if (lis->flags & LIS302DL_F_DR)
|
|
return (duration * 25) / 10;
|
|
|
|
return duration * 10;
|
|
@@ -218,15 +206,20 @@ static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
|
|
{
|
|
struct lis302dl_info *lis = dev_get_drvdata(dev);
|
|
unsigned long flags;
|
|
+ int duration_ms = __duration_to_ms(lis, lis->duration);
|
|
|
|
local_irq_save(flags);
|
|
|
|
- if (!strcmp(buf, "400\n"))
|
|
+ if (!strcmp(buf, "400\n")) {
|
|
__reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
|
|
LIS302DL_CTRL1_DR);
|
|
- else
|
|
+ lis->flags |= LIS302DL_F_DR;
|
|
+ } else {
|
|
__reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR,
|
|
- 0);
|
|
+ 0);
|
|
+ lis->flags &= ~LIS302DL_F_DR;
|
|
+ }
|
|
+ lis->duration = __ms_to_duration(lis, duration_ms);
|
|
local_irq_restore(flags);
|
|
|
|
return count;
|
|
@@ -309,6 +302,34 @@ static ssize_t set_threshold(struct device *dev, struct device_attribute *attr,
|
|
|
|
static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold);
|
|
|
|
+static ssize_t show_duration(struct device *dev, struct device_attribute *attr,
|
|
+ char *buf)
|
|
+{
|
|
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
|
+
|
|
+ return sprintf(buf, "%d\n", __duration_to_ms(lis, lis->duration));
|
|
+}
|
|
+
|
|
+static ssize_t set_duration(struct device *dev, struct device_attribute *attr,
|
|
+ const char *buf, size_t count)
|
|
+{
|
|
+ struct lis302dl_info *lis = dev_get_drvdata(dev);
|
|
+ u32 val;
|
|
+
|
|
+ if (sscanf(buf, "%d\n", &val) != 1)
|
|
+ return -EINVAL;
|
|
+ if (val < 0 || val > 2550)
|
|
+ return -ERANGE;
|
|
+
|
|
+ lis->duration = __ms_to_duration(lis, val);
|
|
+ if (lis->flags & LIS302DL_F_INPUT_OPEN)
|
|
+ __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, lis->duration);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static DEVICE_ATTR(duration, S_IRUGO | S_IWUSR, show_duration, set_duration);
|
|
+
|
|
static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
@@ -528,6 +549,7 @@ static struct attribute *lis302dl_sysfs_entries[] = {
|
|
&dev_attr_sample_rate.attr,
|
|
&dev_attr_full_scale.attr,
|
|
&dev_attr_threshold.attr,
|
|
+ &dev_attr_duration.attr,
|
|
&dev_attr_dump.attr,
|
|
&dev_attr_freefall_wakeup_1.attr,
|
|
&dev_attr_freefall_wakeup_2.attr,
|
|
@@ -556,7 +578,7 @@ static int lis302dl_input_open(struct input_dev *inp)
|
|
__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, 0);
|
|
+ __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);
|
|
@@ -670,6 +692,7 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
|
|
set_bit(BTN_Z, lis->input_dev->keybit);
|
|
*/
|
|
lis->threshold = 1;
|
|
+ lis->duration = 0;
|
|
|
|
lis->input_dev->private = lis;
|
|
lis->input_dev->name = pdata->name;
|
|
diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
|
|
index a756f55..f7aa956 100644
|
|
--- a/include/linux/lis302dl.h
|
|
+++ b/include/linux/lis302dl.h
|
|
@@ -30,6 +30,7 @@ struct lis302dl_info {
|
|
struct input_dev *input_dev;
|
|
unsigned int flags;
|
|
unsigned int threshold;
|
|
+ unsigned int duration;
|
|
u_int8_t regs[0x40];
|
|
};
|
|
|
|
@@ -142,6 +143,7 @@ enum lis302dl_reg_cloik_src {
|
|
#define LIS302DL_F_FS 0x0020 /* ADC full scale */
|
|
#define LIS302DL_F_INPUT_OPEN 0x0040 /* Set if input device is opened */
|
|
#define LIS302DL_F_IRQ_WAKE 0x0080 /* IRQ is setup in wake mode */
|
|
+#define LIS302DL_F_DR 0x0100 /* Data rate, 400Hz/100Hz */
|
|
|
|
|
|
#endif /* _LINUX_LIS302DL_H */
|
|
--
|
|
1.5.6.5
|
|
|