Home | History | Annotate | Line # | Download | only in dev
com_ebus.c revision 1.7
      1  1.7  eeh /*	$NetBSD: com_ebus.c,v 1.7 2001/10/02 20:19:33 eeh Exp $	*/
      2  1.1  eeh 
      3  1.1  eeh /*
      4  1.1  eeh  * Copyright (c) 1999, 2000 Matthew R. Green
      5  1.1  eeh  * All rights reserved.
      6  1.1  eeh  *
      7  1.1  eeh  * Redistribution and use in source and binary forms, with or without
      8  1.1  eeh  * modification, are permitted provided that the following conditions
      9  1.1  eeh  * are met:
     10  1.1  eeh  * 1. Redistributions of source code must retain the above copyright
     11  1.1  eeh  *    notice, this list of conditions and the following disclaimer.
     12  1.1  eeh  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  eeh  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  eeh  *    documentation and/or other materials provided with the distribution.
     15  1.1  eeh  * 3. The name of the author may not be used to endorse or promote products
     16  1.1  eeh  *    derived from this software without specific prior written permission.
     17  1.1  eeh  *
     18  1.1  eeh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  1.1  eeh  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  1.1  eeh  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  1.1  eeh  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  1.1  eeh  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     23  1.1  eeh  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  1.1  eeh  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     25  1.1  eeh  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     26  1.1  eeh  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  1.1  eeh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  1.1  eeh  * SUCH DAMAGE.
     29  1.1  eeh  */
     30  1.1  eeh 
     31  1.1  eeh /*
     32  1.1  eeh  * NS Super I/O PC87332VLJ "com" to ebus attachment
     33  1.1  eeh  */
     34  1.1  eeh 
     35  1.1  eeh #include <sys/types.h>
     36  1.1  eeh #include <sys/param.h>
     37  1.1  eeh #include <sys/systm.h>
     38  1.1  eeh #include <sys/device.h>
     39  1.1  eeh #include <sys/tty.h>
     40  1.1  eeh #include <sys/conf.h>
     41  1.1  eeh 
     42  1.1  eeh #include <machine/bus.h>
     43  1.1  eeh #include <machine/autoconf.h>
     44  1.1  eeh #include <machine/openfirm.h>
     45  1.1  eeh 
     46  1.1  eeh #include <sparc64/dev/ebusreg.h>
     47  1.1  eeh #include <sparc64/dev/ebusvar.h>
     48  1.1  eeh 
     49  1.1  eeh #include <dev/cons.h>
     50  1.1  eeh #include <dev/ic/comvar.h>
     51  1.1  eeh #include <dev/sun/kbd_ms_ttyvar.h>
     52  1.1  eeh 
     53  1.1  eeh #include "kbd.h"
     54  1.1  eeh #include "ms.h"
     55  1.1  eeh 
     56  1.1  eeh cdev_decl(com); /* XXX this belongs elsewhere */
     57  1.1  eeh 
     58  1.1  eeh int	com_ebus_match __P((struct device *, struct cfdata *, void *));
     59  1.1  eeh void	com_ebus_attach __P((struct device *, struct device *, void *));
     60  1.1  eeh 
     61  1.1  eeh struct cfattach com_ebus_ca = {
     62  1.1  eeh 	sizeof(struct com_softc), com_ebus_match, com_ebus_attach
     63  1.1  eeh };
     64  1.1  eeh 
     65  1.1  eeh static char *com_names[] = {
     66  1.1  eeh 	"su",
     67  1.1  eeh 	"su_pnp",
     68  1.1  eeh 	NULL
     69  1.1  eeh };
     70  1.1  eeh 
     71  1.1  eeh int
     72  1.1  eeh com_ebus_match(parent, match, aux)
     73  1.1  eeh 	struct device *parent;
     74  1.1  eeh 	struct cfdata *match;
     75  1.1  eeh 	void *aux;
     76  1.1  eeh {
     77  1.1  eeh 	struct ebus_attach_args *ea = aux;
     78  1.1  eeh 	int i;
     79  1.1  eeh 
     80  1.1  eeh 	for (i=0; com_names[i]; i++)
     81  1.1  eeh 		if (strcmp(ea->ea_name, com_names[i]) == 0)
     82  1.1  eeh 			return (1);
     83  1.1  eeh 
     84  1.5  eeh 	if (strcmp(ea->ea_name, "serial") == 0) {
     85  1.5  eeh 		char compat[80];
     86  1.5  eeh 
     87  1.5  eeh 		/* Could be anything. */
     88  1.5  eeh 		if ((i = OF_getproplen(ea->ea_node, "compatible")) &&
     89  1.5  eeh 			OF_getprop(ea->ea_node, "compatible", compat,
     90  1.5  eeh 				sizeof(compat)) == i) {
     91  1.5  eeh 			if (strcmp(compat, "su16550") == 0 ||
     92  1.5  eeh 				strcmp(compat, "su") == 0) {
     93  1.5  eeh 				return (1);
     94  1.5  eeh 			}
     95  1.5  eeh 		}
     96  1.5  eeh 	}
     97  1.1  eeh 	return (0);
     98  1.1  eeh }
     99  1.1  eeh 
    100  1.1  eeh #define BAUD_BASE       (1846200)
    101  1.1  eeh 
    102  1.1  eeh void
    103  1.1  eeh com_ebus_attach(parent, self, aux)
    104  1.1  eeh 	struct device *parent, *self;
    105  1.1  eeh 	void *aux;
    106  1.1  eeh {
    107  1.1  eeh 	struct com_softc *sc = (void *)self;
    108  1.1  eeh 	struct ebus_attach_args *ea = aux;
    109  1.1  eeh 	struct kbd_ms_tty_attach_args kma;
    110  1.1  eeh #if (NKBD > 0) || (NMS > 0)
    111  1.1  eeh 	int maj;
    112  1.1  eeh #endif
    113  1.1  eeh 	int i;
    114  1.7  eeh 	int com_is_input;
    115  1.7  eeh 	int com_is_output;
    116  1.1  eeh 
    117  1.1  eeh 	sc->sc_iot = ea->ea_bustag;
    118  1.1  eeh 	sc->sc_iobase = EBUS_PADDR_FROM_REG(&ea->ea_regs[0]);
    119  1.1  eeh 	/*
    120  1.1  eeh 	 * Addresses that shoud be supplied by the prom:
    121  1.1  eeh 	 *	- normal com registers
    122  1.1  eeh 	 *	- ns873xx configuration registers
    123  1.1  eeh 	 *	- DMA space
    124  1.1  eeh 	 * The `com' driver does not use DMA accesses, so we can
    125  1.1  eeh 	 * ignore that for now.  We should enable the com port in
    126  1.1  eeh 	 * the ns873xx registers here. XXX
    127  1.1  eeh 	 *
    128  1.1  eeh 	 * Use the prom address if there.
    129  1.1  eeh 	 */
    130  1.1  eeh 	if (ea->ea_nvaddrs)
    131  1.1  eeh 		sc->sc_ioh = (bus_space_handle_t)ea->ea_vaddrs[0];
    132  1.1  eeh 	else if (ebus_bus_map(sc->sc_iot, 0,
    133  1.1  eeh 			      EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
    134  1.1  eeh 			      ea->ea_regs[0].size,
    135  1.1  eeh 			      BUS_SPACE_MAP_LINEAR,
    136  1.1  eeh 			      0, &sc->sc_ioh) != 0) {
    137  1.1  eeh 		printf(": can't map register space\n");
    138  1.1  eeh                 return;
    139  1.1  eeh 	}
    140  1.1  eeh 	sc->sc_hwflags = 0;
    141  1.1  eeh 	sc->sc_frequency = BAUD_BASE;
    142  1.1  eeh 
    143  1.1  eeh 	for (i = 0; i < ea->ea_nintrs; i++)
    144  1.5  eeh 		bus_intr_establish(ea->ea_bustag, ea->ea_intrs[i],
    145  1.5  eeh 		    IPL_SERIAL, 0, comintr, sc);
    146  1.1  eeh 
    147  1.1  eeh 	kma.kmta_consdev = NULL;
    148  1.7  eeh 
    149  1.7  eeh 	/* Figure out if we're the console. */
    150  1.7  eeh 	com_is_input = (ea->ea_node == OF_instance_to_package(OF_stdin()));
    151  1.7  eeh 	com_is_output = (ea->ea_node == OF_instance_to_package(OF_stdout()));
    152  1.7  eeh 
    153  1.7  eeh 	if (com_is_input || com_is_output) {
    154  1.1  eeh 		extern struct consdev comcons;
    155  1.7  eeh 		struct consdev *cn_orig;
    156  1.1  eeh 
    157  1.1  eeh 		/* Record some info to attach console. */
    158  1.1  eeh 		kma.kmta_baud = 9600;
    159  1.1  eeh 		kma.kmta_cflag = (CREAD | CS8 | HUPCL);
    160  1.5  eeh 
    161  1.5  eeh 		/* Attach com as the console. */
    162  1.7  eeh 		cn_orig = cn_tab;
    163  1.5  eeh 		if (comcnattach(sc->sc_iot, sc->sc_iobase, kma.kmta_baud,
    164  1.5  eeh 			sc->sc_frequency, kma.kmta_cflag)) {
    165  1.5  eeh 			printf("Error: comcnattach failed\n");
    166  1.5  eeh 		}
    167  1.7  eeh 		cn_tab = cn_orig;
    168  1.7  eeh 		if (com_is_input) {
    169  1.7  eeh 			cn_tab->cn_dev = comcons.cn_dev;
    170  1.7  eeh 			cn_tab->cn_probe = comcons.cn_probe;
    171  1.7  eeh 			cn_tab->cn_init = comcons.cn_init;
    172  1.7  eeh 			cn_tab->cn_getc = comcons.cn_getc;
    173  1.7  eeh 			cn_tab->cn_pollc = comcons.cn_pollc;
    174  1.7  eeh 		}
    175  1.7  eeh 		if (com_is_output) {
    176  1.7  eeh 			cn_tab->cn_putc = comcons.cn_putc;
    177  1.7  eeh 		}
    178  1.7  eeh 		kma.kmta_consdev = cn_tab;
    179  1.1  eeh 	}
    180  1.5  eeh 	/* Now attach the driver */
    181  1.5  eeh 	com_attach_subr(sc);
    182  1.1  eeh 
    183  1.1  eeh #if (NKBD > 0) || (NMS > 0)
    184  1.1  eeh 	kma.kmta_tp = sc->sc_tty;
    185  1.1  eeh /* If we figure out we're the console we should point this to our consdev */
    186  1.1  eeh 
    187  1.1  eeh 	/* locate the major number */
    188  1.1  eeh 	for (maj = 0; maj < nchrdev; maj++)
    189  1.1  eeh 		if (cdevsw[maj].d_open == comopen)
    190  1.1  eeh 			break;
    191  1.1  eeh 
    192  1.1  eeh 	kma.kmta_dev = makedev(maj, sc->sc_dev.dv_unit);
    193  1.1  eeh 
    194  1.1  eeh /* Attach 'em if we got 'em. */
    195  1.1  eeh #if (NKBD > 0)
    196  1.1  eeh 	kma.kmta_name = "keyboard";
    197  1.6  eeh 	if (OF_getproplen(ea->ea_node, kma.kmta_name) == 0) {
    198  1.1  eeh 		config_found(self, (void *)&kma, NULL);
    199  1.1  eeh 	}
    200  1.1  eeh #endif
    201  1.1  eeh #if (NMS > 0)
    202  1.1  eeh 	kma.kmta_name = "mouse";
    203  1.6  eeh 	if (OF_getproplen(ea->ea_node, kma.kmta_name) == 0) {
    204  1.1  eeh 		config_found(self, (void *)&kma, NULL);
    205  1.1  eeh 	}
    206  1.1  eeh #endif
    207  1.1  eeh #endif
    208  1.1  eeh 	if (kma.kmta_consdev) {
    209  1.1  eeh 		/*
    210  1.1  eeh 		 * If we're the keyboard then we need the original
    211  1.1  eeh 		 * cn_tab w/prom I/O, which sunkbd copied into kma.
    212  1.1  eeh 		 * Otherwise we want conscom which we copied into
    213  1.1  eeh 		 * kma.kmta_consdev.
    214  1.1  eeh 		 */
    215  1.1  eeh 		cn_tab = kma.kmta_consdev;
    216  1.1  eeh 	}
    217  1.1  eeh }
    218  1.1  eeh 
    219