Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxboxi2c.c
Go to the documentation of this file.
00001 /* $Id: xboxhw.c 19190 2005-11-13 04:50:55Z fireball $ 00002 * 00003 * FreeLoader 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 00020 #include <freeldr.h> 00021 00022 // These functions are used only inside xbox-specific code 00023 // thus I didn't include them in header 00024 00025 #define I2C_IO_BASE 0xc000 00026 00027 static BOOLEAN 00028 WriteToSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG Data_to_smbus) 00029 { 00030 int nRetriesToLive=50; 00031 00032 while(READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE+0)) & 0x0800) 00033 { 00034 ; // Franz's spin while bus busy with any master traffic 00035 } 00036 00037 while(nRetriesToLive--) 00038 { 00039 UCHAR b; 00040 unsigned int temp; 00041 00042 WRITE_PORT_UCHAR((PUCHAR)(I2C_IO_BASE + 4), (Address << 1) | 0); 00043 WRITE_PORT_UCHAR((PUCHAR)(I2C_IO_BASE + 8), bRegister); 00044 00045 switch (Size) 00046 { 00047 case 4: 00048 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), Data_to_smbus & 0xff); 00049 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 8) & 0xff ); 00050 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 16) & 0xff ); 00051 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9), (Data_to_smbus >> 24) & 0xff ); 00052 WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), 4); 00053 break; 00054 case 2: 00055 WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), Data_to_smbus&0xffff); 00056 break; 00057 default: // 1 00058 WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6), Data_to_smbus&0xff); 00059 break; 00060 } 00061 00062 00063 temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)); 00064 WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); // clear down all preexisting errors 00065 00066 switch (Size) 00067 { 00068 case 4: 00069 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1d); // DWORD modus 00070 break; 00071 case 2: 00072 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1b); // WORD modus 00073 break; 00074 default: // 1 00075 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x1a); // BYTE modus 00076 break; 00077 } 00078 00079 b = 0; 00080 00081 while( (b&0x36)==0 ) 00082 { 00083 b=READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0)); 00084 } 00085 00086 if ((b&0x10) != 0) 00087 { 00088 return TRUE; 00089 } 00090 00091 StallExecutionProcessor(1); 00092 } 00093 00094 return FALSE; 00095 } 00096 00097 00098 static BOOLEAN 00099 ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus) 00100 { 00101 int nRetriesToLive=50; 00102 00103 while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800)) 00104 { 00105 ; /* Franz's spin while bus busy with any master traffic */ 00106 } 00107 00108 while (0 != nRetriesToLive--) 00109 { 00110 UCHAR b; 00111 int temp; 00112 00113 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1); 00114 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister); 00115 00116 temp = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 0)); 00117 WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */ 00118 00119 switch (Size) 00120 { 00121 case 4: 00122 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */ 00123 break; 00124 case 2: 00125 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */ 00126 break; 00127 default: 00128 WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE 00129 break; 00130 } 00131 00132 b = 0; 00133 00134 while (0 == (b & 0x36)) 00135 { 00136 b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0)); 00137 } 00138 00139 if (0 != (b & 0x24)) 00140 { 00141 /* printf("I2CTransmitByteGetReturn error %x\n", b); */ 00142 } 00143 00144 if(0 == (b & 0x10)) 00145 { 00146 /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */ 00147 } 00148 else 00149 { 00150 switch (Size) 00151 { 00152 case 4: 00153 READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); 00154 READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); 00155 READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); 00156 READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); 00157 READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9)); 00158 break; 00159 case 2: 00160 *Data_to_smbus = READ_PORT_USHORT((USHORT *) (I2C_IO_BASE + 6)); 00161 break; 00162 default: 00163 *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6)); 00164 break; 00165 } 00166 00167 00168 return TRUE; 00169 } 00170 } 00171 00172 return FALSE; 00173 } 00174 00175 BOOLEAN 00176 I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return) 00177 { 00178 return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return); 00179 } 00180 00181 // transmit a word, no returned data from I2C device 00182 static BOOLEAN 00183 I2CTransmitWord(UCHAR bPicAddressI2cFormat, USHORT wDataToWrite) 00184 { 00185 return WriteToSMBus(bPicAddressI2cFormat,(wDataToWrite>>8)&0xff,1,(wDataToWrite&0xff)); 00186 } 00187 00188 static void 00189 I2cSetFrontpanelLed(UCHAR b) 00190 { 00191 I2CTransmitWord( 0x10, 0x800 | b); // sequencing thanks to Jarin the Penguin! 00192 I2CTransmitWord( 0x10, 0x701); 00193 } 00194 00195 // Set the pattern of the LED. 00196 // r = Red, g = Green, o = Orange, x = Off 00197 // This func is taken from cromwell, all credits goes for them 00198 void 00199 XboxSetLED(PCSTR pattern) { 00200 const char *x = pattern; 00201 int r, g; 00202 00203 if(strlen(pattern) == 4) { 00204 r = g = 0; 00205 while (*x) { 00206 r *= 2; 00207 g *= 2; 00208 switch (*x) { 00209 case 'r': 00210 r++; 00211 break; 00212 case 'g': 00213 g++; 00214 break; 00215 case 'o': 00216 r++; 00217 g++; 00218 break; 00219 } 00220 x++; 00221 } 00222 I2cSetFrontpanelLed(((r<<4) & 0xF0) + (g & 0xF)); 00223 } 00224 } Generated on Sun May 27 2012 04:19:09 for ReactOS by
1.7.6.1
|