terasic_de4led.c revision 239709
1121468Ssimokawa/*-
2121468Ssimokawa * Copyright (c) 2012 Robert N. M. Watson
3121468Ssimokawa * All rights reserved.
4121468Ssimokawa *
5121468Ssimokawa * This software was developed by SRI International and the University of
6121468Ssimokawa * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7136468Ssimokawa * ("CTSRD"), as part of the DARPA CRASH research programme.
8225214Srwatson *
9121468Ssimokawa * Redistribution and use in source and binary forms, with or without
10151350Syar * modification, are permitted provided that the following conditions
11170172Ssimokawa * are met:
12132091Ssimokawa * 1. Redistributions of source code must retain the above copyright
13121468Ssimokawa *    notice, this list of conditions and the following disclaimer.
14170172Ssimokawa * 2. Redistributions in binary form must reproduce the above copyright
15170172Ssimokawa *    notice, this list of conditions and the following disclaimer in the
16151350Syar *    documentation and/or other materials provided with the distribution.
17121468Ssimokawa *
18121468Ssimokawa * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19121468Ssimokawa * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20121468Ssimokawa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/terasic/de4led/terasic_de4led.c 239709 2012-08-26 09:21:59Z rwatson $");
33
34#include <sys/param.h>
35#include <sys/bus.h>
36#include <sys/lock.h>
37#include <sys/mutex.h>
38#include <sys/rman.h>
39
40#include <machine/bus.h>
41#include <machine/resource.h>
42
43#include <dev/led/led.h>
44#include <dev/terasic/de4led/terasic_de4led.h>
45
46static void
47terasic_de4led_update(struct terasic_de4led_softc *sc)
48{
49
50	TERASIC_DE4LED_LOCK_ASSERT(sc);
51
52	bus_write_1(sc->tdl_res, TERASIC_DE4LED_OFF_LED, sc->tdl_bits);
53}
54
55static void
56led_update(struct terasic_de4led_softc *sc, int bit, int onoff)
57{
58
59	TERASIC_DE4LED_LOCK(sc);
60	TERASIC_DE4LED_SETLED(sc, bit, onoff);
61	terasic_de4led_update(sc);
62	TERASIC_DE4LED_UNLOCK(sc);
63}
64
65static void
66led_0(void *arg, int onoff)
67{
68
69	led_update(arg, 0, onoff);
70}
71
72static void
73led_1(void *arg, int onoff)
74{
75
76	led_update(arg, 1, onoff);
77}
78
79static void
80led_2(void *arg, int onoff)
81{
82
83	led_update(arg, 2, onoff);
84}
85
86static void
87led_3(void *arg, int onoff)
88{
89
90	led_update(arg, 3, onoff);
91}
92
93static void
94led_4(void *arg, int onoff)
95{
96
97	led_update(arg, 4, onoff);
98}
99
100static void
101led_5(void *arg, int onoff)
102{
103
104	led_update(arg, 5, onoff);
105}
106
107static void
108led_6(void *arg, int onoff)
109{
110
111	led_update(arg, 6, onoff);
112}
113
114static void
115led_7(void *arg, int onoff)
116{
117
118	led_update(arg, 7, onoff);
119}
120
121void
122terasic_de4led_attach(struct terasic_de4led_softc *sc)
123{
124	const char *cmd;
125
126	TERASIC_DE4LED_LOCK_INIT(sc);
127
128	/*
129	 * Clear the LED array before we start.
130	 */
131	TERASIC_DE4LED_LOCK(sc);
132	TERASIC_DE4LED_CLEARBAR(sc);
133	terasic_de4led_update(sc);
134	TERASIC_DE4LED_UNLOCK(sc);
135
136	/*
137	 * Register the LED array with led(4).
138	 */
139	sc->tdl_leds[0] = led_create(led_0, sc, "de4led_0");
140	sc->tdl_leds[1] = led_create(led_1, sc, "de4led_1");
141	sc->tdl_leds[2] = led_create(led_2, sc, "de4led_2");
142	sc->tdl_leds[3] = led_create(led_3, sc, "de4led_3");
143	sc->tdl_leds[4] = led_create(led_4, sc, "de4led_4");
144	sc->tdl_leds[5] = led_create(led_5, sc, "de4led_5");
145	sc->tdl_leds[6] = led_create(led_6, sc, "de4led_6");
146	sc->tdl_leds[7] = led_create(led_7, sc, "de4led_7");
147
148	if (resource_string_value(device_get_name(sc->tdl_dev),
149	    sc->tdl_unit, "de4led_0_cmd", &cmd) == 0)
150		led_set("de4led_0", cmd);
151	if (resource_string_value(device_get_name(sc->tdl_dev),
152	    sc->tdl_unit, "de4led_1_cmd", &cmd) == 0)
153		led_set("de4led_1", cmd);
154	if (resource_string_value(device_get_name(sc->tdl_dev),
155	    sc->tdl_unit, "de4led_2_cmd", &cmd) == 0)
156		led_set("de4led_2", cmd);
157	if (resource_string_value(device_get_name(sc->tdl_dev),
158	    sc->tdl_unit, "de4led_3_cmd", &cmd) == 0)
159		led_set("de4led_3", cmd);
160	if (resource_string_value(device_get_name(sc->tdl_dev),
161	    sc->tdl_unit, "de4led_4_cmd", &cmd) == 0)
162		led_set("de4led_4", cmd);
163	if (resource_string_value(device_get_name(sc->tdl_dev),
164	    sc->tdl_unit, "de4led_5_cmd", &cmd) == 0)
165		led_set("de4led_5", cmd);
166	if (resource_string_value(device_get_name(sc->tdl_dev),
167	    sc->tdl_unit, "de4led_6_cmd", &cmd) == 0)
168		led_set("de4led_6", cmd);
169	if (resource_string_value(device_get_name(sc->tdl_dev),
170	    sc->tdl_unit, "de4led_7_cmd", &cmd) == 0)
171		led_set("de4led_7", cmd);
172}
173
174void
175terasic_de4led_detach(struct terasic_de4led_softc *sc)
176{
177	int i;
178
179	for (i = 0; i < 8; i++) {
180		led_destroy(sc->tdl_leds[i]);
181		sc->tdl_leds[i] = NULL;
182	}
183	TERASIC_DE4LED_LOCK(sc);
184	TERASIC_DE4LED_CLEARBAR(sc);
185	terasic_de4led_update(sc);
186	TERASIC_DE4LED_UNLOCK(sc);
187	TERASIC_DE4LED_LOCK_DESTROY(sc);
188}
189