at91ohci.c revision 1.3
11.3Sdsl/* $Id: at91ohci.c,v 1.3 2009/03/14 15:36:01 dsl Exp $ */ 21.3Sdsl/* $NetBSD: at91ohci.c,v 1.3 2009/03/14 15:36:01 dsl Exp $ */ 31.2Smatt 41.2Smatt/*- 51.2Smatt * Copyright (c) 2007 Embedtronics Oy. 61.2Smatt * All rights reserved. 71.2Smatt * 81.2Smatt * Based on arch/arm/ep93xx/epohci.c, 91.2Smatt * Copyright (c) 2004 Jesse Off 101.2Smatt * All rights reserved. 111.2Smatt * 121.2Smatt * Redistribution and use in source and binary forms, with or without 131.2Smatt * modification, are permitted provided that the following conditions 141.2Smatt * are met: 151.2Smatt * 1. Redistributions of source code must retain the above copyright 161.2Smatt * notice, this list of conditions and the following disclaimer. 171.2Smatt * 2. Redistributions in binary form must reproduce the above copyright 181.2Smatt * notice, this list of conditions and the following disclaimer in the 191.2Smatt * documentation and/or other materials provided with the distribution. 201.2Smatt * 211.2Smatt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 221.2Smatt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231.2Smatt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241.2Smatt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 251.2Smatt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261.2Smatt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271.2Smatt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281.2Smatt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291.2Smatt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301.2Smatt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311.2Smatt * SUCH DAMAGE. 321.2Smatt */ 331.2Smatt 341.2Smatt/* 351.2Smatt * USB Open Host Controller driver. 361.2Smatt * 371.2Smatt * OHCI spec: ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.exe 381.2Smatt * USB spec: http://www.usb.org/developers/data/usb11.pdf 391.2Smatt */ 401.2Smatt 411.2Smatt#include <sys/cdefs.h> 421.3Sdsl__KERNEL_RCSID(0, "$NetBSD: at91ohci.c,v 1.3 2009/03/14 15:36:01 dsl Exp $"); 431.2Smatt 441.2Smatt#include <sys/param.h> 451.2Smatt#include <sys/systm.h> 461.2Smatt#include <sys/kernel.h> 471.2Smatt#include <sys/device.h> 481.2Smatt#include <sys/proc.h> 491.2Smatt#include <sys/queue.h> 501.2Smatt 511.2Smatt/* busdma */ 521.2Smatt#include <sys/mbuf.h> 531.2Smatt#include <uvm/uvm_extern.h> 541.2Smatt 551.2Smatt#include <machine/bus.h> 561.2Smatt 571.2Smatt#include <dev/usb/usb.h> 581.2Smatt#include <dev/usb/usbdi.h> 591.2Smatt#include <dev/usb/usbdivar.h> 601.2Smatt#include <dev/usb/usb_mem.h> 611.2Smatt 621.2Smatt#include <dev/usb/ohcireg.h> 631.2Smatt#include <dev/usb/ohcivar.h> 641.2Smatt 651.2Smatt#include <arm/at91/at91reg.h> 661.2Smatt#include <arm/at91/at91var.h> 671.2Smatt 681.2Smattint at91ohci_match(device_t, cfdata_t, void *); 691.2Smattvoid at91ohci_attach(device_t, device_t, void *); 701.2Smattvoid at91ohci_callback(device_t ); 711.2Smatt 721.2Smattstruct at91ohci_softc { 731.2Smatt struct ohci_softc sc; 741.2Smatt void *sc_ih; 751.2Smatt int sc_pid; 761.2Smatt}; 771.2Smatt 781.2SmattCFATTACH_DECL(at91ohci, sizeof(struct at91ohci_softc), 791.2Smatt at91ohci_match, at91ohci_attach, NULL, NULL); 801.2Smatt 811.2Smattint 821.2Smattat91ohci_match(device_t parent, cfdata_t match, void *aux) 831.2Smatt{ 841.2Smatt /* AT91X builtin OHCI module */ 851.2Smatt if (strcmp(match->cf_name, "ohci") == 0 && strcmp(match->cf_atname, "at91ohci") == 0) 861.2Smatt return (2); 871.2Smatt return(0); 881.2Smatt} 891.2Smatt 901.2Smattvoid 911.2Smattat91ohci_attach(device_t parent, device_t self, void *aux) 921.2Smatt{ 931.2Smatt struct at91ohci_softc *sc = (struct at91ohci_softc *)self; 941.2Smatt struct at91bus_attach_args *sa = aux; 951.2Smatt 961.2Smatt sc->sc.iot = sa->sa_iot; 971.2Smatt sc->sc.sc_bus.dmatag = sa->sa_dmat; 981.2Smatt sc->sc_pid = sa->sa_pid; 991.2Smatt 1001.2Smatt /* Map I/O space */ 1011.2Smatt if (bus_space_map(sc->sc.iot, sa->sa_addr, sa->sa_size, 1021.2Smatt 0, &sc->sc.ioh)) { 1031.2Smatt printf(": cannot map mem space\n"); 1041.2Smatt return; 1051.2Smatt } 1061.2Smatt 1071.2Smatt /* enable peripheral clock */ 1081.2Smatt at91_peripheral_clock(sc->sc_pid, 1); 1091.2Smatt 1101.2Smatt printf("\n"); 1111.2Smatt 1121.2Smatt /* Defer the rest until later */ 1131.2Smatt config_defer(self, at91ohci_callback); 1141.2Smatt} 1151.2Smatt 1161.2Smattvoid 1171.3Sdslat91ohci_callback(device_t self) 1181.2Smatt{ 1191.2Smatt struct at91ohci_softc *sc = (struct at91ohci_softc *)self; 1201.2Smatt usbd_status r; 1211.2Smatt 1221.2Smatt /* Disable interrupts, so we don't get any spurious ones. */ 1231.2Smatt bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, 1241.2Smatt OHCI_ALL_INTRS); 1251.2Smatt 1261.2Smatt strlcpy(sc->sc.sc_vendor, "Atmel", sizeof sc->sc.sc_vendor); 1271.2Smatt 1281.2Smatt sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_USB, INTR_HIGH_LEVEL, ohci_intr, sc); 1291.2Smatt r = ohci_init(&sc->sc); 1301.2Smatt 1311.2Smatt if (r != USBD_NORMAL_COMPLETION) { 1321.2Smatt printf("%s: init failed, error=%d\n", device_xname(self), r); 1331.2Smatt 1341.2Smatt at91_intr_disestablish(sc->sc_ih); 1351.2Smatt return; 1361.2Smatt } 1371.2Smatt 1381.2Smatt /* Attach usb device. */ 1391.2Smatt sc->sc.sc_child = config_found((void *) sc, &sc->sc.sc_bus, usbctlprint); 1401.2Smatt} 141