aboutsummaryrefslogtreecommitdiffstats
path: root/drv_G15.c
diff options
context:
space:
mode:
Diffstat (limited to 'drv_G15.c')
-rw-r--r--drv_G15.c151
1 files changed, 118 insertions, 33 deletions
diff --git a/drv_G15.c b/drv_G15.c
index 7922190..98fe120 100644
--- a/drv_G15.c
+++ b/drv_G15.c
@@ -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");