aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>2005-10-30 18:38:01 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-10-30 18:38:01 -0500
commit1753298947afe5eb56da755bc057f1868f345ec1 (patch)
tree029133570ff8c2f0f642ff985b19dd64faf40dfe
parent5ecdb02c9d8b7f76108da6fcb2a66fdf5eed3116 (diff)
[ARM] Sharp sl-5500 touchscreen support
This adds support for sharp zaurus sl-5500 touchscreen. It introduces some not-too-nice ifs, but I guess copying whole ucb1x00-ts.c would be bad idea... Signed-off-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/mfd/ucb1x00-ts.c74
1 files changed, 53 insertions, 21 deletions
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 585cded3d365..a984c0efabf0 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,9 +32,12 @@
32#include <linux/suspend.h> 32#include <linux/suspend.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/kthread.h> 34#include <linux/kthread.h>
35#include <linux/delay.h>
35 36
36#include <asm/dma.h> 37#include <asm/dma.h>
37#include <asm/semaphore.h> 38#include <asm/semaphore.h>
39#include <asm/arch/collie.h>
40#include <asm/mach-types.h>
38 41
39#include "ucb1x00.h" 42#include "ucb1x00.h"
40 43
@@ -85,12 +88,23 @@ static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
85 */ 88 */
86static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts) 89static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
87{ 90{
88 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 91 if (machine_is_collie()) {
89 UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | 92 ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
90 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | 93 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
91 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); 94 UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
95 UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
92 96
93 return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); 97 udelay(55);
98
99 return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
100 } else {
101 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
102 UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
103 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
104 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
105
106 return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
107 }
94} 108}
95 109
96/* 110/*
@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
101 */ 115 */
102static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts) 116static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
103{ 117{
104 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 118 if (machine_is_collie())
105 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | 119 ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
106 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); 120 else {
107 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 121 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
108 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | 122 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
109 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); 123 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
124 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
125 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
126 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
127 }
110 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 128 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
111 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | 129 UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
112 UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); 130 UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
124 */ 142 */
125static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts) 143static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
126{ 144{
127 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 145 if (machine_is_collie())
128 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | 146 ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
129 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); 147 else {
130 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 148 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
131 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | 149 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
132 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); 150 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
151 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
152 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
153 UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
154 }
155
133 ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 156 ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
134 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | 157 UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
135 UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); 158 UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
163 return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); 186 return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
164} 187}
165 188
189static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
190{
191 unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
192 if (machine_is_collie())
193 return (!(val & (UCB_TS_CR_TSPX_LOW)));
194 else
195 return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
196}
197
166/* 198/*
167 * This is a RT kernel thread that handles the ADC accesses 199 * This is a RT kernel thread that handles the ADC accesses
168 * (mainly so we can use semaphores in the UCB1200 core code 200 * (mainly so we can use semaphores in the UCB1200 core code
@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)
186 218
187 add_wait_queue(&ts->irq_wait, &wait); 219 add_wait_queue(&ts->irq_wait, &wait);
188 while (!kthread_should_stop()) { 220 while (!kthread_should_stop()) {
189 unsigned int x, y, p, val; 221 unsigned int x, y, p;
190 signed long timeout; 222 signed long timeout;
191 223
192 ts->restart = 0; 224 ts->restart = 0;
@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
206 msleep(10); 238 msleep(10);
207 239
208 ucb1x00_enable(ts->ucb); 240 ucb1x00_enable(ts->ucb);
209 val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
210 241
211 if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) { 242
243 if (ucb1x00_ts_pen_down(ts)) {
212 set_task_state(tsk, TASK_INTERRUPTIBLE); 244 set_task_state(tsk, TASK_INTERRUPTIBLE);
213 245
214 ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); 246 ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
215 ucb1x00_disable(ts->ucb); 247 ucb1x00_disable(ts->ucb);
216 248
217 /* 249 /*