vrpiu.c revision 1.7
1/*	$NetBSD: vrpiu.c,v 1.7 2000/12/27 12:22:07 sato Exp $	*/
2
3/*
4 * Copyright (c) 1999 Shin Takemura All rights reserved.
5 * Copyright (c) 2000 SATO Kazumi, All rights reserved.
6 * Copyright (c) 1999,2000 PocketBSD Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31/*
32 * A/D polling part written by SATO Kazumi.
33 */
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/device.h>
38#include <sys/kernel.h>
39#include <sys/callout.h>
40#include <sys/boot_flag.h>
41
42#include <dev/wscons/wsconsio.h>
43#include <dev/wscons/wsmousevar.h>
44
45#include <machine/bus.h>
46#include <machine/platid.h>
47#include <machine/platid_mask.h>
48#include <machine/config_hook.h>
49
50#include <hpcmips/hpcmips/machdep.h>
51#include <hpcmips/dev/tpcalibvar.h>
52
53#include <hpcmips/vr/vripvar.h>
54#include <hpcmips/vr/cmureg.h>
55#include <hpcmips/vr/vrpiuvar.h>
56#include <hpcmips/vr/vrpiureg.h>
57
58/*
59 * contant and macro definitions
60 */
61#define VRPIUDEBUG
62#ifdef VRPIUDEBUG
63int	vrpiu_debug = 0;
64#define	DPRINTF(arg) if (vrpiu_debug) printf arg;
65#define	VPRINTF(arg) if (bootverbose || vrpiu_debug) printf arg;
66#else
67#define	DPRINTF(arg)
68#define	VPRINTF(arg) if (bootverbose) printf arg;
69#endif
70
71#ifndef VRPIU_AD_POLL_INTERVAL
72#define VRPIU_AD_POLL_INTERVAL	60	/* interval is 60 sec */
73#endif /* VRPIU_AD_POLL_INTERTVAL */
74/*
75 * data types
76 */
77/* struct vrpiu_softc is defined in vrpiuvar.h */
78
79/*
80 * function prototypes
81 */
82static int	vrpiumatch __P((struct device *, struct cfdata *, void *));
83static void	vrpiuattach __P((struct device *, struct device *, void *));
84
85static void	vrpiu_write __P((struct vrpiu_softc *, int, unsigned short));
86static u_short	vrpiu_read __P((struct vrpiu_softc *, int));
87
88static int	vrpiu_intr __P((void *));
89static void	vrpiu_tp_intr __P((struct vrpiu_softc *));
90static void	vrpiu_ad_intr __P((struct vrpiu_softc *));
91#ifdef DEBUG
92static void	vrpiu_dump_cntreg __P((unsigned int cmd));
93#endif
94
95static int	vrpiu_tp_enable __P((void *));
96static int	vrpiu_tp_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
97static void	vrpiu_tp_disable __P((void *));
98int		vrpiu_ad_enable __P((void *));
99void		vrpiu_ad_disable __P((void *));
100static void	vrpiu_start_powerstate __P((void *));
101static void	vrpiu_calc_powerstate __P((struct vrpiu_softc *));
102static void	vrpiu_power __P((int, void *));
103
104/* mra is defined in mra.c */
105int mra_Y_AX1_BX2_C __P((int *y, int ys, int *x1, int x1s, int *x2, int x2s,
106			 int n, int scale, int *a, int *b, int *c));
107
108/*
109 * static or global variables
110 */
111struct cfattach vrpiu_ca = {
112	sizeof(struct vrpiu_softc), vrpiumatch, vrpiuattach
113};
114
115const struct wsmouse_accessops vrpiu_accessops = {
116	vrpiu_tp_enable,
117	vrpiu_tp_ioctl,
118	vrpiu_tp_disable,
119};
120
121int vrpiu_ad_poll_interval = VRPIU_AD_POLL_INTERVAL;
122
123/*
124 * function definitions
125 */
126static inline void
127vrpiu_write(sc, port, val)
128	struct vrpiu_softc *sc;
129	int port;
130	unsigned short val;
131{
132	bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
133}
134
135static inline u_short
136vrpiu_read(sc, port)
137	struct vrpiu_softc *sc;
138	int port;
139{
140	return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port);
141}
142
143static int
144vrpiumatch(parent, cf, aux)
145	struct device *parent;
146	struct cfdata *cf;
147	void *aux;
148{
149	return 1;
150}
151
152static void
153vrpiuattach(parent, self, aux)
154	struct device *parent;
155	struct device *self;
156	void *aux;
157{
158	struct vrpiu_softc *sc = (struct vrpiu_softc *)self;
159	struct vrip_attach_args *va = aux;
160	struct wsmousedev_attach_args wsmaa;
161
162	bus_space_tag_t iot = va->va_iot;
163	bus_space_handle_t ioh;
164
165	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
166		printf(": can't map bus space\n");
167		return;
168	}
169
170	sc->sc_iot = iot;
171	sc->sc_ioh = ioh;
172	sc->sc_vrip = va->va_vc;
173
174	/*
175	 * disable device until vrpiu_enable called
176	 */
177	sc->sc_tpstat = VRPIU_TP_STAT_DISABLE;
178
179	tpcalib_init(&sc->sc_tpcalib);
180#if 1
181	/*
182	 * XXX, calibrate parameters
183	 */
184	{
185		int i;
186		static const struct {
187			platid_mask_t *mask;
188			struct wsmouse_calibcoords coords;
189		} calibrations[] = {
190			{ &platid_mask_MACH_NEC_MCR_700A,
191				{ 0, 0, 799, 599,
192				  4,
193				{ { 115,  80,   0,   0 },
194				  { 115, 966,   0, 599 },
195				  { 912,  80, 799,   0 },
196				  { 912, 966, 799, 599 } } } },
197
198			{ NULL,		/* samples got on my MC-R500 */
199				{ 0, 0, 639, 239,
200				5,
201				{ { 502, 486, 320, 120 },
202				  {  55, 109,   0,   0 },
203				  {  54, 913,   0, 239 },
204				  { 973, 924, 639, 239 },
205				  { 975, 123, 639,   0 } } } },
206		};
207		for (i = 0; ; i++) {
208			if (calibrations[i].mask == NULL
209			    || platid_match(&platid, calibrations[i].mask))
210				break;
211		}
212		tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
213			      (caddr_t)&calibrations[i].coords, 0, 0);
214	}
215#endif
216
217	/* install interrupt handler and enable interrupt */
218	if (!(sc->sc_handler =
219	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
220				  vrpiu_intr, sc))) {
221		printf (": can't map interrupt line.\n");
222		return;
223	}
224
225	/* mask level2 interrupt, stop scan sequencer and mask clock to piu */
226	vrpiu_tp_disable(sc);
227
228	printf("\n");
229
230	wsmaa.accessops = &vrpiu_accessops;
231	wsmaa.accesscookie = sc;
232
233	/*
234	 * attach the wsmouse
235	 */
236	sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
237
238	/*
239	 * power management events
240	 */
241	sc->sc_power_hook = powerhook_establish(vrpiu_power, sc);
242
243	/*
244	 * init A/D port polling.
245	 */
246	sc->sc_battery.n_values = 3;
247	sc->sc_battery.value[0] = -1;
248	sc->sc_battery.value[1] = -1;
249	sc->sc_battery.value[2] = -1;
250	sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval;
251	callout_init(&sc->sc_adpoll);
252	callout_reset(&sc->sc_adpoll, hz,
253			  vrpiu_start_powerstate, sc);
254}
255
256int
257vrpiu_ad_enable(v)
258	void *v;
259{
260	struct vrpiu_softc *sc = v;
261	int s;
262	unsigned int cnt;
263
264	DPRINTF(("%s(%d): vrpiu_ad_enable()\n", __FILE__, __LINE__));
265	if (sc->sc_adstat != VRPIU_AD_STAT_DISABLE)
266		return EBUSY;
267
268	/* supply clock to PIU */
269	__vrcmu_supply(CMUMSKPIU, 1);
270
271	/* Scan interval 0x7FF is maximum value */
272	vrpiu_write(sc, PIUSIVL_REG_W, 0x7FF);
273
274	s = spltty();
275
276	/* clear interrupt status */
277	vrpiu_write(sc, PIUINT_REG_W, PIUINT_PADADPINTR);
278
279	/* Disable -> Standby */
280	cnt = PIUCNT_PIUPWR |
281		PIUCNT_PIUMODE_COORDINATE |
282		PIUCNT_PADATSTART | PIUCNT_PADATSTOP;
283	vrpiu_write(sc, PIUCNT_REG_W, cnt);
284
285	/* Level2 interrupt register setting */
286	vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, PIUINT_PADADPINTR, 1);
287
288	/* save pen status, touch or release */
289	cnt = vrpiu_read(sc, PIUCNT_REG_W);
290
291	/*
292	 * Enable scan sequencer operation
293	 * Standby -> WaitPenTouch
294	 */
295	cnt |= PIUCNT_PIUSEQEN;
296	vrpiu_write(sc, PIUCNT_REG_W, cnt);
297
298	sc->sc_adstat = VRPIU_AD_STAT_ENABLE;
299
300	splx(s);
301
302	return 0;
303}
304
305void
306vrpiu_ad_disable(v)
307	void *v;
308{
309	struct vrpiu_softc *sc = v;
310
311	DPRINTF(("%s(%d): vrpiu_ad_disable()\n", __FILE__, __LINE__));
312
313	/* Set level2 interrupt register to mask interrupts */
314	vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, PIUINT_PADADPINTR, 0);
315
316	sc->sc_adstat = VRPIU_AD_STAT_DISABLE;
317
318	if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE){
319		/* Disable scan sequencer operation and power off */
320		vrpiu_write(sc, PIUCNT_REG_W, 0);
321
322		/* mask clock to PIU */
323		__vrcmu_supply(CMUMSKPIU, 1);
324	}
325}
326
327int
328vrpiu_tp_enable(v)
329	void *v;
330{
331	struct vrpiu_softc *sc = v;
332	int s;
333	unsigned int cnt;
334
335	DPRINTF(("%s(%d): vrpiu_tp_enable()\n", __FILE__, __LINE__));
336	if (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE)
337		return EBUSY;
338
339	/* supply clock to PIU */
340	__vrcmu_supply(CMUMSKPIU, 1);
341
342	/* Scan interval 0x7FF is maximum value */
343	vrpiu_write(sc, PIUSIVL_REG_W, 0x7FF);
344
345	s = spltty();
346
347	/* clear interrupt status */
348	vrpiu_write(sc, PIUINT_REG_W, PIUINT_ALLINTR&~PIUINT_PADADPINTR);
349
350	/* Disable -> Standby */
351	cnt = PIUCNT_PIUPWR |
352		PIUCNT_PIUMODE_COORDINATE |
353		PIUCNT_PADATSTART | PIUCNT_PADATSTOP;
354	vrpiu_write(sc, PIUCNT_REG_W, cnt);
355
356	/* Level2 interrupt register setting */
357	vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, PIUINT_ALLINTR&~PIUINT_PADADPINTR, 1);
358
359	/* save pen status, touch or release */
360	cnt = vrpiu_read(sc, PIUCNT_REG_W);
361
362	/*
363	 * Enable scan sequencer operation
364	 * Standby -> WaitPenTouch
365	 */
366	cnt |= PIUCNT_PIUSEQEN;
367	vrpiu_write(sc, PIUCNT_REG_W, cnt);
368
369	/* transit status DISABLE -> TOUCH or RELEASE */
370	sc->sc_tpstat = (cnt & PIUCNT_PENSTC) ?
371		VRPIU_TP_STAT_TOUCH : VRPIU_TP_STAT_RELEASE;
372
373	splx(s);
374
375	return 0;
376}
377
378void
379vrpiu_tp_disable(v)
380	void *v;
381{
382	struct vrpiu_softc *sc = v;
383
384	DPRINTF(("%s(%d): vrpiu_tp_disable()\n", __FILE__, __LINE__));
385
386	/* Set level2 interrupt register to mask interrupts */
387	vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, PIUINT_ALLINTR&~PIUINT_PADADPINTR, 0);
388
389	sc->sc_tpstat = VRPIU_TP_STAT_DISABLE;
390
391	if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE){
392		/* Disable scan sequencer operation and power off */
393		vrpiu_write(sc, PIUCNT_REG_W, 0);
394
395		/* mask clock to PIU */
396		__vrcmu_supply(CMUMSKPIU, 1);
397	}
398}
399
400int
401vrpiu_tp_ioctl(v, cmd, data, flag, p)
402	void *v;
403	u_long cmd;
404	caddr_t data;
405	int flag;
406	struct proc *p;
407{
408	struct vrpiu_softc *sc = v;
409
410	DPRINTF(("%s(%d): vrpiu_tp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd));
411
412	switch (cmd) {
413	case WSMOUSEIO_GTYPE:
414		*(u_int *)data = WSMOUSE_TYPE_TPANEL;
415		break;
416
417	case WSMOUSEIO_SRES:
418		printf("%s(%d): WSMOUSRIO_SRES is not supported",
419		       __FILE__, __LINE__);
420		break;
421
422	case WSMOUSEIO_SCALIBCOORDS:
423	case WSMOUSEIO_GCALIBCOORDS:
424                return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
425
426	default:
427		return (-1);
428	}
429	return (0);
430}
431
432/*
433 * PIU AD interrupt handler.
434 */
435void
436vrpiu_ad_intr(sc)
437	struct vrpiu_softc *sc;
438{
439	unsigned int i;
440	unsigned int intrstat;
441
442	intrstat = vrpiu_read(sc, PIUINT_REG_W);
443
444	if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE) {
445		/*
446		 * the device isn't enabled. just clear interrupt.
447		 */
448		vrpiu_write(sc, PIUINT_REG_W, PIUINT_PADADPINTR);
449		return;
450	}
451
452	if (intrstat & PIUINT_PADADPINTR) {
453		sc->sc_battery.value[0] = (unsigned int)vrpiu_read(sc, PIUAB(0));
454		sc->sc_battery.value[1] = (unsigned int)vrpiu_read(sc, PIUAB(1));
455		sc->sc_battery.value[2] = (unsigned int)vrpiu_read(sc, PIUAB(2));
456	}
457
458	if (intrstat & PIUINT_PADADPINTR) {
459		for (i = 0; i < 3; i++) {
460			if (sc->sc_battery.value[i] & PIUAB_VALID)
461				sc->sc_battery.value[i] &= PIUAB_PADDATA_MASK;
462			else
463				sc->sc_battery.value[i] = 0;
464		}
465		vrpiu_calc_powerstate(sc);
466	}
467	vrpiu_write(sc, PIUINT_REG_W, PIUINT_PADADPINTR);
468
469	return;
470}
471/*
472 * PIU TP interrupt handler.
473 */
474void
475vrpiu_tp_intr(sc)
476	struct vrpiu_softc *sc;
477{
478	unsigned int cnt, i;
479	unsigned int intrstat, page;
480	int tpx0, tpx1, tpy0, tpy1;
481	int x, y, xraw, yraw;
482
483	intrstat = vrpiu_read(sc, PIUINT_REG_W);
484
485	if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE) {
486	/*
487		 * the device isn't enabled. just clear interrupt.
488		 */
489		vrpiu_write(sc, PIUINT_REG_W, intrstat&~PIUINT_PADADPINTR);
490		return;
491	}
492
493	page = (intrstat & PIUINT_OVP) ? 1 : 0;
494	if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) {
495		tpx0 = vrpiu_read(sc, PIUPB(page, 0));
496		tpx1 = vrpiu_read(sc, PIUPB(page, 1));
497		tpy0 = vrpiu_read(sc, PIUPB(page, 2));
498		tpy1 = vrpiu_read(sc, PIUPB(page, 3));
499	}
500
501	if (intrstat & PIUINT_PADDLOSTINTR) {
502		page = page ? 0 : 1;
503		for (i = 0; i < 4; i++)
504			vrpiu_read(sc, PIUPB(page, i));
505	}
506
507	cnt = vrpiu_read(sc, PIUCNT_REG_W);
508#ifdef DEBUG
509	if (vrpiu_debug)
510		vrpiu_dump_cntreg(cnt);
511#endif
512
513	/* clear interrupt status */
514	vrpiu_write(sc, PIUINT_REG_W, intrstat&~PIUINT_PADADPINTR);
515
516#if 0
517	DPRINTF(("vrpiu_intr: OVP=%d", page));
518	if (intrstat & PIUINT_PADCMDINTR)
519		DPRINTF((" CMD"));
520	if (intrstat & PIUINT_PADADPINTR)
521		DPRINTF((" A/D"));
522	if (intrstat & PIUINT_PADPAGE1INTR)
523		DPRINTF((" PAGE1"));
524	if (intrstat & PIUINT_PADPAGE0INTR)
525		DPRINTF((" PAGE0"));
526	if (intrstat & PIUINT_PADDLOSTINTR)
527		DPRINTF((" DLOST"));
528	if (intrstat & PIUINT_PENCHGINTR)
529		DPRINTF((" PENCHG"));
530	DPRINTF(("\n"));
531#endif
532	if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) {
533		if (!((tpx0 & PIUPB_VALID) && (tpx1 & PIUPB_VALID) &&
534		      (tpy0 & PIUPB_VALID) && (tpy1 & PIUPB_VALID))) {
535			printf("vrpiu: internal error, data is not valid!\n");
536		} else {
537			tpx0 &= PIUPB_PADDATA_MASK;
538			tpx1 &= PIUPB_PADDATA_MASK;
539			tpy0 &= PIUPB_PADDATA_MASK;
540			tpy1 &= PIUPB_PADDATA_MASK;
541#define ISVALID(n, c, m)	((c) - (m) < (n) && (n) < (c) + (m))
542			if (ISVALID(tpx0 + tpx1, 1024, 200) &&
543			    ISVALID(tpx0 + tpx1, 1024, 200)) {
544#if 0
545				DPRINTF(("%04x %04x %04x %04x\n",
546					 tpx0, tpx1, tpy0, tpy1));
547				DPRINTF(("%3d %3d (%4d %4d)->", tpx0, tpy0,
548					 tpx0 + tpx1, tpy0 + tpy1));
549#endif
550				xraw = tpy1 * 1024 / (tpy0 + tpy1);
551				yraw = tpx1 * 1024 / (tpx0 + tpx1);
552				DPRINTF(("%3d %3d", xraw, yraw));
553
554				tpcalib_trans(&sc->sc_tpcalib,
555					      xraw, yraw, &x, &y);
556
557				DPRINTF(("->%4d %4d", x, y));
558				wsmouse_input(sc->sc_wsmousedev,
559					      (cnt & PIUCNT_PENSTC) ? 1 : 0,
560					      x, /* x */
561					      y, /* y */
562					      0, /* z */
563					      WSMOUSE_INPUT_ABSOLUTE_X |
564					      WSMOUSE_INPUT_ABSOLUTE_Y);
565				DPRINTF(("\n"));
566			}
567		}
568	}
569
570	if (cnt & PIUCNT_PENSTC) {
571		if (sc->sc_tpstat == VRPIU_TP_STAT_RELEASE) {
572			/*
573			 * pen touch
574			 */
575			DPRINTF(("PEN TOUCH\n"));
576			sc->sc_tpstat = VRPIU_TP_STAT_TOUCH;
577			/*
578			 * We should not report button down event while
579			 * we don't know where it occur.
580			 */
581		}
582	} else {
583		if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) {
584			/*
585			 * pen release
586			 */
587			DPRINTF(("RELEASE\n"));
588			sc->sc_tpstat = VRPIU_TP_STAT_RELEASE;
589			/* button 0 UP */
590			wsmouse_input(sc->sc_wsmousedev,
591				      0,
592				      0, 0, 0, 0);
593		}
594	}
595
596	if (intrstat & PIUINT_PADDLOSTINTR) {
597		cnt |= PIUCNT_PIUSEQEN;
598		vrpiu_write(sc, PIUCNT_REG_W, cnt);
599	}
600
601	return;
602}
603
604/*
605 * PIU interrupt handler.
606 */
607int
608vrpiu_intr(arg)
609	void *arg;
610{
611        struct vrpiu_softc *sc = arg;
612
613	vrpiu_ad_intr(sc);
614	vrpiu_tp_intr(sc);
615
616	return 0;
617}
618
619void
620vrpiu_start_powerstate(v)
621	void *v;
622{
623	int mask;
624	struct vrpiu_softc *sc = (struct vrpiu_softc *)v;
625
626	vrpiu_ad_enable(sc);
627	mask = vrpiu_read(sc, PIUAMSK_REG_W);
628	mask &= 0xff8f; /* XXX */
629	vrpiu_write(sc, PIUAMSK_REG_W, mask);
630	vrpiu_write(sc, PIUASCN_REG_W, PIUACN_ADPSSTART);
631	/*
632	 * restart next A/D polling
633	 */
634	callout_reset(&sc->sc_adpoll, hz*vrpiu_ad_poll_interval,
635			 vrpiu_start_powerstate, sc);
636}
637
638void
639vrpiu_calc_powerstate(sc)
640	struct vrpiu_softc *sc;
641{
642	extern void vrgiu_diff_io __P((void));
643	vrpiu_ad_disable(sc);
644	VPRINTF(("vrpiu:AD: %d, %d, %d\n",
645		sc->sc_battery.value[0],
646		sc->sc_battery.value[1],
647		sc->sc_battery.value[2]));
648	sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval;
649#ifdef notyet
650	config_hook_call(CONFIG_HOOK_SET,
651			 CONFIG_HOOK_BATTERYVAL,
652			 (void *)&sc->sc_battery);
653#endif /* notyet */
654	/*
655	 * restart next A/D polling if change polling timming.
656	 */
657	if (sc->sc_battery.nextpoll != hz*vrpiu_ad_poll_interval)
658		callout_reset(&sc->sc_adpoll, sc->sc_battery.nextpoll,
659				 vrpiu_start_powerstate, sc);
660	if (bootverbose)
661		vrgiu_diff_io();
662
663}
664
665static void
666vrpiu_power(why, arg)
667	int why;
668	void *arg;
669{
670	struct vrpiu_softc *sc = arg;
671
672	switch (why) {
673	case PWR_STANDBY:
674	case PWR_SUSPEND:
675		break;
676	case PWR_RESUME:
677		callout_reset(&sc->sc_adpoll, hz,
678				  vrpiu_start_powerstate, sc);
679		break;
680	}
681}
682
683#ifdef DEBUG
684void
685vrpiu_dump_cntreg(cnt)
686	unsigned int cnt;
687{
688	printf("%s", (cnt & PIUCNT_PENSTC) ? "Touch" : "Release");
689	printf(" state=");
690	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_CmdScan)
691		printf("CmdScan");
692	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_IntervalNextScan)
693		printf("IntervalNextScan");
694	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_PenDataScan)
695		printf("PenDataScan");
696	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_WaitPenTouch)
697		printf("WaitPenTouch");
698	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_RFU)
699		printf("???");
700	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_ADPortScan)
701		printf("ADPortScan");
702	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Standby)
703		printf("Standby");
704	if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Disable)
705		printf("Disable");
706	if (cnt & PIUCNT_PADATSTOP)
707		printf(" AutoStop");
708	if (cnt & PIUCNT_PADATSTART)
709		printf(" AutoStart");
710	if (cnt & PIUCNT_PADSCANSTOP)
711		printf(" Stop");
712	if (cnt & PIUCNT_PADSCANSTART)
713		printf(" Start");
714	if (cnt & PIUCNT_PADSCANTYPE)
715		printf(" ScanPressure");
716	if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_ADCONVERTER)
717		printf(" A/D");
718	if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_COORDINATE)
719		printf(" Coordinate");
720	if (cnt & PIUCNT_PIUSEQEN)
721		printf(" SeqEn");
722	if ((cnt & PIUCNT_PIUPWR) == 0)
723		printf(" PowerOff");
724	if ((cnt & PIUCNT_PADRST) == 0)
725		printf(" Reset");
726	printf("\n");
727}
728#endif
729