From 17bb5631e99903c9e5eeba1bb6c0826dc4c0c8fd Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Tue, 8 Aug 2006 19:35:22 +0000 Subject: [lcd4linux @ 2006-08-08 19:35:21 by reinelt] USBHUB driver from Ernst Bachmann --- Makefile.am | 1 + Makefile.in | 2 + config.h.in | 3 + configure | 22 +++- drivers.m4 | 17 ++- drv.c | 9 +- drv_USBHUB.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ usbhub.conf | 51 +++++++++ 8 files changed, 446 insertions(+), 3 deletions(-) create mode 100644 drv_USBHUB.c create mode 100644 usbhub.conf diff --git a/Makefile.am b/Makefile.am index f327a81..91c6673 100644 --- a/Makefile.am +++ b/Makefile.am @@ -84,6 +84,7 @@ drv_serdisplib.c \ drv_SimpleLCD.c \ drv_T6963.c \ drv_Trefon.c \ +drv_USBHUB.c \ drv_USBLCD.c \ drv_WincorNixdorf.c \ drv_X11.c \ diff --git a/Makefile.in b/Makefile.in index 3aefaeb..9fd8356 100644 --- a/Makefile.in +++ b/Makefile.in @@ -259,6 +259,7 @@ drv_serdisplib.c \ drv_SimpleLCD.c \ drv_T6963.c \ drv_Trefon.c \ +drv_USBHUB.c \ drv_USBLCD.c \ drv_WincorNixdorf.c \ drv_X11.c \ @@ -427,6 +428,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_SimpleLCD.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_T6963.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_Trefon.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_USBHUB.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_USBLCD.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_WincorNixdorf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_X11.Po@am__quote@ diff --git a/config.h.in b/config.h.in index 0070c31..c0df0ef 100644 --- a/config.h.in +++ b/config.h.in @@ -440,6 +440,9 @@ /* TREFON driver */ #undef WITH_TREFON +/* USBHUB driver */ +#undef WITH_USBHUB + /* USBLCD driver */ #undef WITH_USBLCD diff --git a/configure b/configure index 8f91e1e..d110d26 100755 --- a/configure +++ b/configure @@ -1307,7 +1307,7 @@ Optional Packages: LUIse, M50530, MatrixOrbital, MilfordInstruments, Noritake, NULL, PNG, PPM, RouterBoard, Sample, serdisplib, SimpleLCD, T6963, Trefon, USBLCD, - WincorNixdorf, X11 + USBHUB, WincorNixdorf, X11 --with-plugins= choose which plugins to compile. type --with-plugins=list for a list of avaible plugins @@ -7603,6 +7603,7 @@ for driver in $drivers; do SIMPLELCD="yes" T6963="yes" Trefon="yes" + USBHUB="yes" USBLCD="yes" WINCORNIXDORF="yes" X11="yes" @@ -7685,6 +7686,9 @@ for driver in $drivers; do Trefon) Trefon=$val ;; + USBHUB) + USBHUB=$val + ;; USBLCD) USBLCD=$val ;; @@ -8066,6 +8070,22 @@ echo "$as_me: WARNING: usb.h not found: Trefon driver disabled" >&2;} fi fi +if test "$USBHUB" = "yes"; then + if test "$has_usb" = "true"; then + GPIO="yes" + DRIVERS="$DRIVERS drv_USBHUB.o" + LIBUSB="yes" + +cat >>confdefs.h <<\_ACEOF +#define WITH_USBHUB 1 +_ACEOF + + else + { echo "$as_me:$LINENO: WARNING: usb.h not found: USB-Hub driver disabled" >&5 +echo "$as_me: WARNING: usb.h not found: USB-Hub driver disabled" >&2;} + fi +fi + if test "$USBLCD" = "yes"; then TEXT="yes" SERIAL="yes" diff --git a/drivers.m4 b/drivers.m4 index 8b13474..b28ef30 100644 --- a/drivers.m4 +++ b/drivers.m4 @@ -33,7 +33,7 @@ AC_ARG_WITH( [ LUIse, M50530, MatrixOrbital, MilfordInstruments,] [ Noritake, NULL, PNG, PPM, RouterBoard, Sample,] [ serdisplib, SimpleLCD, T6963, Trefon, USBLCD,] - [ WincorNixdorf, X11], + [ USBHUB, WincorNixdorf, X11], drivers=$withval, drivers=all ) @@ -80,6 +80,7 @@ for driver in $drivers; do SIMPLELCD="yes" T6963="yes" Trefon="yes" + USBHUB="yes" USBLCD="yes" WINCORNIXDORF="yes" X11="yes" @@ -162,6 +163,9 @@ for driver in $drivers; do Trefon) Trefon=$val ;; + USBHUB) + USBHUB=$val + ;; USBLCD) USBLCD=$val ;; @@ -427,6 +431,17 @@ if test "$Trefon" = "yes"; then fi fi +if test "$USBHUB" = "yes"; then + if test "$has_usb" = "true"; then + GPIO="yes" + DRIVERS="$DRIVERS drv_USBHUB.o" + LIBUSB="yes" + AC_DEFINE(WITH_USBHUB,1,[USBHUB driver]) + else + AC_MSG_WARN(usb.h not found: USB-Hub driver disabled) + fi +fi + if test "$USBLCD" = "yes"; then TEXT="yes" SERIAL="yes" diff --git a/drv.c b/drv.c index 6f5d53e..0d9472b 100644 --- a/drv.c +++ b/drv.c @@ -1,4 +1,4 @@ -/* $Id: drv.c,v 1.42 2006/08/05 21:08:01 harbaum Exp $ +/* $Id: drv.c,v 1.43 2006/08/08 19:35:21 reinelt Exp $ * * new framework for display drivers * @@ -23,6 +23,9 @@ * * * $Log: drv.c,v $ + * Revision 1.43 2006/08/08 19:35:21 reinelt + * USBHUB driver from Ernst Bachmann + * * Revision 1.42 2006/08/05 21:08:01 harbaum * New LEDMATRIX driver (see http://www.harbaum.org/till/ledmatrix) * @@ -232,6 +235,7 @@ extern DRIVER drv_serdisplib; extern DRIVER drv_SimpleLCD; extern DRIVER drv_T6963; extern DRIVER drv_Trefon; +extern DRIVER drv_USBHUB; extern DRIVER drv_USBLCD; extern DRIVER drv_WincorNixdorf; extern DRIVER drv_X11; @@ -318,6 +322,9 @@ DRIVER *Driver[] = { #ifdef WITH_TREFON &drv_Trefon, #endif +#ifdef WITH_USBHUB + &drv_USBHUB, +#endif #ifdef WITH_USBLCD &drv_USBLCD, #endif diff --git a/drv_USBHUB.c b/drv_USBHUB.c new file mode 100644 index 0000000..871850a --- /dev/null +++ b/drv_USBHUB.c @@ -0,0 +1,344 @@ +/* $Id: drv_USBHUB.c,v 1.1 2006/08/08 19:35:22 reinelt Exp $ + * + * new style driver for USBLCD displays + * + * Copyright (C) 2006 Ernst Bachmann + * Copyright (C) 2004,2006 The LCD4Linux Team + * + * Based on the USBLCD driver Copyright (C) 2003 Michael Reinelt + * + * This file is part of LCD4Linux. + * + * LCD4Linux is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LCD4Linux is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: drv_USBHUB.c,v $ + * Revision 1.1 2006/08/08 19:35:22 reinelt + * USBHUB driver from Ernst Bachmann + * + * + */ + +/* + * + * exported fuctions: + * + * struct DRIVER drv_USBHUB + * + */ + +#include "config.h" + +#ifdef HAVE_USB_H +# include +#else +# error The USB-HUB driver only makes sense with USB support +#endif + +#include "debug.h" +#include "cfg.h" +#include "qprintf.h" +#include "udelay.h" +#include "drv.h" +#include "drv_generic_gpio.h" + + + +#define HUB_CONTROL_PORT 0x23 +#define HUB_SET_FEATURE 3 +#define HUB_SET_INDICATOR 22 + +static char Name[] = "USBHUB"; + +/* TODO: Better not specify defaults here, + * instead look for the first suitable HUB arround if + * no Vendor/Product specified in config. + */ + +static int hubVendor=0x0409; +static int hubProduct=0x0058; + +static usb_dev_handle *hub=NULL; + +typedef struct _usb_hub_descriptor { + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t nNbrPorts; + u_int8_t wHubCharacteristicLow; + u_int8_t wHubCharacteristicHigh; + u_int8_t bPwrOn2PwrGood; + u_int8_t bHubContrCurrent; + u_int8_t deviceRemovable; + u_int8_t PortPwrCtrlMask[8]; +} usb_hub_descriptor; + +/****************************************/ +/*** hardware dependant functions ***/ +/****************************************/ + + +static int drv_UH_open(void) +{ + struct usb_bus *busses, *bus; + struct usb_device *dev; + + hub = NULL; + + info("%s: scanning for an USB HUB (0x%04x:0x%04x)...", Name,hubVendor,hubProduct); + + usb_init(); + usb_find_busses(); + usb_find_devices(); + busses = usb_get_busses(); + + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if ((dev->descriptor.idVendor == hubVendor) && + (dev->descriptor.idProduct == hubProduct)) { + + unsigned int v = dev->descriptor.bcdDevice; + + info("%s: found USBHUB V%1d%1d.%1d%1d on bus %s device %s", Name, + (v & 0xF000) >> 12, (v & 0xF00) >> 8, (v & 0xF0) >> 4, (v & 0xF), bus->dirname, dev->filename); + + if (dev->descriptor.bDeviceClass != USB_CLASS_HUB) { + error("%s: the specified device claims to be no HUB"); + return -1; + } + + hub = usb_open(dev); + if (!hub) { + error("%s: usb_open() failed!", Name); + return -1; + } + return 0; + } + } + } + error("%s: could not find a USB HUB", Name); + return -1; +} + + +static int drv_UH_close(void) +{ + debug("closing USB handle"); + + usb_close(hub); + + return 0; +} + + +/* + * Set the Indicator status on port "num+1" to val. + * according to the USB Specification, the following values would be allowed: + * + * 0 : Automatic color (display link state etc) + * 1 : Amber + * 2 : Green + * 3 : Off + * 4..255: Reserved + * + */ + +static int drv_UH_set(const int num, const int val) { + int ret; + + if (!hub) + return -1; + + if (val <0 || val > 3) { + info("%s: value %d out of range (0..3)",Name,val); + return -1; + } + + if((ret=usb_control_msg(hub, + HUB_CONTROL_PORT, + HUB_SET_FEATURE, + HUB_SET_INDICATOR, (val << 8) | (num+1), NULL, 0, 1000)) != 0) { + info("%s: usb_control_msg failed with %d",Name,ret); + return -1; + } + + return 0; +} + + +static int drv_UH_start(const char *section, const int quiet) +{ + char * buf; + + usb_hub_descriptor hub_desc; + int ret; + + + buf=cfg_get(section,"Vendor",NULL); + if (buf) { + if (!*buf) { + error("%s: Strange Vendor Specification"); + return -1; + } + if (sscanf(buf,"0x%x",&hubVendor) != 1) { + error("%s: Strange Vendor Specification: [%s]",buf); + return -1; + } + } + + buf=cfg_get(section,"Product",NULL); + if (buf) { + if (!*buf) { + error("%s: Strange Product Specification"); + return -1; + } + if (sscanf(buf,"0x%x",&hubProduct) != 1) { + error("%s: Strange Product Specification: [%s]",buf); + return -1; + } + } + + if (drv_UH_open() < 0) { + return -1; + } + + + if ((ret=usb_control_msg(hub, + USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE, + USB_REQ_GET_DESCRIPTOR,USB_DT_HUB << 8,0,(char *)&hub_desc,sizeof(hub_desc),1000)) <= 8) { + error("%s: hub_get_descriptor failed with %d",Name,ret); + drv_UH_close(); + return -1; + } + GPOS=hub_desc.nNbrPorts; + debug("%s: HUB claims to have %d ports. Configuring them as GPOs",Name,GPOS); + if (!(hub_desc.wHubCharacteristicLow & 0x80)) { + error("%s: HUB claims to have no Indicator LEDs (Characteristics 0x%04x). Bailing out.",Name, + (hub_desc.wHubCharacteristicHigh << 8) | hub_desc.wHubCharacteristicLow); + /* The HUB Tells us that there are no LEDs to control. Breaking? Maybe don't trust it and continue anyways? */ + drv_UH_close(); + return -1; + + } + + return 0; +} + + +/****************************************/ +/*** plugins ***/ +/****************************************/ + +/* none at the moment... */ + + +/****************************************/ +/*** widget callbacks ***/ +/****************************************/ + + +/* using drv_generic_text_draw(W) */ +/* using drv_generic_text_icon_draw(W) */ +/* using drv_generic_text_bar_draw(W) */ + + +/****************************************/ +/*** exported functions ***/ +/****************************************/ + + +/* list models */ +int drv_UH_list(void) +{ + printf("generic"); + return 0; +} + + +/* initialize driver & display */ +int drv_UH_init(const char *section, const int quiet) +{ + int ret; + int i; + + info("%s: %s", Name, "$Revision: 1.1 $"); + + + + /* start display */ + if ((ret = drv_UH_start(section, quiet)) != 0) + return ret; + + + /* real worker functions */ + drv_generic_gpio_real_set=drv_UH_set; + + + /* initialize generic GPIO driver */ + if ((ret = drv_generic_gpio_init(section, Name)) != 0) + return ret; + + /* register gpio widget, done already by generic_gpio */ + + /* register plugins */ + /* none at the moment... */ + + /* greeting */ + if (!quiet) { + /* Light all LEDS green for a greeting */ + for (i=0; i < GPOS; ++i) { + drv_UH_set(i,2); + } + sleep(1); + for (i=0; i < GPOS; ++i) { + drv_UH_set(i,3); // OFF + } + } + + + return 0; +} + + +/* close driver & display */ +int drv_UH_quit(const int quiet) +{ + int i; + debug("%s: shutting down.", Name); + + /* say goodbye... */ + if (!quiet) { + /* Light all LEDS amber for a goodbye */ + for (i=0; i < GPOS; ++i) { + drv_UH_set(i,1); + } + sleep(1); + + } + + drv_generic_gpio_quit(); + + drv_UH_close(); + + info("%s: shutdown complete.", Name); + return 0; +} + + +DRIVER drv_USBHUB = { + name:Name, + list:drv_UH_list, + init:drv_UH_init, + quit:drv_UH_quit, +}; diff --git a/usbhub.conf b/usbhub.conf new file mode 100644 index 0000000..0d9e8ad --- /dev/null +++ b/usbhub.conf @@ -0,0 +1,51 @@ +Variables { + tick 500 + tack 100 + minute 60000 +} + +Display SitecomHUB { + Driver 'USBHUB' + Vendor '0x04b4' + Product '0x6560' +} + +Display TyphoonHUB { + Driver 'USBHUB' + Vendor '0x0409' + Product '0x0058' +} + + +Widget GPO_Test300 { + class 'GPO' + expression 2+(1+test::onoff(1))/2 + update 300 +} +Widget GPO_Test400 { + class 'GPO' + expression 2+(1+test::onoff(2))/2 + update 400 +} +Widget GPO_Test500 { + class 'GPO' + expression 2+(1+test::onoff(3))/2 + update 500 +} +Widget GPO_Test600 { + class 'GPO' + expression 2+(1+test::onoff(4))/2 + update 600 +} + +Layout TestHUB { + GPO1 'GPO_Test300' + GPO2 'GPO_Test400' + GPO3 'GPO_Test500' + GPO4 'GPO_Test600' +} + +#Display 'SitecomHUB' +Display 'TyphoonHUB' +Layout 'TestHUB' + -- cgit v1.2.3