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