Annotation of sys/arch/sparc64/dev/led.c, Revision 1.1.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