]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i4b/layer1/i4b_tel_s08.c
This commit was generated by cvs2svn to compensate for changes in r56067,
[FreeBSD/FreeBSD.git] / sys / i4b / layer1 / i4b_tel_s08.c
1 /*
2  *   Copyright (c) 1996 Arne Helme. All rights reserved.
3  *
4  *   Copyright (c) 1996 Gary Jennejohn. All rights reserved. 
5  *
6  *   Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
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.
22  *   
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.
34  *
35  *---------------------------------------------------------------------------
36  *
37  *      isic - I4B Siemens ISDN Chipset Driver for Teles S0/8 and clones
38  *      ================================================================
39  *
40  *      $Id: i4b_tel_s08.c,v 1.2 1999/12/13 21:25:27 hm Exp $ 
41  *
42  * $FreeBSD$
43  *
44  *      last edit-date: [Mon Dec 13 22:03:06 1999]
45  *
46  *---------------------------------------------------------------------------*/
47
48 #include "isic.h"
49 #include "opt_i4b.h"
50
51 #if NISIC > 0 && defined(TEL_S0_8)
52
53 #include <sys/param.h>
54 #include <sys/ioccom.h>
55 #include <sys/kernel.h>
56 #include <sys/systm.h>
57 #include <sys/mbuf.h>
58 #include <sys/socket.h>
59
60 #include <machine/clock.h>
61 #include <machine/md_var.h>
62
63 #include <net/if.h>
64
65 #include <machine/i4b_debug.h>
66 #include <machine/i4b_ioctl.h>
67
68 #include <i4b/layer1/i4b_l1.h>
69 #include <i4b/layer1/i4b_isac.h>
70 #include <i4b/layer1/i4b_hscx.h>
71
72 #include <i4b/include/i4b_global.h>
73 #include <i4b/include/i4b_l1l2.h>
74 #include <i4b/include/i4b_mbuf.h>
75
76 #define TELES_S08_MEMSIZE 0x1000
77
78 static const bus_size_t offset[] = { 0x100, 0x180, 0x1c0 };
79
80 /*---------------------------------------------------------------------------*
81  *      Teles S0/8 write register routine
82  *---------------------------------------------------------------------------*/
83 static void
84 tels08_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
85 {
86         bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem);
87         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
88
89         offs += offset[what];
90
91         if (offs & 0x01)
92                 offs |= 0x200;
93
94         bus_space_write_1(t, h, offs, data);
95 }
96
97 /*---------------------------------------------------------------------------*
98  *      Teles S0/8 read register routine
99  *---------------------------------------------------------------------------*/
100 static u_int8_t
101 tels08_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
102 {
103         bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem);
104         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
105
106         offs += offset[what];
107
108         if (offs & 0x01)
109                 offs |= 0x200;
110
111         return bus_space_read_1(t, h, offs);
112 }
113
114 /*---------------------------------------------------------------------------*
115  *      Teles S0/8 fifo write access
116  *---------------------------------------------------------------------------*/
117 static void
118 tels08_write_fifo(struct l1_softc *sc, int what, void *data, size_t size)
119 {
120         bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem);
121         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
122         bus_space_write_region_1(t, h, offset[what], data, size);
123 }
124
125 /*---------------------------------------------------------------------------*
126  *      Teles S0/8 fifo read access
127  *---------------------------------------------------------------------------*/
128 static void
129 tels08_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
130 {
131         bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem);
132         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
133         bus_space_read_region_1(t, h, offset[what], buf, size);
134 }
135
136 /*---------------------------------------------------------------------------*
137  *      isic_probe_s08 - probe for Teles S0/8 and compatibles
138  *---------------------------------------------------------------------------*/
139 int
140 isic_probe_s08(device_t dev)
141 {
142         size_t unit = device_get_unit(dev);     /* get unit */
143         struct l1_softc *sc = 0;                /* pointer to softc */
144         void *ih = 0;                           /* dummy */
145
146         /* check max unit range */
147
148         if(unit >= ISIC_MAXUNIT)
149         {
150                 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/8!\n",
151                                 unit, unit);
152                 return(ENXIO);  
153         }
154
155         sc = &l1_sc[unit];              /* get pointer to softc */
156
157         sc->sc_unit = unit;             /* set unit */
158
159         sc->sc_flags = FLAG_TELES_S0_8; /* set flags */
160
161         /* see if an io base was supplied */
162
163         if((sc->sc_resources.io_base[0] =
164                         bus_alloc_resource(dev, SYS_RES_IOPORT,
165                                            &sc->sc_resources.io_rid[0],
166                                            0ul, ~0ul, 1, RF_ACTIVE)))
167         {
168                 /* the S0/8 is completely memory mapped ! */
169                 
170                 bus_release_resource(dev,SYS_RES_IOPORT,
171                                      sc->sc_resources.io_rid[0],
172                                      sc->sc_resources.io_base[0]);
173                 printf("isic%d: Error, iobase specified for Teles S0/8!\n", unit);
174                 return(ENXIO);
175         }
176
177         /* allocate memory */
178
179         if(!(sc->sc_resources.mem =
180                 bus_alloc_resource(dev, SYS_RES_MEMORY,
181                                 &sc->sc_resources.mem_rid,
182                                 0ul, ~0ul, TELES_S08_MEMSIZE, RF_ACTIVE)))
183         {
184                 printf("isic%d: Could not allocate memory for Teles S0/8!\n", unit);
185                 return(ENXIO);
186         }
187
188         /* 
189          * get virtual addr. it's just needed to see if it is in
190          * the valid range
191          */
192
193         sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem);
194                 
195         /* check if inside memory range of 0xA0000 .. 0xDF000 */
196
197         if((kvtop(sc->sc_vmem_addr) < 0xa0000) ||
198            (kvtop(sc->sc_vmem_addr) > 0xdf000))
199         {
200                 printf("isic%d: Error, mem addr 0x%lx outside 0xA0000-0xDF000 for Teles S0/8!\n",
201                                 unit, kvtop(sc->sc_vmem_addr));
202                 bus_release_resource(dev,SYS_RES_MEMORY,
203                                      sc->sc_resources.mem_rid,
204                                      sc->sc_resources.mem);
205                 sc->sc_resources.mem = 0;
206                 return(ENXIO);
207         }
208         
209         /* setup ISAC access routines */
210
211         sc->clearirq = NULL;
212
213         sc->readreg = tels08_read_reg;
214         sc->writereg = tels08_write_reg;
215
216         sc->readfifo = tels08_read_fifo;
217         sc->writefifo = tels08_write_fifo;
218
219         sc->sc_cardtyp = CARD_TYPEP_8;          /* setup card type */
220         
221         sc->sc_bustyp = BUS_TYPE_IOM1;          /* setup IOM bus type */
222
223         sc->sc_ipac = 0;
224         sc->sc_bfifolen = HSCX_FIFO_LEN;
225
226         /* setup ISAC base addr, though we don't really need it */
227         
228         ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100);
229
230         /* setup HSCX base addr */
231         
232         HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180);
233         HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0);
234
235         /* allocate our irq */
236
237         if(!(sc->sc_resources.irq =
238                         bus_alloc_resource(dev, SYS_RES_IRQ,
239                                                 &sc->sc_resources.irq_rid,
240                                                 0ul, ~0ul, 1, RF_ACTIVE)))
241         {
242                 printf("isic%d: Could not allocate irq for Teles S0/8!\n",unit);
243
244                 bus_release_resource(dev,SYS_RES_MEMORY,
245                                      sc->sc_resources.mem_rid,
246                                      sc->sc_resources.mem);
247
248                 sc->sc_resources.mem = 0;
249                 return ENXIO;
250         }
251
252         /* get the irq number */
253
254         sc->sc_irq = rman_get_start(sc->sc_resources.irq);
255         
256         /* check IRQ validity */
257
258         switch(sc->sc_irq)
259         {
260                 case 2:
261                 case 9:         /* XXX */
262                 case 3:
263                 case 4:
264                 case 5:
265                 case 6:
266                 case 7:
267                         break;
268                         
269                 default:
270                         printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/8!\n",
271                                 unit, sc->sc_irq);
272                         bus_release_resource(dev,SYS_RES_IRQ,
273                                              sc->sc_resources.irq_rid,
274                                              sc->sc_resources.irq);
275                         sc->sc_resources.irq = 0;
276                         bus_release_resource(dev,SYS_RES_MEMORY,
277                                              sc->sc_resources.mem_rid,
278                                              sc->sc_resources.mem);
279                         sc->sc_resources.mem = 0;
280                         return(ENXIO);
281                         break;
282         }
283
284         /* register interupt routine */
285
286         bus_setup_intr(dev, sc->sc_resources.irq,
287                         INTR_TYPE_NET,
288                         (void(*)(void *))(isicintr),
289                         sc, &ih);
290
291         return (0);
292 }
293
294 /*---------------------------------------------------------------------------*
295  *      isic_attach_s08 - attach Teles S0/8 and compatibles
296  *---------------------------------------------------------------------------*/
297 int
298 isic_attach_s08(device_t dev)
299 {
300         struct l1_softc *sc = &l1_sc[device_get_unit(dev)];
301         bus_space_tag_t t = rman_get_bustag(sc->sc_resources.mem);
302         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.mem);
303
304         /* set card off */
305
306         bus_space_write_1(t, h, 0x80, 0);
307
308         DELAY(SEC_DELAY / 5);
309
310         /* set card on */
311
312         bus_space_write_1(t, h, 0x80, 1);
313
314         DELAY(SEC_DELAY / 5);
315
316         return 0;
317 }
318 #endif /* ISIC > 0 */