mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
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
This commit is contained in:
parent
9c79acf7f8
commit
b2a69d9d5e
5 changed files with 236 additions and 87 deletions
|
@ -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");
|
||||
}
|
||||
|
|
224
reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c
Normal file
224
reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c
Normal file
|
@ -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 <freeldr.h>
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<file>xboxdisk.c</file>
|
||||
<file>xboxfont.c</file>
|
||||
<file>xboxhw.c</file>
|
||||
<file>xboxi2c.c</file>
|
||||
<file>xboxmem.c</file>
|
||||
<file>xboxrtc.c</file>
|
||||
<file>xboxvideo.c</file>
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue