- 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
This commit is contained in:
François Revol 2008-05-06 00:25:26 +00:00
parent 39cd0cea4f
commit c38af24cea
4 changed files with 87 additions and 10 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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