1 /* $NetBSD: zusb.c,v 1.1 2008/03/31 23:32:43 chris Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Christopher Gilbert 5 * All rights reserved. 6 * 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of the company nor the name of the author may be used to 13 * endorse or promote products derived from this software without specific 14 * prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: zusb.c,v 1.1 2008/03/31 23:32:43 chris Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/device.h> 34 #include <sys/kernel.h> 35 36 #include <arm/xscale/pxa2x0reg.h> 37 #include <arm/xscale/pxa2x0var.h> 38 #include <arm/xscale/pxa2x0_gpio.h> 39 40 #include <machine/intr.h> 41 #include <machine/bus.h> 42 43 #include <zaurus/zaurus/zaurus_reg.h> 44 #include <zaurus/zaurus/zaurus_var.h> 45 46 struct zusb_softc { 47 struct device sc_dev; 48 void *sc_client_ih; 49 void *sc_host_ih; 50 bus_space_tag_t sc_iot; 51 bus_space_handle_t sc_ioh; 52 }; 53 54 static int zusb_match(struct device *, struct cfdata *, void *); 55 static void zusb_attach(struct device *, struct device *, void *); 56 57 CFATTACH_DECL(zusb, sizeof(struct zusb_softc), 58 zusb_match, zusb_attach, NULL, NULL); 59 60 static int zusb_client_intr(void *); 61 static int zusb_host_intr(void *); 62 static void zusb_test_and_enabled_host_port(struct zusb_softc *); 63 64 static int 65 zusb_match(struct device *parent, struct cfdata *cf, void *aux) 66 { 67 68 if (ZAURUS_ISC3000) 69 return 1; 70 return 0; 71 } 72 73 static void 74 zusb_attach(struct device *parent, struct device *self, void *aux) 75 { 76 struct zusb_softc *sc = (struct zusb_softc *)self; 77 struct pxaip_attach_args *pxa = aux; 78 79 sc->sc_iot = pxa->pxa_iot; 80 81 /* Map I/O space */ 82 if (bus_space_map(sc->sc_iot, PXA2X0_USBDC_BASE, PXA270_USBDC_SIZE, 0, 83 &sc->sc_ioh)) { 84 aprint_error(": couldn't map memory space\n"); 85 return; 86 } 87 88 pxa2x0_gpio_set_function(C3000_USB_DEVICE_PIN, GPIO_IN); 89 sc->sc_client_ih = pxa2x0_gpio_intr_establish(C3000_USB_DEVICE_PIN, 90 IST_EDGE_BOTH, IPL_BIO, zusb_client_intr, sc); 91 92 pxa2x0_gpio_set_function(C3000_USB_HOST_PIN, GPIO_IN); 93 sc->sc_host_ih = pxa2x0_gpio_intr_establish(C3000_USB_HOST_PIN, 94 IST_EDGE_BOTH, IPL_BIO, zusb_host_intr, sc); 95 96 /* configure port 2 for input */ 97 bus_space_write_4(sc->sc_iot, sc->sc_ioh, USBDC_UP2OCR, 98 USBDC_UP2OCR_HXS | USBDC_UP2OCR_HXOE | 99 USBDC_UP2OCR_DPPDE | USBDC_UP2OCR_DMPDE); 100 101 zusb_test_and_enabled_host_port(sc); 102 103 printf(": USB Mode detection\n"); 104 } 105 106 static int 107 zusb_client_intr(void *v) 108 { 109 struct zusb_softc *sc = v; 110 printf("USB client cable changed\n"); 111 zusb_test_and_enabled_host_port(sc); 112 113 return 1; 114 } 115 116 static int 117 zusb_host_intr(void *v) 118 { 119 struct zusb_softc *sc = v; 120 121 printf("USB host cable changed\n"); 122 zusb_test_and_enabled_host_port(sc); 123 124 return 1; 125 } 126 127 static void 128 zusb_test_and_enabled_host_port(struct zusb_softc *sc) 129 { 130 int host_cable = pxa2x0_gpio_get_bit(C3000_USB_HOST_PIN); 131 int client_cable = pxa2x0_gpio_get_bit(C3000_USB_DEVICE_PIN); 132 133 printf("USB cable: host %d, client %d\n", host_cable, client_cable); 134 if (!host_cable) { 135 pxa2x0_gpio_set_function(C3000_USB_HOST_POWER_PIN, GPIO_OUT | GPIO_SET); 136 printf("USB host power enabled\n"); 137 } else { 138 pxa2x0_gpio_set_function(C3000_USB_HOST_POWER_PIN, GPIO_OUT | GPIO_CLR); 139 printf("USB host power disabled\n"); 140 } 141 } 142 143