Move xbox's i2c support to a separate file, and add support of xbox's LEDs switching...
authorAleksey Bragin <aleksey@reactos.org>
Sat, 10 Dec 2005 13:50:36 +0000 (13:50 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Sat, 10 Dec 2005 13:50:36 +0000 (13:50 +0000)
svn path=/trunk/; revision=20034

reactos/boot/freeldr/freeldr/arch/i386/machxbox.c
reactos/boot/freeldr/freeldr/arch/i386/xboxi2c.c [new file with mode: 0644]
reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c
reactos/boot/freeldr/freeldr/freeldr_base.xml
reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h

index f7ae625..ba6eae8 100644 (file)
@@ -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 (file)
index 0000000..02d0458
--- /dev/null
@@ -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));
+       }
+}
index 7668d4c..bbcf8fe 100644 (file)
@@ -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)
 {
index 732d68b..ef001a8 100644 (file)
@@ -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>
index 641852e..e3c6817 100644 (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 */