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 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__KERNEL_RCSID(0, "$NetBSD: isic_pcmcia_sbspeedstar2.c,v 1.11 2007/10/19 12:01:06 ad Exp $"); 32 33#include "opt_isicpcmcia.h" 34#ifdef ISICPCMCIA_SBSPEEDSTAR2 35 36/* 37 * Card format: 38 * 39 * iobase + 0 : reset on (0x03), off (0x0) 40 * iobase + 1 : isac read/write 41 * iobase + 2 : hscx read/write ( offset 0-0x3f hscx0 , 42 * offset 0x40-0x7f hscx1 ) 43 * iobase + 4 : address register 44 * 45 */ 46 47#define SBSS_RESET 0 /* reset on / off */ 48#define SBSS_ISAC 1 /* ISAC */ 49#define SBSS_HSCX 2 /* HSCX0 */ 50#define SBSS_RW 4 /* indirect access register */ 51 52#define SBSS_REGS 8 /* we use an area of 8 bytes for io */ 53 54#include <sys/param.h> 55#include <sys/callout.h> 56#include <sys/kernel.h> 57#include <sys/systm.h> 58#include <sys/mbuf.h> 59#include <sys/device.h> 60#include <sys/bus.h> 61#include <sys/socket.h> 62#include <net/if.h> 63#include <netisdn/i4b_debug.h> 64#include <netisdn/i4b_ioctl.h> 65#include <netisdn/i4b_l2.h> 66#include <netisdn/i4b_l1l2.h> 67 68#include <dev/ic/isic_l1.h> 69#include <dev/ic/isac.h> 70#include <dev/ic/hscx.h> 71 72#include <netisdn/i4b_global.h> 73#include <netisdn/i4b_l1l2.h> 74#include <netisdn/i4b_mbuf.h> 75#include <dev/pcmcia/pcmciareg.h> 76#include <dev/pcmcia/pcmciavar.h> 77 78#include <dev/pcmcia/isic_pcmcia.h> 79 80/*---------------------------------------------------------------------------* 81 * Sedlbauer SpeedStar ISAC get fifo routine 82 *---------------------------------------------------------------------------*/ 83 84static void 85sws_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) 86{ 87 bus_space_tag_t t = sc->sc_maps[0].t; 88 bus_space_handle_t h = sc->sc_maps[0].h; 89 switch (what) { 90 case ISIC_WHAT_ISAC: 91 bus_space_write_1(t, h, SBSS_RW, 0); 92 bus_space_read_multi_1(t, h, SBSS_ISAC, buf, size); 93 break; 94 case ISIC_WHAT_HSCXA: 95 bus_space_write_1(t, h, SBSS_RW, 0); 96 bus_space_read_multi_1(t, h, SBSS_HSCX, buf, size); 97 break; 98 case ISIC_WHAT_HSCXB: 99 bus_space_write_1(t, h, SBSS_RW, 0x40); 100 bus_space_read_multi_1(t, h, SBSS_HSCX, buf, size); 101 break; 102 } 103} 104 105/*---------------------------------------------------------------------------* 106 * Sedlbauer SpeedStar ISAC put fifo routine 107 *---------------------------------------------------------------------------*/ 108 109static void 110sws_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) 111{ 112 bus_space_tag_t t = sc->sc_maps[0].t; 113 bus_space_handle_t h = sc->sc_maps[0].h; 114 switch (what) { 115 case ISIC_WHAT_ISAC: 116 bus_space_write_1(t, h, SBSS_RW, 0); 117 bus_space_write_multi_1(t, h, SBSS_ISAC, buf, size); 118 break; 119 case ISIC_WHAT_HSCXA: 120 bus_space_write_1(t, h, SBSS_RW, 0); 121 bus_space_write_multi_1(t, h, SBSS_HSCX, buf, size); 122 break; 123 case ISIC_WHAT_HSCXB: 124 bus_space_write_1(t, h, SBSS_RW, 0x40); 125 bus_space_write_multi_1(t, h, SBSS_HSCX, buf, size); 126 break; 127 } 128} 129 130/*---------------------------------------------------------------------------* 131 * Sedlbauer SpeedStar ISAC put register routine 132 *---------------------------------------------------------------------------*/ 133 134static void 135sws_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) 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, SBSS_RW, offs); 142 bus_space_write_1(t, h, SBSS_ISAC, data); 143 break; 144 case ISIC_WHAT_HSCXA: 145 bus_space_write_1(t, h, SBSS_RW, offs); 146 bus_space_write_1(t, h, SBSS_HSCX, data); 147 break; 148 case ISIC_WHAT_HSCXB: 149 bus_space_write_1(t, h, SBSS_RW, 0x40+offs); 150 bus_space_write_1(t, h, SBSS_HSCX, data); 151 break; 152 } 153} 154 155/*---------------------------------------------------------------------------* 156 * Sedlbauer SpeedStar ISAC get register routine 157 *---------------------------------------------------------------------------*/ 158 159static u_int8_t 160sws_read_reg(struct isic_softc *sc, int what, bus_size_t offs) 161{ 162 bus_space_tag_t t = sc->sc_maps[0].t; 163 bus_space_handle_t h = sc->sc_maps[0].h; 164 switch (what) { 165 case ISIC_WHAT_ISAC: 166 bus_space_write_1(t, h, SBSS_RW, offs); 167 return bus_space_read_1(t, h, SBSS_ISAC); 168 case ISIC_WHAT_HSCXA: 169 bus_space_write_1(t, h, SBSS_RW, offs); 170 return bus_space_read_1(t, h, SBSS_HSCX); 171 case ISIC_WHAT_HSCXB: 172 bus_space_write_1(t, h, SBSS_RW, 0x40+offs); 173 return bus_space_read_1(t, h, SBSS_HSCX); 174 } 175 return 0; 176} 177 178/* 179 * XXX - one time only! Some of this has to go into an enable 180 * function, with apropriate counterpart in disable, so a card 181 * could be removed an inserted again. 182 */ 183int 184isic_attach_sbspeedstar2(struct pcmcia_isic_softc *psc, struct pcmcia_config_entry *cfe, struct pcmcia_attach_args *pa) 185{ 186 struct isic_softc * sc = &psc->sc_isic; 187 bus_space_tag_t t; 188 bus_space_handle_t h; 189 190 /* Validate config info */ 191 if (cfe->num_memspace != 0) 192 printf(": unexpected number of memory spaces %d should be 0\n", 193 cfe->num_memspace); 194 if (cfe->num_iospace != 1) 195 printf(": unexpected number of memory spaces %d should be 1\n", 196 cfe->num_iospace); 197 198 /* Allocate pcmcia space */ 199 if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length, 200 cfe->iospace[0].length, &psc->sc_pcioh)) 201 printf(": can't allocate i/o space\n"); 202 203 /* map them */ 204 if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ? 205 PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), &psc->sc_pcioh, 206 &psc->sc_io_window)) { 207 printf(": can't map i/o space\n"); 208 return 0; 209 } 210 211 /* Setup bus space maps */ 212 sc->sc_num_mappings = 1; 213 MALLOC_MAPS(sc); 214 215 /* Copy our handles/tags to the MI maps */ 216 sc->sc_maps[0].t = psc->sc_pcioh.iot; 217 sc->sc_maps[0].h = psc->sc_pcioh.ioh; 218 sc->sc_maps[0].offset = 0; 219 sc->sc_maps[0].size = 0; /* not our mapping */ 220 221 t = sc->sc_maps[0].t; 222 h = sc->sc_maps[0].h; 223 224 /* setup access routines */ 225 226 sc->readreg = sws_read_reg; 227 sc->writereg = sws_write_reg; 228 229 sc->readfifo = sws_read_fifo; 230 sc->writefifo = sws_write_fifo; 231 232 /* setup IOM bus type */ 233 234 sc->sc_bustyp = BUS_TYPE_IOM2; 235 236 sc->sc_ipac = 0; 237 sc->sc_bfifolen = HSCX_FIFO_LEN; 238 239 /* reset card */ 240 { 241 bus_space_tag_t t1 = sc->sc_maps[0].t; 242 bus_space_handle_t h1 = sc->sc_maps[0].h; 243 bus_space_write_1(t1, h1, SBSS_RESET, 0x3); 244 DELAY(SEC_DELAY / 5); 245 bus_space_write_1(t1, h1, SBSS_RESET, 0); 246 DELAY(SEC_DELAY / 5); 247 } 248 249 return 1; 250} 251 252#endif /* ISICPCMCIA_SBSPEEDSTAR2 */ 253