root/trunk/drv_USBHUB.c

Revision 840, 7.4 kB (checked in by michael, 15 months ago)

email address changed

  • Property svn:keywords set to Id URL Rev
Line 
1/* $Id$
2 * $URL$
3 *
4 * new style driver for USBLCD displays
5 *
6 * Copyright (C) 2006 Ernst Bachmann <e.bachmann@xebec.de>
7 * Copyright (C) 2004,2006 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
8 *
9 * Based on the USBLCD driver Copyright (C) 2003 Michael Reinelt <michael@reinelt.co.at>
10 *
11 * This file is part of LCD4Linux.
12 *
13 * LCD4Linux is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * LCD4Linux is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28
29/*
30 *
31 * exported fuctions:
32 *
33 * struct DRIVER drv_USBHUB
34 *
35 */
36
37#include "config.h"
38
39#ifdef HAVE_USB_H
40# include <usb.h>
41#else
42# error The USB-HUB driver only makes sense with USB support
43#endif
44
45#include "debug.h"
46#include "cfg.h"
47#include "qprintf.h"
48#include "udelay.h"
49#include "drv.h"
50#include "drv_generic_gpio.h"
51
52
53
54#define HUB_CONTROL_PORT 0x23
55#define HUB_SET_FEATURE 3
56#define HUB_SET_INDICATOR 22
57
58static char Name[] = "USBHUB";
59
60/* TODO: Better not specify defaults here,
61 * instead look for the first suitable HUB arround if
62 * no Vendor/Product specified in config.
63 */
64
65static unsigned int hubVendor = 0x0409;
66static unsigned int hubProduct = 0x0058;
67
68static usb_dev_handle *hub = NULL;
69
70typedef struct _usb_hub_descriptor {
71    u_int8_t bLength;
72    u_int8_t bDescriptorType;
73    u_int8_t nNbrPorts;
74    u_int8_t wHubCharacteristicLow;
75    u_int8_t wHubCharacteristicHigh;
76    u_int8_t bPwrOn2PwrGood;
77    u_int8_t bHubContrCurrent;
78    u_int8_t deviceRemovable;
79    u_int8_t PortPwrCtrlMask[8];
80} usb_hub_descriptor;
81
82/****************************************/
83/***  hardware dependant functions    ***/
84/****************************************/
85
86
87static int drv_UH_open(void)
88{
89    struct usb_bus *busses, *bus;
90    struct usb_device *dev;
91
92    hub = NULL;
93
94    info("%s: scanning for an USB HUB (0x%04x:0x%04x)...", Name, hubVendor, hubProduct);
95
96    usb_init();
97    usb_find_busses();
98    usb_find_devices();
99    busses = usb_get_busses();
100
101    for (bus = busses; bus; bus = bus->next) {
102  for (dev = bus->devices; dev; dev = dev->next) {
103      if ((dev->descriptor.idVendor == hubVendor) && (dev->descriptor.idProduct == hubProduct)) {
104
105    unsigned int v = dev->descriptor.bcdDevice;
106
107    info("%s: found USBHUB V%1d%1d.%1d%1d on bus %s device %s", Name,
108         (v & 0xF000) >> 12, (v & 0xF00) >> 8, (v & 0xF0) >> 4, (v & 0xF), bus->dirname, dev->filename);
109
110    if (dev->descriptor.bDeviceClass != USB_CLASS_HUB) {
111        error("%s: the specified device claims to be no HUB", Name);
112        return -1;
113    }
114
115    hub = usb_open(dev);
116    if (!hub) {
117        error("%s: usb_open() failed!", Name);
118        return -1;
119    }
120    return 0;
121      }
122  }
123    }
124    error("%s: could not find a USB HUB", Name);
125    return -1;
126}
127
128
129static int drv_UH_close(void)
130{
131    debug("closing USB handle");
132
133    usb_close(hub);
134
135    return 0;
136}
137
138
139/*
140 * Set the Indicator status on port "num+1" to val.
141 * according to the USB Specification, the following values would be allowed:
142 *
143 *   0 : Automatic color (display link state etc)
144 *   1 : Amber
145 *   2 : Green
146 *   3 : Off
147 *   4..255: Reserved
148 *
149 */
150
151static int drv_UH_set(const int num, const int val)
152{
153    int ret;
154
155    if (!hub)
156  return -1;
157
158    if (val < 0 || val > 3) {
159  info("%s: value %d out of range (0..3)", Name, val);
160  return -1;
161    }
162
163    if ((ret = usb_control_msg(hub,
164             HUB_CONTROL_PORT,
165             HUB_SET_FEATURE, HUB_SET_INDICATOR, (val << 8) | (num + 1), NULL, 0, 1000)) != 0) {
166  info("%s: usb_control_msg failed with %d", Name, ret);
167  return -1;
168    }
169
170    return 0;
171}
172
173
174static int drv_UH_start(const char *section, const __attribute__ ((unused))
175      int quiet)
176{
177    char *buf;
178
179    usb_hub_descriptor hub_desc;
180    int ret;
181
182
183    buf = cfg_get(section, "Vendor", NULL);
184    if (buf) {
185  if (!*buf) {
186      error("%s: Strange Vendor Specification", Name);
187      return -1;
188  }
189  if (sscanf(buf, "0x%x", &hubVendor) != 1) {
190      error("%s: Strange Vendor Specification: [%s]", Name, buf);
191      return -1;
192  }
193    }
194
195    buf = cfg_get(section, "Product", NULL);
196    if (buf) {
197  if (!*buf) {
198      error("%s: Strange Product Specification", Name);
199      return -1;
200  }
201  if (sscanf(buf, "0x%x", &hubProduct) != 1) {
202      error("%s: Strange Product Specification: [%s]", Name, buf);
203      return -1;
204  }
205    }
206
207    if (drv_UH_open() < 0) {
208  return -1;
209    }
210
211
212    if ((ret = usb_control_msg(hub,
213             USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
214             USB_REQ_GET_DESCRIPTOR, USB_DT_HUB << 8, 0, (char *) &hub_desc, sizeof(hub_desc),
215             1000)) <= 8) {
216  error("%s: hub_get_descriptor failed with %d", Name, ret);
217  drv_UH_close();
218  return -1;
219    }
220    GPOS = hub_desc.nNbrPorts;
221    debug("%s: HUB claims to have %d ports. Configuring them as GPOs", Name, GPOS);
222    if (!(hub_desc.wHubCharacteristicLow & 0x80)) {
223  error("%s: HUB claims to have no Indicator LEDs (Characteristics 0x%04x). Bailing out.", Name,
224        (hub_desc.wHubCharacteristicHigh << 8) | hub_desc.wHubCharacteristicLow);
225  /* The HUB Tells us that there are no LEDs to control. Breaking? Maybe don't trust it and continue anyways? */
226  drv_UH_close();
227  return -1;
228
229    }
230
231    return 0;
232}
233
234
235/****************************************/
236/***            plugins               ***/
237/****************************************/
238
239/* none at the moment... */
240
241
242/****************************************/
243/***        widget callbacks          ***/
244/****************************************/
245
246
247/* using drv_generic_text_draw(W) */
248/* using drv_generic_text_icon_draw(W) */
249/* using drv_generic_text_bar_draw(W) */
250
251
252/****************************************/
253/***        exported functions        ***/
254/****************************************/
255
256
257/* list models */
258int drv_UH_list(void)
259{
260    printf("generic");
261    return 0;
262}
263
264
265/* initialize driver & display */
266int drv_UH_init(const char *section, const int quiet)
267{
268    int ret;
269    int i;
270
271    info("%s: %s", Name, "$Rev$");
272
273
274
275    /* start display */
276    if ((ret = drv_UH_start(section, quiet)) != 0)
277  return ret;
278
279
280    /* real worker functions */
281    drv_generic_gpio_real_set = drv_UH_set;
282
283
284    /* initialize generic GPIO driver */
285    if ((ret = drv_generic_gpio_init(section, Name)) != 0)
286  return ret;
287
288    /* register gpio widget, done already by generic_gpio */
289
290    /* register plugins */
291    /* none at the moment... */
292
293    /* greeting */
294    if (!quiet) {
295  /* Light all LEDS green for a greeting */
296  for (i = 0; i < GPOS; ++i) {
297      drv_UH_set(i, 2);
298  }
299  sleep(1);
300  for (i = 0; i < GPOS; ++i) {
301      drv_UH_set(i, 3); /* OFF */
302  }
303    }
304
305
306    return 0;
307}
308
309
310/* close driver & display */
311int drv_UH_quit(const int quiet)
312{
313    int i;
314    debug("%s: shutting down.", Name);
315
316    /* say goodbye... */
317    if (!quiet) {
318  /* Light all LEDS amber for a goodbye */
319  for (i = 0; i < GPOS; ++i) {
320      drv_UH_set(i, 1);
321  }
322  sleep(1);
323
324    }
325
326    drv_generic_gpio_quit();
327
328    drv_UH_close();
329
330    info("%s: shutdown complete.", Name);
331    return 0;
332}
333
334
335DRIVER drv_USBHUB = {
336    .name = Name,
337    .list = drv_UH_list,
338    .init = drv_UH_init,
339    .quit = drv_UH_quit,
340};
Note: See TracBrowser for help on using the browser.