xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/ucb1400_ts.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Philips UCB1400 touchscreen driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Author:	Nicolas Pitre
6*4882a593Smuzhiyun  *  Created:	September 25, 2006
7*4882a593Smuzhiyun  *  Copyright:	MontaVista Software, Inc.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Spliting done by: Marek Vasut <marek.vasut@gmail.com>
10*4882a593Smuzhiyun  * If something doesn't work and it worked before spliting, e-mail me,
11*4882a593Smuzhiyun  * dont bother Nicolas please ;-)
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * This code is heavily based on ucb1x00-*.c copyrighted by Russell King
14*4882a593Smuzhiyun  * covering the UCB1100, UCB1200 and UCB1300..  Support for the UCB1400 has
15*4882a593Smuzhiyun  * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/delay.h>
20*4882a593Smuzhiyun #include <linux/sched.h>
21*4882a593Smuzhiyun #include <linux/wait.h>
22*4882a593Smuzhiyun #include <linux/input.h>
23*4882a593Smuzhiyun #include <linux/device.h>
24*4882a593Smuzhiyun #include <linux/interrupt.h>
25*4882a593Smuzhiyun #include <linux/ucb1400.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define UCB1400_TS_POLL_PERIOD	10 /* ms */
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun static bool adcsync;
30*4882a593Smuzhiyun static int ts_delay = 55; /* us */
31*4882a593Smuzhiyun static int ts_delay_pressure;	/* us */
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* Switch to interrupt mode. */
ucb1400_ts_mode_int(struct ucb1400_ts * ucb)34*4882a593Smuzhiyun static void ucb1400_ts_mode_int(struct ucb1400_ts *ucb)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
37*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
38*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
39*4882a593Smuzhiyun 			UCB_TS_CR_MODE_INT);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun  * Switch to pressure mode, and read pressure.  We don't need to wait
44*4882a593Smuzhiyun  * here, since both plates are being driven.
45*4882a593Smuzhiyun  */
ucb1400_ts_read_pressure(struct ucb1400_ts * ucb)46*4882a593Smuzhiyun static unsigned int ucb1400_ts_read_pressure(struct ucb1400_ts *ucb)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
49*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
50*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
51*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	udelay(ts_delay_pressure);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * Switch to X position mode and measure Y plate.  We switch the plate
60*4882a593Smuzhiyun  * configuration in pressure mode, then switch to position mode.  This
61*4882a593Smuzhiyun  * gives a faster response time.  Even so, we need to wait about 55us
62*4882a593Smuzhiyun  * for things to stabilise.
63*4882a593Smuzhiyun  */
ucb1400_ts_read_xpos(struct ucb1400_ts * ucb)64*4882a593Smuzhiyun static unsigned int ucb1400_ts_read_xpos(struct ucb1400_ts *ucb)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
67*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
68*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
69*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
70*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
71*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
72*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
73*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
74*4882a593Smuzhiyun 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	udelay(ts_delay);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPY, adcsync);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun  * Switch to Y position mode and measure X plate.  We switch the plate
83*4882a593Smuzhiyun  * configuration in pressure mode, then switch to position mode.  This
84*4882a593Smuzhiyun  * gives a faster response time.  Even so, we need to wait about 55us
85*4882a593Smuzhiyun  * for things to stabilise.
86*4882a593Smuzhiyun  */
ucb1400_ts_read_ypos(struct ucb1400_ts * ucb)87*4882a593Smuzhiyun static int ucb1400_ts_read_ypos(struct ucb1400_ts *ucb)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
90*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
91*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
92*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
93*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
94*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
95*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
96*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
97*4882a593Smuzhiyun 			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	udelay(ts_delay);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	return ucb1400_adc_read(ucb->ac97, UCB_ADC_INP_TSPX, adcsync);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /*
105*4882a593Smuzhiyun  * Switch to X plate resistance mode.  Set MX to ground, PX to
106*4882a593Smuzhiyun  * supply.  Measure current.
107*4882a593Smuzhiyun  */
ucb1400_ts_read_xres(struct ucb1400_ts * ucb)108*4882a593Smuzhiyun static unsigned int ucb1400_ts_read_xres(struct ucb1400_ts *ucb)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
111*4882a593Smuzhiyun 			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
112*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
113*4882a593Smuzhiyun 	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /*
117*4882a593Smuzhiyun  * Switch to Y plate resistance mode.  Set MY to ground, PY to
118*4882a593Smuzhiyun  * supply.  Measure current.
119*4882a593Smuzhiyun  */
ucb1400_ts_read_yres(struct ucb1400_ts * ucb)120*4882a593Smuzhiyun static unsigned int ucb1400_ts_read_yres(struct ucb1400_ts *ucb)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR,
123*4882a593Smuzhiyun 			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
124*4882a593Smuzhiyun 			UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
125*4882a593Smuzhiyun 	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
ucb1400_ts_pen_up(struct ucb1400_ts * ucb)128*4882a593Smuzhiyun static int ucb1400_ts_pen_up(struct ucb1400_ts *ucb)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	unsigned short val = ucb1400_reg_read(ucb->ac97, UCB_TS_CR);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	return val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
ucb1400_ts_irq_enable(struct ucb1400_ts * ucb)135*4882a593Smuzhiyun static void ucb1400_ts_irq_enable(struct ucb1400_ts *ucb)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, UCB_IE_TSPX);
138*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
139*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_TSPX);
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun 
ucb1400_ts_irq_disable(struct ucb1400_ts * ucb)142*4882a593Smuzhiyun static void ucb1400_ts_irq_disable(struct ucb1400_ts *ucb)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
ucb1400_ts_report_event(struct input_dev * idev,u16 pressure,u16 x,u16 y)147*4882a593Smuzhiyun static void ucb1400_ts_report_event(struct input_dev *idev, u16 pressure, u16 x, u16 y)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	input_report_abs(idev, ABS_X, x);
150*4882a593Smuzhiyun 	input_report_abs(idev, ABS_Y, y);
151*4882a593Smuzhiyun 	input_report_abs(idev, ABS_PRESSURE, pressure);
152*4882a593Smuzhiyun 	input_report_key(idev, BTN_TOUCH, 1);
153*4882a593Smuzhiyun 	input_sync(idev);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
ucb1400_ts_event_release(struct input_dev * idev)156*4882a593Smuzhiyun static void ucb1400_ts_event_release(struct input_dev *idev)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	input_report_abs(idev, ABS_PRESSURE, 0);
159*4882a593Smuzhiyun 	input_report_key(idev, BTN_TOUCH, 0);
160*4882a593Smuzhiyun 	input_sync(idev);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
ucb1400_clear_pending_irq(struct ucb1400_ts * ucb)163*4882a593Smuzhiyun static void ucb1400_clear_pending_irq(struct ucb1400_ts *ucb)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	unsigned int isr;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	isr = ucb1400_reg_read(ucb->ac97, UCB_IE_STATUS);
168*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
169*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	if (isr & UCB_IE_TSPX)
172*4882a593Smuzhiyun 		ucb1400_ts_irq_disable(ucb);
173*4882a593Smuzhiyun 	else
174*4882a593Smuzhiyun 		dev_dbg(&ucb->ts_idev->dev,
175*4882a593Smuzhiyun 			"ucb1400: unexpected IE_STATUS = %#x\n", isr);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /*
179*4882a593Smuzhiyun  * A restriction with interrupts exists when using the ucb1400, as
180*4882a593Smuzhiyun  * the codec read/write routines may sleep while waiting for codec
181*4882a593Smuzhiyun  * access completion and uses semaphores for access control to the
182*4882a593Smuzhiyun  * AC97 bus. Therefore the driver is forced to use threaded interrupt
183*4882a593Smuzhiyun  * handler.
184*4882a593Smuzhiyun  */
ucb1400_irq(int irqnr,void * devid)185*4882a593Smuzhiyun static irqreturn_t ucb1400_irq(int irqnr, void *devid)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = devid;
188*4882a593Smuzhiyun 	unsigned int x, y, p;
189*4882a593Smuzhiyun 	bool penup;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	if (unlikely(irqnr != ucb->irq))
192*4882a593Smuzhiyun 		return IRQ_NONE;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	ucb1400_clear_pending_irq(ucb);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	/* Start with a small delay before checking pendown state */
197*4882a593Smuzhiyun 	msleep(UCB1400_TS_POLL_PERIOD);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	while (!ucb->stopped && !(penup = ucb1400_ts_pen_up(ucb))) {
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 		ucb1400_adc_enable(ucb->ac97);
202*4882a593Smuzhiyun 		x = ucb1400_ts_read_xpos(ucb);
203*4882a593Smuzhiyun 		y = ucb1400_ts_read_ypos(ucb);
204*4882a593Smuzhiyun 		p = ucb1400_ts_read_pressure(ucb);
205*4882a593Smuzhiyun 		ucb1400_adc_disable(ucb->ac97);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 		ucb1400_ts_report_event(ucb->ts_idev, p, x, y);
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 		wait_event_timeout(ucb->ts_wait, ucb->stopped,
210*4882a593Smuzhiyun 				   msecs_to_jiffies(UCB1400_TS_POLL_PERIOD));
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	ucb1400_ts_event_release(ucb->ts_idev);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	if (!ucb->stopped) {
216*4882a593Smuzhiyun 		/* Switch back to interrupt mode. */
217*4882a593Smuzhiyun 		ucb1400_ts_mode_int(ucb);
218*4882a593Smuzhiyun 		ucb1400_ts_irq_enable(ucb);
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	return IRQ_HANDLED;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
ucb1400_ts_stop(struct ucb1400_ts * ucb)224*4882a593Smuzhiyun static void ucb1400_ts_stop(struct ucb1400_ts *ucb)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun 	/* Signal IRQ thread to stop polling and disable the handler. */
227*4882a593Smuzhiyun 	ucb->stopped = true;
228*4882a593Smuzhiyun 	mb();
229*4882a593Smuzhiyun 	wake_up(&ucb->ts_wait);
230*4882a593Smuzhiyun 	disable_irq(ucb->irq);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	ucb1400_ts_irq_disable(ucb);
233*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_TS_CR, 0);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /* Must be called with ts->lock held */
ucb1400_ts_start(struct ucb1400_ts * ucb)237*4882a593Smuzhiyun static void ucb1400_ts_start(struct ucb1400_ts *ucb)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun 	/* Tell IRQ thread that it may poll the device. */
240*4882a593Smuzhiyun 	ucb->stopped = false;
241*4882a593Smuzhiyun 	mb();
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	ucb1400_ts_mode_int(ucb);
244*4882a593Smuzhiyun 	ucb1400_ts_irq_enable(ucb);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	enable_irq(ucb->irq);
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
ucb1400_ts_open(struct input_dev * idev)249*4882a593Smuzhiyun static int ucb1400_ts_open(struct input_dev *idev)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = input_get_drvdata(idev);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	ucb1400_ts_start(ucb);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	return 0;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
ucb1400_ts_close(struct input_dev * idev)258*4882a593Smuzhiyun static void ucb1400_ts_close(struct input_dev *idev)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = input_get_drvdata(idev);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	ucb1400_ts_stop(ucb);
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun #ifndef NO_IRQ
266*4882a593Smuzhiyun #define NO_IRQ	0
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun /*
270*4882a593Smuzhiyun  * Try to probe our interrupt, rather than relying on lots of
271*4882a593Smuzhiyun  * hard-coded machine dependencies.
272*4882a593Smuzhiyun  */
ucb1400_ts_detect_irq(struct ucb1400_ts * ucb,struct platform_device * pdev)273*4882a593Smuzhiyun static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb,
274*4882a593Smuzhiyun 					   struct platform_device *pdev)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	unsigned long mask, timeout;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	mask = probe_irq_on();
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	/* Enable the ADC interrupt. */
281*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, UCB_IE_ADC);
282*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_ADC);
283*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
284*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	/* Cause an ADC interrupt. */
287*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA);
288*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	/* Wait for the conversion to complete. */
291*4882a593Smuzhiyun 	timeout = jiffies + HZ/2;
292*4882a593Smuzhiyun 	while (!(ucb1400_reg_read(ucb->ac97, UCB_ADC_DATA) &
293*4882a593Smuzhiyun 						UCB_ADC_DAT_VALID)) {
294*4882a593Smuzhiyun 		cpu_relax();
295*4882a593Smuzhiyun 		if (time_after(jiffies, timeout)) {
296*4882a593Smuzhiyun 			dev_err(&pdev->dev, "timed out in IRQ probe\n");
297*4882a593Smuzhiyun 			probe_irq_off(mask);
298*4882a593Smuzhiyun 			return -ENODEV;
299*4882a593Smuzhiyun 		}
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, 0);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	/* Disable and clear interrupt. */
304*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, 0);
305*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
306*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
307*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	/* Read triggered interrupt. */
310*4882a593Smuzhiyun 	ucb->irq = probe_irq_off(mask);
311*4882a593Smuzhiyun 	if (ucb->irq < 0 || ucb->irq == NO_IRQ)
312*4882a593Smuzhiyun 		return -ENODEV;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	return 0;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
ucb1400_ts_probe(struct platform_device * pdev)317*4882a593Smuzhiyun static int ucb1400_ts_probe(struct platform_device *pdev)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = dev_get_platdata(&pdev->dev);
320*4882a593Smuzhiyun 	int error, x_res, y_res;
321*4882a593Smuzhiyun 	u16 fcsr;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	ucb->ts_idev = input_allocate_device();
324*4882a593Smuzhiyun 	if (!ucb->ts_idev) {
325*4882a593Smuzhiyun 		error = -ENOMEM;
326*4882a593Smuzhiyun 		goto err;
327*4882a593Smuzhiyun 	}
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/* Only in case the IRQ line wasn't supplied, try detecting it */
330*4882a593Smuzhiyun 	if (ucb->irq < 0) {
331*4882a593Smuzhiyun 		error = ucb1400_ts_detect_irq(ucb, pdev);
332*4882a593Smuzhiyun 		if (error) {
333*4882a593Smuzhiyun 			dev_err(&pdev->dev, "IRQ probe failed\n");
334*4882a593Smuzhiyun 			goto err_free_devs;
335*4882a593Smuzhiyun 		}
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "found IRQ %d\n", ucb->irq);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	init_waitqueue_head(&ucb->ts_wait);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	input_set_drvdata(ucb->ts_idev, ucb);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	ucb->ts_idev->dev.parent	= &pdev->dev;
344*4882a593Smuzhiyun 	ucb->ts_idev->name		= "UCB1400 touchscreen interface";
345*4882a593Smuzhiyun 	ucb->ts_idev->id.vendor		= ucb1400_reg_read(ucb->ac97,
346*4882a593Smuzhiyun 						AC97_VENDOR_ID1);
347*4882a593Smuzhiyun 	ucb->ts_idev->id.product	= ucb->id;
348*4882a593Smuzhiyun 	ucb->ts_idev->open		= ucb1400_ts_open;
349*4882a593Smuzhiyun 	ucb->ts_idev->close		= ucb1400_ts_close;
350*4882a593Smuzhiyun 	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
351*4882a593Smuzhiyun 	ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	/*
354*4882a593Smuzhiyun 	 * Enable ADC filter to prevent horrible jitter on Colibri.
355*4882a593Smuzhiyun 	 * This also further reduces jitter on boards where ADCSYNC
356*4882a593Smuzhiyun 	 * pin is connected.
357*4882a593Smuzhiyun 	 */
358*4882a593Smuzhiyun 	fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
359*4882a593Smuzhiyun 	ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	ucb1400_adc_enable(ucb->ac97);
362*4882a593Smuzhiyun 	x_res = ucb1400_ts_read_xres(ucb);
363*4882a593Smuzhiyun 	y_res = ucb1400_ts_read_yres(ucb);
364*4882a593Smuzhiyun 	ucb1400_adc_disable(ucb->ac97);
365*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "x/y = %d/%d\n", x_res, y_res);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
368*4882a593Smuzhiyun 	input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
369*4882a593Smuzhiyun 	input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	ucb1400_ts_stop(ucb);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	error = request_threaded_irq(ucb->irq, NULL, ucb1400_irq,
374*4882a593Smuzhiyun 				     IRQF_TRIGGER_RISING | IRQF_ONESHOT,
375*4882a593Smuzhiyun 				     "UCB1400", ucb);
376*4882a593Smuzhiyun 	if (error) {
377*4882a593Smuzhiyun 		dev_err(&pdev->dev,
378*4882a593Smuzhiyun 			"unable to grab irq%d: %d\n", ucb->irq, error);
379*4882a593Smuzhiyun 		goto err_free_devs;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	error = input_register_device(ucb->ts_idev);
383*4882a593Smuzhiyun 	if (error)
384*4882a593Smuzhiyun 		goto err_free_irq;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	return 0;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun err_free_irq:
389*4882a593Smuzhiyun 	free_irq(ucb->irq, ucb);
390*4882a593Smuzhiyun err_free_devs:
391*4882a593Smuzhiyun 	input_free_device(ucb->ts_idev);
392*4882a593Smuzhiyun err:
393*4882a593Smuzhiyun 	return error;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
ucb1400_ts_remove(struct platform_device * pdev)396*4882a593Smuzhiyun static int ucb1400_ts_remove(struct platform_device *pdev)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = dev_get_platdata(&pdev->dev);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	free_irq(ucb->irq, ucb);
401*4882a593Smuzhiyun 	input_unregister_device(ucb->ts_idev);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	return 0;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
ucb1400_ts_suspend(struct device * dev)406*4882a593Smuzhiyun static int __maybe_unused ucb1400_ts_suspend(struct device *dev)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = dev_get_platdata(dev);
409*4882a593Smuzhiyun 	struct input_dev *idev = ucb->ts_idev;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	mutex_lock(&idev->mutex);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if (idev->users)
414*4882a593Smuzhiyun 		ucb1400_ts_stop(ucb);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	mutex_unlock(&idev->mutex);
417*4882a593Smuzhiyun 	return 0;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun 
ucb1400_ts_resume(struct device * dev)420*4882a593Smuzhiyun static int __maybe_unused ucb1400_ts_resume(struct device *dev)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	struct ucb1400_ts *ucb = dev_get_platdata(dev);
423*4882a593Smuzhiyun 	struct input_dev *idev = ucb->ts_idev;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	mutex_lock(&idev->mutex);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	if (idev->users)
428*4882a593Smuzhiyun 		ucb1400_ts_start(ucb);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	mutex_unlock(&idev->mutex);
431*4882a593Smuzhiyun 	return 0;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(ucb1400_ts_pm_ops,
435*4882a593Smuzhiyun 			 ucb1400_ts_suspend, ucb1400_ts_resume);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun static struct platform_driver ucb1400_ts_driver = {
438*4882a593Smuzhiyun 	.probe	= ucb1400_ts_probe,
439*4882a593Smuzhiyun 	.remove	= ucb1400_ts_remove,
440*4882a593Smuzhiyun 	.driver	= {
441*4882a593Smuzhiyun 		.name	= "ucb1400_ts",
442*4882a593Smuzhiyun 		.pm	= &ucb1400_ts_pm_ops,
443*4882a593Smuzhiyun 	},
444*4882a593Smuzhiyun };
445*4882a593Smuzhiyun module_platform_driver(ucb1400_ts_driver);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun module_param(adcsync, bool, 0444);
448*4882a593Smuzhiyun MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun module_param(ts_delay, int, 0444);
451*4882a593Smuzhiyun MODULE_PARM_DESC(ts_delay, "Delay between panel setup and"
452*4882a593Smuzhiyun 			    " position read. Default = 55us.");
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun module_param(ts_delay_pressure, int, 0444);
455*4882a593Smuzhiyun MODULE_PARM_DESC(ts_delay_pressure,
456*4882a593Smuzhiyun 		"delay between panel setup and pressure read."
457*4882a593Smuzhiyun 		"  Default = 0us.");
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun MODULE_DESCRIPTION("Philips UCB1400 touchscreen driver");
460*4882a593Smuzhiyun MODULE_LICENSE("GPL");
461