slhci_intio.c revision 1.7
1/* $NetBSD: slhci_intio.c,v 1.7 2005/12/11 12:19:37 christos Exp $ */ 2 3/* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Tetsuya Isaki. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * USB part of Nereid Ethernet/USB/Memory board 41 */ 42 43#include <sys/cdefs.h> 44__KERNEL_RCSID(0, "$NetBSD: slhci_intio.c,v 1.7 2005/12/11 12:19:37 christos Exp $"); 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/device.h> 49 50#include <machine/bus.h> 51#include <machine/cpu.h> 52 53#include <dev/usb/usb.h> 54#include <dev/usb/usbdi.h> 55#include <dev/usb/usbdivar.h> 56 57#include <dev/ic/sl811hsreg.h> 58#include <dev/ic/sl811hsvar.h> 59 60#include <arch/x68k/dev/intiovar.h> 61 62#include <arch/x68k/dev/slhci_intio_var.h> 63 64static int slhci_intio_match(struct device *, struct cfdata *, void *); 65static void slhci_intio_attach(struct device *, struct device *, void *); 66static void slhci_intio_enable_power(void *, int); 67static void slhci_intio_enable_intr(void *, int); 68static int slhci_intio_intr(void *); 69 70CFATTACH_DECL(slhci_intio, sizeof(struct slhci_intio_softc), 71 slhci_intio_match, slhci_intio_attach, NULL, NULL); 72 73static int 74slhci_intio_match(struct device *parent, struct cfdata *cf, void *aux) 75{ 76 struct intio_attach_args *ia = aux; 77 bus_space_tag_t iot = ia->ia_bst; 78 bus_space_handle_t ioh; 79 bus_space_handle_t nch; 80 int nc_addr; 81 int nc_size; 82 83 if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 84 ia->ia_addr = SLHCI_INTIO_ADDR1; 85 if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 86 ia->ia_intr = SLHCI_INTIO_INTR1; 87 88 /* fixed parameters */ 89 if ( !(ia->ia_addr == SLHCI_INTIO_ADDR1 && 90 ia->ia_intr == SLHCI_INTIO_INTR1 ) && 91 !(ia->ia_addr == SLHCI_INTIO_ADDR2 && 92 ia->ia_intr == SLHCI_INTIO_INTR2 ) ) 93 return 0; 94 95 /* Whether the control port is accessible or not */ 96 nc_addr = ia->ia_addr + NEREID_ADDR_OFFSET; 97 nc_size = 0x02; 98 if (badbaddr(INTIO_ADDR(nc_addr))) 99 return 0; 100 101 /* Map two I/O spaces */ 102 ia->ia_size = SL11_PORTSIZE * 2; 103 if (bus_space_map(iot, ia->ia_addr, ia->ia_size, 104 BUS_SPACE_MAP_SHIFTED, &ioh)) 105 return 0; 106 107 if (bus_space_map(iot, nc_addr, nc_size, 108 BUS_SPACE_MAP_SHIFTED, &nch)) 109 return 0; 110 111 bus_space_unmap(iot, ioh, ia->ia_size); 112 bus_space_unmap(iot, nch, nc_size); 113 114 return 1; 115} 116 117static void 118slhci_intio_attach(struct device *parent, struct device *self, void *aux) 119{ 120 struct slhci_intio_softc *sc = (struct slhci_intio_softc *)self; 121 struct intio_attach_args *ia = aux; 122 bus_space_tag_t iot = ia->ia_bst; 123 bus_space_handle_t ioh; 124 int nc_addr; 125 int nc_size; 126 127 printf(": Nereid USB\n"); 128 129 /* Map I/O space */ 130 if (bus_space_map(iot, ia->ia_addr, SL11_PORTSIZE * 2, 131 BUS_SPACE_MAP_SHIFTED, &ioh)) { 132 printf("%s: can't map I/O space\n", 133 sc->sc_sc.sc_bus.bdev.dv_xname); 134 return; 135 } 136 137 nc_addr = ia->ia_addr + NEREID_ADDR_OFFSET; 138 nc_size = 0x02; 139 if (bus_space_map(iot, nc_addr, nc_size, 140 BUS_SPACE_MAP_SHIFTED, &sc->sc_nch)) { 141 printf("%s: can't map I/O control space\n", 142 sc->sc_sc.sc_bus.bdev.dv_xname); 143 return; 144 } 145 146 /* Initialize sc */ 147 sc->sc_sc.sc_iot = iot; 148 sc->sc_sc.sc_ioh = ioh; 149 sc->sc_sc.sc_dmat = ia->ia_dmat; 150 sc->sc_sc.sc_enable_power = slhci_intio_enable_power; 151 sc->sc_sc.sc_enable_intr = slhci_intio_enable_intr; 152 sc->sc_sc.sc_arg = sc; 153 154 /* Establish the interrupt handler */ 155 if (intio_intr_establish(ia->ia_intr, "slhci", slhci_intio_intr, sc)) { 156 printf("%s: can't establish interrupt\n", 157 sc->sc_sc.sc_bus.bdev.dv_xname); 158 return; 159 } 160 161 /* Reset controller */ 162 bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL, NEREID_CTRL_RESET); 163 delay(40000); 164 165 /* Attach SL811HS/T */ 166 if (slhci_attach(&sc->sc_sc, self)) 167 return; 168} 169 170static void 171slhci_intio_enable_power(void *arg, int mode) 172{ 173 struct slhci_intio_softc *sc = arg; 174 bus_space_tag_t iot = sc->sc_sc.sc_iot; 175 u_int8_t r; 176 177 r = bus_space_read_1(iot, sc->sc_nch, NEREID_CTRL); 178 if (mode == POWER_ON) 179 bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL, 180 r | NEREID_CTRL_POWER); 181 else 182 bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL, 183 r & ~NEREID_CTRL_POWER); 184} 185 186static void 187slhci_intio_enable_intr(void *arg, int mode) 188{ 189 struct slhci_intio_softc *sc = arg; 190 bus_space_tag_t iot = sc->sc_sc.sc_iot; 191 u_int8_t r; 192 193 r = bus_space_read_1(iot, sc->sc_nch, NEREID_CTRL); 194 if (mode == INTR_ON) 195 bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL, 196 r | NEREID_CTRL_INTR); 197 else 198 bus_space_write_1(iot, sc->sc_nch, NEREID_CTRL, 199 r & ~NEREID_CTRL_INTR); 200} 201 202static int 203slhci_intio_intr(void *arg) 204{ 205 struct slhci_intio_softc *sc = arg; 206 207 return slhci_intr(&sc->sc_sc); 208} 209