KeyLargo.h   [plain text]


/*
 * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * The contents of this file constitute Original Code as defined in and
 * are subject to the Apple Public Source License Version 1.1 (the
 * "License").  You may not use this file except in compliance with the
 * License.  Please obtain a copy of the License at
 * http://www.apple.com/publicsource and read it before using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1998-2001 Apple Computer, Inc.  All rights reserved.
 *
 *  DRI: Dave Radcliffe
 *
 */

#ifndef _IOKIT_KEYLARGO_H
#define _IOKIT_KEYLARGO_H

#include <IOKit/IOLocks.h>

#include <IOKit/platform/AppleMacIO.h>

#include "USBKeyLargo.h"
#include "KeyLargoWatchDogTimer.h"

enum {
    kKeyLargoDeviceId22			= 0x22,				// KeyLargo
	kKeyLargoVersion2			= 2,

    kPangeaDeviceId25			= 0x25,				// Pangea
	kPangeaVersion0				= 0
};

enum {
	// KeyLargo Register Offsets
	kKeyLargoMediaBay						= 0x00034,			// KeyLargo only, reserved on Pangea
	kKeyLargoFCRBase						= 0x00038,
	kKeyLargoFCRCount						= 5,
	kPangeaFCRCount							= 6,
	kKeyLargoFCR0							= 0x00038,
	kKeyLargoFCR1							= 0x0003C,
	kKeyLargoFCR2							= 0x00040,
	kKeyLargoFCR3							= 0x00044,
	kKeyLargoFCR4							= 0x00048,
	kKeyLargoFCR5							= 0x0004C,			// Pangea only
  
	kKeyLargoGTimerFreq						= 18432000UL,
	kKeyLargoWatchDogLowOffset				= 0x15030,
	kKeyLargoWatchDogHighOffset				= 0x15034,
	kKeyLargoCounterLoOffset				= 0x15038,
	kKeyLargoCounterHiOffset				= 0x1503C,
	kKeyLargoWatchDogEnableOffset			= 0x15048,
  
	// MediaBay Register Definitions (KeyLargo only)
	kKeyLargoMB0DevEnable					= 1 << 12,			// MB0_Dev1_Enable_h
	kKeyLargoMB0DevPower					= 1 << 10,			// MB0_Power_l
	kKeyLargoMB0DevReset					= 1 <<  9,			// MB0_Reset_l
	kKeyLargoMB0Enable						= 1 <<  8,			// MB0_Enable_h
	kKeyLargoMB1DevEnable					= 1 << 28,			// MB1_Dev1_Enable_h
	kKeyLargoMB1DevPower					= 1 << 26,			// MB1_Power_l
	kKeyLargoMB1DevReset					= 1 << 25,			// MB1_Reset_l
	kKeyLargoMB1Enable						= 1 << 24,			// MB1_Enable_h
  
	// Feature Control Register 0 Definitions
	kKeyLargoFCR0ChooseSCCB					= 1 << 0,			// ChooseSCCB (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR0ChooseSCCA					= 1 << 1,			// ChooseSCCA
	kKeyLargoFCR0SlowSccPClk				= 1 << 2,			// SlowSccPClk_h
	kKeyLargoFCR0ResetSCC					= 1 << 3,			// ResetScc_h
	kKeyLargoFCR0SccAEnable					= 1 << 4,			// SccAEnable_h
	kKeyLargoFCR0SccBEnable					= 1 << 5,			// SccBEnable_h
	kKeyLargoFCR0SccCellEnable				= 1 << 6,			// SCC_Cell_EN_h
	kKeyLargoFCR0ChooseVIA					= 1 << 7,			// ChooseVIA
	
	kKeyLargoFCR0HighBandFor1MB				= 1 << 8,			// HighBandFor1MB (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR0UseIRSource2				= 1 << 9,			// UseIRSource2 (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR0UseIRSource1				= 1 << 10,			// UseIRSource1 (KeyLargo only)
	kPangeaFCR0USB0PMIEnable				= 1 << 10,			// USB0_PMI_En_h (Pangea only)
	kKeyLargoFCR0IRDASWReset				= 1 << 11,			// IRDA_SW_Reset_h (KeyLargo only)
	kPangeaFCR0USB0RefSuspendSel			= 1 << 11,			// USB0_RefSuspendSel_h (Pangea only)
	kKeyLargoFCR0IRDADefault1				= 1 << 12,			// IRDA_Default1 (KeyLargo only)
	kPangeaFCR0USB0RefSuspend				= 1 << 12,			// USB0_RefSuspend_h (Pangea only)
	kKeyLargoFCR0IRDADefault0				= 1 << 13,			// IRDA_Default0 (KeyLargo only)
	kPangeaFCR0USB0PadSuspendSel			= 1 << 13,			// USB0_PadSuspendSel_h (Pangea only)
	kKeyLargoFCR0IRDAFastCon				= 1 << 14,			// IRDA_FAST_CON (KeyLargo only)
	kPangeaFCR0USB1PMIEnable				= 1 << 14,			// USB0_PadSuspendSel_h (Pangea only)
	kKeyLargoFCR0IRDAEnable					= 1 << 15,			// IRDAEnable_h (KeyLargo only)
	kPangeaFCR0USB1RefSuspendSel			= 1 << 15,			// USB1_RefSuspendSel_h (Pangea only)
	
	kKeyLargoFCR0IRDAClk32Enable			= 1 << 16,			// IRDA_Clk32_EN_h (KeyLargo only)
	kPangeaFCR0USB1RefSuspend				= 1 << 16,			// USB1_RefSuspend_h (Pangea only)
	kKeyLargoFCR0IRDAClk19Enable			= 1 << 17,			// IRDA_Clk19_EN_h (KeyLargo only)
	kPangeaFCR0USB1PadSuspendSel			= 1 << 17,			// USB1_PadSuspendSel_h (Pangea only)
	kKeyLargoFCR0USB0PadSuspend0			= 1 << 18,			// USB0_PadSuspend0_h
	kKeyLargoFCR0USB0PadSuspend1			= 1 << 19,			// USB0_PadSuspend1_h
	kKeyLargoFCR0USB0CellEnable				= 1 << 20,			// USB0_Cell_EN_h
	kKeyLargoFCR0USB1PadSuspend0			= 1 << 22,			// USB1_PadSuspend0_h
	kKeyLargoFCR0USB1PadSuspend1			= 1 << 23,			// USB1_PadSuspend1_h
	
	kKeyLargoFCR0USB1CellEnable				= 1 << 24,			// USB1_Cell_EN_h
	kKeyLargoFCR0USBRefSuspend				= 1 << 28,			// USB_RefSuspend_h
  
	// Feature Control Register 1 Definitions
	kKeyLargoFCR1AudioSel22MClk				= 1 << 1,			// Audio_Sel22MClk
	kKeyLargoFCR1AudioClkEnable				= 1 << 3,			// AudClkEnBit_h
	kKeyLargoFCR1AudioClkOutEnable			= 1 << 5,			// AudioClkOut_EN_h
	kKeyLargoFCR1AudioCellEnable			= 1 << 6,			// AUDIO_Cell_EN_h
	kKeyLargoFCR1ChooseAudio				= 1 << 7,			// ChooseAudio
	
	kKeyLargoFCR1ChooseI2S0					= 1 << 9,			// ChooseI2S0 (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR1I2S0CellEnable				= 1 << 10,			// I2S0_Cell_EN_h
	kKeyLargoFCR1I2S0ClkEnable				= 1 << 12,			// I2S0_ClkEnBit_h
	kKeyLargoFCR1I2S0Enable					= 1 << 13,			// I2S0Enable_h
	
	kKeyLargoFCR1I2S1CellEnable				= 1 << 17,			// I2S1_Cell_EN_h
	kKeyLargoFCR1I2S1ClkEnable				= 1 << 19,			// I2S1_ClkEnBit_h
	kKeyLargoFCR1I2S1Enable					= 1 << 20,			// I2S1Enable_h
	kKeyLargoFCR1EIDE0Enable				= 1 << 23,			// EIDE0_EN_h (KeyLargo only - reserved on Pangea)
	
	kKeyLargoFCR1EIDE0Reset					= 1 << 24,			// EIDE0_Reset_l (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR1EIDE1Enable				= 1 << 26,			// EIDE1_EN_h (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR1EIDE1Reset					= 1 << 27,			// EIDE1_Reset_l (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR1UIDEEnable					= 1 << 29,			// IDE_UD_EN_h
	kKeyLargoFCR1UIDEReset					= 1 << 30,			// UltraIDE_Reset_l
  
	// Feature Control Register 2 Definitions
	kKeyLargoFCR2IOBusEnable				= 1 << 1,			// IOBus_EN_h
	kKeyLargoFCR2SleepState					= 1 << 8,			// SleepStateBit_h (KeyLargo only)
	kPangeaFCR2StopAllKLClocks				= 1 << 8,			// StopAllKLClocks (Pangea only)
	kKeyLargoFCR2MPICEnable					= 1 << 17,			// MPIC_Enable_h
	kPangeaCardSlotReset					= 1 << 18,			// CardSlot_Reset_h (Pangea only - reserved on KeyLargo)
	kKeyLargoFCR2AltDataOut					= 1 << 25,			// AltDataOut - spare on Pangea
  
	// Feature Control Register 3 Definitions
	kKeyLargoFCR3ShutdownPLLTotal			= 1 << 0,			// Shutdown_PLL_Total
	kKeyLargoFCR3ShutdownPLLKW6				= 1 << 1,			// Shutdown_PLLKW6
	kKeyLargoFCR3ShutdownPLLKW4				= 1 << 2,			// Shutdown_PLLKW4
	kKeyLargoFCR3ShutdownPLLKW35			= 1 << 3,			// Shutdown_PLLKW35
	kKeyLargoFCR3ShutdownPLLKW12			= 1 << 4,			// Shutdown_PLLKW12 (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR3PLLReset					= 1 << 5,			// PLL_Reset
	kKeyLargoFCR3ShutdownPLL2X				= 1 << 7,			// Shutdown_PLL2X (KeyLargo only - reserved on Pangea)
	
	kKeyLargoFCR3Clk66Enable				= 1 << 8,			// Clk66_EN_h (KeyLargo only - reserved on Pangea)
	kKeyLargoFCR3Clk49Enable				= 1 << 9,			// Clk49_EN_h
	kKeyLargoFCR3Clk45Enable				= 1 << 10,			// Clk45_EN_h
	kKeyLargoFCR3Clk31Enable				= 1 << 11,			// Clk31_EN_h
	kKeyLargoFCR3TimerClk18Enable			= 1 << 12,			// TIMER_Clk18_EN_h
	kKeyLargoFCR3I2S1Clk18Enable			= 1 << 13,			// I2S1_Clk18_EN_h
	kKeyLargoFCR3I2S0Clk18Enable			= 1 << 14,			// I2S0_Clk18_EN_h
	kKeyLargoFCR3ViaClk16Enable				= 1 << 15,			// VIA_Clk16_EN_h
	
	kKeyLargoFCR3Stopping33Enabled			= 1 << 19,			// Stopping33Enabled_h (KeyLargo only)
	kPangeaFCR3PLLEnableTest				= 1 << 19,			// PLL_EN_TST (Pangea only)
  
	// Feature Control Register 4 Definitions
	kKeyLargoFCR4Port1DisconnectSelect		= 1 << 0,			// Port1_DisconnectSelect
	kKeyLargoFCR4Port1ConnectSelect			= 1 << 1,			// Port1_ConnectSelect
	kKeyLargoFCR4Port1ResumeSelect			= 1 << 2,			// Port1_ResumeSelect
	kKeyLargoFCR4Port1Enable				= 1 << 3,			// Port1_Enable
	kKeyLargoFCR4Port1Disconnect			= 1 << 4,			// Port1_Disconnect
	kKeyLargoFCR4Port1Connect				= 1 << 5,			// Port1_Connect
	kKeyLargoFCR4Port1Resume				= 1 << 6,			// Port1_Resume
  
	kKeyLargoFCR4Port2DisconnectSelect		= 1 << 8,			// Port2_DisconnectSelect
	kKeyLargoFCR4Port2ConnectSelect			= 1 << 9,			// Port2_ConnectSelect
	kKeyLargoFCR4Port2ResumeSelect			= 1 << 10,			// Port2_ResumeSelect
	kKeyLargoFCR4Port2Enable				= 1 << 11,			// Port2_Enable
	kKeyLargoFCR4Port2Disconnect			= 1 << 12,			// Port2_Disconnect
	kKeyLargoFCR4Port2Connect				= 1 << 13,			// Port2_Connect
	kKeyLargoFCR4Port2Resume				= 1 << 14,			// Port2_Resume
  
	kKeyLargoFCR4Port3DisconnectSelect		= 1 << 16,			// Port3_DisconnectSelect
	kKeyLargoFCR4Port3ConnectSelect			= 1 << 17,			// Port3_ConnectSelect
	kKeyLargoFCR4Port3ResumeSelect			= 1 << 18,			// Port3_ResumeSelect
	kKeyLargoFCR4Port3Enable				= 1 << 19,			// Port3_Enable
	kKeyLargoFCR4Port3Disconnect			= 1 << 20,			// Port3_Disconnect
	kKeyLargoFCR4Port3Connect				= 1 << 21,			// Port3_Connect
	kKeyLargoFCR4Port3Resume				= 1 << 22,			// Port3_Resume
  
	kKeyLargoFCR4Port4DisconnectSelect		= 1 << 24,			// Port4_DisconnectSelect
	kKeyLargoFCR4Port4ConnectSelect			= 1 << 25,			// Port4_ConnectSelect
	kKeyLargoFCR4Port4ResumeSelect			= 1 << 26,			// Port4_ResumeSelect
	kKeyLargoFCR4Port4Enable				= 1 << 27,			// Port4_Enable
	kKeyLargoFCR4Port4Disconnect			= 1 << 28,			// Port4_Disconnect
	kKeyLargoFCR4Port4Connect				= 1 << 29,			// Port4_Connect
	kKeyLargoFCR4Port4Resume				= 1 << 30,			// Port4_Resume
	
	// Feature Control Register 5 Definitions (Pangea only, FCR5 does not exist on KeyLargo)
	kPangeaFCR5ViaUseClk31					= 1 << 0,				// ViaUseClk31
	kPangeaFCR5SCCUseClk31					= 1 << 1,				// SCCUseClk31
	kPangeaFCR5PwmClk32Enable				= 1 << 2,				// PwmClk32_EN_h
	kPangeaFCR5Clk3_68Enable				= 1 << 4,				// Clk3_68_EN_h
	kPangeaFCR5Clk32Enable					= 1 << 5,				// Clk32_EN_h
};

enum {
  // Feature Control Register 0 Sleep Settings for KeyLargo
  kKeyLargoFCR0SleepBitsSet				= (kKeyLargoFCR0USBRefSuspend),
  
  kKeyLargoFCR0SleepBitsClear			= (kKeyLargoFCR0SccAEnable |
											kKeyLargoFCR0SccBEnable |
											kKeyLargoFCR0SccCellEnable |
											kKeyLargoFCR0IRDAEnable |
											kKeyLargoFCR0IRDAClk32Enable |
											kKeyLargoFCR0IRDAClk19Enable),
  
  // Feature Control Register 1 Sleep Settings
  kKeyLargoFCR1SleepBitsSet				= 0,
  
  kKeyLargoFCR1SleepBitsClear			= (kKeyLargoFCR1AudioSel22MClk |
											kKeyLargoFCR1AudioClkEnable |
											kKeyLargoFCR1AudioClkOutEnable |
											kKeyLargoFCR1AudioCellEnable |
											kKeyLargoFCR1I2S0CellEnable |
											kKeyLargoFCR1I2S0ClkEnable |
											kKeyLargoFCR1I2S0Enable |
											kKeyLargoFCR1I2S1CellEnable |
											kKeyLargoFCR1I2S1ClkEnable |
											kKeyLargoFCR1I2S1Enable |
											kKeyLargoFCR1EIDE0Enable |
											kKeyLargoFCR1EIDE1Enable |
											kKeyLargoFCR1UIDEEnable |
											kKeyLargoFCR1EIDE0Reset |
											kKeyLargoFCR1EIDE1Reset),
  
  // Feature Control Register 2 Sleep Settings
  kKeyLargoFCR2SleepBitsSet				= 0,
  
  kKeyLargoFCR2SleepBitsClear			= kKeyLargoFCR2IOBusEnable,
  
  // Feature Control Register 3 Sleep and Restart Settings
  kKeyLargoFCR3SleepBitsSet				= (kKeyLargoFCR3ShutdownPLLKW6 |
											kKeyLargoFCR3ShutdownPLLKW4 |
											kKeyLargoFCR3ShutdownPLLKW35 |
											kKeyLargoFCR3ShutdownPLLKW12),
  
  kKeyLargoFCR3SleepBitsClear			= (kKeyLargoFCR3Clk66Enable |
											kKeyLargoFCR3Clk49Enable |
											kKeyLargoFCR3Clk45Enable |
											kKeyLargoFCR3Clk31Enable |
											kKeyLargoFCR3TimerClk18Enable |
											kKeyLargoFCR3I2S1Clk18Enable |
											kKeyLargoFCR3I2S0Clk18Enable |
											kKeyLargoFCR3ViaClk16Enable),
  
  kKeyLargoFCR3RestartBitsSet			= (kKeyLargoFCR3ShutdownPLLKW6 |
											kKeyLargoFCR3ShutdownPLLKW4 |
											kKeyLargoFCR3ShutdownPLLKW35),
  
  kKeyLargoFCR3RestartBitsClear			= (kKeyLargoFCR3Clk66Enable |
											kKeyLargoFCR3Clk49Enable |
											kKeyLargoFCR3Clk45Enable |
											kKeyLargoFCR3Clk31Enable |
											kKeyLargoFCR3I2S1Clk18Enable |
											kKeyLargoFCR3I2S0Clk18Enable),
  
  // Feature Control Register 4 Sleep Settings
  // Marco since we are going to have two different controllers for each usb, I am going
  // to separate each bus bit set:
    kKeyLargoFCR4USB0SleepBitsSet		= (kKeyLargoFCR4Port1DisconnectSelect |
											kKeyLargoFCR4Port1ConnectSelect |
											kKeyLargoFCR4Port1ResumeSelect |
											kKeyLargoFCR4Port1Enable |
											kKeyLargoFCR4Port2DisconnectSelect |
											kKeyLargoFCR4Port2ConnectSelect |
											kKeyLargoFCR4Port2ResumeSelect |
											kKeyLargoFCR4Port2Enable),

    kKeyLargoFCR4USB1SleepBitsSet		= (kKeyLargoFCR4Port3DisconnectSelect |
											kKeyLargoFCR4Port3ConnectSelect |
											kKeyLargoFCR4Port3ResumeSelect |
											kKeyLargoFCR4Port3Enable |
											kKeyLargoFCR4Port4DisconnectSelect |
											kKeyLargoFCR4Port4ConnectSelect |
											kKeyLargoFCR4Port4ResumeSelect |
											kKeyLargoFCR4Port4Enable),

    kKeyLargoFCR4SleepBitsSet			= (kKeyLargoFCR4USB0SleepBitsSet |
											kKeyLargoFCR4USB1SleepBitsSet),

    kKeyLargoFCR4USB0SleepBitsClear		= 0,
    kKeyLargoFCR4USB1SleepBitsClear		= 0,

    kKeyLargoFCR4SleepBitsClear			= kKeyLargoFCR4USB0SleepBitsClear | kKeyLargoFCR4USB1SleepBitsClear
};

// desired state of Pangea FCR registers when sleeping
enum {
	// Feature Control Register 0 Sleep Settings for Pangea
    kPangeaFCR0SleepBitsSet			=	0,
	
    kPangeaFCR0SleepBitsClear		=	kKeyLargoFCR0USB1CellEnable |
											kKeyLargoFCR0USB0CellEnable |
											kKeyLargoFCR0SccCellEnable |
											kKeyLargoFCR0SccBEnable |
											kKeyLargoFCR0SccAEnable,

    // Feature Control Register 1 Sleep Settings
    kPangeaFCR1SleepBitsSet			=	0,
	
    kPangeaFCR1SleepBitsClear		=	kKeyLargoFCR1UIDEEnable |
											kKeyLargoFCR1I2S1Enable |
											kKeyLargoFCR1I2S1ClkEnable |
											kKeyLargoFCR1I2S1CellEnable |
											kKeyLargoFCR1I2S0Enable |
											kKeyLargoFCR1I2S0ClkEnable |
											kKeyLargoFCR1I2S0CellEnable |
											kKeyLargoFCR1AudioCellEnable |
											kKeyLargoFCR1AudioClkOutEnable |
											kKeyLargoFCR1AudioClkEnable |
											kKeyLargoFCR1AudioSel22MClk,
                                                
    // Feature Control Register 2 Sleep Settings
    kPangeaFCR2SleepBitsSet			=	kKeyLargoFCR2AltDataOut,
	
    kPangeaFCR2SleepBitsClear		=	0,

    // Feature Control Register 3 Sleep and Restart Settings
    kPangeaFCR3SleepBitsSet			=	kKeyLargoFCR3ShutdownPLLKW35 |
											kKeyLargoFCR3ShutdownPLLKW4 |
											kKeyLargoFCR3ShutdownPLLKW6,
										
    kPangeaFCR3SleepBitsClear		=	kKeyLargoFCR3ViaClk16Enable |
											kKeyLargoFCR3I2S0Clk18Enable |
											kKeyLargoFCR3I2S1Clk18Enable |
											kKeyLargoFCR3TimerClk18Enable |
											kKeyLargoFCR3Clk31Enable |
											kKeyLargoFCR3Clk45Enable |
											kKeyLargoFCR3Clk49Enable,	

    // do not turn off SPI interface when restarting
	
    kPangeaFCR3RestartBitsSet		=	kKeyLargoFCR3ShutdownPLLKW35 |
											kKeyLargoFCR3ShutdownPLLKW4 |
											kKeyLargoFCR3ShutdownPLLKW6,
										
    kPangeaFCR3RestartBitsClear		=	kKeyLargoFCR3I2S0Clk18Enable |
											kKeyLargoFCR3I2S1Clk18Enable |
											kKeyLargoFCR3Clk31Enable |
											kKeyLargoFCR3Clk45Enable |
											kKeyLargoFCR3Clk49Enable,
                                                
    // Feature Control Register 4 Sleep Settings    
    kPangeaFCR4SleepBitsSet			=	0,
	
    kPangeaFCR4SleepBitsClear		=	0
};

	// Offsets for the registers we wish to save.
	// These come (almost) unchanged from the MacOS9 Power
	// Manager plug-in (p99powerplugin.h)

	// MPIC offsets and registers
	enum {
		kKeyLargoMPICVectorsCount			= 64,
		kKeyLargoMPICIPICount				= 4,
		kKeyLargoMPICTaskPriorityCount		= 4,
		kKeyLargoMPICTimerCount				= 4,
		kKeyLargoMPICBaseOffset				= 0x40000,						// MPIC base offset from start of KeyLargo
	
		kKeyLargoMPICIPI0					= 0x10A0,						// MPIC IPI0 vector/priority register
		kKeyLargoMPICIPI1					= 0x10B0,						// MPIC IPI1 vector/priority register
		kKeyLargoMPICIPI2					= 0x10C0,						// MPIC IPI2 vector/priority register
		kKeyLargoMPICIPI3					= 0x10D0,						// MPIC IPI3 vector/priority register
	
		kKeyLargoMPICSpuriousVector			= 0x10E0,						// MPIC spurious vector register
		kKeyLargoMPICTimeFreq				= 0x10F0,						// MPIC timer frequency reporting register
	
		kKeyLargoMPICTimerBase0				= 0x1110,						// MPIC timer 0 base count register
		kKeyLargoMPICTimerBase1				= 0x1150,						// MPIC timer 1 base count register
		kKeyLargoMPICTimerBase2				= 0x1190,						// MPIC timer 2 base count register
		kKeyLargoMPICTimerBase3				= 0x11D0,						// MPIC timer 3 base count register
	
		kKeyLargoMPICIntSrcSize				= 0x20,
		kKeyLargoMPICIntSrcVectPriBase		= 0x10000,						// MPIC interrupt source vector/priority base offset
		kKeyLargoMPICIntSrcDestBase			= 0x10010,						// MPIC interrupt source destination register base offset
	
		kKeyLargoMPICP0CurrTaskPriority		= 0x20080,						// MPIC CPU 0 current task priority register
		kKeyLargoMPICP1CurrTaskPriority		= 0x21080,						// MPIC CPU 1 current task priority register
		kKeyLargoMPICP2CurrTaskPriority		= 0x22080,						// MPIC CPU 2 current task priority register
		kKeyLargoMPICP3CurrTaskPriority		= 0x23080						// MPIC CPU 3 current task priority register
	};

	// 6522 VIA1 (and VIA2) register offsets
	enum {
		kKeyLargoVIABaseOffset	=	0x16000,								// VIA base offset from start of KeyLargo
		kKeyLargovBufB			=	0,                                      // BUFFER B
		kKeyLargovBufAH			=	0x200,                                  // buffer a (with handshake) [ Dont use! ]
		kKeyLargovDIRB			=	0x400,                                  // DIRECTION B
		kKeyLargovDIRA			=	0x600,                                  // DIRECTION A
		kKeyLargovT1C			=	0x800,                                  // TIMER 1 COUNTER (L.O.)
		kKeyLargovT1CH			=	0xA00,                                  // timer 1 counter (high order)
		kKeyLargovT1L			=	0xC00,                                  // TIMER 1 LATCH (L.O.)
		kKeyLargovT1LH			=	0xE00,                                  // timer 1 latch (high order)
		kKeyLargovT2C			=	0x1000,                                 // TIMER 2 LATCH (L.O.)
		kKeyLargovT2CH			=	0x1200,                                 // timer 2 counter (high order)
		kKeyLargovSR			=	0x1400,                                 // SHIFT REGISTER
		kKeyLargovACR			=	0x1600,                                 // AUX. CONTROL REG.
		kKeyLargovPCR			=	0x1800,                                 // PERIPH. CONTROL REG.
		kKeyLargovIFR			=	0x1A00,                                 // INT. FLAG REG.
		kKeyLargovIER			=	0x1C00,                                 // INT. ENABLE REG.
		kKeyLargovBufA			=	0x1E00,                                 // BUFFER A
		kKeyLargovBufD			=	kKeyLargovBufA                          // disk head select is buffer A
	};
	
	// DBDMA offsets
	enum {
		kKeyLargoDBDMAChannelCount		= 13,								// 13 DBDMA channels
		kKeyLargoDBDMABaseOffset		= 0x8000,							// Base address of DBDMA channel registers
		kKeyLargoDBDMAChannelStride		= 0x100								// Stride between successive DBDMA channels
	};

	// Audio offsets
	enum {
		kKeyLargoAudioRegisterCount		= 25,								// 25 audio registers
		kKeyLargoAudioBaseOffset		= 0x14000,							// Base address of audio channel registers
		kKeyLargoAudioRegisterStride	= 0x10								// Stride between successive audio register
	};

	// I2S offsets
	enum {
		kKeyLargoI2SRegisterCount		= 10,								// 10 I2S registers (per channel)
		kKeyLargoI2SChannelCount		= 2,								// 2 channels
		kKeyLargoI2S0BaseOffset			= 0x10000,							// Base address of I2S0 registers
		kKeyLargoI2S1BaseOffset			= 0x11000,							// Base address of I2S1 registers
		kKeyLargoI2SRegisterStride		= 0x10								// Stride between successive I2S register
	};
	
	// GPIO offsets
	enum {
		kKeyLargoGPIOLevels0			= 0x50,								// Offset to GPIO Levels 0 register
		kKeyLargoGPIOLevels1			= 0x54,								// Offset to GPIO Levels 1 register
		// There is an inconsistency here - see usage of kKeyLargoExtIntGPIOBase
		kKeyLargoExtIntGPIOBase			= 0x50,								// Ext-int GPIO base offset
		kKeyLargoExtIntGPIORegBase		= 0x58,								// Ext-int GPIO register base offset
		kKeyLargoExtIntGPIOCount		= 18,								// Ext-int GPIO count
		kKeyLargoGPIOBase				= 0x6A,								// GPIO base offset
		kKeyLargoGPIOCount				= 17,								// GPIO count
		kKeyLargoGPIOOutputEnable		= 0x04,								// DDIR
		kKeyLargoGPIOData				= 0x01,								// GPIO data
  
	};

// Much needed forward declaration:
class USBKeyLargo;
class KeyLargoWatchDogTimer;

class KeyLargo : public AppleMacIO
{
	OSDeclareDefaultStructors(KeyLargo);
  
private:
	IOLogicalAddress	keyLargoBaseAddress;
	UInt32				keyLargoVersion;
	UInt32				keyLargoDeviceId;
	UInt32				keyLargoCPUVCoreSelectGPIO;
 
	// Remember if the media bay needs to be turnedOn:
	bool		   	mediaIsOn;
	void			EnableSCC(bool state, UInt8 device, bool type);
	void			PowerModem(bool state);
	void 			ModemResetLow();
	void 			ModemResetHigh();
	void			PowerI2S (bool powerOn, UInt32 cellNum);
	IOReturn		SetPowerSupply (bool powerHi);
	void			AdjustBusSpeeds ( void );
  
	KeyLargoWatchDogTimer	*watchDogTimer;

	// ***Added for outputting the FCR values to the IORegistry
	IOService 		*keyLargoService;
	const OSSymbol	*keyLargo_FCRNode;
	const OSObject	*fcrs[kPangeaFCRCount];  
	const OSArray	*fcrArray;
  
	// callPlatformFunction symbols
	const OSSymbol 	*keyLargo_resetUniNEthernetPhy;
	const OSSymbol 	*keyLargo_restoreRegisterState;
	const OSSymbol 	*keyLargo_syncTimeBase;
	const OSSymbol 	*keyLargo_recalibrateBusSpeeds;
	const OSSymbol 	*keyLargo_saveRegisterState;
	const OSSymbol 	*keyLargo_turnOffIO;
	const OSSymbol 	*keyLargo_writeRegUInt8;
	const OSSymbol 	*keyLargo_safeWriteRegUInt8;
	const OSSymbol 	*keyLargo_safeReadRegUInt8;
	const OSSymbol 	*keyLargo_safeWriteRegUInt32;
	const OSSymbol 	*keyLargo_safeReadRegUInt32;
	const OSSymbol 	*keyLargo_powerMediaBay;
	const OSSymbol 	*keyLargo_getHostKeyLargo;
	const OSSymbol 	*keyLargo_powerI2S;
	const OSSymbol 	*keyLargo_setPowerSupply;
  
	// Power Management support functions and data structures:
	// These come (almost) unchanged from the MacOS9 Power
	// Manager plug-in (p99powerplugin.c)

	struct MPICTimers {
		UInt32			currentCountRegister;
		UInt32			baseCountRegister;
		UInt32			vectorPriorityRegister;
		UInt32			destinationRegister;
	};
	typedef struct MPICTimers MPICTimers;
	typedef volatile MPICTimers *MPICTimersPtr;

	struct KeyLargoMPICState {
		UInt32 			mpicIPI[kKeyLargoMPICIPICount];
		UInt32 			mpicSpuriousVector;
		UInt32 			mpicTimerFrequencyReporting;
		MPICTimers 		mpicTimers[kKeyLargoMPICTimerCount];
		UInt32 			mpicInterruptSourceVectorPriority[kKeyLargoMPICVectorsCount];
		UInt32 			mpicInterruptSourceDestination[kKeyLargoMPICVectorsCount];
		UInt32			mpicCurrentTaskPriorities[kKeyLargoMPICTaskPriorityCount];
	};
	typedef struct KeyLargoMPICState KeyLargoMPICState;
	typedef volatile KeyLargoMPICState *KeyLargoMPICStatePtr;

	struct KeyLargoGPIOState {
		UInt32 			gpioLevels[2];
		UInt8 			extIntGPIO[18];
		UInt8 			gpio[17];
	};
	typedef struct KeyLargoGPIOState KeyLargoGPIOState;
	typedef volatile KeyLargoGPIOState *KeyLargoGPIOStatePtr;

	struct KeyLargoConfigRegistersState {
		UInt32 			mediaBay;
		UInt32 			featureControl[kPangeaFCRCount];		// Allow for worst case - Pangea
	};
	typedef struct KeyLargoConfigRegistersState KeyLargoConfigRegistersState;
	typedef volatile KeyLargoConfigRegistersState *KeyLargoConfigRegistersStatePtr;

	// This is a short version of the IODBDMAChannelRegisters which includes only
	// the registers we actually mean to save
	struct DBDMAChannelRegisters {
		UInt32			commandPtrLo;
		UInt32			interruptSelect;
		UInt32			branchSelect;
		UInt32			waitSelect;
	};
	typedef struct DBDMAChannelRegisters DBDMAChannelRegisters;
	typedef volatile DBDMAChannelRegisters *DBDMAChannelRegistersPtr;

	struct KeyLargoDBDMAState {
		DBDMAChannelRegisters 	dmaChannel[kKeyLargoDBDMAChannelCount];
	};
	typedef struct KeyLargoDBDMAState KeyLargoDBDMAState;
	typedef volatile KeyLargoDBDMAState *KeyLargoDBDMAStatePtr;


	struct KeyLargoAudioState {
		UInt32					audio[kKeyLargoAudioRegisterCount];
	};
	typedef struct KeyLargoAudioState KeyLargoAudioState;
	typedef volatile KeyLargoAudioState *KeyLargoAudioStateStatePtr;


	struct KeyLargoI2SState {
		UInt32					i2s[kKeyLargoI2SRegisterCount * kKeyLargoI2SChannelCount];
	};
	typedef struct KeyLargoI2SState KeyLargoI2SState;
	typedef volatile KeyLargoI2SState *KeyLargoI2SStateStatePtr;

	struct KeyLargoState {
		bool							thisStateIsValid;
		KeyLargoMPICState				savedMPICState;
		KeyLargoGPIOState				savedGPIOState;
		KeyLargoConfigRegistersState	savedConfigRegistersState;
		KeyLargoDBDMAState				savedDBDMAState;
		KeyLargoAudioState				savedAudioState;
		KeyLargoI2SState				savedI2SState;
		UInt8							savedVIAState[9];
	};
	typedef struct KeyLargoState KeyLargoState;

	// These are actually the buffers where we save keylargo's state (above there
	// are only definitions).
	KeyLargoState savedKeyLargoState;
  
	// This is instead only for the wireless slot:
	typedef struct WirelessPower {
		bool		cardPower;				// Keeps track of the power in the wireless card.
		UInt8		wirelessCardReg[5];		// A backup of the registers we are overwriting.
	} WirelessPower;
	WirelessPower cardStatus;
	

	// the two USB busses:
	enum {
		kNumUSB = 2
	};
	USBKeyLargo *usbBus[kNumUSB];

	// Methods to save and restore the state:
	void saveKeyLargoState();
	void restoreKeyLargoState();
	void saveVIAState();
	void restoreVIAState();

	// this is to ensure mutual exclusive access to
	// the keylargo registers:
	IOSimpleLock *mutex;

	// Remember the bus speed:
	long long busSpeed;
  
	// Reference counts for shared hardware
	long clk31RefCount;			// 31.3 MHz clock - SCC & VIA
	long clk45RefCount;			// 45.1 MHz clock - Audio, I2S & SCC
	long clk49RefCount;			// 49.1 MHz clock - Audio & I2S
	long clk32RefCount;			// 32.0 MHz clock - SCC & VIA (Pangea only)
  
	// true for PowerBooks/iBooks
	bool hostIsMobile;

	void resetUniNEthernetPhy(void);
  
public:
	virtual bool      init(OSDictionary *);
	virtual bool      start(IOService *provider);
	virtual void      stop(IOService *provider);
  
	virtual IOReturn callPlatformFunction(const OSSymbol *functionName,
					bool waitForFunction, void *param1, void *param2,
					void *param3, void *param4);
  
	virtual IOReturn callPlatformFunction( const char * functionName,
					  bool waitForFunction, void *param1, void *param2,
					  void *param3, void *param4);
					  
	virtual long long syncTimeBase(void);
	virtual void	  recalibrateBusSpeeds(void);

	virtual void      turnOffKeyLargoIO(bool restart);
	virtual void      turnOffPangeaIO(bool restart);

	virtual void      powerWireless(bool powerOn);

	virtual void	  setReferenceCounts (void);
	virtual void      saveRegisterState(void);
	virtual void      restoreRegisterState(void);
	virtual void      enableCells();
  
	virtual UInt8     readRegUInt8(unsigned long offset);
	virtual void      writeRegUInt8(unsigned long offset, UInt8 data);
	virtual UInt32    readRegUInt32(unsigned long offset);
	virtual void      writeRegUInt32(unsigned long offset, UInt32 data);
  
	// Remember if the media bay needs to be turnedOn:
	virtual void      powerMediaBay(bool powerOn, UInt8 whichDevice);  

	// share register access:
	void safeWriteRegUInt8(unsigned long offset, UInt8 mask, UInt8 data);
	UInt8 safeReadRegUInt8(unsigned long offset);
	void safeWriteRegUInt32(unsigned long offset, UInt32 mask, UInt32 data);
	UInt32 safeReadRegUInt32(unsigned long offset);

	// Power handling methods:
	void initForPM (IOService *provider);
	IOReturn setPowerState(unsigned long powerStateOrdinal, IOService* whatDevice);
  
};

#endif /* ! _IOKIT_KEYLARGO_H */