xref: /openbmc/u-boot/drivers/misc/ali512x.c (revision 2290fe06)
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 }
403