1/* $NetBSD: pxa2x0_com.c,v 1.14 2018/12/08 17:46:10 thorpej 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.14 2018/12/08 17:46:10 thorpej 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 <sys/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 65static int pxauart_match(device_t, cfdata_t , void *); 66static void pxauart_attach(device_t, device_t, void *); 67 68CFATTACH_DECL_NEW(pxauart, sizeof(struct com_softc), 69 pxauart_match, pxauart_attach, NULL, NULL); 70 71static int 72pxauart_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 if (CPU_IS_PXA270) 107 return (0); 108 gpioconf = pxa25x_com_hwuart_gpioconf; 109 break; 110 111 default: 112 return (0); 113 } 114 for (i = 0; gpioconf[i].pin != -1; i++) { 115 gpio = pxa2x0_gpio_get_function(gpioconf[i].pin); 116 if (GPIO_FN(gpio) != GPIO_FN(gpioconf[i].value) || 117 GPIO_FN_IS_OUT(gpio) != GPIO_FN_IS_OUT(gpioconf[i].value)) 118 return (0); 119 } 120 121 pxa->pxa_size = 0x20; 122 123 if (com_is_console(bt, pxa->pxa_addr, NULL)) 124 return (1); 125 126 if (bus_space_map(bt, pxa->pxa_addr, pxa->pxa_size, 0, &bh)) 127 return (0); 128 129 /* Make sure the UART is enabled */ 130 bus_space_write_1(bt, bh, com_ier, IER_EUART); 131 132 rv = comprobe1(bt, bh); 133 bus_space_unmap(bt, bh, pxa->pxa_size); 134 135 return (rv); 136} 137 138static void 139pxauart_attach(device_t parent, device_t self, void *aux) 140{ 141 struct com_softc *sc = device_private(self); 142 struct pxaip_attach_args *pxa = aux; 143 bus_space_tag_t iot; 144 bus_space_handle_t ioh; 145 bus_addr_t iobase; 146 int cken = 0; 147 148 sc->sc_dev = self; 149 iot = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */ 150 iobase = pxa->pxa_addr; 151 sc->sc_frequency = PXA2X0_COM_FREQ; 152 sc->sc_type = COM_TYPE_PXA2x0; 153 154 if (com_is_console(iot, iobase, &ioh) == 0 && 155 bus_space_map(iot, iobase, pxa->pxa_size, 0, &ioh)) { 156 aprint_error(": can't map registers\n"); 157 return; 158 } 159 com_init_regs(&sc->sc_regs, iot, ioh, iobase); 160 161 switch (pxa->pxa_addr) { 162 case PXA2X0_FFUART_BASE: cken = CKEN_FFUART; break; 163 case PXA2X0_STUART_BASE: cken = CKEN_STUART; break; 164 case PXA2X0_BTUART_BASE: cken = CKEN_BTUART; break; 165 case PXA2X0_HWUART_BASE: cken = CKEN_HWUART; break; 166 } 167 pxa2x0_clkman_config(cken, 1); 168 169 com_attach_subr(sc); 170 171 pxa2x0_intr_establish(pxa->pxa_intr, IPL_SERIAL, comintr, sc); 172} 173