2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
6 #include "NW80xCamDevice.h"
11 // http://nw802.cvs.sourceforge.net
12 // http://nw802.cvs.sourceforge.net/nw802/nw802-2.4/
13 // http://www.medias.ne.jp/~takam/bsd/NetBSD.html#nw802
14 // https://dev.openwrt.org/attachment/ticket/2319/nw802-patch.txt
15 // win binary driver template, readme has interesting info:
16 // http://www.bulgar-bg.com/Downloads/drivers/PCAMDriver/
17 // http://www.bulgar-bg.com/Downloads/drivers/PCAMDriver/Readme.txt
19 const usb_webcam_support_descriptor kSupportedDevices
[] = {
20 {{ 0, 0, 0, 0x046d, 0xd001 }, "Logitech", "QuickCam Pro", "??" }, // Alan's
21 // other IDs according to nw802 linux driver:
22 {{ 0, 0, 0, 0x052b, 0xd001 }, "Ezonics", "EZCam Pro", "??" },
23 {{ 0, 0, 0, 0x055f, 0xd001 }, "Mustek"/*"PCLine"*/, "WCam 300"/*"PCL-W300"*/, "??" },
24 {{ 0, 0, 0, 0x06a5, 0xd001 }, "Divio", "NW802", "??" },
25 {{ 0, 0, 0, 0x06a5, 0x0000 }, "Divio", "NW800", "??" },
26 {{ 0, 0, 0, 0, 0}, NULL
, NULL
, NULL
}
32 // datasheets: (scarce)
33 // http://www.digchip.com/datasheets/parts/datasheet/132/NW800.php
34 // http://www.digchip.com/datasheets/parts/datasheet/132/NW802.php
35 // http://web.archive.org/web/*/divio.com/*
36 // http://web.archive.org/web/20020217173519/divio.com/NW802.html
39 // Sensor Model # Data Width Voltage Timing
40 // Conexant CN0352 10 bits 3.3 V Master
41 // Elecvision EVS110K 8 bits 3.3 V Slave
42 // HP (Agilent) HDC1000 10 bits 3.3 V Master
43 // Hyundai HB7121B 8 bits 3.3 V Master
44 // Pixart PAS006AC 9 bits 3.3 V Master
45 // TASC TAS5110A 9 bits 3.8 V Slave
47 // http://www.wifi.com.ar/english/doc/webcam/ov511cameras.html says:
48 // 06a5 (Divio) d800 Etoms ET31X110 (A.K.A Divio NW800)
50 NW80xCamDevice::NW80xCamDevice(CamDeviceAddon
&_addon
, BUSBDevice
* _device
)
51 :CamDevice(_addon
, _device
)
55 // linux seems to infer this sets I2C controller to 8 or 16 bit mode...
56 // sensors will set to the mode they want when probing
60 // reset I2C mode to 8 bit as linux driver does
62 // not much we can do anyway
69 NW80xCamDevice::~NW80xCamDevice()
76 NW80xCamDevice::SupportsBulk()
83 NW80xCamDevice::SupportsIsochronous()
90 NW80xCamDevice::StartTransfer()
97 SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1));
99 //SetVideoFrame(BRect(0, 0, 320-1, 240-1));
103 err
= ReadReg(SN9C102_CHIP_CTRL
, &r
, 1, true);
107 err
= WriteReg8(SN9C102_CHIP_CTRL
, r
);
111 return CamDevice::StartTransfer();
116 NW80xCamDevice::StopTransfer()
122 err
= CamDevice::StopTransfer();
126 err
= ReadReg(SN9C102_CHIP_CTRL
, &r
, 1, true);
130 err
= WriteReg8(SN9C102_CHIP_CTRL
, r
);
139 NW80xCamDevice::WriteReg(uint16 address
, uint8
*data
, size_t count
)
141 PRINT((CH
"(%u, @%p, %u)" CT
, address
, data
, count
));
142 return SendCommand(USB_REQTYPE_DEVICE_OUT
, 0x04, address
, 0, count
, data
);
147 NW80xCamDevice::ReadReg(uint16 address
, uint8
*data
, size_t count
, bool cached
)
149 PRINT((CH
"(%u, @%p, %u, %d)" CT
, address
, data
, count
, cached
));
150 memset(data
, 0xaa, count
); // linux drivers do that without explaining why !?
151 return SendCommand(USB_REQTYPE_DEVICE_IN
, 0x04, address
, 0, count
, data
);
156 NW80xCamDevice::GetStatusIIC()
158 status_t err
= B_ERROR
;
161 //dprintf(ID "i2c_status: error 0x%08lx, status = %02x\n", err, status);
164 return (status
&0x08)?EIO
:0;
169 NW80xCamDevice::WaitReadyIIC()
178 NW80xCamDevice::WriteIIC(uint8 address
, uint8
*data
, size_t count
)
185 memset(buffer
, 0, sizeof(buffer
));
186 buffer
[0x20] = Sensor() ? Sensor()->IICWriteAddress() : 0;
187 buffer
[0x21] = count
- 1;
189 for (i
= 0; i
< count
; i
++) {
190 buffer
[i
] = address
+ i
;
191 buffer
[i
+16] = data
[i
];
193 return SendCommand(USB_REQTYPE_DEVICE_OUT
, 0x04, STV_I2C_WRITE
, 0, 0x23, buffer
);
198 NW80xCamDevice::ReadIIC(uint8 address
, uint8
*data
)
200 return ReadIIC(address
, data
);
205 NW80xCamDevice::ReadIIC8(uint8 address
, uint8
*data
)
210 memset(buffer
, 0, sizeof(buffer
));
211 buffer
[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
212 buffer
[0x21] = 1 - 1;
215 err
= SendCommand(USB_REQTYPE_DEVICE_OUT
, 0x04, STV_I2C_WRITE
, 0, 0x23, buffer
);
216 PRINT((CH
": SendCommand: %s" CT
, strerror(err
)));
221 err
= SendCommand(USB_REQTYPE_DEVICE_IN
, 0x04, STV_I2C_READ
, 0, 0x1, buffer
);
222 PRINT((CH
": SendCommand: %s" CT
, strerror(err
)));
227 PRINT((CH
": 0x%02x" CT
, *data
));
233 NW80xCamDevice::ReadIIC16(uint8 address
, uint16
*data
)
238 memset(buffer
, 0, sizeof(buffer
));
239 buffer
[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
240 buffer
[0x21] = 1 - 1;
243 err
= SendCommand(USB_REQTYPE_DEVICE_OUT
, 0x04, STV_I2C_WRITE
, 0, 0x23, buffer
);
249 err
= SendCommand(USB_REQTYPE_DEVICE_IN
, 0x04, STV_I2C_READ
, 0, 0x2, buffer
);
250 PRINT((CH
": SendCommand: %s" CT
, strerror(err
)));
254 if (fChipIsBigEndian
)
255 *data
= B_HOST_TO_BENDIAN_INT16(*(uint16
*)(&buffer
[0]));
257 *data
= B_HOST_TO_LENDIAN_INT16(*(uint16
*)(&buffer
[0]));
258 PRINT((CH
": 0x%04x" CT
, *data
));
264 NW80xCamDevice::SetIICBitsMode(size_t bits
)
268 WriteReg8(STV_REG23
, 0);
271 WriteReg8(STV_REG23
, 1);
281 NW80xCamDevice::SendCommand(uint8 dir
, uint8 request
, uint16 value
,
282 uint16 index
, uint16 length
, void* data
)
287 if (length
> GetDevice()->MaxEndpoint0PacketSize())
289 ret
= GetDevice()->ControlTransfer(
290 USB_REQTYPE_VENDOR
| dir
,
291 request
, value
, index
, length
, data
);
296 NW80xCamDeviceAddon::NW80xCamDeviceAddon(WebCamMediaAddOn
* webcam
)
297 : CamDeviceAddon(webcam
)
299 SetSupportedDevices(kSupportedDevices
);
303 NW80xCamDeviceAddon::~NW80xCamDeviceAddon()
309 NW80xCamDeviceAddon::BrandName()
311 return "NW80x-based";
316 NW80xCamDeviceAddon::Instantiate(CamRoster
&roster
, BUSBDevice
*from
)
318 return new NW80xCamDevice(*this, from
);
323 B_WEBCAM_MKINTFUNC(nw80xcam
)
324 (WebCamMediaAddOn
* webcam
, CamDeviceAddon
**addon
)
326 *addon
= new NW80xCamDeviceAddon(webcam
);