xref: /OK3568_Linux_fs/kernel/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
4*4882a593Smuzhiyun  *		      Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
5*4882a593Smuzhiyun  * Copyright (c) 2002, 2003 Tuukka Toivonen
6*4882a593Smuzhiyun  * Copyright (c) 2008 Erik Andrén
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
9*4882a593Smuzhiyun  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
10*4882a593Smuzhiyun  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
11*4882a593Smuzhiyun  * P/N 861055:      Sensor ST VV6410       ASIC STV0610   - LEGO cam
12*4882a593Smuzhiyun  * P/N 861075-0040: Sensor HDCS1000        ASIC
13*4882a593Smuzhiyun  * P/N 961179-0700: Sensor ST VV6410       ASIC STV0602   - Dexxa WebCam USB
14*4882a593Smuzhiyun  * P/N 861040-0000: Sensor ST VV6410       ASIC STV0610   - QuickCam Web
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifndef STV06XX_VV6410_H_
18*4882a593Smuzhiyun #define STV06XX_VV6410_H_
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include "stv06xx_sensor.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define VV6410_COLS			416
23*4882a593Smuzhiyun #define VV6410_ROWS			320
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* Status registers */
26*4882a593Smuzhiyun /* Chip identification number including revision indicator */
27*4882a593Smuzhiyun #define VV6410_DEVICEH			0x00
28*4882a593Smuzhiyun #define VV6410_DEVICEL			0x01
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* User can determine whether timed I2C data
31*4882a593Smuzhiyun    has been consumed by interrogating flag states */
32*4882a593Smuzhiyun #define VV6410_STATUS0			0x02
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /* Current line counter value */
35*4882a593Smuzhiyun #define VV6410_LINECOUNTH		0x03
36*4882a593Smuzhiyun #define VV6410_LINECOUNTL		0x04
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /* End x coordinate of image size */
39*4882a593Smuzhiyun #define VV6410_XENDH			0x05
40*4882a593Smuzhiyun #define VV6410_XENDL			0x06
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* End y coordinate of image size */
43*4882a593Smuzhiyun #define VV6410_YENDH			0x07
44*4882a593Smuzhiyun #define VV6410_YENDL			0x08
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* This is the average pixel value returned from the
47*4882a593Smuzhiyun    dark line offset cancellation algorithm */
48*4882a593Smuzhiyun #define VV6410_DARKAVGH			0x09
49*4882a593Smuzhiyun #define VV6410_DARKAVGL			0x0a
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* This is the average pixel value returned from the
52*4882a593Smuzhiyun    black line offset cancellation algorithm  */
53*4882a593Smuzhiyun #define VV6410_BLACKAVGH		0x0b
54*4882a593Smuzhiyun #define VV6410_BLACKAVGL		0x0c
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* Flags to indicate whether the x or y image coordinates have been clipped */
57*4882a593Smuzhiyun #define VV6410_STATUS1			0x0d
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* Setup registers */
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* Low-power/sleep modes & video timing */
62*4882a593Smuzhiyun #define VV6410_SETUP0			0x10
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /* Various parameters */
65*4882a593Smuzhiyun #define VV6410_SETUP1			0x11
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun /* Contains pixel counter reset value used by external sync */
68*4882a593Smuzhiyun #define VV6410_SYNCVALUE		0x12
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* Frame grabbing modes (FST, LST and QCK) */
71*4882a593Smuzhiyun #define VV6410_FGMODES			0x14
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /* FST and QCK mapping modes. */
74*4882a593Smuzhiyun #define VV6410_PINMAPPING		0x15
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun /* Data resolution */
77*4882a593Smuzhiyun #define VV6410_DATAFORMAT		0x16
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* Output coding formats */
80*4882a593Smuzhiyun #define VV6410_OPFORMAT			0x17
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /* Various mode select bits */
83*4882a593Smuzhiyun #define VV6410_MODESELECT		0x18
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /* Exposure registers */
86*4882a593Smuzhiyun /* Fine exposure. */
87*4882a593Smuzhiyun #define VV6410_FINEH			0x20
88*4882a593Smuzhiyun #define VV6410_FINEL			0x21
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /* Coarse exposure */
91*4882a593Smuzhiyun #define VV6410_COARSEH			0x22
92*4882a593Smuzhiyun #define VV6410_COARSEL			0x23
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /* Analog gain setting */
95*4882a593Smuzhiyun #define VV6410_ANALOGGAIN		0x24
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* Clock division */
98*4882a593Smuzhiyun #define VV6410_CLKDIV			0x25
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* Dark line offset cancellation value */
101*4882a593Smuzhiyun #define VV6410_DARKOFFSETH		0x2c
102*4882a593Smuzhiyun #define VV6410_DARKOFFSETL		0x2d
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /* Dark line offset cancellation enable */
105*4882a593Smuzhiyun #define VV6410_DARKOFFSETSETUP		0x2e
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /* Video timing registers */
108*4882a593Smuzhiyun /* Line Length (Pixel Clocks) */
109*4882a593Smuzhiyun #define VV6410_LINELENGTHH		0x52
110*4882a593Smuzhiyun #define VV6410_LINELENGTHL		0x53
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /* X-co-ordinate of top left corner of region of interest (x-offset) */
113*4882a593Smuzhiyun #define VV6410_XOFFSETH			0x57
114*4882a593Smuzhiyun #define VV6410_XOFFSETL			0x58
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /* Y-coordinate of top left corner of region of interest (y-offset) */
117*4882a593Smuzhiyun #define VV6410_YOFFSETH			0x59
118*4882a593Smuzhiyun #define VV6410_YOFFSETL			0x5a
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun /* Field length (Lines) */
121*4882a593Smuzhiyun #define VV6410_FIELDLENGTHH		0x61
122*4882a593Smuzhiyun #define VV6410_FIELDLENGTHL		0x62
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /* System registers */
125*4882a593Smuzhiyun /* Black offset cancellation default value */
126*4882a593Smuzhiyun #define VV6410_BLACKOFFSETH		0x70
127*4882a593Smuzhiyun #define VV6410_BLACKOFFSETL		0x71
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun /* Black offset cancellation setup */
130*4882a593Smuzhiyun #define VV6410_BLACKOFFSETSETUP		0x72
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* Analog Control Register 0 */
133*4882a593Smuzhiyun #define VV6410_CR0			0x75
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /* Analog Control Register 1 */
136*4882a593Smuzhiyun #define VV6410_CR1			0x76
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* ADC Setup Register */
139*4882a593Smuzhiyun #define VV6410_AS0			0x77
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /* Analog Test Register */
142*4882a593Smuzhiyun #define VV6410_AT0			0x78
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /* Audio Amplifier Setup Register */
145*4882a593Smuzhiyun #define VV6410_AT1			0x79
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun #define VV6410_HFLIP			(1 << 3)
148*4882a593Smuzhiyun #define VV6410_VFLIP			(1 << 4)
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #define VV6410_LOW_POWER_MODE		(1 << 0)
151*4882a593Smuzhiyun #define VV6410_SOFT_RESET		(1 << 2)
152*4882a593Smuzhiyun #define VV6410_PAL_25_FPS		(0 << 3)
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun #define VV6410_CLK_DIV_2		(1 << 1)
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun #define VV6410_FINE_EXPOSURE		320
157*4882a593Smuzhiyun #define VV6410_COARSE_EXPOSURE		192
158*4882a593Smuzhiyun #define VV6410_DEFAULT_GAIN		5
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define VV6410_SUBSAMPLE		0x01
161*4882a593Smuzhiyun #define VV6410_CROP_TO_QVGA		0x02
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun #define VV6410_CIF_LINELENGTH		415
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun static int vv6410_probe(struct sd *sd);
166*4882a593Smuzhiyun static int vv6410_start(struct sd *sd);
167*4882a593Smuzhiyun static int vv6410_init(struct sd *sd);
168*4882a593Smuzhiyun static int vv6410_init_controls(struct sd *sd);
169*4882a593Smuzhiyun static int vv6410_stop(struct sd *sd);
170*4882a593Smuzhiyun static int vv6410_dump(struct sd *sd);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun /* V4L2 controls supported by the driver */
173*4882a593Smuzhiyun static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
174*4882a593Smuzhiyun static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
175*4882a593Smuzhiyun static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
176*4882a593Smuzhiyun static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
179*4882a593Smuzhiyun 	.name = "ST VV6410",
180*4882a593Smuzhiyun 	.i2c_flush = 5,
181*4882a593Smuzhiyun 	.i2c_addr = 0x20,
182*4882a593Smuzhiyun 	.i2c_len = 1,
183*4882a593Smuzhiyun 	/* FIXME (see if we can lower packet_size-s, needs testing, and also
184*4882a593Smuzhiyun 	   adjusting framerate when the bandwidth gets lower) */
185*4882a593Smuzhiyun 	.min_packet_size = { 1023 },
186*4882a593Smuzhiyun 	.max_packet_size = { 1023 },
187*4882a593Smuzhiyun 	.init = vv6410_init,
188*4882a593Smuzhiyun 	.init_controls = vv6410_init_controls,
189*4882a593Smuzhiyun 	.probe = vv6410_probe,
190*4882a593Smuzhiyun 	.start = vv6410_start,
191*4882a593Smuzhiyun 	.stop = vv6410_stop,
192*4882a593Smuzhiyun 	.dump = vv6410_dump,
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /* If NULL, only single value to write, stored in len */
196*4882a593Smuzhiyun struct stv_init {
197*4882a593Smuzhiyun 	u16 addr;
198*4882a593Smuzhiyun 	u8 data;
199*4882a593Smuzhiyun };
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun static const struct stv_init stv_bridge_init[] = {
202*4882a593Smuzhiyun 	/* This reg is written twice. Some kind of reset? */
203*4882a593Smuzhiyun 	{STV_RESET, 0x80},
204*4882a593Smuzhiyun 	{STV_RESET, 0x00},
205*4882a593Smuzhiyun 	{STV_SCAN_RATE, 0x00},
206*4882a593Smuzhiyun 	{STV_I2C_FLUSH, 0x04},
207*4882a593Smuzhiyun 	{STV_REG00, 0x0b},
208*4882a593Smuzhiyun 	{STV_REG01, 0xa7},
209*4882a593Smuzhiyun 	{STV_REG02, 0xb7},
210*4882a593Smuzhiyun 	{STV_REG03, 0x00},
211*4882a593Smuzhiyun 	{STV_REG04, 0x00},
212*4882a593Smuzhiyun 	{0x1536, 0x02},
213*4882a593Smuzhiyun 	{0x1537, 0x00},
214*4882a593Smuzhiyun 	{0x1538, 0x60},
215*4882a593Smuzhiyun 	{0x1539, 0x01},
216*4882a593Smuzhiyun 	{0x153a, 0x20},
217*4882a593Smuzhiyun 	{0x153b, 0x01},
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun static const u8 vv6410_sensor_init[][2] = {
221*4882a593Smuzhiyun 	/* Setup registers */
222*4882a593Smuzhiyun 	{VV6410_SETUP0,	VV6410_SOFT_RESET},
223*4882a593Smuzhiyun 	{VV6410_SETUP0,	VV6410_LOW_POWER_MODE},
224*4882a593Smuzhiyun 	/* Use shuffled read-out mode */
225*4882a593Smuzhiyun 	{VV6410_SETUP1,	BIT(6)},
226*4882a593Smuzhiyun 	/* All modes to 1, FST, Fast QCK, Free running QCK, Free running LST, FST will qualify visible pixels */
227*4882a593Smuzhiyun 	{VV6410_FGMODES, BIT(6) | BIT(4) | BIT(2) | BIT(0)},
228*4882a593Smuzhiyun 	{VV6410_PINMAPPING, 0x00},
229*4882a593Smuzhiyun 	/* Pre-clock generator divide off */
230*4882a593Smuzhiyun 	{VV6410_DATAFORMAT, BIT(7) | BIT(0)},
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	{VV6410_CLKDIV,	VV6410_CLK_DIV_2},
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	/* System registers */
235*4882a593Smuzhiyun 	/* Enable voltage doubler */
236*4882a593Smuzhiyun 	{VV6410_AS0, BIT(6) | BIT(4) | BIT(3) | BIT(2) | BIT(1)},
237*4882a593Smuzhiyun 	{VV6410_AT0, 0x00},
238*4882a593Smuzhiyun 	/* Power up audio, differential */
239*4882a593Smuzhiyun 	{VV6410_AT1, BIT(4) | BIT(0)},
240*4882a593Smuzhiyun };
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun #endif
243