]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/MAI/AmigaOneG3SE/smbus.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / AmigaOneG3SE / smbus.c
1 #include "memio.h"
2 #include "articiaS.h"
3
4 #ifndef FALSE
5 #define FALSE 0
6 #endif
7
8 #ifndef TRUE
9 #define TRUE 1
10 #endif
11
12
13 void sm_write_mode(void)
14 {
15     out_byte(0xA539, 0x00);
16     out_byte(0xA53A, 0x03);
17 }
18
19 void sm_read_mode(void)
20 {
21     out_byte(0xA53A, 0x02);
22     out_byte(0xA539, 0x02);
23 }
24
25 void sm_write_byte(uint8 writeme)
26 {
27     int i;
28     int level;
29     
30     out_byte(0xA539, 0x00);
31
32     level = 0;
33
34     for (i=0; i<8; i++)
35     {
36         if ((writeme & 0x80) == (level<<7)) 
37         {
38             /* Bit did not change, rewrite strobe */
39             out_byte(0xA539, level | 0x02);
40             out_byte(0xA539, level); 
41         }
42         else
43         {
44             /* Bit changed, set bit, then strobe */
45             level = (writeme & 0x80) >> 7;
46             out_byte(0xA539, level);
47             out_byte(0xA539, level | 0x02);
48             out_byte(0xA539, level);
49         }
50         writeme <<= 1;
51     }
52     out_byte(0xA539, 0x00);
53 }
54
55 uint8 sm_read_byte(void)
56 {
57     uint8 retme, r;
58     int i;
59
60     retme = 0;
61     for (i=0; i<8; i++)
62     {
63         retme <<= 1;
64         out_byte(0xA539, 0x00);
65         out_byte(0xA539, 0x02);
66         r = in_byte(0xA538) & 0x01;
67         retme |= r;
68     }
69
70     return retme;
71
72
73 int sm_get_ack(void)
74 {
75     uint8 r;
76     r = in_byte(0xA538);
77     if ((r&0x01) == 0) return TRUE;
78     else return FALSE;
79 }
80
81 void sm_write_ack(void)
82 {
83     out_byte(0xA539, 0x00);
84     out_byte(0xA539, 0x02);
85     out_byte(0xA539, 0x00);
86 }
87
88 void sm_write_nack(void)
89 {
90     out_byte(0xA539, 0x01);
91     out_byte(0xA539, 0x03);
92     out_byte(0xA539, 0x01);
93 }
94
95 void sm_send_start(void)
96 {
97     out_byte(0xA539, 0x03);
98     out_byte(0xA539, 0x02);
99 }
100
101 void sm_send_stop(void)
102 {
103     out_byte(0xA539, 0x02);
104     out_byte(0xA539, 0x03);
105 }
106
107 int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
108 {
109     // S Addr Wr
110     sm_write_mode();
111     sm_send_start();
112     sm_write_byte((addr<<1));
113     
114     // [A]
115     sm_read_mode();
116     if (sm_get_ack() == FALSE) return FALSE;
117
118     // Comm
119     sm_write_mode();
120     sm_write_byte(reg);
121     
122     // [A]
123     sm_read_mode();
124     if (sm_get_ack() == FALSE) return FALSE;
125
126     // S Addr Rd
127     sm_write_mode();
128     sm_send_start();
129     sm_write_byte((addr<<1)|1);
130     
131     // [A]
132     sm_read_mode();
133     if (sm_get_ack() == FALSE) return FALSE;
134
135     // [Data]
136     *storage = sm_read_byte();
137     
138     // NA
139     sm_write_mode();
140     sm_write_nack();
141     sm_send_stop();
142
143     return TRUE;
144 }
145
146 void sm_init(void)
147 {  
148     /* Switch to PMC mode */
149     pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
150  
151     /* Set GPIO Base */
152     pci_write_cfg_long(0, 0, 0x40, 0xa500);
153
154     /* Enable GPIO */
155     pci_write_cfg_byte(0, 0, 0x44, 0x11);
156
157     /* Set both GPIO 0 and 1 as output */
158     out_byte(0xA53A, 0x03); 
159 }
160
161
162 void sm_term(void)
163 {  
164     /* Switch to normal mode */
165     pci_write_cfg_byte(0, 0, REG_GROUP, 0);
166 }
167
168
169 int sm_get_data(uint8 *DataArray, int dimm_socket)
170 {
171     int j;
172
173 #if 0
174     /* Switch to PMC mode */
175     pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
176  
177     /* Set GPIO Base */
178     pci_write_cfg_long(0, 0, 0x40, 0xa500);
179
180     /* Enable GPIO */
181     pci_write_cfg_byte(0, 0, 0x44, 0x11);
182
183     /* Set both GPIO 0 and 1 as output */
184     out_byte(0xA53A, 0x03); 
185 #endif
186
187     sm_init();
188     /* Start reading the rom */
189
190     j = 0;
191
192     do
193     {
194         if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
195         {
196             sm_term();
197             return FALSE;
198         }
199
200         DataArray++;
201         j++;
202     } while (j < 128);
203
204     sm_term();
205     return TRUE;
206 }