From c38af24ceadc7935c37043e4a0b137542762f90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 May 2008 00:25:26 +0000 Subject: [PATCH] - Finaly got sensor gain to work for mine... - added brightness and contrast parameters for sn9cxxx according to a linux driver, but doesn't seem to work for mine. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25323 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/media-add-ons/usb_webcam/README.txt | 3 + .../addons/sonix/SonixCamDevice.cpp | 62 +++++++++++++++++-- .../usb_webcam/addons/sonix/SonixCamDevice.h | 9 +++ .../usb_webcam/sensors/tas5110c1b.cpp | 23 +++++-- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/README.txt b/src/add-ons/media/media-add-ons/usb_webcam/README.txt index 50e365a344..c8d33e8b4e 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/README.txt +++ b/src/add-ons/media/media-add-ons/usb_webcam/README.txt @@ -81,10 +81,13 @@ http://www.smcc.demon.nl/webcam/ (philips) http://www.medias.ne.jp/~takam/bsd/NetBSD.html http://blognux.free.fr/sources/EasyCam2/04032006_19:49/ http://www.wifi.com.ar/english/doc/webcam/ov511cameras.html +http://mxhaard.free.fr/spca5xx.html * CMOS Sensor datasheets (rather, marketing buzz): +http://mxhaard.free.fr/spca50x/Doc/ many http://www.tascorp.com.tw/product_file/TAS5110C1B_Brief_V0.3.pdf http://www.tascorp.com.tw/product_file/TAS5130D1B_Brief_V0.3.pdf +http://www.mnementh.co.uk/sonix/hv7131e1.pdf Divio NW80x: http://www.digchip.com/datasheets/parts/datasheet/132/NW800.php http://www.digchip.com/datasheets/parts/datasheet/132/NW802.php 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 579a921e82..4fd161ad13 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 @@ -78,6 +78,8 @@ SonixCamDevice::SonixCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device) fFrameTagState = 0; fRGain = fGGain = fBGain = 0; + // unknown + fBrightness = 0.5; memset(fCachedRegs, 0, SN9C102_REG_COUNT); fChipVersion = 2; @@ -271,13 +273,16 @@ SonixCamDevice::WriteIIC(uint8 address, uint8 *data, size_t count) count++; // includes address if (count > 5) return EINVAL; - buffer[0] = (count << 4) | Sensor()->Use400kHz()?0x01:0 - | Sensor()->UseRealIIC()?0x80:0; + buffer[0] = ((count) << 4) | (Sensor()->Use400kHz()?0x01:0) + | (Sensor()->UseRealIIC()?0x80:0); buffer[1] = Sensor()->IICWriteAddress(); buffer[2] = address; memset(&buffer[3], 0, 5); - memcpy(&buffer[3], data, count); - buffer[7] = 0x14; /* absolutely no idea why V4L2 driver use that value */ + memcpy(&buffer[3], data, count-1); + buffer[7] = 0x10; /*0x14;*/ /* absolutely no idea why V4L2 driver use that value */ + for (int i = 0; i < 8; i++) { + PRINT(("[%d] = %02x\n", i, buffer[i])); + } err = WriteReg(SN9C102_I2C_SETUP, buffer, 8); //dprintf(ID "sonix_i2c_write_multi: set_regs error 0x%08lx\n", err); //PRINT((CH ": WriteReg: %s" CT, strerror(err))); @@ -403,16 +408,31 @@ SonixCamDevice::SetVideoParams(float brightness, float contrast, float hue, floa void SonixCamDevice::AddParameters(BParameterGroup *group, int32 &index) { + BParameterGroup *g; BContinuousParameter *p; CamDevice::AddParameters(group, index); - p = group->MakeContinuousParameter(index++, + // R,G,B gains + g = group->MakeGroup("RGB gain"); + p = g->MakeContinuousParameter(index++, B_MEDIA_RAW_VIDEO, "RGB gain", B_GAIN, "", 1.0, 1.0+(float)(SN9C102_RGB_GAIN_MAX)/8, (float)1.0/8); p->SetChannelCount(3); +#if 0 + // Contrast - NON FUNCTIONAL + g = group->MakeGroup("Contrast"); + p = g->MakeContinuousParameter(index++, + B_MEDIA_RAW_VIDEO, "Contrast", + B_GAIN, "", 0.0, 1.0, 1.0/256); + // Brightness - NON FUNCTIONAL + g = group->MakeGroup("Brightness"); + p = g->MakeContinuousParameter(index++, + B_MEDIA_RAW_VIDEO, "Brightness", + B_GAIN, "", 0.0, 1.0, 1.0/256); +#endif } status_t @@ -428,6 +448,20 @@ SonixCamDevice::GetParameterValue(int32 id, bigtime_t *last_change, void *value, gains[2] = 1.0 + (float)fBGain / 8; *last_change = fLastParameterChanges; return B_OK; +#if 0 + case 1: + *size = sizeof(float); + gains = ((float *)value); + gains[0] = fContrast; + *last_change = fLastParameterChanges; + return B_OK; + case 2: + *size = sizeof(float); + gains = ((float *)value); + gains[0] = fBrightness; + *last_change = fLastParameterChanges; + return B_OK; +#endif } return B_BAD_VALUE; } @@ -473,6 +507,24 @@ SonixCamDevice::SetParameterValue(int32 id, bigtime_t when, const void *value, s WriteReg(SN9C102_R_B_GAIN, buf, 2); #endif return B_OK; +#if 0 + case 1: + if (!value || (size != sizeof(float))) + return B_BAD_VALUE; + gains = ((float *)value); + fContrast = gains[0]; + WriteReg8(SN9C10x_CONTRAST, ((uint8)(fContrast * 256))); + return B_OK; + case 2: + if (!value || (size != sizeof(float))) + return B_BAD_VALUE; + gains = ((float *)value); + fBrightness = gains[0]; + // it actually ends up writing to SN9C102_V_SIZE... + WriteReg8(SN9C10x_BRIGHTNESS, ((uint8)(fBrightness * 256))); + + return B_OK; +#endif } return B_BAD_VALUE; } 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 1cdfebac2a..ab600e6e6b 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 @@ -40,6 +40,13 @@ #define SN9C102_AE_ENDX 0x1e #define SN9C102_AE_ENDY 0x1f +// extra regs ? maybe 103 or later only ? used by gspcav1 +#define SN9C10x_CONTRAST 0x84 +#define SN9C10x_BRIGHTNESS 0x96 +#undef SN9C102_REG_COUNT +#define SN9C102_REG_COUNT 0x100 + + #define SN9C102_RGB_GAIN_MAX 0x7f // This class represents each webcam @@ -95,6 +102,8 @@ class SonixCamDevice : public CamDevice uint8 fRGain; uint8 fGGain; uint8 fBGain; + float fContrast; + float fBrightness; }; // the addon itself, that instanciate diff --git a/src/add-ons/media/media-add-ons/usb_webcam/sensors/tas5110c1b.cpp b/src/add-ons/media/media-add-ons/usb_webcam/sensors/tas5110c1b.cpp index 5de809832b..c0302f1395 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/sensors/tas5110c1b.cpp +++ b/src/add-ons/media/media-add-ons/usb_webcam/sensors/tas5110c1b.cpp @@ -18,7 +18,7 @@ public: virtual bool Use400kHz() const { return false; }; virtual bool UseRealIIC() const { return false; }; virtual uint8 IICReadAddress() const { return 0x00; }; - virtual uint8 IICWriteAddress() const { return 0xff; }; + virtual uint8 IICWriteAddress() const { return 0x11; /*0xff;*/ }; virtual int MaxWidth() const { return 352; }; virtual int MaxHeight() const { return 288; }; virtual status_t SetVideoFrame(BRect rect); @@ -71,10 +71,11 @@ TAS5110C1BSensor::Setup() Device()->WriteReg8(SN9C102_PIX_CLK, 0xfb); /* pixclk = 2 * masterclk, sensor is slave mode */ } - //sonix_i2c_write_multi(dev, dev->sensor->i2c_wid, 2, 0xc0, 0x80, 0, 0, 0); /* AEC = 0x203 ??? */ - Device()->WriteIIC8(0xc0, 0x80); /* AEC = 0x203 ??? */ if (fIsSonix) { + //sonix_i2c_write_multi(dev, dev->sensor->i2c_wid, 2, 0xc0, 0x80, 0, 0, 0); /* AEC = 0x203 ??? */ + Device()->WriteIIC8(0xc0, 0x80); /* AEC = 0x203 ??? */ + // set crop Device()->WriteReg8(SN9C102_H_SIZE, 69); Device()->WriteReg8(SN9C102_V_SIZE, 9); @@ -126,6 +127,7 @@ TAS5110C1BSensor::AddParameters(BParameterGroup *group, int32 &index) CamSensor::AddParameters(group, index); #ifdef ENABLE_GAIN + // NON-FUNCTIONAL p = group->MakeContinuousParameter(index++, B_MEDIA_RAW_VIDEO, "global gain", B_GAIN, "", (float)0x00, (float)0xf6, (float)1); @@ -157,8 +159,19 @@ TAS5110C1BSensor::SetParameterValue(int32 id, bigtime_t when, const void *value, return B_OK; fGain = *(float *)value; fLastParameterChanges = when; - PRINT((CH ": gain: %f (%d)" CT, fGain, (unsigned)(0xf6-fGain))); - Device()->WriteIIC8(0x20, (uint8)0xf6 - (uint8)fGain); + PRINT((CH ": gain: %f" CT, fGain)); + + if (fIsSonix) { + // some drivers do: + //Device()->WriteIIC8(0x20, (uint8)0xf6 - (uint8)fGain); + // but it doesn't seem to work + + // works, not sure why yet, XXX check datasheet for AEG/AEC + uint8 buf[2] = { 0x20, 0x70 }; + buf[1] = (uint8)0xff - (uint8)fGain; + Device()->WriteIIC(0x02, buf, 2); + } + return B_OK; } #endif