1 /* $NetBSD: pxa2x0_com.c,v 1.10 2008/03/14 15:09:09 cube Exp $ */ 2 3 /* 4 * Copyright 2003 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Steve C. Woodford for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_com.c,v 1.10 2008/03/14 15:09:09 cube Exp $"); 40 41 #include "opt_com.h" 42 43 #ifndef COM_PXA2X0 44 #error "You must use options COM_PXA2X0 to get PXA2x0 serial port support" 45 #endif 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/device.h> 50 #include <sys/termios.h> 51 52 #include <machine/intr.h> 53 #include <machine/bus.h> 54 55 #include <dev/ic/comreg.h> 56 #include <dev/ic/comvar.h> 57 58 #include <arm/xscale/pxa2x0cpu.h> 59 #include <arm/xscale/pxa2x0reg.h> 60 #include <arm/xscale/pxa2x0var.h> 61 #include <arm/xscale/pxa2x0_gpio.h> 62 63 #include "locators.h" 64 65 static int pxauart_match(device_t, cfdata_t , void *); 66 static void pxauart_attach(device_t, device_t, void *); 67 68 CFATTACH_DECL_NEW(pxauart, sizeof(struct com_softc), 69 pxauart_match, pxauart_attach, NULL, NULL); 70 71 static int 72 pxauart_match(device_t parent, cfdata_t cf, void *aux) 73 { 74 struct pxaip_attach_args *pxa = aux; 75 bus_space_tag_t bt = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */ 76 bus_space_handle_t bh; 77 struct pxa2x0_gpioconf *gpioconf; 78 u_int gpio; 79 int rv, i; 80 81 switch (pxa->pxa_addr) { 82 case PXA2X0_FFUART_BASE: 83 if (pxa->pxa_intr != PXA2X0_INT_FFUART) 84 return (0); 85 gpioconf = CPU_IS_PXA250 ? pxa25x_com_ffuart_gpioconf : 86 pxa27x_com_ffuart_gpioconf; 87 break; 88 89 case PXA2X0_STUART_BASE: 90 if (pxa->pxa_intr != PXA2X0_INT_STUART) 91 return (0); 92 gpioconf = CPU_IS_PXA250 ? pxa25x_com_stuart_gpioconf : 93 pxa27x_com_stuart_gpioconf; 94 break; 95 96 case PXA2X0_BTUART_BASE: /* XXX: Config file option ... */ 97 if (pxa->pxa_intr != PXA2X0_INT_BTUART) 98 return (0); 99 gpioconf = CPU_IS_PXA250 ? pxa25x_com_btuart_gpioconf : 100 pxa27x_com_btuart_gpioconf; 101 break; 102 103 case PXA2X0_HWUART_BASE: 104 if (pxa->pxa_intr != PXA2X0_INT_HWUART) 105 return (0); 106 gpioconf = CPU_IS_PXA250 ? pxa25x_com_hwuart_gpioconf : 107 pxa27x_com_hwuart_gpioconf; 108 break; 109 110 default: 111 return (0); 112 } 113 for (i = 0; gpioconf[i].pin != -1; i++) { 114 gpio = pxa2x0_gpio_get_function(gpioconf[i].pin); 115 if (GPIO_FN(gpio) != GPIO_FN(gpioconf[i].value) || 116 GPIO_FN_IS_OUT(gpio) != GPIO_FN_IS_OUT(gpioconf[i].value)) 117 return (0); 118 } 119 120 pxa->pxa_size = 0x20; 121 122 if (com_is_console(bt, pxa->pxa_addr, NULL)) 123 return (1); 124 125 if (bus_space_map(bt, pxa->pxa_addr, pxa->pxa_size, 0, &bh)) 126 return (0); 127 128 /* Make sure the UART is enabled */ 129 bus_space_write_1(bt, bh, com_ier, IER_EUART); 130 131 rv = comprobe1(bt, bh); 132 bus_space_unmap(bt, bh, pxa->pxa_size); 133 134 return (rv); 135 } 136 137 static void 138 pxauart_attach(device_t parent, device_t self, void *aux) 139 { 140 struct com_softc *sc = device_private(self); 141 struct pxaip_attach_args *pxa = aux; 142 bus_space_tag_t iot; 143 bus_space_handle_t ioh; 144 bus_addr_t iobase; 145 146 sc->sc_dev = self; 147 iot = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */ 148 iobase = pxa->pxa_addr; 149 sc->sc_frequency = PXA2X0_COM_FREQ; 150 sc->sc_type = COM_TYPE_PXA2x0; 151 152 if (com_is_console(iot, iobase, &ioh) == 0 && 153 bus_space_map(iot, iobase, pxa->pxa_size, 0, &ioh)) { 154 aprint_error(": can't map registers\n"); 155 return; 156 } 157 COM_INIT_REGS(sc->sc_regs, iot, ioh, iobase); 158 159 com_attach_subr(sc); 160 161 pxa2x0_intr_establish(pxa->pxa_intr, IPL_SERIAL, comintr, sc); 162 } 163