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/8 and clones
38 * ================================================================
40 * $Id: isic_isa_tel_s08.c,v 1.9 2007/10/19 12:00:19 ad Exp $
42 * last edit-date: [Fri Jan 5 11:37:22 2001]
46 * -hm NetBSD patches from Martin
47 * -hm making it finally work (checked with board revision 1.2)
48 * -hm converting asm -> C
50 *---------------------------------------------------------------------------*/
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: isic_isa_tel_s08.c,v 1.8 2007/03/04 06:02:12 christos Exp $");
55 #include "opt_isicisa.h"
56 #ifdef ISICISA_TEL_S0_8
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>
103 static u_int8_t
tels08_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
);
104 static void tels08_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
);
105 static void tels08_write_fifo(struct isic_softc
*sc
, int what
, const void *data
, size_t size
);
106 static void tels08_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
);
109 /*---------------------------------------------------------------------------*
110 * Teles S0/8 write register routine
111 *---------------------------------------------------------------------------*/
115 tels08_write_reg(u_char
*base
, u_int i
, u_int v
)
124 static const bus_size_t offset
[] = { 0x100, 0x180, 0x1c0 };
127 tels08_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
)
129 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
130 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
132 offs
+= offset
[what
];
137 bus_space_write_1(t
, h
, offs
, data
);
141 /*---------------------------------------------------------------------------*
142 * Teles S0/8 read register routine
143 *---------------------------------------------------------------------------*/
147 tels08_read_reg(u_char
*base
, u_int i
)
157 tels08_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
)
159 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
160 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
162 offs
+= offset
[what
];
167 return bus_space_read_1(t
, h
, offs
);
171 /*---------------------------------------------------------------------------*
172 * Teles S0/8 fifo read/write access
173 *---------------------------------------------------------------------------*/
177 tels08_memcpyb(void *to
, const void *from
, size_t len
)
180 *((unsigned char *)to
)++ = *((unsigned char *)from
)++;
186 tels08_write_fifo(struct isic_softc
*sc
, int what
, const void *data
, size_t size
)
188 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
189 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
190 bus_space_write_region_1(t
, h
, offset
[what
], data
, size
);
194 tels08_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
)
196 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
197 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
198 bus_space_read_region_1(t
, h
, offset
[what
], buf
, size
);
202 /*---------------------------------------------------------------------------*
203 * isic_probe_s08 - probe for Teles S0/8 and compatibles
204 *---------------------------------------------------------------------------*/
208 isic_probe_s08(struct isa_device
*dev
)
210 struct isic_softc
*sc
= &l1_sc
[dev
->id_unit
];
212 /* check max unit range */
214 if(dev
->id_unit
>= ISIC_MAXUNIT
)
216 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/8!\n",
217 dev
->id_unit
, dev
->id_unit
);
220 sc
->sc_unit
= dev
->id_unit
;
222 /* check IRQ validity */
224 switch(ffs(dev
->id_irq
)-1)
236 printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/8!\n",
237 dev
->id_unit
, ffs(dev
->id_irq
)-1);
241 sc
->sc_irq
= dev
->id_irq
;
243 /* check if we got an iobase */
245 if(dev
->id_iobase
> 0)
247 printf("isic%d: Error, iobase specified for Teles S0/8!\n",
252 /* check if inside memory range of 0xA0000 .. 0xDF000 */
254 if( (kvtop(dev
->id_maddr
) < 0xa0000) ||
255 (kvtop(dev
->id_maddr
) > 0xdf000) )
257 printf("isic%d: Error, mem addr 0x%lx outside 0xA0000-0xDF000 for Teles S0/8!\n",
258 dev
->id_unit
, kvtop(dev
->id_maddr
));
262 sc
->sc_vmem_addr
= (void *) dev
->id_maddr
;
263 dev
->id_msize
= 0x1000;
265 /* setup ISAC access routines */
268 sc
->readreg
= tels08_read_reg
;
269 sc
->writereg
= tels08_write_reg
;
271 sc
->readfifo
= tels08_memcpyb
;
272 sc
->writefifo
= tels08_memcpyb
;
274 /* setup card type */
276 sc
->sc_cardtyp
= CARD_TYPEP_8
;
278 /* setup IOM bus type */
280 sc
->sc_bustyp
= BUS_TYPE_IOM1
;
283 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
285 /* setup ISAC base addr */
287 ISAC_BASE
= (void *)((dev
->id_maddr
) + 0x100);
289 /* setup HSCX base addr */
291 HSCX_A_BASE
= (void *)((dev
->id_maddr
) + 0x180);
292 HSCX_B_BASE
= (void *)((dev
->id_maddr
) + 0x1c0);
300 isic_probe_s08(struct isic_attach_args
*ia
)
302 /* no real sensible probe is easy - write to fifo memory
303 and read back to verify there is memory doesn't work,
304 because you talk to tx fifo and rcv fifo. So, just check
305 HSCX version, which at least fails if no card present
306 at the given location. */
307 bus_space_tag_t t
= ia
->ia_maps
[0].t
;
308 bus_space_handle_t h
= ia
->ia_maps
[0].h
;
312 v1
= bus_space_read_1(t
, h
, offset
[1] + H_VSTR
) & 0x0f;
313 if (v1
!= HSCX_VA1
&& v1
!= HSCX_VA2
&& v1
!= HSCX_VA3
&& v1
!= HSCX_V21
)
317 v2
= bus_space_read_1(t
, h
, offset
[2] + H_VSTR
) & 0x0f;
318 if (v2
!= HSCX_VA1
&& v2
!= HSCX_VA2
&& v2
!= HSCX_VA3
&& v2
!= HSCX_V21
)
321 /* both HSCX channels should have the same version... */
329 /*---------------------------------------------------------------------------*
330 * isic_attach_s08 - attach Teles S0/8 and compatibles
331 *---------------------------------------------------------------------------*/
334 isic_attach_s08(struct isa_device
*dev
)
336 isic_attach_s08(struct isic_softc
*sc
)
340 struct isic_softc
*sc
= &l1_sc
[dev
->id_unit
];
342 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
343 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
349 sc
->sc_vmem_addr
[0x80] = 0;
351 bus_space_write_1(t
, h
, 0x80, 0);
354 DELAY(SEC_DELAY
/ 5);
359 sc
->sc_vmem_addr
[0x80] = 1;
361 bus_space_write_1(t
, h
, 0x80, 1);
364 DELAY(SEC_DELAY
/ 5);
368 /* setup ISAC access routines */
371 sc
->readreg
= tels08_read_reg
;
372 sc
->writereg
= tels08_write_reg
;
373 sc
->readfifo
= tels08_read_fifo
;
374 sc
->writefifo
= tels08_write_fifo
;
376 /* setup card type */
378 sc
->sc_cardtyp
= CARD_TYPEP_8
;
380 /* setup IOM bus type */
382 sc
->sc_bustyp
= BUS_TYPE_IOM1
;
385 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
392 #endif /* ISICISA_TEL_S0_8 */