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