aboutsummaryrefslogtreecommitdiffstats
path: root/drv_USBHUB.c
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2006-08-08 19:35:22 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2006-08-08 19:35:22 +0000
commit8029d9e8c20c56b5013ff3ce2a203084e12dd638 (patch)
tree305ad5e9c770cbeb44bf0367d64b1ce1d89bf661 /drv_USBHUB.c
parent0577f2c47263a4317a93c753f0e09269e67c06d9 (diff)
downloadlcd4linux-8029d9e8c20c56b5013ff3ce2a203084e12dd638.tar.gz
[lcd4linux @ 2006-08-08 19:35:21 by reinelt]
USBHUB driver from Ernst Bachmann git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@683 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to 'drv_USBHUB.c')
-rw-r--r--drv_USBHUB.c344
1 files changed, 344 insertions, 0 deletions
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 <e.bachmann@xebec.de>
+ * Copyright (C) 2004,2006 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * Based on the USBLCD driver Copyright (C) 2003 Michael Reinelt <reinelt@eunet.at>
+ *
+ * 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 <usb.h>
+#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,
+};