apu1c led driver

Ermal Luçi eri at freebsd.org
Wed May 7 08:19:40 UTC 2014


Hello,

find attached the driver as written today.
It needs some reshaping to be integrate with led(4) and gpio(4).

I will see to have the reshaping done and submit it for inclusion.
The idea as it is today is that it expses an gpioapu device to which you
can write a string with 3 digits "101" for each led.
If you read from this device you just get the status of the switch on the
APU.



On Tue, Apr 22, 2014 at 6:34 AM, Jim Thompson <jim at netgate.com> wrote:

>
> Might want to get Ermal to post the driver he did for us (@ pfSense).
>
> Or just submit it to the process for -HEAD.
>
> Jim
>
> On Apr 21, 2014, at 9:01 PM, Larry Baird <lab at gta.com> wrote:
>
> > There exists a nice simple linux driver for the leds on a pc engines
> apu1c
> > board at http://daduke.org/linux/apu/.  Converting driver to use led(4)
> > and run on FreeBSD seemed straight forward.  Or that is until I realized
> > I don't know how to alloc and write to a fixed set of I/O ports. I
> believe
> > the magic happens by using bus_alloc_resource(). Code below attempts to
> allow
> > control of the second of three leds on the apu1c board.  Once I get that
> > working, it should be easy to extend driver to support all three leds.
> > What is the correct way to allocate and write to a a set of I/O ports at
> > address 0xFED801BD?
> >
> > #include <sys/param.h>
> > #include <sys/bus.h>
> > #include <sys/kernel.h>
> > #include <sys/module.h>
> > #include <sys/rman.h>
> > #include <x86/bus.h>
> > #include <dev/led/led.h>
> >
> > #define BASEADDR        (0xFED801BD)
> > #define LEDON           (0x8)
> > #define LEDOFF          (0xC8)
> >
> > #define GPIO_187      187       // MODESW
> > #define GPIO_189      189       // LED1#
> > #define GPIO_190      190       // LED2#
> > #define GPIO_191      191       // LED3#
> >
> > struct apuled_softc {
> >       device_t        sc_dev;
> >        int             sc_rid;
> >        int             sc_type;
> >        int             sc_offset;
> >       struct resource *sc_res;
> >       void            *sc_led1;
> > };
> >
> > /*
> > * Device methods.
> > */
> > static int    apuled_probe(device_t dev);
> > static int    apuled_attach(device_t dev);
> > static int    apuled_detach(device_t dev);
> >
> > static device_method_t apuled_methods[] = {
> >       /* Device interface */
> >       DEVMETHOD(device_probe,         apuled_probe),
> >       DEVMETHOD(device_attach,        apuled_attach),
> >       DEVMETHOD(device_detach,        apuled_detach),
> >
> >       DEVMETHOD_END
> > };
> >
> > static driver_t apuled_driver = {
> >       "apuled",
> >       apuled_methods,
> >       sizeof(struct apuled_softc),
> > };
> >
> > static devclass_t apuled_devclass;
> > DRIVER_MODULE(apuled, pci, apuled_driver, apuled_devclass, NULL, NULL);
> >
> >
> > static int
> > apuled_probe(device_t dev)
> > {
> >       device_set_desc(dev, "APU led");
> >
> >       return (BUS_PROBE_GENERIC);
> > }
> >
> > static void
> > led_func(void *ptr, int onoff)
> > {
> >       struct apuled_softc *sc = (struct apuled_softc *)ptr;
> >       u_int8_t value;
> >
> >       if ( onoff ) {
> >               value = LEDON;
> >       } else {
> >               value = LEDOFF;
> >       }
> >
> >       bus_write_1(sc->sc_res, 1, value);
> > }
> >
> > static int
> > apuled_attach(device_t dev)
> > {
> >       struct apuled_softc *sc = device_get_softc(dev);
> >
> >       sc->sc_dev = dev;
> >       sc->sc_rid = 1;
> >       sc->sc_type = SYS_RES_IOPORT;
> >
> >       if ( (sc->sc_res = bus_alloc_resource( sc->sc_dev,
> >                                          sc->sc_type,
> >                                          &sc->sc_rid,
> >                                          BASEADDR,
> >                                          BASEADDR + 4,
> >                                          4,
> >                                          RF_ACTIVE)) == NULL ) {
> >               device_printf( sc->sc_dev, "Unable to allocate bus
> resource\n" );
> >               return ENXIO;
> >
> >       } else if ( (sc->sc_led1 = led_create(led_func, sc, "led1")) ==
> NULL ) {
> >               device_printf( sc->sc_dev, "Unable to create LED 1\n" );
> >               return ENXIO;
> >
> >       } else {
> >               device_printf( sc->sc_dev, "LED 1 created\n" );
> >       }
> >
> >       return (0);
> > }
> >
> > int
> > apuled_detach(device_t dev)
> > {
> >       struct apuled_softc *sc = device_get_softc(dev);
> >
> >       if ( sc->sc_led1 != NULL ) {
> >               led_destroy( sc->sc_led1 );
> >       }
> >
> >       if ( sc->sc_res != NULL ) {
> >               bus_release_resource( sc->sc_dev, sc->sc_type, sc->sc_rid,
> sc->sc_res );
> >       }
> >
> >       return (0);
> > }
> >
> > --
> > ------------------------------------------------------------------------
> > Larry Baird
> > Global Technology Associates, Inc. 1992-2012  | http://www.gta.com
> > Celebrating Twenty Years of Software Innovation | Orlando, FL
> > Email: lab at gta.com                            | TEL 407-380-0220
> > _______________________________________________
> > freebsd-hackers at freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> > To unsubscribe, send any mail to "
> freebsd-hackers-unsubscribe at freebsd.org"
>
>


-- 
Ermal


More information about the freebsd-hackers mailing list