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