- don't hardcode frame size, use the maximum available instead. Setting it at connection won't work yet.

- Added hooks to handle device and sensor-specific parameters
- Added gain controls for my webcam, oddly none seem to work correctly except green gain :^)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25315 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2008-05-04 20:14:19 +00:00
parent c5174c0a7e
commit a486abdce0
10 changed files with 269 additions and 19 deletions

View File

@ -30,6 +30,7 @@ struct { const char *name; SensorInstFunc instfunc; } kSensorTable[] = {
CamDevice::CamDevice(CamDeviceAddon &_addon, BUSBDevice* _device) CamDevice::CamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
: fInitStatus(B_NO_INIT), : fInitStatus(B_NO_INIT),
fSensor(NULL), fSensor(NULL),
fLastParameterChanges(0),
fCamDeviceAddon(_addon), fCamDeviceAddon(_addon),
fDevice(_device), fDevice(_device),
fSupportedDeviceIndex(-1), fSupportedDeviceIndex(-1),
@ -203,6 +204,26 @@ CamDevice::SetVideoParams(float brightness, float contrast, float hue, float red
return B_OK; return B_OK;
} }
// -----------------------------------------------------------------------------
void
CamDevice::AddParameters(BParameterGroup *group, int32 &index)
{
fFirstParameterID = index;
}
status_t
CamDevice::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size)
{
return B_BAD_VALUE;
}
status_t
CamDevice::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size)
{
return B_BAD_VALUE;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
size_t size_t
CamDevice::MinRawFrameSize() CamDevice::MinRawFrameSize()

View File

@ -19,6 +19,7 @@
class BBitmap; class BBitmap;
class BBuffer; class BBuffer;
class BDataIO; class BDataIO;
class BParameterGroup;
class CamRoster; class CamRoster;
class CamDeviceAddon; class CamDeviceAddon;
class CamSensor; class CamSensor;
@ -58,6 +59,11 @@ class CamDevice {
virtual status_t SetScale(float scale); virtual status_t SetScale(float scale);
virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue); virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue);
virtual void AddParameters(BParameterGroup *group, int32 &index);
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size);
virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size);
// for use by deframer // for use by deframer
virtual size_t MinRawFrameSize(); virtual size_t MinRawFrameSize();
virtual size_t MaxRawFrameSize(); virtual size_t MaxRawFrameSize();
@ -108,8 +114,10 @@ class CamDevice {
CamDeframer* fDeframer; CamDeframer* fDeframer;
BDataIO* fDataInput; // where data from usb goes, likely fDeframer BDataIO* fDataInput; // where data from usb goes, likely fDeframer
const BUSBEndpoint* fBulkIn; const BUSBEndpoint* fBulkIn;
int32 fFirstParameterID;
bigtime_t fLastParameterChanges;
private: protected:
friend class CamDeviceAddon; friend class CamDeviceAddon;
CamDeviceAddon& fCamDeviceAddon; CamDeviceAddon& fCamDeviceAddon;
BUSBDevice* fDevice; BUSBDevice* fDevice;

View File

@ -6,6 +6,7 @@ CamSensor::CamSensor(CamDevice *_camera)
: fInitStatus(B_NO_INIT), : fInitStatus(B_NO_INIT),
fTransferEnabled(false), fTransferEnabled(false),
fVideoFrame(), fVideoFrame(),
fLastParameterChanges(0),
fCamDevice(_camera) fCamDevice(_camera)
{ {
@ -68,6 +69,25 @@ CamSensor::SetVideoParams(float brightness, float contrast, float hue, float red
return ENOSYS; return ENOSYS;
} }
// -----------------------------------------------------------------------------
void
CamSensor::AddParameters(BParameterGroup *group, int32 &index)
{
fFirstParameterID = index;
}
status_t
CamSensor::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size)
{
return B_BAD_VALUE;
}
status_t
CamSensor::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size)
{
return B_BAD_VALUE;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
CamDevice * CamDevice *
CamSensor::Device() CamSensor::Device()

View File

@ -32,6 +32,10 @@ class CamSensor
virtual status_t SetVideoFrame(BRect rect); virtual status_t SetVideoFrame(BRect rect);
virtual BRect VideoFrame() const { return fVideoFrame; }; virtual BRect VideoFrame() const { return fVideoFrame; };
virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue); virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue);
virtual void AddParameters(BParameterGroup *group, int32 &index);
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size);
virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size);
CamDevice *Device(); CamDevice *Device();
@ -50,6 +54,8 @@ class CamSensor
status_t fInitStatus; status_t fInitStatus;
bool fTransferEnabled; bool fTransferEnabled;
BRect fVideoFrame; BRect fVideoFrame;
int32 fFirstParameterID;
bigtime_t fLastParameterChanges;
private: private:
CamDevice *fCamDevice; CamDevice *fCamDevice;
}; };

View File

@ -34,7 +34,7 @@ CamStreamingDeframer::Write(const void *buffer, size_t size)
int bufsize = size; int bufsize = size;
bool detach = false; bool detach = false;
bool discard = false; bool discard = false;
PRINT((CH "(%p, %d); state=%s framesz=%u queued=%u" CT, buffer, size, (fState==ST_SYNC)?"sync":"frame", (size_t)(fCurrentFrame?(fCurrentFrame->Position()):-1), (size_t)fInputBuff.Position())); //PRINT((CH "(%p, %d); state=%s framesz=%u queued=%u" CT, buffer, size, (fState==ST_SYNC)?"sync":"frame", (size_t)(fCurrentFrame?(fCurrentFrame->Position()):-1), (size_t)fInputBuff.Position()));
if (!fCurrentFrame) { if (!fCurrentFrame) {
BAutolock l(fLocker); BAutolock l(fLocker);
if (fFrames.CountItems() < MAXFRAMEBUF) if (fFrames.CountItems() < MAXFRAMEBUF)

View File

@ -18,6 +18,7 @@
#include <interface/Bitmap.h> #include <interface/Bitmap.h>
#include "CamDevice.h" #include "CamDevice.h"
#include "CamSensor.h"
#define TOUCH(x) ((void)(x)) #define TOUCH(x) ((void)(x))
@ -138,11 +139,24 @@ VideoProducer::NodeRegistered()
return; return;
} }
int32 id = P_COLOR;
/* Set up the parameter web */ /* Set up the parameter web */
//TODO: remove and put sensible stuff there
BParameterWeb *web = new BParameterWeb(); BParameterWeb *web = new BParameterWeb();
BParameterGroup *main = web->MakeGroup(Name()); BParameterGroup *main = web->MakeGroup(Name());
BDiscreteParameter *state = main->MakeDiscreteParameter( BDiscreteParameter *state = main->MakeDiscreteParameter(
P_COLOR, B_MEDIA_RAW_VIDEO, "Color", "Color"); P_COLOR, B_MEDIA_RAW_VIDEO, "Color", "Color");
id++;
if (fCamDevice) {
BParameterGroup *dev = web->MakeGroup("Device");
fCamDevice->AddParameters(dev, id);
if (fCamDevice->Sensor()) {
BParameterGroup *sensor = web->MakeGroup("Sensor");
fCamDevice->Sensor()->AddParameters(sensor, id);
}
}
state->AddItem(B_HOST_TO_LENDIAN_INT32(0x00ff0000), "Red"); state->AddItem(B_HOST_TO_LENDIAN_INT32(0x00ff0000), "Red");
state->AddItem(B_HOST_TO_LENDIAN_INT32(0x0000ff00), "Green"); state->AddItem(B_HOST_TO_LENDIAN_INT32(0x0000ff00), "Green");
state->AddItem(B_HOST_TO_LENDIAN_INT32(0x000000ff), "Blue"); state->AddItem(B_HOST_TO_LENDIAN_INT32(0x000000ff), "Blue");
@ -385,12 +399,20 @@ VideoProducer::PrepareToConnect(const media_source &source,
} }
//XXX:FIXME //XXX:FIXME
#if 1
// if (format->u.raw_video.display.line_width == 0) // if (format->u.raw_video.display.line_width == 0)
format->u.raw_video.display.line_width = 352;//320; format->u.raw_video.display.line_width = 352;//320;
format->u.raw_video.display.line_width = 320; format->u.raw_video.display.line_width = 320;
// if (format->u.raw_video.display.line_count == 0) // if (format->u.raw_video.display.line_count == 0)
format->u.raw_video.display.line_count = 288;//240; format->u.raw_video.display.line_count = 288;//240;
format->u.raw_video.display.line_count = 240; format->u.raw_video.display.line_count = 240;
#endif
if (fCamDevice) {
format->u.raw_video.display.line_width = fCamDevice->VideoFrame().IntegerWidth() + 1;
format->u.raw_video.display.line_count = fCamDevice->VideoFrame().IntegerHeight() + 1;
}
if (format->u.raw_video.field_rate == 0) if (format->u.raw_video.field_rate == 0)
format->u.raw_video.field_rate = 29.97f; format->u.raw_video.field_rate = 29.97f;
@ -494,7 +516,7 @@ VideoProducer::Disconnect(const media_source &source,
return; return;
} }
#if 0 #if 1
/* Some dumb apps don't stop nodes before disconnecting... */ /* Some dumb apps don't stop nodes before disconnecting... */
if (fRunning) if (fRunning)
HandleStop(); HandleStop();
@ -560,31 +582,58 @@ status_t
VideoProducer::GetParameterValue( VideoProducer::GetParameterValue(
int32 id, bigtime_t *last_change, void *value, size_t *size) int32 id, bigtime_t *last_change, void *value, size_t *size)
{ {
if (id != P_COLOR) status_t err;
return B_BAD_VALUE;
*last_change = fLastColorChange; if (id == P_COLOR) {
*size = sizeof(uint32); //return B_BAD_VALUE;
*((uint32 *)value) = fColor;
return B_OK; *last_change = fLastColorChange;
*size = sizeof(uint32);
*((uint32 *)value) = fColor;
return B_OK;
}
if (fCamDevice) {
BAutolock lock(fCamDevice->Locker());
err = fCamDevice->GetParameterValue(id, last_change, value, size);
if (err >= B_OK)
return err;
if (fCamDevice->Sensor()) {
err = fCamDevice->Sensor()->GetParameterValue(id, last_change, value, size);
if (err >= B_OK)
return err;
}
}
return B_BAD_VALUE;
} }
void void
VideoProducer::SetParameterValue( VideoProducer::SetParameterValue(
int32 id, bigtime_t when, const void *value, size_t size) int32 id, bigtime_t when, const void *value, size_t size)
{ {
if ((id != P_COLOR) || !value || (size != sizeof(uint32))) status_t err = B_OK;
return;
if (*(uint32 *)value == fColor) if (id == P_COLOR) {
return; if (!value || (size != sizeof(uint32)))
return;
fColor = *(uint32 *)value; if (*(uint32 *)value == fColor)
fLastColorChange = when; return;
BroadcastNewParameterValue( fColor = *(uint32 *)value;
fLastColorChange, P_COLOR, &fColor, sizeof(fColor)); fLastColorChange = when;
} else if (fCamDevice) {
BAutolock lock(fCamDevice->Locker());
err = fCamDevice->SetParameterValue(id, when, value, size);
if ((err < B_OK) && (fCamDevice->Sensor())) {
err = fCamDevice->Sensor()->SetParameterValue(id, when, value, size);
}
}
if (err >= B_OK)
BroadcastNewParameterValue(when, id, (void *)value, size);
} }
status_t status_t

View File

@ -23,6 +23,7 @@ virtual ~VideoProducer();
virtual status_t InitCheck() const { return fInitStatus; } virtual status_t InitCheck() const { return fInitStatus; }
/* BMediaNode */ /* BMediaNode */
public: public:
virtual port_id ControlPort() const; virtual port_id ControlPort() const;

View File

@ -4,6 +4,7 @@
#include "CamBufferingDeframer.h" #include "CamBufferingDeframer.h"
#include "CamStreamingDeframer.h" #include "CamStreamingDeframer.h"
#include <ParameterWeb.h>
#include <interface/Bitmap.h> #include <interface/Bitmap.h>
#include <media/Buffer.h> #include <media/Buffer.h>
@ -36,6 +37,8 @@ SonixCamDevice::SonixCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
status_t err; status_t err;
fFrameTagState = 0; fFrameTagState = 0;
fRGain = fGGain = fBGain = 0;
memset(fCachedRegs, 0, SN9C102_REG_COUNT); memset(fCachedRegs, 0, SN9C102_REG_COUNT);
fChipVersion = 2; fChipVersion = 2;
if ((GetDevice()->ProductID() & ~0x3F) == 0x6080) { if ((GetDevice()->ProductID() & ~0x3F) == 0x6080) {
@ -88,6 +91,7 @@ SonixCamDevice::SonixCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
if (Sensor()) { if (Sensor()) {
PRINT((CH ": CamSensor: %s" CT, Sensor()->Name())); PRINT((CH ": CamSensor: %s" CT, Sensor()->Name()));
fInitStatus = Sensor()->Setup(); fInitStatus = Sensor()->Setup();
fVideoFrame = BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1);
// SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1)); // SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1));
// SetVideoFrame(BRect(0, 0, 320-1, 240-1)); // SetVideoFrame(BRect(0, 0, 320-1, 240-1));
} }
@ -127,7 +131,7 @@ SonixCamDevice::StartTransfer()
if (Sensor()) if (Sensor())
SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1)); SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1));
SetVideoFrame(BRect(0, 0, 320-1, 240-1)); //SetVideoFrame(BRect(0, 0, 320-1, 240-1));
DumpRegs(); DumpRegs();
err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true); err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true);
@ -364,6 +368,76 @@ SonixCamDevice::SetVideoParams(float brightness, float contrast, float hue, floa
return B_OK; return B_OK;
} }
void
SonixCamDevice::AddParameters(BParameterGroup *group, int32 &index)
{
BContinuousParameter *p;
CamDevice::AddParameters(group, index);
p = group->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);
}
status_t
SonixCamDevice::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size)
{
float *gains;
switch (id - fFirstParameterID) {
case 0:
*size = 3 * sizeof(float);
gains = ((float *)value);
gains[0] = 1.0 + (float)fRGain / 8;
gains[1] = 1.0 + (float)fGGain / 8;
gains[2] = 1.0 + (float)fBGain / 8;
*last_change = fLastParameterChanges;
return B_OK;
}
return B_BAD_VALUE;
}
status_t
SonixCamDevice::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size)
{
float *gains;
switch (id - fFirstParameterID) {
case 0:
if (!value || (size != 3 * sizeof(float)))
return B_BAD_VALUE;
gains = ((float *)value);
if ((gains[0] == 1.0 + (float)fRGain / 8)
&& (gains[1] == 1.0 + (float)fGGain / 8)
&& (gains[2] == 1.0 + (float)fBGain / 8))
return B_OK;
fRGain = (int)(8 * (gains[0] - 1.0)) & SN9C102_RGB_GAIN_MAX;
fGGain = (int)(8 * (gains[1] - 1.0)) & SN9C102_RGB_GAIN_MAX;
fBGain = (int)(8 * (gains[2] - 1.0)) & SN9C102_RGB_GAIN_MAX;
fLastParameterChanges = when;
PRINT((CH ": gain: %d,%d,%d" CT, fRGain, fGGain, fBGain));
//WriteReg8(SN9C102_R_B_GAIN, (fBGain << 4) | fRGain); /* red, blue gain = 1+0/8 = 1 */
/* Datasheet says:
* reg 0x10 [0:3] is rgain, [4:7] is bgain and 0x11 [0:3] is ggain
* according to sn9c102-1.15 linux driver it's wrong for reg 0x10,
* but it doesn't seem to work any better for a rev 2 chip.
* XXX
*/
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));
return B_OK;
}
return B_BAD_VALUE;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
size_t size_t
SonixCamDevice::MinRawFrameSize() SonixCamDevice::MinRawFrameSize()

View File

@ -8,6 +8,9 @@
#define SN9C102_ASIC_ID 0x00 #define SN9C102_ASIC_ID 0x00
#define SN9C102_CHIP_CTRL 0x01 #define SN9C102_CHIP_CTRL 0x01
#define SN9C102_GPIO 0x02 #define SN9C102_GPIO 0x02
#define SN9C103_G_GAIN 0x04 /* chip version dependant! */
#define SN9C102_R_GAIN 0x05
#define SN9C102_B_GAIN 0x06
#define SN9C102_I2C_SETUP 0x08 #define SN9C102_I2C_SETUP 0x08
#define SN9C102_I2C_SLAVE_ID 0x09 #define SN9C102_I2C_SLAVE_ID 0x09
#define SN9C102_I2C_DATA0 0x0a #define SN9C102_I2C_DATA0 0x0a
@ -16,7 +19,7 @@
#define SN9C102_I2C_DATA3 0x0d #define SN9C102_I2C_DATA3 0x0d
#define SN9C102_I2C_DATA4 0x0e #define SN9C102_I2C_DATA4 0x0e
#define SN9C102_CONTROL_STAT 0x0f /*I2C ??*/ #define SN9C102_CONTROL_STAT 0x0f /*I2C ??*/
#define SN9C102_R_B_GAIN 0x10 #define SN9C102_R_B_GAIN 0x10 /* datasheet says so but it's WRONG */
#define SN9C102_G_GAIN 0x11 /* Green channel gain control. -> Gain = (1+G_GAIN/8) #define SN9C102_G_GAIN 0x11 /* Green channel gain control. -> Gain = (1+G_GAIN/8)
Note: It is sync with VSYNC */ Note: It is sync with VSYNC */
#define SN9C102_H_START 0x12 /* Start active pixel number after H­sync of sensor #define SN9C102_H_START 0x12 /* Start active pixel number after H­sync of sensor
@ -37,6 +40,8 @@
#define SN9C102_AE_ENDX 0x1e #define SN9C102_AE_ENDX 0x1e
#define SN9C102_AE_ENDY 0x1f #define SN9C102_AE_ENDY 0x1f
#define SN9C102_RGB_GAIN_MAX 0x7f
// This class represents each webcam // This class represents each webcam
class SonixCamDevice : public CamDevice class SonixCamDevice : public CamDevice
{ {
@ -62,6 +67,11 @@ class SonixCamDevice : public CamDevice
virtual status_t SetScale(float scale); virtual status_t SetScale(float scale);
virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue); virtual status_t SetVideoParams(float brightness, float contrast, float hue, float red, float green, float blue);
virtual void AddParameters(BParameterGroup *group, int32 &index);
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size);
virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size);
// for use by deframer // for use by deframer
virtual size_t MinRawFrameSize(); virtual size_t MinRawFrameSize();
virtual size_t MaxRawFrameSize(); virtual size_t MaxRawFrameSize();
@ -81,6 +91,10 @@ class SonixCamDevice : public CamDevice
int fChipVersion; int fChipVersion;
int fFrameTagState; int fFrameTagState;
uint8 fRGain;
uint8 fGGain;
uint8 fBGain;
}; };
// the addon itself, that instanciate // the addon itself, that instanciate

View File

@ -1,10 +1,14 @@
/* /*
*/ */
#include <ParameterWeb.h>
#include "CamSensor.h" #include "CamSensor.h"
#include "CamDebug.h" #include "CamDebug.h"
#include "addons/sonix/SonixCamDevice.h" #include "addons/sonix/SonixCamDevice.h"
#define ENABLE_GAIN 1
class TAS5110C1BSensor : public CamSensor { class TAS5110C1BSensor : public CamSensor {
public: public:
TAS5110C1BSensor(CamDevice *_camera); TAS5110C1BSensor(CamDevice *_camera);
@ -18,8 +22,13 @@ public:
virtual int MaxWidth() const { return 352; }; virtual int MaxWidth() const { return 352; };
virtual int MaxHeight() const { return 288; }; virtual int MaxHeight() const { return 288; };
virtual status_t SetVideoFrame(BRect rect); virtual status_t SetVideoFrame(BRect rect);
virtual void AddParameters(BParameterGroup *group, int32 &firstID);
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size);
virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size);
private: private:
bool fIsSonix; bool fIsSonix;
float fGain;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -33,6 +42,7 @@ TAS5110C1BSensor::TAS5110C1BSensor(CamDevice *_camera)
PRINT((CH ": unknown camera device!" CT)); PRINT((CH ": unknown camera device!" CT));
fInitStatus = ENODEV; fInitStatus = ENODEV;
} }
fGain = (float)0x40; // default
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -109,6 +119,53 @@ TAS5110C1BSensor::SetVideoFrame(BRect rect)
return B_OK; return B_OK;
} }
void
TAS5110C1BSensor::AddParameters(BParameterGroup *group, int32 &index)
{
BContinuousParameter *p;
CamSensor::AddParameters(group, index);
#ifdef ENABLE_GAIN
p = group->MakeContinuousParameter(index++,
B_MEDIA_RAW_VIDEO, "global gain",
B_GAIN, "", (float)0x00, (float)0xf6, (float)1);
#endif
}
status_t
TAS5110C1BSensor::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size)
{
#ifdef ENABLE_GAIN
if (id == fFirstParameterID) {
*size = sizeof(float);
*((float *)value) = fGain;
*last_change = fLastParameterChanges;
}
#endif
return B_BAD_VALUE;
}
status_t
TAS5110C1BSensor::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size)
{
#ifdef ENABLE_GAIN
if (id == fFirstParameterID) {
if (!value || (size != sizeof(float)))
return B_BAD_VALUE;
if (*(float *)value == fGain)
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);
return B_OK;
}
#endif
return B_BAD_VALUE;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
B_WEBCAM_DECLARE_SENSOR(TAS5110C1BSensor, tas5110c1b) B_WEBCAM_DECLARE_SENSOR(TAS5110C1BSensor, tas5110c1b)