diff --git a/ChangeLog b/ChangeLog index 24b6d2078..00b422020 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-07-24 Henning Meier-Geinitz + + * tools/check-usb-chip.c: Added support for detecting Genesys + Logic GL646. + 2003-07-23 Henning Meier-Geinitz * include/sane/sanei_thread.h include/sane/sanei_usb.h: Changed diff --git a/tools/check-usb-chip.c b/tools/check-usb-chip.c index d12ef1296..94f1b1b94 100644 --- a/tools/check-usb-chip.c +++ b/tools/check-usb-chip.c @@ -984,6 +984,194 @@ check_merlin (struct usb_device *dev) } } +/********** the gl646 section **********/ + + +static int +gl646_write_reg (usb_dev_handle * handle, unsigned char reg, unsigned char val) +{ + int result; + + result = usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) ®, 0x01, TIMEOUT); + if (result < 0) + return 0; + + result = usb_control_msg (handle, 0x00, 0x00, 0x85, 0x00, (char *) &val, 0x01, TIMEOUT); + if (result < 0) + return 0; + + return 1; +} + +static int +gl646_read_reg (usb_dev_handle * handle, unsigned char reg, unsigned char *val) +{ + int result; + + result = usb_control_msg (handle, 0x00, 0x00, 0x83, 0x00, (char *) ®, 0x01, TIMEOUT); + if (result < 0) + return 0; + + result = usb_control_msg (handle, 0x80, 0x00, 0x84, 0x00, (char *) val, 0x01, TIMEOUT); + if (result < 0) + return 0; + + return 1; +} + + +static char * +check_gl646 (struct usb_device *dev) +{ + unsigned char val; + int result; + usb_dev_handle *handle; + + if (verbose > 2) + printf (" checking for GL646 ...\n"); + + /* Check device descriptor */ + if ( (dev->descriptor.bDeviceClass != USB_CLASS_PER_INTERFACE) + || (dev->config[0].interface[0].altsetting[0].bInterfaceClass != + 0x10)) + { + if (verbose > 2) + printf + (" this is not a GL646 (bDeviceClass = %d, bInterfaceClass = %d)\n", + dev->descriptor.bDeviceClass, + dev->config[0].interface[0].altsetting[0].bInterfaceClass); + return 0; + } + if (dev->descriptor.bcdUSB != 0x110) + { + if (verbose > 2) + printf (" this is not a GL646 (bcdUSB = 0x%x)\n", + dev->descriptor.bcdUSB); + return 0; + } + if (dev->descriptor.bDeviceSubClass != 0x00) + { + if (verbose > 2) + printf (" this is not a GL646 (bDeviceSubClass = 0x%x)\n", + dev->descriptor.bDeviceSubClass); + return 0; + } + if (dev->descriptor.bDeviceProtocol != 0) + { + if (verbose > 2) + printf (" this is not a GL646 (bDeviceProtocol = 0x%x)\n", + dev->descriptor.bDeviceProtocol); + return 0; + } + + /* Check endpoints */ + if (dev->config[0].interface[0].altsetting[0].bNumEndpoints != 3) + { + if (verbose > 2) + printf (" this is not a GL646 (bNumEndpoints = %d)\n", + dev->config[0].interface[0].altsetting[0].bNumEndpoints); + return 0; + } + + if ((dev->config[0].interface[0].altsetting[0].endpoint[0]. + bEndpointAddress != 0x81) + || (dev->config[0].interface[0].altsetting[0].endpoint[0]. + bmAttributes != 0x02) + || (dev->config[0].interface[0].altsetting[0].endpoint[0]. + wMaxPacketSize != 0x40) + || (dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval != + 0x0)) + { + if (verbose > 2) + printf + (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + dev->config[0].interface[0].altsetting[0].endpoint[0]. + bEndpointAddress, + dev->config[0].interface[0].altsetting[0].endpoint[0].bmAttributes, + dev->config[0].interface[0].altsetting[0].endpoint[0]. + wMaxPacketSize, + dev->config[0].interface[0].altsetting[0].endpoint[0].bInterval); + return 0; + } + + if ((dev->config[0].interface[0].altsetting[0].endpoint[1]. + bEndpointAddress != 0x02) + || (dev->config[0].interface[0].altsetting[0].endpoint[1]. + bmAttributes != 0x02) + || (dev->config[0].interface[0].altsetting[0].endpoint[1]. + wMaxPacketSize != 0x40) + || (dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval != 0) + ) + { + if (verbose > 2) + printf + (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + dev->config[0].interface[0].altsetting[0].endpoint[1]. + bEndpointAddress, + dev->config[0].interface[0].altsetting[0].endpoint[1].bmAttributes, + dev->config[0].interface[0].altsetting[0].endpoint[1]. + wMaxPacketSize, + dev->config[0].interface[0].altsetting[0].endpoint[1].bInterval); + return 0; + } + + if ((dev->config[0].interface[0].altsetting[0].endpoint[2]. + bEndpointAddress != 0x83) + || (dev->config[0].interface[0].altsetting[0].endpoint[2]. + bmAttributes != 0x03) + || (dev->config[0].interface[0].altsetting[0].endpoint[2]. + wMaxPacketSize != 0x1) + || (dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval != 8) + ) + { + if (verbose > 2) + printf + (" this is not a GL646 (bEndpointAddress = 0x%x, bmAttributes = 0x%x, " + "wMaxPacketSize = 0x%x, bInterval = 0x%x)\n", + dev->config[0].interface[0].altsetting[0].endpoint[2]. + bEndpointAddress, + dev->config[0].interface[0].altsetting[0].endpoint[2].bmAttributes, + dev->config[0].interface[0].altsetting[0].endpoint[2]. + wMaxPacketSize, + dev->config[0].interface[0].altsetting[0].endpoint[2].bInterval); + return 0; + } + + result = prepare_interface (dev, &handle); + if (!result) + return "GL646?"; + + result = gl646_write_reg (handle, 0x38, 0x15); + if (!result) + { + if (verbose > 2) + printf (" this is not a GL646 (writing register failed)\n"); + finish_interface (handle); + return 0; + } + + result = gl646_read_reg (handle, 0x4e, &val); + if (!result) + { + if (verbose > 2) + printf (" this is not a GL646 (reading register failed)\n"); + finish_interface (handle); + return 0; + } + + if (val != 0x15) + { + if (verbose > 2) + printf (" this is not a GL646 (reg 0x4e != reg 0x38)\n"); + finish_interface (handle); + return 0; + } + finish_interface (handle); + return "GL646"; +} + char * check_usb_chip (struct usb_device *dev, int verbosity) @@ -1016,6 +1204,10 @@ check_usb_chip (struct usb_device *dev, int verbosity) if (chip_name) return chip_name; + chip_name = check_gl646 (dev); + if (chip_name) + return chip_name; + return 0; /* unknown chipset */ }