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