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
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
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]
45 * -hm checked with a Creatix ISDN-S0 (PCB version: mp 130.1)
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>
62 #include <sys/ioctl.h>
64 #include <sys/kernel.h>
65 #include <sys/systm.h>
68 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
69 #include <sys/callout.h>
73 #include <machine/clock.h>
74 #include <machine/md_var.h>
75 #include <i386/isa/isa_device.h>
78 #include <sys/device.h>
81 #include <sys/socket.h>
85 #include <machine/i4b_debug.h>
86 #include <machine/i4b_ioctl.h>
88 #include <netisdn/i4b_debug.h>
89 #include <netisdn/i4b_ioctl.h>
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 };
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
);
111 /*---------------------------------------------------------------------------*
112 * Teles S0/16 write register routine
113 *---------------------------------------------------------------------------*/
117 tels016_write_reg(u_char
*base
, u_int i
, u_int v
)
126 static const bus_size_t offset
[] = { 0x100, 0x180, 0x1c0 };
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
];
138 bus_space_write_1(t
, h
, offs
, data
);
142 /*---------------------------------------------------------------------------*
143 * Teles S0/16 read register routine
144 *---------------------------------------------------------------------------*/
148 tels016_read_reg(u_char
*base
, u_int i
)
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
];
168 return bus_space_read_1(t
, h
, offs
);
172 /*---------------------------------------------------------------------------*
173 * Teles S0/16 fifo read/write routines
174 *---------------------------------------------------------------------------*/
178 tels016_memcpyb(void *to
, const void *from
, size_t len
)
181 *((unsigned char *)to
)++ = *((unsigned char *)from
)++;
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
);
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
);
203 /*---------------------------------------------------------------------------*
204 * isic_probe_s016 - probe for Teles S0/16 and compatibles
205 *---------------------------------------------------------------------------*/
208 isic_probe_s016(struct isa_device
*dev
)
210 struct isic_softc
*sc
= &l1_sc
[dev
->id_unit
];
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
);
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);
231 sc
->sc_irq
= dev
->id_irq
;
233 /* check if we got an iobase */
235 switch(dev
->id_iobase
)
243 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n",
244 dev
->id_unit
, dev
->id_iobase
);
248 sc
->sc_port
= dev
->id_iobase
;
250 /* check if valid memory addr */
252 switch((unsigned int)kvtop(dev
->id_maddr
))
273 printf("isic%d: Error, invalid mem addr 0x%lx for Teles S0/16!\n",
274 dev
->id_unit
, kvtop(dev
->id_maddr
));
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",
290 if((byte
= inb(sc
->sc_port
+ 1)) != 0x93)
292 printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n",
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",
306 /* setup access routines */
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
;
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);
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
;
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))
358 /*---------------------------------------------------------------------------*
359 * isic_attach_s016 - attach Teles S0/16 and compatibles
360 *---------------------------------------------------------------------------*/
363 isic_attach_s016(struct isa_device
*dev
)
365 isic_attach_s016(struct isic_softc
*sc
)
370 struct isic_softc
*sc
= &l1_sc
[dev
->id_unit
];
376 /* setup access routines */
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
;
394 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
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);
406 irq
= intr_no
[sc
->sc_irq
];
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);
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);
458 #endif /* ISICISA_TEL_S0_16 */