1 /* $Id: hfcscard.c,v 1.7 2000/06/26 08:59:13 keil Exp $
3 * hfcscard.c low level stuff for hfcs based cards (Teles3c, ACER P10)
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * This file is (c) under GNU PUBLIC LICENSE
11 #define __NO_VERSION__
13 #include "hfc_2bds0.h"
16 extern const char *CardType
[];
18 static const char *hfcs_revision
= "$Revision: 1.7 $";
21 hfcs_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
23 struct IsdnCardState
*cs
= dev_id
;
27 printk(KERN_WARNING
"HFCS: Spurious interrupt!\n");
30 if ((HFCD_ANYINT
| HFCD_BUSY_NBUSY
) &
31 (stat
= cs
->BC_Read_Reg(cs
, HFCD_DATA
, HFCD_STAT
))) {
32 val
= cs
->BC_Read_Reg(cs
, HFCD_DATA
, HFCD_INT_S1
);
33 if (cs
->debug
& L1_DEB_ISAC
)
34 debugl1(cs
, "HFCS: stat(%02x) s1(%02x)", stat
, val
);
35 hfc2bds0_interrupt(cs
, val
);
37 if (cs
->debug
& L1_DEB_ISAC
)
38 debugl1(cs
, "HFCS: irq_no_irq stat(%02x)", stat
);
43 hfcs_Timer(struct IsdnCardState
*cs
)
45 cs
->hw
.hfcD
.timer
.expires
= jiffies
+ 75;
47 /* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt | 0x80);
48 add_timer(&cs->hw.hfcD.timer);
53 release_io_hfcs(struct IsdnCardState
*cs
)
56 del_timer(&cs
->hw
.hfcD
.timer
);
58 release_region(cs
->hw
.hfcD
.addr
, 2);
62 reset_hfcs(struct IsdnCardState
*cs
)
66 printk(KERN_INFO
"HFCS: resetting card\n");
67 cs
->hw
.hfcD
.cirm
= HFCD_RESET
;
68 if (cs
->typ
== ISDN_CTYPE_TELES3C
)
69 cs
->hw
.hfcD
.cirm
|= HFCD_MEM8K
;
70 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CIRM
, cs
->hw
.hfcD
.cirm
); /* Reset On */
73 set_current_state(TASK_UNINTERRUPTIBLE
);
74 schedule_timeout((30*HZ
)/1000);
76 if (cs
->typ
== ISDN_CTYPE_TELES3C
)
77 cs
->hw
.hfcD
.cirm
|= HFCD_MEM8K
;
78 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CIRM
, cs
->hw
.hfcD
.cirm
); /* Reset Off */
79 set_current_state(TASK_UNINTERRUPTIBLE
);
80 schedule_timeout((10*HZ
)/1000);
81 if (cs
->typ
== ISDN_CTYPE_TELES3C
)
82 cs
->hw
.hfcD
.cirm
|= HFCD_INTB
;
83 else if (cs
->typ
== ISDN_CTYPE_ACERP10
)
84 cs
->hw
.hfcD
.cirm
|= HFCD_INTA
;
85 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CIRM
, cs
->hw
.hfcD
.cirm
);
86 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CLKDEL
, 0x0e);
87 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_TEST
, HFCD_AUTO_AWAKE
); /* S/T Auto awake */
88 cs
->hw
.hfcD
.ctmt
= HFCD_TIM25
| HFCD_AUTO_TIMER
;
89 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CTMT
, cs
->hw
.hfcD
.ctmt
);
90 cs
->hw
.hfcD
.int_m2
= HFCD_IRQ_ENABLE
;
91 cs
->hw
.hfcD
.int_m1
= HFCD_INTS_B1TRANS
| HFCD_INTS_B2TRANS
|
92 HFCD_INTS_DTRANS
| HFCD_INTS_B1REC
| HFCD_INTS_B2REC
|
93 HFCD_INTS_DREC
| HFCD_INTS_L1STATE
;
94 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_INT_M1
, cs
->hw
.hfcD
.int_m1
);
95 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_INT_M2
, cs
->hw
.hfcD
.int_m2
);
96 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_STATES
, HFCD_LOAD_STATE
| 2); /* HFC ST 2 */
98 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_STATES
, 2); /* HFC ST 2 */
99 cs
->hw
.hfcD
.mst_m
= HFCD_MASTER
;
100 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_MST_MODE
, cs
->hw
.hfcD
.mst_m
); /* HFC Master */
101 cs
->hw
.hfcD
.sctrl
= 0;
102 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_SCTRL
, cs
->hw
.hfcD
.sctrl
);
103 restore_flags(flags
);
107 hfcs_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
111 if (cs
->debug
& L1_DEB_ISAC
)
112 debugl1(cs
, "HFCS: card_msg %x", mt
);
121 cs
->hw
.hfcD
.timer
.expires
= jiffies
+ 75;
122 add_timer(&cs
->hw
.hfcD
.timer
);
126 set_current_state(TASK_UNINTERRUPTIBLE
);
127 schedule_timeout((80*HZ
)/1000);
128 cs
->hw
.hfcD
.ctmt
|= HFCD_TIM800
;
129 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_CTMT
, cs
->hw
.hfcD
.ctmt
);
130 cs
->BC_Write_Reg(cs
, HFCD_DATA
, HFCD_MST_MODE
, cs
->hw
.hfcD
.mst_m
);
131 restore_flags(flags
);
140 setup_hfcs(struct IsdnCard
*card
))
142 struct IsdnCardState
*cs
= card
->cs
;
145 strcpy(tmp
, hfcs_revision
);
146 printk(KERN_INFO
"HiSax: HFC-S driver Rev. %s\n", HiSax_getrev(tmp
));
147 cs
->hw
.hfcD
.addr
= card
->para
[1] & 0xfffe;
148 cs
->irq
= card
->para
[0];
150 cs
->hw
.hfcD
.int_s1
= 0;
151 cs
->hw
.hfcD
.send
= NULL
;
152 cs
->bcs
[0].hw
.hfc
.send
= NULL
;
153 cs
->bcs
[1].hw
.hfc
.send
= NULL
;
154 cs
->hw
.hfcD
.dfifosize
= 512;
155 cs
->dc
.hfcd
.ph_state
= 0;
156 cs
->hw
.hfcD
.fifo
= 255;
157 if (cs
->typ
== ISDN_CTYPE_TELES3C
) {
158 cs
->hw
.hfcD
.bfifosize
= 1024 + 512;
159 } else if (cs
->typ
== ISDN_CTYPE_ACERP10
) {
160 cs
->hw
.hfcD
.bfifosize
= 7*1024 + 512;
163 if (check_region((cs
->hw
.hfcD
.addr
), 2)) {
165 "HiSax: %s config port %x-%x already in use\n",
168 cs
->hw
.hfcD
.addr
+ 2);
171 request_region(cs
->hw
.hfcD
.addr
, 2, "HFCS isdn");
174 "HFCS: defined at 0x%x IRQ %d HZ %d\n",
177 if (cs
->typ
== ISDN_CTYPE_TELES3C
) {
178 /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */
179 outb(0x00, cs
->hw
.hfcD
.addr
);
180 outb(0x56, cs
->hw
.hfcD
.addr
| 1);
181 } else if (cs
->typ
== ISDN_CTYPE_ACERP10
) {
182 /* Acer P10 IO ADR is 0x300 */
183 outb(0x00, cs
->hw
.hfcD
.addr
);
184 outb(0x57, cs
->hw
.hfcD
.addr
| 1);
187 cs
->hw
.hfcD
.timer
.function
= (void *) hfcs_Timer
;
188 cs
->hw
.hfcD
.timer
.data
= (long) cs
;
189 init_timer(&cs
->hw
.hfcD
.timer
);
191 cs
->cardmsg
= &hfcs_card_msg
;
192 cs
->irq_func
= &hfcs_interrupt
;