From 638326e8fa5990bf20e05d1ce662fec611842fc1 Mon Sep 17 00:00:00 2001 From: GWater Date: Sun, 17 Feb 2008 23:11:02 +0100 Subject: [PATCH] Nicolas's patch for reading/writing multiple bytes. --- microdia-dev.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++---------- microdia-usb.c | 20 ++++---- microdia.h | 88 ++++++++++++++++---------------- 3 files changed, 185 insertions(+), 80 deletions(-) diff --git a/microdia-dev.c b/microdia-dev.c index 8c8ffd6..a843464 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -44,6 +44,96 @@ #include "microdia.h" +/** + * @brief From UsbSnoop-plugin-parsed.log + * + * @param dev + * + * @returns + */ +int microdia_627b_initialize(struct usb_microdia *dev) +{ + int i; + int actual; + int ret; + __u8 buf[32]; + + usb_microdia_control_read(dev, 0x130d, buf, 1); // URB 5 + usb_microdia_control_write(dev, 0x0000, 0x1040, buf, 1); // URB 6 + + usb_microdia_control_read(dev, 0x118a, buf, 1); // URB 7 + usb_microdia_control_read(dev, 0x0395, buf, 1); // URB 8 + + buf[0] = 0x05; + usb_microdia_control_write(dev, 0x0000, 0x118a, buf, 1); // URB 9 + usb_microdia_control_write(dev, 0x0000, 0x0395, buf, 1); // URB 10 + + usb_microdia_control_read(dev, 0x11b8, buf, 1); // URB 11 + + buf[0] = 0x10; + usb_microdia_control_write(dev, 0x0000, 0x11b8, buf, 1); // URB 12 + + usb_microdia_control_read(dev, 0x1000, buf, 5); // URB 13 + + buf[0] = 0x70; buf[1] = 0x00; buf[2] = 0x18; buf[3] = 0x00; buf[4] = 0x00; + usb_microdia_control_write(dev, 0x0000, 0x1000, buf, 5); // URB 14 + + usb_microdia_control_read(dev, 0x1060, buf, 2); // URB 15 + + buf[0] = 0x00; buf[1] = 0x03; + usb_microdia_control_write(dev, 0x0000, 0x1060, buf, 2); // URB 16 + + buf[0] = 0x21; + usb_microdia_control_write(dev, 0x0000, 0x10c8, buf, 1); // URB 17 + + buf[0] = 0x90; buf[1] = 0x21; buf[2] = 0x0a; buf[3] = 0x00; + buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x00; + usb_microdia_control_write(dev, 0x0000, 0x10c0, buf, 8); // URB 18 + + for (i=0; i<8; i++) + usb_microdia_control_read(dev, 0x10c0, buf, 1); // URB 19 - 26 + + buf[0] = 0x92; buf[1] = 0x21; buf[2] = 0x00; buf[3] = 0x00; + buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x10; + usb_microdia_control_write(dev, 0x0000, 0x10c0, buf, 8); // URB 27 + + usb_microdia_control_read(dev, 0x10c0, buf, 1); // URB 28 + usb_microdia_control_read(dev, 0x10c2, buf, 5); // URB 29 + + buf[0] = 0x21; + usb_microdia_control_write(dev, 0x0000, 0x10c8, buf, 1); // URB 30 + + buf[0] = 0x92; buf[1] = 0x21; buf[2] = 0x0a; buf[3] = 0x00; + buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x10; + usb_microdia_control_write(dev, 0x0000, 0x10c0, buf, 8); // URB 31 + + usb_microdia_control_read(dev, 0x10c0, buf, 1); // URB 32 + + buf[0] = 0x92; buf[1] = 0x21; buf[2] = 0x00; buf[3] = 0x00; + buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x10; + usb_microdia_control_read(dev, 0x10c0, buf, 8); // URB 33 + + usb_microdia_control_write(dev, 0x0000, 0x10c0, buf, 1); // URB 34 + usb_microdia_control_read(dev, 0x10c2, buf, 5); // URB 35 + + buf[0] = 0xa6; + usb_microdia_control_write(dev, 0x0000, 0x118a, buf, 1); // URB 36 + usb_microdia_control_write(dev, 0x0000, 0x0395, buf, 1); // URB 37 + + buf[0] = 0x06; + usb_microdia_control_write(dev, 0x0000, 0x11b8, buf, 1); // URB 38 + + buf[0] = 0x30; buf[1] = 0xcf; buf[2] = 0x00; buf[3] = 0x03; buf[4] = 0x02; + usb_microdia_control_write(dev, 0x0000, 0x11b8, buf, 5); // URB 39 + + buf[0] = 0x08; buf[1] = 0x00; + usb_microdia_control_write(dev, 0x0000, 0x1060, buf, 2); // URB 40 + + ret = usb_interrupt_msg(dev->udev, 0x00000083, buf, 0x0000001, &actual, 1000); // URB 41 + + return ret; +} + /** * @brief From UsbSnoop-plugin-parsed.log @@ -56,9 +146,9 @@ int microdia_624f_initialize(struct usb_microdia *dev) { int actual; int ret; - __u8 buf; + __u8 buf[32]; - usb_microdia_control_read(dev, 0x130d, &buf); + usb_microdia_control_read(dev, 0x130d, buf, 1); // URB5 /* * Right now this is totally a black box: in particular, we @@ -69,34 +159,49 @@ int microdia_624f_initialize(struct usb_microdia *dev) * could have some strange relationship with the read values. */ - usb_microdia_control_read(dev, 0x1040, &buf); - usb_microdia_control_write(dev, 0x0000, 0x10c8, buf); + usb_microdia_control_read(dev, 0x1040, buf, 1); // URB 6 + usb_microdia_control_write(dev, 0x0000, 0x10c8, buf, 1); // URB 7 + + ret = usb_interrupt_msg(dev->udev, 0x00000083, buf, 0x0000001, &actual, 1000); // URB 8 + + usb_microdia_control_read(dev, 0x100a, buf, 1); // URB 9 + usb_microdia_control_write(dev, 0x0000, 0x100a, buf, 1); // URB 10 + + usb_microdia_control_read(dev, 0x100b, buf, 1); // URB 11 + + buf[0] = 0x04; + usb_microdia_control_write(dev, 0x0000, 0x100b, buf, 1); // URB 12 + + usb_microdia_control_read(dev, 0x1001, buf, 1); // URB 13 + + buf[0] = 0xc7; + usb_microdia_control_write(dev, 0x0000, 0x1001, buf, 1); // URB 14 + + ret = usb_interrupt_msg(dev->udev, 0x00000083, buf, 0x0000001, &actual, 1000); // URB 15 - ret = usb_interrupt_msg(dev->udev, 0x00000083, &buf, 0x0000001, &actual, 1000); + usb_microdia_control_read(dev, 0x1040, buf, 1); // URB 16 - usb_microdia_control_read(dev, 0x100a, &buf); - usb_microdia_control_write(dev, 0x0000, 0x100a, buf); + buf[0] = 0x00; + usb_microdia_control_write(dev, 0x0000, 0x1040, buf, 1); // URB 17 - usb_microdia_control_read(dev, 0x100b, &buf); - usb_microdia_control_write(dev, 0x0000, 0x100b, 0x04); + usb_microdia_control_read(dev, 0x1045, buf, 1); // URB 18 - usb_microdia_control_read(dev, 0x1001, &buf); - usb_microdia_control_write(dev, 0x0000, 0x1001, 0xc7); + buf[0] = 0x04; + usb_microdia_control_write(dev, 0x0000, 0x1045, buf, 1); // URB 19 - ret = usb_interrupt_msg(dev->udev, 0x00000083, &buf, 0x0000001, &actual, 1000); + usb_microdia_control_read(dev, 0x1046, buf, 1); // URB 20 - usb_microdia_control_read(dev, 0x1040, &buf); - usb_microdia_control_write(dev, 0x0000, 0x1040, 0x00); + buf[0] = 0x10; + usb_microdia_control_write(dev, 0x0000, 0x1046, buf, 1); // URB 21 - usb_microdia_control_read(dev, 0x1045, &buf); - usb_microdia_control_write(dev, 0x0000, 0x1045, 0x04); + buf[0] = 0x14; + usb_microdia_control_write(dev, 0x0000, 0x1045, buf, 1); // URB 22 - usb_microdia_control_read(dev, 0x1046, &buf); - usb_microdia_control_write(dev, 0x0000, 0x1046, 0x10); + buf[0] = 0x01; + usb_microdia_control_write(dev, 0x0000, 0x1040, buf, 1); // URB 23 - usb_microdia_control_write(dev, 0x0000, 0x1045, 0x14); - usb_microdia_control_write(dev, 0x0000, 0x1040, 0x01); - usb_microdia_control_write(dev, 0x0000, 0x1020, 0x80); + buf[0] = 0x80; + usb_microdia_control_write(dev, 0x0000, 0x1020, buf, 1); // URB 24 return ret; } @@ -112,14 +217,12 @@ int microdia_624e_initialize(struct usb_microdia *dev) { int actual; int ret; - __u8 buf; - __u8 u; + __u8 buf[32]; - usb_microdia_control_read(dev, 0x130d, &buf); - usb_microdia_control_read(dev, 0x1040, &buf); + usb_microdia_control_read(dev, 0x130d, buf, 1); + usb_microdia_control_read(dev, 0x1040, buf, 1); - u = 0x00; /** Will have to be set for every single interrupt. */ - ret = usb_interrupt_msg(dev->udev, 0x00000083, &u, 0x0000001, &actual, 1000); + ret = usb_interrupt_msg(dev->udev, 0x00000083, buf, 0x0000001, &actual, 1000); return ret; } diff --git a/microdia-usb.c b/microdia-usb.c index de55eee..a03c933 100644 --- a/microdia-usb.c +++ b/microdia-usb.c @@ -545,19 +545,18 @@ int usb_microdia_set_configuration(struct usb_microdia *dev) * * This function permits to write a 16-bit value to a 16-bit register on the USB bus. */ -int usb_microdia_control_write(struct usb_microdia *dev, __u16 index, __u16 value, __u8 data) +int usb_microdia_control_write(struct usb_microdia *dev, __u16 index, __u16 value, __u8 *data, __u16 length) { int result; struct usb_device *udev = dev->udev; - __u8 buf = data; result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, index, - &buf, - sizeof(__u8), + data, + length, 500); if (result < 0) @@ -578,21 +577,21 @@ int usb_microdia_control_write(struct usb_microdia *dev, __u16 index, __u16 valu * * This function permits to read a 16-bit value from a 16-bit register on the USB bus. */ -int usb_microdia_control_read(struct usb_microdia *dev, __u16 index, __u8 *buf) +int usb_microdia_control_read(struct usb_microdia *dev, __u16 index, __u8 *data, __u16 length) { int result; struct usb_device *udev = dev->udev; - *buf = 0; + *data = 0; result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, index, 0x00, - buf, - sizeof(__u8), + data, + length, 500); if (result < 0) @@ -631,6 +630,7 @@ static int usb_microdia_default_settings(struct usb_microdia *dev) return 0; } +extern int microdia_627b_initialize(struct usb_microdia *dev); extern int microdia_624f_initialize(struct usb_microdia *dev); extern int microdia_624e_initialize(struct usb_microdia *dev); @@ -656,7 +656,7 @@ static int usb_microdia_probe(struct usb_interface *interface, const struct usb_ int bNumInterfaces; int webcam_model; int webcam_type; - int (*initialize)(struct usb_microdia *); + int (*initialize)(struct usb_microdia *) = NULL; struct usb_microdia *dev = NULL; struct usb_device *udev = interface_to_usbdev(interface); @@ -741,8 +741,10 @@ static int usb_microdia_probe(struct usb_interface *interface, const struct usb_ break; case USB_UDIA_627B_PRODUCT_ID: + UDIA_INFO("Microdia USB2.0 Webcam - Product ID 627B.\n"); webcam_model = MICRODIA_627B; webcam_type = MICRODIA_VGA; + initialize = microdia_627b_initialize; break; case USB_UDIA_62C0_PRODUCT_ID: diff --git a/microdia.h b/microdia.h index 0f9c2de..daf47b9 100644 --- a/microdia.h +++ b/microdia.h @@ -35,31 +35,31 @@ #define MICRODIA_H -#define DRIVER_NAME "microdia" /**< Name of this driver */ -#define DRIVER_VERSION "v0.0.0" /**< Version of this driver */ -#define DRIVER_VERSION_NUM 0x000000 /**< Version numerical of this driver */ -#define DRIVER_DESC "Microdia USB Video Camera" /**< Short description of this driver */ -#define DRIVER_AUTHOR "Nicolas VIVIEN" /**< Author of this driver */ -#define PREFIX DRIVER_NAME ": " /**< Prefix use for the STK "printk" */ - -#define USB_MICRODIA_VENDOR_ID 0x0c45 /**< Vendor ID of the camera */ - -#define USB_UDIA_6027_PRODUCT_ID 0xA311 /**< Product ID of the camera ??? */ -//#define USB_UDIA_6027_PRODUCT_ID 0x6027 /**< Product ID of the camera ??? */ -#define USB_UDIA_608F_PRODUCT_ID 0x608f /**< Product ID of the camera ??? */ -#define USB_UDIA_60FE_PRODUCT_ID 0x60fe /**< Product ID of the camera ??? */ -#define USB_UDIA_6242_PRODUCT_ID 0x6242 /**< Product ID of the camera ??? */ -#define USB_UDIA_6253_PRODUCT_ID 0x6253 /**< Product ID of the camera ??? */ -#define USB_UDIA_6260_PRODUCT_ID 0x6260 /**< Product ID of the camera ??? */ -#define USB_UDIA_6270_PRODUCT_ID 0x6270 /**< Product ID of the camera ??? */ -#define USB_UDIA_60C0_PRODUCT_ID 0x60c0 /**< Product ID of the camera ??? */ -#define USB_UDIA_613B_PRODUCT_ID 0x613b /**< Product ID of the camera ??? */ -#define USB_UDIA_613C_PRODUCT_ID 0x613c /**< Product ID of the camera ??? */ -#define USB_UDIA_624F_PRODUCT_ID 0x624f /**< Product ID of the camera ??? */ -#define USB_UDIA_627B_PRODUCT_ID 0x627b /**< Product ID of the camera ??? */ -#define USB_UDIA_62C0_PRODUCT_ID 0x62c0 /**< Product ID of the camera ??? */ -#define USB_UDIA_8105_PRODUCT_ID 0x8105 /**< Product ID of the camera ??? */ -#define USB_UDIA_624E_PRODUCT_ID 0x624e /**< Product ID of the camera ??? */ +#define DRIVER_NAME "microdia" /**< Name of this driver */ +#define DRIVER_VERSION "v0.0.0" /**< Version of this driver */ +#define DRIVER_VERSION_NUM 0x000000 /**< Version numerical of this driver */ +#define DRIVER_DESC "Microdia USB Video Camera" /**< Short description of this driver */ +#define DRIVER_AUTHOR "Nicolas VIVIEN" /**< Author of this driver */ +#define PREFIX DRIVER_NAME ": " /**< Prefix use for the STK "printk" */ + +#define USB_MICRODIA_VENDOR_ID 0x0c45 /**< Vendor ID of the camera */ + +#define USB_UDIA_6027_PRODUCT_ID 0xA311 /**< Product ID of the camera ??? */ +//#define USB_UDIA_6027_PRODUCT_ID 0x6027 /**< Product ID of the camera ??? */ +#define USB_UDIA_608F_PRODUCT_ID 0x608f /**< Product ID of the camera ??? */ +#define USB_UDIA_60FE_PRODUCT_ID 0x60fe /**< Product ID of the camera ??? */ +#define USB_UDIA_6242_PRODUCT_ID 0x6242 /**< Product ID of the camera ??? */ +#define USB_UDIA_6253_PRODUCT_ID 0x6253 /**< Product ID of the camera ??? */ +#define USB_UDIA_6260_PRODUCT_ID 0x6260 /**< Product ID of the camera ??? */ +#define USB_UDIA_6270_PRODUCT_ID 0x6270 /**< Product ID of the camera ??? */ +#define USB_UDIA_60C0_PRODUCT_ID 0x60c0 /**< Product ID of the camera ??? */ +#define USB_UDIA_613B_PRODUCT_ID 0x613b /**< Product ID of the camera ??? */ +#define USB_UDIA_613C_PRODUCT_ID 0x613c /**< Product ID of the camera ??? */ +#define USB_UDIA_624F_PRODUCT_ID 0x624f /**< Product ID of the camera ??? */ +#define USB_UDIA_627B_PRODUCT_ID 0x627b /**< Product ID of the camera ??? */ +#define USB_UDIA_62C0_PRODUCT_ID 0x62c0 /**< Product ID of the camera ??? */ +#define USB_UDIA_8105_PRODUCT_ID 0x8105 /**< Product ID of the camera ??? */ +#define USB_UDIA_624E_PRODUCT_ID 0x624e /**< Product ID of the camera ??? */ /** @@ -305,35 +305,35 @@ struct microdia_video { * @struct usb_microdia */ struct usb_microdia { - struct video_device *vdev; /**< Pointer on a V4L2 video device */ - struct usb_device *udev; /**< Pointer on a USB device */ + struct video_device *vdev; /**< Pointer on a V4L2 video device */ + struct usb_device *udev; /**< Pointer on a USB device */ struct usb_interface *interface; /**< Pointer on a USB interface */ - int release; /**< Release of the device (bcdDevice) */ - int webcam_model; /**< Model of video camera device */ - int webcam_type; /**< Type of camera : VGA, SXGA (1.3M), UXGA (2M) */ + int release; /**< Release of the device (bcdDevice) */ + int webcam_model; /**< Model of video camera device */ + int webcam_type; /**< Type of camera : VGA, SXGA (1.3M), UXGA (2M) */ unsigned char *int_in_buffer; /**< Interrupt IN buffer */ - size_t int_in_size; /**< Interrupt IN buffer size */ - __u8 int_in_endpointAddr; /**< Interrupt IN endpoint address */ + size_t int_in_size; /**< Interrupt IN buffer size */ + __u8 int_in_endpointAddr; /**< Interrupt IN endpoint address */ - size_t isoc_in_size; /**< Isochrone IN size */ - __u8 isoc_in_endpointAddr; /**< Isochrone IN endpoint address */ + size_t isoc_in_size; /**< Isochrone IN size */ + __u8 isoc_in_endpointAddr; /**< Isochrone IN endpoint address */ - int watchdog; /**< Counter for the software watchdog */ + int watchdog; /**< Counter for the software watchdog */ - struct microdia_video vsettings; /**< Video settings (brightness, whiteness...) */ + struct microdia_video vsettings; /**< Video settings (brightness, whiteness...) */ int error_status; - int vopen; /**< Video status (Opened or Closed) */ - int visoc_errors; /**< Count the number of ISOCH errors */ - int vframes_error; /**< Count the number of fault frames (so dropped) */ - int vframes_dumped; /**< Count the number of ignored frames */ + int vopen; /**< Video status (Opened or Closed) */ + int visoc_errors; /**< Count the number of ISOCH errors */ + int vframes_error; /**< Count the number of fault frames (so dropped) */ + int vframes_dumped; /**< Count the number of ignored frames */ - spinlock_t spinlock; /**< Spin lock */ - struct semaphore mutex; /**< Mutex */ + spinlock_t spinlock; /**< Spin lock */ + struct semaphore mutex; /**< Mutex */ wait_queue_head_t wait_frame; /**< Queue head */ @@ -384,8 +384,8 @@ struct usb_microdia { extern const struct microdia_coord microdia_image_sizes[MICRODIA_NBR_SIZES]; -int usb_microdia_control_write(struct usb_microdia *, __u16, __u16, __u8); -int usb_microdia_control_read(struct usb_microdia *, __u16, __u8 *); +int usb_microdia_control_write(struct usb_microdia *, __u16, __u16, __u8 *, __u16); +int usb_microdia_control_read(struct usb_microdia *, __u16, __u8 *, __u16); int usb_microdia_set_feature(struct usb_microdia *, int); int usb_microdia_set_configuration(struct usb_microdia *); int usb_microdia_isoc_init(struct usb_microdia *); -- 2.11.4.GIT