1 /*-
2 * Copyright (c) 2002 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Martin Husemann <martin@NetBSD.org>.
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 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the NetBSD
19 * Foundation, Inc. and its contributors.
20 * 4. Neither the name of The NetBSD Foundation nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: isic_pcmcia_elsa_isdnmc.c,v 1.6 2003/12/04 13:57:31 keihan Exp $");
39
40 #include "opt_isicpcmcia.h"
41 #ifdef ISICPCMCIA_ELSA_ISDNMC
42
43 #include <sys/param.h>
44 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
45 #include <sys/ioccom.h>
46 #else
47 #include <sys/ioctl.h>
48 #endif
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
51 #include <sys/mbuf.h>
52
53 #ifdef __FreeBSD__
54 #include <machine/clock.h>
55 #include <i386/isa/isa_device.h>
56 #else
57 #include <machine/bus.h>
58 #include <sys/device.h>
59 #endif
60
61 #include <sys/socket.h>
62 #include <net/if.h>
63
64 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
65 #include <sys/callout.h>
66 #endif
67
68 #ifdef __FreeBSD__
69 #include <machine/i4b_debug.h>
70 #include <machine/i4b_ioctl.h>
71 #else
72 #include <netisdn/i4b_debug.h>
73 #include <netisdn/i4b_ioctl.h>
74
75 #include <dev/pcmcia/pcmciareg.h>
76 #include <dev/pcmcia/pcmciavar.h>
77 #endif
78
79 #include <netisdn/i4b_l2.h>
80 #include <netisdn/i4b_l1l2.h>
81 #include <dev/ic/isic_l1.h>
82 #include <dev/ic/isac.h>
83 #include <dev/ic/hscx.h>
84
85 #include <dev/pcmcia/isic_pcmcia.h>
86
87 #ifndef __FreeBSD__
88 /* PCMCIA support routines */
89 static u_int8_t elsa_isdnmc_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs));
90 static void elsa_isdnmc_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data));
91 static void elsa_isdnmc_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size));
92 static void elsa_isdnmc_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size));
93 static void elsa_isdnmc_clrirq __P((struct isic_softc *sc));
94 #endif
95
96 /*
97 * The ELSA MicroLink ISDN/MC uses one contigous IO region,
98 * mapped by the pcmcia code.
99 * The chip access is via three ports:
100 */
101 #define ISAC_DATA 1 /* ISAC dataport at offset 1 */
102 #define HSCX_DATA 2 /* HSCX dataport at offset 2 */
103 #define ADDR_LATCH 4 /* address latch at offset 4 */
104
105 /* This is very similar to the ELSA QuickStep 1000 (ISA) card */
106
107 #ifdef __FreeBSD__
108 static void
109 elsa_isdnmc_clrirq(void *base)
110 {
111 }
112 #else
113 static void
114 elsa_isdnmc_clrirq(struct isic_softc *sc)
115 {
116 ISAC_WRITE(I_MASK, 0xff);
117 HSCX_WRITE(0, H_MASK, 0xff);
118 HSCX_WRITE(1, H_MASK, 0xff);
119 ISAC_WRITE(I_MASK, ISAC_IMASK);
120 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
121 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
122 }
123 #endif
124
125 /*---------------------------------------------------------------------------*
126 * read fifo routines
127 *---------------------------------------------------------------------------*/
128 #ifdef __FreeBSD__
129 static void
130 elsa_isdnmc_read_fifo(void *buf, const void *base, size_t len)
131 {
132 }
133 #else
134 static void
135 elsa_isdnmc_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
136 {
137 bus_space_tag_t t = sc->sc_maps[0].t;
138 bus_space_handle_t h = sc->sc_maps[0].h;
139 switch (what) {
140 case ISIC_WHAT_ISAC:
141 bus_space_write_1(t, h, ADDR_LATCH, 0);
142 bus_space_read_multi_1(t, h, ISAC_DATA, buf, size);
143 break;
144 case ISIC_WHAT_HSCXA:
145 bus_space_write_1(t, h, ADDR_LATCH, 0);
146 bus_space_read_multi_1(t, h, HSCX_DATA, buf, size);
147 break;
148 case ISIC_WHAT_HSCXB:
149 bus_space_write_1(t, h, ADDR_LATCH, 0x40);
150 bus_space_read_multi_1(t, h, HSCX_DATA, buf, size);
151 break;
152 }
153 }
154 #endif
155
156 /*---------------------------------------------------------------------------*
157 * write fifo routines
158 *---------------------------------------------------------------------------*/
159 #ifdef __FreeBSD__
160 static void
161 elsa_isdnmc_write_fifo(void *base, const void *buf, size_t len)
162 {
163 }
164 #else
165 static void
166 elsa_isdnmc_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
167 {
168 bus_space_tag_t t = sc->sc_maps[0].t;
169 bus_space_handle_t h = sc->sc_maps[0].h;
170 switch (what) {
171 case ISIC_WHAT_ISAC:
172 bus_space_write_1(t, h, ADDR_LATCH, 0);
173 bus_space_write_multi_1(t, h, ISAC_DATA, (u_int8_t*)buf, size);
174 break;
175 case ISIC_WHAT_HSCXA:
176 bus_space_write_1(t, h, ADDR_LATCH, 0);
177 bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size);
178 break;
179 case ISIC_WHAT_HSCXB:
180 bus_space_write_1(t, h, ADDR_LATCH, 0x40);
181 bus_space_write_multi_1(t, h, HSCX_DATA, (u_int8_t*)buf, size);
182 break;
183 }
184 }
185 #endif
186
187 /*---------------------------------------------------------------------------*
188 * write register routines
189 *---------------------------------------------------------------------------*/
190 #ifdef __FreeBSD__
191 static void
192 elsa_isdnmc_write_reg(u_char *base, u_int offset, u_int v)
193 {
194 }
195 #else
196 static void
197 elsa_isdnmc_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
198 {
199 bus_space_tag_t t = sc->sc_maps[0].t;
200 bus_space_handle_t h = sc->sc_maps[0].h;
201 switch (what) {
202 case ISIC_WHAT_ISAC:
203 bus_space_write_1(t, h, ADDR_LATCH, offs);
204 bus_space_write_1(t, h, ISAC_DATA, data);
205 break;
206 case ISIC_WHAT_HSCXA:
207 bus_space_write_1(t, h, ADDR_LATCH, offs);
208 bus_space_write_1(t, h, HSCX_DATA, data);
209 break;
210 case ISIC_WHAT_HSCXB:
211 bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs);
212 bus_space_write_1(t, h, HSCX_DATA, data);
213 break;
214 }
215 }
216 #endif
217
218 /*---------------------------------------------------------------------------*
219 * read register routines
220 *---------------------------------------------------------------------------*/
221 #ifdef __FreeBSD__
222 static u_char
223 elsa_isdnmc_read_reg(u_char *base, u_int offset)
224 {
225 return 0;
226 }
227 #else
228 static u_int8_t
229 elsa_isdnmc_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
230 {
231 bus_space_tag_t t = sc->sc_maps[0].t;
232 bus_space_handle_t h = sc->sc_maps[0].h;
233 switch (what) {
234 case ISIC_WHAT_ISAC:
235 bus_space_write_1(t, h, ADDR_LATCH, offs);
236 return bus_space_read_1(t, h, ISAC_DATA);
237 case ISIC_WHAT_HSCXA:
238 bus_space_write_1(t, h, ADDR_LATCH, offs);
239 return bus_space_read_1(t, h, HSCX_DATA);
240 case ISIC_WHAT_HSCXB:
241 bus_space_write_1(t, h, ADDR_LATCH, 0x40+offs);
242 return bus_space_read_1(t, h, HSCX_DATA);
243 }
244 return 0;
245 }
246 #endif
247
248 #ifdef __FreeBSD__
249 #else
250
251 /*
252 * XXX - one time only! Some of this has to go into an enable
253 * function, with apropriate counterpart in disable, so a card
254 * could be removed an inserted again.
255 */
256 int
257 isic_attach_elsaisdnmc(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa)
258 {
259 struct isic_softc *sc = &psc->sc_isic;
260 bus_space_tag_t t;
261 bus_space_handle_t h;
262
263 /* Validate config info */
264 if (cfe->num_memspace != 0)
265 printf(": unexpected number of memory spaces %d should be 0\n",
266 cfe->num_memspace);
267 if (cfe->num_iospace != 1)
268 printf(": unexpected number of memory spaces %d should be 1\n",
269 cfe->num_iospace);
270
271 /* Allocate pcmcia space */
272 if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
273 cfe->iospace[0].length, &psc->sc_pcioh))
274 printf(": can't allocate i/o space\n");
275
276 /* map them */
277 if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
278 PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0,
279 cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
280 printf(": can't map i/o space\n");
281 return 0;
282 }
283
284 /* Setup bus space maps */
285 sc->sc_num_mappings = 1;
286 MALLOC_MAPS(sc);
287
288 /* Copy our handles/tags to the MI maps */
289 sc->sc_maps[0].t = psc->sc_pcioh.iot;
290 sc->sc_maps[0].h = psc->sc_pcioh.ioh;
291 sc->sc_maps[0].offset = 0;
292 sc->sc_maps[0].size = 0; /* not our mapping */
293
294 t = sc->sc_maps[0].t;
295 h = sc->sc_maps[0].h;
296
297 sc->clearirq = elsa_isdnmc_clrirq;
298
299 sc->readreg = elsa_isdnmc_read_reg;
300 sc->writereg = elsa_isdnmc_write_reg;
301
302 sc->readfifo = elsa_isdnmc_read_fifo;
303 sc->writefifo = elsa_isdnmc_write_fifo;
304
305 /* setup IOM bus type */
306
307 sc->sc_bustyp = BUS_TYPE_IOM2;
308
309 sc->sc_ipac = 0;
310 sc->sc_bfifolen = HSCX_FIFO_LEN;
311
312 return 1;
313 }
314 #endif
315
316 #endif /* ISICPCMCIA_ELSA_ISDNMC */
Cache object: a5615645103f0ec7c256c7efc6c9fff8
|