ucbtp.c revision 1.4.6.2 1 1.4.6.2 bouyer /* $NetBSD: ucbtp.c,v 1.4.6.2 2000/11/20 20:46:22 bouyer Exp $ */
2 1.4.6.2 bouyer
3 1.4.6.2 bouyer /*-
4 1.4.6.2 bouyer * Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved.
5 1.4.6.2 bouyer *
6 1.4.6.2 bouyer * Redistribution and use in source and binary forms, with or without
7 1.4.6.2 bouyer * modification, are permitted provided that the following conditions
8 1.4.6.2 bouyer * are met:
9 1.4.6.2 bouyer * 1. Redistributions of source code must retain the above copyright
10 1.4.6.2 bouyer * notice, this list of conditions and the following disclaimer.
11 1.4.6.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
12 1.4.6.2 bouyer * notice, this list of conditions and the following disclaimer in the
13 1.4.6.2 bouyer * documentation and/or other materials provided with the distribution.
14 1.4.6.2 bouyer * 3. The name of the author may not be used to endorse or promote products
15 1.4.6.2 bouyer * derived from this software without specific prior written permission.
16 1.4.6.2 bouyer *
17 1.4.6.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 1.4.6.2 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 1.4.6.2 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 1.4.6.2 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 1.4.6.2 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 1.4.6.2 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 1.4.6.2 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 1.4.6.2 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 1.4.6.2 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 1.4.6.2 bouyer * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 1.4.6.2 bouyer */
28 1.4.6.2 bouyer
29 1.4.6.2 bouyer /*
30 1.4.6.2 bouyer * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
31 1.4.6.2 bouyer * Touch panel part.
32 1.4.6.2 bouyer */
33 1.4.6.2 bouyer #define UCBTPDEBUG
34 1.4.6.2 bouyer
35 1.4.6.2 bouyer #include "opt_tx39_debug.h"
36 1.4.6.2 bouyer #include "opt_use_poll.h"
37 1.4.6.2 bouyer
38 1.4.6.2 bouyer #include <sys/param.h>
39 1.4.6.2 bouyer #include <sys/systm.h>
40 1.4.6.2 bouyer #include <sys/device.h>
41 1.4.6.2 bouyer
42 1.4.6.2 bouyer #include <machine/bus.h>
43 1.4.6.2 bouyer #include <machine/intr.h>
44 1.4.6.2 bouyer #include <machine/bootinfo.h> /* bootinfo */
45 1.4.6.2 bouyer
46 1.4.6.2 bouyer #include <dev/wscons/wsconsio.h>
47 1.4.6.2 bouyer #include <dev/wscons/wsmousevar.h>
48 1.4.6.2 bouyer
49 1.4.6.2 bouyer #include <hpcmips/dev/tpcalibvar.h>
50 1.4.6.2 bouyer
51 1.4.6.2 bouyer #include <hpcmips/tx/tx39var.h>
52 1.4.6.2 bouyer #include <hpcmips/tx/tx39sibvar.h>
53 1.4.6.2 bouyer #include <hpcmips/tx/tx39sibreg.h>
54 1.4.6.2 bouyer #include <hpcmips/tx/tx39icureg.h>
55 1.4.6.2 bouyer
56 1.4.6.2 bouyer #include <hpcmips/dev/ucb1200var.h>
57 1.4.6.2 bouyer #include <hpcmips/dev/ucb1200reg.h>
58 1.4.6.2 bouyer
59 1.4.6.2 bouyer #include <hpcmips/tx/txsnd.h>
60 1.4.6.2 bouyer #include <hpcmips/dev/video_subr.h> /* debug */
61 1.4.6.2 bouyer
62 1.4.6.2 bouyer #ifdef UCBTPDEBUG
63 1.4.6.2 bouyer int ucbtp_debug = 0;
64 1.4.6.2 bouyer #define DPRINTF(arg) if (ucbtp_debug) printf arg;
65 1.4.6.2 bouyer #define DPRINTFN(n, arg) if (ucbtp_debug > (n)) printf arg;
66 1.4.6.2 bouyer #else
67 1.4.6.2 bouyer #define DPRINTF(arg)
68 1.4.6.2 bouyer #define DPRINTFN(n, arg)
69 1.4.6.2 bouyer #endif
70 1.4.6.2 bouyer
71 1.4.6.2 bouyer enum ucbts_stat {
72 1.4.6.2 bouyer UCBTS_STAT_DISABLE,
73 1.4.6.2 bouyer UCBTS_STAT_RELEASE,
74 1.4.6.2 bouyer UCBTS_STAT_TOUCH,
75 1.4.6.2 bouyer UCBTS_STAT_DRAG,
76 1.4.6.2 bouyer };
77 1.4.6.2 bouyer
78 1.4.6.2 bouyer #define UCBTS_POSX 1
79 1.4.6.2 bouyer #define UCBTS_POSY 2
80 1.4.6.2 bouyer #define UCBTS_PRESS 3
81 1.4.6.2 bouyer
82 1.4.6.2 bouyer #define UCBTS_PRESS_THRESHOLD 80
83 1.4.6.2 bouyer #define UCBTS_TAP_THRESHOLD 5
84 1.4.6.2 bouyer
85 1.4.6.2 bouyer enum ucbadc_state {
86 1.4.6.2 bouyer /* 0 */ UCBADC_IDLE,
87 1.4.6.2 bouyer /* 1 */ UCBADC_ADC_INIT,
88 1.4.6.2 bouyer /* 2 */ UCBADC_ADC_FINI,
89 1.4.6.2 bouyer /* 3 */ UCBADC_MEASUMENT_INIT,
90 1.4.6.2 bouyer /* 4 */ UCBADC_MEASUMENT_FINI,
91 1.4.6.2 bouyer /* 5 */ UCBADC_ADC_ENABLE,
92 1.4.6.2 bouyer /* 6 */ UCBADC_ADC_START0,
93 1.4.6.2 bouyer /* 7 */ UCBADC_ADC_START1,
94 1.4.6.2 bouyer /* 8 */ UCBADC_ADC_DATAREAD,
95 1.4.6.2 bouyer /* 9 */ UCBADC_ADC_DATAREAD_WAIT,
96 1.4.6.2 bouyer /*10 */ UCBADC_ADC_DISABLE,
97 1.4.6.2 bouyer /*11 */ UCBADC_ADC_INTRMODE,
98 1.4.6.2 bouyer /*12 */ UCBADC_ADC_INPUT,
99 1.4.6.2 bouyer /*13 */ UCBADC_INTR_ACK0,
100 1.4.6.2 bouyer /*14 */ UCBADC_INTR_ACK1,
101 1.4.6.2 bouyer /*15 */ UCBADC_INTR_ACK2,
102 1.4.6.2 bouyer /*16 */ UCBADC_REGREAD,
103 1.4.6.2 bouyer /*17 */ UCBADC_REGWRITE
104 1.4.6.2 bouyer };
105 1.4.6.2 bouyer
106 1.4.6.2 bouyer struct ucbtp_softc {
107 1.4.6.2 bouyer struct device sc_dev;
108 1.4.6.2 bouyer struct device *sc_sib; /* parent (TX39 SIB module) */
109 1.4.6.2 bouyer struct device *sc_ucb; /* parent (UCB1200 module) */
110 1.4.6.2 bouyer tx_chipset_tag_t sc_tc;
111 1.4.6.2 bouyer
112 1.4.6.2 bouyer enum ucbts_stat sc_stat;
113 1.4.6.2 bouyer int sc_polling;
114 1.4.6.2 bouyer int sc_polling_finish;
115 1.4.6.2 bouyer void *sc_pollh;
116 1.4.6.2 bouyer
117 1.4.6.2 bouyer struct tpcalib_softc sc_tpcalib;
118 1.4.6.2 bouyer int sc_calibrated;
119 1.4.6.2 bouyer
120 1.4.6.2 bouyer /* measurement value */
121 1.4.6.2 bouyer int sc_x, sc_y, sc_p;
122 1.4.6.2 bouyer int sc_ox, sc_oy;
123 1.4.6.2 bouyer int sc_xy_reverse; /* some platform pin connect interchanged */
124 1.4.6.2 bouyer
125 1.4.6.2 bouyer /*
126 1.4.6.2 bouyer * touch panel state machine
127 1.4.6.2 bouyer */
128 1.4.6.2 bouyer void *sm_ih; /* TX39 SIB subframe 0 interrupt handler */
129 1.4.6.2 bouyer
130 1.4.6.2 bouyer int sm_addr; /* UCB1200 register address */
131 1.4.6.2 bouyer u_int32_t sm_reg; /* UCB1200 register data & TX39 SIB header */
132 1.4.6.2 bouyer int sm_tmpreg;
133 1.4.6.2 bouyer #define UCBADC_RETRY_DEFAULT 200
134 1.4.6.2 bouyer int sm_retry; /* retry counter */
135 1.4.6.2 bouyer
136 1.4.6.2 bouyer enum ucbadc_state sm_state;
137 1.4.6.2 bouyer int sm_measurement; /* X, Y, Pressure */
138 1.4.6.2 bouyer #define UCBADC_MEASUREMENT_X 0
139 1.4.6.2 bouyer #define UCBADC_MEASUREMENT_Y 1
140 1.4.6.2 bouyer #define UCBADC_MEASUREMENT_PRESSURE 2
141 1.4.6.2 bouyer int sm_returnstate;
142 1.4.6.2 bouyer
143 1.4.6.2 bouyer int sm_read_state, sm_write_state;
144 1.4.6.2 bouyer int sm_writing; /* writing state flag */
145 1.4.6.2 bouyer u_int32_t sm_write_val; /* temporary buffer */
146 1.4.6.2 bouyer
147 1.4.6.2 bouyer int sm_rw_retry; /* retry counter for r/w */
148 1.4.6.2 bouyer
149 1.4.6.2 bouyer /* wsmouse */
150 1.4.6.2 bouyer struct device *sc_wsmousedev;
151 1.4.6.2 bouyer };
152 1.4.6.2 bouyer
153 1.4.6.2 bouyer int ucbtp_match __P((struct device*, struct cfdata*, void*));
154 1.4.6.2 bouyer void ucbtp_attach __P((struct device*, struct device*, void*));
155 1.4.6.2 bouyer
156 1.4.6.2 bouyer int ucbtp_sibintr __P((void*));
157 1.4.6.2 bouyer int ucbtp_poll __P((void*));
158 1.4.6.2 bouyer int ucbtp_adc_async __P((void*));
159 1.4.6.2 bouyer int ucbtp_input __P((struct ucbtp_softc*));
160 1.4.6.2 bouyer int ucbtp_busy __P((void*));
161 1.4.6.2 bouyer
162 1.4.6.2 bouyer int ucbtp_enable __P((void*));
163 1.4.6.2 bouyer int ucbtp_ioctl __P((void*, u_long, caddr_t, int, struct proc*));
164 1.4.6.2 bouyer void ucbtp_disable __P((void*));
165 1.4.6.2 bouyer
166 1.4.6.2 bouyer struct cfattach ucbtp_ca = {
167 1.4.6.2 bouyer sizeof(struct ucbtp_softc), ucbtp_match, ucbtp_attach
168 1.4.6.2 bouyer };
169 1.4.6.2 bouyer
170 1.4.6.2 bouyer const struct wsmouse_accessops ucbtp_accessops = {
171 1.4.6.2 bouyer ucbtp_enable,
172 1.4.6.2 bouyer ucbtp_ioctl,
173 1.4.6.2 bouyer ucbtp_disable,
174 1.4.6.2 bouyer };
175 1.4.6.2 bouyer
176 1.4.6.2 bouyer /*
177 1.4.6.2 bouyer * XXX currently no calibration method. this is temporary hack.
178 1.4.6.2 bouyer */
179 1.4.6.2 bouyer #include <machine/platid.h>
180 1.4.6.2 bouyer
181 1.4.6.2 bouyer struct wsmouse_calibcoords *calibration_sample_lookup __P((void));
182 1.4.6.2 bouyer int ucbtp_calibration __P((struct ucbtp_softc*));
183 1.4.6.2 bouyer
184 1.4.6.2 bouyer struct calibration_sample_table {
185 1.4.6.2 bouyer platid_t cst_platform;
186 1.4.6.2 bouyer struct wsmouse_calibcoords cst_sample;
187 1.4.6.2 bouyer } calibration_sample_table[] = {
188 1.4.6.2 bouyer {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}}, /* uch machine */
189 1.4.6.2 bouyer { 0, 0, 639, 239, 5,
190 1.4.6.2 bouyer {{ 507, 510, 320, 120 },
191 1.4.6.2 bouyer { 898, 757, 40, 40 },
192 1.4.6.2 bouyer { 900, 255, 40, 200 },
193 1.4.6.2 bouyer { 109, 249, 600, 200 },
194 1.4.6.2 bouyer { 110, 753, 600, 40 }}}},
195 1.4.6.2 bouyer
196 1.4.6.2 bouyer {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */
197 1.4.6.2 bouyer { 0, 0, 639, 239, 5,
198 1.4.6.2 bouyer {{ 506, 487, 320, 120 },
199 1.4.6.2 bouyer { 880, 250, 40, 40 },
200 1.4.6.2 bouyer { 880, 718, 40, 200 },
201 1.4.6.2 bouyer { 140, 726, 600, 200 },
202 1.4.6.2 bouyer { 137, 250, 600, 40 }}}},
203 1.4.6.2 bouyer
204 1.4.6.2 bouyer {{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */
205 1.4.6.2 bouyer { 0, 0, 639, 239, 5,
206 1.4.6.2 bouyer {{ 497, 501, 320, 120 },
207 1.4.6.2 bouyer { 752, 893, 40, 40 },
208 1.4.6.2 bouyer { 242, 891, 40, 200 },
209 1.4.6.2 bouyer { 241, 115, 600, 200 },
210 1.4.6.2 bouyer { 747, 101, 600, 40 }}}},
211 1.4.6.2 bouyer
212 1.4.6.2 bouyer {{{PLATID_WILD, PLATID_MACH_SHARP_TELIOS_HCAJ1}}, /* uch machine */
213 1.4.6.2 bouyer { 0, 0, 799, 479, 5,
214 1.4.6.2 bouyer {{ 850, 150, 1, 1 },
215 1.4.6.2 bouyer { 850, 880, 1, 479 },
216 1.4.6.2 bouyer { 850, 880, 1, 479 },
217 1.4.6.2 bouyer { 85, 880, 799, 479 },
218 1.4.6.2 bouyer { 85, 150, 799, 1 }}}},
219 1.4.6.2 bouyer
220 1.4.6.2 bouyer {{{PLATID_UNKNOWN, PLATID_UNKNOWN}},
221 1.4.6.2 bouyer { 0, 0, 639, 239, 5,
222 1.4.6.2 bouyer {{0, 0, 0, 0},
223 1.4.6.2 bouyer {0, 0, 0, 0},
224 1.4.6.2 bouyer {0, 0, 0, 0},
225 1.4.6.2 bouyer {0, 0, 0, 0},
226 1.4.6.2 bouyer {0, 0, 0, 0}}}},
227 1.4.6.2 bouyer };
228 1.4.6.2 bouyer
229 1.4.6.2 bouyer struct wsmouse_calibcoords *
230 1.4.6.2 bouyer calibration_sample_lookup()
231 1.4.6.2 bouyer {
232 1.4.6.2 bouyer struct calibration_sample_table *tab;
233 1.4.6.2 bouyer platid_mask_t mask;
234 1.4.6.2 bouyer
235 1.4.6.2 bouyer for (tab = calibration_sample_table;
236 1.4.6.2 bouyer tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
237 1.4.6.2 bouyer
238 1.4.6.2 bouyer mask = PLATID_DEREF(&tab->cst_platform);
239 1.4.6.2 bouyer
240 1.4.6.2 bouyer if (platid_match(&platid, &mask)) {
241 1.4.6.2 bouyer return (&tab->cst_sample);
242 1.4.6.2 bouyer }
243 1.4.6.2 bouyer }
244 1.4.6.2 bouyer
245 1.4.6.2 bouyer return (0);
246 1.4.6.2 bouyer }
247 1.4.6.2 bouyer
248 1.4.6.2 bouyer int
249 1.4.6.2 bouyer ucbtp_calibration(sc)
250 1.4.6.2 bouyer struct ucbtp_softc *sc;
251 1.4.6.2 bouyer {
252 1.4.6.2 bouyer struct wsmouse_calibcoords *cs;
253 1.4.6.2 bouyer
254 1.4.6.2 bouyer if (sc->sc_tc->tc_videot)
255 1.4.6.2 bouyer video_calibration_pattern(sc->sc_tc->tc_videot); /* debug */
256 1.4.6.2 bouyer
257 1.4.6.2 bouyer tpcalib_init(&sc->sc_tpcalib);
258 1.4.6.2 bouyer
259 1.4.6.2 bouyer if (!(cs = calibration_sample_lookup())) {
260 1.4.6.2 bouyer DPRINTF(("no calibration data"));
261 1.4.6.2 bouyer return (1);
262 1.4.6.2 bouyer }
263 1.4.6.2 bouyer
264 1.4.6.2 bouyer sc->sc_calibrated =
265 1.4.6.2 bouyer tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
266 1.4.6.2 bouyer (caddr_t)cs, 0, 0) == 0 ? 1 : 0;
267 1.4.6.2 bouyer
268 1.4.6.2 bouyer if (!sc->sc_calibrated)
269 1.4.6.2 bouyer printf("not ");
270 1.4.6.2 bouyer printf("calibrated");
271 1.4.6.2 bouyer
272 1.4.6.2 bouyer return (0);
273 1.4.6.2 bouyer }
274 1.4.6.2 bouyer
275 1.4.6.2 bouyer int
276 1.4.6.2 bouyer ucbtp_match(parent, cf, aux)
277 1.4.6.2 bouyer struct device *parent;
278 1.4.6.2 bouyer struct cfdata *cf;
279 1.4.6.2 bouyer void *aux;
280 1.4.6.2 bouyer {
281 1.4.6.2 bouyer return (1);
282 1.4.6.2 bouyer }
283 1.4.6.2 bouyer
284 1.4.6.2 bouyer void
285 1.4.6.2 bouyer ucbtp_attach(parent, self, aux)
286 1.4.6.2 bouyer struct device *parent;
287 1.4.6.2 bouyer struct device *self;
288 1.4.6.2 bouyer void *aux;
289 1.4.6.2 bouyer {
290 1.4.6.2 bouyer struct ucb1200_attach_args *ucba = aux;
291 1.4.6.2 bouyer struct ucbtp_softc *sc = (void*)self;
292 1.4.6.2 bouyer struct wsmousedev_attach_args wsmaa;
293 1.4.6.2 bouyer tx_chipset_tag_t tc;
294 1.4.6.2 bouyer
295 1.4.6.2 bouyer tc = sc->sc_tc = ucba->ucba_tc;
296 1.4.6.2 bouyer sc->sc_sib = ucba->ucba_sib;
297 1.4.6.2 bouyer sc->sc_ucb = ucba->ucba_ucb;
298 1.4.6.2 bouyer
299 1.4.6.2 bouyer printf(": ");
300 1.4.6.2 bouyer /* touch panel interrupt */
301 1.4.6.2 bouyer tx_intr_establish(tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
302 1.4.6.2 bouyer IST_EDGE, IPL_TTY, ucbtp_sibintr, sc);
303 1.4.6.2 bouyer
304 1.4.6.2 bouyer /* attempt to calibrate touch panel */
305 1.4.6.2 bouyer ucbtp_calibration(sc);
306 1.4.6.2 bouyer #ifdef TX392X /* hack for Telios HC-VJ1C */
307 1.4.6.2 bouyer sc->sc_xy_reverse = 1;
308 1.4.6.2 bouyer #endif
309 1.4.6.2 bouyer
310 1.4.6.2 bouyer printf("\n");
311 1.4.6.2 bouyer
312 1.4.6.2 bouyer wsmaa.accessops = &ucbtp_accessops;
313 1.4.6.2 bouyer wsmaa.accesscookie = sc;
314 1.4.6.2 bouyer
315 1.4.6.2 bouyer ucb1200_state_install(parent, ucbtp_busy, self, UCB1200_TP_MODULE);
316 1.4.6.2 bouyer
317 1.4.6.2 bouyer /*
318 1.4.6.2 bouyer * attach the wsmouse
319 1.4.6.2 bouyer */
320 1.4.6.2 bouyer sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
321 1.4.6.2 bouyer }
322 1.4.6.2 bouyer
323 1.4.6.2 bouyer int
324 1.4.6.2 bouyer ucbtp_busy(arg)
325 1.4.6.2 bouyer void *arg;
326 1.4.6.2 bouyer {
327 1.4.6.2 bouyer struct ucbtp_softc *sc = arg;
328 1.4.6.2 bouyer
329 1.4.6.2 bouyer return (sc->sm_state != UCBADC_IDLE);
330 1.4.6.2 bouyer }
331 1.4.6.2 bouyer
332 1.4.6.2 bouyer int
333 1.4.6.2 bouyer ucbtp_poll(arg)
334 1.4.6.2 bouyer void *arg;
335 1.4.6.2 bouyer {
336 1.4.6.2 bouyer struct ucbtp_softc *sc = arg;
337 1.4.6.2 bouyer
338 1.4.6.2 bouyer if (!ucb1200_state_idle(sc->sc_ucb)) /* subframe0 busy */
339 1.4.6.2 bouyer return (POLL_CONT);
340 1.4.6.2 bouyer
341 1.4.6.2 bouyer if (sc->sc_polling_finish) {
342 1.4.6.2 bouyer sc->sc_polling_finish = 0;
343 1.4.6.2 bouyer return (POLL_END);
344 1.4.6.2 bouyer }
345 1.4.6.2 bouyer
346 1.4.6.2 bouyer /* execute A-D converter */
347 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_INIT;
348 1.4.6.2 bouyer ucbtp_adc_async(sc);
349 1.4.6.2 bouyer
350 1.4.6.2 bouyer return (POLL_CONT);
351 1.4.6.2 bouyer }
352 1.4.6.2 bouyer
353 1.4.6.2 bouyer int
354 1.4.6.2 bouyer ucbtp_sibintr(arg)
355 1.4.6.2 bouyer void *arg;
356 1.4.6.2 bouyer {
357 1.4.6.2 bouyer struct ucbtp_softc *sc = arg;
358 1.4.6.2 bouyer
359 1.4.6.2 bouyer sc->sc_stat = UCBTS_STAT_TOUCH;
360 1.4.6.2 bouyer
361 1.4.6.2 bouyer /* click! */
362 1.4.6.2 bouyer tx_sound_click(sc->sc_tc);
363 1.4.6.2 bouyer
364 1.4.6.2 bouyer /* invoke touch panel polling */
365 1.4.6.2 bouyer if (!sc->sc_polling) {
366 1.4.6.2 bouyer sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
367 1.4.6.2 bouyer ucbtp_poll, sc);
368 1.4.6.2 bouyer if (!sc->sc_pollh) {
369 1.4.6.2 bouyer printf("%s: can't poll\n", sc->sc_dev.dv_xname);
370 1.4.6.2 bouyer }
371 1.4.6.2 bouyer }
372 1.4.6.2 bouyer
373 1.4.6.2 bouyer /* don't acknoledge interrupt until polling finish */
374 1.4.6.2 bouyer
375 1.4.6.2 bouyer return (0);
376 1.4.6.2 bouyer }
377 1.4.6.2 bouyer
378 1.4.6.2 bouyer #define REGWRITE(addr, reg, ret) ( \
379 1.4.6.2 bouyer sc->sm_addr = (addr), \
380 1.4.6.2 bouyer sc->sm_reg = (reg), \
381 1.4.6.2 bouyer sc->sm_returnstate = (ret), \
382 1.4.6.2 bouyer sc->sm_state = UCBADC_REGWRITE)
383 1.4.6.2 bouyer #define REGREAD(addr, ret) ( \
384 1.4.6.2 bouyer sc->sm_addr = (addr), \
385 1.4.6.2 bouyer sc->sm_returnstate = (ret), \
386 1.4.6.2 bouyer sc->sm_state = UCBADC_REGREAD)
387 1.4.6.2 bouyer
388 1.4.6.2 bouyer int
389 1.4.6.2 bouyer ucbtp_adc_async(arg)
390 1.4.6.2 bouyer void *arg;
391 1.4.6.2 bouyer {
392 1.4.6.2 bouyer struct ucbtp_softc *sc = arg;
393 1.4.6.2 bouyer tx_chipset_tag_t tc = sc->sc_tc;
394 1.4.6.2 bouyer txreg_t reg;
395 1.4.6.2 bouyer u_int16_t reg16;
396 1.4.6.2 bouyer
397 1.4.6.2 bouyer DPRINTFN(9, ("state: %d\n", sc->sm_state));
398 1.4.6.2 bouyer
399 1.4.6.2 bouyer switch (sc->sm_state) {
400 1.4.6.2 bouyer default:
401 1.4.6.2 bouyer panic("ucbtp_adc: invalid state %d", sc->sm_state);
402 1.4.6.2 bouyer /* NOTREACHED */
403 1.4.6.2 bouyer break;
404 1.4.6.2 bouyer
405 1.4.6.2 bouyer case UCBADC_IDLE:
406 1.4.6.2 bouyer /* nothing to do */
407 1.4.6.2 bouyer break;
408 1.4.6.2 bouyer
409 1.4.6.2 bouyer case UCBADC_ADC_INIT:
410 1.4.6.2 bouyer sc->sc_polling++;
411 1.4.6.2 bouyer sc->sc_stat = UCBTS_STAT_DRAG;
412 1.4.6.2 bouyer /* enable heart beat of this state machine */
413 1.4.6.2 bouyer sc->sm_ih = tx_intr_establish(
414 1.4.6.2 bouyer tc,
415 1.4.6.2 bouyer MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
416 1.4.6.2 bouyer IST_EDGE, IPL_TTY, ucbtp_adc_async, sc);
417 1.4.6.2 bouyer
418 1.4.6.2 bouyer sc->sm_state = UCBADC_MEASUMENT_INIT;
419 1.4.6.2 bouyer break;
420 1.4.6.2 bouyer
421 1.4.6.2 bouyer case UCBADC_ADC_FINI:
422 1.4.6.2 bouyer /* disable heart beat of this state machine */
423 1.4.6.2 bouyer tx_intr_disestablish(tc, sc->sm_ih);
424 1.4.6.2 bouyer sc->sm_state = UCBADC_IDLE;
425 1.4.6.2 bouyer break;
426 1.4.6.2 bouyer
427 1.4.6.2 bouyer case UCBADC_MEASUMENT_INIT:
428 1.4.6.2 bouyer switch (sc->sm_measurement) {
429 1.4.6.2 bouyer default:
430 1.4.6.2 bouyer panic("unknown measurement spec.");
431 1.4.6.2 bouyer /* NOTREACHED */
432 1.4.6.2 bouyer break;
433 1.4.6.2 bouyer case UCBADC_MEASUREMENT_X:
434 1.4.6.2 bouyer REGWRITE(UCB1200_TSCTRL_REG,
435 1.4.6.2 bouyer UCB1200_TSCTRL_XPOSITION,
436 1.4.6.2 bouyer UCBADC_ADC_ENABLE);
437 1.4.6.2 bouyer break;
438 1.4.6.2 bouyer case UCBADC_MEASUREMENT_Y:
439 1.4.6.2 bouyer REGWRITE(UCB1200_TSCTRL_REG,
440 1.4.6.2 bouyer UCB1200_TSCTRL_YPOSITION,
441 1.4.6.2 bouyer UCBADC_ADC_ENABLE);
442 1.4.6.2 bouyer break;
443 1.4.6.2 bouyer case UCBADC_MEASUREMENT_PRESSURE:
444 1.4.6.2 bouyer REGWRITE(UCB1200_TSCTRL_REG,
445 1.4.6.2 bouyer UCB1200_TSCTRL_PRESSURE,
446 1.4.6.2 bouyer UCBADC_ADC_ENABLE);
447 1.4.6.2 bouyer break;
448 1.4.6.2 bouyer }
449 1.4.6.2 bouyer break;
450 1.4.6.2 bouyer
451 1.4.6.2 bouyer case UCBADC_MEASUMENT_FINI:
452 1.4.6.2 bouyer switch (sc->sm_measurement) {
453 1.4.6.2 bouyer case UCBADC_MEASUREMENT_X:
454 1.4.6.2 bouyer sc->sm_measurement = UCBADC_MEASUREMENT_Y;
455 1.4.6.2 bouyer sc->sm_state = UCBADC_MEASUMENT_INIT;
456 1.4.6.2 bouyer break;
457 1.4.6.2 bouyer case UCBADC_MEASUREMENT_Y:
458 1.4.6.2 bouyer sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
459 1.4.6.2 bouyer sc->sm_state = UCBADC_MEASUMENT_INIT;
460 1.4.6.2 bouyer break;
461 1.4.6.2 bouyer case UCBADC_MEASUREMENT_PRESSURE:
462 1.4.6.2 bouyer sc->sm_measurement = UCBADC_MEASUREMENT_X;
463 1.4.6.2 bouyer /* measument complete. pass down to wsmouse_input */
464 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_INPUT;
465 1.4.6.2 bouyer break;
466 1.4.6.2 bouyer }
467 1.4.6.2 bouyer break;
468 1.4.6.2 bouyer
469 1.4.6.2 bouyer case UCBADC_ADC_ENABLE:
470 1.4.6.2 bouyer switch (sc->sm_measurement) {
471 1.4.6.2 bouyer case UCBADC_MEASUREMENT_PRESSURE:
472 1.4.6.2 bouyer /* FALLTHROUGH */
473 1.4.6.2 bouyer case UCBADC_MEASUREMENT_X:
474 1.4.6.2 bouyer sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
475 1.4.6.2 bouyer UCB1200_ADCCTRL_ENABLE,
476 1.4.6.2 bouyer UCB1200_ADCCTRL_INPUT_TSPX);
477 1.4.6.2 bouyer REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
478 1.4.6.2 bouyer UCBADC_ADC_START0);
479 1.4.6.2 bouyer break;
480 1.4.6.2 bouyer case UCBADC_MEASUREMENT_Y:
481 1.4.6.2 bouyer sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
482 1.4.6.2 bouyer UCB1200_ADCCTRL_ENABLE,
483 1.4.6.2 bouyer UCB1200_ADCCTRL_INPUT_TSPY);
484 1.4.6.2 bouyer REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
485 1.4.6.2 bouyer UCBADC_ADC_START0);
486 1.4.6.2 bouyer break;
487 1.4.6.2 bouyer }
488 1.4.6.2 bouyer break;
489 1.4.6.2 bouyer
490 1.4.6.2 bouyer case UCBADC_ADC_START0:
491 1.4.6.2 bouyer REGWRITE(UCB1200_ADCCTRL_REG,
492 1.4.6.2 bouyer sc->sm_tmpreg | UCB1200_ADCCTRL_START,
493 1.4.6.2 bouyer UCBADC_ADC_START1);
494 1.4.6.2 bouyer break;
495 1.4.6.2 bouyer
496 1.4.6.2 bouyer case UCBADC_ADC_START1:
497 1.4.6.2 bouyer REGWRITE(UCB1200_ADCCTRL_REG,
498 1.4.6.2 bouyer sc->sm_tmpreg,
499 1.4.6.2 bouyer UCBADC_ADC_DATAREAD);
500 1.4.6.2 bouyer sc->sm_retry = UCBADC_RETRY_DEFAULT;
501 1.4.6.2 bouyer break;
502 1.4.6.2 bouyer
503 1.4.6.2 bouyer case UCBADC_ADC_DATAREAD:
504 1.4.6.2 bouyer REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
505 1.4.6.2 bouyer break;
506 1.4.6.2 bouyer
507 1.4.6.2 bouyer case UCBADC_ADC_DATAREAD_WAIT:
508 1.4.6.2 bouyer reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
509 1.4.6.2 bouyer if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
510 1.4.6.2 bouyer --sc->sm_retry > 0) {
511 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_DATAREAD;
512 1.4.6.2 bouyer } else {
513 1.4.6.2 bouyer if (sc->sm_retry <= 0) {
514 1.4.6.2 bouyer printf("dataread failed\n");
515 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_FINI;
516 1.4.6.2 bouyer break;
517 1.4.6.2 bouyer }
518 1.4.6.2 bouyer
519 1.4.6.2 bouyer switch (sc->sm_measurement) {
520 1.4.6.2 bouyer case UCBADC_MEASUREMENT_X:
521 1.4.6.2 bouyer sc->sc_x = UCB1200_ADCDATA(reg16);
522 1.4.6.2 bouyer DPRINTFN(9, ("x=%d\n", sc->sc_x));
523 1.4.6.2 bouyer break;
524 1.4.6.2 bouyer case UCBADC_MEASUREMENT_Y:
525 1.4.6.2 bouyer sc->sc_y = UCB1200_ADCDATA(reg16);
526 1.4.6.2 bouyer DPRINTFN(9, ("y=%d\n", sc->sc_y));
527 1.4.6.2 bouyer break;
528 1.4.6.2 bouyer case UCBADC_MEASUREMENT_PRESSURE:
529 1.4.6.2 bouyer sc->sc_p = UCB1200_ADCDATA(reg16);
530 1.4.6.2 bouyer DPRINTFN(9, ("p=%d\n", sc->sc_p));
531 1.4.6.2 bouyer break;
532 1.4.6.2 bouyer }
533 1.4.6.2 bouyer
534 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_DISABLE;
535 1.4.6.2 bouyer }
536 1.4.6.2 bouyer
537 1.4.6.2 bouyer break;
538 1.4.6.2 bouyer
539 1.4.6.2 bouyer case UCBADC_ADC_DISABLE:
540 1.4.6.2 bouyer REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
541 1.4.6.2 bouyer
542 1.4.6.2 bouyer break;
543 1.4.6.2 bouyer case UCBADC_ADC_INTRMODE:
544 1.4.6.2 bouyer REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
545 1.4.6.2 bouyer UCBADC_MEASUMENT_FINI);
546 1.4.6.2 bouyer break;
547 1.4.6.2 bouyer
548 1.4.6.2 bouyer case UCBADC_ADC_INPUT:
549 1.4.6.2 bouyer if (ucbtp_input(sc) == 0)
550 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_FINI;
551 1.4.6.2 bouyer else
552 1.4.6.2 bouyer sc->sm_state = UCBADC_INTR_ACK0;
553 1.4.6.2 bouyer break;
554 1.4.6.2 bouyer
555 1.4.6.2 bouyer case UCBADC_INTR_ACK0:
556 1.4.6.2 bouyer REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
557 1.4.6.2 bouyer break;
558 1.4.6.2 bouyer
559 1.4.6.2 bouyer case UCBADC_INTR_ACK1:
560 1.4.6.2 bouyer REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
561 1.4.6.2 bouyer break;
562 1.4.6.2 bouyer
563 1.4.6.2 bouyer case UCBADC_INTR_ACK2:
564 1.4.6.2 bouyer sc->sc_polling_finish = 1;
565 1.4.6.2 bouyer REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
566 1.4.6.2 bouyer break;
567 1.4.6.2 bouyer
568 1.4.6.2 bouyer /*
569 1.4.6.2 bouyer * UCB1200 register access state
570 1.4.6.2 bouyer */
571 1.4.6.2 bouyer case UCBADC_REGREAD:
572 1.4.6.2 bouyer /*
573 1.4.6.2 bouyer * In : sc->sm_addr
574 1.4.6.2 bouyer * Out : sc->sm_reg (with SIBtag)
575 1.4.6.2 bouyer */
576 1.4.6.2 bouyer #define TXSIB_REGREAD_INIT 0
577 1.4.6.2 bouyer #define TXSIB_REGREAD_READ 1
578 1.4.6.2 bouyer switch (sc->sm_read_state) {
579 1.4.6.2 bouyer case TXSIB_REGREAD_INIT:
580 1.4.6.2 bouyer reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
581 1.4.6.2 bouyer tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
582 1.4.6.2 bouyer sc->sm_rw_retry = UCBADC_RETRY_DEFAULT;
583 1.4.6.2 bouyer sc->sm_read_state = TXSIB_REGREAD_READ;
584 1.4.6.2 bouyer break;
585 1.4.6.2 bouyer case TXSIB_REGREAD_READ:
586 1.4.6.2 bouyer reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
587 1.4.6.2 bouyer if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
588 1.4.6.2 bouyer --sc->sm_rw_retry > 0) {
589 1.4.6.2 bouyer break;
590 1.4.6.2 bouyer }
591 1.4.6.2 bouyer
592 1.4.6.2 bouyer if (sc->sm_rw_retry <= 0) {
593 1.4.6.2 bouyer printf("sf0read: command failed\n");
594 1.4.6.2 bouyer sc->sm_state = UCBADC_ADC_FINI;
595 1.4.6.2 bouyer } else {
596 1.4.6.2 bouyer sc->sm_reg = reg;
597 1.4.6.2 bouyer sc->sm_read_state = TXSIB_REGREAD_INIT;
598 1.4.6.2 bouyer DPRINTFN(9, ("%08x\n", reg));
599 1.4.6.2 bouyer if (sc->sm_writing)
600 1.4.6.2 bouyer sc->sm_state = UCBADC_REGWRITE;
601 1.4.6.2 bouyer else
602 1.4.6.2 bouyer sc->sm_state = sc->sm_returnstate;
603 1.4.6.2 bouyer }
604 1.4.6.2 bouyer break;
605 1.4.6.2 bouyer }
606 1.4.6.2 bouyer break;
607 1.4.6.2 bouyer
608 1.4.6.2 bouyer case UCBADC_REGWRITE:
609 1.4.6.2 bouyer /*
610 1.4.6.2 bouyer * In : sc->sm_addr, sc->sm_reg (lower 16bit only)
611 1.4.6.2 bouyer */
612 1.4.6.2 bouyer #define TXSIB_REGWRITE_INIT 0
613 1.4.6.2 bouyer #define TXSIB_REGWRITE_WRITE 1
614 1.4.6.2 bouyer switch (sc->sm_write_state) {
615 1.4.6.2 bouyer case TXSIB_REGWRITE_INIT:
616 1.4.6.2 bouyer sc->sm_writing = 1;
617 1.4.6.2 bouyer sc->sm_write_state = TXSIB_REGWRITE_WRITE;
618 1.4.6.2 bouyer sc->sm_state = UCBADC_REGREAD;
619 1.4.6.2 bouyer
620 1.4.6.2 bouyer sc->sm_write_val = sc->sm_reg;
621 1.4.6.2 bouyer break;
622 1.4.6.2 bouyer case TXSIB_REGWRITE_WRITE:
623 1.4.6.2 bouyer sc->sm_writing = 0;
624 1.4.6.2 bouyer sc->sm_write_state = TXSIB_REGWRITE_INIT;
625 1.4.6.2 bouyer sc->sm_state = sc->sm_returnstate;
626 1.4.6.2 bouyer
627 1.4.6.2 bouyer reg = sc->sm_reg;
628 1.4.6.2 bouyer reg |= TX39_SIBSF0_WRITE;
629 1.4.6.2 bouyer TX39_SIBSF0_REGDATA_CLR(reg);
630 1.4.6.2 bouyer reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
631 1.4.6.2 bouyer tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
632 1.4.6.2 bouyer break;
633 1.4.6.2 bouyer }
634 1.4.6.2 bouyer break;
635 1.4.6.2 bouyer }
636 1.4.6.2 bouyer
637 1.4.6.2 bouyer return (0);
638 1.4.6.2 bouyer }
639 1.4.6.2 bouyer
640 1.4.6.2 bouyer int
641 1.4.6.2 bouyer ucbtp_input(sc)
642 1.4.6.2 bouyer struct ucbtp_softc *sc;
643 1.4.6.2 bouyer {
644 1.4.6.2 bouyer int rx, ry, x, y, p;
645 1.4.6.2 bouyer
646 1.4.6.2 bouyer rx = sc->sc_x;
647 1.4.6.2 bouyer ry = sc->sc_y;
648 1.4.6.2 bouyer p = sc->sc_p;
649 1.4.6.2 bouyer
650 1.4.6.2 bouyer if (!sc->sc_calibrated) {
651 1.4.6.2 bouyer DPRINTFN(2, ("x=%4d y=%4d p=%4d\n", rx, ry, p));
652 1.4.6.2 bouyer DPRINTF(("ucbtp_input: no calibration data\n"));
653 1.4.6.2 bouyer }
654 1.4.6.2 bouyer
655 1.4.6.2 bouyer if (p < UCBTS_PRESS_THRESHOLD || rx == 0x3ff || ry == 0x3ff ||
656 1.4.6.2 bouyer rx == 0 || ry == 0) {
657 1.4.6.2 bouyer sc->sc_stat = UCBTS_STAT_RELEASE;
658 1.4.6.2 bouyer if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
659 1.4.6.2 bouyer DPRINTFN(2, ("TAP!\n"));
660 1.4.6.2 bouyer /* button 0 DOWN */
661 1.4.6.2 bouyer wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
662 1.4.6.2 bouyer /* button 0 UP */
663 1.4.6.2 bouyer wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
664 1.4.6.2 bouyer } else {
665 1.4.6.2 bouyer wsmouse_input(sc->sc_wsmousedev, 0,
666 1.4.6.2 bouyer sc->sc_ox, sc->sc_oy, 0,
667 1.4.6.2 bouyer WSMOUSE_INPUT_ABSOLUTE_X |
668 1.4.6.2 bouyer WSMOUSE_INPUT_ABSOLUTE_Y);
669 1.4.6.2 bouyer
670 1.4.6.2 bouyer DPRINTFN(2, ("RELEASE\n"));
671 1.4.6.2 bouyer }
672 1.4.6.2 bouyer sc->sc_polling = 0;
673 1.4.6.2 bouyer
674 1.4.6.2 bouyer return (1);
675 1.4.6.2 bouyer }
676 1.4.6.2 bouyer
677 1.4.6.2 bouyer if (sc->sc_xy_reverse)
678 1.4.6.2 bouyer tpcalib_trans(&sc->sc_tpcalib, ry, rx, &x, &y);
679 1.4.6.2 bouyer else
680 1.4.6.2 bouyer tpcalib_trans(&sc->sc_tpcalib, rx, ry, &x, &y);
681 1.4.6.2 bouyer
682 1.4.6.2 bouyer DPRINTFN(2, ("x: %4d->%4d y: %4d->%4d pressure=%4d\n",
683 1.4.6.2 bouyer rx, x, ry, y, p));
684 1.4.6.2 bouyer
685 1.4.6.2 bouyer /* debug draw */
686 1.4.6.2 bouyer if (sc->sc_tc->tc_videot) {
687 1.4.6.2 bouyer if (sc->sc_polling == 1)
688 1.4.6.2 bouyer video_dot(sc->sc_tc->tc_videot, x, y);
689 1.4.6.2 bouyer else
690 1.4.6.2 bouyer video_line(sc->sc_tc->tc_videot, sc->sc_ox,
691 1.4.6.2 bouyer sc->sc_oy, x, y);
692 1.4.6.2 bouyer }
693 1.4.6.2 bouyer
694 1.4.6.2 bouyer sc->sc_ox = x, sc->sc_oy = y;
695 1.4.6.2 bouyer
696 1.4.6.2 bouyer wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
697 1.4.6.2 bouyer WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
698 1.4.6.2 bouyer
699 1.4.6.2 bouyer return (0);
700 1.4.6.2 bouyer }
701 1.4.6.2 bouyer
702 1.4.6.2 bouyer /*
703 1.4.6.2 bouyer * access ops.
704 1.4.6.2 bouyer */
705 1.4.6.2 bouyer
706 1.4.6.2 bouyer int
707 1.4.6.2 bouyer ucbtp_enable(v)
708 1.4.6.2 bouyer void *v;
709 1.4.6.2 bouyer {
710 1.4.6.2 bouyer /* not yet */
711 1.4.6.2 bouyer return (0);
712 1.4.6.2 bouyer }
713 1.4.6.2 bouyer
714 1.4.6.2 bouyer void
715 1.4.6.2 bouyer ucbtp_disable(v)
716 1.4.6.2 bouyer void *v;
717 1.4.6.2 bouyer {
718 1.4.6.2 bouyer /* not yet */
719 1.4.6.2 bouyer }
720 1.4.6.2 bouyer
721 1.4.6.2 bouyer int
722 1.4.6.2 bouyer ucbtp_ioctl(v, cmd, data, flag, p)
723 1.4.6.2 bouyer void *v;
724 1.4.6.2 bouyer u_long cmd;
725 1.4.6.2 bouyer caddr_t data;
726 1.4.6.2 bouyer int flag;
727 1.4.6.2 bouyer struct proc *p;
728 1.4.6.2 bouyer {
729 1.4.6.2 bouyer struct ucbtp_softc *sc = v;
730 1.4.6.2 bouyer
731 1.4.6.2 bouyer DPRINTF(("%s(%d): ucbtp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd));
732 1.4.6.2 bouyer
733 1.4.6.2 bouyer switch (cmd) {
734 1.4.6.2 bouyer case WSMOUSEIO_GTYPE:
735 1.4.6.2 bouyer *(u_int *)data = WSMOUSE_TYPE_TPANEL;
736 1.4.6.2 bouyer break;
737 1.4.6.2 bouyer
738 1.4.6.2 bouyer case WSMOUSEIO_SRES:
739 1.4.6.2 bouyer printf("%s(%d): WSMOUSRIO_SRES is not supported",
740 1.4.6.2 bouyer __FILE__, __LINE__);
741 1.4.6.2 bouyer break;
742 1.4.6.2 bouyer
743 1.4.6.2 bouyer case WSMOUSEIO_SCALIBCOORDS:
744 1.4.6.2 bouyer case WSMOUSEIO_GCALIBCOORDS:
745 1.4.6.2 bouyer return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
746 1.4.6.2 bouyer
747 1.4.6.2 bouyer default:
748 1.4.6.2 bouyer return (-1);
749 1.4.6.2 bouyer }
750 1.4.6.2 bouyer
751 1.4.6.2 bouyer return (0);
752 1.4.6.2 bouyer }
753