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