diff options
Diffstat (limited to 'drivers/input/touchscreen/ads7846.c')
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 1c9069cd3bae..96581d08774f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -95,7 +95,7 @@ struct ads7846 { | |||
95 | u16 dummy; /* for the pwrdown read */ | 95 | u16 dummy; /* for the pwrdown read */ |
96 | struct ts_event tc; | 96 | struct ts_event tc; |
97 | 97 | ||
98 | struct spi_transfer xfer[10]; | 98 | struct spi_transfer xfer[18]; |
99 | struct spi_message msg[5]; | 99 | struct spi_message msg[5]; |
100 | struct spi_message *last_msg; | 100 | struct spi_message *last_msg; |
101 | int msg_idx; | 101 | int msg_idx; |
@@ -107,6 +107,8 @@ struct ads7846 { | |||
107 | u16 debounce_tol; | 107 | u16 debounce_tol; |
108 | u16 debounce_rep; | 108 | u16 debounce_rep; |
109 | 109 | ||
110 | u16 penirq_recheck_delay_usecs; | ||
111 | |||
110 | spinlock_t lock; | 112 | spinlock_t lock; |
111 | struct hrtimer timer; | 113 | struct hrtimer timer; |
112 | unsigned pendown:1; /* P: lock */ | 114 | unsigned pendown:1; /* P: lock */ |
@@ -553,6 +555,15 @@ static void ads7846_rx(void *ads) | |||
553 | return; | 555 | return; |
554 | } | 556 | } |
555 | 557 | ||
558 | /* Maybe check the pendown state before reporting. This discards | ||
559 | * false readings when the pen is lifted. | ||
560 | */ | ||
561 | if (ts->penirq_recheck_delay_usecs) { | ||
562 | udelay(ts->penirq_recheck_delay_usecs); | ||
563 | if (!ts->get_pendown_state()) | ||
564 | Rt = 0; | ||
565 | } | ||
566 | |||
556 | /* NOTE: We can't rely on the pressure to determine the pen down | 567 | /* NOTE: We can't rely on the pressure to determine the pen down |
557 | * state, even this controller has a pressure sensor. The pressure | 568 | * state, even this controller has a pressure sensor. The pressure |
558 | * value can fluctuate for quite a while after lifting the pen and | 569 | * value can fluctuate for quite a while after lifting the pen and |
@@ -896,6 +907,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
896 | ts->filter = ads7846_no_filter; | 907 | ts->filter = ads7846_no_filter; |
897 | ts->get_pendown_state = pdata->get_pendown_state; | 908 | ts->get_pendown_state = pdata->get_pendown_state; |
898 | 909 | ||
910 | if (pdata->penirq_recheck_delay_usecs) | ||
911 | ts->penirq_recheck_delay_usecs = | ||
912 | pdata->penirq_recheck_delay_usecs; | ||
913 | |||
899 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); | 914 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
900 | 915 | ||
901 | input_dev->name = "ADS784x Touchscreen"; | 916 | input_dev->name = "ADS784x Touchscreen"; |
@@ -936,6 +951,24 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
936 | x->len = 2; | 951 | x->len = 2; |
937 | spi_message_add_tail(x, m); | 952 | spi_message_add_tail(x, m); |
938 | 953 | ||
954 | /* the first sample after switching drivers can be low quality; | ||
955 | * optionally discard it, using a second one after the signals | ||
956 | * have had enough time to stabilize. | ||
957 | */ | ||
958 | if (pdata->settle_delay_usecs) { | ||
959 | x->delay_usecs = pdata->settle_delay_usecs; | ||
960 | |||
961 | x++; | ||
962 | x->tx_buf = &ts->read_y; | ||
963 | x->len = 1; | ||
964 | spi_message_add_tail(x, m); | ||
965 | |||
966 | x++; | ||
967 | x->rx_buf = &ts->tc.y; | ||
968 | x->len = 2; | ||
969 | spi_message_add_tail(x, m); | ||
970 | } | ||
971 | |||
939 | m->complete = ads7846_rx_val; | 972 | m->complete = ads7846_rx_val; |
940 | m->context = ts; | 973 | m->context = ts; |
941 | 974 | ||
@@ -954,6 +987,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
954 | x->len = 2; | 987 | x->len = 2; |
955 | spi_message_add_tail(x, m); | 988 | spi_message_add_tail(x, m); |
956 | 989 | ||
990 | /* ... maybe discard first sample ... */ | ||
991 | if (pdata->settle_delay_usecs) { | ||
992 | x->delay_usecs = pdata->settle_delay_usecs; | ||
993 | |||
994 | x++; | ||
995 | x->tx_buf = &ts->read_x; | ||
996 | x->len = 1; | ||
997 | spi_message_add_tail(x, m); | ||
998 | |||
999 | x++; | ||
1000 | x->rx_buf = &ts->tc.x; | ||
1001 | x->len = 2; | ||
1002 | spi_message_add_tail(x, m); | ||
1003 | } | ||
1004 | |||
957 | m->complete = ads7846_rx_val; | 1005 | m->complete = ads7846_rx_val; |
958 | m->context = ts; | 1006 | m->context = ts; |
959 | 1007 | ||
@@ -973,6 +1021,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
973 | x->len = 2; | 1021 | x->len = 2; |
974 | spi_message_add_tail(x, m); | 1022 | spi_message_add_tail(x, m); |
975 | 1023 | ||
1024 | /* ... maybe discard first sample ... */ | ||
1025 | if (pdata->settle_delay_usecs) { | ||
1026 | x->delay_usecs = pdata->settle_delay_usecs; | ||
1027 | |||
1028 | x++; | ||
1029 | x->tx_buf = &ts->read_z1; | ||
1030 | x->len = 1; | ||
1031 | spi_message_add_tail(x, m); | ||
1032 | |||
1033 | x++; | ||
1034 | x->rx_buf = &ts->tc.z1; | ||
1035 | x->len = 2; | ||
1036 | spi_message_add_tail(x, m); | ||
1037 | } | ||
1038 | |||
976 | m->complete = ads7846_rx_val; | 1039 | m->complete = ads7846_rx_val; |
977 | m->context = ts; | 1040 | m->context = ts; |
978 | 1041 | ||
@@ -990,6 +1053,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
990 | x->len = 2; | 1053 | x->len = 2; |
991 | spi_message_add_tail(x, m); | 1054 | spi_message_add_tail(x, m); |
992 | 1055 | ||
1056 | /* ... maybe discard first sample ... */ | ||
1057 | if (pdata->settle_delay_usecs) { | ||
1058 | x->delay_usecs = pdata->settle_delay_usecs; | ||
1059 | |||
1060 | x++; | ||
1061 | x->tx_buf = &ts->read_z2; | ||
1062 | x->len = 1; | ||
1063 | spi_message_add_tail(x, m); | ||
1064 | |||
1065 | x++; | ||
1066 | x->rx_buf = &ts->tc.z2; | ||
1067 | x->len = 2; | ||
1068 | spi_message_add_tail(x, m); | ||
1069 | } | ||
1070 | |||
993 | m->complete = ads7846_rx_val; | 1071 | m->complete = ads7846_rx_val; |
994 | m->context = ts; | 1072 | m->context = ts; |
995 | } | 1073 | } |