terasic_de4led.c revision 245380
1240116Smarcel/*-
2240116Smarcel * Copyright (c) 2012 Robert N. M. Watson
3240116Smarcel * All rights reserved.
4240116Smarcel *
5240116Smarcel * This software was developed by SRI International and the University of
6240116Smarcel * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7240116Smarcel * ("CTSRD"), as part of the DARPA CRASH research programme.
8240116Smarcel *
9240116Smarcel * Redistribution and use in source and binary forms, with or without
10240116Smarcel * modification, are permitted provided that the following conditions
11240116Smarcel * are met:
12240116Smarcel * 1. Redistributions of source code must retain the above copyright
13240116Smarcel *    notice, this list of conditions and the following disclaimer.
14240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
15240116Smarcel *    notice, this list of conditions and the following disclaimer in the
16240116Smarcel *    documentation and/or other materials provided with the distribution.
17240116Smarcel *
18240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19240116Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20240116Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21240116Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22240116Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24240116Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26240116Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27240116Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28240116Smarcel * SUCH DAMAGE.
29240116Smarcel */
30240116Smarcel
31240116Smarcel#include <sys/cdefs.h>
32240116Smarcel__FBSDID("$FreeBSD: head/sys/dev/terasic/de4led/terasic_de4led.c 245380 2013-01-13 16:57:11Z rwatson $");
33240116Smarcel
34240116Smarcel#include <sys/param.h>
35240116Smarcel#include <sys/bus.h>
36240116Smarcel#include <sys/lock.h>
37240116Smarcel#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
46devclass_t	terasic_de4led_devclass;
47
48static void
49terasic_de4led_update(struct terasic_de4led_softc *sc)
50{
51
52	TERASIC_DE4LED_LOCK_ASSERT(sc);
53
54	bus_write_1(sc->tdl_res, TERASIC_DE4LED_OFF_LED, sc->tdl_bits);
55}
56
57static void
58led_update(struct terasic_de4led_softc *sc, int bit, int onoff)
59{
60
61	TERASIC_DE4LED_LOCK(sc);
62	TERASIC_DE4LED_SETLED(sc, bit, onoff);
63	terasic_de4led_update(sc);
64	TERASIC_DE4LED_UNLOCK(sc);
65}
66
67static void
68led_0(void *arg, int onoff)
69{
70
71	led_update(arg, 0, onoff);
72}
73
74static void
75led_1(void *arg, int onoff)
76{
77
78	led_update(arg, 1, onoff);
79}
80
81static void
82led_2(void *arg, int onoff)
83{
84
85	led_update(arg, 2, onoff);
86}
87
88static void
89led_3(void *arg, int onoff)
90{
91
92	led_update(arg, 3, onoff);
93}
94
95static void
96led_4(void *arg, int onoff)
97{
98
99	led_update(arg, 4, onoff);
100}
101
102static void
103led_5(void *arg, int onoff)
104{
105
106	led_update(arg, 5, onoff);
107}
108
109static void
110led_6(void *arg, int onoff)
111{
112
113	led_update(arg, 6, onoff);
114}
115
116static void
117led_7(void *arg, int onoff)
118{
119
120	led_update(arg, 7, onoff);
121}
122
123void
124terasic_de4led_attach(struct terasic_de4led_softc *sc)
125{
126	const char *cmd;
127
128	TERASIC_DE4LED_LOCK_INIT(sc);
129
130	/*
131	 * Clear the LED array before we start.
132	 */
133	TERASIC_DE4LED_LOCK(sc);
134	TERASIC_DE4LED_CLEARBAR(sc);
135	terasic_de4led_update(sc);
136	TERASIC_DE4LED_UNLOCK(sc);
137
138	/*
139	 * Register the LED array with led(4).
140	 */
141	sc->tdl_leds[0] = led_create(led_0, sc, "de4led_0");
142	sc->tdl_leds[1] = led_create(led_1, sc, "de4led_1");
143	sc->tdl_leds[2] = led_create(led_2, sc, "de4led_2");
144	sc->tdl_leds[3] = led_create(led_3, sc, "de4led_3");
145	sc->tdl_leds[4] = led_create(led_4, sc, "de4led_4");
146	sc->tdl_leds[5] = led_create(led_5, sc, "de4led_5");
147	sc->tdl_leds[6] = led_create(led_6, sc, "de4led_6");
148	sc->tdl_leds[7] = led_create(led_7, sc, "de4led_7");
149
150	if (resource_string_value(device_get_name(sc->tdl_dev),
151	    sc->tdl_unit, "de4led_0_cmd", &cmd) == 0)
152		led_set("de4led_0", cmd);
153	if (resource_string_value(device_get_name(sc->tdl_dev),
154	    sc->tdl_unit, "de4led_1_cmd", &cmd) == 0)
155		led_set("de4led_1", cmd);
156	if (resource_string_value(device_get_name(sc->tdl_dev),
157	    sc->tdl_unit, "de4led_2_cmd", &cmd) == 0)
158		led_set("de4led_2", cmd);
159	if (resource_string_value(device_get_name(sc->tdl_dev),
160	    sc->tdl_unit, "de4led_3_cmd", &cmd) == 0)
161		led_set("de4led_3", cmd);
162	if (resource_string_value(device_get_name(sc->tdl_dev),
163	    sc->tdl_unit, "de4led_4_cmd", &cmd) == 0)
164		led_set("de4led_4", cmd);
165	if (resource_string_value(device_get_name(sc->tdl_dev),
166	    sc->tdl_unit, "de4led_5_cmd", &cmd) == 0)
167		led_set("de4led_5", cmd);
168	if (resource_string_value(device_get_name(sc->tdl_dev),
169	    sc->tdl_unit, "de4led_6_cmd", &cmd) == 0)
170		led_set("de4led_6", cmd);
171	if (resource_string_value(device_get_name(sc->tdl_dev),
172	    sc->tdl_unit, "de4led_7_cmd", &cmd) == 0)
173		led_set("de4led_7", cmd);
174}
175
176void
177terasic_de4led_detach(struct terasic_de4led_softc *sc)
178{
179	int i;
180
181	for (i = 0; i < 8; i++) {
182		led_destroy(sc->tdl_leds[i]);
183		sc->tdl_leds[i] = NULL;
184	}
185	TERASIC_DE4LED_LOCK(sc);
186	TERASIC_DE4LED_CLEARBAR(sc);
187	terasic_de4led_update(sc);
188	TERASIC_DE4LED_UNLOCK(sc);
189	TERASIC_DE4LED_LOCK_DESTROY(sc);
190}
191