Quickcam Web under Linux
A Linux driver for the Quickcam Web.
This page exists to summarize the results of my reverse engineering of
the Logitech Quickcam Web. I have my own variant quickcam-web.tar.gz of Georg's quickcam
driver which is working with my cam in both compressed and
uncompressed modes. The decompression code is included. It takes
some MMX optimized routines from libmpeg2 which are also
included. Note: You may need to choose between MMXEXT or MMX
by changing the value of vo_mm_accel
at the end of
decode-lvc.c. Set it to 0 for no MMX.
Cristiano de Michele has added the necessary patches to the qce-ga driver, to get full video4linux support. I'm not sure whether it supports compressed mode, though.
Links to other sites
Most of the remaining text is probably black magic to you. But if not, read
on :)
Components
The Logitech Quickcam Web consists of a STV0610 for USB communication and the imaging chip VV6410. The VV6410 has good public documentation, but the STV0610 seems to be kept secret.
STV0610 ASIC
The STV0610 works similar to the STV0600, but has several more registers. Here is a complete register dump taken just after plugging in the cam. Spaces mark that the registers are not giving out values. The dump was produced byqcdump
which is
included in the tar.gz package I mentioned above.
Range 0x400 - 0x600
400: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 410: 420: a2 07 06 00 00 540: 00 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 550: 00 04 560: 40 00 80 80
This seems to be some registers shadowed from 0x1xxx. They always contain the same value; changing one changes the other, too. The Logitech driver writes to these register set and writes a "1" to register 0x1704 afterwards. For explanation of the contents see the 0x1xxx area.
Range 0x1400-0x1424
1400: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1410: 1420: a2 07 06 00 00 ; I2C_ADDR, I2C_LENGTH I2C_RW, REG23, I2C_TXCOUNT
This is the I2C area. The registers 0x1400-0x140f contain the i2c register numbers, the register 0x1410-0x141f their values.
Register 0x1420 contains the address of the I2C partner, 0x1421 the number of valid register/value pairs minus 1. Register 0x1422 is 1 for write, 3 for read commands. The registers 0x1400-0x1422 are normally written in one big bunch for an I2C command.
The purpose of 0x1423 is still unknown: sometimes it is set to 4 sometimes to 5, I don't know.
The register 0x1424 gives the number of succesfully transmitted i2c register values.
When reading two I2C register the results are written to 0x1410 and 0x1412, instead of 0x1410-0x1411. Don't know why.
Range 0x1440-0x1424
1440: 00 00 12 00 00 00 ; ISO_ENABLE, ?,?, SCAN_RATE, ?, LED
0x1440 | turn ISO stream (image data stream) on(1) or off(0) |
0x1443 | SCAN_RATE (?) |
0x1445 | turn LED on(1) or off(0) |
Range 0x1500-0x15ff
1500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1520: 00 00 00 00 00 00 00 00 00 00 00 1530: 00 00 00 00 00 00 00 00 00 00 00 00 1540: 00 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 1550: 00 04 00 00 00 00 00 00 00 1560: 40 00 80 80 00 ff 0a 01 00 00 00 00 1580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15a0: 00 00 00 00 00 00 00 15c0: 00 ff 03 00 84 00 00 00 0f 00
0x1580 - 0x15a6 | Various compression quality parameters? |
According to Georg Acher: | |
0x15c1/0x15c2 | Max. ISO packet size L/H |
0x15c3 | Y-Control, 1: 288 lines, 2: 144 lines |
0x1680?? | X-Control, 0xa: 352 columns, 6: 176 columns |
Range 0x1600-0x16ff
1600: 41 3f 00 00 00 00 00 00 00 3f 2a 7f 0a 00 01 02 1610: 00 00 00 c9 00 00 40 1f 00 40 1f 00 80 bb 00 1620: 00 00 00 1630: 00 01
I don't know anything about these registers.
Registers 1701, 1704, b000
1 4 1700: 00 00
0x1704 is written when a 0x400-0x5ff register is accessed.
b000: 00
????
Registers 0xe000-0xefff
e000: 12 01 00 01 ff ff ff 08 6d 04 50 08 00 01 00 01 e010: 00 01 09 02 b6 00 03 01 00 80 32 09 04 00 00 02 e020: ff ff ff 00 07 05 81 01 00 00 01 07 05 82 03 01 e030: 00 10 09 04 00 01 02 ff ff ff 00 07 05 81 01 ff e040: 03 01 07 05 82 03 01 00 10 09 04 01 00 00 01 01 e050: 00 00 09 24 01 00 01 27 00 01 02 0c 24 02 01 01 e060: 02 00 01 00 00 00 00 09 24 06 02 01 02 43 00 00 e070: 09 24 03 03 01 01 00 02 00 09 04 02 00 01 01 02 e080: 00 00 09 05 83 01 00 00 01 00 00 09 04 02 01 01 e090: 01 02 00 00 07 24 01 03 01 01 00 1d 24 02 01 01 e0a0: 02 10 07 40 1f 00 11 28 00 80 3e 00 22 56 00 00 e0b0: 7d 00 44 ac 00 80 bb 00 09 05 83 01 64 00 01 00 e0c0: 00 07 25 01 01 00 00 00 04 03 09 04 0e 03 43 00 ......C. e0d0: 61 00 6d 00 65 00 72 00 61 00 00 00 00 00 00 00 a.m.e.r. a. e0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .... e1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Registers 0xe000-0xe0c8 is the USB info block. This contains the same as /proc/bus/usb/001/*. This 512 bytes repeats over and over up to 0xefff. I haven't tested whether you can write to this space.
Registers 0xf000-0xffff
f000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .... fff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
As you can see they are completely zero. They aren't accessed by the Logitech driver.