import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / isdn / hisax / jade.c
1 /* $Id: jade.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
2  *
3  * JADE stuff (derived from original hscx.c)
4  *
5  * Author       Roland Klabunde
6  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.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.
10  *
11  */
12
13
14 #define __NO_VERSION__
15 #include <linux/init.h>
16 #include "hisax.h"
17 #include "hscx.h"
18 #include "jade.h"
19 #include "isdnl1.h"
20 #include <linux/interrupt.h>
21
22
23 int __init
24 JadeVersion(struct IsdnCardState *cs, char *s)
25 {
26     int ver,i;
27     int to = 50;
28     cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
29     i=0;
30     while (to) {
31         udelay(1);
32         ver = cs->BC_Read_Reg(cs, -1, 0x60);
33         to--;
34         if (ver)
35             break;
36         if (!to) {
37             printk(KERN_INFO "%s JADE version not obtainable\n", s);
38             return (0);
39         }
40     }
41     /* Wait for the JADE */
42     udelay(10);
43     /* Read version */
44     ver = cs->BC_Read_Reg(cs, -1, 0x60);
45     printk(KERN_INFO "%s JADE version: %d\n", s, ver);
46     return (1);
47 }
48
49 /* Write to indirect accessible jade register set */
50 static void
51 jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
52 {
53     int to = 50;
54     long flags;
55     u_char ret;
56     save_flags(flags);
57     cli();
58     /* Write the data */
59     cs->BC_Write_Reg(cs, -1, COMM_JADE+1, value);
60     /* Say JADE we wanna write indirect reg 'reg' */
61     cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
62     to = 50;
63     /* Wait for RDY goes high */
64     while (to) {
65         udelay(1);
66         ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
67         to--;
68         if (ret & 1)
69             /* Got acknowledge */
70             break;
71         if (!to) {
72             restore_flags(flags);
73             printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
74             return;
75         }
76     }
77     restore_flags(flags);
78 }
79
80
81
82 void
83 modejade(struct BCState *bcs, int mode, int bc)
84 {
85     struct IsdnCardState *cs = bcs->cs;
86     int jade = bcs->hw.hscx.hscx;
87
88     if (cs->debug & L1_DEB_HSCX) {
89         char tmp[40];
90         sprintf(tmp, "jade %c mode %d ichan %d",
91                 'A' + jade, mode, bc);
92         debugl1(cs, tmp);
93     }
94     bcs->mode = mode;
95     bcs->channel = bc;
96         
97     cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO:0x00));
98     cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU|jadeCCR0_ITF));
99     cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
100
101     jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
102     jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
103     jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
104     jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
105
106     cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
107     cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
108
109     if (bc == 0) {
110         cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
111         cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
112     } else {
113         cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
114         cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
115     }
116     switch (mode) {
117         case (L1_MODE_NULL):
118                 cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
119                 break;
120         case (L1_MODE_TRANS):
121                 cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO|jadeMODE_RAC|jadeMODE_XAC));
122                 break;
123         case (L1_MODE_HDLC):
124                 cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC|jadeMODE_XAC));
125                 break;
126     }
127     if (mode) {
128         cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES|jadeRCMD_RMC));
129         cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
130         /* Unmask ints */
131         cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
132     }
133     else
134         /* Mask ints */
135         cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
136 }
137
138 void
139 jade_sched_event(struct BCState *bcs, int event)
140 {
141     bcs->event |= 1 << event;
142     queue_task(&bcs->tqueue, &tq_immediate);
143     mark_bh(IMMEDIATE_BH);
144 }
145
146 static void
147 jade_l2l1(struct PStack *st, int pr, void *arg)
148 {
149     struct sk_buff *skb = arg;
150     long flags;
151
152     switch (pr) {
153         case (PH_DATA | REQUEST):
154                 save_flags(flags);
155                 cli();
156                 if (st->l1.bcs->tx_skb) {
157                         skb_queue_tail(&st->l1.bcs->squeue, skb);
158                         restore_flags(flags);
159                 } else {
160                         st->l1.bcs->tx_skb = skb;
161                         test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
162                         st->l1.bcs->hw.hscx.count = 0;
163                         restore_flags(flags);
164                         st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
165                 }
166                 break;
167         case (PH_PULL | INDICATION):
168                 if (st->l1.bcs->tx_skb) {
169                         printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n");
170                         break;
171                 }
172                 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
173                 st->l1.bcs->tx_skb = skb;
174                 st->l1.bcs->hw.hscx.count = 0;
175                 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
176                 break;
177         case (PH_PULL | REQUEST):
178                 if (!st->l1.bcs->tx_skb) {
179                     test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
180                     st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
181                 } else
182                     test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
183                 break;
184         case (PH_ACTIVATE | REQUEST):
185                 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
186                 modejade(st->l1.bcs, st->l1.mode, st->l1.bc);
187                 l1_msg_b(st, pr, arg);
188                 break;
189         case (PH_DEACTIVATE | REQUEST):
190                 l1_msg_b(st, pr, arg);
191                 break;
192         case (PH_DEACTIVATE | CONFIRM):
193                 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
194                 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
195                 modejade(st->l1.bcs, 0, st->l1.bc);
196                 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
197                 break;
198     }
199 }
200
201 void
202 close_jadestate(struct BCState *bcs)
203 {
204     modejade(bcs, 0, bcs->channel);
205     if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
206         if (bcs->hw.hscx.rcvbuf) {
207                 kfree(bcs->hw.hscx.rcvbuf);
208                 bcs->hw.hscx.rcvbuf = NULL;
209         }
210         if (bcs->blog) {
211                 kfree(bcs->blog);
212                 bcs->blog = NULL;
213         }
214         skb_queue_purge(&bcs->rqueue);
215         skb_queue_purge(&bcs->squeue);
216         if (bcs->tx_skb) {
217                 dev_kfree_skb_any(bcs->tx_skb);
218                 bcs->tx_skb = NULL;
219                 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
220         }
221     }
222 }
223
224 static int
225 open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
226 {
227         if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
228                 if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
229                         printk(KERN_WARNING
230                                "HiSax: No memory for hscx.rcvbuf\n");
231                         test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
232                         return (1);
233                 }
234                 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
235                         printk(KERN_WARNING
236                                 "HiSax: No memory for bcs->blog\n");
237                         test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
238                         kfree(bcs->hw.hscx.rcvbuf);
239                         bcs->hw.hscx.rcvbuf = NULL;
240                         return (2);
241                 }
242                 skb_queue_head_init(&bcs->rqueue);
243                 skb_queue_head_init(&bcs->squeue);
244         }
245         bcs->tx_skb = NULL;
246         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
247         bcs->event = 0;
248         bcs->hw.hscx.rcvidx = 0;
249         bcs->tx_cnt = 0;
250         return (0);
251 }
252
253
254 int
255 setstack_jade(struct PStack *st, struct BCState *bcs)
256 {
257         bcs->channel = st->l1.bc;
258         if (open_jadestate(st->l1.hardware, bcs))
259                 return (-1);
260         st->l1.bcs = bcs;
261         st->l2.l2l1 = jade_l2l1;
262         setstack_manager(st);
263         bcs->st = st;
264         setstack_l1_B(st);
265         return (0);
266 }
267
268 void __init
269 clear_pending_jade_ints(struct IsdnCardState *cs)
270 {
271         int val;
272         char tmp[64];
273
274         cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
275         cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
276
277         val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR);
278         sprintf(tmp, "jade B ISTA %x", val);
279         debugl1(cs, tmp);
280         val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR);
281         sprintf(tmp, "jade A ISTA %x", val);
282         debugl1(cs, tmp);
283         val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR);
284         sprintf(tmp, "jade B STAR %x", val);
285         debugl1(cs, tmp);
286         val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR);
287         sprintf(tmp, "jade A STAR %x", val);
288         debugl1(cs, tmp);
289         /* Unmask ints */
290         cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8);
291         cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
292 }
293
294 void __init
295 initjade(struct IsdnCardState *cs)
296 {
297         cs->bcs[0].BC_SetStack = setstack_jade;
298         cs->bcs[1].BC_SetStack = setstack_jade;
299         cs->bcs[0].BC_Close = close_jadestate;
300         cs->bcs[1].BC_Close = close_jadestate;
301         cs->bcs[0].hw.hscx.hscx = 0;
302         cs->bcs[1].hw.hscx.hscx = 1;
303
304         /* Stop DSP audio tx/rx */
305         jade_write_indirect(cs, 0x11, 0x0f);
306         jade_write_indirect(cs, 0x17, 0x2f);
307
308         /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */
309         cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO);
310         cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO);
311         /* Power down, 1-Idle, RxTx least significant bit first */
312         cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00);
313         cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00);
314         /* Mask all interrupts */
315         cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR,  0x00);
316         cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
317         /* Setup host access to hdlc controller */
318         jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
319         /* Unmask HDLC int (donĀ“t forget DSP int later on)*/
320         cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
321
322         /* once again TRANSPARENT */    
323         modejade(cs->bcs, 0, 0);
324         modejade(cs->bcs + 1, 0, 0);
325 }
326