1601cedceSFrançois Revol /*
2a1830cbdSFrançois Revol * Copyright 2004-2008, François Revol, <revol@free.fr>.
3a1830cbdSFrançois Revol * Distributed under the terms of the MIT License.
4601cedceSFrançois Revol */
5601cedceSFrançois Revol
6a486abdcSFrançois Revol #include <ParameterWeb.h>
7a486abdcSFrançois Revol
8601cedceSFrançois Revol #include "CamSensor.h"
9601cedceSFrançois Revol #include "CamDebug.h"
10601cedceSFrançois Revol #include "addons/sonix/SonixCamDevice.h"
11601cedceSFrançois Revol
12fb086488SFrançois Revol //#define ENABLE_GAIN 1
13fb086488SFrançois Revol
14a486abdcSFrançois Revol
15601cedceSFrançois Revol class TAS5110C1BSensor : public CamSensor {
16601cedceSFrançois Revol public:
17601cedceSFrançois Revol TAS5110C1BSensor(CamDevice *_camera);
18601cedceSFrançois Revol ~TAS5110C1BSensor();
19fb086488SFrançois Revol virtual status_t Probe();
20601cedceSFrançois Revol virtual status_t Setup();
21601cedceSFrançois Revol const char *Name();
Use400kHz() const22601cedceSFrançois Revol virtual bool Use400kHz() const { return false; };
UseRealIIC() const23fb086488SFrançois Revol virtual bool UseRealIIC() const { return true /*false*/; };
IICReadAddress() const24601cedceSFrançois Revol virtual uint8 IICReadAddress() const { return 0x00; };
IICWriteAddress() const25fb086488SFrançois Revol virtual uint8 IICWriteAddress() const { return 0x61; /*0x11;*/ /*0xff;*/ };
260866ac7eSFrançois Revol
MaxWidth() const27601cedceSFrançois Revol virtual int MaxWidth() const { return 352; };
MaxHeight() const28601cedceSFrançois Revol virtual int MaxHeight() const { return 288; };
290866ac7eSFrançois Revol
300866ac7eSFrançois Revol virtual status_t AcceptVideoFrame(uint32 &width, uint32 &height);
31601cedceSFrançois Revol virtual status_t SetVideoFrame(BRect rect);
32a486abdcSFrançois Revol virtual void AddParameters(BParameterGroup *group, int32 &firstID);
33a486abdcSFrançois Revol virtual status_t GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size);
34a486abdcSFrançois Revol virtual status_t SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size);
35a486abdcSFrançois Revol
36601cedceSFrançois Revol private:
37601cedceSFrançois Revol bool fIsSonix;
38a486abdcSFrançois Revol float fGain;
39601cedceSFrançois Revol };
40601cedceSFrançois Revol
410866ac7eSFrançois Revol
TAS5110C1BSensor(CamDevice * _camera)42601cedceSFrançois Revol TAS5110C1BSensor::TAS5110C1BSensor(CamDevice *_camera)
43601cedceSFrançois Revol : CamSensor(_camera)
44601cedceSFrançois Revol {
45601cedceSFrançois Revol fIsSonix = (dynamic_cast<SonixCamDevice *>(_camera) != NULL);
46601cedceSFrançois Revol if (fIsSonix) {
47601cedceSFrançois Revol fInitStatus = B_OK;
48601cedceSFrançois Revol } else {
49601cedceSFrançois Revol PRINT((CH ": unknown camera device!" CT));
50601cedceSFrançois Revol fInitStatus = ENODEV;
51601cedceSFrançois Revol }
52a486abdcSFrançois Revol fGain = (float)0x40; // default
53601cedceSFrançois Revol }
54601cedceSFrançois Revol
550866ac7eSFrançois Revol
~TAS5110C1BSensor()56601cedceSFrançois Revol TAS5110C1BSensor::~TAS5110C1BSensor()
57601cedceSFrançois Revol {
58601cedceSFrançois Revol }
59601cedceSFrançois Revol
600866ac7eSFrançois Revol
61601cedceSFrançois Revol status_t
Probe()62fb086488SFrançois Revol TAS5110C1BSensor::Probe()
63fb086488SFrançois Revol {
64fb086488SFrançois Revol PRINT((CH "()" CT));
65fb086488SFrançois Revol
66fb086488SFrançois Revol return B_OK;
67fb086488SFrançois Revol }
68fb086488SFrançois Revol
69fb086488SFrançois Revol
70fb086488SFrançois Revol status_t
Setup()71601cedceSFrançois Revol TAS5110C1BSensor::Setup()
72601cedceSFrançois Revol {
73601cedceSFrançois Revol PRINT((CH "()" CT));
74601cedceSFrançois Revol if (InitCheck())
75601cedceSFrançois Revol return InitCheck();
76fb086488SFrançois Revol Device()->PowerOnSensor(false);
77fb086488SFrançois Revol Device()->PowerOnSensor(true);
78601cedceSFrançois Revol if (fIsSonix) {
79fb086488SFrançois Revol #if 1
80601cedceSFrançois Revol Device()->WriteReg8(SN9C102_CHIP_CTRL, 0x01); /* power down the sensor */
81601cedceSFrançois Revol Device()->WriteReg8(SN9C102_CHIP_CTRL, 0x44); /* power up the sensor, enable tx, sysclk@24MHz */
82fb086488SFrançois Revol Device()->WriteReg8(SN9C102_CHIP_CTRL, 0x04); /* power up the sensor, enable tx, sysclk@24MHz */
83601cedceSFrançois Revol Device()->WriteReg8(SN9C102_R_B_GAIN, 0x00); /* red, blue gain = 1+0/8 = 1 */
84601cedceSFrançois Revol Device()->WriteReg8(SN9C102_G_GAIN, 0x00); /* green gain = 1+0/8 = 1 */
85601cedceSFrançois Revol Device()->WriteReg8(SN9C102_OFFSET, 0x0a); /* 10 pix offset */
86601cedceSFrançois Revol Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x60); /* enable sensor clk, and invert it */
87fb086488SFrançois Revol Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x60); /* enable sensor clk, and invert it */
88601cedceSFrançois Revol Device()->WriteReg8(SN9C102_SYNC_N_SCALE, 0x06); /* no compression, normal curve,
89601cedceSFrançois Revol * no scaling, vsync active low,
90601cedceSFrançois Revol * v/hsync change at rising edge,
91601cedceSFrançois Revol * falling edge of sensor pck */
92601cedceSFrançois Revol Device()->WriteReg8(SN9C102_PIX_CLK, 0xfb); /* pixclk = 2 * masterclk, sensor is slave mode */
93fb086488SFrançois Revol
94fb086488SFrançois Revol // some IIC stuff for the sensor
95fb086488SFrançois Revol // though it seems more data is sent than told the controller
96fb086488SFrançois Revol // this is what the XP driver sends to the ICECAM...
97fb086488SFrançois Revol uint8 tmp_7[] = { 0xb0, 0x61, 0x1c, 0xf8, 0x10, 0x00, 0x00, 0x16 };
98fb086488SFrançois Revol Device()->WriteReg(SN9C102_I2C_SETUP, tmp_7, 8);
99fb086488SFrançois Revol
100fb086488SFrançois Revol Device()->WriteReg8(SN9C102_PIX_CLK, 0x4b);
101fb086488SFrançois Revol
102fb086488SFrançois Revol uint8 tmp_8[] = { 0xa0, 0x61, 0x1c, 0x0f, 0x10, 0x00, 0x00, 0x16 };
103fb086488SFrançois Revol Device()->WriteReg(SN9C102_I2C_SETUP, tmp_8, 8);
104fb086488SFrançois Revol
105fb086488SFrançois Revol #endif
106601cedceSFrançois Revol }
107601cedceSFrançois Revol
108c38af24cSFrançois Revol
109c38af24cSFrançois Revol if (fIsSonix) {
110601cedceSFrançois Revol //sonix_i2c_write_multi(dev, dev->sensor->i2c_wid, 2, 0xc0, 0x80, 0, 0, 0); /* AEC = 0x203 ??? */
111fb086488SFrançois Revol //Device()->WriteIIC8(0xc0, 0x80); /* AEC = 0x203 ??? */
112fb086488SFrançois Revol //Device()->WriteIIC8(0x1c, 0x80); /* AEC = 0x203 ??? */
113601cedceSFrançois Revol
114601cedceSFrançois Revol // set crop
115601cedceSFrançois Revol Device()->WriteReg8(SN9C102_H_SIZE, 69);
116601cedceSFrançois Revol Device()->WriteReg8(SN9C102_V_SIZE, 9);
117fb086488SFrançois Revol SetVideoFrame(BRect(0, 0, 352-1, 288-1));
118601cedceSFrançois Revol
119601cedceSFrançois Revol }
120601cedceSFrançois Revol
121601cedceSFrançois Revol //Device()->SetScale(1);
122601cedceSFrançois Revol
123601cedceSFrançois Revol return B_OK;
124601cedceSFrançois Revol }
125601cedceSFrançois Revol
1260866ac7eSFrançois Revol
127601cedceSFrançois Revol const char *
Name()128601cedceSFrançois Revol TAS5110C1BSensor::Name()
129601cedceSFrançois Revol {
130601cedceSFrançois Revol return "TASC tas5110c1b";
131601cedceSFrançois Revol }
132601cedceSFrançois Revol
1330866ac7eSFrançois Revol
1340866ac7eSFrançois Revol status_t
AcceptVideoFrame(uint32 & width,uint32 & height)1350866ac7eSFrançois Revol TAS5110C1BSensor::AcceptVideoFrame(uint32 &width, uint32 &height)
1360866ac7eSFrançois Revol {
1370866ac7eSFrançois Revol // default sanity checks
1380866ac7eSFrançois Revol status_t err = CamSensor::AcceptVideoFrame(width, height);
1390866ac7eSFrançois Revol if (err < B_OK)
1400866ac7eSFrançois Revol return err;
1410866ac7eSFrançois Revol // must be modulo 16
1420866ac7eSFrançois Revol width /= 16;
1430866ac7eSFrançois Revol width *= 16;
1440866ac7eSFrançois Revol height /= 16;
1450866ac7eSFrançois Revol height *= 16;
1460866ac7eSFrançois Revol return B_OK;
1470866ac7eSFrançois Revol }
1480866ac7eSFrançois Revol
1490866ac7eSFrançois Revol
150601cedceSFrançois Revol status_t
SetVideoFrame(BRect rect)151601cedceSFrançois Revol TAS5110C1BSensor::SetVideoFrame(BRect rect)
152601cedceSFrançois Revol {
153601cedceSFrançois Revol if (fIsSonix) {
154601cedceSFrançois Revol // set crop
155601cedceSFrançois Revol Device()->WriteReg8(SN9C102_H_START, /*rect.left + */69);
156601cedceSFrançois Revol Device()->WriteReg8(SN9C102_V_START, /*rect.top + */9);
157601cedceSFrançois Revol Device()->WriteReg8(SN9C102_PIX_CLK, 0xfb);
158601cedceSFrançois Revol Device()->WriteReg8(SN9C102_HO_SIZE, 0x14);
159601cedceSFrançois Revol Device()->WriteReg8(SN9C102_VO_SIZE, 0x0a);
160601cedceSFrançois Revol fVideoFrame = rect;
161601cedceSFrançois Revol /* HACK: TEST IMAGE */
162601cedceSFrançois Revol //Device()->WriteReg8(SN9C102_CLOCK_SEL, 0x70); /* enable sensor clk, and invert it, test img */
163601cedceSFrançois Revol
164601cedceSFrançois Revol }
165601cedceSFrançois Revol
166601cedceSFrançois Revol return B_OK;
167601cedceSFrançois Revol }
168601cedceSFrançois Revol
1690866ac7eSFrançois Revol
170a486abdcSFrançois Revol void
AddParameters(BParameterGroup * group,int32 & index)171a486abdcSFrançois Revol TAS5110C1BSensor::AddParameters(BParameterGroup *group, int32 &index)
172a486abdcSFrançois Revol {
173a486abdcSFrançois Revol CamSensor::AddParameters(group, index);
174a486abdcSFrançois Revol
175a486abdcSFrançois Revol #ifdef ENABLE_GAIN
176*628ddb27SFranck LeCodeur BContinuousParameter *p;
177c38af24cSFrançois Revol // NON-FUNCTIONAL
1780866ac7eSFrançois Revol BParameterGroup *g = group->MakeGroup("global gain");
1790866ac7eSFrançois Revol p = g->MakeContinuousParameter(index++,
180a486abdcSFrançois Revol B_MEDIA_RAW_VIDEO, "global gain",
181a486abdcSFrançois Revol B_GAIN, "", (float)0x00, (float)0xf6, (float)1);
182a486abdcSFrançois Revol #endif
183a486abdcSFrançois Revol }
184a486abdcSFrançois Revol
185a486abdcSFrançois Revol
186a486abdcSFrançois Revol status_t
GetParameterValue(int32 id,bigtime_t * last_change,void * value,size_t * size)187a486abdcSFrançois Revol TAS5110C1BSensor::GetParameterValue(int32 id, bigtime_t *last_change, void *value, size_t *size)
188a486abdcSFrançois Revol {
189a486abdcSFrançois Revol #ifdef ENABLE_GAIN
190a486abdcSFrançois Revol if (id == fFirstParameterID) {
191a486abdcSFrançois Revol *size = sizeof(float);
192a486abdcSFrançois Revol *((float *)value) = fGain;
193a486abdcSFrançois Revol *last_change = fLastParameterChanges;
194a486abdcSFrançois Revol }
195a486abdcSFrançois Revol #endif
196a486abdcSFrançois Revol return B_BAD_VALUE;
197a486abdcSFrançois Revol }
198a486abdcSFrançois Revol
1990866ac7eSFrançois Revol
200a486abdcSFrançois Revol status_t
SetParameterValue(int32 id,bigtime_t when,const void * value,size_t size)201a486abdcSFrançois Revol TAS5110C1BSensor::SetParameterValue(int32 id, bigtime_t when, const void *value, size_t size)
202a486abdcSFrançois Revol {
203a486abdcSFrançois Revol #ifdef ENABLE_GAIN
204a486abdcSFrançois Revol if (id == fFirstParameterID) {
205a486abdcSFrançois Revol if (!value || (size != sizeof(float)))
206a486abdcSFrançois Revol return B_BAD_VALUE;
207a486abdcSFrançois Revol if (*(float *)value == fGain)
208a486abdcSFrançois Revol return B_OK;
209a486abdcSFrançois Revol fGain = *(float *)value;
210a486abdcSFrançois Revol fLastParameterChanges = when;
211c38af24cSFrançois Revol PRINT((CH ": gain: %f" CT, fGain));
212c38af24cSFrançois Revol
213c38af24cSFrançois Revol if (fIsSonix) {
214c38af24cSFrançois Revol // some drivers do:
215c38af24cSFrançois Revol //Device()->WriteIIC8(0x20, (uint8)0xf6 - (uint8)fGain);
216c38af24cSFrançois Revol // but it doesn't seem to work
217c38af24cSFrançois Revol
218c38af24cSFrançois Revol // works, not sure why yet, XXX check datasheet for AEG/AEC
219c38af24cSFrançois Revol uint8 buf[2] = { 0x20, 0x70 };
220c38af24cSFrançois Revol buf[1] = (uint8)0xff - (uint8)fGain;
221c38af24cSFrançois Revol Device()->WriteIIC(0x02, buf, 2);
222c38af24cSFrançois Revol }
223c38af24cSFrançois Revol
224a486abdcSFrançois Revol return B_OK;
225a486abdcSFrançois Revol }
226a486abdcSFrançois Revol #endif
227a486abdcSFrançois Revol return B_BAD_VALUE;
228a486abdcSFrançois Revol }
229a486abdcSFrançois Revol
230a486abdcSFrançois Revol
2310866ac7eSFrançois Revol
232601cedceSFrançois Revol B_WEBCAM_DECLARE_SENSOR(TAS5110C1BSensor, tas5110c1b)
233601cedceSFrançois Revol
234