From b2a69d9d5e5ef68f0ffb314cc602642f8838bbc1 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 10 Dec 2005 13:50:36 +0000 Subject: [PATCH] Move xbox's i2c support to a separate file, and add support of xbox's LEDs switching. Currently it initializes leds to red, and immediately after base init is done (means video has been initialized) they are turned to orange (good for debugging). svn path=/trunk/; revision=20034 --- .../boot/freeldr/freeldr/arch/i386/machxbox.c | 6 + .../boot/freeldr/freeldr/arch/i386/xboxi2c.c | 224 ++++++++++++++++++ .../freeldr/freeldr/arch/i386/xboxvideo.c | 89 +------ reactos/boot/freeldr/freeldr/freeldr_base.xml | 1 + .../freeldr/include/arch/i386/machxbox.h | 3 + 5 files changed, 236 insertions(+), 87 deletions(-) create mode 100644 reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c diff --git a/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c b/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c index f7ae6255c3f..ba6eae8d82b 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c @@ -22,6 +22,9 @@ VOID XboxMachInit(const char *CmdLine) { + /* Set LEDs to red before anything is initialized */ + XboxSetLED("rrrr"); + /* Initialize our stuff */ XboxMemInit(); XboxVideoInit(); @@ -55,4 +58,7 @@ XboxMachInit(const char *CmdLine) MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount; MachVtbl.RTCGetCurrentDateTime = XboxRTCGetCurrentDateTime; MachVtbl.HwDetect = XboxHwDetect; + + /* Set LEDs to orange after init */ + XboxSetLED("oooo"); } diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c new file mode 100644 index 00000000000..02d0458fa59 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c @@ -0,0 +1,224 @@ +/* $Id: xboxhw.c 19190 2005-11-13 04:50:55Z fireball $ + * + * FreeLoader + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +// These functions are used only inside xbox-specific code +// thus I didn't include them in header + +#define I2C_IO_BASE 0xc000 + +static BOOL +WriteToSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG Data_to_smbus) +{ + int nRetriesToLive=50; + + while(READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE+0)) & 0x0800) + { + ; // Franz's spin while bus busy with any master traffic + } + + while(nRetriesToLive--) + { + UCHAR b; + unsigned int temp; + + WRITE_PORT_UCHAR((PUCHAR)(I2C_IO_BASE + 4), (Address << 1) | 0); + WRITE_PORT_UCHAR((PUCHAR)(I2C_IO_BASE + 8), bRegister); + + switch (Size) + { + case 4: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), Data_to_smbus & 0xff); + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 8) & 0xff ); + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 16) & 0xff ); + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 24) & 0xff ); + WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), 4); + break; + case 2: + WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), Data_to_smbus&0xffff); + break; + default: // 1 + WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), Data_to_smbus&0xff); + break; + } + + + temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)); + WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); // clear down all preexisting errors + + switch (Size) + { + case 4: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1d); // DWORD modus + break; + case 2: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1b); // WORD modus + break; + default: // 1 + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1a); // BYTE modus + break; + } + + b = 0; + + while( (b&0x36)==0 ) + { + b=READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0)); + } + + if ((b&0x10) != 0) + { + return TRUE; + } + + StallExecutionProcessor(1); + } + + return FALSE; +} + + +static BOOL +ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus) +{ + int nRetriesToLive=50; + + while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800)) + { + ; /* Franz's spin while bus busy with any master traffic */ + } + + while (0 != nRetriesToLive--) + { + UCHAR b; + int temp; + + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1); + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister); + + temp = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 0)); + WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */ + + switch (Size) + { + case 4: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */ + break; + case 2: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */ + break; + default: + WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE + break; + } + + b = 0; + + while (0 == (b & 0x36)) + { + b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0)); + } + + if (0 != (b & 0x24)) + { + /* printf("I2CTransmitByteGetReturn error %x\n", b); */ + } + + if(0 == (b & 0x10)) + { + /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */ + } + else + { + switch (Size) + { + case 4: + READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); + READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); + READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); + READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); + READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); + break; + case 2: + *Data_to_smbus = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 6)); + break; + default: + *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); + break; + } + + + return TRUE; + } + } + + return FALSE; +} + +BOOL +I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return) +{ + return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return); +} + +// transmit a word, no returned data from I2C device +static BOOL +I2CTransmitWord(UCHAR bPicAddressI2cFormat, USHORT wDataToWrite) +{ + return WriteToSMBus(bPicAddressI2cFormat,(wDataToWrite>>8)&0xff,1,(wDataToWrite&0xff)); +} + +static void +I2cSetFrontpanelLed(UCHAR b) +{ + I2CTransmitWord( 0x10, 0x800 | b); // sequencing thanks to Jarin the Penguin! + I2CTransmitWord( 0x10, 0x701); +} + +// Set the pattern of the LED. +// r = Red, g = Green, o = Orange, x = Off +// This func is taken from cromwell, all credits goes for them +void +XboxSetLED(UCHAR *pattern) { + char *x = pattern; + int r, g; + + if(strlen(pattern) == 4) { + r = g = 0; + while (*x) { + r *= 2; + g *= 2; + switch (*x) { + case 'r': + r++; + break; + case 'g': + g++; + break; + case 'o': + r++; + g++; + break; + } + x++; + } + I2cSetFrontpanelLed(((r<<4) & 0xF0) + (g & 0xF)); + } +} diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c index 7668d4cee82..bbcf8fef204 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c @@ -22,8 +22,6 @@ #include -#define I2C_IO_BASE 0xc000 - static PVOID FrameBuffer; static ULONG ScreenWidth; static ULONG ScreenHeight; @@ -39,6 +37,8 @@ static ULONG Delta; #define MAKE_COLOR(Red, Green, Blue) (0xff000000 | (((Red) & 0xff) << 16) | (((Green) & 0xff) << 8) | ((Blue) & 0xff)) +BOOL I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return); + static VOID XboxVideoOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG BgColor) { @@ -119,91 +119,6 @@ XboxVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y) XboxVideoOutputChar(Ch, X, Y, FgColor, BgColor); } -static BOOL -ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus) -{ - int nRetriesToLive=50; - - while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800)) - { - ; /* Franz's spin while bus busy with any master traffic */ - } - - while (0 != nRetriesToLive--) - { - UCHAR b; - int temp; - - WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1); - WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister); - - temp = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 0)); - WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */ - - switch (Size) - { - case 4: - WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */ - break; - case 2: - WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */ - break; - default: - WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE - break; - } - - b = 0; - - while (0 == (b & 0x36)) - { - b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0)); - } - - if (0 != (b & 0x24)) - { - /* printf("I2CTransmitByteGetReturn error %x\n", b); */ - } - - if(0 == (b & 0x10)) - { - /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */ - } - else - { - switch (Size) - { - case 4: - READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); - READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); - READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); - READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); - READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); - break; - case 2: - *Data_to_smbus = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 6)); - break; - default: - *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); - break; - } - - - return TRUE; - } - } - - return FALSE; -} - - -static BOOL -I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return) -{ - return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return); -} - - VOID XboxVideoInit(VOID) { diff --git a/reactos/boot/freeldr/freeldr/freeldr_base.xml b/reactos/boot/freeldr/freeldr/freeldr_base.xml index 732d68b7d72..ef001a8a210 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_base.xml +++ b/reactos/boot/freeldr/freeldr/freeldr_base.xml @@ -36,6 +36,7 @@ xboxdisk.c xboxfont.c xboxhw.c + xboxi2c.c xboxmem.c xboxrtc.c xboxvideo.c diff --git a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h index 641852e02a4..e3c6817d042 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h +++ b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h @@ -60,6 +60,9 @@ VOID XboxRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hou VOID XboxHwDetect(VOID); +VOID XboxSetLED(UCHAR *Pattern); + + #endif /* __I386_HWXBOX_H_ */ /* EOF */