[BACK]Return to pm_direct.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / macppc / dev

Annotation of src/sys/arch/macppc/dev/pm_direct.c, Revision 1.9.2.1

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

CVSweb <webmaster@jp.NetBSD.org>