gpioled.c (27067774dce3388702a4cf744d7096c6fb71b688) gpioled.c (aabc5ce043340c18d7bc7f7ca956724c66583625)
1/*-
2 * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 25 unchanged lines hidden (view full) ---

34#include <sys/bus.h>
35#include <sys/gpio.h>
36#include <sys/kernel.h>
37#include <sys/lock.h>
38#include <sys/malloc.h>
39#include <sys/module.h>
40#include <sys/mutex.h>
41
1/*-
2 * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 25 unchanged lines hidden (view full) ---

34#include <sys/bus.h>
35#include <sys/gpio.h>
36#include <sys/kernel.h>
37#include <sys/lock.h>
38#include <sys/malloc.h>
39#include <sys/module.h>
40#include <sys/mutex.h>
41
42#ifdef FDT
43#include <dev/fdt/fdt_common.h>
44#include <dev/ofw/ofw_bus.h>
45#endif
46
47#include <dev/gpio/gpiobusvar.h>
48#include <dev/led/led.h>
49
50#include "gpiobus_if.h"
51
52/*
53 * Only one pin for led
54 */

--- 31 unchanged lines hidden (view full) ---

86 if (sc->sc_invert)
87 onoff = !onoff;
88 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, GPIOLED_PIN,
89 onoff ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
90 }
91 GPIOLED_UNLOCK(sc);
92}
93
42#include <dev/gpio/gpiobusvar.h>
43#include <dev/led/led.h>
44
45#include "gpiobus_if.h"
46
47/*
48 * Only one pin for led
49 */

--- 31 unchanged lines hidden (view full) ---

81 if (sc->sc_invert)
82 onoff = !onoff;
83 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, GPIOLED_PIN,
84 onoff ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
85 }
86 GPIOLED_UNLOCK(sc);
87}
88
94#ifdef FDT
95static void
96gpioled_identify(driver_t *driver, device_t bus)
97{
98 phandle_t child, leds, root;
99
100 root = OF_finddevice("/");
101 if (root == 0)
102 return;
103 for (leds = OF_child(root); leds != 0; leds = OF_peer(leds)) {
104 if (!fdt_is_compatible_strict(leds, "gpio-leds"))
105 continue;
106 /* Traverse the 'gpio-leds' node and add its children. */
107 for (child = OF_child(leds); child != 0; child = OF_peer(child)) {
108 if (!OF_hasprop(child, "gpios"))
109 continue;
110 if (ofw_gpiobus_add_fdt_child(bus, driver->name, child) == NULL)
111 continue;
112 }
113 }
114}
115#endif
116
117static int
118gpioled_probe(device_t dev)
119{
89static int
90gpioled_probe(device_t dev)
91{
120#ifdef FDT
121 int match;
122 phandle_t node;
123 char *compat;
124
125 /*
126 * We can match against our own node compatible string and also against
127 * our parent node compatible string. The first is normally used to
128 * describe leds on a gpiobus and the later when there is a common node
129 * compatible with 'gpio-leds' which is used to concentrate all the
130 * leds nodes on the dts.
131 */
132 match = 0;
133 if (ofw_bus_is_compatible(dev, "gpioled"))
134 match = 1;
135
136 if (match == 0) {
137 if ((node = ofw_bus_get_node(dev)) == -1)
138 return (ENXIO);
139 if ((node = OF_parent(node)) == -1)
140 return (ENXIO);
141 if (OF_getprop_alloc(node, "compatible", 1,
142 (void **)&compat) == -1)
143 return (ENXIO);
144
145 if (strcasecmp(compat, "gpio-leds") == 0)
146 match = 1;
147
148 OF_prop_free(compat);
149 }
150
151 if (match == 0)
152 return (ENXIO);
153#endif
154 device_set_desc(dev, "GPIO led");
155
156 return (BUS_PROBE_DEFAULT);
157}
158
159static int
160gpioled_attach(device_t dev)
161{
162 struct gpioled_softc *sc;
163 int state;
92 device_set_desc(dev, "GPIO led");
93
94 return (BUS_PROBE_DEFAULT);
95}
96
97static int
98gpioled_attach(device_t dev)
99{
100 struct gpioled_softc *sc;
101 int state;
164#ifdef FDT
165 phandle_t node;
166 char *default_state;
167 char *name;
168#else
169 const char *name;
102 const char *name;
170#endif
171
172 sc = device_get_softc(dev);
173 sc->sc_dev = dev;
174 sc->sc_busdev = device_get_parent(dev);
175 GPIOLED_LOCK_INIT(sc);
176
177 state = 0;
178
103
104 sc = device_get_softc(dev);
105 sc->sc_dev = dev;
106 sc->sc_busdev = device_get_parent(dev);
107 GPIOLED_LOCK_INIT(sc);
108
109 state = 0;
110
179#ifdef FDT
180 if ((node = ofw_bus_get_node(dev)) == -1)
181 return (ENXIO);
182
183 if (OF_getprop_alloc(node, "default-state",
184 sizeof(char), (void **)&default_state) != -1) {
185 if (strcasecmp(default_state, "on") == 0)
186 state = 1;
187 else if (strcasecmp(default_state, "off") == 0)
188 state = 0;
189 else if (strcasecmp(default_state, "keep") == 0)
190 state = -1;
191 else {
192 device_printf(dev,
193 "unknown value for default-state in FDT\n");
194 }
195 OF_prop_free(default_state);
196 }
197
198 name = NULL;
199 if (OF_getprop_alloc(node, "label", 1, (void **)&name) == -1)
200 OF_getprop_alloc(node, "name", 1, (void **)&name);
201#else
202 if (resource_string_value(device_get_name(dev),
203 device_get_unit(dev), "name", &name))
204 name = NULL;
205 resource_int_value(device_get_name(dev),
206 device_get_unit(dev), "invert", &sc->sc_invert);
111 if (resource_string_value(device_get_name(dev),
112 device_get_unit(dev), "name", &name))
113 name = NULL;
114 resource_int_value(device_get_name(dev),
115 device_get_unit(dev), "invert", &sc->sc_invert);
207#endif
208
209 sc->sc_leddev = led_create_state(gpioled_control, sc, name ? name :
210 device_get_nameunit(dev), state);
116
117 sc->sc_leddev = led_create_state(gpioled_control, sc, name ? name :
118 device_get_nameunit(dev), state);
211#ifdef FDT
212 if (name != NULL)
213 OF_prop_free(name);
214#endif
215
216 return (0);
217}
218
219static int
220gpioled_detach(device_t dev)
221{
222 struct gpioled_softc *sc;

--- 6 unchanged lines hidden (view full) ---

229 GPIOLED_LOCK_DESTROY(sc);
230 return (0);
231}
232
233static devclass_t gpioled_devclass;
234
235static device_method_t gpioled_methods[] = {
236 /* Device interface */
119
120 return (0);
121}
122
123static int
124gpioled_detach(device_t dev)
125{
126 struct gpioled_softc *sc;

--- 6 unchanged lines hidden (view full) ---

133 GPIOLED_LOCK_DESTROY(sc);
134 return (0);
135}
136
137static devclass_t gpioled_devclass;
138
139static device_method_t gpioled_methods[] = {
140 /* Device interface */
237#ifdef FDT
238 DEVMETHOD(device_identify, gpioled_identify),
239#endif
240 DEVMETHOD(device_probe, gpioled_probe),
241 DEVMETHOD(device_attach, gpioled_attach),
242 DEVMETHOD(device_detach, gpioled_detach),
243
244 DEVMETHOD_END
245};
246
247static driver_t gpioled_driver = {
248 "gpioled",
249 gpioled_methods,
250 sizeof(struct gpioled_softc),
251};
252
253DRIVER_MODULE(gpioled, gpiobus, gpioled_driver, gpioled_devclass, 0, 0);
254MODULE_DEPEND(gpioled, gpiobus, 1, 1, 1);
141 DEVMETHOD(device_probe, gpioled_probe),
142 DEVMETHOD(device_attach, gpioled_attach),
143 DEVMETHOD(device_detach, gpioled_detach),
144
145 DEVMETHOD_END
146};
147
148static driver_t gpioled_driver = {
149 "gpioled",
150 gpioled_methods,
151 sizeof(struct gpioled_softc),
152};
153
154DRIVER_MODULE(gpioled, gpiobus, gpioled_driver, gpioled_devclass, 0, 0);
155MODULE_DEPEND(gpioled, gpiobus, 1, 1, 1);