kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / net / i4b / layer1 / isic / i4b_asuscom_ipac.c
1 /*
2  * Copyright (c) 1999 Ari Suutari. All rights reserved.
3  *
4  * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *---------------------------------------------------------------------------
28  *
29  *      isic - I4B Siemens ISDN Chipset Driver for Asuscom ISDNlink 128K PnP
30  *      =====================================================================
31  *
32  *      This driver works with Asuscom ISDNlink 128K PnP ISA adapter,
33  *      which is based on Siemens IPAC chip (my card probes as ASU1690).
34  *      Older Asuscom ISA cards are based on different chipset
35  *      (containing two chips) - for those cards, one might want
36  *      to try the Dynalink driver.
37  *
38  *      This driver is heavily based on ELSA Quickstep 1000pro PCI
39  *      driver written by Hellmuth Michaelis. Card initialization
40  *      code is modeled after Linux i4l driver written by Karsten
41  *      Keil.
42  *
43  * $FreeBSD: src/sys/i4b/layer1/isic/i4b_asuscom_ipac.c,v 1.5.2.1 2001/08/10 14:08:38 obrien Exp $
44  * $DragonFly: src/sys/net/i4b/layer1/isic/i4b_asuscom_ipac.c,v 1.3 2003/08/07 21:17:26 dillon Exp $
45  *
46  *      last edit-date: [Wed Jan 24 09:06:30 2001]
47  *
48  *---------------------------------------------------------------------------*/
49
50 #include "use_isic.h"
51 #include "opt_i4b.h"
52
53 #if (NISIC > 0) && defined (ASUSCOM_IPAC)
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/socket.h>
58 #include <net/if.h>
59
60 #include <machine/i4b_ioctl.h>
61 #include "i4b_isic.h"
62 #include "i4b_ipac.h"
63
64 /* masks for register encoded in base addr */
65
66 #define ASI_BASE_MASK           0x0ffff
67 #define ASI_OFF_MASK            0xf0000
68
69 /* register id's to be encoded in base addr */
70
71 #define ASI_IDISAC              0x00000
72 #define ASI_IDHSCXA             0x10000
73 #define ASI_IDHSCXB             0x20000
74 #define ASI_IDIPAC              0x40000
75
76 /* offsets from base address */
77
78 #define ASI_OFF_ALE             0x00
79 #define ASI_OFF_RW              0x01
80
81 /*---------------------------------------------------------------------------*
82  *      Asuscom ISDNlink 128K ISAC get fifo routine
83  *---------------------------------------------------------------------------*/
84 static void 
85 asi_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
86 {
87         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
88         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
89
90         switch ( what )
91         {
92                 case ISIC_WHAT_ISAC:
93                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_ISAC_OFF);
94                         bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size);
95                         break;
96                 case ISIC_WHAT_HSCXA:
97                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF);
98                         bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size);
99                         break;
100                 case ISIC_WHAT_HSCXB:
101                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF);
102                         bus_space_read_multi_1(t,h,ASI_OFF_RW,buf,size);
103                         break;
104         }
105 }
106
107 /*---------------------------------------------------------------------------*
108  *      Asuscom ISDNlink 128K ISAC put fifo routine
109  *---------------------------------------------------------------------------*/
110 static void 
111 asi_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
112 {
113         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
114         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
115
116         switch ( what )
117         {
118                 case ISIC_WHAT_ISAC:
119                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_ISAC_OFF);
120                         bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size);
121                         break;
122                 case ISIC_WHAT_HSCXA:
123                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXA_OFF);
124                         bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size);
125                         break;
126                 case ISIC_WHAT_HSCXB:
127                         bus_space_write_1(t,h,ASI_OFF_ALE,IPAC_HSCXB_OFF);
128                         bus_space_write_multi_1(t,h,ASI_OFF_RW,buf,size);
129                         break;
130         }
131 }
132
133 /*---------------------------------------------------------------------------*
134  *      Asuscom ISDNlink 128K ISAC put register routine
135  *---------------------------------------------------------------------------*/
136 static void
137 asi_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
138 {
139         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
140         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
141
142         switch ( what )
143         {
144                 case ISIC_WHAT_ISAC:
145                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_ISAC_OFF);
146                         bus_space_write_1(t,h,ASI_OFF_RW,data);
147                         break;
148                 case ISIC_WHAT_HSCXA:
149                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF);
150                         bus_space_write_1(t,h,ASI_OFF_RW,data);
151                         break;
152                 case ISIC_WHAT_HSCXB:
153                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF);
154                         bus_space_write_1(t,h,ASI_OFF_RW,data);
155                         break;
156                 case ISIC_WHAT_IPAC:
157                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF);
158                         bus_space_write_1(t,h,ASI_OFF_RW,data);
159                         break;
160         }
161 }
162
163 /*---------------------------------------------------------------------------*
164  *      Asuscom ISDNlink 128K ISAC get register routine
165  *---------------------------------------------------------------------------*/
166 static u_int8_t
167 asi_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
168 {
169         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
170         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
171
172         switch ( what )
173         {
174                 case ISIC_WHAT_ISAC:
175                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_ISAC_OFF);
176                         return bus_space_read_1(t,h,ASI_OFF_RW);
177                 case ISIC_WHAT_HSCXA:
178                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXA_OFF);
179                         return bus_space_read_1(t,h,ASI_OFF_RW);
180                 case ISIC_WHAT_HSCXB:
181                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_HSCXB_OFF);
182                         return bus_space_read_1(t,h,ASI_OFF_RW);
183                 case ISIC_WHAT_IPAC:
184                         bus_space_write_1(t,h,ASI_OFF_ALE,reg+IPAC_IPAC_OFF);
185                         return bus_space_read_1(t,h,ASI_OFF_RW);
186                 default:
187                         return 0;
188         }
189 }
190
191 /*---------------------------------------------------------------------------*
192  *      isic_attach_siemens_isurf - attach for Asuscom ISDNlink 128K
193  *---------------------------------------------------------------------------*/
194 int
195 isic_attach_asi(device_t dev)
196 {
197         int unit = device_get_unit(dev);
198         struct l1_softc *sc = &l1_sc[unit];     
199         
200         /* setup access routines */
201
202         sc->clearirq = NULL;
203         sc->readreg = asi_read_reg;
204         sc->writereg = asi_write_reg;
205
206         sc->readfifo = asi_read_fifo;
207         sc->writefifo = asi_write_fifo;
208
209         /* setup card type */
210         
211         sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC;
212
213         /* setup IOM bus type */
214         
215         sc->sc_bustyp = BUS_TYPE_IOM2;
216
217         /* setup chip type = IPAC ! */
218         
219         sc->sc_ipac = 1;
220         sc->sc_bfifolen = IPAC_BFIFO_LEN;
221
222         /* enable hscx/isac irq's */
223 /*
224  * This has been taken from Linux driver.
225  * (Removed initialization that was not applicaple to
226  * this board or was already register default setting.)
227  */
228         IPAC_WRITE (IPAC_ACFG, 0xff);   /* Setup AUX pin modes          */
229         IPAC_WRITE (IPAC_AOE, 0x0);     /* Setup AUX pin modes          */
230         IPAC_WRITE (IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
231
232         return(0);
233 }
234 #endif /* (NISIC > 0) && defined (ASUSCOM_IPAC) */