[BACK]Return to ibm561.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/ibm561.c, Revision 1.1

1.1     ! nbrk        1: /* $NetBSD: ibm561.c,v 1.1 2001/12/12 07:46:48 elric Exp $ */
        !             2: /* $OpenBSD: ibm561.c,v 1.4 2006/07/16 21:50:58 miod Exp $ */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 2001 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by Roland C. Dowdeswell of Ponte, Inc.
        !            10:  *
        !            11:  * Redistribution and use in source and binary forms, with or without
        !            12:  * modification, are permitted provided that the following conditions
        !            13:  * are met:
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  * 2. Redistributions in binary form must reproduce the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer in the
        !            18:  *    documentation and/or other materials provided with the distribution.
        !            19:  * 3. All advertising materials mentioning features or use of this software
        !            20:  *    must display the following acknowledgement:
        !            21:  *     This product includes software developed by the NetBSD
        !            22:  *     Foundation, Inc. and its contributors.
        !            23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            24:  *    contributors may be used to endorse or promote products derived
        !            25:  *    from this software without specific prior written permission.
        !            26:  *
        !            27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            37:  * POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: #include <sys/param.h>
        !            41: #include <sys/systm.h>
        !            42: #include <sys/device.h>
        !            43: #include <sys/buf.h>
        !            44: #include <sys/kernel.h>
        !            45: #include <sys/malloc.h>
        !            46:
        !            47: #include <uvm/uvm_extern.h>
        !            48:
        !            49: #include <dev/pci/pcivar.h>
        !            50: #include <dev/ic/ibm561reg.h>
        !            51: #include <dev/ic/ibm561var.h>
        !            52: #include <dev/ic/ramdac.h>
        !            53:
        !            54: #include <dev/wscons/wsconsio.h>
        !            55:
        !            56: /*
        !            57:  * Functions exported via the RAMDAC configuration table.
        !            58:  */
        !            59: void   ibm561_init(struct ramdac_cookie *);
        !            60: int    ibm561_set_cmap(struct ramdac_cookie *,
        !            61:            struct wsdisplay_cmap *);
        !            62: int    ibm561_get_cmap(struct ramdac_cookie *,
        !            63:            struct wsdisplay_cmap *);
        !            64: int    ibm561_set_cursor(struct ramdac_cookie *,
        !            65:            struct wsdisplay_cursor *);
        !            66: int    ibm561_get_cursor(struct ramdac_cookie *,
        !            67:            struct wsdisplay_cursor *);
        !            68: int    ibm561_set_curpos(struct ramdac_cookie *,
        !            69:            struct wsdisplay_curpos *);
        !            70: int    ibm561_get_curpos(struct ramdac_cookie *,
        !            71:            struct wsdisplay_curpos *);
        !            72: int    ibm561_get_curmax(struct ramdac_cookie *,
        !            73:            struct wsdisplay_curpos *);
        !            74: int    ibm561_set_dotclock(struct ramdac_cookie *,
        !            75:            unsigned);
        !            76:
        !            77: /* XXX const */
        !            78: struct ramdac_funcs ibm561_funcsstruct = {
        !            79:        "IBM561",
        !            80:        ibm561_register,
        !            81:        ibm561_init,
        !            82:        ibm561_set_cmap,
        !            83:        ibm561_get_cmap,
        !            84:        ibm561_set_cursor,
        !            85:        ibm561_get_cursor,
        !            86:        ibm561_set_curpos,
        !            87:        ibm561_get_curpos,
        !            88:        ibm561_get_curmax,
        !            89:        NULL,                   /* check_curcmap; not needed */
        !            90:        NULL,                   /* set_curcmap; not needed */
        !            91:        NULL,                   /* get_curcmap; not needed */
        !            92:        ibm561_set_dotclock,
        !            93: };
        !            94:
        !            95: /*
        !            96:  * Private data.
        !            97:  */
        !            98: struct ibm561data {
        !            99:        void            *cookie;
        !           100:
        !           101:        int             (*ramdac_sched_update)(void *, void (*)(void *));
        !           102:        void            (*ramdac_wr)(void *, u_int, u_int8_t);
        !           103:        u_int8_t        (*ramdac_rd)(void *, u_int);
        !           104:
        !           105: #define CHANGED_CURCMAP                0x0001  /* cursor cmap */
        !           106: #define CHANGED_CMAP           0x0002  /* color map */
        !           107: #define CHANGED_WTYPE          0x0004  /* window types */
        !           108: #define CHANGED_DOTCLOCK       0x0008  /* dot clock */
        !           109: #define CHANGED_ALL            0x000f  /* or of all above */
        !           110:        u_int8_t        changed;
        !           111:
        !           112:        /* dotclock parameters */
        !           113:        u_int8_t        vco_div;
        !           114:        u_int8_t        pll_ref;
        !           115:        u_int8_t        div_dotclock;
        !           116:
        !           117:        /* colormaps et al. */
        !           118:        u_int8_t        curcmap_r[2];
        !           119:        u_int8_t        curcmap_g[2];
        !           120:        u_int8_t        curcmap_b[2];
        !           121:
        !           122:        u_int8_t        cmap_r[IBM561_NCMAP_ENTRIES];
        !           123:        u_int8_t        cmap_g[IBM561_NCMAP_ENTRIES];
        !           124:        u_int8_t        cmap_b[IBM561_NCMAP_ENTRIES];
        !           125:
        !           126:        u_int16_t       gamma_r[IBM561_NGAMMA_ENTRIES];
        !           127:        u_int16_t       gamma_g[IBM561_NGAMMA_ENTRIES];
        !           128:        u_int16_t       gamma_b[IBM561_NGAMMA_ENTRIES];
        !           129:
        !           130:        u_int16_t       wtype[IBM561_NWTYPES];
        !           131: };
        !           132:
        !           133: /*
        !           134:  * private functions
        !           135:  */
        !           136: void   ibm561_update(void *);
        !           137: static void ibm561_load_cmap(struct ibm561data *);
        !           138: static void ibm561_load_dotclock(struct ibm561data *);
        !           139: static void ibm561_regbegin(struct ibm561data *, u_int16_t);
        !           140: static void ibm561_regcont(struct ibm561data *, u_int16_t, u_int8_t);
        !           141: static void ibm561_regcont10bit(struct ibm561data *, u_int16_t, u_int16_t);
        !           142: static void ibm561_regwr(struct ibm561data *, u_int16_t, u_int8_t);
        !           143:
        !           144: struct ramdac_funcs *
        !           145: ibm561_funcs(void)
        !           146: {
        !           147:        return &ibm561_funcsstruct;
        !           148: }
        !           149:
        !           150: struct ibm561data ibm561_console_data;
        !           151:
        !           152: struct ramdac_cookie *
        !           153: ibm561_register(v, sched_update, wr, rd)
        !           154:        void *v;
        !           155:        int (*sched_update)(void *, void (*)(void *));
        !           156:        void (*wr)(void *, u_int, u_int8_t);
        !           157:        u_int8_t (*rd)(void *, u_int);
        !           158: {
        !           159:        struct ibm561data *data;
        !           160:
        !           161:        if (ibm561_console_data.cookie == NULL) {
        !           162:                data = malloc(sizeof *data, M_DEVBUF, M_WAITOK);
        !           163:                bzero(data, sizeof *data);
        !           164:        } else
        !           165:                data = &ibm561_console_data;
        !           166:        data->cookie = v;
        !           167:        data->ramdac_sched_update = sched_update;
        !           168:        data->ramdac_wr = wr;
        !           169:        data->ramdac_rd = rd;
        !           170:        return (struct ramdac_cookie *)data;
        !           171: }
        !           172:
        !           173: /*
        !           174:  * This function exists solely to provide a means to init
        !           175:  * the RAMDAC without first registering.  It is useful for
        !           176:  * initializing the console early on.
        !           177:  */
        !           178:
        !           179: void
        !           180: ibm561_cninit(v, sched_update, wr, rd, dotclock)
        !           181:        void *v;
        !           182:        int (*sched_update)(void *, void (*)(void *));
        !           183:        void (*wr)(void *, u_int, u_int8_t);
        !           184:        u_int8_t (*rd)(void *, u_int);
        !           185:        u_int dotclock;
        !           186: {
        !           187:        struct ibm561data *data = &ibm561_console_data;
        !           188:        data->cookie = v;
        !           189:        data->ramdac_sched_update = sched_update;
        !           190:        data->ramdac_wr = wr;
        !           191:        data->ramdac_rd = rd;
        !           192:        ibm561_set_dotclock((struct ramdac_cookie *)data, dotclock);
        !           193:        ibm561_init((struct ramdac_cookie *)data);
        !           194: }
        !           195:
        !           196: void
        !           197: ibm561_init(rc)
        !           198:        struct ramdac_cookie *rc;
        !           199: {
        !           200:        struct  ibm561data *data = (struct ibm561data *)rc;
        !           201:        int     i;
        !           202:
        !           203:        /* XXX this is _essential_ */
        !           204:
        !           205:        ibm561_load_dotclock(data);
        !           206:
        !           207:        /* XXXrcd: bunch of magic of which I have no current clue */
        !           208:        ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a);
        !           209:        ibm561_regwr(data, IBM561_CONFIG_REG3, 0x41);
        !           210:        ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20);
        !           211:
        !           212:        /* initialize the card a bit */
        !           213:        ibm561_regwr(data, IBM561_SYNC_CNTL, 0x1);
        !           214:        ibm561_regwr(data, IBM561_CONFIG_REG2, 0x19);
        !           215:
        !           216:        ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a);
        !           217:        ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20);
        !           218:
        !           219:        ibm561_regbegin(data, IBM561_WAT_SEG_REG);
        !           220:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           221:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           222:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           223:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           224:        ibm561_regbegin(data, IBM561_CHROMAKEY0);
        !           225:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           226:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           227:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           228:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           229:
        !           230:        ibm561_regwr(data, IBM561_CURS_CNTL_REG, 0x00); /* XXX off? */
        !           231:
        !           232:        /* cursor `hot spot' registers */
        !           233:        ibm561_regbegin(data, IBM561_HOTSPOT_REG);
        !           234:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           235:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           236:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           237:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           238:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           239:        ibm561_regcont(data, IBM561_CMD, 0x00);
        !           240:
        !           241:        /* VRAM Mask Registers (diagnostics) */
        !           242:        ibm561_regbegin(data, IBM561_VRAM_MASK_REG);
        !           243:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           244:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           245:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           246:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           247:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           248:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           249:        ibm561_regcont(data, IBM561_CMD, 0xff);
        !           250:
        !           251:        /* let's set up some decent default colour maps and gammas */
        !           252:        for (i=0; i < IBM561_NCMAP_ENTRIES; i++)
        !           253:                data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 0xff;
        !           254:        data->cmap_r[0]   = data->cmap_g[0]   = data->cmap_b[0]   = 0x00;
        !           255:        data->cmap_r[256] = data->cmap_g[256] = data->cmap_b[256] = 0x00;
        !           256:        data->cmap_r[512] = data->cmap_g[512] = data->cmap_b[512] = 0x00;
        !           257:        data->cmap_r[768] = data->cmap_g[768] = data->cmap_b[768] = 0x00;
        !           258:
        !           259:        data->gamma_r[0] = data->gamma_g[0] = data->gamma_b[0] = 0x00;
        !           260:        for (i=0; i < IBM561_NGAMMA_ENTRIES; i++)
        !           261:                data->gamma_r[i] = data->gamma_g[i] = data->gamma_b[i] = 0xff;
        !           262:
        !           263:        for (i=0; i < IBM561_NWTYPES; i++)
        !           264:                data->wtype[i] = 0x0036;
        !           265:        data->wtype[1] = 0x0028;
        !           266:
        !           267:        /* the last step: */
        !           268:        data->changed = CHANGED_ALL;
        !           269:        data->ramdac_sched_update(data->cookie, ibm561_update);
        !           270: }
        !           271:
        !           272: int
        !           273: ibm561_set_cmap(rc, cmapp)
        !           274:        struct ramdac_cookie *rc;
        !           275:        struct wsdisplay_cmap *cmapp;
        !           276: {
        !           277:        struct ibm561data *data = (struct ibm561data *)rc;
        !           278:        u_int count, index;
        !           279:        int error;
        !           280:        int s;
        !           281:
        !           282:        index = cmapp->index;
        !           283:        count = cmapp->count;
        !           284:
        !           285:        if (index >= IBM561_NCMAP_ENTRIES ||
        !           286:            count > IBM561_NCMAP_ENTRIES - index)
        !           287:                return (EINVAL);
        !           288:
        !           289:        s = spltty();
        !           290:        if ((error = copyin(cmapp->red, &data->cmap_r[index], count)) != 0) {
        !           291:                splx(s);
        !           292:                return (error);
        !           293:        }
        !           294:        if ((error = copyin(cmapp->green, &data->cmap_g[index], count)) != 0) {
        !           295:                splx(s);
        !           296:                return (error);
        !           297:        }
        !           298:        if ((error = copyin(cmapp->blue, &data->cmap_b[index], count)) != 0) {
        !           299:                splx(s);
        !           300:                return (error);
        !           301:        }
        !           302:        data->changed |= CHANGED_CMAP;
        !           303:        data->ramdac_sched_update(data->cookie, ibm561_update);
        !           304:        splx(s);
        !           305:        return (0);
        !           306: }
        !           307:
        !           308: int
        !           309: ibm561_get_cmap(rc, cmapp)
        !           310:        struct ramdac_cookie *rc;
        !           311:        struct wsdisplay_cmap *cmapp;
        !           312: {
        !           313:        struct ibm561data *data = (struct ibm561data *)rc;
        !           314:        u_int count, index;
        !           315:        int error;
        !           316:
        !           317:        if (cmapp->index >= IBM561_NCMAP_ENTRIES ||
        !           318:            cmapp->count > IBM561_NCMAP_ENTRIES - cmapp->index)
        !           319:                return (EINVAL);
        !           320:        count = cmapp->count;
        !           321:        index = cmapp->index;
        !           322:        error = copyout(&data->cmap_r[index], cmapp->red, count);
        !           323:        if (error)
        !           324:                return (error);
        !           325:        error = copyout(&data->cmap_g[index], cmapp->green, count);
        !           326:        if (error)
        !           327:                return (error);
        !           328:        error = copyout(&data->cmap_b[index], cmapp->blue, count);
        !           329:        return (error);
        !           330: }
        !           331:
        !           332: /*
        !           333:  * XXX:
        !           334:  *  I am leaving these functions returning EINVAL, as they are
        !           335:  *  not strictly necessary for the correct functioning of the
        !           336:  *  card and in fact are not used on the other TGA variants, except
        !           337:  *  they are exported via ioctl(2) to userland, which does not in
        !           338:  *  fact use them.
        !           339:  */
        !           340:
        !           341: int
        !           342: ibm561_set_cursor(rc, cursorp)
        !           343:        struct ramdac_cookie *rc;
        !           344:        struct wsdisplay_cursor *cursorp;
        !           345: {
        !           346:        return EINVAL;
        !           347: }
        !           348:
        !           349: int
        !           350: ibm561_get_cursor(rc, cursorp)
        !           351:        struct ramdac_cookie *rc;
        !           352:        struct wsdisplay_cursor *cursorp;
        !           353: {
        !           354:        return EINVAL;
        !           355: }
        !           356:
        !           357: int
        !           358: ibm561_set_curpos(rc, curposp)
        !           359:        struct ramdac_cookie *rc;
        !           360:        struct wsdisplay_curpos *curposp;
        !           361: {
        !           362:        return EINVAL;
        !           363: }
        !           364:
        !           365: int
        !           366: ibm561_get_curpos(rc, curposp)
        !           367:        struct ramdac_cookie *rc;
        !           368:        struct wsdisplay_curpos *curposp;
        !           369: {
        !           370:        return EINVAL;
        !           371: }
        !           372:
        !           373: int
        !           374: ibm561_get_curmax(rc, curposp)
        !           375:        struct ramdac_cookie *rc;
        !           376:        struct wsdisplay_curpos *curposp;
        !           377: {
        !           378:        return EINVAL;
        !           379: }
        !           380:
        !           381: int
        !           382: ibm561_set_dotclock(rc, dotclock)
        !           383:        struct ramdac_cookie *rc;
        !           384:        unsigned dotclock;
        !           385: {
        !           386:        struct ibm561data *data = (struct ibm561data *)rc;
        !           387:
        !           388:        /* XXXrcd:  a couple of these are a little hazy, vis a vis
        !           389:         *          check 175MHz and 202MHz, which are wrong...
        !           390:         */
        !           391:        switch (dotclock) {
        !           392:        case  25175000: data->vco_div = 0x3e; data->pll_ref = 0x09; break;
        !           393:        case  31500000: data->vco_div = 0x17; data->pll_ref = 0x05; break;
        !           394:        case  40000000: data->vco_div = 0x42; data->pll_ref = 0x06; break;
        !           395:        case  50000000: data->vco_div = 0x45; data->pll_ref = 0x05; break;
        !           396:        case  65000000: data->vco_div = 0xac; data->pll_ref = 0x0c; break;
        !           397:        case  69000000: data->vco_div = 0xa9; data->pll_ref = 0x0b; break;
        !           398:        case  74000000: data->vco_div = 0x9c; data->pll_ref = 0x09; break;
        !           399:        case  75000000: data->vco_div = 0x93; data->pll_ref = 0x08; break;
        !           400:        case 103994000: data->vco_div = 0x96; data->pll_ref = 0x06; break;
        !           401:        case 108180000: data->vco_div = 0xb8; data->pll_ref = 0x08; break;
        !           402:        case 110000000: data->vco_div = 0xba; data->pll_ref = 0x08; break;
        !           403:        case 119840000: data->vco_div = 0x82; data->pll_ref = 0x04; break;
        !           404:        case 130808000: data->vco_div = 0xc8; data->pll_ref = 0x08; break;
        !           405:        case 135000000: data->vco_div = 0xc1; data->pll_ref = 0x07; break;
        !           406:        case 175000000: data->vco_div = 0xe2; data->pll_ref = 0x07; break;
        !           407:        case 202500000: data->vco_div = 0xe2; data->pll_ref = 0x07; break;
        !           408:        default:
        !           409:                return EINVAL;
        !           410:        }
        !           411:
        !           412:        data->div_dotclock = 0xb0;
        !           413:        data->changed |= CHANGED_DOTCLOCK;
        !           414:        return 0;
        !           415: }
        !           416:
        !           417: /*
        !           418:  * Internal Functions
        !           419:  */
        !           420:
        !           421: void
        !           422: ibm561_update(vp)
        !           423:        void *vp;
        !           424: {
        !           425:        struct ibm561data *data = (struct ibm561data *)vp;
        !           426:        int     i;
        !           427:
        !           428:        /* XXX see comment above ibm561_cninit() */
        !           429:        if (!data)
        !           430:                data = &ibm561_console_data;
        !           431:
        !           432:        if (data->changed & CHANGED_WTYPE) {
        !           433:                ibm561_regbegin(data, IBM561_FB_WINTYPE);
        !           434:                for (i=0; i < IBM561_NWTYPES; i++)
        !           435:                        ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, data->wtype[i]);
        !           436:
        !           437:                /* XXXrcd:  quick hack here for AUX FB table */
        !           438:                ibm561_regbegin(data, IBM561_AUXFB_WINTYPE);
        !           439:                for (i=0; i < IBM561_NWTYPES; i++)
        !           440:                        ibm561_regcont(data, IBM561_CMD, 0x04);
        !           441:
        !           442:                /* XXXrcd:  quick hack here for OL WAT table */
        !           443:                ibm561_regbegin(data, IBM561_OL_WINTYPE);
        !           444:                for (i=0; i < IBM561_NWTYPES; i++)
        !           445:                        ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, 0x0231);
        !           446:
        !           447:                /* XXXrcd:  quick hack here for AUX OL WAT table */
        !           448:                ibm561_regbegin(data, IBM561_AUXOL_WINTYPE);
        !           449:                for (i=0; i < IBM561_NWTYPES; i++)
        !           450:                        ibm561_regcont(data, IBM561_CMD, 0x0c);
        !           451:        }
        !           452:
        !           453:        if (data->changed & CHANGED_CMAP)
        !           454:                ibm561_load_cmap(data);
        !           455:
        !           456:        /* XXX:  I am not sure in what situations it is safe to
        !           457:         *       change the dotclock---hope this is good.
        !           458:         */
        !           459:        if (data->changed & CHANGED_DOTCLOCK)
        !           460:                ibm561_load_dotclock(data);
        !           461: }
        !           462:
        !           463: static void
        !           464: ibm561_load_cmap(struct ibm561data *data)
        !           465: {
        !           466:        int     i;
        !           467:
        !           468:        ibm561_regbegin(data, IBM561_CMAP_TABLE);
        !           469:        for (i=0; i < IBM561_NCMAP_ENTRIES; i++) {
        !           470:                ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_r[i]);
        !           471:                ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_g[i]);
        !           472:                ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_b[i]);
        !           473:        }
        !           474:
        !           475:        ibm561_regbegin(data, IBM561_RED_GAMMA_TABLE);
        !           476:        for (i=0; i < 256; i++)
        !           477:                ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_r[i]);
        !           478:
        !           479:        ibm561_regbegin(data, IBM561_GREEN_GAMMA_TABLE);
        !           480:        for (i=1; i < 256; i++)
        !           481:                ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_g[i]);
        !           482:
        !           483:        ibm561_regbegin(data, IBM561_BLUE_GAMMA_TABLE);
        !           484:        for (i=1; i < 256; i++)
        !           485:                ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_b[i]);
        !           486:
        !           487: }
        !           488:
        !           489: static void
        !           490: ibm561_load_dotclock(struct ibm561data *data)
        !           491: {
        !           492:        /* XXX
        !           493:         * we should probably be more pro-active here, but it shouldn't
        !           494:         * actually happen...
        !           495:         */
        !           496:        if (!data->vco_div || !data->pll_ref || ! data->div_dotclock) {
        !           497:                panic("ibm561_load_dotclock: called uninitialized");
        !           498:        }
        !           499:
        !           500:        ibm561_regwr(data, IBM561_PLL_VCO_DIV,  data->vco_div);
        !           501:        ibm561_regwr(data, IBM561_PLL_REF_REG, data->pll_ref);
        !           502:        ibm561_regwr(data, IBM561_DIV_DOTCLCK, data->div_dotclock);
        !           503: }
        !           504:
        !           505: static void
        !           506: ibm561_regcont10bit(struct ibm561data *data, u_int16_t reg, u_int16_t val)
        !           507: {
        !           508:        data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val >> 2) & 0xff);
        !           509:        data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val & 0x3) << 6);
        !           510: }
        !           511:
        !           512: static void
        !           513: ibm561_regbegin(struct ibm561data *data, u_int16_t reg)
        !           514: {
        !           515:        data->ramdac_wr(data->cookie, IBM561_ADDR_LOW, reg & 0xff);
        !           516:        data->ramdac_wr(data->cookie, IBM561_ADDR_HIGH, (reg >> 8) & 0xff);
        !           517: }
        !           518:
        !           519: static void
        !           520: ibm561_regcont(struct ibm561data *data, u_int16_t reg, u_int8_t val)
        !           521: {
        !           522:        data->ramdac_wr(data->cookie, reg, val);
        !           523: }
        !           524:
        !           525: static void
        !           526: ibm561_regwr(struct ibm561data *data, u_int16_t reg, u_int8_t val)
        !           527: {
        !           528:        ibm561_regbegin(data, reg);
        !           529:        ibm561_regcont(data, IBM561_CMD, val);
        !           530: }

CVSweb