1 /* $Id: sedlbauer.c,v 1.25.6.6 2001/09/23 22:24:51 kai Exp $
3 * low level stuff for Sedlbauer cards
4 * includes support for the Sedlbauer speed star (speed star II),
5 * support for the Sedlbauer speed fax+,
6 * support for the Sedlbauer ISDN-Controller PC/104 and
7 * support for the Sedlbauer speed pci
8 * derived from the original file asuscom.c from Karsten Keil
10 * Author Marcus Niemann
11 * Copyright by Marcus Niemann <niemann@www-bib.fh-bielefeld.de>
13 * This software may be used and distributed according to the terms
14 * of the GNU General Public License, incorporated herein by reference.
16 * Thanks to Karsten Keil
17 * Sedlbauer AG for informations
23 * Card: Chip: Configuration: Comment:
24 * ---------------------------------------------------------------------
25 * Speed Card ISAC_HSCX DIP-SWITCH
26 * Speed Win ISAC_HSCX ISAPNP
27 * Speed Fax+ ISAC_ISAR ISAPNP Full analog support
28 * Speed Star ISAC_HSCX CARDMGR
29 * Speed Win2 IPAC ISAPNP
30 * ISDN PC/104 IPAC DIP-SWITCH
31 * Speed Star2 IPAC CARDMGR
32 * Speed PCI IPAC PCI PNP
33 * Speed Fax+ ISAC_ISAR PCI PNP Full analog support
36 * For the sedlbauer speed fax+ to work properly you have to download
37 * the firmware onto the card.
38 * For example: hisaxctrl <DriverID> 9 ISAR.BIN
41 #include <linux/init.h>
42 #include <linux/config.h>
49 #include <linux/pci.h>
50 #include <linux/isapnp.h>
52 extern const char *CardType
[];
53 static spinlock_t sedlbauer_lock
= SPIN_LOCK_UNLOCKED
;
55 const char *Sedlbauer_revision
= "$Revision: 1.25.6.6 $";
57 const char *Sedlbauer_Types
[] =
58 {"None", "speed card/win", "speed star", "speed fax+",
59 "speed win II / ISDN PC/104", "speed star II", "speed pci",
60 "speed fax+ pyramid", "speed fax+ pci"};
62 #define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
63 #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
64 #define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
65 #define PCI_SUB_ID_SEDLBAUER 0x01
67 #define SEDL_SPEED_CARD_WIN 1
68 #define SEDL_SPEED_STAR 2
69 #define SEDL_SPEED_FAX 3
70 #define SEDL_SPEED_WIN2_PC104 4
71 #define SEDL_SPEED_STAR2 5
72 #define SEDL_SPEED_PCI 6
73 #define SEDL_SPEEDFAX_PYRAMID 7
74 #define SEDL_SPEEDFAX_PCI 8
76 #define SEDL_CHIP_ISAC_HSCX 1
77 #define SEDL_CHIP_ISAC_ISAR 2
78 #define SEDL_CHIP_IPAC 3
80 #define SEDL_BUS_ISA 1
81 #define SEDL_BUS_PCI 2
82 #define SEDL_BUS_PCMCIA 3
84 #define byteout(addr,val) outb(val,addr)
85 #define bytein(addr) inb(addr)
87 #define SEDL_HSCX_ISA_RESET_ON 0
88 #define SEDL_HSCX_ISA_RESET_OFF 1
89 #define SEDL_HSCX_ISA_ISAC 2
90 #define SEDL_HSCX_ISA_HSCX 3
91 #define SEDL_HSCX_ISA_ADR 4
93 #define SEDL_HSCX_PCMCIA_RESET 0
94 #define SEDL_HSCX_PCMCIA_ISAC 1
95 #define SEDL_HSCX_PCMCIA_HSCX 2
96 #define SEDL_HSCX_PCMCIA_ADR 4
98 #define SEDL_ISAR_ISA_ISAC 4
99 #define SEDL_ISAR_ISA_ISAR 6
100 #define SEDL_ISAR_ISA_ADR 8
101 #define SEDL_ISAR_ISA_ISAR_RESET_ON 10
102 #define SEDL_ISAR_ISA_ISAR_RESET_OFF 12
104 #define SEDL_IPAC_ANY_ADR 0
105 #define SEDL_IPAC_ANY_IPAC 2
107 #define SEDL_IPAC_PCI_BASE 0
108 #define SEDL_IPAC_PCI_ADR 0xc0
109 #define SEDL_IPAC_PCI_IPAC 0xc8
110 #define SEDL_ISAR_PCI_ADR 0xc8
111 #define SEDL_ISAR_PCI_ISAC 0xd0
112 #define SEDL_ISAR_PCI_ISAR 0xe0
113 #define SEDL_ISAR_PCI_ISAR_RESET_ON 0x01
114 #define SEDL_ISAR_PCI_ISAR_RESET_OFF 0x18
115 #define SEDL_ISAR_PCI_LED1 0x08
116 #define SEDL_ISAR_PCI_LED2 0x10
118 #define SEDL_RESET 0x3 /* same as DOS driver */
121 readreg(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
)
126 spin_lock_irqsave(&sedlbauer_lock
, flags
);
127 byteout(cs
->hw
.sedl
.adr
, off
);
129 spin_unlock_irqrestore(&sedlbauer_lock
, flags
);
134 readfifo(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8
* data
, int size
)
138 spin_lock_irqsave(&sedlbauer_lock
, flags
);
139 byteout(cs
->hw
.sedl
.adr
, off
);
140 insb(adr
, data
, size
);
141 spin_unlock_irqrestore(&sedlbauer_lock
, flags
);
146 writereg(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8 data
)
148 byteout(cs
->hw
.sedl
.adr
, off
);
153 writefifo(struct IsdnCardState
*cs
, unsigned int adr
, u8 off
, u8
* data
, int size
)
155 byteout(cs
->hw
.sedl
.adr
, off
);
156 outsb(adr
, data
, size
);
160 isac_read(struct IsdnCardState
*cs
, u8 offset
)
162 return readreg(cs
, cs
->hw
.sedl
.isac
, offset
);
166 isac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
168 writereg(cs
, cs
->hw
.sedl
.isac
, offset
, value
);
172 isac_read_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
174 readfifo(cs
, cs
->hw
.sedl
.isac
, 0, data
, size
);
178 isac_write_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
180 writefifo(cs
, cs
->hw
.sedl
.isac
, 0, data
, size
);
183 static struct dc_hw_ops isac_ops
= {
184 .read_reg
= isac_read
,
185 .write_reg
= isac_write
,
186 .read_fifo
= isac_read_fifo
,
187 .write_fifo
= isac_write_fifo
,
191 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 offset
)
193 return readreg(cs
, cs
->hw
.sedl
.hscx
, offset
+ (hscx
? 0x40 : 0));
197 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 offset
, u8 value
)
199 writereg(cs
, cs
->hw
.sedl
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
203 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
205 readfifo(cs
, cs
->hw
.sedl
.hscx
, hscx
? 0x40 : 0, data
, size
);
209 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
211 writefifo(cs
, cs
->hw
.sedl
.hscx
, hscx
? 0x40 : 0, data
, size
);
214 static struct bc_hw_ops hscx_ops
= {
215 .read_reg
= hscx_read
,
216 .write_reg
= hscx_write
,
217 .read_fifo
= hscx_read_fifo
,
218 .write_fifo
= hscx_write_fifo
,
222 ipac_read(struct IsdnCardState
*cs
, u8 offset
)
224 return readreg(cs
, cs
->hw
.sedl
.isac
, offset
);
228 ipac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
230 writereg(cs
, cs
->hw
.sedl
.isac
, offset
, value
);
234 ipac_readfifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
236 readfifo(cs
, cs
->hw
.sedl
.isac
, offset
, data
, size
);
240 ipac_writefifo(struct IsdnCardState
*cs
, u8 offset
, u8
*data
, int size
)
242 writefifo(cs
, cs
->hw
.sedl
.isac
, offset
, data
, size
);
245 /* This will generate ipac_dc_ops and ipac_bc_ops using the functions
248 BUILD_IPAC_OPS(ipac
);
251 /* ISAR access routines
252 * mode = 0 access with IRQ on
253 * mode = 1 access with IRQ off
254 * mode = 2 access with IRQ off and using last offset
258 isar_read(struct IsdnCardState
*cs
, int mode
, u8 offset
)
261 return readreg(cs
, cs
->hw
.sedl
.hscx
, offset
);
264 byteout(cs
->hw
.sedl
.adr
, offset
);
266 return bytein(cs
->hw
.sedl
.hscx
);
270 isar_write(struct IsdnCardState
*cs
, int mode
, u8 offset
, u8 value
)
273 return writereg(cs
, cs
->hw
.sedl
.hscx
, offset
, value
);
276 byteout(cs
->hw
.sedl
.adr
, offset
);
278 byteout(cs
->hw
.sedl
.hscx
, value
);
281 static struct bc_hw_ops isar_ops
= {
282 .read_reg
= isar_read
,
283 .write_reg
= isar_write
,
287 sedlbauer_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
289 struct IsdnCardState
*cs
= dev_id
;
291 if ((cs
->hw
.sedl
.bus
== SEDL_BUS_PCMCIA
) && (*cs
->busy_flag
== 1)) {
292 /* The card tends to generate interrupts while being removed
293 causing us to just crash the kernel. bad. */
294 printk(KERN_WARNING
"Sedlbauer: card not available!\n");
297 return hscxisac_irq(intno
, dev_id
, regs
);
301 sedlbauer_isar_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
303 struct IsdnCardState
*cs
= dev_id
;
307 spin_lock(&cs
->lock
);
308 val
= isar_read(cs
, 0, ISAR_IRQBIT
);
310 if (val
& ISAR_IRQSTA
)
312 val
= isac_read(cs
, ISAC_ISTA
);
315 isac_interrupt(cs
, val
);
316 val
= isar_read(cs
, 0, ISAR_IRQBIT
);
317 if ((val
& ISAR_IRQSTA
) && --cnt
) {
318 if (cs
->debug
& L1_DEB_HSCX
)
319 debugl1(cs
, "ISAR IntStat after IntRoutine");
322 val
= isac_read(cs
, ISAC_ISTA
);
324 if (cs
->debug
& L1_DEB_ISAC
)
325 debugl1(cs
, "ISAC IntStat after IntRoutine");
329 if (cs
->debug
& L1_DEB_ISAC
)
330 debugl1(cs
, "Sedlbauer IRQ LOOP");
332 isar_write(cs
, 0, ISAR_IRQBIT
, 0);
333 isac_write(cs
, ISAC_MASK
, 0xFF);
334 isac_write(cs
, ISAC_MASK
, 0x0);
335 isar_write(cs
, 0, ISAR_IRQBIT
, ISAR_IRQMSK
);
336 spin_unlock(&cs
->lock
);
341 sedlbauer_ipac_reset(struct IsdnCardState
*cs
)
343 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_POTA2
, 0x20);
344 set_current_state(TASK_UNINTERRUPTIBLE
);
345 schedule_timeout((10*HZ
)/1000);
346 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_POTA2
, 0x0);
347 set_current_state(TASK_UNINTERRUPTIBLE
);
348 schedule_timeout((10*HZ
)/1000);
349 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_CONF
, 0x0);
350 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_ACFG
, 0xff);
351 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_AOE
, 0x0);
352 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_MASK
, 0xc0);
353 writereg(cs
, cs
->hw
.sedl
.isac
, IPAC_PCFG
, 0x12);
358 sedlbauer_isar_pci_reset(struct IsdnCardState
*cs
)
360 byteout(cs
->hw
.sedl
.cfg_reg
+3, cs
->hw
.sedl
.reset_on
);
361 current
->state
= TASK_UNINTERRUPTIBLE
;
362 schedule_timeout((20*HZ
)/1000);
363 byteout(cs
->hw
.sedl
.cfg_reg
+3, cs
->hw
.sedl
.reset_off
);
364 current
->state
= TASK_UNINTERRUPTIBLE
;
365 schedule_timeout((20*HZ
)/1000);
370 sedlbauer_reset(struct IsdnCardState
*cs
)
372 printk(KERN_INFO
"Sedlbauer: resetting card\n");
373 if (cs
->hw
.sedl
.bus
== SEDL_BUS_PCMCIA
&&
374 cs
->hw
.sedl
.chip
== SEDL_CHIP_ISAC_HSCX
)
377 if (cs
->hw
.sedl
.chip
== SEDL_CHIP_IPAC
) {
378 return sedlbauer_ipac_reset(cs
);
379 } else if ((cs
->hw
.sedl
.chip
== SEDL_CHIP_ISAC_ISAR
) &&
380 (cs
->hw
.sedl
.bus
== SEDL_BUS_PCI
)) {
381 return sedlbauer_isar_pci_reset(cs
);
383 byteout(cs
->hw
.sedl
.reset_on
, SEDL_RESET
); /* Reset On */
384 set_current_state(TASK_UNINTERRUPTIBLE
);
385 schedule_timeout((10*HZ
)/1000);
386 byteout(cs
->hw
.sedl
.reset_off
, 0); /* Reset Off */
387 set_current_state(TASK_UNINTERRUPTIBLE
);
388 schedule_timeout((10*HZ
)/1000);
394 sedlbauer_isar_release(struct IsdnCardState
*cs
)
396 isar_write(cs
, 0, ISAR_IRQBIT
, 0);
397 isac_write(cs
, ISAC_MASK
, 0xFF);
399 isar_write(cs
, 0, ISAR_IRQBIT
, 0);
400 isac_write(cs
, ISAC_MASK
, 0xFF);
401 hisax_release_resources(cs
);
405 sedlbauer_led_handler(struct IsdnCardState
*cs
)
407 if (cs
->subtyp
!= SEDL_SPEEDFAX_PYRAMID
)
410 if (cs
->status
& 0x2000)
411 cs
->hw
.sedl
.reset_off
&= ~SEDL_ISAR_PCI_LED2
;
413 cs
->hw
.sedl
.reset_off
|= SEDL_ISAR_PCI_LED2
;
415 if (cs
->status
& 0x1000)
416 cs
->hw
.sedl
.reset_off
&= ~SEDL_ISAR_PCI_LED1
;
418 cs
->hw
.sedl
.reset_off
|= SEDL_ISAR_PCI_LED1
;
420 byteout(cs
->hw
.sedl
.cfg_reg
+3, cs
->hw
.sedl
.reset_off
);
424 sedlbauer_isar_init(struct IsdnCardState
*cs
)
426 isar_write(cs
, 0, ISAR_IRQBIT
, 0);
431 static struct card_ops sedlbauer_ops
= {
432 .init
= inithscxisac
,
433 .reset
= sedlbauer_reset
,
434 .release
= hisax_release_resources
,
435 .led_handler
= sedlbauer_led_handler
,
436 .irq_func
= sedlbauer_interrupt
,
439 static struct card_ops sedlbauer_ipac_ops
= {
441 .reset
= sedlbauer_reset
,
442 .release
= hisax_release_resources
,
443 .led_handler
= sedlbauer_led_handler
,
444 .irq_func
= ipac_irq
,
447 static struct card_ops sedlbauer_isar_ops
= {
448 .init
= sedlbauer_isar_init
,
449 .reset
= sedlbauer_reset
,
450 .release
= sedlbauer_isar_release
,
451 .led_handler
= sedlbauer_led_handler
,
452 .irq_func
= sedlbauer_isar_interrupt
,
456 sedl_ipac_probe(struct IsdnCardState
*cs
)
460 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_ADR
;
461 val
= readreg(cs
, cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_IPAC
, IPAC_ID
);
462 printk(KERN_DEBUG
"Sedlbauer: testing IPAC version %x\n", val
);
463 return (val
== 1 || val
== 2);
467 sedl_ipac_init(struct IsdnCardState
*cs
)
469 cs
->card_ops
= &sedlbauer_ipac_ops
;
470 if (ipac_setup(cs
, &ipac_dc_ops
, &ipac_bc_ops
))
477 sedl_isac_isar_init(struct IsdnCardState
*cs
)
479 cs
->bcs
[0].hw
.isar
.reg
= &cs
->hw
.sedl
.isar
;
480 cs
->bcs
[1].hw
.isar
.reg
= &cs
->hw
.sedl
.isar
;
481 __set_bit(HW_ISAR
, &cs
->HW_Flags
);
482 cs
->card_ops
= &sedlbauer_isar_ops
;
483 cs
->auxcmd
= &isar_auxcmd
;
484 isac_setup(cs
, &isac_ops
);
485 return isar_setup(cs
, &isar_ops
);
489 sedl_isac_hscx_init(struct IsdnCardState
*cs
)
491 cs
->card_ops
= &sedlbauer_ops
;
492 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
499 sedl_card_win_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
501 cs
->irq
= card
->para
[0];
502 cs
->hw
.sedl
.cfg_reg
= card
->para
[1];
503 cs
->hw
.sedl
.bus
= SEDL_BUS_ISA
;
504 if (!request_io(&cs
->rs
, cs
->hw
.sedl
.cfg_reg
, 8, "sedlbauer isdn"))
507 if (sedl_ipac_probe(cs
)) {
508 cs
->subtyp
= SEDL_SPEED_WIN2_PC104
;
509 cs
->hw
.sedl
.chip
= SEDL_CHIP_IPAC
;
510 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_ADR
;
511 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_IPAC
;
512 if (sedl_ipac_init(cs
))
515 cs
->subtyp
= SEDL_SPEED_CARD_WIN
;
516 cs
->hw
.sedl
.chip
= SEDL_CHIP_ISAC_HSCX
;
517 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_ISA_ADR
;
518 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_ISA_ISAC
;
519 cs
->hw
.sedl
.hscx
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_ISA_HSCX
;
520 cs
->hw
.sedl
.reset_on
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_ISA_RESET_ON
;
521 cs
->hw
.sedl
.reset_off
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_ISA_RESET_OFF
;
522 if (sedl_isac_hscx_init(cs
))
525 printk(KERN_INFO
"Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
526 Sedlbauer_Types
[cs
->subtyp
],
527 cs
->hw
.sedl
.cfg_reg
, cs
->hw
.sedl
.cfg_reg
+ 8, cs
->irq
);
531 hisax_release_resources(cs
);
536 sedl_star_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
538 cs
->hw
.sedl
.bus
= SEDL_BUS_PCMCIA
;
539 if (sedl_ipac_probe(cs
)) {
540 cs
->subtyp
= SEDL_SPEED_STAR2
;
541 cs
->hw
.sedl
.chip
= SEDL_CHIP_IPAC
;
542 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_ADR
;
543 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_ANY_IPAC
;
544 if (sedl_ipac_init(cs
))
547 cs
->subtyp
= SEDL_SPEED_STAR
;
548 cs
->hw
.sedl
.chip
= SEDL_CHIP_ISAC_HSCX
;
549 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_PCMCIA_ADR
;
550 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_PCMCIA_ISAC
;
551 cs
->hw
.sedl
.hscx
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_PCMCIA_HSCX
;
552 cs
->hw
.sedl
.reset_on
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_PCMCIA_RESET
;
553 cs
->hw
.sedl
.reset_off
= cs
->hw
.sedl
.cfg_reg
+ SEDL_HSCX_PCMCIA_RESET
;
554 if (sedl_isac_hscx_init(cs
))
557 printk(KERN_INFO
"Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
558 Sedlbauer_Types
[cs
->subtyp
],
559 cs
->hw
.sedl
.cfg_reg
, cs
->hw
.sedl
.cfg_reg
+ 8, cs
->irq
);
563 hisax_release_resources(cs
);
568 sedl_fax_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
570 cs
->subtyp
= SEDL_SPEED_FAX
;
571 cs
->hw
.sedl
.bus
= SEDL_BUS_ISA
;
572 cs
->hw
.sedl
.chip
= SEDL_CHIP_ISAC_ISAR
;
573 if (!request_io(&cs
->rs
, cs
->hw
.sedl
.cfg_reg
, 16, "sedlbauer isdn"))
576 printk(KERN_INFO
"Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
577 Sedlbauer_Types
[cs
->subtyp
],
578 cs
->hw
.sedl
.cfg_reg
, cs
->hw
.sedl
.cfg_reg
+ 16, cs
->irq
);
580 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_ISA_ADR
;
581 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_ISA_ISAC
;
582 cs
->hw
.sedl
.hscx
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_ISA_ISAR
;
583 cs
->hw
.sedl
.reset_on
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_ISA_ISAR_RESET_ON
;
584 cs
->hw
.sedl
.reset_off
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_ISA_ISAR_RESET_OFF
;
585 if (sedl_isac_isar_init(cs
))
590 hisax_release_resources(cs
);
595 sedl_pci_init(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
598 cs
->irq_flags
|= SA_SHIRQ
;
599 cs
->hw
.sedl
.cfg_reg
= pci_resource_start(pdev
, 0);
600 cs
->hw
.sedl
.bus
= SEDL_BUS_PCI
;
602 if (!request_io(&cs
->rs
, cs
->hw
.sedl
.cfg_reg
, 256, "sedlbauer isdn"))
605 printk(KERN_INFO
"Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
606 Sedlbauer_Types
[cs
->subtyp
],
607 cs
->hw
.sedl
.cfg_reg
, cs
->hw
.sedl
.cfg_reg
+ 256, cs
->irq
);
609 cs
->hw
.sedl
.reset_on
= SEDL_ISAR_PCI_ISAR_RESET_ON
;
610 cs
->hw
.sedl
.reset_off
= SEDL_ISAR_PCI_ISAR_RESET_OFF
;
611 byteout(cs
->hw
.sedl
.cfg_reg
, 0xff);
612 byteout(cs
->hw
.sedl
.cfg_reg
, 0x00);
613 byteout(cs
->hw
.sedl
.cfg_reg
+ 2, 0xdd);
614 byteout(cs
->hw
.sedl
.cfg_reg
+ 5, 0x02);
615 byteout(cs
->hw
.sedl
.cfg_reg
+3, cs
->hw
.sedl
.reset_on
);
616 current
->state
= TASK_UNINTERRUPTIBLE
;
617 schedule_timeout((10*HZ
)/1000);
618 byteout(cs
->hw
.sedl
.cfg_reg
+3, cs
->hw
.sedl
.reset_off
);
623 sedl_fax_pyramid_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
625 if (pci_enable_device(pdev
))
628 cs
->subtyp
= SEDL_SPEEDFAX_PYRAMID
;
629 cs
->hw
.sedl
.chip
= SEDL_CHIP_ISAC_ISAR
;
630 if (sedl_pci_init(cs
, pdev
))
633 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ADR
;
634 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ISAC
;
635 cs
->hw
.sedl
.hscx
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ISAR
;
636 if (sedl_isac_isar_init(cs
))
641 hisax_release_resources(cs
);
646 sedl_fax_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
648 if (pci_enable_device(pdev
))
651 cs
->subtyp
= SEDL_SPEEDFAX_PCI
;
652 cs
->hw
.sedl
.chip
= SEDL_CHIP_ISAC_ISAR
;
654 if (sedl_pci_init(cs
, pdev
))
657 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ADR
;
658 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ISAC
;
659 cs
->hw
.sedl
.hscx
= cs
->hw
.sedl
.cfg_reg
+ SEDL_ISAR_PCI_ISAR
;
660 if (sedl_isac_isar_init(cs
))
665 hisax_release_resources(cs
);
670 sedl_pci_probe(struct IsdnCardState
*cs
, struct pci_dev
*pdev
)
672 if (pci_enable_device(pdev
))
675 cs
->subtyp
= SEDL_SPEED_PCI
;
676 cs
->hw
.sedl
.chip
= SEDL_CHIP_IPAC
;
677 if (sedl_pci_init(cs
, pdev
))
680 cs
->hw
.sedl
.adr
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_PCI_ADR
;
681 cs
->hw
.sedl
.isac
= cs
->hw
.sedl
.cfg_reg
+ SEDL_IPAC_PCI_IPAC
;
682 if (sedl_ipac_init(cs
))
686 hisax_release_resources(cs
);
690 static struct pci_dev
*dev_sedl __devinitdata
= NULL
;
693 static struct isapnp_device_id sedl_ids
[] __initdata
= {
694 { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
695 ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
696 (unsigned long) "Speed win" },
697 { ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
698 ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
699 (unsigned long) "Speed Fax+" },
703 static struct isapnp_device_id
*pdev
= &sedl_ids
[0];
704 static struct pnp_card
*pnp_c __devinitdata
= NULL
;
708 setup_sedlbauer(struct IsdnCard
*card
)
710 struct IsdnCardState
*cs
= card
->cs
;
712 u16 sub_vendor_id
, sub_id
;
714 strcpy(tmp
, Sedlbauer_revision
);
715 printk(KERN_INFO
"HiSax: Sedlbauer driver Rev. %s\n",
719 if (cs
->typ
== ISDN_CTYPE_SEDLBAUER
) {
720 if (sedl_card_win_probe(card
->cs
, card
) < 0)
723 } else if (cs
->typ
== ISDN_CTYPE_SEDLBAUER_PCMCIA
) {
724 if (sedl_star_probe(card
->cs
, card
) < 0)
727 } else if (cs
->typ
== ISDN_CTYPE_SEDLBAUER_FAX
) {
728 if (sedl_fax_probe(card
->cs
, card
) < 0)
734 if (isapnp_present()) {
738 while(pdev
->card_vendor
) {
739 if ((pb
= pnp_find_card(pdev
->card_vendor
,
744 if ((pd
= pnp_find_dev(pnp_c
,
748 printk(KERN_INFO
"HiSax: %s detected\n",
749 (char *)pdev
->driver_data
);
750 if (pnp_device_attach(pd
) < 0) {
751 printk(KERN_ERR
"Sedlbauer PnP: attach failed\n");
754 if (pnp_activate_dev(pd
) < 0) {
755 printk(KERN_ERR
"Sedlbauer PnP: activate failed\n");
756 pnp_device_detach(pd
);
759 if (!pnp_irq_valid(pd
, 0) || !pnp_port_valid(pd
, 0)) {
760 printk(KERN_ERR
"Sedlbauer PnP:some resources are missing %ld/%lx\n",
761 pnp_irq(pd
, 0), pnp_port_start(pd
, 0));
762 pnp_device_detach(pd
);
765 card
->para
[1] = pnp_port_start(pd
, 0);
766 card
->para
[0] = pnp_irq(pd
, 0);
767 cs
->hw
.sedl
.cfg_reg
= card
->para
[1];
768 cs
->irq
= card
->para
[0];
769 if (pdev
->function
== ISAPNP_FUNCTION(0x2)) {
770 if (sedl_fax_probe(card
->cs
, card
))
774 if (sedl_card_win_probe(card
->cs
, card
))
779 printk(KERN_ERR
"Sedlbauer PnP: PnP error card found, no device\n");
786 if (!pdev
->card_vendor
) {
787 printk(KERN_INFO
"Sedlbauer PnP: no ISAPnP card found\n");
791 /* Probe for Sedlbauer speed pci */
793 dev_sedl
= pci_find_device(PCI_VENDOR_ID_TIGERJET
,
794 PCI_DEVICE_ID_TIGERJET_100
, dev_sedl
);
796 sub_vendor_id
= dev_sedl
->subsystem_vendor
;
797 sub_id
= dev_sedl
->subsystem_device
;
798 printk(KERN_INFO
"Sedlbauer: PCI subvendor:%x subid %x\n",
799 sub_vendor_id
, sub_id
);
800 if (sub_id
!= PCI_SUB_ID_SEDLBAUER
) {
801 printk(KERN_ERR
"Sedlbauer: unknown sub id %#x\n", sub_id
);
804 if (sub_vendor_id
== PCI_SUBVENDOR_SPEEDFAX_PYRAMID
) {
805 if (sedl_fax_pyramid_probe(cs
, dev_sedl
))
808 } else if (sub_vendor_id
== PCI_SUBVENDOR_SPEEDFAX_PCI
) {
809 if (sedl_fax_pci_probe(cs
, dev_sedl
))
812 } else if (sub_vendor_id
== PCI_SUBVENDOR_SEDLBAUER_PCI
) {
813 if (sedl_pci_probe(cs
, dev_sedl
))
817 printk(KERN_ERR
"Sedlbauer: unknown sub vendor id %#x\n",
821 #endif /* CONFIG_PCI */