Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / isapnp / isic_isapnp_drn_ngo.c
blobe8389f8bc5e9d44beba9db3c10a96426778d034c
1 /*
2 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
25 *---------------------------------------------------------------------------
27 * i4b_drn_ngo.c - Dr. Neuhaus Niccy GO@ and SAGEM Cybermod
28 * --------------------------------------------------------
30 * $Id: isic_isapnp_drn_ngo.c,v 1.10 2007/10/19 12:00:32 ad Exp $
32 * last edit-date: [Fri Jan 5 11:38:29 2001]
34 *---------------------------------------------------------------------------*/
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: isic_isapnp_drn_ngo.c,v 1.9 2007/03/04 06:02:13 christos Exp $");
39 #include "opt_isicpnp.h"
40 #ifdef ISICPNP_DRN_NGO
42 #include <sys/param.h>
43 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
44 #include <sys/ioccom.h>
45 #else
46 #include <sys/ioctl.h>
47 #endif
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 #include <sys/mbuf.h>
52 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
53 #include <sys/callout.h>
54 #endif
56 #ifdef __FreeBSD__
57 #include <machine/clock.h>
58 #include <i386/isa/isa_device.h>
59 #else
60 #include <sys/bus.h>
61 #include <sys/device.h>
62 #endif
64 #include <sys/socket.h>
65 #include <net/if.h>
67 #ifdef __FreeBSD__
68 #include <machine/i4b_debug.h>
69 #include <machine/i4b_ioctl.h>
70 #else
71 #include <netisdn/i4b_debug.h>
72 #include <netisdn/i4b_ioctl.h>
73 #endif
75 #include <netisdn/i4b_global.h>
76 #include <netisdn/i4b_l2.h>
77 #include <netisdn/i4b_l1l2.h>
79 #include <dev/ic/isic_l1.h>
80 #include <dev/ic/isac.h>
81 #include <dev/ic/hscx.h>
83 /*---------------------------------------------------------------------------*
84 * Niccy GO@ definitions
86 * the card uses 2 i/o addressranges each using 2 bytes
88 * addressrange 0:
89 * offset 0 - ISAC dataregister
90 * offset 1 - HSCX dataregister
91 * addressrange 1:
92 * offset 0 - ISAC addressregister
93 * offset 1 - HSCX addressregister
95 * to access an ISAC/HSCX register, you have to write the register
96 * number into the ISAC or HSCX addressregister and then read/write
97 * data for the ISAC/HSCX register into/from the corresponding
98 * dataregister.
100 * Thanks to Klaus Muehle of Dr. Neuhaus Telekommunikation for giving
101 * out this information!
103 *---------------------------------------------------------------------------*/
104 #define NICCY_PORT_MIN 0x200
105 #define NICCY_PORT_MAX 0x3e0
107 #define HSCX_ABIT 0x1000 /* flag, HSCX A is meant */
108 #define HSCX_BBIT 0x2000 /* flag, HSCX B is meant */
110 #define HSCX_BOFF 0x40
112 #define ADDR_OFF 2 /* address register range offset XXX */
114 #define ISAC_DATA 0
115 #define HSCX_DATA 1
117 #define ISAC_ADDR 0
118 #define HSCX_ADDR 1
120 #ifdef __FreeBSD__
122 #if 0
123 #define HSCXADEBUG
124 #define HSCXBDEBUG
125 #define ISACDEBUG
126 #else
127 #undef HSCXADEBUG
128 #undef HSCXBDEBUG
129 #undef ISACDEBUG
130 #endif
132 /*---------------------------------------------------------------------------*
133 * Dr. Neuhaus Niccy GO@ read fifo routine
134 *---------------------------------------------------------------------------*/
135 static void
136 drnngo_read_fifo(void *buf, const void *base, size_t len)
138 register int offset;
139 register u_int data;
141 int x = SPLI4B();
143 if((u_int)base & HSCX_ABIT)
145 (u_int)base &= ~HSCX_ABIT;
146 (u_int)data = ((u_int)base + HSCX_DATA);
147 (u_int)base += (ADDR_OFF + HSCX_ADDR);
148 offset = 0;
149 #ifdef HSCXADEBUG
150 printf("GO/A/frd: base=0x%x, data=0x%x, len=%d\n", base, data, len);
151 #endif
153 else if((u_int)base & HSCX_BBIT)
155 (u_int)base &= ~HSCX_BBIT;
156 (u_int)data = ((u_int)base + HSCX_DATA);
157 (u_int)base += (ADDR_OFF + HSCX_ADDR);
158 offset = HSCX_BOFF;
159 #ifdef HSCXBDEBUG
160 printf("GO/B/frd: base=0x%x, data=0x%x, len=%d\n", base, data, len);
161 #endif
163 else
165 (u_int)data = ((u_int)base + ISAC_DATA);
166 (u_int)base += (ADDR_OFF + ISAC_ADDR);
167 offset = 0;
168 #ifdef ISACDEBUG
169 printf("GO/I/frd: base=0x%x, data=0x%x, len=%d\n", base, data, len);
170 #endif
173 for(;len > 0; len--, offset++)
175 outb((int)base, (u_char)offset);
176 *((u_char *)buf + offset) = inb((int)data);
179 splx(x);
182 /*---------------------------------------------------------------------------*
183 * Dr. Neuhaus Niccy GO@ write fifo routine
184 *---------------------------------------------------------------------------*/
185 static void
186 drnngo_write_fifo(void *base, const void *buf, size_t len)
188 register int offset;
189 register u_int data;
191 int x = SPLI4B();
193 if((u_int)base & HSCX_ABIT)
195 (u_int)base &= ~HSCX_ABIT;
196 (u_int)data = ((u_int)base + HSCX_DATA);
197 (u_int)base += (ADDR_OFF + HSCX_ADDR);
198 offset = 0;
199 #ifdef HSCXADEBUG
200 printf("GO/A/fwr: base=0x%x, data=0x%x, len=%d\n", base, data, len);
201 #endif
203 else if((u_int)base & HSCX_BBIT)
205 (u_int)base &= ~HSCX_BBIT;
206 (u_int)data = ((u_int)base + HSCX_DATA);
207 (u_int)base += (ADDR_OFF + HSCX_ADDR);
208 offset = HSCX_BOFF;
209 #ifdef HSCXBDEBUG
210 printf("GO/B/fwr: base=0x%x, data=0x%x, len=%d\n", base, data, len);
211 #endif
213 else
215 (u_int)data = ((u_int)base + ISAC_DATA);
216 (u_int)base += (ADDR_OFF + ISAC_ADDR);
217 offset = 0;
218 #ifdef ISACDEBUG
219 printf("GO/I/fwr: base=0x%x, data=0x%x, len=%d\n", base, data, len);
220 #endif
223 for(;len > 0; len--, offset++)
225 outb((int)base, (u_char)offset);
226 outb((int)data, *((u_char *)buf + offset));
229 splx(x);
232 /*---------------------------------------------------------------------------*
233 * Dr. Neuhaus Niccy GO@ write register routine
234 *---------------------------------------------------------------------------*/
235 static void
236 drnngo_write_reg(u_char *base, u_int offset, u_int v)
238 int x = SPLI4B();
239 if((u_int)base & HSCX_ABIT)
241 (u_int)base &= ~HSCX_ABIT;
242 outb((int)base + ADDR_OFF + HSCX_ADDR, (u_char)offset);
243 outb((int)base + HSCX_DATA, (u_char)v);
244 #ifdef HSCXADEBUG
245 printf("GO/A/rwr: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
246 (int)base + ADDR_OFF + HSCX_ADDR, (int)base + HSCX_DATA,
247 (u_char)offset, (u_char)v);
248 #endif
250 else if((u_int)base & HSCX_BBIT)
252 (u_int)base &= ~HSCX_BBIT;
253 outb((int)base + ADDR_OFF + HSCX_ADDR, (u_char)(offset + HSCX_BOFF));
254 outb((int)base + HSCX_DATA, (u_char)v);
255 #ifdef HSCXBDEBUG
256 printf("GO/B/rwr: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
257 (int)base + ADDR_OFF + HSCX_ADDR, (int)base + HSCX_DATA,
258 (u_char)(offset + HSCX_BOFF), (u_char)v);
259 #endif
261 else
263 outb((int)base + ADDR_OFF + ISAC_ADDR, (u_char)offset);
264 outb((int)base + ISAC_DATA, (u_char)v);
265 #ifdef ISACDEBUG
266 printf("GO/I/rwr: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
267 (int)base + ADDR_OFF + ISAC_ADDR, (int)base + ISAC_DATA,
268 (u_char)offset, (u_char)v);
269 #endif
271 splx(x);
274 /*---------------------------------------------------------------------------*
275 * Dr. Neuhaus Niccy GO@ read register routine
276 *---------------------------------------------------------------------------*/
277 static u_char
278 drnngo_read_reg(u_char *base, u_int offset)
280 u_char val;
281 int x = SPLI4B();
283 if((u_int)base & HSCX_ABIT)
285 (u_int)base &= ~HSCX_ABIT;
286 outb((int)base + ADDR_OFF + HSCX_ADDR, (u_char)offset);
287 val = inb((int)base + HSCX_DATA);
288 #ifdef HSCXADEBUG
289 printf("GO/A/rrd: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
290 (int)base + ADDR_OFF + HSCX_ADDR, (int)base + HSCX_DATA,
291 (u_char)offset, (u_char)val);
292 #endif
294 else if((u_int)base & HSCX_BBIT)
296 (u_int)base &= ~HSCX_BBIT;
297 outb((int)base + ADDR_OFF + HSCX_ADDR, (u_char)(offset + HSCX_BOFF));
298 val = inb((int)base + HSCX_DATA);
299 #ifdef HSCXBDEBUG
300 printf("GO/B/rrd: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
301 (int)base + ADDR_OFF + HSCX_ADDR, (int)base + HSCX_DATA,
302 (u_char)(offset + HSCX_BOFF), (u_char)val);
303 #endif
305 else
307 outb((int)base + ADDR_OFF + ISAC_ADDR, (u_char)offset);
308 val = inb((int)base + ISAC_DATA);
309 #ifdef ISACDEBUG
310 printf("GO/I/rrd: base=0x%x, addr=0x%x, offset=0x%x, val=0x%x\n",
311 (int)base + ADDR_OFF + ISAC_ADDR, (int)base + ISAC_DATA,
312 (u_char)offset, (u_char)val);
313 #endif
315 splx(x);
316 return(val);
319 /*---------------------------------------------------------------------------*
320 * isic_probe_drnngo - probe for Dr. Neuhaus Niccy GO@
321 *---------------------------------------------------------------------------*/
323 isic_probe_drnngo(struct isa_device *dev, unsigned int iobase2)
325 struct isic_softc *sc = &l1_sc[dev->id_unit];
327 /* check max unit range */
329 if(dev->id_unit >= ISIC_MAXUNIT)
331 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Dr. Neuhaus Niccy GO@!\n",
332 dev->id_unit, dev->id_unit);
333 return(0);
335 sc->sc_unit = dev->id_unit;
337 /* check IRQ validity */
339 switch(ffs(dev->id_irq)-1)
341 case 3:
342 case 4:
343 case 5:
344 case 9:
345 case 10:
346 case 11:
347 case 12:
348 case 15:
349 break;
351 default:
352 printf("isic%d: Error, invalid IRQ [%d] specified for Dr. Neuhaus Niccy GO@!\n",
353 dev->id_unit, ffs(dev->id_irq)-1);
354 return(0);
355 break;
357 sc->sc_irq = dev->id_irq;
359 /* check if memory addr specified */
361 if(dev->id_maddr)
363 printf("isic%d: Error, mem addr 0x%lx specified for Dr. Neuhaus Niccy GO@!\n",
364 dev->id_unit, (u_long)dev->id_maddr);
365 return(0);
367 dev->id_msize = 0;
369 /* check if we got an iobase */
371 if(dev->id_iobase < NICCY_PORT_MIN || dev->id_iobase > NICCY_PORT_MAX)
373 printf("isic%d: Error, invalid iobase 0x%x specified for Dr. Neuhaus Niccy GO@!\n",
374 dev->id_unit, dev->id_iobase);
375 return(0);
377 sc->sc_port = dev->id_iobase;
379 if(iobase2 == 0)
381 printf("isic%d: Error, iobase2 is 0 for Dr. Neuhaus Niccy GO@!\n",
382 dev->id_unit);
383 return(0);
386 if(iobase2 < NICCY_PORT_MIN || iobase2 > NICCY_PORT_MAX)
388 printf("isic%d: Error, invalid port1 0x%x specified for Dr. Neuhaus Niccy GO@!\n",
389 dev->id_unit, iobase2);
390 return(0);
393 /*XXX*/ if((dev->id_iobase + 2) != iobase2)
395 printf("isic%d: Error, port1 must be (port0+2) for Dr.Neuhaus Niccy GO@!\n",
396 dev->id_unit);
397 return(0);
400 /* setup ISAC access routines */
402 sc->clearirq = NULL;
403 sc->readreg = drnngo_read_reg;
404 sc->writereg = drnngo_write_reg;
406 sc->readfifo = drnngo_read_fifo;
407 sc->writefifo = drnngo_write_fifo;
409 /* setup card type */
411 sc->sc_cardtyp = CARD_TYPEP_DRNNGO;
413 /* setup IOM bus type */
415 sc->sc_bustyp = BUS_TYPE_IOM2;
417 sc->sc_ipac = 0;
418 sc->sc_bfifolen = HSCX_FIFO_LEN;
420 /* setup ISAC and HSCX base addr */
422 ISAC_BASE = (void *)dev->id_iobase;
423 HSCX_A_BASE = (void *)(((u_int)dev->id_iobase) | HSCX_ABIT);
424 HSCX_B_BASE = (void *)(((u_int)dev->id_iobase) | HSCX_BBIT);
427 * Read HSCX A/B VSTR. Expected value for Dr. Neuhaus Niccy GO@ based
428 * boards is 0x05 in the least significant bits.
431 if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
432 ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
434 printf("isic%d: HSCX VSTR test failed for Dr. Neuhaus Niccy GO@\n",
435 dev->id_unit);
436 printf("isic%d: HSC0: VSTR: %#x\n",
437 dev->id_unit, HSCX_READ(0, H_VSTR));
438 printf("isic%d: HSC1: VSTR: %#x\n",
439 dev->id_unit, HSCX_READ(1, H_VSTR));
440 return (0);
443 return (1);
446 /*---------------------------------------------------------------------------*
447 * isic_attach_drnngo - attach Dr. Neuhaus Niccy GO@
448 *---------------------------------------------------------------------------*/
450 isic_attach_drnngo(struct isa_device *dev, unsigned int iobase2)
452 return (1);
455 #else
457 static u_int8_t drnngo_read_reg(struct isic_softc *sc, int what, bus_size_t offs);
458 static void drnngo_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
459 static void drnngo_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
460 static void drnngo_write_fifo(struct isic_softc *sc, int what, const void *data, size_t size);
461 void isic_attach_drnngo(struct isic_softc *sc);
464 * Mapping from "what" parameter to offsets into the io map
466 static struct {
467 bus_size_t oa, /* address register offset */
468 od, /* data register offset */
469 or; /* additional chip register offset */
470 } offset[] =
472 { ISAC_ADDR, ISAC_DATA, 0 }, /* ISAC access */
473 { HSCX_ADDR, HSCX_DATA, 0 }, /* HSCX A access */
474 { HSCX_ADDR, HSCX_DATA, HSCX_BOFF } /* HSCX B access */
477 static void
478 drnngo_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
480 bus_space_tag_t t = sc->sc_maps[0].t;
481 bus_space_handle_t hd = sc->sc_maps[0].h, ha = sc->sc_maps[1].h;
482 bus_space_write_1(t, ha, offset[what].oa, offset[what].or);
483 bus_space_read_multi_1(t, hd, offset[what].od, buf, size);
486 static void
487 drnngo_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
489 bus_space_tag_t t = sc->sc_maps[0].t;
490 bus_space_handle_t hd = sc->sc_maps[0].h, ha = sc->sc_maps[1].h;
491 bus_space_write_1(t, ha, offset[what].oa, offset[what].or);
492 bus_space_write_multi_1(t, hd, offset[what].od, buf, size);
495 static void
496 drnngo_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
498 bus_space_tag_t t = sc->sc_maps[0].t;
499 bus_space_handle_t hd = sc->sc_maps[0].h, ha = sc->sc_maps[1].h;
500 bus_space_write_1(t, ha, offset[what].oa, offs+offset[what].or);
501 bus_space_write_1(t, hd, offset[what].od, data);
504 static u_int8_t
505 drnngo_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
507 bus_space_tag_t t = sc->sc_maps[0].t;
508 bus_space_handle_t hd = sc->sc_maps[0].h, ha = sc->sc_maps[1].h;
509 bus_space_write_1(t, ha, offset[what].oa, offs+offset[what].or);
510 return bus_space_read_1(t, hd, offset[what].od);
513 void
514 isic_attach_drnngo(struct isic_softc *sc)
516 /* setup access routines */
518 sc->clearirq = NULL;
519 sc->readreg = drnngo_read_reg;
520 sc->writereg = drnngo_write_reg;
522 sc->readfifo = drnngo_read_fifo;
523 sc->writefifo = drnngo_write_fifo;
525 /* setup card type */
527 sc->sc_cardtyp = CARD_TYPEP_DRNNGO;
529 /* setup IOM bus type */
531 sc->sc_bustyp = BUS_TYPE_IOM2;
533 sc->sc_ipac = 0;
534 sc->sc_bfifolen = HSCX_FIFO_LEN;
537 #endif
539 #endif /* ISICPNP_DRN_NGO */