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

Annotation of sys/arch/zaurus/dev/zaurus_ssp.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: zaurus_ssp.c,v 1.6 2005/04/08 21:58:49 uwe Exp $      */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/param.h>
                     20: #include <sys/systm.h>
                     21: #include <sys/device.h>
                     22:
                     23: #include <machine/bus.h>
                     24:
                     25: #include <arm/xscale/pxa2x0reg.h>
                     26: #include <arm/xscale/pxa2x0var.h>
                     27: #include <arm/xscale/pxa2x0_gpio.h>
                     28:
                     29: #include <zaurus/dev/zaurus_sspvar.h>
                     30:
                     31: #define GPIO_ADS7846_CS_C3000  14      /* SSP SFRM */
                     32: #define GPIO_MAX1111_CS_C3000  20
                     33: #define GPIO_TG_CS_C3000       53
                     34:
                     35: #define SSCR0_ADS7846_C3000    0x06ab
                     36: #define        SSCR0_LZ9JG18           0x01ab
                     37: #define SSCR0_MAX1111          0x0387
                     38:
                     39: struct zssp_softc {
                     40:        struct device sc_dev;
                     41:        bus_space_tag_t sc_iot;
                     42:        bus_space_handle_t sc_ioh;
                     43: };
                     44:
                     45: int    zssp_match(struct device *, void *, void *);
                     46: void   zssp_attach(struct device *, struct device *, void *);
                     47: void   zssp_init(void);
                     48: void   zssp_powerhook(int, void *);
                     49:
                     50: int    zssp_read_max1111(u_int32_t);
                     51: u_int32_t zssp_read_ads7846(u_int32_t);
                     52: void   zssp_write_lz9jg18(u_int32_t);
                     53:
                     54: struct cfattach zssp_ca = {
                     55:        sizeof (struct zssp_softc), zssp_match, zssp_attach
                     56: };
                     57:
                     58: struct cfdriver zssp_cd = {
                     59:        NULL, "zssp", DV_DULL
                     60: };
                     61:
                     62: int
                     63: zssp_match(struct device *parent, void *match, void *aux)
                     64: {
                     65:        return 1;
                     66: }
                     67:
                     68: void
                     69: zssp_attach(struct device *parent, struct device *self, void *aux)
                     70: {
                     71:        struct zssp_softc *sc = (struct zssp_softc *)self;
                     72:
                     73:        sc->sc_iot = &pxa2x0_bs_tag;
                     74:        if (bus_space_map(sc->sc_iot, PXA2X0_SSP1_BASE, PXA2X0_SSP_SIZE,
                     75:            0, &sc->sc_ioh)) {
                     76:                printf(": can't map bus space\n");
                     77:                return;
                     78:        }
                     79:
                     80:        printf("\n");
                     81:
                     82:        if (powerhook_establish(zssp_powerhook, sc) == NULL)
                     83:                printf("%s: can't establish power hook\n",
                     84:                    sc->sc_dev.dv_xname);
                     85:
                     86:        zssp_init();
                     87: }
                     88:
                     89: /*
                     90:  * Initialize the dedicated SSP unit and disable all chip selects.
                     91:  * This function is called with interrupts disabled.
                     92:  */
                     93: void
                     94: zssp_init(void)
                     95: {
                     96:        struct zssp_softc *sc;
                     97:
                     98:        KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
                     99:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    100:
                    101:        pxa2x0_clkman_config(CKEN_SSP, 1);
                    102:
                    103:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, SSCR0_LZ9JG18);
                    104:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
                    105:
                    106:        pxa2x0_gpio_set_function(GPIO_ADS7846_CS_C3000, GPIO_OUT|GPIO_SET);
                    107:        pxa2x0_gpio_set_function(GPIO_MAX1111_CS_C3000, GPIO_OUT|GPIO_SET);
                    108:        pxa2x0_gpio_set_function(GPIO_TG_CS_C3000, GPIO_OUT|GPIO_SET);
                    109: }
                    110:
                    111: void
                    112: zssp_powerhook(int why, void *arg)
                    113: {
                    114:        int s;
                    115:
                    116:        if (why == PWR_RESUME) {
                    117:                s = splhigh();
                    118:                zssp_init();
                    119:                splx(s);
                    120:        }
                    121: }
                    122:
                    123: /*
                    124:  * Transmit a single data word to one of the ICs, keep the chip selected
                    125:  * afterwards, and don't wait for data to be returned in SSDR.  Interrupts
                    126:  * must be held off until zssp_ic_stop() gets called.
                    127:  */
                    128: void
                    129: zssp_ic_start(int ic, u_int32_t data)
                    130: {
                    131:        struct zssp_softc *sc;
                    132:
                    133:        KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
                    134:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    135:
                    136:        /* disable other ICs */
                    137:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
                    138:        if (ic != ZSSP_IC_ADS7846)
                    139:                pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
                    140:        if (ic != ZSSP_IC_LZ9JG18)
                    141:                pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    142:        if (ic != ZSSP_IC_MAX1111)
                    143:                pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
                    144:
                    145:        /* activate the chosen one */
                    146:        switch (ic) {
                    147:        case ZSSP_IC_ADS7846:
                    148:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
                    149:                    SSCR0_ADS7846_C3000);
                    150:                pxa2x0_gpio_clear_bit(GPIO_ADS7846_CS_C3000);
                    151:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data);
                    152:                while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    153:                    & SSSR_TNF) != SSSR_TNF)
                    154:                        /* poll */;
                    155:                break;
                    156:        case ZSSP_IC_LZ9JG18:
                    157:                pxa2x0_gpio_clear_bit(GPIO_TG_CS_C3000);
                    158:                break;
                    159:        case ZSSP_IC_MAX1111:
                    160:                pxa2x0_gpio_clear_bit(GPIO_MAX1111_CS_C3000);
                    161:                break;
                    162:        }
                    163: }
                    164:
                    165: /*
                    166:  * Read the last value from SSDR and deactivate all chip-selects.
                    167:  */
                    168: u_int32_t
                    169: zssp_ic_stop(int ic)
                    170: {
                    171:        struct zssp_softc *sc;
                    172:        u_int32_t rv;
                    173:
                    174:        KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
                    175:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    176:
                    177:        switch (ic) {
                    178:        case ZSSP_IC_ADS7846:
                    179:                /* read result of last command */
                    180:                while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    181:                    & SSSR_RNE) != SSSR_RNE)
                    182:                        /* poll */;
                    183:                rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
                    184:                break;
                    185:        case ZSSP_IC_LZ9JG18:
                    186:        case ZSSP_IC_MAX1111:
                    187:                /* last value received is irrelevant or undefined */
                    188:        default:
                    189:                rv = 0;
                    190:                break;
                    191:        }
                    192:
                    193:        pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
                    194:        pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    195:        pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
                    196:
                    197:        return (rv);
                    198: }
                    199:
                    200: /*
                    201:  * Activate one of the chip-select lines, transmit one word value in
                    202:  * each direction, and deactivate the chip-select again.
                    203:  */
                    204: u_int32_t
                    205: zssp_ic_send(int ic, u_int32_t data)
                    206: {
                    207:
                    208:        switch (ic) {
                    209:        case ZSSP_IC_MAX1111:
                    210:                return (zssp_read_max1111(data));
                    211:        case ZSSP_IC_ADS7846:
                    212:                return (zssp_read_ads7846(data));
                    213:        case ZSSP_IC_LZ9JG18:
                    214:                zssp_write_lz9jg18(data);
                    215:                return 0;
                    216:        default:
                    217:                printf("zssp_ic_send: invalid IC %d\n", ic);
                    218:                return 0;
                    219:        }
                    220: }
                    221:
                    222: int
                    223: zssp_read_max1111(u_int32_t cmd)
                    224: {
                    225:        struct zssp_softc *sc;
                    226:        int     voltage[2];
                    227:        int     i;
                    228:        int     s;
                    229:
                    230:        KASSERT(zssp_cd.cd_ndevs > 0 && zssp_cd.cd_devs[0] != NULL);
                    231:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    232:
                    233:        s = splhigh();
                    234:
                    235:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
                    236:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, SSCR0_MAX1111);
                    237:
                    238:        pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    239:        pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
                    240:        pxa2x0_gpio_clear_bit(GPIO_MAX1111_CS_C3000);
                    241:
                    242:        delay(1);
                    243:
                    244:        /* Send the command word and read a dummy word back. */
                    245:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
                    246:        while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    247:            & SSSR_TNF) != SSSR_TNF)
                    248:                /* poll */;
                    249:        /* XXX is this delay necessary? */
                    250:        delay(1);
                    251:        while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    252:            & SSSR_RNE) != SSSR_RNE)
                    253:                /* poll */;
                    254:        i = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
                    255:
                    256:        for (i = 0; i < 2; i++) {
                    257:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, 0);
                    258:                while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    259:                    & SSSR_TNF) != SSSR_TNF)
                    260:                        /* poll */;
                    261:                /* XXX again, is this delay necessary? */
                    262:                delay(1);
                    263:                while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    264:                    & SSSR_RNE) != SSSR_RNE)
                    265:                        /* poll */;
                    266:                voltage[i] = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
                    267:                    SSP_SSDR);
                    268:        }
                    269:
                    270:        pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    271:        pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
                    272:        pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
                    273:
                    274:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
                    275:
                    276:        /* XXX no idea what this means, but it's what Linux would do. */
                    277:        if ((voltage[0] & 0xc0) != 0 || (voltage[1] & 0x3f) != 0)
                    278:                voltage[0] = -1;
                    279:        else
                    280:                voltage[0] = ((voltage[0] << 2) & 0xfc) |
                    281:                    ((voltage[1] >> 6) & 0x03);
                    282:
                    283:        splx(s);
                    284:        return voltage[0];
                    285: }
                    286:
                    287: /* XXX - only does CS_ADS7846 */
                    288: u_int32_t
                    289: zssp_read_ads7846(u_int32_t cmd)
                    290: {
                    291:        struct zssp_softc *sc;
                    292:
                    293:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    294:        unsigned int cr0;
                    295:        int s;
                    296:        u_int32_t val;
                    297:
                    298:        if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) {
                    299:                printf("zssp_read_ads7846: not configured\n");
                    300:                return 0;
                    301:        }
                    302:        sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
                    303:
                    304:        s = splhigh();
                    305:        if (1) {
                    306:                cr0 =  SSCR0_ADS7846_C3000;
                    307:        } else {
                    308:                cr0 =  0x00ab;
                    309:        }
                    310:         bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
                    311:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, cr0);
                    312:
                    313:        pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    314:        pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
                    315:        pxa2x0_gpio_clear_bit(GPIO_ADS7846_CS_C3000);
                    316:
                    317:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
                    318:
                    319:        while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    320:            & SSSR_TNF) != SSSR_TNF)
                    321:                /* poll */;
                    322:
                    323:        delay(1);
                    324:
                    325:        while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
                    326:            & SSSR_RNE) != SSSR_RNE)
                    327:                /* poll */;
                    328:
                    329:        val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
                    330:
                    331:        pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000); /* deselect */
                    332:
                    333:        splx(s);
                    334:
                    335:        return val;
                    336: }
                    337:
                    338: void
                    339: zssp_write_lz9jg18(u_int32_t data)
                    340: {
                    341:        int s;
                    342:        int sclk_pin, sclk_fn;
                    343:        int sfrm_pin, sfrm_fn;
                    344:        int txd_pin, txd_fn;
                    345:        int rxd_pin, rxd_fn;
                    346:        int i;
                    347:
                    348:        /* XXX this creates a DAC command from a backlight duty value. */
                    349:        data = 0x40 | (data & 0x1f);
                    350:
                    351:        if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) {
                    352:                /* C3000 */
                    353:                sclk_pin = 19;
                    354:                sfrm_pin = 14;
                    355:                txd_pin = 87;
                    356:                rxd_pin = 86;
                    357:        } else {
                    358:                sclk_pin = 23;
                    359:                sfrm_pin = 24;
                    360:                txd_pin = 25;
                    361:                rxd_pin = 26;
                    362:        }
                    363:
                    364:        s = splhigh();
                    365:
                    366:        sclk_fn = pxa2x0_gpio_get_function(sclk_pin);
                    367:        sfrm_fn = pxa2x0_gpio_get_function(sfrm_pin);
                    368:        txd_fn = pxa2x0_gpio_get_function(txd_pin);
                    369:        rxd_fn = pxa2x0_gpio_get_function(rxd_pin);
                    370:
                    371:        pxa2x0_gpio_set_function(sfrm_pin, GPIO_OUT | GPIO_SET);
                    372:        pxa2x0_gpio_set_function(sclk_pin, GPIO_OUT | GPIO_CLR);
                    373:        pxa2x0_gpio_set_function(txd_pin, GPIO_OUT | GPIO_CLR);
                    374:        pxa2x0_gpio_set_function(rxd_pin, GPIO_IN);
                    375:
                    376:        pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
                    377:        pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
                    378:        pxa2x0_gpio_clear_bit(GPIO_TG_CS_C3000);
                    379:
                    380:        delay(10);
                    381:
                    382:        for (i = 0; i < 8; i++) {
                    383:                if (data & 0x80)
                    384:                        pxa2x0_gpio_set_bit(txd_pin);
                    385:                else
                    386:                        pxa2x0_gpio_clear_bit(txd_pin);
                    387:                delay(10);
                    388:                pxa2x0_gpio_set_bit(sclk_pin);
                    389:                delay(10);
                    390:                pxa2x0_gpio_clear_bit(sclk_pin);
                    391:                delay(10);
                    392:                data <<= 1;
                    393:        }
                    394:
                    395:        pxa2x0_gpio_clear_bit(txd_pin);
                    396:        pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
                    397:
                    398:        pxa2x0_gpio_set_function(sclk_pin, sclk_fn);
                    399:        pxa2x0_gpio_set_function(sfrm_pin, sfrm_fn);
                    400:        pxa2x0_gpio_set_function(txd_pin, txd_fn);
                    401:        pxa2x0_gpio_set_function(rxd_pin, rxd_fn);
                    402:
                    403:        splx(s);
                    404: }

CVSweb