Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/powerpc/mikrotik/rb_led.c
39536 views
1
/*-
2
* Copyright (c) 2017 Justin Hibbits
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
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*
26
*/
27
28
#include <sys/param.h>
29
#include <sys/systm.h>
30
#include <sys/module.h>
31
#include <sys/bus.h>
32
#include <sys/conf.h>
33
#include <sys/kernel.h>
34
35
#include <dev/ofw/ofw_bus.h>
36
#include <dev/ofw/openfirm.h>
37
#include <dev/led/led.h>
38
39
#include "gpio_if.h"
40
41
struct rbled_softc {
42
struct cdev *sc_led;
43
device_t sc_gpio;
44
uint32_t sc_ledpin;
45
};
46
47
static int rbled_probe(device_t);
48
static int rbled_attach(device_t);
49
static int rbled_detach(device_t);
50
static void rbled_toggle(void *, int);
51
52
static device_method_t rbled_methods[] = {
53
/* Device interface */
54
DEVMETHOD(device_probe, rbled_probe),
55
DEVMETHOD(device_attach, rbled_attach),
56
DEVMETHOD(device_detach, rbled_detach),
57
58
DEVMETHOD_END
59
};
60
61
static driver_t rbled_driver = {
62
"rbled",
63
rbled_methods,
64
sizeof(struct rbled_softc),
65
};
66
67
DRIVER_MODULE(rbled, simplebus, rbled_driver, 0, 0);
68
69
static int
70
rbled_probe(device_t dev)
71
{
72
phandle_t node;
73
const char *name;
74
cell_t gp[2];
75
char model[6];
76
77
node = ofw_bus_get_node(dev);
78
79
name = ofw_bus_get_name(dev);
80
if (name == NULL)
81
return (ENXIO);
82
if (strcmp(name, "led") != 0)
83
return (ENXIO);
84
85
if (OF_getprop(node, "user_led", gp, sizeof(gp)) <= 0)
86
return (ENXIO);
87
88
/* Check root model. */
89
node = OF_peer(0);
90
if (OF_getprop(node, "model", model, sizeof(model)) <= 0)
91
return (ENXIO);
92
if (strcmp(model, "RB800") != 0)
93
return (ENXIO);
94
95
device_set_desc(dev, "RouterBoard LED");
96
return (0);
97
}
98
99
static int
100
rbled_attach(device_t dev)
101
{
102
struct rbled_softc *sc;
103
phandle_t node;
104
cell_t gp[2];
105
106
sc = device_get_softc(dev);
107
node = ofw_bus_get_node(dev);
108
109
if (OF_getprop(node, "user_led", gp, sizeof(gp)) <= 0)
110
return (ENXIO);
111
112
sc->sc_gpio = OF_device_from_xref(gp[0]);
113
if (sc->sc_gpio == NULL) {
114
device_printf(dev, "No GPIO resource found!\n");
115
return (ENXIO);
116
}
117
sc->sc_ledpin = gp[1];
118
119
sc->sc_led = led_create(rbled_toggle, sc, "user_led");
120
121
if (sc->sc_led == NULL)
122
return (ENXIO);
123
124
return (0);
125
}
126
127
static int
128
rbled_detach(device_t dev)
129
{
130
struct rbled_softc *sc;
131
132
sc = device_get_softc(dev);
133
led_destroy(sc->sc_led);
134
135
return (0);
136
}
137
138
static void
139
rbled_toggle(void *priv, int onoff)
140
{
141
struct rbled_softc *sc = priv;
142
143
GPIO_PIN_SET(sc->sc_gpio, sc->sc_ledpin, onoff);
144
}
145
146