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