diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1304--Acceleration-threshold-configuration-lis302dl-con.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1304--Acceleration-threshold-configuration-lis302dl-con.patch | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1304--Acceleration-threshold-configuration-lis302dl-con.patch b/target/linux/s3c24xx/patches-2.6.24/1304--Acceleration-threshold-configuration-lis302dl-con.patch new file mode 100644 index 0000000000..5e9eb2aac9 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.24/1304--Acceleration-threshold-configuration-lis302dl-con.patch @@ -0,0 +1,298 @@ +From 35d910f40ce2c7c959edfbaa671f88e8da5fa6b1 Mon Sep 17 00:00:00 2001 +From: Simon Kagstrom <simon.kagstrom@gmail.com> +Date: Mon, 13 Oct 2008 12:47:12 +0100 +Subject: [PATCH] : Acceleration threshold configuration: lis302dl-configure-threshold-on-bitbang.patch + +Configure threshold for accelerometer input + +From: Simon Kagstrom <simon.kagstrom@gmail.com> + +This patch, based on bitbang-all-the-way from the andy branch, +implements a configurable acceleration threshold that need to be +exceeded for the accelerometer to generate input data. The threshold can +be set in sysfs: + + cd /sys/devices/.../lis302dl.1/ + echo 10 > threshold + +A value of 10 (180 mg, from the lis302dl application note) seems +empirically good to keep the accelerometers quiet while riding a (calm) +train. + + +The patch moves the sample reading for the accelerometers from +mach-gta02.c to lis302dl.c and instead exports the generic +lis302dl_bitbang function. This is to easier support both "raw" data +reading and reading with a threshold in the future (not yet implemented). + +Signed-off-by: Simon Kagstrom <simon.kagstrom@gmail.com> +--- + arch/arm/mach-s3c2440/mach-gta02.c | 35 ++------------- + drivers/input/misc/lis302dl.c | 83 ++++++++++++++++++++++++++++++++++-- + include/linux/lis302dl.h | 3 + + 3 files changed, 87 insertions(+), 34 deletions(-) + +diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c +index b19632c..1a9d823 100644 +--- a/arch/arm/mach-s3c2440/mach-gta02.c ++++ b/arch/arm/mach-s3c2440/mach-gta02.c +@@ -1050,7 +1050,6 @@ static struct platform_device gta02_vibrator_dev = { + */ + + /* #define DEBUG_SPEW_MS */ +-#define MG_PER_SAMPLE 18 + + struct lis302dl_platform_data lis302_pdata_top; + struct lis302dl_platform_data lis302_pdata_bottom; +@@ -1060,7 +1059,7 @@ struct lis302dl_platform_data lis302_pdata_bottom; + * only call with interrupts off! + */ + +-static void __gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx, ++static void gta02_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx, + int tx_bytes, u8 *rx, int rx_bytes) + { + struct lis302dl_platform_data *pdata = lis->pdata; +@@ -1124,7 +1123,7 @@ static int gta02_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg) + + local_irq_save(flags); + +- __gta02_lis302dl_bitbang(lis, &data, 1, &data, 1); ++ gta02_lis302dl_bitbang(lis, &data, 1, &data, 1); + + local_irq_restore(flags); + +@@ -1139,37 +1138,13 @@ static void gta02_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg, + + local_irq_save(flags); + +- __gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0); ++ gta02_lis302dl_bitbang(lis, &data[0], 2, NULL, 0); + + local_irq_restore(flags); + + } + + +-static void gta02_lis302dl_bitbang_sample(struct lis302dl_info *lis) +-{ +- u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */ +- u8 read[5]; +- unsigned long flags; +- +- local_irq_save(flags); +- +- __gta02_lis302dl_bitbang(lis, &data, 1, &read[0], 5); +- +- local_irq_restore(flags); +- +- input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]); +- input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]); +- input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]); +- +- input_sync(lis->input_dev); +-#ifdef DEBUG_SPEW_MS +- printk(KERN_INFO "%s: %d %d %d\n", pdata->name, read[0], read[2], +- read[4]); +-#endif +-} +- +- + void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume) + { + struct lis302dl_platform_data *pdata = lis->pdata; +@@ -1210,7 +1185,7 @@ struct lis302dl_platform_data lis302_pdata_top = { + .pin_miso = S3C2410_GPG5, + .interrupt = GTA02_IRQ_GSENSOR_1, + .open_drain = 1, /* altered at runtime by PCB rev */ +- .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample, ++ .lis302dl_bitbang = gta02_lis302dl_bitbang, + .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg, + .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg, + .lis302dl_suspend_io = gta02_lis302dl_suspend_io, +@@ -1224,7 +1199,7 @@ struct lis302dl_platform_data lis302_pdata_bottom = { + .pin_miso = S3C2410_GPG5, + .interrupt = GTA02_IRQ_GSENSOR_2, + .open_drain = 1, /* altered at runtime by PCB rev */ +- .lis302dl_bitbang_read_sample = gta02_lis302dl_bitbang_sample, ++ .lis302dl_bitbang = gta02_lis302dl_bitbang, + .lis302dl_bitbang_reg_read = gta02_lis302dl_bitbang_read_reg, + .lis302dl_bitbang_reg_write = gta02_lis302dl_bitbang_write_reg, + .lis302dl_suspend_io = gta02_lis302dl_suspend_io, +diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c +index 1d5781d..1013f4a 100644 +--- a/drivers/input/misc/lis302dl.c ++++ b/drivers/input/misc/lis302dl.c +@@ -4,6 +4,8 @@ + * Author: Harald Welte <laforge@openmoko.org> + * converted to private bitbang by: + * Andy Green <andy@openmoko.com> ++ * ability to set acceleration threshold added by: ++ * Simon Kagstrom <simon.kagstrom@gmail.com> + * All rights reserved. + * + * This program is free software; you can redistribute it and/or +@@ -67,6 +69,31 @@ enum lis302dl_intmode { + LIS302DL_INTMODE_CLICK = 0x07, + }; + ++#define MG_PER_SAMPLE 18 ++ ++static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis) ++{ ++ u8 data = 0xc0 | LIS302DL_REG_OUT_X; /* read, autoincrement */ ++ u8 read[5]; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ (lis->pdata->lis302dl_bitbang)(lis, &data, 1, &read[0], 5); ++ ++ local_irq_restore(flags); ++ ++ input_report_rel(lis->input_dev, REL_X, MG_PER_SAMPLE * (s8)read[0]); ++ input_report_rel(lis->input_dev, REL_Y, MG_PER_SAMPLE * (s8)read[2]); ++ input_report_rel(lis->input_dev, REL_Z, MG_PER_SAMPLE * (s8)read[4]); ++ ++ input_sync(lis->input_dev); ++ ++ /* Reset the HP filter */ ++ (lis->pdata->lis302dl_bitbang_reg_read)(lis, ++ LIS302DL_REG_HP_FILTER_RESET); ++} ++ + static void __lis302dl_int_mode(struct device *dev, int int_pin, + enum lis302dl_intmode mode) + { +@@ -108,7 +135,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *_lis) + { + struct lis302dl_info *lis = _lis; + +- (lis->pdata->lis302dl_bitbang_read_sample)(lis); ++ lis302dl_bitbang_read_sample(lis); + return IRQ_HANDLED; + } + +@@ -187,6 +214,36 @@ static ssize_t set_scale(struct device *dev, struct device_attribute *attr, + + static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale); + ++static ssize_t show_threshold(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", lis->threshold); ++} ++ ++static ssize_t set_threshold(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 > 255) ++ return -ERANGE; ++ ++ /* Set the threshold and write it out if the device is used */ ++ lis->threshold = val; ++ if (lis->flags & LIS302DL_F_INPUT_OPEN) ++ (lis->pdata->lis302dl_bitbang_reg_write)(lis, ++ LIS302DL_REG_FF_WU_THS_1, lis->threshold); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold); ++ + static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr, + char *buf) + { +@@ -436,6 +493,7 @@ static DEVICE_ATTR(freefall_wakeup_2, S_IRUGO | S_IWUSR, show_freefall_2, + static struct attribute *lis302dl_sysfs_entries[] = { + &dev_attr_sample_rate.attr, + &dev_attr_full_scale.attr, ++ &dev_attr_threshold.attr, + &dev_attr_dump.attr, + &dev_attr_freefall_wakeup_1.attr, + &dev_attr_freefall_wakeup_2.attr, +@@ -454,17 +512,32 @@ 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); + ++ (lis->pdata->lis302dl_bitbang_reg_write)(lis, LIS302DL_REG_CTRL2, ++ ctrl2); ++ (lis->pdata->lis302dl_bitbang_reg_write)(lis, ++ LIS302DL_REG_FF_WU_THS_1, lis->threshold); ++ (lis->pdata->lis302dl_bitbang_reg_write)(lis, ++ LIS302DL_REG_FF_WU_DURATION_1, 0); ++ ++ /* Clear the HP filter "starting point" */ ++ (lis->pdata->lis302dl_bitbang_reg_read)(lis, ++ LIS302DL_REG_HP_FILTER_RESET); ++ (lis->pdata->lis302dl_bitbang_reg_write)(lis, ++ LIS302DL_REG_FF_WU_CFG_1, LIS302DL_FFWUCFG_XHIE | ++ LIS302DL_FFWUCFG_YHIE | LIS302DL_FFWUCFG_ZHIE); ++ + lis->flags |= LIS302DL_F_INPUT_OPEN; + + /* kick it off -- since we are edge triggered, if we missed the edge + * permanent low interrupt is death for us */ +- (lis->pdata->lis302dl_bitbang_read_sample)(lis); ++ lis302dl_bitbang_read_sample(lis); + + local_irq_restore(flags); + +@@ -567,6 +640,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev) + set_bit(BTN_Y, lis->input_dev->keybit); + set_bit(BTN_Z, lis->input_dev->keybit); + */ ++ lis->threshold = 1; ++ + lis->input_dev->private = lis; + lis->input_dev->name = pdata->name; + /* SPI Bus not defined as a valid bus for input subsystem*/ +@@ -617,8 +692,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev) + (lis->pdata->lis302dl_bitbang_reg_write)(lis, + LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL); + +- __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY); +- __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY); ++ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12); ++ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12); + + (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_STATUS); + (lis->pdata->lis302dl_bitbang_reg_read)(lis, LIS302DL_REG_FF_WU_SRC_1); +diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h +index 4578db4..f3f994d 100644 +--- a/include/linux/lis302dl.h ++++ b/include/linux/lis302dl.h +@@ -16,6 +16,8 @@ struct lis302dl_platform_data { + unsigned long pin_miso; + int open_drain; + int interrupt; ++ void (*lis302dl_bitbang)(struct lis302dl_info *lis, u8 *tx, ++ int tx_bytes, u8 *rx, int rx_bytes); + void (*lis302dl_bitbang_read_sample)(struct lis302dl_info *); + void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming); + int (*lis302dl_bitbang_reg_read)(struct lis302dl_info *, u8 reg); +@@ -28,6 +30,7 @@ struct lis302dl_info { + struct device *dev; + struct input_dev *input_dev; + unsigned int flags; ++ unsigned int threshold; + u_int8_t regs[0x40]; + }; + +-- +1.5.6.5 + |