1164508Skevlo/*-
2164508Skevlo * Copyright (c) 2006 Kevin Lo.  All rights reserved.
3164508Skevlo *
4164508Skevlo * Redistribution and use in source and binary forms, with or without
5164508Skevlo * modification, are permitted provided that the following conditions
6164508Skevlo * are met:
7164508Skevlo * 1. Redistributions of source code must retain the above copyright
8164508Skevlo *    notice, this list of conditions and the following disclaimer.
9164508Skevlo * 2. Redistributions in binary form must reproduce the above copyright
10164508Skevlo *    notice, this list of conditions and the following disclaimer in the
11164508Skevlo *    documentation and/or other materials provided with the distribution.
12164508Skevlo *
13164508Skevlo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14164508Skevlo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15164508Skevlo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16164508Skevlo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17164508Skevlo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18164508Skevlo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19164508Skevlo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20164508Skevlo * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21164508Skevlo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22164508Skevlo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23164508Skevlo */
24164508Skevlo
25164508Skevlo#include <sys/cdefs.h>
26164508Skevlo__FBSDID("$FreeBSD$");
27164508Skevlo
28164508Skevlo#include <sys/param.h>
29164508Skevlo#include <sys/systm.h>
30164508Skevlo#include <sys/kernel.h>
31164508Skevlo#include <sys/module.h>
32164508Skevlo#include <sys/bus.h>
33164508Skevlo
34164508Skevlo#include <arm/xscale/ixp425/ixp425reg.h>
35164508Skevlo#include <arm/xscale/ixp425/ixp425var.h>
36164508Skevlo
37164508Skevlo#include <dev/led/led.h>
38164508Skevlo
39164508Skevlo#define	GPIO_LED_STATUS	3
40186352Ssam#define	GPIO_LED_STATUS_BIT	(1U << GPIO_LED_STATUS)
41164508Skevlo
42164508Skevlostruct led_avila_softc {
43164508Skevlo	device_t		sc_dev;
44164508Skevlo	bus_space_tag_t		sc_iot;
45164508Skevlo	bus_space_handle_t	sc_gpio_ioh;
46186352Ssam	struct cdev		*sc_led;
47164508Skevlo};
48164508Skevlo
49164508Skevlostatic void
50186352Ssamled_func(void *arg, int onoff)
51164508Skevlo{
52186352Ssam	struct led_avila_softc *sc = arg;
53164508Skevlo	uint32_t reg;
54164508Skevlo
55215319Sthompsa	IXP4XX_GPIO_LOCK();
56164508Skevlo	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
57164508Skevlo	if (onoff)
58164508Skevlo		reg &= ~GPIO_LED_STATUS_BIT;
59164508Skevlo	else
60164508Skevlo		reg |= GPIO_LED_STATUS_BIT;
61164508Skevlo	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg);
62215319Sthompsa	IXP4XX_GPIO_UNLOCK();
63164508Skevlo}
64164508Skevlo
65164508Skevlostatic int
66164508Skevloled_avila_probe(device_t dev)
67164508Skevlo{
68186352Ssam	device_set_desc(dev, "Gateworks Avila Front Panel LED");
69164508Skevlo	return (0);
70164508Skevlo}
71164508Skevlo
72164508Skevlostatic int
73164508Skevloled_avila_attach(device_t dev)
74164508Skevlo{
75164508Skevlo	struct led_avila_softc *sc = device_get_softc(dev);
76164508Skevlo	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
77164508Skevlo
78164508Skevlo	sc->sc_dev = dev;
79164508Skevlo	sc->sc_iot = sa->sc_iot;
80164508Skevlo	sc->sc_gpio_ioh = sa->sc_gpio_ioh;
81164508Skevlo
82164508Skevlo	/* Configure LED GPIO pin as output */
83186352Ssam	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER,
84186352Ssam	    GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) &~ GPIO_LED_STATUS_BIT);
85164508Skevlo
86186352Ssam	sc->sc_led = led_create(led_func, sc, "gpioled");
87164508Skevlo
88186352Ssam	led_func(sc, 1);		/* Turn on LED */
89164508Skevlo
90164508Skevlo	return (0);
91164508Skevlo}
92164508Skevlo
93194015Savgstatic int
94186352Ssamled_avila_detach(device_t dev)
95186352Ssam{
96186352Ssam	struct led_avila_softc *sc = device_get_softc(dev);
97186352Ssam
98186352Ssam	if (sc->sc_led != NULL)
99186352Ssam		led_destroy(sc->sc_led);
100194015Savg	return (0);
101186352Ssam}
102186352Ssam
103164508Skevlostatic device_method_t led_avila_methods[] = {
104164508Skevlo	DEVMETHOD(device_probe,		led_avila_probe),
105164508Skevlo	DEVMETHOD(device_attach,	led_avila_attach),
106186352Ssam	DEVMETHOD(device_detach,	led_avila_detach),
107164508Skevlo
108164508Skevlo	{0, 0},
109164508Skevlo};
110164508Skevlo
111164508Skevlostatic driver_t led_avila_driver = {
112164508Skevlo	"led_avila",
113164508Skevlo	led_avila_methods,
114164508Skevlo	sizeof(struct led_avila_softc),
115164508Skevlo};
116164508Skevlostatic devclass_t led_avila_devclass;
117164508Skevlo
118164508SkevloDRIVER_MODULE(led_avila, ixp, led_avila_driver, led_avila_devclass, 0, 0);
119