Home | History | Annotate | Line # | Download | only in vr
vrled.c revision 1.2.2.1
      1 /*	$NetBSD: vrled.c,v 1.2.2.1 2001/10/01 12:39:27 fvdl Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2000 SATO Kazumi. All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/param.h>
     29 #include <sys/systm.h>
     30 #include <sys/device.h>
     31 #include <sys/reboot.h>
     32 
     33 #include <machine/bus.h>
     34 #include <machine/config_hook.h>
     35 
     36 #include <hpcmips/vr/vripvar.h>
     37 #include <hpcmips/vr/vrledvar.h>
     38 #include <hpcmips/vr/vrledreg.h>
     39 
     40 
     41 #ifdef VRLEDDEBUG
     42 #ifndef VRLEDDEBUG_CONF
     43 #define VRLEDDEBUG_CONF 0
     44 #endif /* VRLEDDEBUG_CONF */
     45 int vrleddebug = VRLEDDEBUG_CONF;
     46 #define DPRINTF(arg) if (vrleddebug) printf arg;
     47 #define VPRINTF(arg) if (bootverbose||vrleddebug) printf arg;
     48 #else /* VRLEDDEBUG */
     49 #define DPRINTF(arg)
     50 #define VPRINTF(arg) if (bootverbose) printf arg;
     51 #endif /* VRLEDDEBUG */
     52 
     53 static int vrledmatch(struct device *, struct cfdata *, void *);
     54 static void vrledattach(struct device *, struct device *, void *);
     55 
     56 static void vrled_write(struct vrled_softc *, int, unsigned short);
     57 static unsigned short vrled_read(struct vrled_softc *, int);
     58 
     59 static void vrled_stop(struct vrled_softc *);
     60 static void vrled_on(struct vrled_softc *);
     61 static void vrled_blink(struct vrled_softc *);
     62 static void vrled_flash(struct vrled_softc *);
     63 static void vrled_change_state(struct vrled_softc *);
     64 static int vrled_event(void *, int, long, void *);
     65 
     66 int vrled_intr(void *);
     67 
     68 struct cfattach vrled_ca = {
     69 	sizeof(struct vrled_softc), vrledmatch, vrledattach
     70 };
     71 
     72 struct vrled_softc *this_led;
     73 
     74 static inline void
     75 vrled_write(struct vrled_softc *sc, int port, unsigned short val)
     76 {
     77 
     78 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
     79 }
     80 
     81 static inline unsigned short
     82 vrled_read(struct vrled_softc *sc, int port)
     83 {
     84 
     85 	return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, port));
     86 }
     87 
     88 static int
     89 vrledmatch(struct device *parent, struct cfdata *cf, void *aux)
     90 {
     91 
     92 	return (1);
     93 }
     94 
     95 static void
     96 vrledattach(struct device *parent, struct device *self, void *aux)
     97 {
     98 	struct vrled_softc *sc = (struct vrled_softc *)self;
     99 	struct vrip_attach_args *va = aux;
    100 
    101 	bus_space_tag_t iot = va->va_iot;
    102 	bus_space_handle_t ioh;
    103 
    104 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    105 		printf(": can't map bus space\n");
    106 		return;
    107 	}
    108 
    109 	sc->sc_iot = iot;
    110 	sc->sc_ioh = ioh;
    111 
    112 	if (!(sc->sc_handler =
    113 	    vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    114 		vrled_intr, sc))) {
    115 		printf (": can't map interrupt line.\n");
    116 		return;
    117 	}
    118 
    119 	printf("\n");
    120 	/* clear interrupt status */
    121 	vrled_write(sc, LEDINT_REG_W, LEDINT_ALL);
    122 
    123 	/* basic setup */
    124 	sc->sc_state_cnt = 1;
    125 	vrled_write(sc, LEDASTC_REG_W, 1); /* 1time */
    126 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    127 	vrled_stop(sc);
    128 
    129 	sc->sc_hook = config_hook(CONFIG_HOOK_SET,
    130 	    CONFIG_HOOK_LED, CONFIG_HOOK_SHARE, vrled_event, sc);
    131 
    132 	this_led = sc;
    133 }
    134 
    135 
    136 /*
    137  * LED interrupt handler.
    138  *
    139  */
    140 int
    141 vrled_intr(void *arg)
    142 {
    143         struct vrled_softc *sc = arg;
    144 	unsigned int intstat;
    145 
    146 	intstat = vrled_read(sc, LEDINT_REG_W);
    147 	/* clear interrupt status */
    148 	vrled_write(sc, LEDINT_REG_W, intstat);
    149 	if (intstat&LEDINT_AUTOSTOP) {
    150 		vrled_change_state(sc);
    151 	}
    152 	return (0);
    153 }
    154 
    155 /*
    156  * LED turn OFF
    157  *
    158  */
    159 void
    160 vrled_stop(struct vrled_softc *sc)
    161 {
    162 	vrled_write(sc, LEDHTS_REG_W, LEDHTS_DIV16SEC);
    163 	vrled_write(sc, LEDLTS_REG_W, LEDLTS_4SEC);
    164 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    165 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    166 
    167 	sc->sc_state = LEDOFF;
    168 	sc->sc_next = LEDOFF;
    169 }
    170 
    171 /*
    172  * LED turn ON
    173  *
    174  */
    175 void
    176 vrled_on(struct vrled_softc *sc)
    177 {
    178 	vrled_write(sc, LEDHTS_REG_W, LEDHTS_SEC);
    179 	vrled_write(sc, LEDLTS_REG_W, LEDLTS_DIV16SEC);
    180 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    181 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    182 
    183 	sc->sc_state = LEDON;
    184 	sc->sc_next = LEDON;
    185 }
    186 
    187 /*
    188  * LED blink
    189  *
    190  */
    191 void
    192 vrled_blink(struct vrled_softc *sc)
    193 {
    194 	int ledhts;
    195 	int ledlts;
    196 
    197 	switch (sc->sc_next) {
    198 	case LED1SB:
    199 		ledhts = LEDHTS_DIV2SEC;
    200 		ledlts = LEDLTS_DIV2SEC;
    201 		break;
    202 	case LED2SB:
    203 		ledhts = LEDHTS_SEC;
    204 		ledlts = LEDLTS_SEC;
    205 		break;
    206 	default:
    207 		vrled_stop(sc);
    208 		return;
    209 	}
    210 
    211 	vrled_write(sc, LEDHTS_REG_W, ledhts);
    212 	vrled_write(sc, LEDLTS_REG_W, ledlts);
    213 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    214 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    215 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    216 
    217 	sc->sc_state = sc->sc_next;
    218 }
    219 
    220 /*
    221  * LED flash once
    222  *
    223  */
    224 void
    225 vrled_flash(struct vrled_softc *sc)
    226 {
    227 	int ledhts;
    228 	int ledlts;
    229 
    230 	switch (sc->sc_next) {
    231 	case LED8DIVF:
    232 		ledhts = LEDHTS_DIV16SEC;
    233 		ledlts = LEDLTS_DIV16SEC;
    234 		break;
    235 	case LED4DIVF:
    236 		ledhts = LEDHTS_DIV8SEC;
    237 		ledlts = LEDLTS_DIV8SEC;
    238 		break;
    239 	case LED2DIVF:
    240 		ledhts = LEDHTS_DIV4SEC;
    241 		ledlts = LEDLTS_DIV4SEC;
    242 		break;
    243 	case LED1SF:
    244 		ledhts = LEDHTS_DIV2SEC;
    245 		ledlts = LEDLTS_DIV2SEC;
    246 		break;
    247 	default:
    248 		vrled_stop(sc);
    249 		return;
    250 	}
    251 
    252 	vrled_write(sc, LEDHTS_REG_W, ledhts);
    253 	vrled_write(sc, LEDLTS_REG_W, ledlts);
    254 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    255 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    256 
    257 	sc->sc_state = sc->sc_next;
    258 	sc->sc_next = LEDOFF;
    259 	sc->sc_state_cnt = 1;
    260 }
    261 
    262 /*
    263  * Change LED state
    264  *
    265  */
    266 void
    267 vrled_change_state(struct vrled_softc *sc)
    268 {
    269 
    270 	switch (sc->sc_next) {
    271 	case LEDOFF:
    272 		vrled_stop(sc);
    273 		break;
    274 	case LEDON:
    275 		vrled_on(sc);
    276 		break;
    277 	case LED1SB:
    278 	case LED2SB:
    279 		vrled_blink(sc);
    280 		break;
    281 	case LED8DIVF:
    282 	case LED4DIVF:
    283 	case LED2DIVF:
    284 	case LED1SF:
    285 		vrled_flash(sc);
    286 		break;
    287 	default:
    288 		vrled_stop(sc);
    289 		break;
    290 	}
    291 }
    292 
    293 /*
    294  * Set LED state
    295  *
    296  */
    297 void
    298 vrled_set_state(struct vrled_softc *sc, vrled_status state)
    299 {
    300 
    301 	int ledstate;
    302 
    303 	ledstate = vrled_read(sc, LEDCNT_REG_W);
    304 	if (ledstate&LEDCNT_BLINK) { /* currently processing */
    305 		if (sc->sc_next == state)
    306 			sc->sc_state_cnt++;
    307 		switch (sc->sc_next) {
    308 		case LEDOFF:
    309 		case LEDON:
    310 			sc->sc_next = state;
    311 			break;
    312 		case LED8DIVF:
    313 		case LED4DIVF:
    314 		case LED2DIVF:
    315 		case LED1SF:
    316 			switch (state) {
    317 			case LEDOFF:
    318 			case LED8DIVF:
    319 			case LED4DIVF:
    320 			case LED2DIVF:
    321 			case LED1SF:
    322 				sc->sc_next = state;
    323 				break;
    324 			default:
    325 				break;
    326 			}
    327 			break;
    328 		case LED1SB:
    329 		case LED2SB:
    330 			switch (state) {
    331 			case LEDOFF:
    332 			case LEDON:
    333 			case LED1SB:
    334 			case LED2SB:
    335 				sc->sc_next = state;
    336 				break;
    337 			default:
    338 				break;
    339 			}
    340 			break;
    341 		default:
    342 			sc->sc_next = LEDOFF;
    343 			break;
    344 		}
    345 		return;
    346 	}
    347 	sc->sc_next = state;
    348 	vrled_change_state(sc);
    349 }
    350 
    351 /*
    352  * LED config hook events
    353  *
    354  */
    355 int
    356 vrled_event(void *ctx, int type, long id, void *msg)
    357 {
    358 	struct vrled_softc *sc = (struct vrled_softc *)ctx;
    359         int why =*(int *)msg;
    360 
    361 	if (type != CONFIG_HOOK_SET
    362 	    || id != CONFIG_HOOK_LED)
    363 		return (1);
    364 	if (msg == NULL)
    365 		return (1);
    366 
    367         switch (why) {
    368         case CONFIG_HOOK_LED_OFF:
    369 		vrled_set_state(sc, LEDOFF);
    370                 break;
    371         case CONFIG_HOOK_LED_ON:
    372 		vrled_set_state(sc, LEDON);
    373                 break;
    374         case CONFIG_HOOK_LED_FLASH:
    375 		vrled_set_state(sc, LED8DIVF);
    376                 break;
    377         case CONFIG_HOOK_LED_FLASH2:
    378 		vrled_set_state(sc, LED4DIVF);
    379                 break;
    380         case CONFIG_HOOK_LED_FLASH5:
    381 		vrled_set_state(sc, LED2DIVF);
    382                 break;
    383         case CONFIG_HOOK_LED_BLINK:
    384 		vrled_set_state(sc, LED1SB);
    385                 break;
    386         case CONFIG_HOOK_LED_BLINK2:
    387 		vrled_set_state(sc, LED2SB);
    388                 break;
    389 	default:
    390 		vrled_set_state(sc, LEDOFF);
    391         }
    392         return (0);
    393 }
    394 
    395 /* end */
    396