Home | History | Annotate | Line # | Download | only in dev
auxio.c revision 1.22.12.1
      1  1.22.12.1  jdolecek /*	$NetBSD: auxio.c,v 1.22.12.1 2017/12/03 11:36:44 jdolecek Exp $	*/
      2        1.1       mrg 
      3        1.1       mrg /*
      4  1.22.12.1  jdolecek  * Copyright (c) 2000, 2001, 2015 Matthew R. Green
      5        1.1       mrg  * All rights reserved.
      6        1.1       mrg  *
      7        1.1       mrg  * Redistribution and use in source and binary forms, with or without
      8        1.1       mrg  * modification, are permitted provided that the following conditions
      9        1.1       mrg  * are met:
     10        1.1       mrg  * 1. Redistributions of source code must retain the above copyright
     11        1.1       mrg  *    notice, this list of conditions and the following disclaimer.
     12        1.1       mrg  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1       mrg  *    notice, this list of conditions and the following disclaimer in the
     14        1.1       mrg  *    documentation and/or other materials provided with the distribution.
     15        1.1       mrg  *
     16        1.1       mrg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17        1.1       mrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18        1.1       mrg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19        1.1       mrg  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20        1.1       mrg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21        1.1       mrg  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22        1.1       mrg  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23        1.1       mrg  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24        1.1       mrg  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25        1.1       mrg  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26        1.1       mrg  * SUCH DAMAGE.
     27        1.1       mrg  */
     28        1.1       mrg 
     29        1.1       mrg /*
     30        1.2       mrg  * AUXIO registers support on the sbus & ebus2, used for the floppy driver
     31        1.2       mrg  * and to control the system LED, for the BLINK option.
     32        1.1       mrg  */
     33       1.11     lukem 
     34       1.11     lukem #include <sys/cdefs.h>
     35  1.22.12.1  jdolecek __KERNEL_RCSID(0, "$NetBSD: auxio.c,v 1.22.12.1 2017/12/03 11:36:44 jdolecek Exp $");
     36       1.10      heas 
     37       1.10      heas #include "opt_auxio.h"
     38        1.1       mrg 
     39        1.1       mrg #include <sys/param.h>
     40        1.1       mrg #include <sys/systm.h>
     41        1.2       mrg #include <sys/kernel.h>
     42        1.2       mrg #include <sys/callout.h>
     43        1.1       mrg #include <sys/errno.h>
     44        1.1       mrg #include <sys/device.h>
     45        1.1       mrg #include <sys/malloc.h>
     46        1.1       mrg 
     47        1.1       mrg #include <machine/autoconf.h>
     48        1.1       mrg #include <machine/cpu.h>
     49        1.1       mrg 
     50        1.2       mrg #include <dev/ebus/ebusreg.h>
     51        1.4       mrg #include <dev/ebus/ebusvar.h>
     52       1.21  nakayama #include <dev/sbus/sbusvar.h>
     53        1.1       mrg #include <sparc64/dev/auxioreg.h>
     54       1.16   jnemeth #include <sparc64/dev/auxiovar.h>
     55        1.2       mrg 
     56  1.22.12.1  jdolecek static uint32_t	auxio_read_led(struct auxio_softc *);
     57  1.22.12.1  jdolecek static void	auxio_write_led(struct auxio_softc *, uint32_t);
     58  1.22.12.1  jdolecek void	auxio_attach_common(struct auxio_softc *);
     59        1.2       mrg 
     60  1.22.12.1  jdolecek extern struct cfdriver auxio_cd;
     61        1.1       mrg 
     62  1.22.12.1  jdolecek static __inline__ uint32_t
     63  1.22.12.1  jdolecek auxio_read_led(struct auxio_softc *sc)
     64  1.22.12.1  jdolecek {
     65  1.22.12.1  jdolecek 	uint32_t led;
     66        1.1       mrg 
     67  1.22.12.1  jdolecek 	if (sc->sc_flags & AUXIO_EBUS)
     68  1.22.12.1  jdolecek 		led = le32toh(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
     69  1.22.12.1  jdolecek 	else
     70  1.22.12.1  jdolecek 		led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
     71        1.1       mrg 
     72  1.22.12.1  jdolecek 	return led;
     73  1.22.12.1  jdolecek }
     74        1.8   thorpej 
     75  1.22.12.1  jdolecek static __inline__ void
     76  1.22.12.1  jdolecek auxio_write_led(struct auxio_softc *sc, uint32_t led)
     77  1.22.12.1  jdolecek {
     78        1.1       mrg 
     79  1.22.12.1  jdolecek 	if (sc->sc_flags & AUXIO_EBUS)
     80  1.22.12.1  jdolecek 		bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
     81  1.22.12.1  jdolecek 	else
     82  1.22.12.1  jdolecek 		bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
     83  1.22.12.1  jdolecek }
     84       1.16   jnemeth 
     85        1.2       mrg #ifdef BLINK
     86       1.17        ad static callout_t blink_ch;
     87        1.2       mrg static void auxio_blink(void *);
     88        1.2       mrg 
     89       1.12       mrg /* let someone disable it if it's already turned on; XXX sysctl? */
     90       1.12       mrg int do_blink = 1;
     91       1.12       mrg 
     92        1.2       mrg static void
     93       1.15       cdi auxio_blink(void *x)
     94        1.2       mrg {
     95        1.2       mrg 	struct auxio_softc *sc = x;
     96        1.2       mrg 	int s;
     97       1.15       cdi 	uint32_t led;
     98        1.2       mrg 
     99       1.12       mrg 	if (do_blink == 0)
    100       1.12       mrg 		return;
    101       1.12       mrg 
    102  1.22.12.1  jdolecek 	mutex_enter(&sc->sc_lock);
    103  1.22.12.1  jdolecek 	led = auxio_read_led(sc);
    104       1.13    bouyer 	led = led ^ AUXIO_LED_LED;
    105  1.22.12.1  jdolecek 	auxio_write_led(sc, led);
    106  1.22.12.1  jdolecek 	mutex_exit(&sc->sc_lock);
    107        1.2       mrg 
    108        1.2       mrg 	/*
    109        1.2       mrg 	 * Blink rate is:
    110        1.2       mrg 	 *	full cycle every second if completely idle (loadav = 0)
    111        1.2       mrg 	 *	full cycle every 2 seconds if loadav = 1
    112        1.2       mrg 	 *	full cycle every 3 seconds if loadav = 2
    113        1.2       mrg 	 * etc.
    114        1.2       mrg 	 */
    115        1.2       mrg 	s = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
    116        1.2       mrg 	callout_reset(&blink_ch, s, auxio_blink, sc);
    117        1.2       mrg }
    118        1.2       mrg #endif
    119        1.2       mrg 
    120        1.2       mrg void
    121       1.15       cdi auxio_attach_common(struct auxio_softc *sc)
    122        1.2       mrg {
    123        1.2       mrg 	static int do_once = 1;
    124        1.2       mrg 
    125        1.2       mrg 	/* only start one blinker */
    126        1.2       mrg 	if (do_once) {
    127  1.22.12.1  jdolecek 		mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
    128  1.22.12.1  jdolecek #ifdef BLINK
    129  1.22.12.1  jdolecek 		callout_init(&blink_ch, CALLOUT_MPSAFE);
    130        1.2       mrg 		auxio_blink(sc);
    131  1.22.12.1  jdolecek #endif
    132        1.2       mrg 		do_once = 0;
    133        1.2       mrg 	}
    134        1.2       mrg 	printf("\n");
    135        1.2       mrg }
    136        1.2       mrg 
    137        1.1       mrg int
    138       1.16   jnemeth auxio_fd_control(u_int32_t bits)
    139       1.16   jnemeth {
    140       1.16   jnemeth 	struct auxio_softc *sc;
    141       1.16   jnemeth 	u_int32_t led;
    142       1.16   jnemeth 
    143       1.16   jnemeth 	if (auxio_cd.cd_ndevs == 0) {
    144       1.16   jnemeth 		return ENXIO;
    145       1.16   jnemeth 	}
    146       1.16   jnemeth 
    147       1.16   jnemeth 	/*
    148       1.16   jnemeth 	 * XXX This does not handle > 1 auxio correctly.
    149       1.16   jnemeth 	 * We'll assume the floppy drive is tied to first auxio found.
    150       1.16   jnemeth 	 */
    151       1.20    cegger 	sc = device_lookup_private(&auxio_cd, 0);
    152  1.22.12.1  jdolecek 	if (!sc) {
    153  1.22.12.1  jdolecek 		return ENXIO;
    154  1.22.12.1  jdolecek 	}
    155       1.16   jnemeth 
    156  1.22.12.1  jdolecek 	mutex_enter(&sc->sc_lock);
    157  1.22.12.1  jdolecek 	led = auxio_read_led(sc);
    158       1.16   jnemeth 	led = (led & ~AUXIO_LED_FLOPPY_MASK) | bits;
    159  1.22.12.1  jdolecek 	auxio_write_led(sc, led);
    160  1.22.12.1  jdolecek 	mutex_exit(&sc->sc_lock);
    161       1.16   jnemeth 
    162       1.16   jnemeth 	return 0;
    163       1.16   jnemeth }
    164