Annotation of sys/arch/sparc64/dev/led.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: led.c,v 1.1 2007/05/29 04:08:02 kettenis Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2007 Mark Kettenis
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: /*
! 20: * Driver for leds on Fire V215/V245.
! 21: */
! 22:
! 23: #include <sys/param.h>
! 24: #include <sys/kernel.h>
! 25: #include <sys/device.h>
! 26: #include <sys/malloc.h>
! 27: #include <sys/systm.h>
! 28: #include <sys/timeout.h>
! 29:
! 30: #include <machine/autoconf.h>
! 31: #include <machine/bus.h>
! 32: #include <machine/cpu.h>
! 33:
! 34: #include <sparc64/dev/ebusreg.h>
! 35: #include <sparc64/dev/ebusvar.h>
! 36:
! 37: /*
! 38: * Register access is indirect, through an address and data port.
! 39: */
! 40:
! 41: #define EPIC_DATA 0x40
! 42: #define EPIC_ADDR 0x41
! 43: #define EPIC_WRITE_MASK 0x80
! 44:
! 45: #define EPIC_FW_VERSION 0x05
! 46: #define EPIC_LED_STATE0 0x06
! 47:
! 48: #define EPIC_ALERT_LED_MASK 0x0C
! 49: #define EPIC_ALERT_LED_OFF 0x00
! 50: #define EPIC_ALERT_LED_ON 0x04
! 51:
! 52: #define EPIC_POWER_LED_MASK 0x30
! 53: #define EPIC_POWER_LED_OFF 0x00
! 54: #define EPIC_POWER_LED_ON 0x10
! 55: #define EPIC_POWER_LED_SB_BLINK 0x20
! 56: #define EPIC_POWER_LED_FAST_BLINK 0x30
! 57:
! 58: struct led_softc {
! 59: struct device sc_dv;
! 60: bus_space_tag_t sc_iot;
! 61: bus_space_handle_t sc_ioh;
! 62:
! 63: struct timeout sc_to;
! 64: int sc_on;
! 65: struct blink_led sc_blink;
! 66: };
! 67:
! 68: int led_match(struct device *, void *, void *);
! 69: void led_attach(struct device *, struct device *, void *);
! 70:
! 71: struct cfattach led_ca = {
! 72: sizeof(struct led_softc), led_match, led_attach
! 73: };
! 74:
! 75: struct cfdriver led_cd = {
! 76: NULL, "led", DV_DULL
! 77: };
! 78:
! 79: void led_blink(void *, int);
! 80: void led_blink_finish(void *);
! 81:
! 82: int
! 83: led_match(struct device *parent, void *cf, void *aux)
! 84: {
! 85: struct ebus_attach_args *ea = aux;
! 86: char *str;
! 87:
! 88: if (strcmp("env-monitor", ea->ea_name) != 0)
! 89: return (0);
! 90:
! 91: str = getpropstring(ea->ea_node, "compatible");
! 92: if (strcmp(str, "epic") == 0)
! 93: return (1);
! 94:
! 95: return (0);
! 96: }
! 97:
! 98: void
! 99: led_attach(struct device *parent, struct device *self, void *aux)
! 100: {
! 101: struct led_softc *sc = (void *)self;
! 102: struct ebus_attach_args *ea = aux;
! 103: int rev;
! 104:
! 105: if (ebus_bus_map(ea->ea_iotag, 0,
! 106: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
! 107: ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
! 108: sc->sc_iot = ea->ea_iotag;
! 109: } else if (ebus_bus_map(ea->ea_memtag, 0,
! 110: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
! 111: ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
! 112: sc->sc_iot = ea->ea_memtag;
! 113: } else {
! 114: printf("%s: can't map register space\n", self->dv_xname);
! 115: return;
! 116: }
! 117:
! 118: bus_space_write_1(sc->sc_iot, sc->sc_ioh, EPIC_ADDR, EPIC_FW_VERSION);
! 119: delay(10000);
! 120: rev = bus_space_read_1(sc->sc_iot, sc->sc_ioh, EPIC_DATA);
! 121: printf(": rev 0x%02x\n", rev);
! 122:
! 123: /* Turn off the alert LED. */
! 124: bus_space_write_1(sc->sc_iot, sc->sc_ioh,
! 125: EPIC_WRITE_MASK, EPIC_ALERT_LED_MASK);
! 126: bus_space_write_1(sc->sc_iot, sc->sc_ioh,
! 127: EPIC_ADDR, EPIC_LED_STATE0);
! 128: delay(10000);
! 129: bus_space_write_1(sc->sc_iot, sc->sc_ioh,
! 130: EPIC_DATA, EPIC_ALERT_LED_OFF);
! 131:
! 132: timeout_set(&sc->sc_to, led_blink_finish, sc);
! 133:
! 134: sc->sc_blink.bl_func = led_blink;
! 135: sc->sc_blink.bl_arg = sc;
! 136: blink_led_register(&sc->sc_blink);
! 137: }
! 138:
! 139: void
! 140: led_blink(void *v, int on)
! 141: {
! 142: struct led_softc *sc = v;
! 143:
! 144: sc->sc_on = on;
! 145: bus_space_write_1(sc->sc_iot, sc->sc_ioh, EPIC_ADDR, EPIC_LED_STATE0);
! 146: timeout_add(&sc->sc_to, max(1, hz / 100));
! 147: }
! 148:
! 149: void
! 150: led_blink_finish(void *v)
! 151: {
! 152: struct led_softc *sc = v;
! 153: u_int8_t reg;
! 154:
! 155: if (sc->sc_on)
! 156: reg = EPIC_ALERT_LED_ON;
! 157: else
! 158: reg = EPIC_ALERT_LED_OFF;
! 159:
! 160: bus_space_write_1(sc->sc_iot, sc->sc_ioh, EPIC_DATA, reg);
! 161: }
CVSweb