1 /* 2 * Copyright 2004-2008, François Revol, <revol@free.fr>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <ParameterWeb.h> 7 8 #include "CamSensor.h" 9 #include "CamDebug.h" 10 #include "addons/sonix/SonixCamDevice.h" 11 12 //XXX: unfinished! 13 14 #define ENABLE_GAIN 1 15 16 17 class TAS5130D1BSensor : public CamSensor { 18 public: 19 TAS5130D1BSensor(CamDevice *_camera); 20 ~TAS5130D1BSensor(); 21 virtual status_t Probe(); 22 virtual status_t Setup(); 23 const char *Name(); 24 virtual bool Use400kHz() const { return false; }; 25 virtual bool UseRealIIC() const { return false; }; 26 virtual uint8 IICReadAddress() const { return 0x00; }; 27 virtual uint8 IICWriteAddress() const { return 0x11; /*0xff;*/ }; 28 29 virtual int MaxWidth() const { return 640; }; 30 virtual int MaxHeight() const { return 480; }; 31 32 virtual status_t AcceptVideoFrame(uint32 &width, uint32 &height); 33 virtual status_t SetVideoFrame(BRect rect); 34 virtual void AddParameters(BParameterGroup *group, int32 &firstID); 35 virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size); 36 virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size); 37 38 private: 39 bool fIsSonix; 40 float fGain; 41 }; 42 43 44 TAS5130D1BSensor::TAS5130D1BSensor(CamDevice *_camera) 45 : CamSensor(_camera) 46 { 47 fIsSonix = (dynamic_cast<SonixCamDevice *>(_camera) != NULL); 48 if (fIsSonix) { 49 fInitStatus = B_OK; 50 } else { 51 PRINT((CH ": unknown camera device!" CT)); 52 fInitStatus = ENODEV; 53 } 54 fGain = (float)0x40; // default 55 } 56 57 58 TAS5130D1BSensor::~TAS5130D1BSensor() 59 { 60 } 61 62 63 status_t 64 TAS5130D1BSensor::Probe() 65 { 66 PRINT((CH "()" CT)); 67 68 return B_OK; 69 } 70 71 72 status_t 73 TAS5130D1BSensor::Setup() 74 { 75 PRINT((CH "()" CT)); 76 if (InitCheck()) 77 return InitCheck(); 78 /* 79 Device()->PowerOnSensor(false); 80 Device()->PowerOnSensor(true); 81 */ 82 if (fIsSonix) { 83 // linux driver seems to do this, but doesn't say why 84 Device()->WriteReg8(SN9C102_CHIP_CTRL, 0x01); /* power down the sensor */ 85 Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x20); /* enable sensor clk */ 86 Device()->WriteReg8(SN9C102_CHIP_CTRL, 0x04); /* power up the sensor, enable tx, sysclk@12MHz */ 87 Device()->WriteReg8(SN9C102_R_B_GAIN, 0x01); /* red gain = 1+0/8 = 1, red gain = 1+1/8 !!? */ 88 Device()->WriteReg8(SN9C102_G_GAIN, 0x00); /* green gain = 1+0/8 = 1 */ 89 Device()->WriteReg8(SN9C102_OFFSET, 0x0a); /* 0 pix offset */ 90 Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x60); /* enable sensor clk, and invert it */ 91 Device()->WriteReg8(SN9C102_SYNC_N_SCALE, 0x06); /* no compression, normal curve, 92 * no scaling, vsync active low, 93 * v/hsync change at rising edge, 94 * raising edge of sensor pck */ 95 Device()->WriteReg8(SN9C102_PIX_CLK, 0xf3); /* pixclk = masterclk, sensor is slave mode */ 96 } 97 98 99 if (fIsSonix) { 100 //sonix_i2c_write_multi(dev, dev->sensor->i2c_wid, 2, 0xc0, 0x80, 0, 0, 0); /* AEC = 0x203 ??? */ 101 #if 0 102 Device()->WriteIIC8(0xc0, 0x80); /* AEC = 0x203 ??? */ 103 #endif 104 105 #if 1 106 Device()->WriteIIC8(0x20, 0xf6 - 0xd0); /* GAIN */ 107 Device()->WriteIIC8(0x40, 0x47 - 0x40); /* Exposure */ 108 // set crop 109 Device()->WriteReg8(SN9C102_H_SIZE, 104); 110 Device()->WriteReg8(SN9C102_V_SIZE, 12); 111 SetVideoFrame(BRect(0, 0, 320-1, 240-1)); 112 #endif 113 114 #if 0 115 //XXX 116 Device()->WriteIIC8(0xc0, 0x80); /* AEC = 0x203 ??? */ 117 Device()->WriteReg8(SN9C102_H_SIZE, 69); 118 Device()->WriteReg8(SN9C102_V_SIZE, 9); 119 SetVideoFrame(BRect(0, 0, 352-1, 288-1)); 120 #endif 121 122 } 123 124 //Device()->SetScale(1); 125 126 return B_OK; 127 } 128 129 130 const char * 131 TAS5130D1BSensor::Name() 132 { 133 return "TASC tas5130d1b"; 134 } 135 136 137 status_t 138 TAS5130D1BSensor::AcceptVideoFrame(uint32 &width, uint32 &height) 139 { 140 // default sanity checks 141 status_t err = CamSensor::AcceptVideoFrame(width, height); 142 if (err < B_OK) 143 return err; 144 // must be modulo 16 145 width /= 16; 146 width *= 16; 147 height /= 16; 148 height *= 16; 149 return B_OK; 150 } 151 152 153 status_t 154 TAS5130D1BSensor::SetVideoFrame(BRect rect) 155 { 156 if (fIsSonix) { 157 // set crop 158 Device()->WriteReg8(SN9C102_H_START, /*rect.left + */104); 159 Device()->WriteReg8(SN9C102_V_START, /*rect.top + */12); 160 Device()->WriteReg8(SN9C102_PIX_CLK, 0xfb); 161 Device()->WriteReg8(SN9C102_HO_SIZE, 0x14); 162 Device()->WriteReg8(SN9C102_VO_SIZE, 0x0a); 163 #if 0 164 Device()->WriteReg8(SN9C102_H_START, /*rect.left + */104); 165 Device()->WriteReg8(SN9C102_V_START, /*rect.top + */12); 166 Device()->WriteReg8(SN9C102_PIX_CLK, 0xf3); 167 Device()->WriteReg8(SN9C102_HO_SIZE, 0x1f); 168 Device()->WriteReg8(SN9C102_VO_SIZE, 0x1a); 169 #endif 170 fVideoFrame = rect; 171 /* HACK: TEST IMAGE */ 172 //Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x70); /* enable sensor clk, and invert it, test img */ 173 174 } 175 176 return B_OK; 177 } 178 179 180 void 181 TAS5130D1BSensor::AddParameters(BParameterGroup *group, int32 &index) 182 { 183 BContinuousParameter *p; 184 CamSensor::AddParameters(group, index); 185 186 #ifdef ENABLE_GAIN 187 // NON-FUNCTIONAL 188 BParameterGroup *g = group->MakeGroup("global gain"); 189 p = g->MakeContinuousParameter(index++, 190 B_MEDIA_RAW_VIDEO, "global gain", 191 B_GAIN, "", (float)0x00, (float)0xf6, (float)1); 192 #endif 193 } 194 195 196 status_t 197 TAS5130D1BSensor::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size) 198 { 199 #ifdef ENABLE_GAIN 200 if (id == fFirstParameterID) { 201 *size = sizeof(float); 202 *((float *)value) = fGain; 203 *last_change = fLastParameterChanges; 204 } 205 #endif 206 return B_BAD_VALUE; 207 } 208 209 210 status_t 211 TAS5130D1BSensor::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size) 212 { 213 #ifdef ENABLE_GAIN 214 if (id == fFirstParameterID) { 215 if (!value || (size != sizeof(float))) 216 return B_BAD_VALUE; 217 if (*(float *)value == fGain) 218 return B_OK; 219 fGain = *(float *)value; 220 fLastParameterChanges = when; 221 PRINT((CH ": gain: %f" CT, fGain)); 222 223 if (fIsSonix) { 224 // some drivers do: 225 //Device()->WriteIIC8(0x20, (uint8)0xf6 - (uint8)fGain); 226 // but it doesn't seem to work 227 228 // works, not sure why yet, XXX check datasheet for AEG/AEC 229 uint8 buf[2] = { 0x20, 0x70 }; 230 buf[1] = (uint8)0xff - (uint8)fGain; 231 Device()->WriteIIC(0x02, buf, 2); 232 } 233 234 return B_OK; 235 } 236 #endif 237 return B_BAD_VALUE; 238 } 239 240 241 B_WEBCAM_DECLARE_SENSOR(TAS5130D1BSensor, tas5130d1b) 242 243