1 /* $Id: hscx.c,v 1.21.6.3 2001/09/23 22:24:48 kai Exp $
3 * HSCX specific routines
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/init.h>
18 #include <linux/interrupt.h>
20 static char *HSCXVer
[] __initdata
=
21 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
22 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
25 hscx_read(struct BCState
*bcs
, u8 addr
)
27 struct IsdnCardState
*cs
= bcs
->cs
;
29 return cs
->bc_hw_ops
->read_reg(cs
, bcs
->unit
, addr
);
33 hscx_write(struct BCState
*bcs
, u8 addr
, u8 val
)
35 struct IsdnCardState
*cs
= bcs
->cs
;
37 cs
->bc_hw_ops
->write_reg(cs
, bcs
->unit
, addr
, val
);
41 hscx_write_fifo(struct BCState
*bcs
, u8
*p
, int len
)
43 struct IsdnCardState
*cs
= bcs
->cs
;
45 cs
->bc_hw_ops
->write_fifo(cs
, bcs
->unit
, p
, len
);
49 HscxVersion(struct IsdnCardState
*cs
, char *s
)
53 verA
= cs
->bc_hw_ops
->read_reg(cs
, 0, HSCX_VSTR
) & 0xf;
54 verB
= cs
->bc_hw_ops
->read_reg(cs
, 1, HSCX_VSTR
) & 0xf;
55 printk(KERN_INFO
"%s HSCX version A: %s B: %s\n", s
,
56 HSCXVer
[verA
], HSCXVer
[verB
]);
57 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf))
64 modehscx(struct BCState
*bcs
, int mode
, int bc
)
66 struct IsdnCardState
*cs
= bcs
->cs
;
69 if (cs
->debug
& L1_DEB_HSCX
)
70 debugl1(cs
, "hscx %c mode %d ichan %d",
71 'A' + hscx
, mode
, bc
);
74 hscx_write(bcs
, HSCX_XAD1
, 0xFF);
75 hscx_write(bcs
, HSCX_XAD2
, 0xFF);
76 hscx_write(bcs
, HSCX_RAH2
, 0xFF);
77 hscx_write(bcs
, HSCX_XBCH
, 0x0);
78 hscx_write(bcs
, HSCX_RLCR
, 0x0);
79 hscx_write(bcs
, HSCX_CCR1
,
80 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x82 : 0x85);
81 hscx_write(bcs
, HSCX_CCR2
, 0x30);
82 hscx_write(bcs
, HSCX_XCCR
, 7);
83 hscx_write(bcs
, HSCX_RCCR
, 7);
85 /* Switch IOM 1 SSI */
86 if (test_bit(HW_IOM1
, &cs
->HW_Flags
) && (hscx
== 0))
90 hscx_write(bcs
, HSCX_TSAX
,
91 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
92 hscx_write(bcs
, HSCX_TSAR
,
93 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
95 hscx_write(bcs
, HSCX_TSAX
, bcs
->hw
.hscx
.tsaxr1
);
96 hscx_write(bcs
, HSCX_TSAR
, bcs
->hw
.hscx
.tsaxr1
);
100 hscx_write(bcs
, HSCX_TSAX
, 0x1f);
101 hscx_write(bcs
, HSCX_TSAR
, 0x1f);
102 hscx_write(bcs
, HSCX_MODE
, 0x84);
105 hscx_write(bcs
, HSCX_MODE
, 0xe4);
108 hscx_write(bcs
, HSCX_CCR1
,
109 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x8a : 0x8d);
110 hscx_write(bcs
, HSCX_MODE
, 0x8c);
114 hscx_write(bcs
, HSCX_CMDR
, 0x41);
116 hscx_write(bcs
, HSCX_ISTA
, 0x00);
120 hscx_l2l1(struct PStack
*st
, int pr
, void *arg
)
122 struct sk_buff
*skb
= arg
;
125 case (PH_DATA
| REQUEST
):
126 xmit_data_req_b(st
->l1
.bcs
, skb
);
128 case (PH_PULL
| INDICATION
):
129 xmit_pull_ind_b(st
->l1
.bcs
, skb
);
131 case (PH_PULL
| REQUEST
):
134 case (PH_ACTIVATE
| REQUEST
):
135 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
136 modehscx(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
137 l1_msg_b(st
, pr
, arg
);
139 case (PH_DEACTIVATE
| REQUEST
):
140 l1_msg_b(st
, pr
, arg
);
142 case (PH_DEACTIVATE
| CONFIRM
):
143 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
144 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
145 modehscx(st
->l1
.bcs
, 0, st
->l1
.bc
);
146 L1L2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
152 close_hscxstate(struct BCState
*bcs
)
154 modehscx(bcs
, 0, bcs
->channel
);
159 open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
163 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
171 setstack_hscx(struct PStack
*st
, struct BCState
*bcs
)
173 bcs
->channel
= st
->l1
.bc
;
174 if (open_hscxstate(st
->l1
.hardware
, bcs
))
177 st
->l1
.l2l1
= hscx_l2l1
;
178 setstack_manager(st
);
184 static void hscx_fill_fifo(struct BCState
*bcs
);
186 static struct bc_l1_ops hscx_l1_ops
= {
187 .fill_fifo
= hscx_fill_fifo
,
188 .open
= setstack_hscx
,
189 .close
= close_hscxstate
,
193 inithscx(struct IsdnCardState
*cs
)
197 cs
->bc_l1_ops
= &hscx_l1_ops
;
200 cs
->bcs
[0].hw
.hscx
.tsaxr0
= 0x2f;
201 cs
->bcs
[0].hw
.hscx
.tsaxr1
= 3;
202 cs
->bcs
[1].hw
.hscx
.tsaxr0
= 0x2f;
203 cs
->bcs
[1].hw
.hscx
.tsaxr1
= 3;
205 val
= hscx_read(&cs
->bcs
[1], HSCX_ISTA
);
206 debugl1(cs
, "HSCX B ISTA %x", val
);
208 eval
= hscx_read(&cs
->bcs
[1], HSCX_EXIR
);
209 debugl1(cs
, "HSCX B EXIR %x", eval
);
212 eval
= hscx_read(&cs
->bcs
[0], HSCX_EXIR
);
213 debugl1(cs
, "HSCX A EXIR %x", eval
);
215 val
= hscx_read(&cs
->bcs
[0], HSCX_ISTA
);
216 debugl1(cs
, "HSCX A ISTA %x", val
);
217 val
= hscx_read(&cs
->bcs
[1], HSCX_STAR
);
218 debugl1(cs
, "HSCX B STAR %x", val
);
219 val
= hscx_read(&cs
->bcs
[0], HSCX_STAR
);
220 debugl1(cs
, "HSCX A STAR %x", val
);
221 /* disable all IRQ */
222 hscx_write(&cs
->bcs
[0], HSCX_MASK
, 0xFF);
223 hscx_write(&cs
->bcs
[1], HSCX_MASK
, 0xFF);
225 modehscx(&cs
->bcs
[0], 0, 0);
226 modehscx(&cs
->bcs
[1], 0, 0);
228 /* Reenable all IRQ */
229 hscx_write(&cs
->bcs
[0], HSCX_MASK
, 0x0);
230 hscx_write(&cs
->bcs
[1], HSCX_MASK
, 0x0);
234 inithscxisac(struct IsdnCardState
*cs
)
241 hscxisac_setup(struct IsdnCardState
*cs
, struct dc_hw_ops
*isac_ops
,
242 struct bc_hw_ops
*hscx_ops
)
244 isac_setup(cs
, isac_ops
);
245 cs
->bc_hw_ops
= hscx_ops
;
246 if (HscxVersion(cs
, "HiSax:")) {
247 printk(KERN_WARNING
"HiSax: invalid HSCX version\n");
253 #include "hscx_irq.c"