[PATCH] DVB: Update documentation and credits
[linux-2.6/history.git] / drivers / isdn / hisax / hscx.c
blob35dc68c1466eae9a6df0ebcbb6cfc502b6066956
1 /* $Id: hscx.c,v 1.21.6.3 2001/09/23 22:24:48 kai Exp $
3 * HSCX specific routines
5 * Author Karsten Keil
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
7 *
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>
14 #include "hisax.h"
15 #include "hscx.h"
16 #include "isac.h"
17 #include "isdnl1.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", "???"};
24 static inline u8
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);
32 static inline void
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);
40 static inline void
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);
48 static int
49 HscxVersion(struct IsdnCardState *cs, char *s)
51 int verA, verB;
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))
58 return 1;
59 else
60 return 0;
63 void
64 modehscx(struct BCState *bcs, int mode, int bc)
66 struct IsdnCardState *cs = bcs->cs;
67 int hscx = bcs->unit;
69 if (cs->debug & L1_DEB_HSCX)
70 debugl1(cs, "hscx %c mode %d ichan %d",
71 'A' + hscx, mode, bc);
72 bcs->mode = mode;
73 bcs->channel = 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))
87 bc = 1 - bc;
89 if (bc == 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);
94 } else {
95 hscx_write(bcs, HSCX_TSAX, bcs->hw.hscx.tsaxr1);
96 hscx_write(bcs, HSCX_TSAR, bcs->hw.hscx.tsaxr1);
98 switch (mode) {
99 case L1_MODE_NULL:
100 hscx_write(bcs, HSCX_TSAX, 0x1f);
101 hscx_write(bcs, HSCX_TSAR, 0x1f);
102 hscx_write(bcs, HSCX_MODE, 0x84);
103 break;
104 case L1_MODE_TRANS:
105 hscx_write(bcs, HSCX_MODE, 0xe4);
106 break;
107 case L1_MODE_HDLC:
108 hscx_write(bcs, HSCX_CCR1,
109 test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d);
110 hscx_write(bcs, HSCX_MODE, 0x8c);
111 break;
113 if (mode)
114 hscx_write(bcs, HSCX_CMDR, 0x41);
116 hscx_write(bcs, HSCX_ISTA, 0x00);
119 void
120 hscx_l2l1(struct PStack *st, int pr, void *arg)
122 struct sk_buff *skb = arg;
124 switch (pr) {
125 case (PH_DATA | REQUEST):
126 xmit_data_req_b(st->l1.bcs, skb);
127 break;
128 case (PH_PULL | INDICATION):
129 xmit_pull_ind_b(st->l1.bcs, skb);
130 break;
131 case (PH_PULL | REQUEST):
132 xmit_pull_req_b(st);
133 break;
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);
138 break;
139 case (PH_DEACTIVATE | REQUEST):
140 l1_msg_b(st, pr, arg);
141 break;
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);
147 break;
151 void
152 close_hscxstate(struct BCState *bcs)
154 modehscx(bcs, 0, bcs->channel);
155 bc_close(bcs);
159 open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
161 bc_open(bcs);
162 bcs->tx_skb = NULL;
163 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
164 bcs->event = 0;
165 bcs->rcvidx = 0;
166 bcs->tx_cnt = 0;
167 return (0);
171 setstack_hscx(struct PStack *st, struct BCState *bcs)
173 bcs->channel = st->l1.bc;
174 if (open_hscxstate(st->l1.hardware, bcs))
175 return (-1);
176 st->l1.bcs = bcs;
177 st->l1.l2l1 = hscx_l2l1;
178 setstack_manager(st);
179 bcs->st = st;
180 setstack_l1_B(st);
181 return (0);
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,
192 void __init
193 inithscx(struct IsdnCardState *cs)
195 int val, eval;
197 cs->bc_l1_ops = &hscx_l1_ops;
198 cs->bcs[0].unit = 0;
199 cs->bcs[1].unit = 1;
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);
207 if (val & 0x01) {
208 eval = hscx_read(&cs->bcs[1], HSCX_EXIR);
209 debugl1(cs, "HSCX B EXIR %x", eval);
211 if (val & 0x02) {
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);
233 void
234 inithscxisac(struct IsdnCardState *cs)
236 initisac(cs);
237 inithscx(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");
248 return -ENODEV;
250 return 0;
253 #include "hscx_irq.c"