From 5b880818a5d7b789bdd2b3a253b320b26c3dd1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 May 2008 00:32:02 +0000 Subject: [PATCH] - some code to support isochronous, not yet functional. - some code for quickcam, not yet functional. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25319 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media-add-ons/usb_webcam/CamDevice.cpp | 60 ++++++- .../media-add-ons/usb_webcam/CamDevice.h | 5 + .../media/media-add-ons/usb_webcam/Jamfile | 5 +- .../addons/quickcam/QuickCamDevice.cpp | 151 ++++++++++++++++++ .../addons/quickcam/QuickCamDevice.h | 36 ++++- .../addons/sonix/SonixCamDevice.cpp | 14 +- .../usb_webcam/addons/sonix/SonixCamDevice.h | 4 +- 7 files changed, 267 insertions(+), 8 deletions(-) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp b/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp index 39138ed6cc..958f464bfb 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp +++ b/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp @@ -413,8 +413,48 @@ CamDevice::DataPumpThread() //snooze(2000); } } - if (SupportsIsochronous()) { - ;//XXX: TODO +#ifdef SUPPORT_ISO + else if (SupportsIsochronous()) { + int numPacketDescriptors = 20; + usb_iso_packet_descriptor packetDescriptors[numPacketDescriptors]; + while (fTransferEnabled) { + ssize_t len = -1; + BAutolock lock(fLocker); + if (!lock.IsLocked()) + break; + if (!fIsoIn) + break; +#ifndef DEBUG_DISCARD_INPUT + len = fIsoIn->IsochronousTransfer(fBuffer, fBufferLen, packetDescriptors, numPacketDescriptors); +#endif + + //PRINT((CH ": got %d bytes" CT, len)); +#ifdef DEBUG_WRITE_DUMP + write(fDumpFD, fBuffer, len); +#endif +#ifdef DEBUG_READ_DUMP + if ((len = read(fDumpFD, fBuffer, fBufferLen)) < fBufferLen) + lseek(fDumpFD, 0LL, SEEK_SET); +#endif + + if (len <= 0) { + PRINT((CH ": BulkIn: %s" CT, strerror(len))); + break; + } + +#ifndef DEBUG_DISCARD_DATA + if (fDataInput) { + fDataInput->Write(fBuffer, len); + // else drop + } +#endif + //snooze(2000); + } + } +#endif + else { + PRINT((CH ": No supported transport." CT)); + return B_UNSUPPORTED; } return B_OK; } @@ -433,6 +473,22 @@ CamDevice::DumpRegs() { } +// ----------------------------------------------------------------------------- +status_t +CamDevice::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 | USB_REQTYPE_INTERFACE_OUT | dir, + request, value, index, length, data); + return ret; +} + // ----------------------------------------------------------------------------- CamDeviceAddon::CamDeviceAddon(WebCamMediaAddOn* webcam) : fWebCamAddOn(webcam), diff --git a/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.h b/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.h index 43c1300caf..abc78dbd62 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.h +++ b/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.h @@ -5,8 +5,10 @@ #include #include #ifdef __HAIKU__ +//#if 1 # include # include +# define SUPPORT_ISO #else # include # include @@ -104,6 +106,8 @@ class CamDevice { virtual void DumpRegs(); protected: + virtual status_t SendCommand(uint8 dir, uint8 request, uint16 value, + uint16 index, uint16 length, void* data); CamSensor *CreateSensor(const char *name); status_t fInitStatus; flavor_info fFlavorInfo; @@ -114,6 +118,7 @@ class CamDevice { CamDeframer* fDeframer; BDataIO* fDataInput; // where data from usb goes, likely fDeframer const BUSBEndpoint* fBulkIn; + const BUSBEndpoint* fIsoIn; int32 fFirstParameterID; bigtime_t fLastParameterChanges; diff --git a/src/add-ons/media/media-add-ons/usb_webcam/Jamfile b/src/add-ons/media/media-add-ons/usb_webcam/Jamfile index e19741d36b..14771d1f75 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/Jamfile +++ b/src/add-ons/media/media-add-ons/usb_webcam/Jamfile @@ -6,7 +6,10 @@ SetSubDirSupportedPlatformsBeOSCompatible ; if $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { usbKitLibraryName = libdevice.so ; } else { - usbKitLibraryName = usb ; +# usbKitLibraryName = usb ; + usbKitLibraryName = USBKit.a ; + UsePublicHeaders [ FDirName drivers ] ; + UsePublicHeaders [ FDirName device ] ; } # source directories diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.cpp b/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.cpp index 0327b2fd22..536d4a6c23 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.cpp +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.cpp @@ -1,4 +1,9 @@ #include "QuickCamDevice.h" +#include "CamDebug.h" +#include "CamSensor.h" + +// see http://www.lrr.in.tum.de/~acher/quickcam/quickcam.html + const usb_named_support_descriptor kSupportedDevices[] = { {{ 0, 0, 0, 0x046d, 0x0840 }, "Logitech", "QuickCam Express"}, @@ -21,6 +26,152 @@ QuickCamDevice::~QuickCamDevice() } +// ----------------------------------------------------------------------------- +bool +QuickCamDevice::SupportsBulk() +{ + return true; +} + +// ----------------------------------------------------------------------------- +bool +QuickCamDevice::SupportsIsochronous() +{ + return true; +} + +// ----------------------------------------------------------------------------- +status_t +QuickCamDevice::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 +QuickCamDevice::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 +QuickCamDevice::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 +QuickCamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached) +{ + PRINT((CH "(%u, @%p, %u, %d)" CT, address, data, count, cached)); + return SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, address, 0, count, data); +} + +// ----------------------------------------------------------------------------- +status_t +QuickCamDevice::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 +QuickCamDevice::WaitReadyIIC() +{ + status_t err; +#warning WRITEME + return EBUSY; +} + +// ----------------------------------------------------------------------------- +ssize_t +QuickCamDevice::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, data); +} + +// ----------------------------------------------------------------------------- +ssize_t +QuickCamDevice::ReadIIC(uint8 address, uint8 *data) +{ +#warning WRITEME + return 1; +} + + +// ----------------------------------------------------------------------------- +status_t +QuickCamDevice::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; +} + // ----------------------------------------------------------------------------- QuickCamDeviceAddon::QuickCamDeviceAddon(WebCamMediaAddOn* webcam) : CamDeviceAddon(webcam) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.h b/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.h index 2e9c605e10..0579c01869 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.h +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/quickcam/QuickCamDevice.h @@ -3,14 +3,48 @@ #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 QuickCamDevice : public CamDevice { public: QuickCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device); ~QuickCamDevice(); - + 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); + private: + virtual status_t SendCommand(uint8 dir, uint8 request, uint16 value, + uint16 index, uint16 length, void* data); }; // the addon itself, that instanciate diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.cpp b/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.cpp index 763cbe25e1..6cecd5d289 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.cpp +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.cpp @@ -470,12 +470,20 @@ SonixCamDevice::SetParameterValue(int32 id, bigtime_t when, const void *value, s * but it doesn't seem to work any better for a rev 2 chip. * XXX */ +#if 1 WriteReg8(SN9C102_R_GAIN, fRGain); WriteReg8(SN9C102_B_GAIN, fBGain); if (fChipVersion >= 3) WriteReg8(SN9C103_G_GAIN, fGGain); else WriteReg8(SN9C102_G_GAIN, (fGGain / 16)); +#endif +#if 0 + uint8 buf[2]; + buf[0] = (fBGain << 4) | fRGain; + buf[1] = fGGain; + WriteReg(SN9C102_R_B_GAIN, buf, 2); +#endif return B_OK; } return B_BAD_VALUE; @@ -616,21 +624,23 @@ SonixCamDevice::DumpRegs() regs[24], regs[25], regs[26], regs[27], regs[28], regs[29], regs[30], regs[31]); } +#if 0 // ----------------------------------------------------------------------------- status_t SonixCamDevice::SendCommand(uint8 dir, uint8 request, uint16 value, uint16 index, uint16 length, void* data) { size_t ret; - if (length > 64) - return EINVAL; if (!GetDevice()) return ENODEV; + if (length > GetDevice()->MaxEndpoint0PacketSize()) + return EINVAL; ret = GetDevice()->ControlTransfer( USB_REQTYPE_VENDOR | USB_REQTYPE_INTERFACE_OUT | dir, request, value, index, length, data); return ret; } +#endif // ----------------------------------------------------------------------------- SonixCamDeviceAddon::SonixCamDeviceAddon(WebCamMediaAddOn* webcam) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.h b/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.h index b80c380fdf..1cdfebac2a 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.h +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/sonix/SonixCamDevice.h @@ -85,8 +85,8 @@ class SonixCamDevice : public CamDevice void DumpRegs(); private: - status_t SendCommand(uint8 dir, uint8 request, uint16 value, - uint16 index, uint16 length, void* data); +// status_t SendCommand(uint8 dir, uint8 request, uint16 value, +// uint16 index, uint16 length, void* data); uint8 fCachedRegs[SN9C102_REG_COUNT]; int fChipVersion;