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