[BACK]Return to zts.c CVS log [TXT][DIR] Up to [local] / sys / arch / zaurus / dev

Annotation of sys/arch/zaurus/dev/zts.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: zts.c,v 1.11 2007/05/29 21:09:43 robert Exp $ */
        !             2: /*
        !             3:  * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17:
        !            18: #include <sys/types.h>
        !            19: #include <sys/param.h>
        !            20: #include <sys/systm.h>
        !            21: #include <sys/device.h>
        !            22: #include <sys/malloc.h>
        !            23: #include <sys/timeout.h>
        !            24: #include <sys/kernel.h>
        !            25:
        !            26: #include <arm/xscale/pxa2x0reg.h>
        !            27: #include <arm/xscale/pxa2x0_gpio.h>
        !            28:
        !            29: #include <zaurus/dev/zaurus_sspvar.h>
        !            30:
        !            31: #include <dev/wscons/wsconsio.h>
        !            32: #include <dev/wscons/wsmousevar.h>
        !            33:
        !            34: #include <dev/wscons/wsdisplayvar.h>
        !            35: #include <arm/xscale/pxa2x0var.h>
        !            36: #include <arm/xscale/pxa2x0_lcd.h>
        !            37:
        !            38: #ifdef ZTS_DEBUG
        !            39: #define DPRINTF(x)     do { printf x; } while (0)
        !            40: #else
        !            41: #define DPRINTF(x)
        !            42: #endif
        !            43:
        !            44: /*
        !            45:  * ADS784x touch screen controller
        !            46:  */
        !            47: #define ADSCTRL_PD0_SH          0       /* PD0 bit */
        !            48: #define ADSCTRL_PD1_SH          1       /* PD1 bit */
        !            49: #define ADSCTRL_DFR_SH          2       /* SER/DFR bit */
        !            50: #define ADSCTRL_MOD_SH          3       /* Mode bit */
        !            51: #define ADSCTRL_ADR_SH          4       /* Address setting */
        !            52: #define ADSCTRL_STS_SH          7       /* Start bit */
        !            53:
        !            54: #define GPIO_TP_INT_C3K                11
        !            55: #define GPIO_HSYNC_C3K         22
        !            56:
        !            57: #define POLL_TIMEOUT_RATE0     ((hz * 150)/1000)
        !            58: #define POLL_TIMEOUT_RATE1     (hz / 100) /* XXX every tick */
        !            59:
        !            60: #define CCNT_HS_400_VGA_C3K 6250       /* 15.024us */
        !            61:
        !            62: struct tsscale {
        !            63:        int minx, maxx;
        !            64:        int miny, maxy;
        !            65:        int swapxy;
        !            66:        int resx, resy;
        !            67: } zts_scale = {
        !            68:        /* C3000 */
        !            69:        209, 3620, 312, 3780, 0, 640, 480
        !            70: };
        !            71:
        !            72: int    zts_match(struct device *, void *, void *);
        !            73: void   zts_attach(struct device *, struct device *, void *);
        !            74: int    zts_enable(void *);
        !            75: void   zts_disable(void *);
        !            76: void   zts_power(int, void *);
        !            77: void   zts_poll(void *);
        !            78: int    zts_irq(void *);
        !            79: int    zts_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !            80:
        !            81: struct zts_softc {
        !            82:        struct device sc_dev;
        !            83:        struct timeout sc_ts_poll;
        !            84:        void *sc_gh;
        !            85:        void *sc_powerhook;
        !            86:        int sc_enabled;
        !            87:        int sc_buttons; /* button emulation ? */
        !            88:        struct device *sc_wsmousedev;
        !            89:        int sc_oldx;
        !            90:        int sc_oldy;
        !            91:        int sc_rawmode;
        !            92:
        !            93:        struct tsscale sc_tsscale;
        !            94: };
        !            95:
        !            96: struct cfattach zts_ca = {
        !            97:        sizeof(struct zts_softc), zts_match, zts_attach
        !            98: };
        !            99:
        !           100: struct cfdriver zts_cd = {
        !           101:        NULL, "zts", DV_DULL
        !           102: };
        !           103:
        !           104: int
        !           105: zts_match(struct device *parent, void *cf, void *aux)
        !           106: {
        !           107:        return 1;
        !           108: }
        !           109:
        !           110: const struct wsmouse_accessops zts_accessops = {
        !           111:         zts_enable,
        !           112:        zts_ioctl,
        !           113:        zts_disable
        !           114: };
        !           115:
        !           116: void
        !           117: zts_attach(struct device *parent, struct device *self, void *aux)
        !           118: {
        !           119:        struct zts_softc *sc = (struct zts_softc *)self;
        !           120:        struct wsmousedev_attach_args a;
        !           121:
        !           122:        timeout_set(&sc->sc_ts_poll, zts_poll, sc);
        !           123:
        !           124:        /* Initialize ADS7846 Difference Reference mode */
        !           125:        (void)zssp_ic_send(ZSSP_IC_ADS7846,
        !           126:            (1<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
        !           127:        delay(5000);
        !           128:        (void)zssp_ic_send(ZSSP_IC_ADS7846,
        !           129:            (3<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
        !           130:        delay(5000);
        !           131:        (void)zssp_ic_send(ZSSP_IC_ADS7846,
        !           132:            (4<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
        !           133:        delay(5000);
        !           134:        (void)zssp_ic_send(ZSSP_IC_ADS7846,
        !           135:            (5<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH));
        !           136:        delay(5000);
        !           137:
        !           138:        a.accessops = &zts_accessops;
        !           139:        a.accesscookie = sc;
        !           140:        printf("\n");
        !           141:
        !           142:        /* Copy the default scalue values to each softc */
        !           143:        bcopy(&zts_scale, &sc->sc_tsscale, sizeof(sc->sc_tsscale));
        !           144:
        !           145:        sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
        !           146: }
        !           147:
        !           148: int
        !           149: zts_enable(void *v)
        !           150: {
        !           151:        struct zts_softc *sc = v;
        !           152:
        !           153:        if (sc->sc_enabled)
        !           154:                return EBUSY;
        !           155:
        !           156:        timeout_del(&sc->sc_ts_poll);
        !           157:
        !           158:        sc->sc_powerhook = powerhook_establish(zts_power, sc);
        !           159:        if (sc->sc_powerhook == NULL) {
        !           160:                printf("%s: enable failed\n", sc->sc_dev.dv_xname);
        !           161:                return ENOMEM;
        !           162:        }
        !           163:
        !           164:        pxa2x0_gpio_set_function(GPIO_TP_INT_C3K, GPIO_IN);
        !           165:
        !           166:        /* XXX */
        !           167:        if (sc->sc_gh == NULL)
        !           168:                sc->sc_gh = pxa2x0_gpio_intr_establish(GPIO_TP_INT_C3K,
        !           169:                    IST_EDGE_FALLING, IPL_TTY, zts_irq, sc,
        !           170:                    sc->sc_dev.dv_xname);
        !           171:        else
        !           172:                pxa2x0_gpio_intr_unmask(sc->sc_gh);
        !           173:
        !           174:        /* enable interrupts */
        !           175:        sc->sc_enabled = 1;
        !           176:        sc->sc_buttons = 0;
        !           177:
        !           178:        return 0;
        !           179: }
        !           180:
        !           181: void
        !           182: zts_disable(void *v)
        !           183: {
        !           184:        struct zts_softc *sc = v;
        !           185:
        !           186:        timeout_del(&sc->sc_ts_poll);
        !           187:
        !           188:        if (sc->sc_powerhook != NULL) {
        !           189:                powerhook_disestablish(sc->sc_powerhook);
        !           190:                sc->sc_powerhook = NULL;
        !           191:        }
        !           192:
        !           193:        if (sc->sc_gh != NULL) {
        !           194: #if 0
        !           195:                pxa2x0_gpio_intr_disestablish(sc->sc_gh);
        !           196:                sc->sc_gh = NULL;
        !           197: #endif
        !           198:        }
        !           199:
        !           200:        /* disable interrupts */
        !           201:        sc->sc_enabled = 0;
        !           202: }
        !           203:
        !           204: void
        !           205: zts_power(int why, void *v)
        !           206: {
        !           207:        struct zts_softc *sc = v;
        !           208:
        !           209:        switch (why) {
        !           210:        case PWR_STANDBY:
        !           211:        case PWR_SUSPEND:
        !           212:                sc->sc_enabled = 0;
        !           213: #if 0
        !           214:                pxa2x0_gpio_intr_disestablish(sc->sc_gh);
        !           215: #endif
        !           216:                timeout_del(&sc->sc_ts_poll);
        !           217:
        !           218:                pxa2x0_gpio_intr_mask(sc->sc_gh);
        !           219:
        !           220:                /* Turn off reference voltage but leave ADC on. */
        !           221:                (void)zssp_ic_send(ZSSP_IC_ADS7846, (1 << ADSCTRL_PD1_SH) |
        !           222:                    (1 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH));
        !           223:
        !           224:                pxa2x0_gpio_set_function(GPIO_TP_INT_C3K,
        !           225:                    GPIO_OUT | GPIO_SET);
        !           226:                break;
        !           227:
        !           228:        case PWR_RESUME:
        !           229:                pxa2x0_gpio_set_function(GPIO_TP_INT_C3K, GPIO_IN);
        !           230:                pxa2x0_gpio_intr_mask(sc->sc_gh);
        !           231:
        !           232:                /* Enable automatic low power mode. */
        !           233:                (void)zssp_ic_send(ZSSP_IC_ADS7846,
        !           234:                    (4 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH));
        !           235:
        !           236: #if 0
        !           237:                sc->sc_gh = pxa2x0_gpio_intr_establish(GPIO_TP_INT_C3K,
        !           238:                    IST_EDGE_FALLING, IPL_TTY, zts_irq, sc,
        !           239:                    sc->sc_dev.dv_xname);
        !           240: #else
        !           241:                pxa2x0_gpio_intr_unmask(sc->sc_gh);
        !           242: #endif
        !           243:                sc->sc_enabled = 1;
        !           244:                break;
        !           245:        }
        !           246: }
        !           247:
        !           248: struct zts_pos {
        !           249:        int x;
        !           250:        int y;
        !           251:        int z;                  /* touch pressure */
        !           252: };
        !           253:
        !           254: #define NSAMPLES 3
        !           255: struct zts_pos zts_samples[NSAMPLES];
        !           256: int    ztsavgloaded = 0;
        !           257:
        !           258: int    zts_readpos(struct zts_pos *);
        !           259: void   zts_avgpos(struct zts_pos *);
        !           260:
        !           261: #define HSYNC()                                                        \
        !           262:        do {                                                            \
        !           263:                while (pxa2x0_gpio_get_bit(GPIO_HSYNC_C3K) == 0);       \
        !           264:                while (pxa2x0_gpio_get_bit(GPIO_HSYNC_C3K) != 0);       \
        !           265:        } while (0)
        !           266:
        !           267: int      pxa2x0_ccnt_enable(int);
        !           268: u_int32_t pxa2x0_read_ccnt(void);
        !           269: u_int32_t zts_sync_ads784x(int, int, u_int32_t);
        !           270: void     zts_sync_send(u_int32_t);
        !           271:
        !           272: int
        !           273: pxa2x0_ccnt_enable(int on)
        !           274: {
        !           275:        u_int32_t rv;
        !           276:
        !           277:        on = on ? 0x1 : 0x0;
        !           278:        __asm __volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (rv));
        !           279:        __asm __volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (on));
        !           280:        return ((int)(rv & 0x1));
        !           281: }
        !           282:
        !           283: u_int32_t
        !           284: pxa2x0_read_ccnt(void)
        !           285: {
        !           286:        u_int32_t rv;
        !           287:
        !           288:        __asm __volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (rv));
        !           289:        return (rv);
        !           290: }
        !           291:
        !           292: /*
        !           293:  * Communicate synchronously with the ADS784x touch screen controller.
        !           294:  */
        !           295: u_int32_t
        !           296: zts_sync_ads784x(int dorecv/* XXX */, int dosend/* XXX */, u_int32_t cmd)
        !           297: {
        !           298:        int     ccen;
        !           299:        u_int32_t rv;
        !           300:
        !           301:        /* XXX poll hsync only if LCD is enabled */
        !           302:
        !           303:        /* start clock counter */
        !           304:        ccen = pxa2x0_ccnt_enable(1);
        !           305:
        !           306:        HSYNC();
        !           307:
        !           308:        if (dorecv)
        !           309:                /* read SSDR and disable ADS784x */
        !           310:                rv = zssp_ic_stop(ZSSP_IC_ADS7846);
        !           311:        else
        !           312:                rv = 0;
        !           313:
        !           314:        if (dosend)
        !           315:                zts_sync_send(cmd);
        !           316:
        !           317:        /* stop clock counter */
        !           318:        pxa2x0_ccnt_enable(ccen);
        !           319:
        !           320:        return (rv);
        !           321: }
        !           322:
        !           323: void
        !           324: zts_sync_send(u_int32_t cmd)
        !           325: {
        !           326:        u_int32_t tck;
        !           327:        u_int32_t a, b;
        !           328:
        !           329:        /* XXX */
        !           330:        tck = CCNT_HS_400_VGA_C3K - 151;
        !           331:
        !           332:        /* send dummy command; discard SSDR */
        !           333:        (void)zssp_ic_send(ZSSP_IC_ADS7846, cmd);
        !           334:
        !           335:        /* wait for refresh */
        !           336:        HSYNC();
        !           337:
        !           338:        /* wait after refresh */
        !           339:        a = pxa2x0_read_ccnt();
        !           340:        b = pxa2x0_read_ccnt();
        !           341:        while ((b - a) < tck)
        !           342:                b = pxa2x0_read_ccnt();
        !           343:
        !           344:        /* send the actual command; keep ADS784x enabled */
        !           345:        zssp_ic_start(ZSSP_IC_ADS7846, cmd);
        !           346: }
        !           347:
        !           348: int
        !           349: zts_readpos(struct zts_pos *pos)
        !           350: {
        !           351:        int cmd;
        !           352:        int t0, t1;
        !           353:        int down;
        !           354:
        !           355:        /* XXX */
        !           356:        pxa2x0_gpio_set_function(GPIO_HSYNC_C3K, GPIO_IN);
        !           357:
        !           358:        /* check that pen is down */
        !           359:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           360:            (3 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           361:
        !           362:        t0 = zssp_ic_send(ZSSP_IC_ADS7846, cmd);
        !           363:        down = !(t0 < 10);
        !           364:        if (down == 0)
        !           365:                goto out;
        !           366:
        !           367:        /* Y */
        !           368:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           369:            (1 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           370:
        !           371:        (void)zts_sync_ads784x(0, 1, cmd);
        !           372:
        !           373:        /* Y */
        !           374:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           375:            (1 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           376:
        !           377:        (void)zts_sync_ads784x(1, 1, cmd);
        !           378:
        !           379:        /* X */
        !           380:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           381:            (5 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           382:
        !           383:        pos->y = zts_sync_ads784x(1, 1, cmd);
        !           384:
        !           385:        /* T0 */
        !           386:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           387:            (3 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           388:
        !           389:        pos->x = zts_sync_ads784x(1, 1, cmd);
        !           390:
        !           391:        /* T1 */
        !           392:        cmd = (1 << ADSCTRL_PD0_SH) | (1 << ADSCTRL_PD1_SH) |
        !           393:            (4 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           394:
        !           395:        t0 = zts_sync_ads784x(1, 1, cmd);
        !           396:        t1 = zts_sync_ads784x(1, 0, cmd);
        !           397:
        !           398:        /* check that pen is still down */
        !           399:        /* XXX pressure sensitivity varies with X or what? */
        !           400:        if (t0 == 0 || (pos->x * (t1 - t0) / t0) >= 15000)
        !           401:                down = 0;
        !           402:        pos->z = down;
        !           403:
        !           404: out:
        !           405:        /* Enable automatic low power mode. */
        !           406:         cmd = (4 << ADSCTRL_ADR_SH) | (1 << ADSCTRL_STS_SH);
        !           407:        (void)zssp_ic_send(ZSSP_IC_ADS7846, cmd);
        !           408:
        !           409:        return (down);
        !           410: }
        !           411:
        !           412: #define NAVGSAMPLES (NSAMPLES < 3 ? NSAMPLES : 3)
        !           413: void
        !           414: zts_avgpos(struct zts_pos *pos)
        !           415: {
        !           416:        struct zts_pos *tpp = zts_samples;
        !           417:        int diff[NAVGSAMPLES];
        !           418:        int mindiff, mindiffv;
        !           419:        int n;
        !           420:        int i;
        !           421:        static int tail;
        !           422:
        !           423:        if (ztsavgloaded < NAVGSAMPLES) {
        !           424:                tpp[(tail + ztsavgloaded) % NSAMPLES] = *pos;
        !           425:                ztsavgloaded++;
        !           426:                return;
        !           427:        }
        !           428:
        !           429:        tpp[tail] = *pos;
        !           430:        tail = (tail+1) % NSAMPLES;
        !           431:
        !           432:        /* X */
        !           433:        i = tail;
        !           434:        for (n = 0 ; n < NAVGSAMPLES; n++) {
        !           435:                int alt;
        !           436:                alt = (i+1) % NSAMPLES;
        !           437:                diff[n] = tpp[i].x - tpp[alt].x;
        !           438:                if (diff[n] < 0)
        !           439:                        diff[n] = - diff[n]; /* ABS */
        !           440:                i = alt;
        !           441:        }
        !           442:        mindiffv = diff[0];
        !           443:        mindiff = 0;
        !           444:        for (n = 1; n < NAVGSAMPLES; n++) {
        !           445:                if (diff[n] < mindiffv) {
        !           446:                        mindiffv = diff[n];
        !           447:                        mindiff = n;
        !           448:                }
        !           449:        }
        !           450:        pos->x = (tpp[(tail + mindiff) % NSAMPLES].x +
        !           451:            tpp[(tail + mindiff + 1) % NSAMPLES].x) / 2;
        !           452:
        !           453:        /* Y */
        !           454:        i = tail;
        !           455:        for (n = 0 ; n < NAVGSAMPLES; n++) {
        !           456:                int alt;
        !           457:                alt = (i+1) % NSAMPLES;
        !           458:                diff[n] = tpp[i].y - tpp[alt].y;
        !           459:                if (diff[n] < 0)
        !           460:                        diff[n] = - diff[n]; /* ABS */
        !           461:                i = alt;
        !           462:        }
        !           463:        mindiffv = diff[0];
        !           464:        mindiff = 0;
        !           465:        for (n = 1; n < NAVGSAMPLES; n++) {
        !           466:                if (diff[n] < mindiffv) {
        !           467:                        mindiffv = diff[n];
        !           468:                        mindiff = n;
        !           469:                }
        !           470:        }
        !           471:        pos->y = (tpp[(tail + mindiff) % NSAMPLES].y +
        !           472:            tpp[(tail + mindiff + 1) % NSAMPLES].y) / 2;
        !           473: }
        !           474:
        !           475: void
        !           476: zts_poll(void *v)
        !           477: {
        !           478:        int s;
        !           479:
        !           480:        s = spltty();
        !           481:        (void)zts_irq(v);
        !           482:        splx(s);
        !           483: }
        !           484:
        !           485: #define TS_STABLE 8
        !           486: int
        !           487: zts_irq(void *v)
        !           488: {
        !           489:        struct zts_softc *sc = v;
        !           490:        struct zts_pos tp;
        !           491:        int s;
        !           492:        int pindown;
        !           493:        int down;
        !           494:        extern int zkbd_modstate;
        !           495:
        !           496:        if (!sc->sc_enabled)
        !           497:                return 0;
        !           498:
        !           499:        s = splhigh();
        !           500:        pindown = pxa2x0_gpio_get_bit(GPIO_TP_INT_C3K) ? 0 : 1;
        !           501:        if (pindown) {
        !           502:                pxa2x0_gpio_intr_mask(sc->sc_gh);
        !           503:                timeout_add(&sc->sc_ts_poll, POLL_TIMEOUT_RATE1);
        !           504:        }
        !           505:
        !           506:        down = zts_readpos(&tp);
        !           507:
        !           508:        if (!pindown) {
        !           509:                pxa2x0_gpio_intr_unmask(sc->sc_gh);
        !           510:                timeout_add(&sc->sc_ts_poll, POLL_TIMEOUT_RATE0);
        !           511:                ztsavgloaded = 0;
        !           512:        }
        !           513:        pxa2x0_gpio_clear_intr(GPIO_TP_INT_C3K);
        !           514:        splx(s);
        !           515:
        !           516:        if (down) {
        !           517:                zts_avgpos(&tp);
        !           518:                if (!sc->sc_rawmode) {
        !           519:                        /* Scale down to the screen resolution. */
        !           520:                        tp.x = ((tp.x - sc->sc_tsscale.minx) *
        !           521:                            sc->sc_tsscale.resx) /
        !           522:                            (sc->sc_tsscale.maxx - sc->sc_tsscale.minx);
        !           523:                        tp.y = ((tp.y - sc->sc_tsscale.miny) *
        !           524:                            sc->sc_tsscale.resy) /
        !           525:                            (sc->sc_tsscale.maxy - sc->sc_tsscale.miny);
        !           526:                }
        !           527:        }
        !           528:
        !           529:        if (zkbd_modstate != 0 && down) {
        !           530:                if(zkbd_modstate & (1 << 1)) {
        !           531:                        /* Fn */
        !           532:                        down = 2;
        !           533:                }
        !           534:                if(zkbd_modstate & (1 << 2)) {
        !           535:                        /* 'Alt' */
        !           536:                        down = 4;
        !           537:                }
        !           538:        }
        !           539:        if (!down) {
        !           540:                /* x/y values are not reliable when pen is up */
        !           541:                tp.x = sc->sc_oldx;
        !           542:                tp.y = sc->sc_oldy;
        !           543:        }
        !           544:
        !           545:        if (down || sc->sc_buttons != down) {
        !           546:                DPRINTF(("%s: tp.z = %d, tp.x = %d, tp.y = %d\n",
        !           547:                    sc->sc_dev.dv_xname, tp.z, tp.x, tp.y));
        !           548:
        !           549:                wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y,
        !           550:                    0 /* z */, 0 /* w */,
        !           551:                    WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
        !           552:                    WSMOUSE_INPUT_ABSOLUTE_Z);
        !           553:                sc->sc_buttons = down;
        !           554:                sc->sc_oldx = tp.x;
        !           555:                sc->sc_oldy = tp.y;
        !           556:        }
        !           557:
        !           558:        return 1;
        !           559: }
        !           560:
        !           561: int
        !           562: zts_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           563: {
        !           564:        int error = 0;
        !           565:        struct zts_softc *sc = v;
        !           566:        struct wsmouse_calibcoords *wsmc = (struct wsmouse_calibcoords *)data;
        !           567:
        !           568:        DPRINTF(("zts_ioctl(%d, '%c', %d)\n",
        !           569:            IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd & 0xff));
        !           570:
        !           571:        switch (cmd) {
        !           572:        case WSMOUSEIO_SCALIBCOORDS:
        !           573:                if (!(wsmc->minx >= 0 && wsmc->maxx >= 0 &&
        !           574:                    wsmc->miny >= 0 && wsmc->maxy >= 0 &&
        !           575:                    wsmc->resx >= 0 && wsmc->resy >= 0 &&
        !           576:                    wsmc->minx < 32768 && wsmc->maxx < 32768 &&
        !           577:                    wsmc->miny < 32768 && wsmc->maxy < 32768 &&
        !           578:                    wsmc->resx < 32768 && wsmc->resy < 32768 &&
        !           579:                    wsmc->swapxy >= 0 && wsmc->swapxy <= 1 &&
        !           580:                    wsmc->samplelen >= 0 && wsmc->samplelen <= 1))
        !           581:                        return (EINVAL);
        !           582:
        !           583:                sc->sc_tsscale.minx = wsmc->minx;
        !           584:                sc->sc_tsscale.maxx = wsmc->maxx;
        !           585:                sc->sc_tsscale.miny = wsmc->miny;
        !           586:                sc->sc_tsscale.maxy = wsmc->maxy;
        !           587:                sc->sc_tsscale.swapxy = wsmc->swapxy;
        !           588:                sc->sc_tsscale.resx = wsmc->resx;
        !           589:                sc->sc_tsscale.resy = wsmc->resy;
        !           590:                sc->sc_rawmode = wsmc->samplelen;
        !           591:                break;
        !           592:        case WSMOUSEIO_GCALIBCOORDS:
        !           593:                wsmc->minx = sc->sc_tsscale.minx;
        !           594:                wsmc->maxx = sc->sc_tsscale.maxx;
        !           595:                wsmc->miny = sc->sc_tsscale.miny;
        !           596:                wsmc->maxy = sc->sc_tsscale.maxy;
        !           597:                wsmc->swapxy = sc->sc_tsscale.swapxy;
        !           598:                wsmc->resx = sc->sc_tsscale.resx;
        !           599:                wsmc->resy = sc->sc_tsscale.resy;
        !           600:                wsmc->samplelen = sc->sc_rawmode;
        !           601:                break;
        !           602:        case WSMOUSEIO_GTYPE:
        !           603:                *(u_int *)data = WSMOUSE_TYPE_TPANEL;
        !           604:                break;
        !           605:        default:
        !           606:                error = ENOTTY;
        !           607:                break;
        !           608:        }
        !           609:
        !           610:        return (error);
        !           611: }

CVSweb