Turns out my QuickCam is not a usual quickcam with an WTV600 chip but an NW80x based one...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25321 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -359,6 +359,28 @@ CamDevice::WriteIIC16(uint8 address, uint16 data)
|
|||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
CamDevice::ReadIIC(uint8 address, uint8 *data)
|
CamDevice::ReadIIC(uint8 address, uint8 *data)
|
||||||
|
{
|
||||||
|
//TODO: make it mode generic
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
CamDevice::ReadIIC8(uint8 address, uint8 *data)
|
||||||
|
{
|
||||||
|
return ReadIIC(address, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
CamDevice::ReadIIC16(uint8 address, uint16 *data)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CamDevice::SetIICBitsMode(size_t bits)
|
||||||
{
|
{
|
||||||
return ENOSYS;
|
return ENOSYS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ class CamDevice {
|
|||||||
virtual ssize_t WriteIIC8(uint8 address, uint8 data);
|
virtual ssize_t WriteIIC8(uint8 address, uint8 data);
|
||||||
virtual ssize_t WriteIIC16(uint8 address, uint16 data);
|
virtual ssize_t WriteIIC16(uint8 address, uint16 data);
|
||||||
virtual ssize_t ReadIIC(uint8 address, uint8 *data);
|
virtual ssize_t ReadIIC(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC8(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC16(uint8 address, uint16 *data);
|
||||||
|
virtual status_t SetIICBitsMode(size_t bits=8);
|
||||||
|
|
||||||
|
|
||||||
void SetDataInput(BDataIO *input);
|
void SetDataInput(BDataIO *input);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class CamSensor
|
|||||||
virtual bool Use400kHz() const { return false; };
|
virtual bool Use400kHz() const { return false; };
|
||||||
virtual bool UseRealIIC() const { return true; };
|
virtual bool UseRealIIC() const { return true; };
|
||||||
virtual uint8 IICReadAddress() const { return 0; };
|
virtual uint8 IICReadAddress() const { return 0; };
|
||||||
virtual uint8 IICWriteAddress() const { return 0; };;
|
virtual uint8 IICWriteAddress() const { return 0; };
|
||||||
virtual int MaxWidth() const { return -1; };
|
virtual int MaxWidth() const { return -1; };
|
||||||
virtual int MaxHeight() const { return -1; };
|
virtual int MaxHeight() const { return -1; };
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ if $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
local sourceDirs =
|
local sourceDirs =
|
||||||
addons/quickcam
|
addons/quickcam
|
||||||
addons/sonix
|
addons/sonix
|
||||||
|
addons
|
||||||
cstransforms
|
cstransforms
|
||||||
sensors
|
sensors
|
||||||
;
|
;
|
||||||
@@ -28,7 +29,7 @@ for sourceDir in $(sourceDirs) {
|
|||||||
|
|
||||||
## addon sources
|
## addon sources
|
||||||
local addonSources ;
|
local addonSources ;
|
||||||
addonSources = QuickCamDevice.cpp SonixCamDevice.cpp ;
|
addonSources = QuickCamDevice.cpp SonixCamDevice.cpp NW80xCamDevice.cpp ;
|
||||||
|
|
||||||
## colorspace transforms sources
|
## colorspace transforms sources
|
||||||
local csTransformsSources ;
|
local csTransformsSources ;
|
||||||
|
|||||||
@@ -64,11 +64,13 @@ http://www.mnementh.co.uk/sonix/sn9c102.pdf
|
|||||||
* some of the (many!) linux quickcam drivers:
|
* some of the (many!) linux quickcam drivers:
|
||||||
http://www.lrr.in.tum.de/~acher/quickcam/quickcam.html
|
http://www.lrr.in.tum.de/~acher/quickcam/quickcam.html
|
||||||
http://www.seismo.ethz.ch/linux/webcam.html
|
http://www.seismo.ethz.ch/linux/webcam.html
|
||||||
|
http://tuukkat.awardspace.com/quickcam/quickcam.html for PID 0xd001
|
||||||
|
|
||||||
* Creative's own list of linux drivers:
|
* Creative's own list of linux drivers:
|
||||||
http://connect.creativelabs.com/opensource/Lists/Webcam%20Support/AllItems.aspx
|
http://connect.creativelabs.com/opensource/Lists/Webcam%20Support/AllItems.aspx
|
||||||
|
|
||||||
* Other webcam drivers:
|
* Other webcam drivers:
|
||||||
|
http://nw802.cvs.sourceforge.net NW80x based (like the QuickCam I have here)
|
||||||
http://zc0302.sourceforge.net/zc0302.php?page=cams
|
http://zc0302.sourceforge.net/zc0302.php?page=cams
|
||||||
http://www.medias.ne.jp/~takam/bsd/NetBSD.html
|
http://www.medias.ne.jp/~takam/bsd/NetBSD.html
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,298 @@
|
|||||||
|
#include "NW80xCamDevice.h"
|
||||||
|
#include "CamDebug.h"
|
||||||
|
#include "CamSensor.h"
|
||||||
|
|
||||||
|
// reference: http://nw802.cvs.sourceforge.net
|
||||||
|
|
||||||
|
const usb_webcam_support_descriptor kSupportedDevices[] = {
|
||||||
|
{{ 0, 0, 0, 0x046d, 0xd001 }, "Logitech", "QuickCam Pro", "??" }, // Alan's
|
||||||
|
// other IDs according to nw802 linux driver:
|
||||||
|
{{ 0, 0, 0, 0x052b, 0xd001 }, "Ezonics", "EZCam Pro", "??" },
|
||||||
|
{{ 0, 0, 0, 0x055f, 0xd001 }, "Mustek"/*"PCLine"*/, "WCam 300"/*"PCL-W300"*/, "??" },
|
||||||
|
{{ 0, 0, 0, 0x06a5, 0xd001 }, "Generic", "NW802", "??" },
|
||||||
|
{{ 0, 0, 0, 0x06a5, 0x0000 }, "Generic", "NW800", "??" },
|
||||||
|
{{ 0, 0, 0, 0, 0}, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#warning TODO!
|
||||||
|
|
||||||
|
NW80xCamDevice::NW80xCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
|
||||||
|
:CamDevice(_addon, _device)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
// linux seems to infer this sets I2C controller to 8 or 16 bit mode...
|
||||||
|
// sensors will set to the mode they want when probing
|
||||||
|
SetIICBitsMode(8);
|
||||||
|
err = ProbeSensor();
|
||||||
|
if (err < B_OK) {
|
||||||
|
// reset I2C mode to 8 bit as linux driver does
|
||||||
|
SetIICBitsMode(8);
|
||||||
|
// not much we can do anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
fInitStatus = B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NW80xCamDevice::~NW80xCamDevice()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
NW80xCamDevice::SupportsBulk()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
NW80xCamDevice::SupportsIsochronous()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::StartTransfer()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
uint8 r;
|
||||||
|
|
||||||
|
SetScale(1);
|
||||||
|
if (Sensor())
|
||||||
|
SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1));
|
||||||
|
|
||||||
|
//SetVideoFrame(BRect(0, 0, 320-1, 240-1));
|
||||||
|
|
||||||
|
DumpRegs();
|
||||||
|
#if 0
|
||||||
|
err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
r |= 0x04;
|
||||||
|
err = WriteReg8(SN9C102_CHIP_CTRL, r);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
return CamDevice::StartTransfer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::StopTransfer()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
uint8 r;
|
||||||
|
|
||||||
|
DumpRegs();
|
||||||
|
err = CamDevice::StopTransfer();
|
||||||
|
#if 0
|
||||||
|
// if (err < 0)
|
||||||
|
// return err;
|
||||||
|
err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
r &= ~0x04;
|
||||||
|
err = WriteReg8(SN9C102_CHIP_CTRL, r);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::WriteReg(uint16 address, uint8 *data, size_t count)
|
||||||
|
{
|
||||||
|
PRINT((CH "(%u, @%p, %u)" CT, address, data, count));
|
||||||
|
return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, address, 0, count, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached)
|
||||||
|
{
|
||||||
|
PRINT((CH "(%u, @%p, %u, %d)" CT, address, data, count, cached));
|
||||||
|
memset(data, 0xaa, count); // linux drivers do that without explaining why !?
|
||||||
|
return SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, address, 0, count, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::GetStatusIIC()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
uint8 status = 0;
|
||||||
|
#warning WRITEME
|
||||||
|
//dprintf(ID "i2c_status: error 0x%08lx, status = %02x\n", err, status);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return (status&0x08)?EIO:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::WaitReadyIIC()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
#warning WRITEME
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::WriteIIC(uint8 address, uint8 *data, size_t count)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
int i;
|
||||||
|
uint8 buffer[0x23];
|
||||||
|
if (count > 16)
|
||||||
|
return EINVAL;
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
buffer[0x20] = Sensor() ? Sensor()->IICWriteAddress() : 0;
|
||||||
|
buffer[0x21] = count - 1;
|
||||||
|
buffer[0x22] = 0x01;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
buffer[i] = address + i;
|
||||||
|
buffer[i+16] = data[i];
|
||||||
|
}
|
||||||
|
return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::ReadIIC(uint8 address, uint8 *data)
|
||||||
|
{
|
||||||
|
return ReadIIC(address, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::ReadIIC8(uint8 address, uint8 *data)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
int i;
|
||||||
|
uint8 buffer[0x23];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
|
||||||
|
buffer[0x21] = 1 - 1;
|
||||||
|
buffer[0x22] = 0x03;
|
||||||
|
buffer[0] = address;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
buffer[0] = 0xaa;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x1, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*data = buffer[0];
|
||||||
|
PRINT((CH ": 0x%02x" CT, *data));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
NW80xCamDevice::ReadIIC16(uint8 address, uint16 *data)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
int i;
|
||||||
|
uint8 buffer[0x23];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
|
||||||
|
buffer[0x21] = 1 - 1;
|
||||||
|
buffer[0x22] = 0x03;
|
||||||
|
buffer[0] = address;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
buffer[0] = 0xaa;
|
||||||
|
buffer[1] = 0xaa;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x2, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (fChipIsBigEndian)
|
||||||
|
*data = B_HOST_TO_BENDIAN_INT16(*(uint16 *)(&buffer[0]));
|
||||||
|
else
|
||||||
|
*data = B_HOST_TO_LENDIAN_INT16(*(uint16 *)(&buffer[0]));
|
||||||
|
PRINT((CH ": 0x%04x" CT, *data));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::SetIICBitsMode(size_t bits)
|
||||||
|
{
|
||||||
|
switch (bits) {
|
||||||
|
case 8:
|
||||||
|
WriteReg8(STV_REG23, 0);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
WriteReg8(STV_REG23, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NW80xCamDevice::SendCommand(uint8 dir, uint8 request, uint16 value,
|
||||||
|
uint16 index, uint16 length, void* data)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
if (!GetDevice())
|
||||||
|
return ENODEV;
|
||||||
|
if (length > GetDevice()->MaxEndpoint0PacketSize())
|
||||||
|
return EINVAL;
|
||||||
|
ret = GetDevice()->ControlTransfer(
|
||||||
|
USB_REQTYPE_VENDOR | dir,
|
||||||
|
request, value, index, length, data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NW80xCamDeviceAddon::NW80xCamDeviceAddon(WebCamMediaAddOn* webcam)
|
||||||
|
: CamDeviceAddon(webcam)
|
||||||
|
{
|
||||||
|
SetSupportedDevices(kSupportedDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NW80xCamDeviceAddon::~NW80xCamDeviceAddon()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
NW80xCamDeviceAddon::BrandName()
|
||||||
|
{
|
||||||
|
return "NW80x-based";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NW80xCamDevice *
|
||||||
|
NW80xCamDeviceAddon::Instantiate(CamRoster &roster, BUSBDevice *from)
|
||||||
|
{
|
||||||
|
return new NW80xCamDevice(*this, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" status_t
|
||||||
|
B_WEBCAM_MKINTFUNC(nw80xcam)
|
||||||
|
(WebCamMediaAddOn* webcam, CamDeviceAddon **addon)
|
||||||
|
{
|
||||||
|
*addon = new NW80xCamDeviceAddon(webcam);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef _NW80X_CAM_DEVICE_H
|
||||||
|
#define _NW80X_CAM_DEVICE_H
|
||||||
|
|
||||||
|
#include "CamDevice.h"
|
||||||
|
|
||||||
|
#define STV_REG_COUNT 0x0c
|
||||||
|
// Control registers of the STV0600 ASIC
|
||||||
|
#define STV_I2C_WRITE 0x400
|
||||||
|
#define STV_I2C_WRITE1 0x400
|
||||||
|
#define STV_I2C_READ 0x1410
|
||||||
|
#define STV_ISO_ENABLE 0x1440
|
||||||
|
#define STV_SCAN_RATE 0x1443
|
||||||
|
#define STV_ISO_SIZE 0x15c1
|
||||||
|
#define STV_Y_CTRL 0x15c3
|
||||||
|
#define STV_X_CTRL 0x1680
|
||||||
|
#define STV_REG00 0x1500
|
||||||
|
#define STV_REG01 0x1501
|
||||||
|
#define STV_REG02 0x1502
|
||||||
|
#define STV_REG03 0x1503
|
||||||
|
#define STV_REG04 0x1504
|
||||||
|
#define STV_REG23 0x0423
|
||||||
|
|
||||||
|
|
||||||
|
// This class represents each webcam
|
||||||
|
class NW80xCamDevice : public CamDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NW80xCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device);
|
||||||
|
~NW80xCamDevice();
|
||||||
|
virtual bool SupportsBulk();
|
||||||
|
virtual bool SupportsIsochronous();
|
||||||
|
virtual status_t StartTransfer();
|
||||||
|
virtual status_t StopTransfer();
|
||||||
|
|
||||||
|
// generic register-like access
|
||||||
|
virtual ssize_t WriteReg(uint16 address, uint8 *data, size_t count=1);
|
||||||
|
virtual ssize_t ReadReg(uint16 address, uint8 *data, size_t count=1, bool cached=false);
|
||||||
|
|
||||||
|
// I2C-like access
|
||||||
|
virtual status_t GetStatusIIC();
|
||||||
|
virtual status_t WaitReadyIIC();
|
||||||
|
virtual ssize_t WriteIIC(uint8 address, uint8 *data, size_t count=1);
|
||||||
|
virtual ssize_t ReadIIC(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC8(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC16(uint8 address, uint16 *data);
|
||||||
|
virtual status_t SetIICBitsMode(size_t bits=8);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual status_t SendCommand(uint8 dir, uint8 request, uint16 value,
|
||||||
|
uint16 index, uint16 length, void* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// the addon itself, that instanciate
|
||||||
|
|
||||||
|
class NW80xCamDeviceAddon : public CamDeviceAddon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NW80xCamDeviceAddon(WebCamMediaAddOn* webcam);
|
||||||
|
virtual ~NW80xCamDeviceAddon();
|
||||||
|
|
||||||
|
virtual const char *BrandName();
|
||||||
|
virtual NW80xCamDevice *Instantiate(CamRoster &roster, BUSBDevice *from);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _NW80X_CAM_CAM_DEVICE_H */
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
const usb_webcam_support_descriptor kSupportedDevices[] = {
|
const usb_webcam_support_descriptor kSupportedDevices[] = {
|
||||||
{{ 0, 0, 0, 0x046d, 0x0840 }, "Logitech", "QuickCam Express", NULL },
|
{{ 0, 0, 0, 0x046d, 0x0840 }, "Logitech", "QuickCam Express", NULL },
|
||||||
{{ 0, 0, 0, 0x046d, 0x0850 }, "Logitech", "QuickCam Express LEGO", NULL },
|
{{ 0, 0, 0, 0x046d, 0x0850 }, "Logitech", "QuickCam Express LEGO", NULL },
|
||||||
{{ 0, 0, 0, 0x046d, 0xd001 }, "Logitech", "QuickCam Express", NULL }, // Alan's
|
|
||||||
{{ 0, 0, 0, 0, 0}, NULL, NULL, NULL }
|
{{ 0, 0, 0, 0, 0}, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,6 +14,18 @@ const usb_webcam_support_descriptor kSupportedDevices[] = {
|
|||||||
QuickCamDevice::QuickCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
|
QuickCamDevice::QuickCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
|
||||||
:CamDevice(_addon, _device)
|
:CamDevice(_addon, _device)
|
||||||
{
|
{
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
// linux seems to infer this sets I2C controller to 8 or 16 bit mode...
|
||||||
|
// sensors will set to the mode they want when probing
|
||||||
|
SetIICBitsMode(8);
|
||||||
|
err = ProbeSensor();
|
||||||
|
if (err < B_OK) {
|
||||||
|
// reset I2C mode to 8 bit as linux driver does
|
||||||
|
SetIICBitsMode(8);
|
||||||
|
// not much we can do anyway
|
||||||
|
}
|
||||||
|
|
||||||
fInitStatus = B_OK;
|
fInitStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +111,7 @@ ssize_t
|
|||||||
QuickCamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached)
|
QuickCamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached)
|
||||||
{
|
{
|
||||||
PRINT((CH "(%u, @%p, %u, %d)" CT, address, data, count, cached));
|
PRINT((CH "(%u, @%p, %u, %d)" CT, address, data, count, cached));
|
||||||
|
memset(data, 0xaa, count); // linux drivers do that without explaining why !?
|
||||||
return SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, address, 0, count, data);
|
return SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, address, 0, count, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,18 +154,92 @@ QuickCamDevice::WriteIIC(uint8 address, uint8 *data, size_t count)
|
|||||||
buffer[i] = address + i;
|
buffer[i] = address + i;
|
||||||
buffer[i+16] = data[i];
|
buffer[i+16] = data[i];
|
||||||
}
|
}
|
||||||
return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, data);
|
return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
QuickCamDevice::ReadIIC(uint8 address, uint8 *data)
|
QuickCamDevice::ReadIIC(uint8 address, uint8 *data)
|
||||||
{
|
{
|
||||||
#warning WRITEME
|
return ReadIIC(address, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
QuickCamDevice::ReadIIC8(uint8 address, uint8 *data)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
int i;
|
||||||
|
uint8 buffer[0x23];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
|
||||||
|
buffer[0x21] = 1 - 1;
|
||||||
|
buffer[0x22] = 0x03;
|
||||||
|
buffer[0] = address;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
buffer[0] = 0xaa;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x1, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*data = buffer[0];
|
||||||
|
PRINT((CH ": 0x%02x" CT, *data));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
QuickCamDevice::ReadIIC16(uint8 address, uint16 *data)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
int i;
|
||||||
|
uint8 buffer[0x23];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
|
||||||
|
buffer[0x21] = 1 - 1;
|
||||||
|
buffer[0x22] = 0x03;
|
||||||
|
buffer[0] = address;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
buffer[0] = 0xaa;
|
||||||
|
buffer[1] = 0xaa;
|
||||||
|
err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x2, buffer);
|
||||||
|
PRINT((CH ": SendCommand: %s" CT, strerror(err)));
|
||||||
|
if (err < B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (fChipIsBigEndian)
|
||||||
|
*data = B_HOST_TO_BENDIAN_INT16(*(uint16 *)(&buffer[0]));
|
||||||
|
else
|
||||||
|
*data = B_HOST_TO_LENDIAN_INT16(*(uint16 *)(&buffer[0]));
|
||||||
|
PRINT((CH ": 0x%04x" CT, *data));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
QuickCamDevice::SetIICBitsMode(size_t bits)
|
||||||
|
{
|
||||||
|
switch (bits) {
|
||||||
|
case 8:
|
||||||
|
WriteReg8(STV_REG23, 0);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
WriteReg8(STV_REG23, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
QuickCamDevice::SendCommand(uint8 dir, uint8 request, uint16 value,
|
QuickCamDevice::SendCommand(uint8 dir, uint8 request, uint16 value,
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ class QuickCamDevice : public CamDevice
|
|||||||
virtual status_t WaitReadyIIC();
|
virtual status_t WaitReadyIIC();
|
||||||
virtual ssize_t WriteIIC(uint8 address, uint8 *data, size_t count=1);
|
virtual ssize_t WriteIIC(uint8 address, uint8 *data, size_t count=1);
|
||||||
virtual ssize_t ReadIIC(uint8 address, uint8 *data);
|
virtual ssize_t ReadIIC(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC8(uint8 address, uint8 *data);
|
||||||
|
virtual ssize_t ReadIIC16(uint8 address, uint16 *data);
|
||||||
|
virtual status_t SetIICBitsMode(size_t bits=8);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual status_t SendCommand(uint8 dir, uint8 request, uint16 value,
|
virtual status_t SendCommand(uint8 dir, uint8 request, uint16 value,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <media/Buffer.h>
|
#include <media/Buffer.h>
|
||||||
|
|
||||||
const usb_webcam_support_descriptor kSupportedDevices[] = {
|
const usb_webcam_support_descriptor kSupportedDevices[] = {
|
||||||
{{ 0, 0, 0, 0x0c45, 0x6005 }, "Sonix", "Sonix", "foo,bar,tas5110c1b" }, // mine
|
{{ 0, 0, 0, 0x0c45, 0x6005 }, "Sonix", "Sonix", "tas5110c1b" }, // mine
|
||||||
{{ 0, 0, 0, 0x0c45, 0x6009 }, "Trust", "spacec@m 120", NULL },
|
{{ 0, 0, 0, 0x0c45, 0x6009 }, "Trust", "spacec@m 120", NULL },
|
||||||
{{ 0, 0, 0, 0x0c45, 0x600d }, "Trust", "spacec@m 120", NULL },
|
{{ 0, 0, 0, 0x0c45, 0x600d }, "Trust", "spacec@m 120", NULL },
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ TYPE := ADDON
|
|||||||
# in folder names do not work well with this makefile.
|
# in folder names do not work well with this makefile.
|
||||||
SRCS := $(wildcard *.cpp) \
|
SRCS := $(wildcard *.cpp) \
|
||||||
$(wildcard addons/*/*.cpp) \
|
$(wildcard addons/*/*.cpp) \
|
||||||
|
$(wildcard addons/*.cpp) \
|
||||||
$(wildcard sensors/*.cpp) \
|
$(wildcard sensors/*.cpp) \
|
||||||
$(wildcard cstransforms/*.cpp)
|
$(wildcard cstransforms/*.cpp)
|
||||||
|
|
||||||
@@ -193,8 +194,8 @@ CamRoster.cpp: CamInternalAddons.h
|
|||||||
CamDevice.cpp: CamInternalSensors.h
|
CamDevice.cpp: CamInternalSensors.h
|
||||||
CamColorSpaceTransform.cpp: CamInternalColorSpaceTransforms.h
|
CamColorSpaceTransform.cpp: CamInternalColorSpaceTransforms.h
|
||||||
|
|
||||||
CamInternalAddons.h: $(wildcard addons/*/*CamDevice.cpp)
|
CamInternalAddons.h: $(wildcard addons/*/*CamDevice.cpp) $(wildcard addons/*CamDevice.cpp)
|
||||||
grep -h B_WEBCAM_MKINTFUNC $(CURDIR)/addons/*/*CamDevice.cpp > $@
|
grep -h B_WEBCAM_MKINTFUNC $(CURDIR)/addons/*/*CamDevice.cpp $(CURDIR)/addons/*CamDevice.cpp > $@
|
||||||
|
|
||||||
CamInternalSensors.h: $(wildcard sensors/*.cpp)
|
CamInternalSensors.h: $(wildcard sensors/*.cpp)
|
||||||
grep -h B_WEBCAM_DECLARE_SENSOR $(CURDIR)/sensors/*.cpp > $@
|
grep -h B_WEBCAM_DECLARE_SENSOR $(CURDIR)/sensors/*.cpp > $@
|
||||||
|
|||||||
@@ -2,25 +2,53 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CamSensor.h"
|
#include "CamSensor.h"
|
||||||
|
#include "CamDebug.h"
|
||||||
|
|
||||||
|
#define HDCS_ADDR_QC 0xaa
|
||||||
|
|
||||||
|
#define HDCS_IDENT 0x00
|
||||||
|
|
||||||
class HDCS1000Sensor : public CamSensor {
|
class HDCS1000Sensor : public CamSensor {
|
||||||
public:
|
public:
|
||||||
HDCS1000Sensor(CamDevice *_camera);
|
HDCS1000Sensor(CamDevice *_camera);
|
||||||
~HDCS1000Sensor();
|
~HDCS1000Sensor();
|
||||||
|
|
||||||
|
virtual status_t Probe();
|
||||||
|
|
||||||
|
virtual uint8 IICReadAddress() const { return HDCS_ADDR_QC; };
|
||||||
|
virtual uint8 IICWriteAddress() const { return HDCS_ADDR_QC; };
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
HDCS1000Sensor::HDCS1000Sensor(CamDevice *_camera)
|
HDCS1000Sensor::HDCS1000Sensor(CamDevice *_camera)
|
||||||
: CamSensor(_camera)
|
: CamSensor(_camera)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
HDCS1000Sensor::~HDCS1000Sensor()
|
HDCS1000Sensor::~HDCS1000Sensor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
status_t
|
||||||
|
HDCS1000Sensor::Probe()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
uint8 data;
|
||||||
|
PRINT((CH "()" CT));
|
||||||
|
Device()->SetIICBitsMode(8);
|
||||||
|
// QuickCam only ?
|
||||||
|
err = Device()->ReadIIC8(HDCS_IDENT+1, &data);
|
||||||
|
if (err < B_OK)
|
||||||
|
return ENODEV;
|
||||||
|
if (data == 8) {
|
||||||
|
PRINT((CH ": found %s sensor!" CT, Name()));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
B_WEBCAM_DECLARE_SENSOR(HDCS1000Sensor, hdcs1000)
|
B_WEBCAM_DECLARE_SENSOR(HDCS1000Sensor, hdcs1000)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CamSensor.h"
|
||||||
|
#include "CamDebug.h"
|
||||||
|
|
||||||
|
#define PB_ADDR_QC 0xba
|
||||||
|
|
||||||
|
#define PB_IDENT 0x00
|
||||||
|
|
||||||
|
|
||||||
|
class PB0100Sensor : public CamSensor {
|
||||||
|
public:
|
||||||
|
PB0100Sensor(CamDevice *_camera);
|
||||||
|
~PB0100Sensor();
|
||||||
|
virtual status_t Probe();
|
||||||
|
|
||||||
|
virtual uint8 IICReadAddress() const { return PB_ADDR_QC; };
|
||||||
|
virtual uint8 IICWriteAddress() const { return PB_ADDR_QC; };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PB0100Sensor::PB0100Sensor(CamDevice *_camera)
|
||||||
|
: CamSensor(_camera)
|
||||||
|
{
|
||||||
|
Device()->SetIICBitsMode(16);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PB0100Sensor::~PB0100Sensor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PB0100Sensor::Probe()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
uint16 data;
|
||||||
|
PRINT((CH "()" CT));
|
||||||
|
Device()->SetIICBitsMode(16);
|
||||||
|
// QuickCam only ?
|
||||||
|
err = Device()->ReadIIC16(PB_IDENT, &data);
|
||||||
|
if (err < B_OK)
|
||||||
|
return ENODEV;
|
||||||
|
if (data == 0x64) {
|
||||||
|
PRINT((CH ": found %s sensor!" CT, Name()));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
B_WEBCAM_DECLARE_SENSOR(PB0100Sensor, pb0100)
|
||||||
|
|
||||||
Reference in New Issue
Block a user