fc283af7e987c3621fbd2c35c9e7f88a28ed680f
[reactos.git] / win32ss / drivers / miniport / xboxvmp / xboxi2c.c
1 /*
2 * PROJECT: ReactOS Xbox miniport video driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: I2C SMBus routines
5 * COPYRIGHT: Copyright 2004 Gé van Geldorp
6 * Copyright 2004 Filip Navara
7 * Copyright 2019 Stanislav Motylkov (x86corez@gmail.com)
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include "xboxvmp.h"
13
14 #include <debug.h>
15 #include <dpfilter.h>
16
17 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
18
19 static
20 BOOLEAN
21 ReadfromSMBus(
22 UCHAR Address,
23 UCHAR bRegister,
24 UCHAR Size,
25 ULONG *Data_to_smbus)
26 {
27 int nRetriesToLive = 50;
28
29 while ((VideoPortReadPortUshort((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800) != 0)
30 {
31 ; /* Franz's spin while bus busy with any master traffic */
32 }
33
34 while (nRetriesToLive-- != 0)
35 {
36 UCHAR b;
37 int temp;
38
39 VideoPortWritePortUchar((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
40 VideoPortWritePortUchar((PUCHAR) (I2C_IO_BASE + 8), bRegister);
41
42 temp = VideoPortReadPortUshort((PUSHORT) (I2C_IO_BASE + 0));
43 VideoPortWritePortUshort((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */
44
45 switch (Size)
46 {
47 case 4:
48 {
49 VideoPortWritePortUchar((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */
50 break;
51 }
52
53 case 2:
54 {
55 VideoPortWritePortUchar((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */
56 break;
57 }
58
59 default:
60 {
61 VideoPortWritePortUchar((PUCHAR) (I2C_IO_BASE + 2), 0x0a); /* BYTE */
62 }
63 }
64
65 b = 0;
66
67 while ((b & 0x36) == 0)
68 {
69 b = VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 0));
70 }
71
72 if ((b & 0x24) != 0)
73 {
74 ERR_(IHVVIDEO, "I2CTransmitByteGetReturn error %x\n", b);
75 }
76
77 if ((b & 0x10) == 0)
78 {
79 ERR_(IHVVIDEO, "I2CTransmitByteGetReturn no complete, retry\n");
80 }
81 else
82 {
83 switch (Size)
84 {
85 case 4:
86 {
87 VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 6));
88 VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 9));
89 VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 9));
90 VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 9));
91 VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 9));
92 break;
93 }
94
95 case 2:
96 {
97 *Data_to_smbus = VideoPortReadPortUshort((PUSHORT) (I2C_IO_BASE + 6));
98 break;
99 }
100
101 default:
102 {
103 *Data_to_smbus = VideoPortReadPortUchar((PUCHAR) (I2C_IO_BASE + 6));
104 }
105 }
106
107 return TRUE;
108 }
109 }
110
111 return FALSE;
112 }
113
114 BOOLEAN
115 I2CTransmitByteGetReturn(
116 UCHAR bPicAddressI2cFormat,
117 UCHAR bDataToWrite,
118 ULONG *Return)
119 {
120 return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
121 }
122
123 /* EOF */