Port-hpcsh archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

touch-panel driver and manpage for PERSONA SH3 mahicne



Hi!


I wrote touch-panel driver and manpage for HITACHI PERSONA SH3 machine.
I'll be commit next week. (Mon or Tue)

--
kiyohara

Index: share/man/man4/man4.hpcsh/Makefile
===================================================================
RCS file: /cvsroot/src/share/man/man4/man4.hpcsh/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- share/man/man4/man4.hpcsh/Makefile  4 Apr 2004 17:34:43 -0000       1.2
+++ share/man/man4/man4.hpcsh/Makefile  16 May 2005 03:36:30 -0000
@@ -1,6 +1,6 @@
 #      $NetBSD: Makefile,v 1.2 2004/04/04 17:34:43 uwe Exp $
 
-MAN=   intro.4 j6x0lcd.4 j6x0tp.4
+MAN=   intro.4 j6x0lcd.4 j6x0tp.4 psh3tp.4
 
 MANSUBDIR=/hpcsh
 
Index: share/man/man4/man4.hpcsh/intro.4
===================================================================
RCS file: /cvsroot/src/share/man/man4/man4.hpcsh/intro.4,v
retrieving revision 1.1
diff -u -r1.1 intro.4
--- share/man/man4/man4.hpcsh/intro.4   4 Apr 2004 17:03:39 -0000       1.1
+++ share/man/man4/man4.hpcsh/intro.4   16 May 2005 03:36:30 -0000
@@ -33,7 +33,7 @@
 .\"
 .\" <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
 .\"
-.Dd April 4, 2004
+.Dd May 14, 2005
 .Dt INTRO 4 hpcsh
 .Os
 .Sh NAME
@@ -179,6 +179,8 @@
 LCD screen of HP Jornada 680 series machines
 .It j6x0tp
 touch screen of HP Jornada 680 series machines
+.It psh3tp
+touch screen of HITACHI PERSONA SH3 series machines
 .El
 .\"
 .Sh SEE ALSO
@@ -186,6 +188,7 @@
 .Xr adc 4 ,
 .Xr j6x0lcd 4 ,
 .Xr j6x0tp 4 ,
+.Xr psh3tp 4 ,
 .Xr shb 4
 .\"
 .Sh BUGS
Index: sys/arch/hpcsh/conf/files.hpcsh
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcsh/conf/files.hpcsh,v
retrieving revision 1.39
diff -u -r1.39 files.hpcsh
--- sys/arch/hpcsh/conf/files.hpcsh     6 Jul 2004 13:09:19 -0000       1.39
+++ sys/arch/hpcsh/conf/files.hpcsh     16 May 2005 03:36:45 -0000
@@ -74,6 +74,10 @@
 attach j6x0lcd at shb
 file   arch/hpcsh/dev/j6x0lcd.c                j6x0lcd
 
+device h50lcd
+attach h50lcd at shb
+file   arch/hpcsh/dev/h50lcd.c                 h50lcd
+
 device j6x0pwr
 attach j6x0pwr at adc
 file   arch/hpcsh/dev/j6x0pwr.c                j6x0pwr
@@ -91,6 +95,11 @@
                                J6X0TP_PGDN_ICON_KEYSYM
                                J6X0TP_SWITCH_ICON_KEYSYM
 
+device psh3tp: hpctpanel, wsmousedev
+attach psh3tp at adc
+file   arch/hpcsh/dev/psh3tp.c                 psh3tp
+defflag        opt_psh3tp.h            PSH3TP_DEBUG
+
 device pfckbd: hpckbdif
 attach pfckbd at mainbus
 file   arch/hpcsh/dev/pfckbd.c                 pfckbd  needs-flag
Index: sys/dev/DEVNAMES
===================================================================
RCS file: /cvsroot/src/sys/dev/DEVNAMES,v
retrieving revision 1.177
diff -u -r1.177 DEVNAMES
--- sys/dev/DEVNAMES    3 Apr 2005 11:40:09 -0000       1.177
+++ sys/dev/DEVNAMES    16 May 2005 03:37:06 -0000
@@ -965,6 +964,7 @@
 ppi                    hp300
 pps                    MI
 ps                     vax
+psh3tp                 hpcsh
 pss                    MI
 psycho                 sparc64
 ptsc                   acorn32
/*      $NetBSD$        */
/*
 * Copyright (c) 2005 KIYOHARA Takashi
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 */

#include <sys/cdefs.h>

#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/callout.h>

#include "opt_psh3tp.h"

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsmousevar.h>
#include <dev/hpc/hpctpanelvar.h>

#include <machine/platid.h>
#include <machine/platid_mask.h>

#include <machine/intr.h>

#include <sh3/exception.h>
#include <sh3/intcreg.h>
#include <sh3/pfcreg.h>
#include <sh3/adcreg.h>

#include <sh3/dev/adcvar.h>


#ifdef PSH3TP_DEBUG
volatile int psh3tp_debug = 4;
#define DPRINTF_PRINTF          printf_nolog
#define DPRINTF(arg)            if (psh3tp_debug) DPRINTF_PRINTF arg
#define DPRINTFN(n, arg)        if (psh3tp_debug > (n)) DPRINTF_PRINTF arg
#else
#define DPRINTF(arg)            ((void)0)
#define DPRINTFN(n, arg)        ((void)0)
#endif


/*
 * PFC bits pertinent to PERSONA HPW-50PA touch-panel
 */
#define PHDR_TP_PEN_UP          0x40
#define SCPDR_TP_SCAN_ENABLE    0x20
#define SCPDR_TP_SCAN_DISABLE   0x01
#define SCPDR_TP_SCAN_X         0x06
#define SCPDR_TP_SCAN_Y         0x09

/*
 * A/D converter channels to get x/y from
 */
#define ADC_CHANNEL_TP_X        1
#define ADC_CHANNEL_TP_Y        0

/*
 * Default (read: my device) raw X/Y values for framebuffer edges.
 */
#define PSH3TP_FB_RIGHT          56
#define PSH3TP_FB_LEFT          969
#define PSH3TP_FB_TOP           848
#define PSH3TP_FB_BOTTOM        121


struct psh3tp_softc {
        struct device sc_dev;

#define PSH3TP_WSMOUSE_ENABLED  0x01
        int sc_enabled;
        struct callout sc_touch_ch;
        struct device *sc_wsmousedev;
        struct tpcalib_softc sc_tpcalib; /* calibration info for wsmouse */
};


/* config machinery */
static int psh3tp_match(struct device *, struct cfdata *, void *);
static void psh3tp_attach(struct device *, struct device *, void *);
static int psh3tp_wsmouse_submatch(struct device *, struct cfdata *, void *);

/* wsmouse accessops */
static int psh3tp_wsmouse_enable(void *);
static int psh3tp_wsmouse_ioctl(void *, u_long, caddr_t, int, struct proc *);
static void psh3tp_wsmouse_disable(void *);

/* internal driver routines */
static void psh3tp_enable(struct psh3tp_softc *);
static void psh3tp_disable(struct psh3tp_softc *);
static int psh3tp_set_enable(struct psh3tp_softc *, int, int);
static int psh3tp_intr(void *);
static void psh3tp_start_polling(void *);
static void psh3tp_stop_polling(struct psh3tp_softc *);
static void psh3tp_callout_wsmouse(void *);
static void psh3tp_wsmouse_input(struct psh3tp_softc *, int, int);
static void psh3tp_get_raw_xy(int *, int *);


const struct wsmouse_accessops psh3tp_accessops = {
        psh3tp_wsmouse_enable,
        psh3tp_wsmouse_ioctl,
        psh3tp_wsmouse_disable
};

static const struct wsmouse_calibcoords psh3tp_default_calib = {
        0, 0, 639, 239,
        4,
        {{ PSH3TP_FB_LEFT,  PSH3TP_FB_TOP,      0,   0 },
         { PSH3TP_FB_RIGHT, PSH3TP_FB_TOP,    639,   0 },
         { PSH3TP_FB_LEFT,  PSH3TP_FB_BOTTOM,   0, 239 },
         { PSH3TP_FB_RIGHT, PSH3TP_FB_BOTTOM, 639, 239 }}
};


CFATTACH_DECL(psh3tp, sizeof(struct psh3tp_softc),
    psh3tp_match, psh3tp_attach, NULL, NULL);


static int
psh3tp_match(struct device *parent, struct cfdata *cf, void *aux)
{

        if (!platid_match(&platid, &platid_mask_MACH_HITACHI_PERSONA))
                return (0);

        if (strcmp(cf->cf_name, "psh3tp") != 0)
                return (0);

        return (1);
}


/*
 * Attach the touch panel driver and its wsmouse child.
 *
 * Note that we have to use submatch to distinguish between child because
 * wsmouse_match match unconditionally.
 */
static void
psh3tp_attach(struct device *parent, struct device *self, void *aux)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;
        struct wsmousedev_attach_args wsma;

        printf("\n");

        sc->sc_enabled = 0;

        /* touch-panel as a pointing device */
        wsma.accessops = &psh3tp_accessops;
        wsma.accesscookie = sc;

        sc->sc_wsmousedev = config_found_sm(
            self, &wsma, wsmousedevprint, psh3tp_wsmouse_submatch);
        if (sc->sc_wsmousedev == NULL)
                return;

        /* init calibration, set default parameters */
        tpcalib_init(&sc->sc_tpcalib);
        tpcalib_ioctl(&sc->sc_tpcalib,
            WSMOUSEIO_SCALIBCOORDS, (caddr_t)&psh3tp_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_IRQ2,
            IST_EDGE, IPL_TTY, psh3tp_intr, sc);
        intc_intr_disable(SH7709_INTEVT2_IRQ2);
}


static int
psh3tp_wsmouse_submatch(struct device *parent, struct cfdata *cf, void *aux)
{

        return (!strcmp(cf->cf_name, "wsmouse"));
}


/*
 * Enable touch panel:  we start in interrupt mode.
 * Must be called as spltty().
 */
static void
psh3tp_enable(struct psh3tp_softc *sc)
{

        DPRINTFN(2, ("%s: enable\n", sc->sc_dev.dv_xname));
        intc_intr_enable(SH7709_INTEVT2_IRQ2);
}


/*
 * Disable touch panel: disable interrupt, cancel pending callout.
 * Must be called as spltty().
 */
static void
psh3tp_disable(struct psh3tp_softc *sc)
{

        DPRINTFN(2, ("%s: disable\n", sc->sc_dev.dv_xname));
        intc_intr_disable(SH7709_INTEVT2_IRQ2);
        callout_stop(&sc->sc_touch_ch);
}


static int
psh3tp_set_enable(struct psh3tp_softc *sc, int on, int child)
{
        int s = spltty();

        if (on) {
                if (!sc->sc_enabled)
                        psh3tp_enable(sc);
                sc->sc_enabled |= child;
        } else {
                sc->sc_enabled &= ~child;
                if (!sc->sc_enabled)
                        psh3tp_disable(sc);
        }

        splx(s);
        return (0);
}


static int
psh3tp_wsmouse_enable(void *self)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;

        DPRINTFN(1, ("%s: wsmouse enable\n", sc->sc_dev.dv_xname));
        return (psh3tp_set_enable(sc, 1, PSH3TP_WSMOUSE_ENABLED));
}


static void
psh3tp_wsmouse_disable(void *self)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;

        DPRINTFN(1, ("%s: wsmouse disable\n", sc->sc_dev.dv_xname));
        psh3tp_set_enable(sc, 0, PSH3TP_WSMOUSE_ENABLED);
}


static int
psh3tp_intr(void *self)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;

        uint8_t irr0;
        uint8_t phdr, touched;
        unsigned int steady, tremor_timeout;

        irr0 = _reg_read_1(SH7709_IRR0);
        if ((irr0 & IRR0_IRQ2) == 0) {
#ifdef DIAGNOSTIC
                printf("%s: irr0 %02x?\n", sc->sc_dev.dv_xname, irr0);
#endif
                return (0);
        }

        if (!sc->sc_enabled) {
                DPRINTFN(1, ("%s: intr: !sc_enabled\n", sc->sc_dev.dv_xname));
                intc_intr_disable(SH7709_INTEVT2_IRQ2);
                goto served;
        }

        /*
         * Number of times the "touched" bit should be read
         * consecutively.
         */
#define TREMOR_THRESHOLD 0x300
        steady = 0;
        tremor_timeout = TREMOR_THRESHOLD * 16; /* XXX: arbitrary */
        touched = TRUE;         /* we start with "touched" state */

        do {
                uint8_t state;

                phdr = _reg_read_1(SH7709_PHDR);
                state = ((phdr & PHDR_TP_PEN_UP) != PHDR_TP_PEN_UP);

                if (state == touched)
                        ++steady;
                else {
                        steady = 0;
                        touched = state;
                }

                if (--tremor_timeout == 0) {
                        DPRINTF(("%s: tremor timeout!\n", sc->sc_dev.dv_xname));
                        goto served;
                }
        } while (steady < TREMOR_THRESHOLD);

        if (touched) {
                intc_intr_disable(SH7709_INTEVT2_IRQ2);

                /*
                 * 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, psh3tp_start_polling, sc);
        } else
                DPRINTFN(1, ("%s: tremor\n", sc->sc_dev.dv_xname));
served:
        /* clear the interrupt */
        _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ2);

        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.
 */
static void
psh3tp_start_polling(void *self)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;
        uint8_t phdr;
        int rawx, rawy;

        phdr = _reg_read_1(SH7709_PHDR);
        if ((phdr & PHDR_TP_PEN_UP) == PHDR_TP_PEN_UP) {
                DPRINTFN(2, ("%s: start: pen is not down\n",
                    sc->sc_dev.dv_xname));
                psh3tp_stop_polling(sc);
                return;
        }

        psh3tp_get_raw_xy(&rawx, &rawy);
        DPRINTFN(2, ("%s: start: %4d %4d -> ",
            sc->sc_dev.dv_xname, rawx, rawy));

        if (sc->sc_enabled & PSH3TP_WSMOUSE_ENABLED) {
                DPRINTFN(2, ("mouse\n"));
                psh3tp_wsmouse_input(sc, rawx, rawy);
                callout_reset(&sc->sc_touch_ch,
                    hz/32, psh3tp_callout_wsmouse, sc);
        } else {
                DPRINTFN(2, ("ignore\n"));
                psh3tp_stop_polling(sc);
        }
}


/*
 * Re-enable touch panel interrupt.
 * Called as spltty() when polling code detects pen-up.
 */
static void
psh3tp_stop_polling(struct psh3tp_softc *sc)
{
        uint8_t irr0;

        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_IRQ2) != 0)
                _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ2);

        intc_intr_enable(SH7709_INTEVT2_IRQ2);
}


/*
 * We are reporting this touch as a mouse click/drag.
 */
static void
psh3tp_callout_wsmouse(void *self)
{
        struct psh3tp_softc *sc = (struct psh3tp_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;
        }

        phdr = _reg_read_1(SH7709_PHDR);
        if ((phdr & PHDR_TP_PEN_UP) != PHDR_TP_PEN_UP) {
                psh3tp_get_raw_xy(&rawx, &rawy);
                psh3tp_wsmouse_input(sc, rawx, rawy); /* mouse dragged */
                callout_schedule(&sc->sc_touch_ch, hz/32);
        } else {
                wsmouse_input( /* button up */
                    sc->sc_wsmousedev, 0, 0, 0, 0, WSMOUSE_INPUT_DELTA);
                psh3tp_stop_polling(sc);
        }
        splx(s);
}


/*
 * Report mouse click/drag.
 */
static void
psh3tp_wsmouse_input(struct psh3tp_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.
 */
static void
psh3tp_get_raw_xy(int *rawxp, int *rawyp)
{
        uint8_t scpdr;

        /* X axis */
        scpdr = _reg_read_1(SH7709_SCPDR);
        scpdr &= ~SCPDR_TP_SCAN_DISABLE;
        scpdr |= (SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_X);
        _reg_write_1(SH7709_SCPDR, scpdr);
        delay(40);

        *rawxp = adc_sample_channel(ADC_CHANNEL_TP_X);

        /* Y axis */
        scpdr = _reg_read_1(SH7709_SCPDR);
        scpdr &=  ~SCPDR_TP_SCAN_X;
        scpdr |= (SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_Y);
        _reg_write_1(SH7709_SCPDR, scpdr);
        delay(40);

        *rawyp = adc_sample_channel(ADC_CHANNEL_TP_Y);

        /* restore SCPDR */
        scpdr = _reg_read_1(SH7709_SCPDR);
        scpdr &= ~(SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_Y);
        scpdr |= SCPDR_TP_SCAN_DISABLE;
        _reg_write_1(SH7709_SCPDR, scpdr);
}


static int
psh3tp_wsmouse_ioctl(
    void *self, u_long cmd, caddr_t data, int flag, struct proc *p)
{
        struct psh3tp_softc *sc = (struct psh3tp_softc *)self;

        return (hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, p));
}
.\"     $NetBSD$
.\"
.\" Copyright (c) 2005 KIYOHARA Takashi
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd May 14, 2005
.Dt PSH3TP 4 hpcsh
.Os
.Sh NAME
.Nm psh3tp
.Nd driver for PERSONA SH3 touch-panel
.Sh SYNOPSIS
.Cd "psh3tp* at adc?"
.Cd "wsmouse* at psh3tp? mux 0"
.Pp
.Sh DESCRIPTION
The
.Nm
driver provides support for the PERSONA SH3 touch-panel.
.Pp
Pen movements are passed to
.Xr wsmouse 4
as mouse clicks and drags.
.El
.Sh SEE ALSO
.Xr adc 4 ,
.Xr wsmouse 4 ,
.Xr tpctl 8
.Sh HISTORY
The
.Nm
driver first appeared in
.Nx 3.0 .


Home | Main Index | Thread Index | Old Index