1 /* $Id: xboxhw.c 19190 2005-11-13 04:50:55Z fireball $
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 // These functions are used only inside xbox-specific code
23 // thus I didn't include them in header
25 #define I2C_IO_BASE 0xc000
28 WriteToSMBus(UCHAR Address
, UCHAR bRegister
, UCHAR Size
, ULONG Data_to_smbus
)
30 int nRetriesToLive
=50;
32 while(READ_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+0)) & 0x0800)
34 ; // Franz's spin while bus busy with any master traffic
37 while(nRetriesToLive
--)
42 WRITE_PORT_UCHAR((PUCHAR
)(I2C_IO_BASE
+ 4), (Address
<< 1) | 0);
43 WRITE_PORT_UCHAR((PUCHAR
)(I2C_IO_BASE
+ 8), bRegister
);
48 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9), Data_to_smbus
& 0xff);
49 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9), (Data_to_smbus
>> 8) & 0xff );
50 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9), (Data_to_smbus
>> 16) & 0xff );
51 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9), (Data_to_smbus
>> 24) & 0xff );
52 WRITE_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 6), 4);
55 WRITE_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 6), Data_to_smbus
&0xffff);
58 WRITE_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 6), Data_to_smbus
&0xff);
63 temp
= READ_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 0));
64 WRITE_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 0), temp
); // clear down all preexisting errors
69 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x1d); // DWORD modus
72 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x1b); // WORD modus
75 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x1a); // BYTE modus
83 b
=READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 0));
91 StallExecutionProcessor(1);
99 ReadfromSMBus(UCHAR Address
, UCHAR bRegister
, UCHAR Size
, ULONG
*Data_to_smbus
)
101 int nRetriesToLive
=50;
103 while (0 != (READ_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 0)) & 0x0800))
105 ; /* Franz's spin while bus busy with any master traffic */
108 while (0 != nRetriesToLive
--)
113 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 4), (Address
<< 1) | 1);
114 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 8), bRegister
);
116 temp
= READ_PORT_USHORT((USHORT
*) (I2C_IO_BASE
+ 0));
117 WRITE_PORT_USHORT((PUSHORT
) (I2C_IO_BASE
+ 0), temp
); /* clear down all preexisting errors */
122 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x0d); /* DWORD modus ? */
125 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x0b); /* WORD modus */
128 WRITE_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 2), 0x0a); // BYTE
134 while (0 == (b
& 0x36))
136 b
= READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 0));
141 /* printf("I2CTransmitByteGetReturn error %x\n", b); */
146 /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
153 READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 6));
154 READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9));
155 READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9));
156 READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9));
157 READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 9));
160 *Data_to_smbus
= READ_PORT_USHORT((USHORT
*) (I2C_IO_BASE
+ 6));
163 *Data_to_smbus
= READ_PORT_UCHAR((PUCHAR
) (I2C_IO_BASE
+ 6));
176 I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat
, UCHAR bDataToWrite
, ULONG
*Return
)
178 return ReadfromSMBus(bPicAddressI2cFormat
, bDataToWrite
, 1, Return
);
181 // transmit a word, no returned data from I2C device
183 I2CTransmitWord(UCHAR bPicAddressI2cFormat
, USHORT wDataToWrite
)
185 return WriteToSMBus(bPicAddressI2cFormat
,(wDataToWrite
>>8)&0xff,1,(wDataToWrite
&0xff));
189 I2cSetFrontpanelLed(UCHAR b
)
191 I2CTransmitWord( 0x10, 0x800 | b
); // sequencing thanks to Jarin the Penguin!
192 I2CTransmitWord( 0x10, 0x701);
195 // Set the pattern of the LED.
196 // r = Red, g = Green, o = Orange, x = Off
197 // This func is taken from cromwell, all credits goes for them
199 XboxSetLED(UCHAR
*pattern
) {
203 if(strlen(pattern
) == 4) {
222 I2cSetFrontpanelLed(((r
<<4) & 0xF0) + (g
& 0xF));