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); |