Home | History | Annotate | Line # | Download | only in vr
vrled.c revision 1.1
      1 /*	$NetBSD: vrled.c,v 1.1 2000/10/03 03:13:05 sato 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 __P((struct device *, struct cfdata *, void *));
     54 static void vrledattach __P((struct device *, struct device *, void *));
     55 
     56 static void vrled_write __P((struct vrled_softc *, int, unsigned short));
     57 static unsigned short vrled_read __P((struct vrled_softc *, int));
     58 
     59 static void vrled_stop __P((struct vrled_softc *));
     60 static void vrled_on __P((struct vrled_softc *));
     61 static void vrled_blink __P((struct vrled_softc *));
     62 static void vrled_flash __P((struct vrled_softc *));
     63 static void vrled_change_state __P((struct vrled_softc *));
     64 static int vrled_event __P((void *, int, long, void *));
     65 
     66 int vrled_intr __P((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(sc, port, val)
     76 	struct vrled_softc *sc;
     77 	int port;
     78 	unsigned short val;
     79 {
     80 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
     81 }
     82 
     83 static inline unsigned short
     84 vrled_read(sc, port)
     85 	struct vrled_softc *sc;
     86 	int port;
     87 {
     88 	return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port);
     89 }
     90 
     91 static int
     92 vrledmatch(parent, cf, aux)
     93 	struct device *parent;
     94 	struct cfdata *cf;
     95 	void *aux;
     96 {
     97 	return 1;
     98 }
     99 
    100 static void
    101 vrledattach(parent, self, aux)
    102 	struct device *parent;
    103 	struct device *self;
    104 	void *aux;
    105 {
    106 	struct vrled_softc *sc = (struct vrled_softc *)self;
    107 	struct vrip_attach_args *va = aux;
    108 
    109 	bus_space_tag_t iot = va->va_iot;
    110 	bus_space_handle_t ioh;
    111 
    112 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    113 		printf(": can't map bus space\n");
    114 		return;
    115 	}
    116 
    117 	sc->sc_iot = iot;
    118 	sc->sc_ioh = ioh;
    119 
    120 	if (!(sc->sc_handler =
    121 	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    122 				  vrled_intr, sc))) {
    123 		printf (": can't map interrupt line.\n");
    124 		return;
    125 	}
    126 
    127 	printf("\n");
    128 	/* clear interrupt status */
    129 	vrled_write(sc, LEDINT_REG_W, LEDINT_ALL);
    130 
    131 	/* basic setup */
    132 	sc->sc_state_cnt = 1;
    133 	vrled_write(sc, LEDASTC_REG_W, 1); /* 1time */
    134 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    135 	vrled_stop(sc);
    136 
    137 	sc->sc_hook = config_hook(CONFIG_HOOK_POWERCONTROL,
    138 					CONFIG_HOOK_POWERCONTROL_LED,
    139 					CONFIG_HOOK_SHARE,
    140 					vrled_event, sc);
    141 	this_led = sc;
    142 }
    143 
    144 
    145 /*
    146  * LED interrupt handler.
    147  *
    148  */
    149 int
    150 vrled_intr(arg)
    151 	void *arg;
    152 {
    153         struct vrled_softc *sc = arg;
    154 	unsigned int intstat;
    155 
    156 	intstat = vrled_read(sc, LEDINT_REG_W);
    157 	/* clear interrupt status */
    158 	vrled_write(sc, LEDINT_REG_W, intstat);
    159 	if (intstat&LEDINT_AUTOSTOP) {
    160 		vrled_change_state(sc);
    161 	}
    162 	return 0;
    163 }
    164 
    165 /*
    166  * LED turn OFF
    167  *
    168  */
    169 void
    170 vrled_stop(sc)
    171 struct vrled_softc *sc;
    172 {
    173 	vrled_write(sc, LEDHTS_REG_W, LEDHTS_DIV16SEC);
    174 	vrled_write(sc, LEDLTS_REG_W, LEDLTS_4SEC);
    175 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    176 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    177 
    178 	sc->sc_state = LEDOFF;
    179 	sc->sc_next = LEDOFF;
    180 }
    181 
    182 /*
    183  * LED turn ON
    184  *
    185  */
    186 void
    187 vrled_on(sc)
    188 struct vrled_softc *sc;
    189 {
    190 	vrled_write(sc, LEDHTS_REG_W, LEDHTS_SEC);
    191 	vrled_write(sc, LEDLTS_REG_W, LEDLTS_DIV16SEC);
    192 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    193 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    194 
    195 	sc->sc_state = LEDON;
    196 	sc->sc_next = LEDON;
    197 }
    198 
    199 /*
    200  * LED blink
    201  *
    202  */
    203 void
    204 vrled_blink(sc)
    205 struct vrled_softc *sc;
    206 {
    207 	int ledhts;
    208 	int ledlts;
    209 
    210 	switch (sc->sc_next) {
    211 	case LED1SB:
    212 		ledhts = LEDHTS_DIV2SEC;
    213 		ledlts = LEDLTS_DIV2SEC;
    214 		break;
    215 	case LED2SB:
    216 		ledhts = LEDHTS_SEC;
    217 		ledlts = LEDLTS_SEC;
    218 		break;
    219 	default:
    220 		vrled_stop(sc);
    221 		return;
    222 	}
    223 
    224 	vrled_write(sc, LEDHTS_REG_W, ledhts);
    225 	vrled_write(sc, LEDLTS_REG_W, ledlts);
    226 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    227 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP);
    228 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    229 
    230 	sc->sc_state = sc->sc_next;
    231 }
    232 
    233 /*
    234  * LED flash once
    235  *
    236  */
    237 void
    238 vrled_flash(sc)
    239 struct vrled_softc *sc;
    240 {
    241 	int ledhts;
    242 	int ledlts;
    243 
    244 	switch (sc->sc_next) {
    245 	case LED8DIVF:
    246 		ledhts = LEDHTS_DIV16SEC;
    247 		ledlts = LEDLTS_DIV16SEC;
    248 		break;
    249 	case LED4DIVF:
    250 		ledhts = LEDHTS_DIV8SEC;
    251 		ledlts = LEDLTS_DIV8SEC;
    252 		break;
    253 	case LED2DIVF:
    254 		ledhts = LEDHTS_DIV4SEC;
    255 		ledlts = LEDLTS_DIV4SEC;
    256 		break;
    257 	case LED1SF:
    258 		ledhts = LEDHTS_DIV2SEC;
    259 		ledlts = LEDLTS_DIV2SEC;
    260 		break;
    261 	default:
    262 		vrled_stop(sc);
    263 		return;
    264 	}
    265 
    266 	vrled_write(sc, LEDHTS_REG_W, ledhts);
    267 	vrled_write(sc, LEDLTS_REG_W, ledlts);
    268 	vrled_write(sc, LEDASTC_REG_W, 2); /* 2time */
    269 	vrled_write(sc, LEDCNT_REG_W, LEDCNT_AUTOSTOP|LEDCNT_BLINK);
    270 
    271 	sc->sc_state = sc->sc_next;
    272 	sc->sc_next = LEDOFF;
    273 	sc->sc_state_cnt = 1;
    274 }
    275 
    276 /*
    277  * Change LED state
    278  *
    279  */
    280 void
    281 vrled_change_state(sc)
    282 struct vrled_softc *sc;
    283 {
    284 
    285 	switch (sc->sc_next) {
    286 	case LEDOFF:
    287 		vrled_stop(sc);
    288 		break;
    289 	case LEDON:
    290 		vrled_on(sc);
    291 		break;
    292 	case LED1SB:
    293 	case LED2SB:
    294 		vrled_blink(sc);
    295 		break;
    296 	case LED8DIVF:
    297 	case LED4DIVF:
    298 	case LED2DIVF:
    299 	case LED1SF:
    300 		vrled_flash(sc);
    301 		break;
    302 	default:
    303 		vrled_stop(sc);
    304 		break;
    305 	}
    306 }
    307 
    308 /*
    309  * Set LED state
    310  *
    311  */
    312 void
    313 vrled_set_state(sc, state)
    314 struct vrled_softc *sc;
    315 vrled_status state;
    316 {
    317 
    318 	int ledstate;
    319 
    320 	ledstate = vrled_read(sc, LEDCNT_REG_W);
    321 	if (ledstate&LEDCNT_BLINK) { /* currently processing */
    322 		if (sc->sc_next == state)
    323 			sc->sc_state_cnt++;
    324 		switch (sc->sc_next) {
    325 		case LEDOFF:
    326 		case LEDON:
    327 			sc->sc_next = state;
    328 			break;
    329 		case LED8DIVF:
    330 		case LED4DIVF:
    331 		case LED2DIVF:
    332 		case LED1SF:
    333 			switch (state) {
    334 			case LEDOFF:
    335 			case LED8DIVF:
    336 			case LED4DIVF:
    337 			case LED2DIVF:
    338 			case LED1SF:
    339 				sc->sc_next = state;
    340 				break;
    341 			default:
    342 				break;
    343 			}
    344 			break;
    345 		case LED1SB:
    346 		case LED2SB:
    347 			switch (state) {
    348 			case LEDOFF:
    349 			case LEDON:
    350 			case LED1SB:
    351 			case LED2SB:
    352 				sc->sc_next = state;
    353 				break;
    354 			default:
    355 				break;
    356 			}
    357 			break;
    358 		default:
    359 			sc->sc_next = LEDOFF;
    360 			break;
    361 		}
    362 		return;
    363 	}
    364 	sc->sc_next = state;
    365 	vrled_change_state(sc);
    366 }
    367 
    368 /*
    369  * LED config hook events
    370  *
    371  */
    372 int
    373 vrled_event(ctx, type, id, msg)
    374 	void *ctx;
    375         int type;
    376         long id;
    377         void *msg;
    378 {
    379 	struct vrled_softc *sc = (struct vrled_softc *)ctx;
    380         int why =(int)msg;
    381 
    382 	if (type != CONFIG_HOOK_POWERCONTROL
    383 		|| id != CONFIG_HOOK_POWERCONTROL_LED)
    384 		return 1;
    385 
    386         switch (why) {
    387         case PWCTL_LED_OFF:
    388 		vrled_set_state(sc, LEDOFF);
    389                 break;
    390         case PWCTL_LED_ON:
    391 		vrled_set_state(sc, LEDON);
    392                 break;
    393         case PWCTL_LED_FLASH:
    394 		vrled_set_state(sc, LED8DIVF);
    395                 break;
    396         case PWCTL_LED_FLASH2:
    397 		vrled_set_state(sc, LED4DIVF);
    398                 break;
    399         case PWCTL_LED_FLASH5:
    400 		vrled_set_state(sc, LED2DIVF);
    401                 break;
    402         case PWCTL_LED_BLINK:
    403 		vrled_set_state(sc, LED1SB);
    404                 break;
    405         case PWCTL_LED_BLINK2:
    406 		vrled_set_state(sc, LED2SB);
    407                 break;
    408 	default:
    409 		vrled_set_state(sc, LEDOFF);
    410         }
    411         return (0);
    412 }
    413 
    414 /* end */
    415