No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / isa / isic_isa_tel_s016.c
blobbb0a13b96c8b57ee09601daa275bfcf110de7981
1 /*
2 * Copyright (c) 1996 Arne Helme. All rights reserved.
4 * Copyright (c) 1996 Gary Jennejohn. All rights reserved.
6 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 * 4. Altered versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software and/or documentation.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 *---------------------------------------------------------------------------
37 * isic - I4B Siemens ISDN Chipset Driver for Teles S0/16 and clones
38 * =================================================================
40 * $Id: isic_isa_tel_s016.c,v 1.9 2007/10/19 12:00:19 ad Exp $
42 * last edit-date: [Fri Jan 5 11:37:22 2001]
44 * -hm clean up
45 * -hm checked with a Creatix ISDN-S0 (PCB version: mp 130.1)
46 * -hm more cleanup
47 * -hm NetBSD patches from Martin
48 * -hm converting asm -> C
50 *---------------------------------------------------------------------------*/
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: isic_isa_tel_s016.c,v 1.8 2007/03/04 06:02:12 christos Exp $");
55 #include "opt_isicisa.h"
56 #ifdef ISICISA_TEL_S0_16
58 #include <sys/param.h>
59 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
60 #include <sys/ioccom.h>
61 #else
62 #include <sys/ioctl.h>
63 #endif
64 #include <sys/kernel.h>
65 #include <sys/systm.h>
66 #include <sys/mbuf.h>
68 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
69 #include <sys/callout.h>
70 #endif
72 #ifdef __FreeBSD__
73 #include <machine/clock.h>
74 #include <machine/md_var.h>
75 #include <i386/isa/isa_device.h>
76 #else
77 #include <sys/bus.h>
78 #include <sys/device.h>
79 #endif
81 #include <sys/socket.h>
82 #include <net/if.h>
84 #ifdef __FreeBSD__
85 #include <machine/i4b_debug.h>
86 #include <machine/i4b_ioctl.h>
87 #else
88 #include <netisdn/i4b_debug.h>
89 #include <netisdn/i4b_ioctl.h>
90 #endif
92 #include <netisdn/i4b_global.h>
93 #include <netisdn/i4b_debug.h>
94 #include <netisdn/i4b_l2.h>
95 #include <netisdn/i4b_l1l2.h>
96 #include <netisdn/i4b_mbuf.h>
98 #include <dev/ic/isic_l1.h>
99 #include <dev/ic/isac.h>
100 #include <dev/ic/hscx.h>
102 static u_char intr_no[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 };
104 #ifndef __FreeBSD__
105 static u_int8_t tels016_read_reg(struct isic_softc *sc, int what, bus_size_t offs);
106 static void tels016_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
107 static void tels016_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
108 static void tels016_write_fifo(struct isic_softc *sc, int what, const void *data, size_t size);
109 #endif
111 /*---------------------------------------------------------------------------*
112 * Teles S0/16 write register routine
113 *---------------------------------------------------------------------------*/
114 #ifdef __FreeBSD__
116 static void
117 tels016_write_reg(u_char *base, u_int i, u_int v)
119 if(i & 0x01)
120 i |= 0x200;
121 base[i] = v;
124 #else
126 static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 };
128 static void
129 tels016_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
131 bus_space_tag_t t = sc->sc_maps[1].t;
132 bus_space_handle_t h = sc->sc_maps[1].h;
134 offs += offset[what];
135 if (offs & 0x01)
136 offs |= 0x200;
138 bus_space_write_1(t, h, offs, data);
140 #endif
142 /*---------------------------------------------------------------------------*
143 * Teles S0/16 read register routine
144 *---------------------------------------------------------------------------*/
145 #ifdef __FreeBSD__
147 static u_char
148 tels016_read_reg(u_char *base, u_int i)
150 if(i & 0x1)
151 i |= 0x200;
152 return(base[i]);
155 #else
157 static u_int8_t
158 tels016_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
160 bus_space_tag_t t = sc->sc_maps[1].t;
161 bus_space_handle_t h = sc->sc_maps[1].h;
163 offs += offset[what];
165 if(offs & 0x01)
166 offs |= 0x200;
168 return bus_space_read_1(t, h, offs);
170 #endif
172 /*---------------------------------------------------------------------------*
173 * Teles S0/16 fifo read/write routines
174 *---------------------------------------------------------------------------*/
175 #ifdef __FreeBSD__
177 static void
178 tels016_memcpyb(void *to, const void *from, size_t len)
180 for(;len > 0; len--)
181 *((unsigned char *)to)++ = *((unsigned char *)from)++;
184 #else
186 static void
187 tels016_write_fifo(struct isic_softc *sc, int what, const void *data, size_t size)
189 bus_space_tag_t t = sc->sc_maps[1].t;
190 bus_space_handle_t h = sc->sc_maps[1].h;
191 bus_space_write_region_1(t, h, offset[what], data, size);
194 static void
195 tels016_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
197 bus_space_tag_t t = sc->sc_maps[1].t;
198 bus_space_handle_t h = sc->sc_maps[1].h;
199 bus_space_read_region_1(t, h, offset[what], buf, size);
201 #endif
203 /*---------------------------------------------------------------------------*
204 * isic_probe_s016 - probe for Teles S0/16 and compatibles
205 *---------------------------------------------------------------------------*/
206 #ifdef __FreeBSD__
208 isic_probe_s016(struct isa_device *dev)
210 struct isic_softc *sc = &l1_sc[dev->id_unit];
211 u_char byte;
213 /* check max unit range */
215 if(dev->id_unit >= ISIC_MAXUNIT)
217 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16!\n",
218 dev->id_unit, dev->id_unit);
219 return(0);
221 sc->sc_unit = dev->id_unit;
223 /* check IRQ validity */
225 if((intr_no[ffs(dev->id_irq) - 1]) == 1)
227 printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16!\n",
228 dev->id_unit, ffs(dev->id_irq)-1);
229 return(0);
231 sc->sc_irq = dev->id_irq;
233 /* check if we got an iobase */
235 switch(dev->id_iobase)
237 case 0xd80:
238 case 0xe80:
239 case 0xf80:
240 break;
242 default:
243 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n",
244 dev->id_unit, dev->id_iobase);
245 return(0);
246 break;
248 sc->sc_port = dev->id_iobase;
250 /* check if valid memory addr */
252 switch((unsigned int)kvtop(dev->id_maddr))
254 case 0xc0000:
255 case 0xc2000:
256 case 0xc4000:
257 case 0xc6000:
258 case 0xc8000:
259 case 0xca000:
260 case 0xcc000:
261 case 0xce000:
262 case 0xd0000:
263 case 0xd2000:
264 case 0xd4000:
265 case 0xd6000:
266 case 0xd8000:
267 case 0xda000:
268 case 0xdc000:
269 case 0xde000:
270 break;
272 default:
273 printf("isic%d: Error, invalid mem addr 0x%lx for Teles S0/16!\n",
274 dev->id_unit, kvtop(dev->id_maddr));
275 return(0);
276 break;
278 sc->sc_vmem_addr = (void *) dev->id_maddr;
279 dev->id_msize = 0x1000;
281 /* check card signature */
283 if((byte = inb(sc->sc_port)) != 0x51)
285 printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16!\n",
286 dev->id_unit, byte);
287 return(0);
290 if((byte = inb(sc->sc_port + 1)) != 0x93)
292 printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n",
293 dev->id_unit, byte);
294 return(0);
297 byte = inb(sc->sc_port + 2);
299 if((byte != 0x1e) && (byte != 0x1f))
301 printf("isic%d: Error, signature 3 0x%x != 0x1e or 0x1f for Teles S0/16!\n",
302 dev->id_unit, byte);
303 return(0);
306 /* setup access routines */
308 sc->clearirq = NULL;
309 sc->readreg = tels016_read_reg;
310 sc->writereg = tels016_write_reg;
312 sc->readfifo = tels016_memcpyb;
313 sc->writefifo = tels016_memcpyb;
315 /* setup card type */
317 sc->sc_cardtyp= CARD_TYPEP_16;
319 /* setup IOM bus type */
321 sc->sc_bustyp = BUS_TYPE_IOM1;
323 sc->sc_ipac = 0;
324 sc->sc_bfifolen = HSCX_FIFO_LEN;
326 /* setup ISAC base addr */
328 ISAC_BASE = (void *) ((dev->id_maddr) + 0x100);
330 /* setup HSCX base addr */
332 HSCX_A_BASE = (void *) ((dev->id_maddr) + 0x180);
333 HSCX_B_BASE = (void *) ((dev->id_maddr) + 0x1c0);
335 return (1);
338 #else
341 isic_probe_s016(struct isic_attach_args *ia)
343 bus_space_tag_t t = ia->ia_maps[0].t;
344 bus_space_handle_t h = ia->ia_maps[0].h;
345 u_int8_t b0, b1, b2;
347 b0 = bus_space_read_1(t, h, 0);
348 b1 = bus_space_read_1(t, h, 1);
349 b2 = bus_space_read_1(t, h, 2);
351 if (b0 == 0x51 && b1 == 0x93 && (b2 == 0x1e || b2 == 0x1f))
352 return 1;
354 return 0;
356 #endif
358 /*---------------------------------------------------------------------------*
359 * isic_attach_s016 - attach Teles S0/16 and compatibles
360 *---------------------------------------------------------------------------*/
362 #ifdef __FreeBSD__
363 isic_attach_s016(struct isa_device *dev)
364 #else
365 isic_attach_s016(struct isic_softc *sc)
366 #endif
369 #ifdef __FreeBSD__
370 struct isic_softc *sc = &l1_sc[dev->id_unit];
371 #endif
373 u_long irq;
375 #ifndef __FreeBSD__
376 /* setup access routines */
378 sc->clearirq = NULL;
379 sc->readreg = tels016_read_reg;
380 sc->writereg = tels016_write_reg;
382 sc->readfifo = tels016_read_fifo;
383 sc->writefifo = tels016_write_fifo;
385 /* setup card type */
387 sc->sc_cardtyp= CARD_TYPEP_16;
389 /* setup IOM bus type */
391 sc->sc_bustyp = BUS_TYPE_IOM1;
393 sc->sc_ipac = 0;
394 sc->sc_bfifolen = HSCX_FIFO_LEN;
396 #endif
398 #ifdef __FreeBSD__
399 if((irq = intr_no[ffs(dev->id_irq) - 1]) == 1)
401 printf("isic%d: Attach error, invalid IRQ [%d] specified for Teles S0/16!\n",
402 dev->id_unit, ffs(dev->id_irq)-1);
403 return(0);
405 #else
406 irq = intr_no[sc->sc_irq];
407 #endif
409 /* configure IRQ */
411 #ifdef __FreeBSD__
412 irq |= ((u_long) sc->sc_vmem_addr) >> 9;
414 DELAY(SEC_DELAY / 10);
415 outb(sc->sc_port + 4, irq);
417 DELAY(SEC_DELAY / 10);
418 outb(sc->sc_port + 4, irq | 0x01);
420 DELAY(SEC_DELAY / 5);
422 /* set card bit off */
424 sc->sc_vmem_addr[0x80] = 0;
425 DELAY(SEC_DELAY / 5);
427 /* set card bit on */
429 sc->sc_vmem_addr[0x80] = 1;
430 DELAY(SEC_DELAY / 5);
432 #else
434 irq |= ((sc->sc_maddr >> 9) & 0x000000f0);
436 DELAY(SEC_DELAY / 10);
437 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 4, irq);
439 DELAY(SEC_DELAY / 10);
440 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 4, irq | 0x01);
442 DELAY(SEC_DELAY / 5);
444 /* set card bit off */
446 bus_space_write_1(sc->sc_maps[1].t, sc->sc_maps[1].h, 0x80, 0);
447 DELAY(SEC_DELAY / 5);
449 /* set card bit on */
451 bus_space_write_1(sc->sc_maps[1].t, sc->sc_maps[1].h, 0x80, 1);
452 DELAY(SEC_DELAY / 5);
453 #endif
455 return (1);
458 #endif /* ISICISA_TEL_S0_16 */