]>
Commit | Line | Data |
---|---|---|
93afd047 MT |
1 | #if defined(__i386__) |
2 | ||
3 | #include <stdio.h> | |
4 | #include <sys/io.h> | |
5 | ||
6 | #include "hd.h" | |
7 | #include "hd_int.h" | |
8 | #include "isa.h" | |
9 | ||
10 | #define AVM_CONFIG_OFF 0x1800 /* offset for config register */ | |
11 | #define AVM_TEST_MASK 0x28 /* allways zero */ | |
12 | #define AVM_HSCX_A_VSTR 0x40e /* HSCX A version reg */ | |
13 | #define AVM_HSCX_B_VSTR 0xc0e /* HSCX B version reg */ | |
14 | ||
15 | int avm_a1_detect(isa_isdn_t **ii) { | |
16 | int adr,i; | |
17 | unsigned char val,v1,v2; | |
18 | int found=0; | |
19 | unsigned short AVM_ADR[4]={0x200,0x240,0x300,0x340}; | |
20 | isa_isdn_t *card; | |
21 | ||
22 | for (i=0;i<4;i++) { | |
23 | adr=AVM_ADR[i] + AVM_CONFIG_OFF; | |
24 | val = inb(adr); | |
25 | if (val & AVM_TEST_MASK) | |
26 | continue; | |
27 | /* May be we found an AVM A1 or AVM Fritz!Classic */ | |
28 | /* Checking HSCX VERSIONS */ | |
29 | v1 = 0xf & inb(AVM_ADR[i] + AVM_HSCX_A_VSTR); | |
30 | if ((v1 != 5) && (v1 != 4)) | |
31 | continue; | |
32 | v2 = 0xf & inb(AVM_ADR[i] + AVM_HSCX_B_VSTR); | |
33 | if (v1 != v2) | |
34 | continue; | |
35 | /* 99% we found an AVM A1 or AVM Fritz!Classic */ | |
36 | /* printf("# AVM A1 or Fritz!Classic found\n"); | |
37 | printf("TYPE=5 SUBTYPE=0 IO=0x%3x\n", AVM_ADR[i]); */ | |
38 | card = new_isa_isdn(ii); | |
39 | card->type = 5; card->has_io = 1; card->io = AVM_ADR[i]; | |
40 | found++; | |
41 | } | |
42 | return(found); | |
43 | } | |
44 | ||
45 | #define ELSA_CONFIG 5 | |
46 | #define ELSA_PC 1 | |
47 | #define ELSA_PCC8 2 | |
48 | #define ELSA_PCC16 3 | |
49 | #define ELSA_PCF 4 | |
50 | #define ELSA_PCFPRO 5 | |
51 | ||
52 | #define ELSA_IRQ_IDX 0x38 /* Bit 3,4,5 des Config-Reg */ | |
53 | #define ELSA_IRQ_IDX_PCC8 0x30 /* Bit 4,5 des Config-Reg */ | |
54 | #define ELSA_IRQ_IDX_PC 0x0c /* Bit 2,3 des Config-Reg */ | |
55 | ||
56 | ||
57 | int | |
58 | probe_elsa_adr(unsigned int adr) | |
59 | { | |
60 | int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0, | |
61 | pc_2 = 0, pfp_1 = 0, pfp_2 = 0; | |
62 | ||
63 | for (i = 0; i < 16; i++) { | |
64 | in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ | |
65 | in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ | |
66 | p16_1 += 0x04 & in1; | |
67 | p16_2 += 0x04 & in2; | |
68 | p8_1 += 0x02 & in1; | |
69 | p8_2 += 0x02 & in2; | |
70 | pc_1 += 0x01 & in1; | |
71 | pc_2 += 0x01 & in2; | |
72 | pfp_1 += 0x40 & in1; | |
73 | pfp_2 += 0x40 & in2; | |
74 | } | |
75 | if (65 == ++p16_1 * ++p16_2) { | |
76 | return (ELSA_PCC16); | |
77 | } else if (1025 == ++pfp_1 * ++pfp_2) { | |
78 | return (ELSA_PCFPRO); | |
79 | } else if (33 == ++p8_1 * ++p8_2) { | |
80 | return (ELSA_PCC8); | |
81 | } else if (17 == ++pc_1 * ++pc_2) { | |
82 | return (ELSA_PC); | |
83 | } | |
84 | return (0); | |
85 | } | |
86 | ||
87 | int | |
88 | probe_elsa(isa_isdn_t **ii) | |
89 | { | |
90 | int i, subtyp, val, irq, found=0; | |
91 | isa_isdn_t *card; | |
92 | ||
93 | unsigned int CARD_portlist[] = | |
94 | {0x160, 0x170, 0x260, 0x360, 0}; | |
95 | ||
96 | for (i = 0; CARD_portlist[i]; i++) { | |
97 | if ((subtyp = probe_elsa_adr(CARD_portlist[i]))) { | |
98 | found++; | |
99 | val = inb(CARD_portlist[i] + ELSA_CONFIG); | |
100 | if (subtyp == ELSA_PC) { | |
101 | int CARD_IrqTab[8] = | |
102 | {7, 3, 5, 9, 0, 0, 0, 0}; | |
103 | irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; | |
104 | } else if (subtyp == ELSA_PCC8) { | |
105 | int CARD_IrqTab[8] = | |
106 | {7, 3, 5, 9, 0, 0, 0, 0}; | |
107 | irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; | |
108 | } else { | |
109 | int CARD_IrqTab[8] = | |
110 | {15, 10, 15, 3, 11, 5, 11, 9}; | |
111 | irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; | |
112 | } | |
113 | switch(subtyp) { | |
114 | case ELSA_PC: | |
115 | /* printf("# Elsa ML PC found\n"); | |
116 | printf("TYPE=6 SUBTYPE=%d IO=0x%03x IRQ=%d\n", | |
117 | subtyp, CARD_portlist[i], irq); */ | |
118 | case ELSA_PCC8: | |
119 | /* printf("# Elsa ML PCC-8 found\n"); | |
120 | printf("TYPE=6 SUBTYPE=%d IO=0x%03x IRQ=%d\n", | |
121 | subtyp, CARD_portlist[i], irq); */ | |
122 | case ELSA_PCC16: | |
123 | /* printf("# Elsa ML PCC-16 found\n"); | |
124 | printf("TYPE=6 SUBTYPE=%d IO=0x%03x IRQ=%d\n", | |
125 | subtyp, CARD_portlist[i], irq); */ | |
126 | case ELSA_PCF: | |
127 | /* printf("# Elsa ML PCF found\n"); | |
128 | printf("TYPE=6 SUBTYPE=%d IO=0x%03x IRQ=%d\n", | |
129 | subtyp, CARD_portlist[i], irq); */ | |
130 | case ELSA_PCFPRO: | |
131 | /* printf("# Elsa ML PCFPro found\n"); | |
132 | printf("TYPE=6 SUBTYPE=%d IO=0x%03x IRQ=%d\n", | |
133 | subtyp, CARD_portlist[i], irq); */ | |
134 | ||
135 | card = new_isa_isdn(ii); | |
136 | card->type = 6; card->subtype = subtyp; | |
137 | card->has_io = 1; card->io = CARD_portlist[i]; | |
138 | card->has_irq = 1; card->irq = irq; | |
139 | break; | |
140 | } | |
141 | } | |
142 | } | |
143 | return (found); | |
144 | } | |
145 | ||
146 | ||
147 | #define TELES_CONFIG_OFF 0xc00 | |
148 | #define TELES_ID1 0x51 | |
149 | #define TELES_ID2 0x93 | |
150 | #define TELES_16_0 0x1e | |
151 | #define TELES_16_0_AB 0x1f | |
152 | #define TELES_16_3_0 0x1c | |
153 | #define TELES_16_3_1 0x39 | |
154 | #define TELES_16_3_3 0x38 | |
155 | #define TELES_16_3_AB 0x46 | |
156 | ||
157 | ||
158 | int telesdetect(isa_isdn_t **ii) { | |
159 | int adr,val,i; | |
160 | int found=0; | |
161 | unsigned short TELES_ADR[3]={0x380,0x280,0x180}; | |
162 | isa_isdn_t *card; | |
163 | ||
164 | for (i=0;i<3;i++) { | |
165 | adr=TELES_ADR[i] + TELES_CONFIG_OFF; | |
166 | ||
167 | val = inb(adr); | |
168 | if (val != TELES_ID1) | |
169 | continue; | |
170 | adr++; | |
171 | val = inb(adr); | |
172 | if (val != TELES_ID2) | |
173 | continue; | |
174 | adr++; | |
175 | val = inb(adr); | |
176 | switch(val) { | |
177 | case TELES_16_0: | |
178 | /* printf("# Teles 16.0 found\n"); | |
179 | printf("TYPE=1 SUBTYPE=0 IO=0x%3x\n", | |
180 | TELES_ADR[i] + TELES_CONFIG_OFF); */ | |
181 | case TELES_16_0_AB: | |
182 | /* printf("# Teles 16.0 AB found\n"); | |
183 | printf("TYPE=1 SUBTYPE=1 IO=0x%3x\n", | |
184 | TELES_ADR[i] + TELES_CONFIG_OFF); */ | |
185 | card = new_isa_isdn(ii); | |
186 | card->type = 1; | |
187 | if(val == TELES_16_0_AB) card->subtype = 1; | |
188 | card->has_io = 1; card->io = TELES_ADR[i] + TELES_CONFIG_OFF; | |
189 | found++; | |
190 | break; | |
191 | case TELES_16_3_0: | |
192 | /* printf("# Teles 16.3 v1.0 found\n"); | |
193 | printf("TYPE=3 SUBTYPE=0 IO=0x%3x\n", | |
194 | TELES_ADR[i]); */ | |
195 | case TELES_16_3_1: | |
196 | /* printf("# Teles 16.3 v1.1 found\n"); | |
197 | printf("TYPE=3 SUBTYPE=0 IO=0x%3x\n", | |
198 | TELES_ADR[i]); */ | |
199 | case TELES_16_3_3: | |
200 | /* printf("# Teles 16.3 v1.3 found\n"); | |
201 | printf("TYPE=3 SUBTYPE=0 IO=0x%3x\n", | |
202 | TELES_ADR[i]); */ | |
203 | case TELES_16_3_AB: | |
204 | /* printf("# Teles 16.3 AB Video found\n"); | |
205 | printf("TYPE=3 SUBTYPE=1 IO=0x%3x\n", | |
206 | TELES_ADR[i]); */ | |
207 | card = new_isa_isdn(ii); | |
208 | card->type = 3; | |
209 | if(val == TELES_16_3_AB) card->subtype = 1; | |
210 | card->has_io = 1; card->io = TELES_ADR[i]; | |
211 | found++; | |
212 | break; | |
213 | default: | |
214 | if (0 /* guess */) | |
215 | printf("# may be a Teles 16.0/16.3 detected at IO=0x%3x byte 3 is 0x%02x\n", | |
216 | TELES_ADR[i] + TELES_CONFIG_OFF, val); | |
217 | break; | |
218 | } | |
219 | } | |
220 | return(found); | |
221 | } | |
222 | ||
223 | isa_isdn_t *isdn_detect() | |
224 | { | |
225 | isa_isdn_t *ii = NULL; | |
226 | ||
227 | if(iopl(3) < 0) return ii; | |
228 | ||
229 | avm_a1_detect(&ii); | |
230 | probe_elsa(&ii); | |
231 | telesdetect(&ii); | |
232 | ||
233 | iopl(0); | |
234 | ||
235 | return ii; | |
236 | } | |
237 | ||
238 | #endif /* i386 */ |