1*5248d82bSjason /* $OpenBSD: apio.c,v 1.2 2002/04/08 17:49:42 jason Exp $ */ 27e81dd80Sjason 37e81dd80Sjason /* 47e81dd80Sjason * Copyright (c) 2002 Jason L. Wright (jason@thought.net) 57e81dd80Sjason * All rights reserved. 67e81dd80Sjason * 77e81dd80Sjason * Redistribution and use in source and binary forms, with or without 87e81dd80Sjason * modification, are permitted provided that the following conditions 97e81dd80Sjason * are met: 107e81dd80Sjason * 1. Redistributions of source code must retain the above copyright 117e81dd80Sjason * notice, this list of conditions and the following disclaimer. 127e81dd80Sjason * 2. Redistributions in binary form must reproduce the above copyright 137e81dd80Sjason * notice, this list of conditions and the following disclaimer in the 147e81dd80Sjason * documentation and/or other materials provided with the distribution. 157e81dd80Sjason * 3. All advertising materials mentioning features or use of this software 167e81dd80Sjason * must display the following acknowledgement: 177e81dd80Sjason * This product includes software developed by Jason L. Wright 187e81dd80Sjason * 4. The name of the author may not be used to endorse or promote products 197e81dd80Sjason * derived from this software without specific prior written permission. 207e81dd80Sjason * 217e81dd80Sjason * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 227e81dd80Sjason * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 237e81dd80Sjason * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 247e81dd80Sjason * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 257e81dd80Sjason * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 267e81dd80Sjason * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 277e81dd80Sjason * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287e81dd80Sjason * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 297e81dd80Sjason * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 307e81dd80Sjason * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 317e81dd80Sjason * POSSIBILITY OF SUCH DAMAGE. 32*5248d82bSjason * 33*5248d82bSjason * Effort sponsored in part by the Defense Advanced Research Projects 34*5248d82bSjason * Agency (DARPA) and Air Force Research Laboratory, Air Force 35*5248d82bSjason * Materiel Command, USAF, under agreement number F30602-01-2-0537. 36*5248d82bSjason * 377e81dd80Sjason */ 387e81dd80Sjason 397e81dd80Sjason /* 407e81dd80Sjason * Driver for Aurora 210SJ parallel ports. 417e81dd80Sjason */ 427e81dd80Sjason 437e81dd80Sjason #include <sys/types.h> 447e81dd80Sjason #include <sys/param.h> 457e81dd80Sjason #include <sys/systm.h> 467e81dd80Sjason #include <sys/kernel.h> 477e81dd80Sjason #include <sys/device.h> 487e81dd80Sjason #include <sys/conf.h> 497e81dd80Sjason #include <sys/timeout.h> 507e81dd80Sjason #include <sys/tty.h> 517e81dd80Sjason 527e81dd80Sjason #include <machine/bus.h> 537e81dd80Sjason #include <machine/autoconf.h> 547e81dd80Sjason #include <machine/openfirm.h> 557e81dd80Sjason 567e81dd80Sjason #include <dev/sbus/sbusvar.h> 577e81dd80Sjason #include <dev/sbus/asioreg.h> 587e81dd80Sjason #include <dev/ic/lptvar.h> 597e81dd80Sjason #include "apio.h" 607e81dd80Sjason #include "lpt.h" 617e81dd80Sjason 627e81dd80Sjason struct apio_softc { 637e81dd80Sjason struct device sc_dev; 647e81dd80Sjason bus_space_tag_t sc_bt; 657e81dd80Sjason bus_space_handle_t sc_csr_h; 667e81dd80Sjason bus_space_handle_t sc_clk_h; 677e81dd80Sjason bus_space_handle_t sc_lpt_h; 687e81dd80Sjason void *sc_ih; 697e81dd80Sjason struct device *sc_port; 707e81dd80Sjason }; 717e81dd80Sjason 727e81dd80Sjason struct apio_attach_args { 737e81dd80Sjason char *aaa_name; 747e81dd80Sjason bus_space_tag_t aaa_iot; 757e81dd80Sjason bus_space_handle_t aaa_ioh; 767e81dd80Sjason bus_space_handle_t aaa_clkh; 777e81dd80Sjason u_int32_t aaa_pri; 787e81dd80Sjason u_int8_t aaa_inten; 797e81dd80Sjason }; 807e81dd80Sjason 817e81dd80Sjason int apio_match(struct device *, void *, void *); 827e81dd80Sjason void apio_attach(struct device *, struct device *, void *); 837e81dd80Sjason int apio_print(void *, const char *); 847e81dd80Sjason void apio_intr_enable(struct device *, u_int8_t); 857e81dd80Sjason 867e81dd80Sjason struct cfattach apio_ca = { 877e81dd80Sjason sizeof(struct apio_softc), apio_match, apio_attach 887e81dd80Sjason }; 897e81dd80Sjason 907e81dd80Sjason struct cfdriver apio_cd = { 917e81dd80Sjason NULL, "apio", DV_DULL 927e81dd80Sjason }; 937e81dd80Sjason 947e81dd80Sjason int 957e81dd80Sjason apio_match(parent, match, aux) 967e81dd80Sjason struct device *parent; 977e81dd80Sjason void *match; 987e81dd80Sjason void *aux; 997e81dd80Sjason { 1007e81dd80Sjason struct sbus_attach_args *sa = aux; 1017e81dd80Sjason 1027e81dd80Sjason if (strcmp(sa->sa_name, "pio1") == 0) 1037e81dd80Sjason return (1); 1047e81dd80Sjason return (0); 1057e81dd80Sjason } 1067e81dd80Sjason 1077e81dd80Sjason void 1087e81dd80Sjason apio_attach(parent, self, aux) 1097e81dd80Sjason struct device *parent, *self; 1107e81dd80Sjason void *aux; 1117e81dd80Sjason { 1127e81dd80Sjason struct apio_softc *sc = (void *)self; 1137e81dd80Sjason struct sbus_attach_args *sa = aux; 1147e81dd80Sjason struct apio_attach_args aaa; 1157e81dd80Sjason char *model; 1167e81dd80Sjason 1177e81dd80Sjason sc->sc_bt = sa->sa_bustag; 1187e81dd80Sjason 1197e81dd80Sjason model = getpropstring(sa->sa_node, "model"); 1207e81dd80Sjason if (model == NULL) { 1217e81dd80Sjason printf(": empty model, unsupported\n"); 1227e81dd80Sjason return; 1237e81dd80Sjason } 1247e81dd80Sjason if (strcmp(model, "210sj") != 0) { 1257e81dd80Sjason printf(": unsupported model %s\n", model); 1267e81dd80Sjason return; 1277e81dd80Sjason } 1287e81dd80Sjason 1297e81dd80Sjason if (sa->sa_nreg < 3) { 1307e81dd80Sjason printf(": %d registers expected, got %d\n", 1317e81dd80Sjason 3, sa->sa_nreg); 1327e81dd80Sjason return; 1337e81dd80Sjason } 1347e81dd80Sjason 1357e81dd80Sjason if (sbus_bus_map(sa->sa_bustag, 1367e81dd80Sjason sa->sa_reg[0].sbr_slot, 1377e81dd80Sjason sa->sa_reg[0].sbr_offset, 1387e81dd80Sjason sa->sa_reg[0].sbr_size, 1397e81dd80Sjason BUS_SPACE_MAP_LINEAR, 0, &sc->sc_csr_h)) { 1407e81dd80Sjason printf(": couldn't map csr\n"); 1417e81dd80Sjason return; 1427e81dd80Sjason } 1437e81dd80Sjason 1447e81dd80Sjason if (sbus_bus_map(sa->sa_bustag, 1457e81dd80Sjason sa->sa_reg[1].sbr_slot, 1467e81dd80Sjason sa->sa_reg[1].sbr_offset, 1477e81dd80Sjason sa->sa_reg[1].sbr_size, 1487e81dd80Sjason BUS_SPACE_MAP_LINEAR, 0, &sc->sc_clk_h)) { 1497e81dd80Sjason printf(": couldn't map clk\n"); 1507e81dd80Sjason return; 1517e81dd80Sjason } 1527e81dd80Sjason 1537e81dd80Sjason if (sbus_bus_map(sa->sa_bustag, 1547e81dd80Sjason sa->sa_reg[2].sbr_slot, 1557e81dd80Sjason sa->sa_reg[2].sbr_offset, 1567e81dd80Sjason sa->sa_reg[2].sbr_size, 1577e81dd80Sjason BUS_SPACE_MAP_LINEAR, 0, &sc->sc_lpt_h)) { 1587e81dd80Sjason printf(": couldn't map clk\n"); 1597e81dd80Sjason return; 1607e81dd80Sjason } 1617e81dd80Sjason 1627e81dd80Sjason printf(": %s\n", model); 1637e81dd80Sjason 1647e81dd80Sjason aaa.aaa_name = "lpt"; 1657e81dd80Sjason aaa.aaa_iot = sc->sc_bt; 1667e81dd80Sjason aaa.aaa_ioh = sc->sc_lpt_h; 1677e81dd80Sjason aaa.aaa_clkh = sc->sc_clk_h; 1687e81dd80Sjason aaa.aaa_inten = ASIO_CSR_SJ_PAR_INTEN; 1697e81dd80Sjason aaa.aaa_pri = sa->sa_intr[0].sbi_pri; 1707e81dd80Sjason sc->sc_port = config_found(self, &aaa, apio_print); 1717e81dd80Sjason } 1727e81dd80Sjason 1737e81dd80Sjason int 1747e81dd80Sjason apio_print(aux, name) 1757e81dd80Sjason void *aux; 1767e81dd80Sjason const char *name; 1777e81dd80Sjason { 1787e81dd80Sjason struct apio_attach_args *aaa; 1797e81dd80Sjason 1807e81dd80Sjason if (name != NULL) 1817e81dd80Sjason printf("%s at %s", aaa->aaa_name, name); 1827e81dd80Sjason return (UNCONF); 1837e81dd80Sjason } 1847e81dd80Sjason 1857e81dd80Sjason #if NLPT_APIO > 0 1867e81dd80Sjason int lpt_apio_match(struct device *, void *, void *); 1877e81dd80Sjason void lpt_apio_attach(struct device *, struct device *, void *); 1887e81dd80Sjason int lpt_apio_intr(void *); 1897e81dd80Sjason 1907e81dd80Sjason struct lpt_apio_softc { 1917e81dd80Sjason struct lpt_softc sc_lpt; 1927e81dd80Sjason bus_space_handle_t sc_clk_h; 1937e81dd80Sjason void *sc_ih; 1947e81dd80Sjason }; 1957e81dd80Sjason 1967e81dd80Sjason struct cfattach lpt_apio_ca = { 1977e81dd80Sjason sizeof(struct lpt_apio_softc), lpt_apio_match, lpt_apio_attach 1987e81dd80Sjason }; 1997e81dd80Sjason 2007e81dd80Sjason void 2017e81dd80Sjason apio_intr_enable(dv, en) 2027e81dd80Sjason struct device *dv; 2037e81dd80Sjason u_int8_t en; 2047e81dd80Sjason { 2057e81dd80Sjason struct apio_softc *sc = (struct apio_softc *)dv; 2067e81dd80Sjason u_int8_t csr; 2077e81dd80Sjason 2087e81dd80Sjason csr = bus_space_read_1(sc->sc_bt, sc->sc_csr_h, 0); 2097e81dd80Sjason csr &= ~(ASIO_CSR_SBUS_INT7 | ASIO_CSR_SBUS_INT6); 2107e81dd80Sjason csr |= ASIO_CSR_SBUS_INT5 | en; 2117e81dd80Sjason bus_space_write_1(sc->sc_bt, sc->sc_csr_h, 0, csr); 2127e81dd80Sjason } 2137e81dd80Sjason 2147e81dd80Sjason int 2157e81dd80Sjason lpt_apio_match(parent, match, aux) 2167e81dd80Sjason struct device *parent; 2177e81dd80Sjason void *match; 2187e81dd80Sjason void *aux; 2197e81dd80Sjason { 2207e81dd80Sjason return (1); 2217e81dd80Sjason } 2227e81dd80Sjason 2237e81dd80Sjason void 2247e81dd80Sjason lpt_apio_attach(parent, self, aux) 2257e81dd80Sjason struct device *parent, *self; 2267e81dd80Sjason void *aux; 2277e81dd80Sjason { 2287e81dd80Sjason struct lpt_apio_softc *sc = (struct lpt_apio_softc *)self; 2297e81dd80Sjason struct apio_attach_args *aaa = aux; 2307e81dd80Sjason 2317e81dd80Sjason sc->sc_lpt.sc_state = 0; 2327e81dd80Sjason sc->sc_lpt.sc_iot = aaa->aaa_iot; 2337e81dd80Sjason sc->sc_lpt.sc_ioh = aaa->aaa_ioh; 2347e81dd80Sjason sc->sc_clk_h = aaa->aaa_clkh; 2357e81dd80Sjason sc->sc_ih = bus_intr_establish(aaa->aaa_iot, aaa->aaa_pri, 2367e81dd80Sjason IPL_TTY, 0, lpt_apio_intr, sc); 2377e81dd80Sjason if (sc->sc_ih == NULL) { 2387e81dd80Sjason printf(": cannot allocate intr\n"); 2397e81dd80Sjason return; 2407e81dd80Sjason } 2417e81dd80Sjason apio_intr_enable(parent, aaa->aaa_inten); 2427e81dd80Sjason 2437e81dd80Sjason lpt_attach_common(&sc->sc_lpt); 2447e81dd80Sjason } 2457e81dd80Sjason 2467e81dd80Sjason int 2477e81dd80Sjason lpt_apio_intr(vsc) 2487e81dd80Sjason void *vsc; 2497e81dd80Sjason { 2507e81dd80Sjason struct lpt_apio_softc *sc = vsc; 2517e81dd80Sjason int r; 2527e81dd80Sjason 2537e81dd80Sjason r = lptintr(&sc->sc_lpt); 2547e81dd80Sjason bus_space_read_1(sc->sc_lpt.sc_iot, sc->sc_clk_h, 0); 2557e81dd80Sjason return (r); 2567e81dd80Sjason } 2577e81dd80Sjason #endif 258