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

Annotation of sys/arch/mac68k/dev/pm_direct.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pm_direct.c,v 1.13 2007/03/17 20:01:44 miod Exp $     */
        !             2: /*     $NetBSD: pm_direct.c,v 1.25 2005/10/28 21:54:52 christos Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (C) 1997 Takashi Hamada
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *  This product includes software developed by Takashi Hamada
        !            19:  * 4. The name of the author may not be used to endorse or promote products
        !            20:  *    derived from this software without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            31:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32:  */
        !            33: /* From: pm_direct.c 1.3 03/18/98 Takashi Hamada */
        !            34:
        !            35: #ifdef DEBUG
        !            36: #ifndef ADB_DEBUG
        !            37: #define ADB_DEBUG
        !            38: #endif
        !            39: #endif
        !            40:
        !            41: /* #define     PM_GRAB_SI      1 */
        !            42:
        !            43: #include <sys/param.h>
        !            44: #include <sys/systm.h>
        !            45: #include <sys/device.h>
        !            46:
        !            47: #include <machine/cpu.h>
        !            48: #include <machine/viareg.h>
        !            49:
        !            50: #include <dev/adb/adb.h>
        !            51: #include <mac68k/dev/adbvar.h>
        !            52: #include <mac68k/dev/pm_direct.h>
        !            53:
        !            54: /* hardware dependent values */
        !            55: u_int32_t HwCfgFlags3;
        !            56: u_short ADBDelay = 0xcea;
        !            57:
        !            58: /* define the types of the Power Manager */
        !            59: #define PM_HW_UNKNOWN          0x00    /* don't know */
        !            60: #define PM_HW_PB1XX            0x01    /* PowerBook 1XX series */
        !            61: #define        PM_HW_PB5XX             0x02    /* PowerBook Duo and 5XX series */
        !            62:
        !            63: /* useful macros */
        !            64: #define PM_SR()                        via_reg(VIA1, vSR)
        !            65: #define PM_VIA_INTR_ENABLE()   via_reg(VIA1, vIER) = 0x90
        !            66: #define PM_VIA_INTR_DISABLE()  via_reg(VIA1, vIER) = 0x10
        !            67: #define PM_VIA_CLR_INTR()      via_reg(VIA1, vIFR) = 0x90
        !            68: #define PM_SET_STATE_ACKON()   via_reg(VIA2, vBufB) |= 0x04
        !            69: #define PM_SET_STATE_ACKOFF()  via_reg(VIA2, vBufB) &= ~0x04
        !            70: #define PM_IS_ON               (0x02 == (via_reg(VIA2, vBufB) & 0x02))
        !            71: #define PM_IS_OFF              (0x00 == (via_reg(VIA2, vBufB) & 0x02))
        !            72:
        !            73: /*
        !            74:  * Variables for internal use
        !            75:  */
        !            76: int    pmHardware = PM_HW_UNKNOWN;
        !            77: u_short        pm_existent_ADB_devices = 0x0;  /* each bit expresses the existent ADB device */
        !            78: u_int  pm_LCD_brightness = 0x0;
        !            79: u_int  pm_LCD_contrast = 0x0;
        !            80: u_int  pm_counter = 0;                 /* clock count */
        !            81:
        !            82: /* these values shows that number of data returned after 'send' cmd is sent */
        !            83: char pm_send_cmd_type[] = {
        !            84:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            85:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            86:        0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            87:        0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
        !            88:        0xff, 0x00, 0x02, 0x01, 0x01, 0xff, 0xff, 0xff,
        !            89:        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            90:        0x04, 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            91:        0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            92:        0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            93:        0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            94:        0x01, 0x00, 0x02, 0x02, 0xff, 0x01, 0x03, 0x01,
        !            95:        0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
        !            96:        0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            97:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
        !            98:        0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
        !            99:        0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x04, 0x04,
        !           100:        0x04, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           101:        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           102:        0x01, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           103:        0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           104:        0x02, 0x02, 0x02, 0x04, 0xff, 0x00, 0xff, 0xff,
        !           105:        0x01, 0x01, 0x03, 0x02, 0xff, 0xff, 0xff, 0xff,
        !           106:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           107:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           108:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           109:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           110:        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           111:        0x01, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
        !           112:        0xff, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           113:        0x03, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
        !           114:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           115:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
        !           116: };
        !           117:
        !           118: /* these values shows that number of data returned after 'receive' cmd is sent */
        !           119: char pm_receive_cmd_type[] = {
        !           120:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           121:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           122:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           123:        0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
        !           124:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           125:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           126:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           127:        0x05, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           128:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           129:        0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           130:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           131:        0x02, 0x00, 0x03, 0x03, 0xff, 0xff, 0xff, 0xff,
        !           132:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           133:        0x04, 0x04, 0x03, 0x09, 0xff, 0xff, 0xff, 0xff,
        !           134:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           135:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01,
        !           136:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           137:        0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           138:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           139:        0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           140:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           141:        0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
        !           142:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           143:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           144:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           145:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           146:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           147:        0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff,
        !           148:        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           149:        0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00,
        !           150:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           151:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           152: };
        !           153:
        !           154:
        !           155: /*
        !           156:  * Define the private functions
        !           157:  */
        !           158:
        !           159: /* for debugging */
        !           160: #ifdef ADB_DEBUG
        !           161: void   pm_printerr(const char *, int, int, char *);
        !           162: #endif
        !           163:
        !           164: int    pm_wait_busy(int);
        !           165: int    pm_wait_free(int);
        !           166:
        !           167: /* these functions are for the PB1XX series */
        !           168: int    pm_receive_pm1(u_char *);
        !           169: int    pm_send_pm1(u_char, int);
        !           170: int    pm_pmgrop_pm1(PMData *);
        !           171: int    pm_intr_pm1(void *);
        !           172:
        !           173: /* these functions are for the PB Duo series and the PB 5XX series */
        !           174: int    pm_receive_pm2(u_char *);
        !           175: int    pm_send_pm2(u_char);
        !           176: int    pm_pmgrop_pm2(PMData *);
        !           177: int    pm_intr_pm2(void *);
        !           178:
        !           179: /* these functions are called from adb_direct.c */
        !           180: void   pm_setup_adb(void);
        !           181: void   pm_check_adb_devices(int);
        !           182: int    pm_intr(void *);
        !           183: int    pm_adb_op(u_char *, void *, void *, int);
        !           184: void   pm_hw_setup(struct device *);
        !           185:
        !           186: /* these functions also use the variables of adb_direct.c */
        !           187: void   pm_adb_get_TALK_result(PMData *);
        !           188: void   pm_adb_get_ADB_data(PMData *);
        !           189: void   pm_adb_poll_next_device_pm1(PMData *);
        !           190:
        !           191:
        !           192: /*
        !           193:  * These variables are in adb_direct.c.
        !           194:  */
        !           195: extern u_char  *adbBuffer;     /* pointer to user data area */
        !           196: extern void    *adbCompRout;   /* pointer to the completion routine */
        !           197: extern void    *adbCompData;   /* pointer to the completion routine data */
        !           198: extern int     adbWaiting;     /* waiting for return data from the device */
        !           199: extern int     adbWaitingCmd;  /* ADB command we are waiting for */
        !           200: extern int     adbStarting;    /* doing ADB reinit, so do "polling" differently */
        !           201:
        !           202: #define        ADB_MAX_MSG_LENGTH      16
        !           203: #define        ADB_MAX_HDR_LENGTH      8
        !           204: struct adbCommand {
        !           205:        u_char  header[ADB_MAX_HDR_LENGTH];     /* not used yet */
        !           206:        u_char  data[ADB_MAX_MSG_LENGTH];       /* packet data only */
        !           207:        u_char  *saveBuf;       /* where to save result */
        !           208:        u_char  *compRout;      /* completion routine pointer */
        !           209:        u_char  *compData;      /* completion routine data pointer */
        !           210:        u_int   cmd;            /* the original command for this data */
        !           211:        u_int   unsol;          /* 1 if packet was unsolicited */
        !           212:        u_int   ack_only;       /* 1 for no special processing */
        !           213: };
        !           214: extern void    adb_pass_up(struct adbCommand *);
        !           215:
        !           216: #ifdef ADB_DEBUG
        !           217: /*
        !           218:  * This function dumps contents of the PMData
        !           219:  */
        !           220: void
        !           221: pm_printerr(const char *ttl, int rval, int num, char *data)
        !           222: {
        !           223:        int i;
        !           224:
        !           225:        printf("pm: %s:%04x %02x ", ttl, rval, num);
        !           226:        for (i = 0; i < num; i++)
        !           227:                printf("%02x ", data[i]);
        !           228:        printf("\n");
        !           229: }
        !           230: #endif
        !           231:
        !           232:
        !           233:
        !           234: /*
        !           235:  * Check the hardware type of the Power Manager
        !           236:  */
        !           237: void
        !           238: pm_setup_adb(void)
        !           239: {
        !           240:        switch (mac68k_machine.machineid) {
        !           241:        case MACH_MACPB140:
        !           242:        case MACH_MACPB145:
        !           243:        case MACH_MACPB160:
        !           244:        case MACH_MACPB165:
        !           245:        case MACH_MACPB165C:
        !           246:        case MACH_MACPB170:
        !           247:        case MACH_MACPB180:
        !           248:        case MACH_MACPB180C:
        !           249:                pmHardware = PM_HW_PB1XX;
        !           250:                break;
        !           251:        case MACH_MACPB150:
        !           252:        case MACH_MACPB210:
        !           253:        case MACH_MACPB230:
        !           254:        case MACH_MACPB250:
        !           255:        case MACH_MACPB270:
        !           256:        case MACH_MACPB280:
        !           257:        case MACH_MACPB280C:
        !           258:        case MACH_MACPB500:
        !           259:        case MACH_MACPB190:
        !           260:        case MACH_MACPB190CS:
        !           261:                pmHardware = PM_HW_PB5XX;
        !           262:                break;
        !           263:        default:
        !           264:                break;
        !           265:        }
        !           266: }
        !           267:
        !           268:
        !           269: /*
        !           270:  * Check the existent ADB devices
        !           271:  */
        !           272: void
        !           273: pm_check_adb_devices(int id)
        !           274: {
        !           275:        u_short ed = 0x1;
        !           276:
        !           277:        ed <<= id;
        !           278:        pm_existent_ADB_devices |= ed;
        !           279: }
        !           280:
        !           281:
        !           282: /*
        !           283:  * Wait until PM IC is busy
        !           284:  */
        !           285: int
        !           286: pm_wait_busy(int xdelay)
        !           287: {
        !           288:        while (PM_IS_ON) {
        !           289: #ifdef PM_GRAB_SI
        !           290:                (void)intr_dispatch(0x70);      /* grab any serial interrupts */
        !           291: #endif
        !           292:                if ((--xdelay) < 0)
        !           293:                        return 1;       /* timeout */
        !           294:        }
        !           295:        return 0;
        !           296: }
        !           297:
        !           298:
        !           299: /*
        !           300:  * Wait until PM IC is free
        !           301:  */
        !           302: int
        !           303: pm_wait_free(int xdelay)
        !           304: {
        !           305:        while (PM_IS_OFF) {
        !           306: #ifdef PM_GRAB_SI
        !           307:                (void)intr_dispatch(0x70);      /* grab any serial interrupts */
        !           308: #endif
        !           309:                if ((--xdelay) < 0)
        !           310:                        return 0;       /* timeout */
        !           311:        }
        !           312:        return 1;
        !           313: }
        !           314:
        !           315:
        !           316:
        !           317: /*
        !           318:  * Functions for the PB1XX series
        !           319:  */
        !           320:
        !           321: /*
        !           322:  * Receive data from PM for the PB1XX series
        !           323:  */
        !           324: int
        !           325: pm_receive_pm1(u_char *data)
        !           326: {
        !           327:        int rval = 0xffffcd34;
        !           328:
        !           329:        via_reg(VIA2, vDirA) = 0x00;
        !           330:
        !           331:        switch (1) {
        !           332:        default:
        !           333:                if (pm_wait_busy(0x40) != 0)
        !           334:                        break;                  /* timeout */
        !           335:
        !           336:                PM_SET_STATE_ACKOFF();
        !           337:                *data = via_reg(VIA2, 0x200);
        !           338:
        !           339:                rval = 0xffffcd33;
        !           340:                if (pm_wait_free(0x40) == 0)
        !           341:                        break;                  /* timeout */
        !           342:
        !           343:                rval = 0x00;
        !           344:                break;
        !           345:        }
        !           346:
        !           347:        PM_SET_STATE_ACKON();
        !           348:        via_reg(VIA2, vDirA) = 0x00;
        !           349:
        !           350:        return rval;
        !           351: }
        !           352:
        !           353:
        !           354:
        !           355: /*
        !           356:  * Send data to PM for the PB1XX series
        !           357:  */
        !           358: int
        !           359: pm_send_pm1(u_char data, int timo)
        !           360: {
        !           361:        int rval;
        !           362:
        !           363:        via_reg(VIA2, vDirA) = 0xff;
        !           364:        via_reg(VIA2, 0x200) = data;
        !           365:
        !           366:        PM_SET_STATE_ACKOFF();
        !           367: #if 0
        !           368:        if (pm_wait_busy(0x400) == 0) {
        !           369: #else
        !           370:        if (pm_wait_busy(timo) == 0) {
        !           371: #endif
        !           372:                PM_SET_STATE_ACKON();
        !           373:                if (pm_wait_free(0x40) != 0)
        !           374:                        rval = 0x0;
        !           375:                else
        !           376:                        rval = 0xffffcd35;
        !           377:        } else {
        !           378:                rval = 0xffffcd36;
        !           379:        }
        !           380:
        !           381:        PM_SET_STATE_ACKON();
        !           382:        via_reg(VIA2, vDirA) = 0x00;
        !           383:
        !           384:        return rval;
        !           385: }
        !           386:
        !           387:
        !           388: /*
        !           389:  * My PMgrOp routine for the PB1XX series
        !           390:  */
        !           391: int
        !           392: pm_pmgrop_pm1(PMData *pmdata)
        !           393: {
        !           394:        int i;
        !           395:        int s = 0x81815963;
        !           396:        u_char via1_vIER, via1_vDirA;
        !           397:        int rval = 0;
        !           398:        int num_pm_data = 0;
        !           399:        u_char pm_cmd;
        !           400:        u_char pm_data;
        !           401:        u_char *pm_buf;
        !           402:
        !           403:        /* disable all inetrrupts but PM */
        !           404:        via1_vIER = via_reg(VIA1, vIER);
        !           405:        PM_VIA_INTR_DISABLE();
        !           406:
        !           407:        via1_vDirA = via_reg(VIA1, vDirA);
        !           408:
        !           409:        switch (pmdata->command) {
        !           410:        default:
        !           411:                for (i = 0; i < 7; i++) {
        !           412:                        via_reg(VIA2, vDirA) = 0x00;
        !           413:
        !           414:                        /* wait until PM is free */
        !           415:                        if (pm_wait_free(ADBDelay) == 0) {      /* timeout */
        !           416:                                via_reg(VIA2, vDirA) = 0x00;
        !           417:                                /* restore former value */
        !           418:                                via_reg(VIA1, vDirA) = via1_vDirA;
        !           419:                                via_reg(VIA1, vIER) = via1_vIER;
        !           420:                                return 0xffffcd38;
        !           421:                        }
        !           422:
        !           423:                        switch (mac68k_machine.machineid) {
        !           424:                        /* XXX what about 140 and 145? -- miod */
        !           425:                        case MACH_MACPB160:
        !           426:                        case MACH_MACPB165:
        !           427:                        case MACH_MACPB165C:
        !           428:                        case MACH_MACPB170:
        !           429:                        case MACH_MACPB180:
        !           430:                        case MACH_MACPB180C:
        !           431:                        {
        !           432:                                int xdelay = ADBDelay * 16;
        !           433:
        !           434:                                via_reg(VIA2, vDirA) = 0x00;
        !           435:                                while ((via_reg(VIA2, 0x200) == 0x7f) && (xdelay >= 0))
        !           436:                                        xdelay--;
        !           437:
        !           438:                                if (xdelay < 0) {       /* timeout */
        !           439:                                        via_reg(VIA2, vDirA) = 0x00;
        !           440:                                        /* restore former value */
        !           441:                                        via_reg(VIA1, vIER) = via1_vIER;
        !           442:                                        return 0xffffcd38;
        !           443:                                }
        !           444:                        }
        !           445:                                break;
        !           446:                        } /* end switch */
        !           447:
        !           448:                        s = splhigh();
        !           449:
        !           450:                        via1_vDirA = via_reg(VIA1, vDirA);
        !           451:                        via_reg(VIA1, vDirA) &= 0x7f;
        !           452:
        !           453:                        pm_cmd = (u_char)(pmdata->command & 0xff);
        !           454:                        if ((rval = pm_send_pm1(pm_cmd, ADBDelay * 8)) == 0)
        !           455:                                break;  /* send command succeeded */
        !           456:
        !           457:                        via_reg(VIA1, vDirA) = via1_vDirA;
        !           458:                        splx(s);
        !           459:                } /* end for */
        !           460:
        !           461:                /* failed to send a command */
        !           462:                if (i == 7) {
        !           463:                        via_reg(VIA2, vDirA) = 0x00;
        !           464:                        /* restore former value */
        !           465:                        via_reg(VIA1, vDirA) = via1_vDirA;
        !           466:                        via_reg(VIA1, vIER) = via1_vIER;
        !           467:                        if (s != 0x81815963)
        !           468:                                splx(s);
        !           469:                        return 0xffffcd38;
        !           470:                }
        !           471:
        !           472:                /* send # of PM data */
        !           473:                num_pm_data = pmdata->num_data;
        !           474:                if ((rval = pm_send_pm1((u_char)(num_pm_data & 0xff), ADBDelay * 8)) != 0)
        !           475:                        break;                  /* timeout */
        !           476:
        !           477:                /* send PM data */
        !           478:                pm_buf = (u_char *)pmdata->s_buf;
        !           479:                for (i = 0; i < num_pm_data; i++)
        !           480:                        if ((rval = pm_send_pm1(pm_buf[i], ADBDelay * 8)) != 0)
        !           481:                                break;          /* timeout */
        !           482:                if ((i != num_pm_data) && (num_pm_data != 0))
        !           483:                        break;                  /* timeout */
        !           484:
        !           485:                /* Will PM IC return data? */
        !           486:                if ((pm_cmd & 0x08) == 0) {
        !           487:                        rval = 0;
        !           488:                        break;                  /* no returned data */
        !           489:                }
        !           490:
        !           491:                rval = 0xffffcd37;
        !           492:                if (pm_wait_busy(ADBDelay) != 0)
        !           493:                        break;                  /* timeout */
        !           494:
        !           495:                /* receive PM command */
        !           496:                if ((rval = pm_receive_pm1(&pm_data)) != 0)
        !           497:                        break;
        !           498:
        !           499:                pmdata->command = pm_data;
        !           500:
        !           501:                /* receive number of PM data */
        !           502:                if ((rval = pm_receive_pm1(&pm_data)) != 0)
        !           503:                        break;                  /* timeout */
        !           504:                num_pm_data = pm_data;
        !           505:                pmdata->num_data = num_pm_data;
        !           506:
        !           507:                /* receive PM data */
        !           508:                pm_buf = (u_char *)pmdata->r_buf;
        !           509:                for (i = 0; i < num_pm_data; i++) {
        !           510:                        if ((rval = pm_receive_pm1(&pm_data)) != 0)
        !           511:                                break;          /* timeout */
        !           512:                        pm_buf[i] = pm_data;
        !           513:                }
        !           514:
        !           515:                rval = 0;
        !           516:        }
        !           517:
        !           518:        via_reg(VIA2, vDirA) = 0x00;
        !           519:
        !           520:        /* restore former value */
        !           521:        via_reg(VIA1, vDirA) = via1_vDirA;
        !           522:        via_reg(VIA1, vIER) = via1_vIER;
        !           523:        if (s != 0x81815963)
        !           524:                splx(s);
        !           525:
        !           526:        return rval;
        !           527: }
        !           528:
        !           529:
        !           530: /*
        !           531:  * My PM interrupt routine for PB1XX series
        !           532:  */
        !           533: int
        !           534: pm_intr_pm1(void *arg)
        !           535: {
        !           536:        int s;
        !           537:        int rval;
        !           538:        PMData pmdata;
        !           539:
        !           540:        s = splhigh();
        !           541:
        !           542:        PM_VIA_CLR_INTR();                              /* clear VIA1 interrupt */
        !           543:
        !           544:        /* ask PM what happend */
        !           545:        pmdata.command = 0x78;
        !           546:        pmdata.num_data = 0;
        !           547:        pmdata.data[0] = pmdata.data[1] = 0;
        !           548:        pmdata.s_buf = &pmdata.data[2];
        !           549:        pmdata.r_buf = &pmdata.data[2];
        !           550:        rval = pm_pmgrop_pm1(&pmdata);
        !           551:        if (rval != 0) {
        !           552: #ifdef ADB_DEBUG
        !           553:                if (adb_debug)
        !           554:                        printf("pm: PM is not ready. error code=%08x\n", rval);
        !           555: #endif
        !           556:                splx(s);
        !           557:        }
        !           558:
        !           559:        if ((pmdata.data[2] & 0x10) == 0x10) {
        !           560:                if ((pmdata.data[2] & 0x0f) == 0) {
        !           561:                        /* ADB data that were requested by TALK command */
        !           562:                        pm_adb_get_TALK_result(&pmdata);
        !           563:                } else if ((pmdata.data[2] & 0x08) == 0x8) {
        !           564:                        /* PM is requesting to poll  */
        !           565:                        pm_adb_poll_next_device_pm1(&pmdata);
        !           566:                } else if ((pmdata.data[2] & 0x04) == 0x4) {
        !           567:                        /* ADB device event */
        !           568:                        pm_adb_get_ADB_data(&pmdata);
        !           569:                }
        !           570:        } else {
        !           571: #ifdef ADB_DEBUG
        !           572:                if (adb_debug)
        !           573:                        pm_printerr("driver does not supported this event.",
        !           574:                            rval, pmdata.num_data, pmdata.data);
        !           575: #endif
        !           576:        }
        !           577:
        !           578:        splx(s);
        !           579:
        !           580:        return (1);
        !           581: }
        !           582:
        !           583:
        !           584:
        !           585: /*
        !           586:  * Functions for the PB Duo series and the PB 5XX series
        !           587:  */
        !           588:
        !           589: /*
        !           590:  * Receive data from PM for the PB Duo series and the PB 5XX series
        !           591:  */
        !           592: int
        !           593: pm_receive_pm2(u_char *data)
        !           594: {
        !           595:        int i;
        !           596:        int rval;
        !           597:
        !           598:        rval = 0xffffcd34;
        !           599:
        !           600:        switch (1) {
        !           601:        default:
        !           602:                /* set VIA SR to input mode */
        !           603:                via_reg(VIA1, vACR) |= 0x0c;
        !           604:                via_reg(VIA1, vACR) &= ~0x10;
        !           605:                i = PM_SR();
        !           606:
        !           607:                PM_SET_STATE_ACKOFF();
        !           608:                if (pm_wait_busy((int)ADBDelay*32) != 0)
        !           609:                        break;          /* timeout */
        !           610:
        !           611:                PM_SET_STATE_ACKON();
        !           612:                rval = 0xffffcd33;
        !           613:                if (pm_wait_free((int)ADBDelay*32) == 0)
        !           614:                        break;          /* timeout */
        !           615:
        !           616:                *data = PM_SR();
        !           617:                rval = 0;
        !           618:
        !           619:                break;
        !           620:        }
        !           621:
        !           622:        PM_SET_STATE_ACKON();
        !           623:        via_reg(VIA1, vACR) |= 0x1c;
        !           624:
        !           625:        return rval;
        !           626: }
        !           627:
        !           628:
        !           629:
        !           630: /*
        !           631:  * Send data to PM for the PB Duo series and the PB 5XX series
        !           632:  */
        !           633: int
        !           634: pm_send_pm2(u_char data)
        !           635: {
        !           636:        int rval;
        !           637:
        !           638:        via_reg(VIA1, vACR) |= 0x1c;
        !           639:        PM_SR() = data;
        !           640:
        !           641:        PM_SET_STATE_ACKOFF();
        !           642:        if (pm_wait_busy((int)ADBDelay*32) == 0) {
        !           643:                PM_SET_STATE_ACKON();
        !           644:                if (pm_wait_free((int)ADBDelay*32) != 0)
        !           645:                        rval = 0;
        !           646:                else
        !           647:                        rval = 0xffffcd35;
        !           648:        } else {
        !           649:                rval = 0xffffcd36;
        !           650:        }
        !           651:
        !           652:        PM_SET_STATE_ACKON();
        !           653:        via_reg(VIA1, vACR) |= 0x1c;
        !           654:
        !           655:        return rval;
        !           656: }
        !           657:
        !           658:
        !           659:
        !           660: /*
        !           661:  * My PMgrOp routine for the PB Duo series and the PB 5XX series
        !           662:  */
        !           663: int
        !           664: pm_pmgrop_pm2(PMData *pmdata)
        !           665: {
        !           666:        int i;
        !           667:        int s;
        !           668:        u_char via1_vIER;
        !           669:        int rval = 0;
        !           670:        int num_pm_data = 0;
        !           671:        u_char pm_cmd;
        !           672:        short pm_num_rx_data;
        !           673:        u_char pm_data;
        !           674:        u_char *pm_buf;
        !           675:
        !           676:        s = splhigh();
        !           677:
        !           678:        /* disable all inetrrupts but PM */
        !           679:        via1_vIER = 0x10;
        !           680:        via1_vIER &= via_reg(VIA1, vIER);
        !           681:        via_reg(VIA1, vIER) = via1_vIER;
        !           682:        if (via1_vIER != 0x0)
        !           683:                via1_vIER |= 0x80;
        !           684:
        !           685:        switch (pmdata->command) {
        !           686:        default:
        !           687:                /* wait until PM is free */
        !           688:                pm_cmd = (u_char)(pmdata->command & 0xff);
        !           689:                rval = 0xcd38;
        !           690:                if (pm_wait_free(ADBDelay * 4) == 0)
        !           691:                        break;                  /* timeout */
        !           692:
        !           693:                if (HwCfgFlags3 & 0x00200000) {
        !           694:                        /* PB 160, PB 165(c), PB 180(c)? */
        !           695:                        int xdelay = ADBDelay * 16;
        !           696:
        !           697:                        via_reg(VIA2, vDirA) = 0x00;
        !           698:                        while ((via_reg(VIA2, 0x200) == 0x07) &&
        !           699:                            (xdelay >= 0))
        !           700:                                xdelay--;
        !           701:
        !           702:                        if (xdelay < 0) {
        !           703:                                rval = 0xffffcd38;
        !           704:                                break;          /* timeout */
        !           705:                        }
        !           706:                }
        !           707:
        !           708:                /* send PM command */
        !           709:                if ((rval = pm_send_pm2((u_char)(pm_cmd & 0xff))))
        !           710:                        break;                          /* timeout */
        !           711:
        !           712:                /* send number of PM data */
        !           713:                num_pm_data = pmdata->num_data;
        !           714:                if (HwCfgFlags3 & 0x00020000) {         /* PB Duo, PB 5XX */
        !           715:                        if (pm_send_cmd_type[pm_cmd] < 0) {
        !           716:                                if ((rval = pm_send_pm2((u_char)(num_pm_data & 0xff))) != 0)
        !           717:                                        break;          /* timeout */
        !           718:                                pmdata->command = 0;
        !           719:                        }
        !           720:                } else {                                /* PB 1XX series ? */
        !           721:                        if ((rval = pm_send_pm2((u_char)(num_pm_data & 0xff))) != 0)
        !           722:                                break;                  /* timeout */
        !           723:                }
        !           724:                /* send PM data */
        !           725:                pm_buf = (u_char *)pmdata->s_buf;
        !           726:                for (i = 0 ; i < num_pm_data; i++)
        !           727:                        if ((rval = pm_send_pm2(pm_buf[i])) != 0)
        !           728:                                break;                  /* timeout */
        !           729:                if (i != num_pm_data)
        !           730:                        break;                          /* timeout */
        !           731:
        !           732:
        !           733:                /* check if PM will send me data  */
        !           734:                pm_num_rx_data = pm_receive_cmd_type[pm_cmd];
        !           735:                pmdata->num_data = pm_num_rx_data;
        !           736:                if (pm_num_rx_data == 0) {
        !           737:                        rval = 0;
        !           738:                        break;                          /* no return data */
        !           739:                }
        !           740:
        !           741:                /* receive PM command */
        !           742:                pm_data = pmdata->command;
        !           743:                if (HwCfgFlags3 & 0x00020000) {         /* PB Duo, PB 5XX */
        !           744:                        pm_num_rx_data--;
        !           745:                        if (pm_num_rx_data == 0)
        !           746:                                if ((rval = pm_receive_pm2(&pm_data)) != 0) {
        !           747:                                        rval = 0xffffcd37;
        !           748:                                        break;
        !           749:                                }
        !           750:                        pmdata->command = pm_data;
        !           751:                } else {                                /* PB 1XX series ? */
        !           752:                        if ((rval = pm_receive_pm2(&pm_data)) != 0) {
        !           753:                                rval = 0xffffcd37;
        !           754:                                break;
        !           755:                        }
        !           756:                        pmdata->command = pm_data;
        !           757:                }
        !           758:
        !           759:                /* receive number of PM data */
        !           760:                if (HwCfgFlags3 & 0x00020000) {         /* PB Duo, PB 5XX */
        !           761:                        if (pm_num_rx_data < 0) {
        !           762:                                if ((rval = pm_receive_pm2(&pm_data)) != 0)
        !           763:                                        break;          /* timeout */
        !           764:                                num_pm_data = pm_data;
        !           765:                        } else
        !           766:                                num_pm_data = pm_num_rx_data;
        !           767:                        pmdata->num_data = num_pm_data;
        !           768:                } else {                                /* PB 1XX serias ? */
        !           769:                        if ((rval = pm_receive_pm2(&pm_data)) != 0)
        !           770:                                break;                  /* timeout */
        !           771:                        num_pm_data = pm_data;
        !           772:                        pmdata->num_data = num_pm_data;
        !           773:                }
        !           774:
        !           775:                /* receive PM data */
        !           776:                pm_buf = (u_char *)pmdata->r_buf;
        !           777:                for (i = 0; i < num_pm_data; i++) {
        !           778:                        if ((rval = pm_receive_pm2(&pm_data)) != 0)
        !           779:                                break;                  /* timeout */
        !           780:                        pm_buf[i] = pm_data;
        !           781:                }
        !           782:
        !           783:                rval = 0;
        !           784:        }
        !           785:
        !           786:        /* restore former value */
        !           787:        via_reg(VIA1, vIER) = via1_vIER;
        !           788:        splx(s);
        !           789:
        !           790:        return rval;
        !           791: }
        !           792:
        !           793:
        !           794: /*
        !           795:  * My PM interrupt routine for the PB Duo series and the PB 5XX series
        !           796:  */
        !           797: int
        !           798: pm_intr_pm2(void *arg)
        !           799: {
        !           800:        int s;
        !           801:        int rval;
        !           802:        PMData pmdata;
        !           803:
        !           804:        s = splhigh();
        !           805:
        !           806:        PM_VIA_CLR_INTR();                      /* clear VIA1 interrupt */
        !           807:                                                /* ask PM what happend */
        !           808:        pmdata.command = 0x78;
        !           809:        pmdata.num_data = 0;
        !           810:        pmdata.s_buf = &pmdata.data[2];
        !           811:        pmdata.r_buf = &pmdata.data[2];
        !           812:        rval = pm_pmgrop_pm2(&pmdata);
        !           813:        if (rval != 0) {
        !           814: #ifdef ADB_DEBUG
        !           815:                if (adb_debug)
        !           816:                        printf("pm: PM is not ready. error code: %08x\n", rval);
        !           817: #endif
        !           818:                splx(s);
        !           819:        }
        !           820:
        !           821:        switch ((u_int)(pmdata.data[2] & 0xff)) {
        !           822:        case 0x00:                      /* 1 sec interrupt? */
        !           823:                break;
        !           824:        case 0x80:                      /* 1 sec interrupt? */
        !           825:                pm_counter++;
        !           826:                break;
        !           827:        case 0x08:                      /* Brightness/Contrast button on LCD panel */
        !           828:                /* get brightness and contrast of the LCD */
        !           829:                pm_LCD_brightness = (u_int)pmdata.data[3] & 0xff;
        !           830:                pm_LCD_contrast = (u_int)pmdata.data[4] & 0xff;
        !           831: /*
        !           832:                pm_printerr("#08", rval, pmdata.num_data, pmdata.data);
        !           833:                pmdata.command = 0x33;
        !           834:                pmdata.num_data = 1;
        !           835:                pmdata.s_buf = pmdata.data;
        !           836:                pmdata.r_buf = pmdata.data;
        !           837:                pmdata.data[0] = pm_LCD_contrast;
        !           838:                rval = pm_pmgrop_pm2(&pmdata);
        !           839:                pm_printerr("#33", rval, pmdata.num_data, pmdata.data);
        !           840: */
        !           841:                /* this is an experimental code */
        !           842:                pmdata.command = 0x41;
        !           843:                pmdata.num_data = 1;
        !           844:                pmdata.s_buf = pmdata.data;
        !           845:                pmdata.r_buf = pmdata.data;
        !           846:                pm_LCD_brightness = 0x7f - pm_LCD_brightness / 2;
        !           847:                if (pm_LCD_brightness < 0x25)
        !           848:                        pm_LCD_brightness = 0x25;
        !           849:                if (pm_LCD_brightness > 0x5a)
        !           850:                        pm_LCD_brightness = 0x7f;
        !           851:                pmdata.data[0] = pm_LCD_brightness;
        !           852:                rval = pm_pmgrop_pm2(&pmdata);
        !           853:                break;
        !           854:        case 0x10:                      /* ADB data that were requested by TALK command */
        !           855:        case 0x14:
        !           856:                pm_adb_get_TALK_result(&pmdata);
        !           857:                break;
        !           858:        case 0x16:                      /* ADB device event */
        !           859:        case 0x18:
        !           860:        case 0x1e:
        !           861:                pm_adb_get_ADB_data(&pmdata);
        !           862:                break;
        !           863:        default:
        !           864: #ifdef ADB_DEBUG
        !           865:                if (adb_debug)
        !           866:                        pm_printerr("driver does not supported this event.",
        !           867:                            pmdata.data[2], pmdata.num_data,
        !           868:                            pmdata.data);
        !           869: #endif
        !           870:                break;
        !           871:        }
        !           872:
        !           873:        splx(s);
        !           874:
        !           875:        return (1);
        !           876: }
        !           877:
        !           878:
        !           879: /*
        !           880:  * My PMgrOp routine
        !           881:  */
        !           882: int
        !           883: pmgrop(PMData *pmdata)
        !           884: {
        !           885:        switch (pmHardware) {
        !           886:        case PM_HW_PB1XX:
        !           887:                return (pm_pmgrop_pm1(pmdata));
        !           888:                break;
        !           889:        case PM_HW_PB5XX:
        !           890:                return (pm_pmgrop_pm2(pmdata));
        !           891:                break;
        !           892:        default:
        !           893:                return 1;
        !           894:        }
        !           895: }
        !           896:
        !           897: int
        !           898: pm_intr(void *arg)
        !           899: {
        !           900:        switch (pmHardware) {
        !           901:        case PM_HW_PB1XX:
        !           902:                return (pm_intr_pm1(arg));
        !           903:        case PM_HW_PB5XX:
        !           904:                return (pm_intr_pm2(arg));
        !           905:        default:
        !           906:                return (-1);
        !           907:        }
        !           908: }
        !           909:
        !           910: void
        !           911: pm_hw_setup(struct device *self)
        !           912: {
        !           913:        switch (pmHardware) {
        !           914:        case PM_HW_PB1XX:
        !           915:                via1_register_irq(4, pm_intr_pm1, self, self->dv_xname);
        !           916:                PM_VIA_CLR_INTR();
        !           917:                break;
        !           918:        case PM_HW_PB5XX:
        !           919:                via1_register_irq(4, pm_intr_pm2, self, self->dv_xname);
        !           920:                PM_VIA_CLR_INTR();
        !           921:                break;
        !           922:        default:
        !           923:                break;
        !           924:        }
        !           925: }
        !           926:
        !           927:
        !           928: /*
        !           929:  * Synchronous ADBOp routine for the Power Manager
        !           930:  */
        !           931: int
        !           932: pm_adb_op(u_char *buffer, void *compRout, void *data, int command)
        !           933: {
        !           934:        int i;
        !           935:        int s;
        !           936:        int rval;
        !           937:        int xdelay;
        !           938:        PMData pmdata;
        !           939:        struct adbCommand packet;
        !           940:
        !           941:        if (adbWaiting == 1)
        !           942:                return 1;
        !           943:
        !           944:        s = splhigh();
        !           945:        via_reg(VIA1, vIER) = 0x10;
        !           946:
        !           947:        adbBuffer = buffer;
        !           948:        adbCompRout = compRout;
        !           949:        adbCompData = data;
        !           950:
        !           951:        pmdata.command = 0x20;
        !           952:        pmdata.s_buf = pmdata.data;
        !           953:        pmdata.r_buf = pmdata.data;
        !           954:
        !           955:        if ((command & 0xc) == 0x8) {           /* if the command is LISTEN, add number of ADB data to number of PM data */
        !           956:                if (buffer != (u_char *)0)
        !           957:                        pmdata.num_data = buffer[0] + 3;
        !           958:        } else {
        !           959:                pmdata.num_data = 3;
        !           960:        }
        !           961:
        !           962:        pmdata.data[0] = (u_char)(command & 0xff);
        !           963:        pmdata.data[1] = 0;
        !           964:        if ((command & 0xc) == 0x8) {           /* if the command is LISTEN, copy ADB data to PM buffer */
        !           965:                if ((buffer != (u_char *)0) && (buffer[0] <= 24)) {
        !           966:                        pmdata.data[2] = buffer[0];             /* number of data */
        !           967:                        for (i = 0; i < buffer[0]; i++)
        !           968:                                pmdata.data[3 + i] = buffer[1 + i];
        !           969:                } else
        !           970:                        pmdata.data[2] = 0;
        !           971:        } else
        !           972:                pmdata.data[2] = 0;
        !           973:
        !           974:        if ((command & 0xc) != 0xc) {           /* if the command is not TALK */
        !           975:                /* set up stuff fNULLor adb_pass_up */
        !           976:                packet.data[0] = 1 + pmdata.data[2];
        !           977:                packet.data[1] = command;
        !           978:                for (i = 0; i < pmdata.data[2]; i++)
        !           979:                        packet.data[i+2] = pmdata.data[i+3];
        !           980:                packet.saveBuf = adbBuffer;
        !           981:                packet.compRout = adbCompRout;
        !           982:                packet.compData = adbCompData;
        !           983:                packet.cmd = command;
        !           984:                packet.unsol = 0;
        !           985:                packet.ack_only = 1;
        !           986:                adb_polling = 1;
        !           987:                adb_pass_up(&packet);
        !           988:                adb_polling = 0;
        !           989:        }
        !           990:
        !           991:        rval = pmgrop(&pmdata);
        !           992:        if (rval != 0) {
        !           993:                splx(s);
        !           994:                return 1;
        !           995:        }
        !           996:
        !           997:        adbWaiting = 1;
        !           998:        adbWaitingCmd = command;
        !           999:
        !          1000:        PM_VIA_INTR_ENABLE();
        !          1001:
        !          1002:        /* wait until the PM interrupt has occurred */
        !          1003:        xdelay = 0x80000;
        !          1004:        while (adbWaiting == 1) {
        !          1005:                switch (mac68k_machine.machineid) {
        !          1006:                case MACH_MACPB150:
        !          1007:                case MACH_MACPB210:
        !          1008:                case MACH_MACPB230:     /* daishi tested with Duo230 */
        !          1009:                case MACH_MACPB250:
        !          1010:                case MACH_MACPB270:
        !          1011:                case MACH_MACPB280:
        !          1012:                case MACH_MACPB280C:
        !          1013:                case MACH_MACPB190:
        !          1014:                case MACH_MACPB190CS:
        !          1015:                        pm_intr((void *)0);
        !          1016:                        break;
        !          1017:                default:
        !          1018:                        if ((via_reg(VIA1, vIFR) & 0x10) == 0x10)
        !          1019:                                pm_intr((void *)0);
        !          1020:                        break;
        !          1021:                }
        !          1022: #ifdef PM_GRAB_SI
        !          1023:                (void)intr_dispatch(0x70);      /* grab any serial interrupts */
        !          1024: #endif
        !          1025:                if ((--xdelay) < 0) {
        !          1026:                        splx(s);
        !          1027:                        return 1;
        !          1028:                }
        !          1029:        }
        !          1030:
        !          1031:        /* this command enables the interrupt by operating ADB devices */
        !          1032:        if (HwCfgFlags3 & 0x00020000) {         /* PB Duo series, PB 5XX series */
        !          1033:                pmdata.command = 0x20;
        !          1034:                pmdata.num_data = 4;
        !          1035:                pmdata.s_buf = pmdata.data;
        !          1036:                pmdata.r_buf = pmdata.data;
        !          1037:                pmdata.data[0] = 0x00;
        !          1038:                pmdata.data[1] = 0x86;  /* magic spell for awaking the PM */
        !          1039:                pmdata.data[2] = 0x00;
        !          1040:                pmdata.data[3] = 0x0c;  /* each bit may express the existent ADB device */
        !          1041:        } else {                                /* PB 1XX series */
        !          1042:                pmdata.command = 0x20;
        !          1043:                pmdata.num_data = 3;
        !          1044:                pmdata.s_buf = pmdata.data;
        !          1045:                pmdata.r_buf = pmdata.data;
        !          1046:                pmdata.data[0] = (u_char)(command & 0xf0) | 0xc;
        !          1047:                pmdata.data[1] = 0x04;
        !          1048:                pmdata.data[2] = 0x00;
        !          1049:        }
        !          1050:        rval = pmgrop(&pmdata);
        !          1051:
        !          1052:        splx(s);
        !          1053:        return rval;
        !          1054: }
        !          1055:
        !          1056:
        !          1057: void
        !          1058: pm_adb_get_TALK_result(PMData *pmdata)
        !          1059: {
        !          1060:        int i;
        !          1061:        struct adbCommand packet;
        !          1062:
        !          1063:        /* set up data for adb_pass_up */
        !          1064:        packet.data[0] = pmdata->num_data-1;
        !          1065:        packet.data[1] = pmdata->data[3];
        !          1066:        for (i = 0; i <packet.data[0]-1; i++)
        !          1067:                packet.data[i+2] = pmdata->data[i+4];
        !          1068:
        !          1069:        packet.saveBuf = adbBuffer;
        !          1070:        packet.compRout = adbCompRout;
        !          1071:        packet.compData = adbCompData;
        !          1072:        packet.unsol = 0;
        !          1073:        packet.ack_only = 0;
        !          1074:        adb_polling = 1;
        !          1075:        adb_pass_up(&packet);
        !          1076:        adb_polling = 0;
        !          1077:
        !          1078:        adbWaiting = 0;
        !          1079:        adbBuffer = (long)0;
        !          1080:        adbCompRout = (long)0;
        !          1081:        adbCompData = (long)0;
        !          1082: }
        !          1083:
        !          1084:
        !          1085: void
        !          1086: pm_adb_get_ADB_data(PMData *pmdata)
        !          1087: {
        !          1088:        int i;
        !          1089:        struct adbCommand packet;
        !          1090:
        !          1091:        /* set up data for adb_pass_up */
        !          1092:        packet.data[0] = pmdata->num_data-1;    /* number of raw data */
        !          1093:        packet.data[1] = pmdata->data[3];       /* ADB command */
        !          1094:        for (i = 0; i <packet.data[0]-1; i++)
        !          1095:                packet.data[i+2] = pmdata->data[i+4];
        !          1096:        packet.unsol = 1;
        !          1097:        packet.ack_only = 0;
        !          1098:        adb_pass_up(&packet);
        !          1099: }
        !          1100:
        !          1101:
        !          1102: void
        !          1103: pm_adb_poll_next_device_pm1(PMData *pmdata)
        !          1104: {
        !          1105:        int i;
        !          1106:        int ndid;
        !          1107:        u_short bendid = 0x1;
        !          1108:        int rval;
        !          1109:        PMData tmp_pmdata;
        !          1110:
        !          1111:        /* find another existent ADB device to poll */
        !          1112:        for (i = 1; i < 16; i++) {
        !          1113:                ndid = (ADB_CMDADDR(pmdata->data[3]) + i) & 0xf;
        !          1114:                bendid <<= ndid;
        !          1115:                if ((pm_existent_ADB_devices & bendid) != 0)
        !          1116:                        break;
        !          1117:        }
        !          1118:
        !          1119:        /* poll the other device */
        !          1120:        tmp_pmdata.command = 0x20;
        !          1121:        tmp_pmdata.num_data = 3;
        !          1122:        tmp_pmdata.s_buf = tmp_pmdata.data;
        !          1123:        tmp_pmdata.r_buf = tmp_pmdata.data;
        !          1124:        tmp_pmdata.data[0] = (u_char)(ndid << 4) | 0xc;
        !          1125:        tmp_pmdata.data[1] = 0x04;      /* magic spell for awaking the PM */
        !          1126:        tmp_pmdata.data[2] = 0x00;
        !          1127:        rval = pmgrop(&tmp_pmdata);
        !          1128: }

CVSweb