]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - lib_i386/ic/ali512x.c
* Patch by Daniel Engström, 13 Nov 2002:
[karo-tx-uboot.git] / lib_i386 / ic / ali512x.c
1 /*
2  * (C) Copyright 2002
3  * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Based on sc520cdp.c from rolo 1.6:
26  *----------------------------------------------------------------------
27  * (C) Copyright 2000
28  * Sysgo Real-Time Solutions GmbH
29  * Klein-Winternheim, Germany
30  *----------------------------------------------------------------------
31  */
32
33 #include <common.h>
34 #include <asm/io.h>
35 #include <asm/ic/ali512x.h>
36
37
38 /* ALI M5123 Logical device numbers:
39  * 0 FDC
40  * 1 unused?
41  * 2 unused?
42  * 3 lpt
43  * 4 UART1
44  * 5 UART2
45  * 6 RTC
46  * 7 mouse/kbd
47  * 8 CIO
48  */
49
50 /*
51  ************************************************************
52  *  Some access primitives for the ALi chip:                *
53  ************************************************************
54  */
55
56 static void ali_write(u8 index, u8 value)
57 {       
58         /* write an arbirary register */
59         outb(index, ALI_INDEX);
60         outb(value, ALI_DATA);
61 }
62
63 static int ali_read(u8 index)
64 {
65         outb(index, ALI_INDEX);
66         return inb(ALI_DATA);
67 }
68
69 #define ALI_OPEN() \
70         outb(0x51, ALI_DATA); \
71         outb(0x23, ALI_DATA)    
72
73
74 #define ALI_CLOSE() \
75         outb(0xbb, ALI_DATA)
76
77 /* Select a logical device */
78 #define ALI_SELDEV(dev) \
79         ali_write(0x07, dev)    
80
81
82 void ali512x_init(void)
83 {
84         ALI_OPEN();
85
86         ali_write(0x02, 0x01);  /* soft reset */
87         ali_write(0x03, 0x03);  /* disable access to CIOs */
88         ali_write(0x22, 0x00);  /* disable direct powerdown */
89         ali_write(0x23, 0x00);  /* disable auto powerdown */
90         ali_write(0x24, 0x00);  /* IR 8 is active hi, pin26 is PDIR */
91
92         ALI_CLOSE();
93 }
94
95 void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel)
96 {
97         ALI_OPEN();
98         ALI_SELDEV(0);
99         
100         ali_write(0x30, enabled?1:0);
101         if (enabled) {
102                 ali_write(0x60, io >> 8);
103                 ali_write(0x61, io & 0xff);
104                 ali_write(0x70, irq);
105                 ali_write(0x74, dma_channel);
106                 
107                 /* AT mode, no drive swap */
108                 ali_write(0xf0, 0x08);
109                 ali_write(0xf1, 0x00);
110                 ali_write(0xf2, 0xff);
111                 ali_write(0xf4, 0x00);
112         }
113         ALI_CLOSE();
114 }
115
116
117 void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel)
118 {
119         ALI_OPEN();
120         ALI_SELDEV(3);
121         
122         ali_write(0x30, enabled?1:0);
123         if (enabled) {
124                 ali_write(0x60, io >> 8);
125                 ali_write(0x61, io & 0xff);
126                 ali_write(0x70, irq);
127                 ali_write(0x74, dma_channel);
128                 
129                 /* mode: EPP 1.9, ECP FIFO threshold = 7, IRQ active low */
130                 ali_write(0xf0, 0xbc);
131                 /* 12 MHz, Burst DMA in ECP */
132                 ali_write(0xf1, 0x05);
133         }
134         ALI_CLOSE();
135
136 }
137
138 void ali512x_set_uart(int enabled, int index, u16 io, u8 irq)
139 {
140         ALI_OPEN();
141         ALI_SELDEV(index?5:4);
142         
143         ali_write(0x30, enabled?1:0);
144         if (enabled) {
145                 ali_write(0x60, io >> 8);
146                 ali_write(0x61, io & 0xff);
147                 ali_write(0x70, irq);
148                 
149                 ali_write(0xf0, 0x00);
150                 ali_write(0xf1, 0x00);
151                 
152                 /* huh? write 0xf2 twice - a typo in rolo
153                  * or some secret ali errata? Who knows? 
154                  */
155                 if (index) {
156                         ali_write(0xf2, 0x00);
157                 }
158                 ali_write(0xf2, 0x0c);
159         }
160         ALI_CLOSE();
161
162 }
163
164 void ali512x_set_uart2_irda(int enabled)
165 {
166         ALI_OPEN();
167         ALI_SELDEV(5);
168         
169         ali_write(0xf1, enabled?0x48:0x00); /* fullduplex IrDa */
170         ALI_CLOSE();
171
172 }
173
174 void ali512x_set_rtc(int enabled, u16 io, u8 irq)
175 {
176         ALI_OPEN();
177         ALI_SELDEV(6);
178         
179         ali_write(0x30, enabled?1:0);
180         if (enabled) {
181                 ali_write(0x60, io >> 8);
182                 ali_write(0x61, io & 0xff);
183                 ali_write(0x70, irq);
184
185                 ali_write(0xf0, 0x00);
186         }
187         ALI_CLOSE();
188 }
189
190 void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq)
191 {
192         ALI_OPEN();
193         ALI_SELDEV(7);
194         
195         ali_write(0x30, enabled?1:0);
196         if (enabled) {
197                 ali_write(0x70, kbc_irq);
198                 ali_write(0x72, mouse_irq);             
199                 
200                 ali_write(0xf0, 0x00);
201         }
202         ALI_CLOSE();
203 }
204
205
206 /* Common I/O
207  * 
208  * (This descripotsion is base on several incompete sources
209  *  since I have not been able to obtain any datasheet for the device
210  *  there may be some mis-understandings burried in here. 
211  *  -- Daniel daniel@omicron.se)
212  * 
213  * There are 22 CIO pins numbered
214  * 10-17
215  * 20-25
216  * 30-37
217  * 
218  * 20-24 are dedicated CIO pins, the other 17 are muliplexed with
219  * other functions.
220  * 
221  *           Secondary 
222  * CIO Pin   Function    Decription
223  * =======================================================
224  * CIO10     IRQIN1      Interrupt input 1?
225  * CIO11     IRQIN2      Interrupt input 2?
226  * CIO12     IRRX        IrDa Receive
227  * CIO13     IRTX        IrDa Transmit
228  * CIO14     P21         KBC P21 fucntion
229  * CIO15     P20         KBC P21 fucntion
230  * CIO16     I2C_CLK     I2C Clock
231  * CIO17     I2C_DAT     I2C Data
232  * 
233  * CIO20     -
234  * CIO21     -
235  * CIO22     -
236  * CIO23     -
237  * CIO24     -
238  * CIO25     LOCK        Keylock
239  * 
240  * CIO30     KBC_CLK     Keybaord Clock
241  * CIO31     CS0J        General Chip Select decoder CS0J
242  * CIO32     CS1J        General Chip Select decoder CS1J
243  * CIO33     ALT_KCLK    Alternative Keyboard Clock
244  * CIO34     ALT_KDAT    Alternative Keyboard Data
245  * CIO35     ALT_MCLK    Alternative Mouse Clock
246  * CIO36     ALT_MDAT    Alternative Mouse Data
247  * CIO37     ALT_KBC     Alternative KBC select
248  *
249  * The CIO use a double indirect address scheme. 
250  * 
251  * Reigster 3 in the SIO is used to selectg where the CIO 
252  * I/O registers show up under function 8. Note that these
253  * registers clash with the CIO function select regsters,
254  * below.
255  * 
256  * SIO reigster 3 (CIO Address Selection) bit definitions:
257  * bit 7   CIO data register enabled
258  * bit 1-0 CIO indirect registers select
259  *       0  index = 0xE0 data = 0xE1
260  *       1  index = 0xE2 data = 0xE3
261  *       2  index = 0xE4 data = 0xE5
262  *       3  index = 0xEA data = 0xEB
263  * 
264  * There are three CIO I/O register accessed via CIO index and CIO data
265  * 0x01     CIO 10-17 data
266  * 0x02     CIO 20-25 data (bits 7-6 unused)
267  * 0x03     CIO 30-37 data
268  * 
269  * 
270  * The pin function is accessed through normal 
271  * SIO registers, each register have the same format:
272  * 
273  * Bit   Function                     Value
274  * 0     Input/output                 1=input 
275  * 1     Polarity of signal           1=inverted
276  * 2     Unused                       ??
277  * 3     Function (normal or special) 1=special
278  * 7-4   Unused
279  * 
280  * SIO REG
281  * 0xe0     CIO 10 Config
282  * 0xe1     CIO 11 Config
283  * 0xe2     CIO 12 Config
284  * 0xe3     CIO 13 Config
285  * 0xe4     CIO 14 Config
286  * 0xe5     CIO 15 Config
287  * 0xe6     CIO 16 Config
288  * 0xe7     CIO 16 Config
289  *
290  * 0xe8     CIO 20 Config
291  * 0xe9     CIO 21 Config
292  * 0xea     CIO 22 Config
293  * 0xeb     CIO 23 Config
294  * 0xec     CIO 24 Config
295  * 0xed     CIO 25 Config
296  *
297  * 0xf5     CIO 30 Config
298  * 0xf6     CIO 31 Config
299  * 0xf7     CIO 32 Config
300  * 0xf8     CIO 33 Config
301  * 0xf9     CIO 34 Config
302  * 0xfa     CIO 35 Config
303  * 0xfb     CIO 36 Config
304  * 0xfc     CIO 37 Config
305  * 
306  */
307
308 void ali512x_set_cio(int enabled)
309 {
310         int i;
311         
312         ALI_OPEN();
313         ali_write(0x3, 3);    /* Disable CIO data register */
314         
315         ALI_SELDEV(8);
316         ali_write(0x30, enabled?1:0);
317         
318         /* set all pins to input to start with */
319         for (i=0xe0;i<0xee;i++) {
320                 ali_write(i, 1);
321         }
322         for (i=0xf5;i<0xfe;i++) {
323                 ali_write(i, 1);
324         }
325                         
326         ALI_CLOSE();
327 }
328
329 void ali512x_cio_function(int pin, int special, int inv, int input)
330 {
331         u8 data;
332         u8 addr;
333         
334         
335         /* valid pins are 10-17, 20-25 and 30-37 */
336         if (pin >= 10 && pin <= 17) { 
337                 addr = 0xe0+(pin-10);
338         } else if (pin >= 20 && pin <= 25) {
339                 addr = 0xe8+(pin-20);
340         } else if (pin >= 30 && pin <= 37) { 
341                 addr = 0xf5+(pin-30);
342         } else {
343                 return;
344         }
345         
346         ALI_OPEN();
347         ALI_SELDEV(8);
348         
349         ali_write(0x03, 0x03);    /* Disable CIO data register */
350         
351         data=0;
352         if (special) {
353                 data |= 0x08;
354         } else {
355                 if (inv) {
356                         data |= 0x02;
357                 }
358                 if (input) {
359                         data |= 0x01;
360                 }
361         }
362         
363         ali_write(addr, data);
364         
365         ALI_CLOSE();
366 }
367
368 void ali512x_cio_out(int pin, int value) 
369 {
370         u8 reg;
371         u8 data;
372         u8 bit;
373         
374         /* valid pins are 10-17, 20-25 and 30-37 */
375         if (pin >= 10 && pin <= 17) { 
376                 reg = 1;
377                 pin -= 10;
378         } else if (pin >= 20 && pin <= 25) {
379                 reg = 2;
380                 pin -= 20;
381         } else if (pin >= 30 && pin <= 37) { 
382                 reg = 3;
383                 pin -= 30;
384         } else {
385                 return;
386         }
387         bit = 1 << pin;
388         
389         ALI_OPEN();
390         ALI_SELDEV(8);
391         
392         ali_write(0x03, 0x83);    /* Enable CIO data register, use data port at 0xea */
393         
394         ali_write(0xea, reg);     /* select I/O register */
395         data = ali_read(0xeb);
396         if (value) {
397                 data |= bit;
398         } else {
399                 data &= ~bit;
400         }
401         ali_write(0xeb, data);
402         ali_write(0xea, 0);       /* select register 0 */
403         ali_write(0x03, 0x03);    /* Disable CIO data register */
404         ALI_CLOSE();
405 }
406
407 int ali512x_cio_in(int pin)
408 {
409         u8 reg;
410         u8 data;
411         u8 bit;
412         
413         /* valid pins are 10-17, 20-25 and 30-37 */
414         if (pin >= 10 && pin <= 17) { 
415                 reg = 1;
416                 pin -= 10;
417         } else if (pin >= 20 && pin <= 25) {
418                 reg = 2;
419                 pin -= 20;
420         } else if (pin >= 30 && pin <= 37) { 
421                 reg = 3;
422                 pin -= 30;
423         } else {
424                 return -1; 
425         }
426         bit = 1 << pin;
427         
428         ALI_OPEN();
429         ALI_SELDEV(8);
430         
431         ali_write(0x03, 0x83);    /* Enable CIO data register, use data port at 0xea */
432         
433         ali_write(0xea, reg);     /* select I/O register */
434         data = ali_read(0xeb);
435         ali_write(0xea, 0);       /* select register 0 */
436         ali_write(0x03, 0x03);    /* Disable CIO data register */
437         ALI_CLOSE();
438         
439         return data & bit; 
440 }
441
442