[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

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