1/*-
2 * Low-level subroutines for Cronyx-Sigma adapter.
3 *
4 * Copyright (C) 1994-2000 Cronyx Engineering.
5 * Author: Serge Vakulenko, <vak@cronyx.ru>
6 *
7 * This software is distributed with NO WARRANTIES, not even the implied
8 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 *
10 * Authors grant any other persons or organisations permission to use
11 * or modify this software as long as this message is kept with the software,
12 * all derivative works or modified versions.
13 *
14 * Cronyx Id: csigma.c,v 1.1.2.1 2003/11/12 17:13:41 rik Exp $
15 * $FreeBSD$
16 */
17#include <dev/cx/machdep.h>
18#include <dev/cx/cxddk.h>
19#include <dev/cx/cxreg.h>
20#include <dev/cx/cronyxfw.h>
21
22#define DMA_MASK	0xd4	/* DMA mask register */
23#define DMA_MASK_CLEAR	0x04	/* DMA clear mask */
24#define DMA_MODE	0xd6	/* DMA mode register */
25#define DMA_MODE_MASTER	0xc0	/* DMA master mode */
26
27#define BYTE *(unsigned char*)&
28
29static unsigned char irqmask [] = {
30	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_3,
31	BCR0_IRQ_DIS,	BCR0_IRQ_5,	BCR0_IRQ_DIS,	BCR0_IRQ_7,
32	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_10,	BCR0_IRQ_11,
33	BCR0_IRQ_12,	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_15,
34};
35
36static unsigned char dmamask [] = {
37	BCR0_DMA_DIS,	BCR0_DMA_DIS,	BCR0_DMA_DIS,	BCR0_DMA_DIS,
38	BCR0_DMA_DIS,	BCR0_DMA_5,	BCR0_DMA_6,	BCR0_DMA_7,
39};
40
41/* standard base port set */
42static short porttab [] = {
43	0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
44	0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0
45};
46
47/* valid IRQs and DRQs */
48static short irqtab [] = { 3, 5, 7, 10, 11, 12, 15, 0 };
49static short dmatab [] = { 5, 6, 7, 0 };
50
51static int valid (short value, short *list)
52{
53	while (*list)
54		if (value == *list++)
55			return 1;
56	return 0;
57}
58
59long cx_rxbaud = 9600;		/* receiver baud rate */
60long cx_txbaud = 9600;		/* transmitter baud rate */
61
62int cx_univ_mode = M_HDLC;	/* univ. chan. mode: async or sync */
63int cx_sync_mode = M_HDLC;	/* sync. chan. mode: HDLC, Bisync or X.21 */
64int cx_iftype = 0;		/* univ. chan. interface: upper/lower */
65
66static int cx_probe_chip (port_t base);
67static void cx_setup_chip (cx_chan_t *c);
68
69/*
70 * Wait for CCR to clear.
71 */
72void cx_cmd (port_t base, int cmd)
73{
74	port_t port = CCR(base);
75	int count;
76
77	/* Wait 10 msec for the previous command to complete. */
78	for (count=0; inb(port) && count<20000; ++count)
79		continue;
80
81	/* Issue the command. */
82	outb (port, cmd);
83
84	/* Wait 10 msec for the command to complete. */
85	for (count=0; inb(port) && count<20000; ++count)
86		continue;
87}
88
89/*
90 * Reset the chip.
91 */
92static int cx_reset (port_t port)
93{
94	int count;
95
96	/* Wait up to 10 msec for revision code to appear after reset. */
97	for (count=0; count<20000; ++count)
98		if (inb(GFRCR(port)) != 0)
99			break;
100
101	cx_cmd (port, CCR_RSTALL);
102
103	/* Firmware revision code should clear immediately. */
104	/* Wait up to 10 msec for revision code to appear again. */
105	for (count=0; count<20000; ++count)
106		if (inb(GFRCR(port)) != 0)
107			return (1);
108
109	/* Reset failed. */
110	return (0);
111}
112
113int cx_download (port_t port, const unsigned char *firmware, long bits,
114	const cr_dat_tst_t *tst)
115{
116	unsigned char cr2, sr;
117	long i, n, maxn = (bits + 7) / 8;
118	int v, b;
119
120	inb (BDET(port));
121	for (i=n=0; n<maxn; ++n) {
122		v = ((firmware[n] ^ ' ') << 1) | (firmware[n] >> 7 & 1);
123		for (b=0; b<7; b+=2, i+=2) {
124			if (i >= bits)
125				break;
126			cr2 = 0;
127			if (v >> b & 1) cr2 |= BCR2_TMS;
128			if (v >> b & 2) cr2 |= BCR2_TDI;
129			outb (BCR2(port), cr2);
130			sr = inb (BSR(port));
131			outb (BCR0(port), BCR0800_TCK);
132			outb (BCR0(port), 0);
133			if (i >= tst->end)
134				++tst;
135			if (i >= tst->start && (sr & BSR800_LERR))
136				return (0);
137		}
138	}
139	return (1);
140}
141
142/*
143 * Check if the Sigma-XXX board is present at the given base port.
144 */
145static int cx_probe_chained_board (port_t port, int *c0, int *c1)
146{
147	int rev, i;
148
149	/* Read and check the board revision code. */
150	rev = inb (BSR(port));
151	*c0 = *c1 = 0;
152	switch (rev & BSR_VAR_MASK) {
153	case CRONYX_100:	*c0 = 1;	break;
154	case CRONYX_400:	*c1 = 1;	break;
155	case CRONYX_500:	*c0 = *c1 = 1;	break;
156	case CRONYX_410:	*c0 = 1;	break;
157	case CRONYX_810:	*c0 = *c1 = 1;	break;
158	case CRONYX_410s:	*c0 = 1;	break;
159	case CRONYX_810s:	*c0 = *c1 = 1;	break;
160	case CRONYX_440:	*c0 = 1;	break;
161	case CRONYX_840:	*c0 = *c1 = 1;	break;
162	case CRONYX_401:	*c0 = 1;	break;
163	case CRONYX_801:	*c0 = *c1 = 1;	break;
164	case CRONYX_401s:	*c0 = 1;	break;
165	case CRONYX_801s:	*c0 = *c1 = 1;	break;
166	case CRONYX_404:	*c0 = 1;	break;
167	case CRONYX_703:	*c0 = *c1 = 1;	break;
168	default:		return (0);	/* invalid variant code */
169	}
170
171	switch (rev & BSR_OSC_MASK) {
172	case BSR_OSC_20:	/* 20 MHz */
173	case BSR_OSC_18432:	/* 18.432 MHz */
174		break;
175	default:
176		return (0);	/* oscillator frequency does not match */
177	}
178
179	for (i=2; i<0x10; i+=2)
180		if ((inb (BSR(port)+i) & BSR_REV_MASK) != (rev & BSR_REV_MASK))
181			return (0);	/* status changed? */
182	return (1);
183}
184
185/*
186 * Check if the Sigma-800 board is present at the given base port.
187 * Read board status register 1 and check identification bits
188 * which should invert every next read.
189 */
190static int cx_probe_800_chained_board (port_t port)
191{
192	unsigned char det, odet;
193	int i;
194
195	odet = inb (BDET(port));
196	if ((odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB &&
197	    (odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB_NEG)
198		return (0);
199	for (i=0; i<100; ++i) {
200		det = inb (BDET(port));
201		if (((det ^ odet) & (BDET_IB | BDET_IB_NEG)) !=
202		    (BDET_IB | BDET_IB_NEG))
203			return (0);
204		odet = det;
205	}
206	/* Reset the controller. */
207	outb (BCR0(port), 0);
208	outb (BCR1(port), 0);
209	outb (BCR2(port), 0);
210	return (1);
211}
212
213/*
214 * Check if the Sigma-2x board is present at the given base port.
215 */
216static int cx_probe_2x_board (port_t port)
217{
218	int rev, i;
219
220	/* Read and check the board revision code. */
221	rev = inb (BSR(port));
222	if ((rev & BSR2X_VAR_MASK) != CRONYX_22 &&
223	    (rev & BSR2X_VAR_MASK) != CRONYX_24)
224		return (0);		/* invalid variant code */
225
226	for (i=2; i<0x10; i+=2)
227		if ((inb (BSR(port)+i) & BSR2X_REV_MASK) !=
228		    (rev & BSR2X_REV_MASK))
229			return (0);	/* status changed? */
230	return (1);
231}
232
233/*
234 * Check if the Cronyx-Sigma board is present at the given base port.
235 */
236int cx_probe_board (port_t port, int irq, int dma)
237{
238	int c0, c1, c2=0, c3=0, result;
239
240	if (! valid (port, porttab))
241		return 0;
242
243	if (irq > 0 && ! valid (irq, irqtab))
244		return 0;
245
246	if (dma > 0 && ! valid (dma, dmatab))
247		return 0;
248
249	if (cx_probe_800_chained_board (port)) {
250		/* Sigma-800 detected. */
251		if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
252			/* chained board attached */
253			if (! cx_probe_800_chained_board (port+0x10))
254				/* invalid chained board? */
255				return (0);
256			if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
257				/* invalid chained board flag? */
258				return (0);
259		}
260		return 1;
261	}
262	if (cx_probe_chained_board (port, &c0, &c1)) {
263		/* Sigma-XXX detected. */
264		if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
265			/* chained board attached */
266			if (! cx_probe_chained_board (port+0x10, &c2, &c3))
267				/* invalid chained board? */
268				return (0);
269			if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
270				/* invalid chained board flag? */
271				return (0);
272		}
273	} else if (cx_probe_2x_board (port)) {
274		c0 = 1;		/* Sigma-2x detected. */
275		c1 = 0;
276	} else
277		return (0);     /* no board detected */
278
279	/* Turn off the reset bit. */
280	outb (BCR0(port), BCR0_NORESET);
281	if (c2 || c3)
282		outb (BCR0(port + 0x10), BCR0_NORESET);
283
284	result = 1;
285	if (c0 && ! cx_probe_chip (CS0(port)))
286		result = 0;	/* no CD2400 chip here */
287	else if (c1 && ! cx_probe_chip (CS1A(port)) &&
288	    ! cx_probe_chip (CS1(port)))
289		result = 0;	/* no second CD2400 chip */
290	else if (c2 && ! cx_probe_chip (CS0(port + 0x10)))
291		result = 0;	/* no CD2400 chip on the slave board */
292	else if (c3 && ! cx_probe_chip (CS1(port + 0x10)))
293		result = 0;	/* no second CD2400 chip on the slave board */
294
295	/* Reset the controller. */
296	outb (BCR0(port), 0);
297	if (c2 || c3)
298		outb (BCR0(port + 0x10), 0);
299
300	/* Yes, we really have valid Sigma board. */
301	return (result);
302}
303
304/*
305 * Check if the CD2400 chip is present at the given base port.
306 */
307static int cx_probe_chip (port_t base)
308{
309	int rev, newrev, count;
310
311	/* Wait up to 10 msec for revision code to appear after reset. */
312	rev = 0;
313	for (count=0; rev==0; ++count) {
314		if (count >= 20000)
315			return (0); /* reset failed */
316		rev = inb (GFRCR(base));
317	}
318
319	/* Read and check the global firmware revision code. */
320	if (! (rev>=REVCL_MIN && rev<=REVCL_MAX) &&
321	    ! (rev>=REVCL31_MIN && rev<=REVCL31_MAX))
322		return (0);	/* CD2400/2431 revision does not match */
323
324	/* Reset the chip. */
325	if (! cx_reset (base))
326		return (0);
327
328	/* Read and check the new global firmware revision code. */
329	newrev = inb (GFRCR(base));
330	if (newrev != rev)
331		return (0);	/* revision changed */
332
333	/* Yes, we really have CD2400/2431 chip here. */
334	return (1);
335}
336
337/*
338 * Check that the irq is functional.
339 * irq>0  - activate the interrupt from the adapter (irq=on)
340 * irq<0  - deactivate the interrupt (irq=off)
341 * irq==0 - free the interrupt line (irq=tri-state)
342 * Return the interrupt mask _before_ activating irq.
343 */
344int cx_probe_irq (cx_board_t *b, int irq)
345{
346	int mask, rev;
347        port_t port;
348
349	rev = inb (BSR(b->port));
350        port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(b->port) : CS1(b->port);
351
352	outb (0x20, 0x0a);
353	mask = inb (0x20);
354	outb (0xa0, 0x0a);
355	mask |= inb (0xa0) << 8;
356
357	if (irq > 0) {
358		outb (BCR0(b->port), BCR0_NORESET | irqmask[irq]);
359		outb (CAR(port), 0);
360		cx_cmd (port, CCR_CLRCH);
361		outb (CMR(port), CMR_HDLC);
362		outb (TCOR(port), 0);
363		outb (TBPR(port), 1);
364		cx_cmd (port, CCR_INITCH | CCR_ENTX);
365		outb (IER(port), IER_TXMPTY);
366	} else if (irq < 0) {
367		cx_reset (port);
368		if (-irq > 7) {
369			outb (0xa0, 0x60 | ((-irq) & 7));
370			outb (0x20, 0x62);
371		} else
372			outb (0x20, 0x60 | (-irq));
373	} else
374		outb (BCR0(b->port), 0);
375	return mask;
376}
377
378static int cx_chip_revision (port_t port, int rev)
379{
380	int count;
381
382	/* Model 400 has no first chip. */
383	port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(port) : CS1(port);
384
385	/* Wait up to 10 msec for revision code to appear after reset. */
386	for (count=0; inb(GFRCR(port))==0; ++count)
387		if (count >= 20000)
388			return (0); /* reset failed */
389
390	return inb (GFRCR (port));
391}
392
393/*
394 * Probe and initialize the board structure.
395 */
396void cx_init (cx_board_t *b, int num, port_t port, int irq, int dma)
397{
398	int gfrcr, rev, chain, mod = 0, rev2 = 0, mod2 = 0;
399
400	rev = inb (BSR(port));
401	chain = ! (rev & BSR_NOCHAIN);
402	if (cx_probe_800_chained_board (port)) {
403		cx_init_800 (b, num, port, irq, dma, chain);
404		return;
405	}
406	if ((rev & BSR2X_VAR_MASK) == CRONYX_22 ||
407	    (rev & BSR2X_VAR_MASK) == CRONYX_24) {
408		cx_init_2x (b, num, port, irq, dma,
409			(rev & BSR2X_VAR_MASK), (rev & BSR2X_OSC_33));
410		return;
411        }
412
413	outb (BCR0(port), BCR0_NORESET);
414	if (chain)
415		outb (BCR0(port+0x10), BCR0_NORESET);
416	gfrcr = cx_chip_revision (port, rev);
417	if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
418		mod = 1;
419	if (chain) {
420		rev2 = inb (BSR(port+0x10));
421		gfrcr = cx_chip_revision (port+0x10, rev2);
422		if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
423			mod2 = 1;
424		outb (BCR0(port+0x10), 0);
425	}
426	outb (BCR0(port), 0);
427
428	cx_init_board (b, num, port, irq, dma, chain,
429		(rev & BSR_VAR_MASK), (rev & BSR_OSC_MASK), mod,
430		(rev2 & BSR_VAR_MASK), (rev2 & BSR_OSC_MASK), mod2);
431}
432
433/*
434 * Initialize the board structure, given the type of the board.
435 */
436void cx_init_board (cx_board_t *b, int num, port_t port, int irq, int dma,
437	int chain, int rev, int osc, int mod, int rev2, int osc2, int mod2)
438{
439	cx_chan_t *c;
440	char *type;
441	int i;
442
443	/* Initialize board structure. */
444	b->port = port;
445	b->num = num;
446	b->irq = irq;
447	b->dma = dma;
448	b->opt = board_opt_dflt;
449
450	b->type = B_SIGMA_XXX;
451	b->if0type = b->if8type = cx_iftype;
452
453	/* Set channels 0 and 8 mode, set DMA and IRQ. */
454	b->bcr0 = b->bcr0b = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
455
456	/* Clear DTR[0..3] and DTR[8..12]. */
457	b->bcr1 = b->bcr1b = 0;
458
459	/*------------------ Master board -------------------*/
460
461	/* Read and check the board revision code. */
462	strcpy (b->name, mod ? "m" : "");
463	switch (rev) {
464	default:	  type = "";	 break;
465	case CRONYX_100:  type = "100";  break;
466	case CRONYX_400:  type = "400";  break;
467	case CRONYX_500:  type = "500";  break;
468	case CRONYX_410:  type = "410";  break;
469	case CRONYX_810:  type = "810";  break;
470	case CRONYX_410s: type = "410s"; break;
471	case CRONYX_810s: type = "810s"; break;
472	case CRONYX_440:  type = "440";  break;
473	case CRONYX_840:  type = "840";  break;
474	case CRONYX_401:  type = "401";  break;
475	case CRONYX_801:  type = "801";  break;
476	case CRONYX_401s: type = "401s"; break;
477	case CRONYX_801s: type = "801s"; break;
478	case CRONYX_404:  type = "404";  break;
479	case CRONYX_703:  type = "703";  break;
480	}
481	strcat (b->name, type);
482
483	switch (osc) {
484	default:
485	case BSR_OSC_20: /* 20 MHz */
486		b->chan[0].oscfreq = b->chan[1].oscfreq =
487		b->chan[2].oscfreq = b->chan[3].oscfreq =
488		b->chan[4].oscfreq = b->chan[5].oscfreq =
489		b->chan[6].oscfreq = b->chan[7].oscfreq =
490			mod ? 33000000L : 20000000L;
491		strcat (b->name, "a");
492		break;
493	case BSR_OSC_18432: /* 18.432 MHz */
494		b->chan[0].oscfreq = b->chan[1].oscfreq =
495		b->chan[2].oscfreq = b->chan[3].oscfreq =
496		b->chan[4].oscfreq = b->chan[5].oscfreq =
497		b->chan[6].oscfreq = b->chan[7].oscfreq =
498			mod ? 20000000L : 18432000L;
499		strcat (b->name, "b");
500		break;
501	}
502
503	/*------------------ Slave board -------------------*/
504
505	if (chain) {
506		/* Read and check the board revision code. */
507		strcat (b->name, mod2 ? "/m" : "/");
508		switch (rev2) {
509		default:	  type = "";	 break;
510		case CRONYX_100:  type = "100";  break;
511		case CRONYX_400:  type = "400";  break;
512		case CRONYX_500:  type = "500";  break;
513		case CRONYX_410:  type = "410";  break;
514		case CRONYX_810:  type = "810";  break;
515		case CRONYX_410s: type = "410s"; break;
516		case CRONYX_810s: type = "810s"; break;
517		case CRONYX_440:  type = "440";  break;
518		case CRONYX_840:  type = "840";  break;
519		case CRONYX_401:  type = "401";  break;
520		case CRONYX_801:  type = "801";  break;
521		case CRONYX_401s: type = "401s"; break;
522		case CRONYX_801s: type = "801s"; break;
523		case CRONYX_404:  type = "404";  break;
524		case CRONYX_703:  type = "703";  break;
525		}
526		strcat (b->name, type);
527
528		switch (osc2) {
529		default:
530		case BSR_OSC_20: /* 20 MHz */
531			b->chan[8].oscfreq = b->chan[9].oscfreq =
532			b->chan[10].oscfreq = b->chan[11].oscfreq =
533			b->chan[12].oscfreq = b->chan[13].oscfreq =
534			b->chan[14].oscfreq = b->chan[15].oscfreq =
535				mod2 ? 33000000L : 20000000L;
536			strcat (b->name, "a");
537			break;
538		case BSR_OSC_18432: /* 18.432 MHz */
539			b->chan[8].oscfreq = b->chan[9].oscfreq =
540			b->chan[10].oscfreq = b->chan[11].oscfreq =
541			b->chan[12].oscfreq = b->chan[13].oscfreq =
542			b->chan[14].oscfreq = b->chan[15].oscfreq =
543				mod2 ? 20000000L : 18432000L;
544			strcat (b->name, "b");
545			break;
546		}
547	}
548
549	/* Initialize channel structures. */
550	for (i=0; i<4; ++i) {
551		b->chan[i+0].port  = CS0(port);
552		b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
553			CS1A(port) : CS1(port);
554		b->chan[i+8].port  = CS0(port+0x10);
555		b->chan[i+12].port = CS1(port+0x10);
556	}
557	for (c=b->chan; c<b->chan+NCHAN; ++c) {
558		c->board = b;
559		c->num = c - b->chan;
560		c->type = T_NONE;
561	}
562
563	/*------------------ Master board -------------------*/
564
565	switch (rev) {
566	case CRONYX_400:
567		for (i=4; i<8; ++i)
568			b->chan[i].type = T_UNIV_RS232;
569		break;
570	case CRONYX_100:
571		b->chan[0].type = T_UNIV_RS232;
572		break;
573	case CRONYX_500:
574		b->chan[0].type = T_UNIV_RS232;
575		for (i=4; i<8; ++i)
576			b->chan[i].type = T_UNIV_RS232;
577		break;
578	case CRONYX_410:
579		b->chan[0].type = T_UNIV_V35;
580		for (i=1; i<4; ++i)
581			b->chan[i].type = T_UNIV_RS232;
582		break;
583	case CRONYX_810:
584		b->chan[0].type = T_UNIV_V35;
585		for (i=1; i<8; ++i)
586			b->chan[i].type = T_UNIV_RS232;
587		break;
588	case CRONYX_410s:
589		b->chan[0].type = T_UNIV_V35;
590		for (i=1; i<4; ++i)
591			b->chan[i].type = T_SYNC_RS232;
592		break;
593	case CRONYX_810s:
594		b->chan[0].type = T_UNIV_V35;
595		for (i=1; i<4; ++i)
596			b->chan[i].type = T_SYNC_RS232;
597		for (i=4; i<8; ++i)
598			b->chan[i].type = T_UNIV_RS232;
599		break;
600	case CRONYX_440:
601		b->chan[0].type = T_UNIV_V35;
602		for (i=1; i<4; ++i)
603			b->chan[i].type = T_SYNC_V35;
604		break;
605	case CRONYX_840:
606		b->chan[0].type = T_UNIV_V35;
607		for (i=1; i<4; ++i)
608			b->chan[i].type = T_SYNC_V35;
609		for (i=4; i<8; ++i)
610			b->chan[i].type = T_UNIV_RS232;
611		break;
612	case CRONYX_401:
613		b->chan[0].type = T_UNIV_RS449;
614		for (i=1; i<4; ++i)
615			b->chan[i].type = T_UNIV_RS232;
616		break;
617	case CRONYX_801:
618		b->chan[0].type = T_UNIV_RS449;
619		for (i=1; i<8; ++i)
620			b->chan[i].type = T_UNIV_RS232;
621		break;
622	case CRONYX_401s:
623		b->chan[0].type = T_UNIV_RS449;
624		for (i=1; i<4; ++i)
625			b->chan[i].type = T_SYNC_RS232;
626		break;
627	case CRONYX_801s:
628		b->chan[0].type = T_UNIV_RS449;
629		for (i=1; i<4; ++i)
630			b->chan[i].type = T_SYNC_RS232;
631		for (i=4; i<8; ++i)
632			b->chan[i].type = T_UNIV_RS232;
633		break;
634	case CRONYX_404:
635		b->chan[0].type = T_UNIV_RS449;
636		for (i=1; i<4; ++i)
637			b->chan[i].type = T_SYNC_RS449;
638		break;
639	case CRONYX_703:
640		b->chan[0].type = T_UNIV_RS449;
641		for (i=1; i<3; ++i)
642			b->chan[i].type = T_SYNC_RS449;
643		for (i=4; i<8; ++i)
644			b->chan[i].type = T_UNIV_RS232;
645		break;
646	}
647
648	/*------------------ Slave board -------------------*/
649
650	if (chain) {
651		switch (rev2) {
652		case CRONYX_400:
653			break;
654		case CRONYX_100:
655			b->chan[8].type = T_UNIV_RS232;
656			break;
657		case CRONYX_500:
658			b->chan[8].type = T_UNIV_RS232;
659			for (i=12; i<16; ++i)
660				b->chan[i].type = T_UNIV_RS232;
661			break;
662		case CRONYX_410:
663			b->chan[8].type = T_UNIV_V35;
664			for (i=9; i<12; ++i)
665				b->chan[i].type = T_UNIV_RS232;
666			break;
667		case CRONYX_810:
668			b->chan[8].type = T_UNIV_V35;
669			for (i=9; i<16; ++i)
670				b->chan[i].type = T_UNIV_RS232;
671			break;
672		case CRONYX_410s:
673			b->chan[8].type = T_UNIV_V35;
674			for (i=9; i<12; ++i)
675				b->chan[i].type = T_SYNC_RS232;
676			break;
677		case CRONYX_810s:
678			b->chan[8].type = T_UNIV_V35;
679			for (i=9; i<12; ++i)
680				b->chan[i].type = T_SYNC_RS232;
681			for (i=12; i<16; ++i)
682				b->chan[i].type = T_UNIV_RS232;
683			break;
684		case CRONYX_440:
685			b->chan[8].type = T_UNIV_V35;
686			for (i=9; i<12; ++i)
687				b->chan[i].type = T_SYNC_V35;
688			break;
689		case CRONYX_840:
690			b->chan[8].type = T_UNIV_V35;
691			for (i=9; i<12; ++i)
692				b->chan[i].type = T_SYNC_V35;
693			for (i=12; i<16; ++i)
694				b->chan[i].type = T_UNIV_RS232;
695			break;
696		case CRONYX_401:
697			b->chan[8].type = T_UNIV_RS449;
698			for (i=9; i<12; ++i)
699				b->chan[i].type = T_UNIV_RS232;
700			break;
701		case CRONYX_801:
702			b->chan[8].type = T_UNIV_RS449;
703			for (i=9; i<16; ++i)
704				b->chan[i].type = T_UNIV_RS232;
705			break;
706		case CRONYX_401s:
707			b->chan[8].type = T_UNIV_RS449;
708			for (i=9; i<12; ++i)
709				b->chan[i].type = T_UNIV_RS232;
710			break;
711		case CRONYX_801s:
712			b->chan[8].type = T_UNIV_RS449;
713			for (i=9; i<12; ++i)
714				b->chan[i].type = T_SYNC_RS232;
715			for (i=12; i<16; ++i)
716				b->chan[i].type = T_UNIV_RS232;
717			break;
718		case CRONYX_404:
719			b->chan[8].type = T_UNIV_RS449;
720			for (i=9; i<12; ++i)
721				b->chan[i].type = T_SYNC_RS449;
722			break;
723		case CRONYX_703:
724			b->chan[8].type = T_UNIV_RS449;
725			for (i=9; i<11; ++i)
726				b->chan[i].type = T_SYNC_RS449;
727			for (i=12; i<16; ++i)
728				b->chan[i].type = T_UNIV_RS232;
729			break;
730		}
731	}
732
733	b->nuniv = b->nsync = b->nasync = 0;
734	for (c=b->chan; c<b->chan+NCHAN; ++c)
735		switch (c->type) {
736		case T_ASYNC:      ++b->nasync; break;
737		case T_UNIV:
738		case T_UNIV_RS232:
739		case T_UNIV_RS449:
740		case T_UNIV_V35:   ++b->nuniv;  break;
741		case T_SYNC_RS232:
742		case T_SYNC_V35:
743		case T_SYNC_RS449: ++b->nsync;  break;
744		}
745
746	cx_reinit_board (b);
747}
748
749/*
750 * Initialize the Sigma-800 board structure.
751 */
752void cx_init_800 (cx_board_t *b, int num, port_t port, int irq, int dma,
753	int chain)
754{
755	cx_chan_t *c;
756	int i;
757
758	/* Initialize board structure. */
759	b->port = port;
760	b->num = num;
761	b->irq = irq;
762	b->dma = dma;
763	b->opt = board_opt_dflt;
764	b->type = B_SIGMA_800;
765
766	/* Set channels 0 and 8 mode, set DMA and IRQ. */
767	b->bcr0 = b->bcr0b = dmamask[b->dma] | irqmask[b->irq];
768
769	/* Clear DTR[0..7] and DTR[8..15]. */
770	b->bcr1 = b->bcr1b = 0;
771
772	strcpy (b->name, "800");
773	if (chain)
774		strcat (b->name, "/800");
775
776	/* Initialize channel structures. */
777	for (i=0; i<4; ++i) {
778		b->chan[i+0].port  = CS0(port);
779		b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
780			CS1A(port) : CS1(port);
781		b->chan[i+8].port  = CS0(port+0x10);
782		b->chan[i+12].port = CS1(port+0x10);
783	}
784	for (c=b->chan; c<b->chan+NCHAN; ++c) {
785		c->board = b;
786		c->num = c - b->chan;
787		c->oscfreq = 33000000L;
788		c->type = (c->num < 8 || chain) ? T_UNIV_RS232 : T_NONE;
789	}
790
791	b->nuniv = b->nsync = b->nasync = 0;
792	for (c=b->chan; c<b->chan+NCHAN; ++c)
793		switch (c->type) {
794		case T_ASYNC:      ++b->nasync; break;
795		case T_UNIV:
796		case T_UNIV_RS232:
797		case T_UNIV_RS449:
798		case T_UNIV_V35:   ++b->nuniv;  break;
799		case T_SYNC_RS232:
800		case T_SYNC_V35:
801		case T_SYNC_RS449: ++b->nsync;  break;
802		}
803
804	cx_reinit_board (b);
805}
806
807/*
808 * Initialize the Sigma-2x board structure.
809 */
810void cx_init_2x (cx_board_t *b, int num, port_t port, int irq, int dma,
811	int rev, int osc)
812{
813	cx_chan_t *c;
814	int i;
815
816	/* Initialize board structure. */
817	b->port = port;
818	b->num = num;
819	b->irq = irq;
820	b->dma = dma;
821	b->opt = board_opt_dflt;
822
823	b->type = B_SIGMA_2X;
824
825	/* Set channels 0 and 8 mode, set DMA and IRQ. */
826	b->bcr0 = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
827	if (b->type == B_SIGMA_2X && b->opt.fast)
828		b->bcr0 |= BCR02X_FAST;
829
830	/* Clear DTR[0..3] and DTR[8..12]. */
831	b->bcr1 = 0;
832
833	/* Initialize channel structures. */
834	for (i=0; i<4; ++i) {
835		b->chan[i+0].port  = CS0(port);
836		b->chan[i+4].port  = CS1(port);
837		b->chan[i+8].port  = CS0(port+0x10);
838		b->chan[i+12].port = CS1(port+0x10);
839	}
840	for (c=b->chan; c<b->chan+NCHAN; ++c) {
841		c->board = b;
842		c->num = c - b->chan;
843		c->type = T_NONE;
844		c->oscfreq = (osc & BSR2X_OSC_33) ? 33000000L : 20000000L;
845	}
846
847	/* Check the board revision code. */
848	strcpy (b->name, "22");
849	b->chan[0].type = T_UNIV;
850	b->chan[1].type = T_UNIV;
851	b->nsync = b->nasync = 0;
852	b->nuniv = 2;
853	if (rev == CRONYX_24) {
854		strcpy (b->name, "24");
855		b->chan[2].type = T_UNIV;
856		b->chan[3].type = T_UNIV;
857		b->nuniv += 2;
858	}
859	strcat (b->name, (osc & BSR2X_OSC_33) ? "c" : "a");
860	cx_reinit_board (b);
861}
862
863/*
864 * Reinitialize all channels, using new options and baud rate.
865 */
866void cx_reinit_board (cx_board_t *b)
867{
868	cx_chan_t *c;
869
870	b->opt = board_opt_dflt;
871	if (b->type == B_SIGMA_2X) {
872		b->bcr0 &= ~BCR02X_FAST;
873		if (b->opt.fast)
874			b->bcr0 |= BCR02X_FAST;
875	} else
876		b->if0type = b->if8type = cx_iftype;
877	for (c=b->chan; c<b->chan+NCHAN; ++c) {
878		switch (c->type) {
879		default:
880		case T_NONE:
881			continue;
882		case T_UNIV:
883		case T_UNIV_RS232:
884		case T_UNIV_RS449:
885		case T_UNIV_V35:
886			c->mode = (cx_univ_mode == M_ASYNC) ?
887				M_ASYNC : cx_sync_mode;
888			break;
889		case T_SYNC_RS232:
890		case T_SYNC_V35:
891		case T_SYNC_RS449:
892			c->mode = cx_sync_mode;
893			break;
894		case T_ASYNC:
895			c->mode = M_ASYNC;
896			break;
897		}
898		c->rxbaud = cx_rxbaud;
899		c->txbaud = cx_txbaud;
900		c->opt = chan_opt_dflt;
901		c->aopt = opt_async_dflt;
902		c->hopt = opt_hdlc_dflt;
903	}
904}
905
906/*
907 * Set up the board.
908 */
909int cx_setup_board (cx_board_t *b, const unsigned char *firmware,
910	long bits, const cr_dat_tst_t *tst)
911{
912	int i;
913#ifndef NDIS_MINIPORT_DRIVER
914	/* Disable DMA channel. */
915	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
916#endif
917	/* Reset the controller. */
918	outb (BCR0(b->port), 0);
919	if (b->chan[8].type || b->chan[12].type)
920		outb (BCR0(b->port+0x10), 0);
921
922	/* Load the firmware. */
923	if (b->type == B_SIGMA_800) {
924		/* Reset the controllers. */
925		outb (BCR2(b->port), BCR2_TMS);
926		if (b->chan[8].type || b->chan[12].type)
927			outb (BCR2(b->port+0x10), BCR2_TMS);
928		outb (BCR2(b->port), 0);
929		if (b->chan[8].type || b->chan[12].type)
930			outb (BCR2(b->port+0x10), 0);
931
932		if (firmware &&
933		    (! cx_download (b->port, firmware, bits, tst) ||
934		    ((b->chan[8].type || b->chan[12].type) &&
935		    ! cx_download (b->port+0x10, firmware, bits, tst))))
936			return (0);
937	}
938
939	/*
940	 * Set channels 0 and 8 to RS232 async. mode.
941	 * Enable DMA and IRQ.
942	 */
943	outb (BCR0(b->port), b->bcr0);
944	if (b->chan[8].type || b->chan[12].type)
945		outb (BCR0(b->port+0x10), b->bcr0b);
946
947	/* Clear DTR[0..3] and DTR[8..12]. */
948	outw (BCR1(b->port), b->bcr1);
949	if (b->chan[8].type || b->chan[12].type)
950		outw (BCR1(b->port+0x10), b->bcr1b);
951
952	if (b->type == B_SIGMA_800)
953		outb (BCR2(b->port), b->opt.fast &
954			(BCR2_BUS0 | BCR2_BUS1));
955
956	/* Initialize all controllers. */
957	for (i=0; i<NCHAN; i+=4)
958		if (b->chan[i].type != T_NONE)
959			cx_setup_chip (b->chan + i);
960#ifndef NDIS_MINIPORT_DRIVER
961	/* Set up DMA channel to master mode. */
962	outb (DMA_MODE, (b->dma & 3) | DMA_MODE_MASTER);
963
964	/* Enable DMA channel. */
965	outb (DMA_MASK, b->dma & 3);
966#endif
967	/* Initialize all channels. */
968	for (i=0; i<NCHAN; ++i)
969		if (b->chan[i].type != T_NONE)
970			cx_setup_chan (b->chan + i);
971	return (1);
972}
973
974/*
975 * Initialize the board.
976 */
977static void cx_setup_chip (cx_chan_t *c)
978{
979	/* Reset the chip. */
980	cx_reset (c->port);
981
982	/*
983	 * Set all interrupt level registers to the same value.
984	 * This enables the internal CD2400 priority scheme.
985	 */
986	outb (RPILR(c->port), BRD_INTR_LEVEL);
987	outb (TPILR(c->port), BRD_INTR_LEVEL);
988	outb (MPILR(c->port), BRD_INTR_LEVEL);
989
990	/* Set bus error count to zero. */
991	outb (BERCNT(c->port), 0);
992
993	/* Set 16-bit DMA mode. */
994	outb (DMR(c->port), 0);
995
996	/* Set timer period register to 1 msec (approximately). */
997	outb (TPR(c->port), 10);
998}
999
1000/*
1001 * Initialize the CD2400 channel.
1002 */
1003void cx_update_chan (cx_chan_t *c)
1004{
1005	int clock, period;
1006
1007	if (c->board->type == B_SIGMA_XXX)
1008		switch (c->num) {
1009		case 0:
1010			c->board->bcr0 &= ~BCR0_UMASK;
1011			if (c->mode != M_ASYNC)
1012				c->board->bcr0 |= BCR0_UM_SYNC;
1013			if (c->board->if0type &&
1014			    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
1015				c->board->bcr0 |= BCR0_UI_RS449;
1016			outb (BCR0(c->board->port), c->board->bcr0);
1017			break;
1018		case 8:
1019			c->board->bcr0b &= ~BCR0_UMASK;
1020			if (c->mode != M_ASYNC)
1021				c->board->bcr0b |= BCR0_UM_SYNC;
1022			if (c->board->if8type &&
1023			    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
1024				c->board->bcr0b |= BCR0_UI_RS449;
1025			outb (BCR0(c->board->port+0x10), c->board->bcr0b);
1026			break;
1027		}
1028
1029	/* set current channel number */
1030	outb (CAR(c->port), c->num & 3);
1031
1032	switch (c->mode) {	/* initialize the channel mode */
1033	case M_ASYNC:
1034		/* set receiver timeout register */
1035		outw (RTPR(c->port), 10);          /* 10 msec, see TPR */
1036		c->opt.rcor.encod = ENCOD_NRZ;
1037
1038		outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_ASYNC);
1039		outb (COR1(c->port), BYTE c->aopt.cor1);
1040		outb (COR2(c->port), BYTE c->aopt.cor2);
1041		outb (COR3(c->port), BYTE c->aopt.cor3);
1042		outb (COR6(c->port), BYTE c->aopt.cor6);
1043		outb (COR7(c->port), BYTE c->aopt.cor7);
1044		outb (SCHR1(c->port), c->aopt.schr1);
1045		outb (SCHR2(c->port), c->aopt.schr2);
1046		outb (SCHR3(c->port), c->aopt.schr3);
1047		outb (SCHR4(c->port), c->aopt.schr4);
1048		outb (SCRL(c->port), c->aopt.scrl);
1049		outb (SCRH(c->port), c->aopt.scrh);
1050		outb (LNXT(c->port), c->aopt.lnxt);
1051		break;
1052	case M_HDLC:
1053		outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_HDLC);
1054		outb (COR1(c->port), BYTE c->hopt.cor1);
1055		outb (COR2(c->port), BYTE c->hopt.cor2);
1056		outb (COR3(c->port), BYTE c->hopt.cor3);
1057		outb (RFAR1(c->port), c->hopt.rfar1);
1058		outb (RFAR2(c->port), c->hopt.rfar2);
1059		outb (RFAR3(c->port), c->hopt.rfar3);
1060		outb (RFAR4(c->port), c->hopt.rfar4);
1061		outb (CPSR(c->port), c->hopt.cpsr);
1062		break;
1063	}
1064
1065	/* set mode-independent options */
1066	outb (COR4(c->port), BYTE c->opt.cor4);
1067	outb (COR5(c->port), BYTE c->opt.cor5);
1068
1069	/* set up receiver clock values */
1070	if (c->mode == M_ASYNC || c->opt.rcor.dpll || c->opt.tcor.llm) {
1071		cx_clock (c->oscfreq, c->rxbaud, &clock, &period);
1072		c->opt.rcor.clk = clock;
1073	} else {
1074		c->opt.rcor.clk = CLK_EXT;
1075		period = 1;
1076	}
1077	outb (RCOR(c->port), BYTE c->opt.rcor);
1078	outb (RBPR(c->port), period);
1079
1080	/* set up transmitter clock values */
1081	if (c->mode == M_ASYNC || !c->opt.tcor.ext1x) {
1082		unsigned ext1x = c->opt.tcor.ext1x;
1083		c->opt.tcor.ext1x = 0;
1084		cx_clock (c->oscfreq, c->txbaud, &clock, &period);
1085		c->opt.tcor.clk = clock;
1086		c->opt.tcor.ext1x = ext1x;
1087	} else {
1088		c->opt.tcor.clk = CLK_EXT;
1089		period = 1;
1090	}
1091	outb (TCOR(c->port), BYTE c->opt.tcor);
1092	outb (TBPR(c->port), period);
1093}
1094
1095/*
1096 * Initialize the CD2400 channel.
1097 */
1098void cx_setup_chan (cx_chan_t *c)
1099{
1100	/* set current channel number */
1101	outb (CAR(c->port), c->num & 3);
1102
1103	/* reset the channel */
1104	cx_cmd (c->port, CCR_CLRCH);
1105
1106	/* set LIVR to contain the board and channel numbers */
1107	outb (LIVR(c->port), c->board->num << 6 | c->num << 2);
1108
1109	/* clear DTR, RTS, set TXCout/DTR pin */
1110	outb (MSVR_RTS(c->port), 0);
1111	outb (MSVR_DTR(c->port), c->mode==M_ASYNC ? 0 : MSV_TXCOUT);
1112
1113	/* set receiver A buffer physical address */
1114	outw (ARBADRU(c->port), (unsigned short) (c->arphys>>16));
1115	outw (ARBADRL(c->port), (unsigned short) c->arphys);
1116
1117	/* set receiver B buffer physical address */
1118	outw (BRBADRU(c->port), (unsigned short) (c->brphys>>16));
1119	outw (BRBADRL(c->port), (unsigned short) c->brphys);
1120
1121	/* set transmitter A buffer physical address */
1122	outw (ATBADRU(c->port), (unsigned short) (c->atphys>>16));
1123	outw (ATBADRL(c->port), (unsigned short) c->atphys);
1124
1125	/* set transmitter B buffer physical address */
1126	outw (BTBADRU(c->port), (unsigned short) (c->btphys>>16));
1127	outw (BTBADRL(c->port), (unsigned short) c->btphys);
1128
1129	c->dtr = 0;
1130	c->rts = 0;
1131
1132	cx_update_chan (c);
1133}
1134
1135/*
1136 * Control DTR signal for the channel.
1137 * Turn it on/off.
1138 */
1139void cx_set_dtr (cx_chan_t *c, int on)
1140{
1141	cx_board_t *b = c->board;
1142
1143	c->dtr = on ? 1 : 0;
1144
1145	if (b->type == B_SIGMA_2X) {
1146		if (on) b->bcr1 |= BCR1_DTR(c->num);
1147		else    b->bcr1 &= ~BCR1_DTR(c->num);
1148		outw (BCR1(b->port), b->bcr1);
1149		return;
1150	}
1151	if (b->type == B_SIGMA_800) {
1152		if (c->num >= 8) {
1153			if (on) b->bcr1b |= BCR1800_DTR(c->num);
1154			else    b->bcr1b &= ~BCR1800_DTR(c->num);
1155			outb (BCR1(b->port+0x10), b->bcr1b);
1156		} else {
1157			if (on) b->bcr1 |= BCR1800_DTR(c->num);
1158			else    b->bcr1 &= ~BCR1800_DTR(c->num);
1159			outb (BCR1(b->port), b->bcr1);
1160		}
1161		return;
1162	}
1163	if (c->mode == M_ASYNC) {
1164		outb (CAR(c->port), c->num & 3);
1165		outb (MSVR_DTR(c->port), on ? MSV_DTR : 0);
1166		return;
1167	}
1168
1169	switch (c->num) {
1170	default:
1171		/* Channels 4..7 and 12..15 in synchronous mode
1172		 * have no DTR signal. */
1173		break;
1174
1175	case 1: case 2:  case 3:
1176		if (c->type == T_UNIV_RS232)
1177			break;
1178	case 0:
1179		if (on) b->bcr1 |= BCR1_DTR(c->num);
1180		else    b->bcr1 &= ~BCR1_DTR(c->num);
1181		outw (BCR1(b->port), b->bcr1);
1182		break;
1183
1184	case 9: case 10: case 11:
1185		if (c->type == T_UNIV_RS232)
1186			break;
1187	case 8:
1188		if (on) b->bcr1b |= BCR1_DTR(c->num & 3);
1189		else    b->bcr1b &= ~BCR1_DTR(c->num & 3);
1190		outw (BCR1(b->port+0x10), b->bcr1b);
1191		break;
1192	}
1193}
1194
1195/*
1196 * Control RTS signal for the channel.
1197 * Turn it on/off.
1198 */
1199void cx_set_rts (cx_chan_t *c, int on)
1200{
1201	c->rts = on ? 1 : 0;
1202	outb (CAR(c->port), c->num & 3);
1203	outb (MSVR_RTS(c->port), on ? MSV_RTS : 0);
1204}
1205
1206/*
1207 * Get the state of DSR signal of the channel.
1208 */
1209int cx_get_dsr (cx_chan_t *c)
1210{
1211	unsigned char sigval;
1212
1213	if (c->board->type == B_SIGMA_2X ||
1214	    c->board->type == B_SIGMA_800 ||
1215	    c->mode == M_ASYNC) {
1216		outb (CAR(c->port), c->num & 3);
1217		return (inb (MSVR(c->port)) & MSV_DSR ? 1 : 0);
1218	}
1219
1220	/*
1221	 * Channels 4..7 and 12..15 don't have DSR signal available.
1222	 */
1223	switch (c->num) {
1224	default:
1225		return (1);
1226
1227	case 1: case 2:  case 3:
1228		if (c->type == T_UNIV_RS232)
1229			return (1);
1230	case 0:
1231		sigval = inw (BSR(c->board->port)) >> 8;
1232		break;
1233
1234	case 9: case 10: case 11:
1235		if (c->type == T_UNIV_RS232)
1236			return (1);
1237	case 8:
1238		sigval = inw (BSR(c->board->port+0x10)) >> 8;
1239		break;
1240	}
1241	return (~sigval >> (c->num & 3) & 1);
1242}
1243
1244/*
1245 * Get the state of CARRIER signal of the channel.
1246 */
1247int cx_get_cd (cx_chan_t *c)
1248{
1249	unsigned char sigval;
1250
1251	if (c->board->type == B_SIGMA_2X ||
1252	    c->board->type == B_SIGMA_800 ||
1253	    c->mode == M_ASYNC) {
1254		outb (CAR(c->port), c->num & 3);
1255		return (inb (MSVR(c->port)) & MSV_CD ? 1 : 0);
1256	}
1257
1258	/*
1259	 * Channels 4..7 and 12..15 don't have CD signal available.
1260	 */
1261	switch (c->num) {
1262	default:
1263		return (1);
1264
1265	case 1: case 2:  case 3:
1266		if (c->type == T_UNIV_RS232)
1267			return (1);
1268	case 0:
1269		sigval = inw (BSR(c->board->port)) >> 8;
1270		break;
1271
1272	case 9: case 10: case 11:
1273		if (c->type == T_UNIV_RS232)
1274			return (1);
1275	case 8:
1276		sigval = inw (BSR(c->board->port+0x10)) >> 8;
1277		break;
1278	}
1279	return (~sigval >> 4 >> (c->num & 3) & 1);
1280}
1281
1282/*
1283 * Get the state of CTS signal of the channel.
1284 */
1285int cx_get_cts (cx_chan_t *c)
1286{
1287	outb (CAR(c->port), c->num & 3);
1288	return (inb (MSVR(c->port)) & MSV_CTS ? 1 : 0);
1289}
1290
1291/*
1292 * Compute CD2400 clock values.
1293 */
1294void cx_clock (long hz, long ba, int *clk, int *div)
1295{
1296	static short clocktab[] = { 8, 32, 128, 512, 2048, 0 };
1297
1298	for (*clk=0; clocktab[*clk]; ++*clk) {
1299		long c = ba * clocktab[*clk];
1300		if (hz <= c*256) {
1301			*div = (2 * hz + c) / (2 * c) - 1;
1302			return;
1303		}
1304	}
1305	/* Incorrect baud rate.  Return some meaningful values. */
1306	*clk = 0;
1307	*div = 255;
1308}
1309
1310/*
1311 * Turn LED on/off.
1312 */
1313void cx_led (cx_board_t *b, int on)
1314{
1315	switch (b->type) {
1316	case B_SIGMA_2X:
1317		if (on) b->bcr0 |= BCR02X_LED;
1318		else    b->bcr0 &= ~BCR02X_LED;
1319		outb (BCR0(b->port), b->bcr0);
1320		break;
1321	}
1322}
1323
1324void cx_disable_dma (cx_board_t *b)
1325{
1326#ifndef NDIS_MINIPORT_DRIVER
1327	/* Disable DMA channel. */
1328	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
1329#endif
1330}
1331
1332cx_board_opt_t board_opt_dflt = { /* board options */
1333	BUS_NORMAL,		/* normal bus master timing */
1334};
1335
1336cx_chan_opt_t chan_opt_dflt = { /* mode-independent options */
1337	{			/* cor4 */
1338		7,		/* FIFO threshold, odd is better */
1339		0,
1340		0,              /* don't detect 1 to 0 on CTS */
1341		1,		/* detect 1 to 0 on CD */
1342		0,              /* detect 1 to 0 on DSR */
1343	},
1344	{			/* cor5 */
1345		0,		/* receive flow control FIFO threshold */
1346		0,
1347		0,              /* don't detect 0 to 1 on CTS */
1348		1,		/* detect 0 to 1 on CD */
1349		0,              /* detect 0 to 1 on DSR */
1350	},
1351	{			/* rcor */
1352		0,		/* dummy clock source */
1353		ENCOD_NRZ,      /* NRZ mode */
1354		0,              /* disable DPLL */
1355		0,
1356		0,		/* transmit line value */
1357	},
1358	{			/* tcor */
1359		0,
1360		0,		/* local loopback mode */
1361		0,
1362		1,		/* external 1x clock mode */
1363		0,
1364		0,		/* dummy transmit clock source */
1365	},
1366};
1367
1368cx_opt_async_t opt_async_dflt = { /* default async options */
1369	{			/* cor1 */
1370		8-1,		/* 8-bit char length */
1371		0,		/* don't ignore parity */
1372		PARM_NOPAR,	/* no parity */
1373		PAR_EVEN,	/* even parity */
1374	},
1375	{			/* cor2 */
1376		0,              /* disable automatic DSR */
1377		1,              /* enable automatic CTS */
1378		0,              /* disable automatic RTS */
1379		0,		/* no remote loopback */
1380		0,
1381		0,              /* disable embedded cmds */
1382		0,		/* disable XON/XOFF */
1383		0,		/* disable XANY */
1384	},
1385	{			/* cor3 */
1386		STOPB_1,	/* 1 stop bit */
1387		0,
1388		0,		/* disable special char detection */
1389		FLOWCC_PASS,	/* pass flow ctl chars to the host */
1390		0,		/* range detect disable */
1391		0,		/* disable extended spec. char detect */
1392	},
1393	{			/* cor6 */
1394		PERR_INTR,	/* generate exception on parity errors */
1395		BRK_INTR,	/* generate exception on break condition */
1396		0,		/* don't translate NL to CR on input */
1397		0,		/* don't translate CR to NL on input */
1398		0,		/* don't discard CR on input */
1399	},
1400	{			/* cor7 */
1401		0,		/* don't translate CR to NL on output */
1402		0,		/* don't translate NL to CR on output */
1403		0,
1404		0,		/* don't process flow ctl err chars */
1405		0,		/* disable LNext option */
1406		0,		/* don't strip 8 bit on input */
1407	},
1408	0, 0, 0, 0, 0, 0, 0,	/* clear schr1-4, scrl, scrh, lnxt */
1409};
1410
1411cx_opt_hdlc_t opt_hdlc_dflt = { /* default hdlc options */
1412	{			/* cor1 */
1413		2,              /* 2 inter-frame flags */
1414		0,		/* no-address mode */
1415		CLRDET_DISABLE,	/* disable clear detect */
1416		AFLO_1OCT,	/* 1-byte address field length */
1417	},
1418	{			/* cor2 */
1419		0,		/* disable automatic DSR */
1420		0,              /* disable automatic CTS */
1421		0,              /* disable automatic RTS */
1422		0,
1423		CRC_INVERT,	/* use CRC V.41 */
1424		0,
1425		FCS_NOTPASS,	/* don't pass received CRC to the host */
1426		0,
1427	},
1428	{			/* cor3 */
1429		0,              /* 0 pad characters sent */
1430		IDLE_FLAG,	/* idle in flag */
1431		0,		/* enable FCS */
1432		FCSP_ONES,	/* FCS preset to all ones (V.41) */
1433		SYNC_AA,	/* use AAh as sync char */
1434		0,              /* disable pad characters */
1435	},
1436	0, 0, 0, 0,		/* clear rfar1-4 */
1437	POLY_V41,		/* use V.41 CRC polynomial */
1438};
1439