diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1308--lis302dl-configure-duration.patch.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1308--lis302dl-configure-duration.patch.patch | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1308--lis302dl-configure-duration.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1308--lis302dl-configure-duration.patch.patch new file mode 100644 index 000000000..dbe08b4cd --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.24/1308--lis302dl-configure-duration.patch.patch @@ -0,0 +1,167 @@ +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 + |