1 /* $Id: t1isa.c,v 1.1.1.1 2005/04/11 02:50:23 jack Exp $
3 * Module for AVM T1 HEMA-card.
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/skbuff.h>
15 #include <linux/delay.h>
17 #include <linux/interrupt.h>
18 #include <linux/ioport.h>
19 #include <linux/capi.h>
20 #include <linux/kernelcapi.h>
21 #include <linux/init.h>
28 static char *revision = "$Revision: 1.1.1.1 $";
30 /* ------------------------------------------------------------- */
32 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
33 MODULE_AUTHOR("Carsten Paeth");
34 MODULE_LICENSE("GPL");
36 /* ------------------------------------------------------------- */
38 static struct capi_driver_interface *di;
40 /* ------------------------------------------------------------- */
42 static int hema_irq_table[16] =
61 static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
63 unsigned char cregs[8];
64 unsigned char reverse_cardnr;
69 reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)
70 | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
71 cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);
72 cregs[1] = 0x00; /* fast & slow link connected to CON1 */
73 cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
75 cregs[4] = 0x11; /* zero wait state */
76 cregs[5] = hema_irq_table[irq & 0xf];
83 t1outp(base, T1_RESETBOARD, 0xf);
85 dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */
88 dummy = (base >> 4) & 0xff;
89 for (i=1;i<=0xf;i++) t1outp(base, i, dummy);
90 t1outp(base, HEMA_PAL_ID & 0xf, dummy);
91 t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);
92 for(i=1;i<7;i++) t1outp(base, 0, cregs[i]);
93 t1outp(base, ((base >> 4)) & 0x3, cregs[7]);
97 t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
98 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
100 t1outp(base, T1_FASTLINK+T1_RESETLINK, 1);
101 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1);
103 t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
104 t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
106 t1outp(base, T1_FASTLINK+T1_ANALYSE, 0);
108 t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0);
110 if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */
112 if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */
114 if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0)
116 if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70)
118 if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0)
120 if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1)
122 if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */
124 if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0)
126 if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0)
131 static void t1_handle_interrupt(avmcard * card)
133 avmctrl_info *cinfo = &card->ctrlinfo[0];
134 struct capi_ctr *ctrl = cinfo->capi_ctrl;
144 while (b1_rx_full(card->port)) {
146 b1cmd = b1_get_byte(card->port);
150 case RECEIVE_DATA_B3_IND:
152 ApplId = (unsigned) b1_get_word(card->port);
153 MsgLen = t1_get_slice(card->port, card->msgbuf);
154 DataB3Len = t1_get_slice(card->port, card->databuf);
156 if (MsgLen < 30) { /* not CAPI 64Bit */
157 memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
159 CAPIMSG_SETLEN(card->msgbuf, 30);
161 if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
162 printk(KERN_ERR "%s: incoming packet dropped\n",
165 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
166 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
167 ctrl->handle_capimsg(ctrl, ApplId, skb);
171 case RECEIVE_MESSAGE:
173 ApplId = (unsigned) b1_get_word(card->port);
174 MsgLen = t1_get_slice(card->port, card->msgbuf);
175 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
176 printk(KERN_ERR "%s: incoming packet dropped\n",
179 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
180 ctrl->handle_capimsg(ctrl, ApplId, skb);
184 case RECEIVE_NEW_NCCI:
186 ApplId = b1_get_word(card->port);
187 NCCI = b1_get_word(card->port);
188 WindowSize = b1_get_word(card->port);
190 ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);
194 case RECEIVE_FREE_NCCI:
196 ApplId = b1_get_word(card->port);
197 NCCI = b1_get_word(card->port);
199 if (NCCI != 0xffffffff)
200 ctrl->free_ncci(ctrl, ApplId, NCCI);
201 else ctrl->appl_released(ctrl, ApplId);
205 b1_put_byte(card->port, SEND_POLLACK);
206 ctrl->resume_output(ctrl);
210 ctrl->suspend_output(ctrl);
215 cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf);
216 b1_parse_version(cinfo);
217 printk(KERN_INFO "%s: %s-card (%s) now active\n",
219 cinfo->version[VER_CARDTYPE],
220 cinfo->version[VER_DRIVER]);
224 case RECEIVE_TASK_READY:
225 ApplId = (unsigned) b1_get_word(card->port);
226 MsgLen = t1_get_slice(card->port, card->msgbuf);
227 card->msgbuf[MsgLen] = 0;
229 && ( card->msgbuf[MsgLen-1] == '\n'
230 || card->msgbuf[MsgLen-1] == '\r')) {
231 card->msgbuf[MsgLen-1] = 0;
234 printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
235 card->name, ApplId, card->msgbuf);
238 case RECEIVE_DEBUGMSG:
239 MsgLen = t1_get_slice(card->port, card->msgbuf);
240 card->msgbuf[MsgLen] = 0;
242 && ( card->msgbuf[MsgLen-1] == '\n'
243 || card->msgbuf[MsgLen-1] == '\r')) {
244 card->msgbuf[MsgLen-1] = 0;
247 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
252 printk(KERN_ERR "%s: card reseted ?\n", card->name);
255 printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
262 /* ------------------------------------------------------------- */
264 static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
268 card = (avmcard *) devptr;
271 printk(KERN_WARNING "t1isa: interrupt: wrong device\n");
274 if (card->interrupt) {
275 printk(KERN_ERR "%s: reentering interrupt hander.\n",
282 t1_handle_interrupt(card);
286 /* ------------------------------------------------------------- */
288 static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
290 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
291 avmcard *card = cinfo->card;
292 unsigned int port = card->port;
296 t1_disable_irq(port);
299 if ((retval = b1_load_t4file(card, &data->firmware))) {
301 printk(KERN_ERR "%s: failed to load t4file!!\n",
306 if (data->configuration.len > 0 && data->configuration.data) {
307 if ((retval = b1_load_config(card, &data->configuration))) {
309 printk(KERN_ERR "%s: failed to load config!!\n",
315 if (!b1_loaded(card)) {
316 printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
322 b1_setinterrupt(port, card->irq, card->cardtype);
323 b1_put_byte(port, SEND_INIT);
324 b1_put_word(port, CAPI_MAXAPPL);
325 b1_put_word(port, AVM_NCCI_PER_CHANNEL*30);
326 b1_put_word(port, ctrl->cnr - 1);
327 restore_flags(flags);
332 void t1isa_reset_ctr(struct capi_ctr *ctrl)
334 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
335 avmcard *card = cinfo->card;
336 unsigned int port = card->port;
338 t1_disable_irq(port);
342 memset(cinfo->version, 0, sizeof(cinfo->version));
346 static void t1isa_remove_ctr(struct capi_ctr *ctrl)
348 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
349 avmcard *card = cinfo->card;
350 unsigned int port = card->port;
352 t1_disable_irq(port);
357 di->detach_ctr(ctrl);
358 free_irq(card->irq, card);
359 release_region(card->port, AVMB1_PORTLEN);
360 kfree(card->ctrlinfo);
366 /* ------------------------------------------------------------- */
368 static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
370 struct capi_ctr *ctrl;
377 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
380 printk(KERN_WARNING "%s: no memory.\n", driver->name);
384 memset(card, 0, sizeof(avmcard));
385 cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
387 printk(KERN_WARNING "%s: no memory.\n", driver->name);
392 memset(cinfo, 0, sizeof(avmctrl_info));
393 card->ctrlinfo = cinfo;
395 sprintf(card->name, "t1isa-%x", p->port);
396 card->port = p->port;
398 card->cardtype = avm_t1isa;
399 card->cardnr = p->cardnr;
401 if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) {
402 printk(KERN_WARNING "%s: illegal port 0x%x.\n",
403 driver->name, card->port);
404 kfree(card->ctrlinfo);
410 if (check_region(card->port, AVMB1_PORTLEN)) {
412 "%s: ports 0x%03x-0x%03x in use.\n",
413 driver->name, card->port, card->port + AVMB1_PORTLEN);
414 kfree(card->ctrlinfo);
419 if (hema_irq_table[card->irq & 0xf] == 0) {
420 printk(KERN_WARNING "%s: irq %d not valid.\n",
421 driver->name, card->irq);
422 kfree(card->ctrlinfo);
427 for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) {
428 avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card;
429 if (cardp->cardnr == card->cardnr) {
430 printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n",
431 driver->name, card->cardnr, cardp->port);
432 kfree(card->ctrlinfo);
438 if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
439 printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
440 driver->name, card->port, retval);
441 kfree(card->ctrlinfo);
446 t1_disable_irq(card->port);
447 b1_reset(card->port);
449 request_region(p->port, AVMB1_PORTLEN, card->name);
451 retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card);
453 printk(KERN_ERR "%s: unable to get IRQ %d.\n",
454 driver->name, card->irq);
455 release_region(card->port, AVMB1_PORTLEN);
456 kfree(card->ctrlinfo);
462 cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
463 if (!cinfo->capi_ctrl) {
464 printk(KERN_ERR "%s: attach controller failed.\n",
466 free_irq(card->irq, card);
467 release_region(card->port, AVMB1_PORTLEN);
468 kfree(card->ctrlinfo);
475 "%s: AVM T1 ISA at i/o %#x, irq %d, card %d\n",
476 driver->name, card->port, card->irq, card->cardnr);
481 static void t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
483 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
484 avmcard *card = cinfo->card;
485 unsigned int port = card->port;
487 __u16 len = CAPIMSG_LEN(skb->data);
488 __u8 cmd = CAPIMSG_COMMAND(skb->data);
489 __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
493 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
494 __u16 dlen = CAPIMSG_DATALEN(skb->data);
495 b1_put_byte(port, SEND_DATA_B3_REQ);
496 t1_put_slice(port, skb->data, len);
497 t1_put_slice(port, skb->data + len, dlen);
499 b1_put_byte(port, SEND_MESSAGE);
500 t1_put_slice(port, skb->data, len);
502 restore_flags(flags);
505 /* ------------------------------------------------------------- */
507 static char *t1isa_procinfo(struct capi_ctr *ctrl)
509 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
513 sprintf(cinfo->infobuf, "%s %s 0x%x %d %d",
514 cinfo->cardname[0] ? cinfo->cardname : "-",
515 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
516 cinfo->card ? cinfo->card->port : 0x0,
517 cinfo->card ? cinfo->card->irq : 0,
518 cinfo->card ? cinfo->card->cardnr : 0
520 return cinfo->infobuf;
524 /* ------------------------------------------------------------- */
526 static struct capi_driver t1isa_driver = {
529 load_firmware: t1isa_load_firmware,
530 reset_ctr: t1isa_reset_ctr,
531 remove_ctr: t1isa_remove_ctr,
532 register_appl: b1_register_appl,
533 release_appl: b1_release_appl,
534 send_message: t1isa_send_message,
536 procinfo: t1isa_procinfo,
537 ctr_read_proc: b1ctl_read_proc,
538 driver_read_proc: 0, /* use standard driver_read_proc */
540 add_card: t1isa_add_card,
543 static int __init t1isa_init(void)
545 struct capi_driver *driver = &t1isa_driver;
551 if ((p = strchr(revision, ':')) != 0 && p[1]) {
552 strncpy(driver->revision, p + 2, sizeof(driver->revision));
553 driver->revision[sizeof(driver->revision)-1] = 0;
554 if ((p = strchr(driver->revision, '$')) != 0 && p > driver->revision)
558 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
560 di = attach_capi_driver(driver);
563 printk(KERN_ERR "%s: failed to attach capi_driver\n",
572 static void __exit t1isa_exit(void)
574 detach_capi_driver(&t1isa_driver);
577 module_init(t1isa_init);
578 module_exit(t1isa_exit);