No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / isa / isic_isa_tel_s08.c
blob0a664a12eb777090d6fd2fa118f6a8b65d0e20c9
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/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]
44 * -hm clean up
45 * -hm more cleanup
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>
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 #ifndef __FreeBSD__
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);
107 #endif
109 /*---------------------------------------------------------------------------*
110 * Teles S0/8 write register routine
111 *---------------------------------------------------------------------------*/
112 #ifdef __FreeBSD__
114 static void
115 tels08_write_reg(u_char *base, u_int i, u_int v)
117 if(i & 0x01)
118 i |= 0x200;
119 base[i] = v;
122 #else
124 static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 };
126 static void
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];
134 if (offs & 0x01)
135 offs |= 0x200;
137 bus_space_write_1(t, h, offs, data);
139 #endif
141 /*---------------------------------------------------------------------------*
142 * Teles S0/8 read register routine
143 *---------------------------------------------------------------------------*/
144 #ifdef __FreeBSD__
146 static u_char
147 tels08_read_reg(u_char *base, u_int i)
149 if(i & 0x1)
150 i |= 0x200;
151 return(base[i]);
154 #else
156 static u_int8_t
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];
164 if (offs & 0x01)
165 offs |= 0x200;
167 return bus_space_read_1(t, h, offs);
169 #endif
171 /*---------------------------------------------------------------------------*
172 * Teles S0/8 fifo read/write access
173 *---------------------------------------------------------------------------*/
174 #ifdef __FreeBSD__
176 static void
177 tels08_memcpyb(void *to, const void *from, size_t len)
179 for(;len > 0; len--)
180 *((unsigned char *)to)++ = *((unsigned char *)from)++;
183 #else
185 static void
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);
193 static void
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);
200 #endif
202 /*---------------------------------------------------------------------------*
203 * isic_probe_s08 - probe for Teles S0/8 and compatibles
204 *---------------------------------------------------------------------------*/
205 #ifdef __FreeBSD__
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);
218 return(0);
220 sc->sc_unit = dev->id_unit;
222 /* check IRQ validity */
224 switch(ffs(dev->id_irq)-1)
226 case 2:
227 case 9: /* XXX */
228 case 3:
229 case 4:
230 case 5:
231 case 6:
232 case 7:
233 break;
235 default:
236 printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/8!\n",
237 dev->id_unit, ffs(dev->id_irq)-1);
238 return(0);
239 break;
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",
248 dev->id_unit);
249 return(0);
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));
259 return(0);
262 sc->sc_vmem_addr = (void *) dev->id_maddr;
263 dev->id_msize = 0x1000;
265 /* setup ISAC access routines */
267 sc->clearirq = NULL;
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;
282 sc->sc_ipac = 0;
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);
294 return (1);
297 #else
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;
309 u_int8_t v1, v2;
311 /* HSCX A VSTR */
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)
314 return 0;
316 /* HSCX B VSTR */
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)
319 return 0;
321 /* both HSCX channels should have the same version... */
322 if (v1 != v2)
323 return 0;
325 return 1;
327 #endif
329 /*---------------------------------------------------------------------------*
330 * isic_attach_s08 - attach Teles S0/8 and compatibles
331 *---------------------------------------------------------------------------*/
333 #ifdef __FreeBSD__
334 isic_attach_s08(struct isa_device *dev)
335 #else
336 isic_attach_s08(struct isic_softc *sc)
337 #endif
339 #ifdef __FreeBSD__
340 struct isic_softc *sc = &l1_sc[dev->id_unit];
341 #else
342 bus_space_tag_t t = sc->sc_maps[0].t;
343 bus_space_handle_t h = sc->sc_maps[0].h;
344 #endif
346 /* set card off */
348 #ifdef __FreeBSD__
349 sc->sc_vmem_addr[0x80] = 0;
350 #else
351 bus_space_write_1(t, h, 0x80, 0);
352 #endif
354 DELAY(SEC_DELAY / 5);
356 /* set card on */
358 #ifdef __FreeBSD__
359 sc->sc_vmem_addr[0x80] = 1;
360 #else
361 bus_space_write_1(t, h, 0x80, 1);
362 #endif
364 DELAY(SEC_DELAY / 5);
366 #ifndef __FreeBSD__
368 /* setup ISAC access routines */
370 sc->clearirq = NULL;
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;
384 sc->sc_ipac = 0;
385 sc->sc_bfifolen = HSCX_FIFO_LEN;
387 #endif
389 return (1);
392 #endif /* ISICISA_TEL_S0_8 */