From owner-freebsd-hackers@FreeBSD.ORG Tue Apr 22 02:07:52 2014 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 39F7FADB for ; Tue, 22 Apr 2014 02:07:52 +0000 (UTC) Received: from mailgate.gta.com (mailgate.gta.com [199.120.225.23]) by mx1.freebsd.org (Postfix) with ESMTP id BB13912D7 for ; Tue, 22 Apr 2014 02:07:51 +0000 (UTC) Received: (qmail 58334 invoked by uid 1000); 22 Apr 2014 02:01:09 -0000 Date: Mon, 21 Apr 2014 22:01:09 -0400 From: Larry Baird To: freebsd-hackers@freebsd.org Subject: apu1c led driver Message-ID: <20140422020109.GA57760@gta.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Mailman-Approved-At: Tue, 22 Apr 2014 03:57:02 +0000 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Apr 2014 02:07:52 -0000 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 #include #include #include #include #include #include #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@gta.com | TEL 407-380-0220