From 0af2a039773731df40301f5f103f79ce6bf69d08 Mon Sep 17 00:00:00 2001 From: uwe Date: Tue, 4 Nov 2003 03:43:12 +0000 Subject: [PATCH] Provide wskbd* at j6x0tp? attachment that maps taps on the "HP hard icons" (along the right edge of the screen) to key presses. --- sys/arch/hpcsh/conf/files.hpcsh | 10 +- sys/arch/hpcsh/dev/j6x0tp.c | 519 +++++++++++++++++++++++++++----- 2 files changed, 449 insertions(+), 80 deletions(-) diff --git a/sys/arch/hpcsh/conf/files.hpcsh b/sys/arch/hpcsh/conf/files.hpcsh index 67be20f16b02..f1fc5e82716c 100644 --- a/sys/arch/hpcsh/conf/files.hpcsh +++ b/sys/arch/hpcsh/conf/files.hpcsh @@ -1,4 +1,4 @@ -# $NetBSD: files.hpcsh,v 1.32 2003/10/19 02:21:40 uwe Exp $ +# $NetBSD: files.hpcsh,v 1.33 2003/11/04 03:43:12 uwe Exp $ # maxpartitions 8 @@ -68,9 +68,15 @@ file arch/hpcsh/dev/j6x0pwr.c j6x0pwr include "dev/hpc/files.hpctp" -device j6x0tp: tpcalib, wsmousedev +device j6x0tp: tpcalib, wsmousedev, wskbddev attach j6x0tp at adc file arch/hpcsh/dev/j6x0tp.c j6x0tp +defflag opt_j6x0tp.h J6X0TP_DEBUG + J6X0TP_WSMOUSE_EXCLUSIVE +defparam opt_j6x0tp.h J6X0TP_SETTINGS_ICON_KEYSYM + J6X0TP_PGUP_ICON_KEYSYM + J6X0TP_PGDN_ICON_KEYSYM + J6X0TP_SWITCH_ICON_KEYSYM device pfckbd: hpckbdif attach pfckbd at mainbus diff --git a/sys/arch/hpcsh/dev/j6x0tp.c b/sys/arch/hpcsh/dev/j6x0tp.c index ea26dd66477b..b61e4fcbb1e2 100644 --- a/sys/arch/hpcsh/dev/j6x0tp.c +++ b/sys/arch/hpcsh/dev/j6x0tp.c @@ -1,4 +1,4 @@ -/* $NetBSD: j6x0tp.c,v 1.2 2003/10/22 23:52:46 uwe Exp $ */ +/* $NetBSD: j6x0tp.c,v 1.3 2003/11/04 03:43:12 uwe Exp $ */ /* * Copyright (c) 2003 Valeriy E. Ushakov @@ -28,7 +28,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: j6x0tp.c,v 1.2 2003/10/22 23:52:46 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: j6x0tp.c,v 1.3 2003/11/04 03:43:12 uwe Exp $"); #include #include @@ -40,8 +40,13 @@ __KERNEL_RCSID(0, "$NetBSD: j6x0tp.c,v 1.2 2003/10/22 23:52:46 uwe Exp $"); #include #endif +#include "opt_j6x0tp.h" + #include #include +#include +#include +#include #include #include @@ -66,71 +71,160 @@ __KERNEL_RCSID(0, "$NetBSD: j6x0tp.c,v 1.2 2003/10/22 23:52:46 uwe Exp $"); #else #ifdef J6X0TP_DEBUG volatile int j6x0tp_debug = 0; -#define DPRINTF(arg) if (j6x0tp_debug) printf_nolog arg -#define DPRINTFN(n, arg) if (j6x0tp_debug > (n)) printf_nolog arg +#define DPRINTF_PRINTF printf_nolog +#define DPRINTF(arg) if (j6x0tp_debug) DPRINTF_PRINTF arg +#define DPRINTFN(n, arg) if (j6x0tp_debug > (n)) DPRINTF_PRINTF arg #else -#define DPRINTF(arg) ((void)0) +#define DPRINTF(arg) ((void)0) #define DPRINTFN(n, arg) ((void)0) #endif #endif -/* PFC bits pertinent to Jornada 6x0 touchpanel */ +/* + * PFC bits pertinent to Jornada 6x0 touchpanel + */ #define PHDR_TP_PEN_DOWN 0x08 #define SCPDR_TP_SCAN_ENABLE 0x20 #define SCPDR_TP_SCAN_Y 0x02 #define SCPDR_TP_SCAN_X 0x01 -/* A/D covnerter channels to get x/y from */ +/* + * A/D covnerter channels to get x/y from + */ #define ADC_CHANNEL_TP_Y 1 #define ADC_CHANNEL_TP_X 2 +/* + * Default (read: my device :) raw X/Y values for framebuffer edges. + * XXX: defopt these? + */ +#define J6X0TP_FB_LEFT 38 +#define J6X0TP_FB_RIGHT 950 +#define J6X0TP_FB_TOP 80 +#define J6X0TP_FB_BOTTOM 900 + +/* + * Bottom of the n'th hard icon (n = 1..4) + */ +#define J6X0TP_HARD_ICON_MAX_Y(n) \ + (J6X0TP_FB_TOP + ((J6X0TP_FB_BOTTOM - J6X0TP_FB_TOP) / 4) * (n)) + struct j6x0tp_softc { struct device sc_dev; - struct callout sc_touch_ch; - int sc_intrlevel; +#define J6X0TP_WSMOUSE_ENABLED 0x01 +#define J6X0TP_WSKBD_ENABLED 0x02 int sc_enabled; + int sc_hard_icon; + + struct callout sc_touch_ch; + struct device *sc_wsmousedev; - struct tpcalib_softc sc_tpcalib; + struct device *sc_wskbddev; + + struct tpcalib_softc sc_tpcalib; /* calibration info for wsmouse */ }; + +/* config machinery */ static int j6x0tp_match(struct device *, struct cfdata *, void *); static void j6x0tp_attach(struct device *, struct device *, void *); +static int j6x0tp_wsmouse_submatch(struct device *, struct cfdata *, + void *); +static int j6x0tp_wskbd_submatch(struct device *, struct cfdata *, + void *); -CFATTACH_DECL(j6x0tp, sizeof(struct j6x0tp_softc), - j6x0tp_match, j6x0tp_attach, NULL, NULL); +/* wsmouse accessops */ +static int j6x0tp_wsmouse_enable(void *); +static int j6x0tp_wsmouse_ioctl(void *, u_long, caddr_t, int, + struct proc *); +static void j6x0tp_wsmouse_disable(void *); +/* wskbd accessops */ +static int j6x0tp_wskbd_enable(void *, int); +static void j6x0tp_wskbd_set_leds(void *, int); +static int j6x0tp_wskbd_ioctl(void *, u_long, caddr_t, int, + struct proc *); + +/* internal driver routines */ +static void j6x0tp_enable(struct j6x0tp_softc *); +static void j6x0tp_disable(struct j6x0tp_softc *); +static int j6x0tp_set_enable(struct j6x0tp_softc *, int, int); +static int j6x0tp_intr(void *); +static void j6x0tp_start_polling(void *); +static void j6x0tp_stop_polling(struct j6x0tp_softc *); +static void j6x0tp_callout_wsmouse(void *); +static void j6x0tp_callout_wskbd(void *); +static void j6x0tp_wsmouse_input(struct j6x0tp_softc *, int, int); +static void j6x0tp_get_raw_xy(int *, int *); +static int j6x0tp_get_hard_icon(int, int); -static int j6x0tp_enable(void *); -static int j6x0tp_ioctl(void *, u_long, caddr_t, int, struct proc *); -static void j6x0tp_disable(void *); const struct wsmouse_accessops j6x0tp_accessops = { - j6x0tp_enable, - j6x0tp_ioctl, - j6x0tp_disable, + j6x0tp_wsmouse_enable, + j6x0tp_wsmouse_ioctl, + j6x0tp_wsmouse_disable }; static const struct wsmouse_calibcoords j6x0tp_default_calib = { 0, 0, 639, 239, 4, - {{ 38, 80, 0, 0 }, /* upper left */ - { 950, 80, 639, 0 }, /* upper right */ - { 38, 900, 0, 239 }, /* lower left */ - { 950, 900, 639, 239 }} /* lower right */ + {{ J6X0TP_FB_LEFT, J6X0TP_FB_TOP, 0, 0 }, + { J6X0TP_FB_RIGHT, J6X0TP_FB_TOP, 639, 0 }, + { J6X0TP_FB_LEFT, J6X0TP_FB_BOTTOM, 0, 239 }, + { J6X0TP_FB_RIGHT, J6X0TP_FB_BOTTOM, 639, 239 }} +}; + +const struct wskbd_accessops j6x0tp_wskbd_accessops = { + j6x0tp_wskbd_enable, + j6x0tp_wskbd_set_leds, + j6x0tp_wskbd_ioctl }; -static int j6x0tp_intr(void *); -static void j6x0tp_poll_callout(void *self); +#ifndef J6X0TP_SETTINGS_ICON_KEYSYM +#define J6X0TP_SETTINGS_ICON_KEYSYM KS_Home +#endif +#ifndef J6X0TP_PGUP_ICON_KEYSYM +#define J6X0TP_PGUP_ICON_KEYSYM KS_Prior +#endif +#ifndef J6X0TP_PGDN_ICON_KEYSYM +#define J6X0TP_PGDN_ICON_KEYSYM KS_Next +#endif +#ifndef J6X0TP_SWITCH_ICON_KEYSYM +#define J6X0TP_SWITCH_ICON_KEYSYM KS_End +#endif + +static const keysym_t j6x0tp_wskbd_keydesc[] = { + KS_KEYCODE(1), J6X0TP_SETTINGS_ICON_KEYSYM, + KS_KEYCODE(2), J6X0TP_PGUP_ICON_KEYSYM, + KS_KEYCODE(3), J6X0TP_PGDN_ICON_KEYSYM, + KS_KEYCODE(4), J6X0TP_SWITCH_ICON_KEYSYM +}; + +const struct wscons_keydesc j6x0tp_wskbd_keydesctab[] = { + { KB_US, 0, + sizeof(j6x0tp_wskbd_keydesc)/sizeof(keysym_t), + j6x0tp_wskbd_keydesc + }, + {0, 0, 0, 0} +}; + +const struct wskbd_mapdata j6x0tp_wskbd_keymapdata = { + j6x0tp_wskbd_keydesctab, KB_US +}; + + +CFATTACH_DECL(j6x0tp, sizeof(struct j6x0tp_softc), + j6x0tp_match, j6x0tp_attach, NULL, NULL); static int -j6x0tp_match(struct device *parent, struct cfdata *cfp, void *aux) +j6x0tp_match(struct device *parent, struct cfdata *cf, void *aux) { /* @@ -140,75 +234,155 @@ j6x0tp_match(struct device *parent, struct cfdata *cfp, void *aux) if (!platid_match(&platid, &platid_mask_MACH_HP_JORNADA_6XX)) return (0); - if (strcmp(cfp->cf_name, "j6x0tp") != 0) + if (strcmp(cf->cf_name, "j6x0tp") != 0) return (0); return (1); } +/* + * Attach the touch panel driver and its ws* children. + * + * Note that we have to use submatch to distinguish between children + * because ws{kbd,mouse}_match match unconditionally. + */ static void j6x0tp_attach(struct device *parent, struct device *self, void *aux) { struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; struct wsmousedev_attach_args wsma; + struct wskbddev_attach_args wska; printf("\n"); sc->sc_enabled = 0; + sc->sc_hard_icon = 0; + /* touch-panel as a pointing device */ wsma.accessops = &j6x0tp_accessops; wsma.accesscookie = sc; - sc->sc_wsmousedev = config_found(self, &wsma, wsmousedevprint); + sc->sc_wsmousedev = config_found_sm(self, &wsma, wsmousedevprint, + j6x0tp_wsmouse_submatch); if (sc->sc_wsmousedev == NULL) return; + /* on-screen "hard icons" as a keyboard device */ + wska.console = 0; + wska.keymap = &j6x0tp_wskbd_keymapdata; + wska.accessops = &j6x0tp_wskbd_accessops; + wska.accesscookie = sc; + + sc->sc_wskbddev = config_found_sm(self, &wska, wskbddevprint, + j6x0tp_wskbd_submatch); + + /* init calibration, set default paramters */ tpcalib_init(&sc->sc_tpcalib); tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, (caddr_t)&j6x0tp_default_calib, 0, 0); + /* used when in polling mode */ callout_init(&sc->sc_touch_ch); + /* establish interrupt handler, but disable until opened */ intc_intr_establish(SH7709_INTEVT2_IRQ3, IST_EDGE, IPL_TTY, j6x0tp_intr, sc); - sc->sc_intrlevel = intc_intr_disable(SH7709_INTEVT2_IRQ3); + intc_intr_disable(SH7709_INTEVT2_IRQ3); } static int -j6x0tp_enable(void *self) +j6x0tp_wsmouse_submatch(struct device *parent, struct cfdata *cf, void *aux) { - struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; - int s; - DPRINTFN(1, ("%s: enable\n", sc->sc_dev.dv_xname)); + return (!strcmp(cf->cf_name, "wsmouse")); +} - s = spltty(); - sc->sc_enabled = 1; - intc_intr_enable(SH7709_INTEVT2_IRQ3, sc->sc_intrlevel); +static int +j6x0tp_wskbd_submatch(struct device *parent, struct cfdata *cf, void *aux) +{ + + return (!strcmp(cf->cf_name, "wskbd")); +} + + +/* + * Enable touch panel: we start in interrupt mode. + * Must be called as spltty(). + */ +static void +j6x0tp_enable(struct j6x0tp_softc *sc) +{ + + DPRINTFN(2, ("%s: enable\n", sc->sc_dev.dv_xname)); + intc_intr_enable(SH7709_INTEVT2_IRQ3); +} + + +/* + * Disable touch panel: disable interrupt, cancel pending callout. + * Must be called as spltty(). + */ +static void +j6x0tp_disable(struct j6x0tp_softc *sc) +{ + + DPRINTFN(2, ("%s: disable\n", sc->sc_dev.dv_xname)); + intc_intr_disable(SH7709_INTEVT2_IRQ3); + callout_stop(&sc->sc_touch_ch); +} + + +static int +j6x0tp_set_enable(struct j6x0tp_softc *sc, int on, int child) +{ + int s = spltty(); + + if (on) { + if (!sc->sc_enabled) + j6x0tp_enable(sc); + sc->sc_enabled |= child; + } else { + sc->sc_enabled &= ~child; + if (!sc->sc_enabled) + j6x0tp_disable(sc); + } splx(s); return (0); } -static void -j6x0tp_disable(void *self) +static int +j6x0tp_wsmouse_enable(void *self) { struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; - int s; - s = spltty(); + DPRINTFN(1, ("%s: wsmouse enable\n", sc->sc_dev.dv_xname)); + return (j6x0tp_set_enable(sc, 1, J6X0TP_WSMOUSE_ENABLED)); +} - DPRINTFN(1, ("%s: disable\n", sc->sc_dev.dv_xname)); - sc->sc_enabled = 0; - intc_intr_disable(SH7709_INTEVT2_IRQ3); - callout_stop(&sc->sc_touch_ch); +static void +j6x0tp_wsmouse_disable(void *self) +{ + struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; - splx(s); + DPRINTFN(1, ("%s: wsmouse disable\n", sc->sc_dev.dv_xname)); + j6x0tp_set_enable(sc, 0, J6X0TP_WSMOUSE_ENABLED); +} + + +static int +j6x0tp_wskbd_enable(void *self, int on) +{ + struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; + + DPRINTFN(1, ("%s: wskbd %sable\n", sc->sc_dev.dv_xname, + on ? "en" : "dis")); + return (j6x0tp_set_enable(sc, on, J6X0TP_WSKBD_ENABLED)); } @@ -229,6 +403,13 @@ j6x0tp_intr(void *self) return (0); } + if (!sc->sc_enabled) { + DPRINTFN(1, ("%s: intr: !sc_enabled\n", sc->sc_dev.dv_xname)); + intc_intr_disable(SH7709_INTEVT2_IRQ3); + goto served; + } + + /* * Number of times the "touched" bit should be read * consecutively. @@ -256,60 +437,200 @@ j6x0tp_intr(void *self) } } while (steady < TREMOR_THRESHOLD); - if (touched == 0) { - DPRINTFN(1, ("%s: tremor\n", sc->sc_dev.dv_xname)); - goto served; - } + if (touched) { + intc_intr_disable(SH7709_INTEVT2_IRQ3); - intc_intr_disable(SH7709_INTEVT2_IRQ3); - - if (sc->sc_enabled) + /* + * ADC readings are not stable yet, so schedule + * callout instead of accessing ADC from the interrupt + * handler only to immediately delay(). + */ callout_reset(&sc->sc_touch_ch, hz/32, - j6x0tp_poll_callout, sc); - else - DPRINTFN(1, ("%s: intr: !sc_enabled\n", sc->sc_dev.dv_xname)); - + j6x0tp_start_polling, sc); + } else + DPRINTFN(1, ("%s: tremor\n", sc->sc_dev.dv_xname)); served: - /* clear the interrupt */ + /* clear the interrupt (XXX: protect access?) */ _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ3); return (1); } +/* + * Called from the interrupt handler at spltty() upon first touch. + * Decide if we are going to report this touch as a mouse click/drag + * or as a key press. + */ static void -j6x0tp_poll_callout(void *self) +j6x0tp_start_polling(void *self) { struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; - uint8_t phdr, scpdr; + uint8_t phdr; + int do_mouse, do_kbd; + int rawx, rawy; + int icon; + + phdr = _reg_read_1(SH7709_PHDR); + if ((phdr & PHDR_TP_PEN_DOWN) == 0) { + DPRINTFN(2, ("%s: start: pen is not down\n", + sc->sc_dev.dv_xname)); + j6x0tp_stop_polling(sc); + } + + j6x0tp_get_raw_xy(&rawx, &rawy); + DPRINTFN(2, ("%s: start: %4d %4d -> ", + sc->sc_dev.dv_xname, rawx, rawy)); + + do_mouse = sc->sc_enabled & J6X0TP_WSMOUSE_ENABLED; +#ifdef J6X0TP_WSMOUSE_EXCLUSIVE + if (do_mouse) + do_kbd = 0; + else +#endif + do_kbd = sc->sc_enabled & J6X0TP_WSKBD_ENABLED; + + icon = 0; + if (do_kbd) + icon = j6x0tp_get_hard_icon(rawx, rawy); + + if (icon != 0) { + DPRINTFN(2, ("icon %d\n", icon)); + sc->sc_hard_icon = icon; + wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_DOWN, icon); + callout_reset(&sc->sc_touch_ch, hz/32, + j6x0tp_callout_wskbd, sc); + } else if (do_mouse) { + DPRINTFN(2, ("mouse\n")); + j6x0tp_wsmouse_input(sc, rawx, rawy); + callout_reset(&sc->sc_touch_ch, hz/32, + j6x0tp_callout_wsmouse, sc); + } else { + DPRINTFN(2, ("ignore\n")); + j6x0tp_stop_polling(sc); + } +} + + +/* + * Re-enable touch panel interrupt. + * Called as spltty() when polling code detects pen-up. + */ +static void +j6x0tp_stop_polling(struct j6x0tp_softc *sc) +{ uint8_t irr0; - int rawx, rawy, x, y; + + DPRINTFN(2, ("%s: stop\n", sc->sc_dev.dv_xname)); + + /* clear pending interrupt signal before re-enabling the interrupt */ + irr0 = _reg_read_1(SH7709_IRR0); + if ((irr0 & IRR0_IRQ3) != 0) + _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ3); + + intc_intr_enable(SH7709_INTEVT2_IRQ3); +} + + +/* + * We are reporting this touch as a keyboard event. + * Poll touch screen waiting for pen-up. + */ +static void +j6x0tp_callout_wskbd(void *self) +{ + struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; + uint8_t phdr; int s; s = spltty(); if (!sc->sc_enabled) { - DPRINTFN(1, ("%s: callout: !sc_enabled\n", + DPRINTFN(1, ("%s: wskbd callout: !sc_enabled\n", sc->sc_dev.dv_xname)); splx(s); return; } phdr = _reg_read_1(SH7709_PHDR); - if ((phdr & PHDR_TP_PEN_DOWN) == 0) { - wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); /* mouse up */ + if ((phdr & PHDR_TP_PEN_DOWN) != 0) { + /* + * Pen is still down, continue polling. Wskbd's + * auto-repeat takes care of repeating the key. + */ + callout_schedule(&sc->sc_touch_ch, hz/32); + } else { + wskbd_input(sc->sc_wskbddev, + WSCONS_EVENT_KEY_UP, sc->sc_hard_icon); + j6x0tp_stop_polling(sc); + } + splx(s); +} - intc_intr_enable(SH7709_INTEVT2_IRQ3, sc->sc_intrlevel); - irr0 = _reg_read_1(SH7709_IRR0); - if ((irr0 & IRR0_IRQ3) != 0) - _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ3); +/* + * We are reporting this touch as a mouse click/drag. + */ +static void +j6x0tp_callout_wsmouse(void *self) +{ + struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; + uint8_t phdr; + int rawx, rawy; + int s; + s = spltty(); + + if (!sc->sc_enabled) { + DPRINTFN(1, ("%s: wsmouse callout: !sc_enabled\n", + sc->sc_dev.dv_xname)); splx(s); return; } - /* XXX: protect accesses to SCPDR? */ + phdr = _reg_read_1(SH7709_PHDR); + if ((phdr & PHDR_TP_PEN_DOWN) != 0) { + j6x0tp_get_raw_xy(&rawx, &rawy); + j6x0tp_wsmouse_input(sc, rawx, rawy); /* mouse dragged */ + callout_schedule(&sc->sc_touch_ch, hz/32); + } else { + wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, /* button up */ + WSMOUSE_INPUT_DELTA); + j6x0tp_stop_polling(sc); + } + splx(s); +} + + +/* + * Report mouse click/drag. + */ +static void +j6x0tp_wsmouse_input(struct j6x0tp_softc *sc, int rawx, int rawy) +{ + int x, y; + + tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); + + DPRINTFN(3, ("%s: %4d %4d -> %3d %3d\n", + sc->sc_dev.dv_xname, rawx, rawy, x, y)); + + wsmouse_input(sc->sc_wsmousedev, + 1, /* button */ + x, y, + 0, /* flags */ + WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); +} + + +/* + * Read raw X/Y coordinates from the ADC. + * XXX: protect accesses to SCPDR? + */ +static void +j6x0tp_get_raw_xy(int *rawxp, int *rawyp) +{ + uint8_t scpdr; /* Y axis */ scpdr = _reg_read_1(SH7709_SCPDR); @@ -317,7 +638,8 @@ j6x0tp_poll_callout(void *self) scpdr &= ~SCPDR_TP_SCAN_Y; /* pull low to scan */ _reg_write_1(SH7709_SCPDR, scpdr); delay(10); - rawy = adc_sample_channel(ADC_CHANNEL_TP_Y); + + *rawyp = adc_sample_channel(ADC_CHANNEL_TP_Y); /* X axis */ scpdr = _reg_read_1(SH7709_SCPDR); @@ -325,29 +647,40 @@ j6x0tp_poll_callout(void *self) scpdr &= ~SCPDR_TP_SCAN_X; /* pull low to scan */ _reg_write_1(SH7709_SCPDR, scpdr); delay(10); - rawx = adc_sample_channel(ADC_CHANNEL_TP_X); + + *rawxp = adc_sample_channel(ADC_CHANNEL_TP_X); /* restore SCPDR */ scpdr = _reg_read_1(SH7709_SCPDR); scpdr |= SCPDR_TP_SCAN_X; scpdr &= ~SCPDR_TP_SCAN_ENABLE; _reg_write_1(SH7709_SCPDR, scpdr); +} - tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); - DPRINTFN(2, ("%s: %4d %4d -> %3d %3d\n", - sc->sc_dev.dv_xname, rawx, rawy, x, y)); +/* + * Check if the (rawx, rawy) is inside one of the 4 hard icons. + * Return the icon number 1..4, or 0 if not inside an icon. + */ +static int +j6x0tp_get_hard_icon(int rawx, int rawy) +{ + if (rawx <= J6X0TP_FB_RIGHT) + return (0); - wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); - - callout_schedule(&sc->sc_touch_ch, hz/32); - splx(s); + if (rawy < J6X0TP_HARD_ICON_MAX_Y(1)) + return (1); + else if (rawy < J6X0TP_HARD_ICON_MAX_Y(2)) + return (2); + else if (rawy < J6X0TP_HARD_ICON_MAX_Y(3)) + return (3); + else + return (4); } static int -j6x0tp_ioctl(void *self, u_long cmd, caddr_t data, int flag, +j6x0tp_wsmouse_ioctl(void *self, u_long cmd, caddr_t data, int flag, struct proc *p) { struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; @@ -366,3 +699,33 @@ j6x0tp_ioctl(void *self, u_long cmd, caddr_t data, int flag, return (EPASSTHROUGH); } } + + +static int +j6x0tp_wskbd_ioctl(void *self, u_long cmd, caddr_t data, int flag, + struct proc *p) +{ + /* struct j6x0tp_softc *sc = (struct j6x0tp_softc *)self; */ + + switch (cmd) { + case WSKBDIO_GTYPE: + *(int *)data = WSKBD_TYPE_HPC_BTN; /* may be use new type? */ + return (0); + + case WSKBDIO_GETLEDS: + *(int *)data = 0; + return (0); + + default: + return (EPASSTHROUGH); + } +} + + +static void +j6x0tp_wskbd_set_leds(void *self, int leds) +{ + + /* nothing to do*/ + return; +}