aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/ads7846.c')
-rw-r--r--drivers/input/touchscreen/ads7846.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 8fd7fc39c4fd..ff97897feaf2 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -33,6 +33,7 @@
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/unaligned.h>
36 37
37/* 38/*
38 * This code has been heavily tested on a Nokia 770, and lightly 39 * This code has been heavily tested on a Nokia 770, and lightly
@@ -199,6 +200,26 @@ struct ads7846 {
199#define REF_ON (READ_12BIT_DFR(x, 1, 1)) 200#define REF_ON (READ_12BIT_DFR(x, 1, 1))
200#define REF_OFF (READ_12BIT_DFR(y, 0, 0)) 201#define REF_OFF (READ_12BIT_DFR(y, 0, 0))
201 202
203static int get_pendown_state(struct ads7846 *ts)
204{
205 if (ts->get_pendown_state)
206 return ts->get_pendown_state();
207
208 return !gpio_get_value(ts->gpio_pendown);
209}
210
211static void ads7846_report_pen_up(struct ads7846 *ts)
212{
213 struct input_dev *input = ts->input;
214
215 input_report_key(input, BTN_TOUCH, 0);
216 input_report_abs(input, ABS_PRESSURE, 0);
217 input_sync(input);
218
219 ts->pendown = false;
220 dev_vdbg(&ts->spi->dev, "UP\n");
221}
222
202/* Must be called with ts->lock held */ 223/* Must be called with ts->lock held */
203static void ads7846_stop(struct ads7846 *ts) 224static void ads7846_stop(struct ads7846 *ts)
204{ 225{
@@ -215,6 +236,10 @@ static void ads7846_stop(struct ads7846 *ts)
215static void ads7846_restart(struct ads7846 *ts) 236static void ads7846_restart(struct ads7846 *ts)
216{ 237{
217 if (!ts->disabled && !ts->suspended) { 238 if (!ts->disabled && !ts->suspended) {
239 /* Check if pen was released since last stop */
240 if (ts->pendown && !get_pendown_state(ts))
241 ads7846_report_pen_up(ts);
242
218 /* Tell IRQ thread that it may poll the device. */ 243 /* Tell IRQ thread that it may poll the device. */
219 ts->stopped = false; 244 ts->stopped = false;
220 mb(); 245 mb();
@@ -411,7 +436,7 @@ static int ads7845_read12_ser(struct device *dev, unsigned command)
411 436
412 if (status == 0) { 437 if (status == 0) {
413 /* BE12 value, then padding */ 438 /* BE12 value, then padding */
414 status = be16_to_cpu(*((u16 *)&req->sample[1])); 439 status = get_unaligned_be16(&req->sample[1]);
415 status = status >> 3; 440 status = status >> 3;
416 status &= 0x0fff; 441 status &= 0x0fff;
417 } 442 }
@@ -606,14 +631,6 @@ static const struct attribute_group ads784x_attr_group = {
606 631
607/*--------------------------------------------------------------------------*/ 632/*--------------------------------------------------------------------------*/
608 633
609static int get_pendown_state(struct ads7846 *ts)
610{
611 if (ts->get_pendown_state)
612 return ts->get_pendown_state();
613
614 return !gpio_get_value(ts->gpio_pendown);
615}
616
617static void null_wait_for_sync(void) 634static void null_wait_for_sync(void)
618{ 635{
619} 636}
@@ -786,10 +803,11 @@ static void ads7846_report_state(struct ads7846 *ts)
786 /* compute touch pressure resistance using equation #2 */ 803 /* compute touch pressure resistance using equation #2 */
787 Rt = z2; 804 Rt = z2;
788 Rt -= z1; 805 Rt -= z1;
789 Rt *= x;
790 Rt *= ts->x_plate_ohms; 806 Rt *= ts->x_plate_ohms;
807 Rt = DIV_ROUND_CLOSEST(Rt, 16);
808 Rt *= x;
791 Rt /= z1; 809 Rt /= z1;
792 Rt = (Rt + 2047) >> 12; 810 Rt = DIV_ROUND_CLOSEST(Rt, 256);
793 } else { 811 } else {
794 Rt = 0; 812 Rt = 0;
795 } 813 }
@@ -868,16 +886,8 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
868 msecs_to_jiffies(TS_POLL_PERIOD)); 886 msecs_to_jiffies(TS_POLL_PERIOD));
869 } 887 }
870 888
871 if (ts->pendown && !ts->stopped) { 889 if (ts->pendown && !ts->stopped)
872 struct input_dev *input = ts->input; 890 ads7846_report_pen_up(ts);
873
874 input_report_key(input, BTN_TOUCH, 0);
875 input_report_abs(input, ABS_PRESSURE, 0);
876 input_sync(input);
877
878 ts->pendown = false;
879 dev_vdbg(&ts->spi->dev, "UP\n");
880 }
881 891
882 return IRQ_HANDLED; 892 return IRQ_HANDLED;
883} 893}