diff options
Diffstat (limited to 'drv_G15.c')
-rw-r--r-- | drv_G15.c | 151 |
1 files changed, 118 insertions, 33 deletions
@@ -1,10 +1,10 @@ -/* $Id: drv_G15.c 773 2007-02-25 12:39:09Z michael $ - * $URL: https://ssl.bulix.org/svn/lcd4linux/branches/0.10.1/drv_G15.c $ +/* $Id: drv_G15.c 1117 2010-04-18 11:47:58Z mzuther $ + * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_G15.c $ * * Driver for Logitech G-15 keyboard LCD screen * * Copyright (C) 2006 Dave Ingram <dave@partis-project.net> - * Copyright (C) 2005 Michael Reinelt <reinelt@eunet.at> + * Copyright (C) 2005 Michael Reinelt <michael@reinelt.co.at> * Copyright (C) 2005 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> * * This file is part of LCD4Linux. @@ -45,6 +45,9 @@ #include <linux/input.h> #include <linux/uinput.h> +#include <unistd.h> +#include <sys/types.h> + #include "debug.h" #include "cfg.h" #include "qprintf.h" @@ -54,8 +57,14 @@ #include "drv_generic_graphic.h" #include "thread.h" +/* Logitech: VendorID 0x046d */ #define G15_VENDOR 0x046d +/* Logitech Keyboard G15: ProductID 0xc222, 0xc227 */ +/* Logitech Speaker Z10: ProductID 0x0a07 */ #define G15_DEVICE 0xc222 +#define G15_DEVICE2 0xc227 +#define Z10_DEVICE 0x0a07 +#define M1730_DEVICE 0xc251 #if 0 #define DEBUG(x) debug("%s(): %s", __FUNCTION__, x); @@ -80,6 +89,8 @@ static int kb_mutex; static int kb_thread_pid; static int kb_single_keypress = 0; +static int usb_endpoint = 0; + /****************************************/ /*** hardware dependant functions ***/ @@ -301,36 +312,108 @@ static int drv_G15_open() struct usb_bus *bus; struct usb_device *dev; char dname[32] = { 0 }; + int interf = -1; + int config = 1; + int retval; g15_lcd = NULL; - info("%s: Scanning USB for G-15 keyboard...", Name); + info("%s: Scanning USB for G-15 keyboard or Z-10 speaker ...", Name); usb_init(); - usb_set_debug(0); - usb_find_busses(); - usb_find_devices(); + usb_set_debug(0); // 0: no, 1 error, 2 warn, 3 info + debug("%s: found %d USB busses", Name, usb_find_busses()); + debug("%s: found %d USB devices", Name, usb_find_devices()); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { - if ((g15_lcd = usb_open(dev))) { - if ((dev->descriptor.idVendor == G15_VENDOR) && (dev->descriptor.idProduct == G15_DEVICE)) { + debug("%s: open %s/%s/%s", Name, bus->dirname, dev->bus->dirname, dev->filename); + if (dev->descriptor.idVendor == G15_VENDOR) { + if ((g15_lcd = usb_open(dev))) { + // get vendor name if possible + if (dev->descriptor.iManufacturer) { + retval = usb_get_string_simple(g15_lcd, dev->descriptor.iManufacturer, dname, sizeof(dname)); + if (retval <= 0) { + snprintf(dname, sizeof(dname), "(unknown)"); + } + } + debug("%s: Found USB vendor ID 0x%x (%s), checking productID 0x%x...", + Name, G15_VENDOR, dname, dev->descriptor.idProduct); + switch (dev->descriptor.idProduct) { + case G15_DEVICE: + case G15_DEVICE2: + case M1730_DEVICE: + { + info("%s: Found Logitech G-15 or Dell M1730 Keyboard", Name); + interf = 0; + config = 1; + usb_endpoint = 0x02; + break; + } + case Z10_DEVICE: + { + info("%s: Found Logitech Z-10 Speaker", Name); + interf = 2; + usb_endpoint = 0x03; + break; + } + default: + debug("%s: Don't found USB product IDs 0x%x|0x%x/0x%x for G-15/M1730 or 0x%x for Z10", + Name, G15_DEVICE, G15_DEVICE2, M1730_DEVICE, Z10_DEVICE); + usb_close(g15_lcd); + } - /* detach from the kernel if we need to */ - int retval = usb_get_driver_np(g15_lcd, 0, dname, 31); - if (retval == 0 && strcmp(dname, "usbhid") == 0) { - usb_detach_kernel_driver_np(g15_lcd, 0); + if (interf >= 0) { + debug("%s: Vendor 0x%x Product 0x%x found", + Name, dev->descriptor.idVendor, dev->descriptor.idProduct); + +#ifdef LIBUSB_HAS_GET_DRIVER_NP + /* detach from the kernel if we need to */ + retval = usb_get_driver_np(g15_lcd, interf, dname, 31); + debug("%s: Ret %i from usb_get_driver_np(interf.%d), Drivername %s", + Name, retval, interf, dname); + switch (retval) { + case -EPERM: + error("%s: Permission denied! eUID of this process is %i %s", + Name, geteuid(), geteuid() != 0 ? "(not root)" : ""); + //return -1; + break; + case -ENODATA: + error("%s: No data available! Device switched off?", Name); + //return -1; + break; + } +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + if (retval == 0 && strcmp(dname, "usbhid") == 0) { + debug("%s: detaching...", Name); + usb_detach_kernel_driver_np(g15_lcd, interf); + } +#endif // detach_kernel_driver_np +#endif // get_driver_np + + retval = usb_set_configuration(g15_lcd, config); + debug("%s: Ret %d from usb_set_configuration(%d)", Name, retval, config); + switch (retval) { + case -EPERM: + error("%s: Permission denied! eUID of this process is %i %s", + Name, geteuid(), geteuid() != 0 ? "(not root)" : ""); + return -1; + break; + case -EBUSY: + error("%s: Device or resource busy! Device switched off?", Name); + return -1; + break; + } + usleep(100); + retval = usb_claim_interface(g15_lcd, interf); + debug("%s: Ret %i from usb_claim_interface(%d)", Name, retval, interf); + return retval; } - usb_set_configuration(g15_lcd, 1); - usleep(100); - usb_claim_interface(g15_lcd, 0); - return 0; - } else { - usb_close(g15_lcd); + } - } - } - } + } // G15_Vendor + } // all devices + } // all busses return -1; } @@ -349,31 +432,33 @@ static int drv_G15_close(void) static void drv_G15_update_img() { int i, j, k; - unsigned char *output = malloc(160 * 43 * sizeof(unsigned char)); + unsigned char *output = malloc(DCOLS * DROWS * sizeof(unsigned char)); + int retval; DEBUG("entered"); if (!output) return; DEBUG("memory allocated"); - memset(output, 0, 160 * 43); + memset(output, 0, DCOLS * DROWS); DEBUG("memory set"); output[0] = 0x03; DEBUG("first output set"); for (k = 0; k < 6; k++) { - for (i = 0; i < 160; i++) { + for (i = 0; i < DCOLS; i++) { int maxj = (k == 5) ? 3 : 8; for (j = 0; j < maxj; j++) { - if (g15_image[(k * 1280) + i + (j * 160)]) - output[32 + i + (k * 160)] |= (1 << j); + if (g15_image[(k * 1280) + i + (j * DCOLS)]) + output[32 + i + (k * DCOLS)] |= (1 << j); } } } DEBUG("output array prepared"); mutex_lock(kb_mutex); - usb_interrupt_write(g15_lcd, 0x02, (char *) output, 992, 1000); + retval = usb_interrupt_write(g15_lcd, usb_endpoint, (char *) output, 992, 1000); + //info("%s: Ret %i from usb_interrupt_write(endpoint %d)", Name, retval, usb_endpoint); mutex_unlock(kb_mutex); usleep(300); @@ -396,7 +481,7 @@ static void drv_G15_blit(const int row, const int col, const int height, const i for (r = row; r < row + height; r++) { for (c = col; c < col + width; c++) { - g15_image[r * 160 + c] = drv_generic_graphic_black(r, c); + g15_image[r * DCOLS + c] = drv_generic_graphic_black(r, c); } } @@ -444,11 +529,11 @@ static int drv_G15_start(const char *section) DEBUG("allocating image buffer"); /* you surely want to allocate a framebuffer or something... */ - g15_image = malloc(160 * 43 * sizeof(unsigned char)); + g15_image = malloc(DCOLS * DROWS * sizeof(unsigned char)); if (!g15_image) return -1; DEBUG("allocated"); - memset(g15_image, 0, 160 * 43); + memset(g15_image, 0, DCOLS * DROWS); DEBUG("zeroed"); /* open communication with the display */ @@ -501,7 +586,7 @@ static int drv_G15_start(const char *section) /* list models */ int drv_G15_list(void) { - printf("generic"); + printf("Logitech G-15 or Z-10 / Dell M1730"); return 0; } @@ -511,7 +596,7 @@ int drv_G15_init(const char *section, const int quiet) { int ret; - info("%s: %s", Name, "$Rev: 773 $"); + info("%s: %s", Name, "$Rev: 1117 $"); DEBUG("entered"); |