aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/usbvision/usbvision.h
blob: 870c0cc81d84d1538de0406c6bab6797cfb9757d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
/*
 * USBVISION.H
 *  usbvision header file
 *
 * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
 *
 * This module is part of usbvision driver project.
 * Updates to driver completed by Dwaine P. Garden
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#ifndef __LINUX_USBVISION_H
#define __LINUX_USBVISION_H

#include <linux/list.h>
#include <linux/usb.h>
#include "usbvision-i2c.h"

#ifndef VID_HARDWARE_USBVISION
	#define VID_HARDWARE_USBVISION 34   /* USBVision Video Grabber */
#endif

#define USBVISION_PWR_REG		0x00
	#define USBVISION_SSPND_EN		(1 << 1)
	#define USBVISION_RES2			(1 << 2)
	#define USBVISION_PWR_VID		(1 << 5)
	#define USBVISION_E2_EN			(1 << 7)
#define USBVISION_CONFIG_REG		0x01
#define USBVISION_ADRS_REG		0x02
#define USBVISION_ALTER_REG		0x03
#define USBVISION_FORCE_ALTER_REG	0x04
#define USBVISION_STATUS_REG		0x05
#define USBVISION_IOPIN_REG		0x06
	#define USBVISION_IO_1			(1 << 0)
	#define USBVISION_IO_2			(1 << 1)
	#define USBVISION_AUDIO_IN		0
	#define USBVISION_AUDIO_TV		1
	#define USBVISION_AUDIO_RADIO		2
	#define USBVISION_AUDIO_MUTE		3
#define USBVISION_SER_MODE		0x07
#define USBVISION_SER_ADRS		0x08
#define USBVISION_SER_CONT		0x09
#define USBVISION_SER_DAT1		0x0A
#define USBVISION_SER_DAT2		0x0B
#define USBVISION_SER_DAT3		0x0C
#define USBVISION_SER_DAT4		0x0D
#define USBVISION_EE_DATA		0x0E
#define USBVISION_EE_LSBAD		0x0F
#define USBVISION_EE_CONT		0x10
#define USBVISION_DRM_CONT			0x12
	#define USBVISION_REF			(1 << 0)
	#define USBVISION_RES_UR		(1 << 2)
	#define USBVISION_RES_FDL		(1 << 3)
	#define USBVISION_RES_VDW		(1 << 4)
#define USBVISION_DRM_PRM1		0x13
#define USBVISION_DRM_PRM2		0x14
#define USBVISION_DRM_PRM3		0x15
#define USBVISION_DRM_PRM4		0x16
#define USBVISION_DRM_PRM5		0x17
#define USBVISION_DRM_PRM6		0x18
#define USBVISION_DRM_PRM7		0x19
#define USBVISION_DRM_PRM8		0x1A
#define USBVISION_VIN_REG1		0x1B
	#define USBVISION_8_422_SYNC		0x01
	#define USBVISION_16_422_SYNC		0x02
	#define USBVISION_VSNC_POL		(1 << 3)
	#define USBVISION_HSNC_POL		(1 << 4)
	#define USBVISION_FID_POL		(1 << 5)
	#define USBVISION_HVALID_PO		(1 << 6)
	#define USBVISION_VCLK_POL		(1 << 7)
#define USBVISION_VIN_REG2		0x1C
	#define USBVISION_AUTO_FID		(1 << 0)
	#define USBVISION_NONE_INTER		(1 << 1)
	#define USBVISION_NOHVALID		(1 << 2)
	#define USBVISION_UV_ID			(1 << 3)
	#define USBVISION_FIX_2C		(1 << 4)
	#define USBVISION_SEND_FID		(1 << 5)
	#define USBVISION_KEEP_BLANK		(1 << 7)
#define USBVISION_LXSIZE_I		0x1D
#define USBVISION_MXSIZE_I		0x1E
#define USBVISION_LYSIZE_I		0x1F
#define USBVISION_MYSIZE_I		0x20
#define USBVISION_LX_OFFST		0x21
#define USBVISION_MX_OFFST		0x22
#define USBVISION_LY_OFFST		0x23
#define USBVISION_MY_OFFST		0x24
#define USBVISION_FRM_RATE		0x25
#define USBVISION_LXSIZE_O		0x26
#define USBVISION_MXSIZE_O		0x27
#define USBVISION_LYSIZE_O		0x28
#define USBVISION_MYSIZE_O		0x29
#define USBVISION_FILT_CONT		0x2A
#define USBVISION_VO_MODE		0x2B
#define USBVISION_INTRA_CYC		0x2C
#define USBVISION_STRIP_SZ		0x2D
#define USBVISION_FORCE_INTRA		0x2E
#define USBVISION_FORCE_UP		0x2F
#define USBVISION_BUF_THR		0x30
#define USBVISION_DVI_YUV		0x31
#define USBVISION_AUDIO_CONT		0x32
#define USBVISION_AUD_PK_LEN		0x33
#define USBVISION_BLK_PK_LEN		0x34
#define USBVISION_PCM_THR1		0x38
#define USBVISION_PCM_THR2		0x39
#define USBVISION_DIST_THR_L		0x3A
#define USBVISION_DIST_THR_H		0x3B
#define USBVISION_MAX_DIST_L		0x3C
#define USBVISION_MAX_DIST_H		0x3D
#define USBVISION_OP_CODE		0x33

#define MAX_BYTES_PER_PIXEL		4

#define MIN_FRAME_WIDTH			64
#define MAX_USB_WIDTH			320  //384
#define MAX_FRAME_WIDTH			320  //384			/*streching sometimes causes crashes*/

#define MIN_FRAME_HEIGHT		48
#define MAX_USB_HEIGHT			240  //288
#define MAX_FRAME_HEIGHT		240  //288			/*Streching sometimes causes crashes*/

#define MAX_FRAME_SIZE     		(MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * MAX_BYTES_PER_PIXEL)
#define USBVISION_CLIPMASK_SIZE		(MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask

#define USBVISION_URB_FRAMES		32
#define USBVISION_MAX_ISOC_PACKET_SIZE 	959			// NT1003 Specs Document says 1023

#define USBVISION_NUM_HEADERMARKER	20
#define USBVISION_NUMFRAMES		3
#define USBVISION_NUMSBUF		2

#define USBVISION_POWEROFF_TIME		3 * (HZ)		// 3 seconds

/* This macro restricts an int variable to an inclusive range */
#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }

/*
 * We use macros to do YUV -> RGB conversion because this is
 * very important for speed and totally unimportant for size.
 *
 * YUV -> RGB Conversion
 * ---------------------
 *
 * B = 1.164*(Y-16)		    + 2.018*(V-128)
 * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
 * R = 1.164*(Y-16) + 1.596*(U-128)
 *
 * If you fancy integer arithmetics (as you should), hear this:
 *
 * 65536*B = 76284*(Y-16)		  + 132252*(V-128)
 * 65536*G = 76284*(Y-16) -  53281*(U-128) -  25625*(V-128)
 * 65536*R = 76284*(Y-16) + 104595*(U-128)
 *
 * Make sure the output values are within [0..255] range.
 */
#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
    int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
    mm_y = (my) - 16;  \
    mm_u = (mu) - 128; \
    mm_v = (mv) - 128; \
    mm_yc= mm_y * 76284; \
    mm_b = (mm_yc		+ 132252*mm_v	) >> 16; \
    mm_g = (mm_yc -  53281*mm_u -  25625*mm_v	) >> 16; \
    mm_r = (mm_yc + 104595*mm_u			) >> 16; \
    mb = LIMIT_RGB(mm_b); \
    mg = LIMIT_RGB(mm_g); \
    mr = LIMIT_RGB(mm_r); \
}



/* Debugging aid */
#define USBVISION_SAY_AND_WAIT(what) { \
	wait_queue_head_t wq; \
	init_waitqueue_head(&wq); \
	printk(KERN_INFO "Say: %s\n", what); \
	interruptible_sleep_on_timeout (&wq, HZ*3); \
}

/*
 * This macro checks if usbvision is still operational. The 'usbvision'
 * pointer must be valid, usbvision->dev must be valid, we are not
 * removing the device and the device has not erred on us.
 */
#define USBVISION_IS_OPERATIONAL(udevice) (\
	(udevice != NULL) && \
	((udevice)->dev != NULL) && \
	((udevice)->last_error == 0) && \
	(!(udevice)->remove_pending))


enum ScanState {
	ScanState_Scanning,	/* Scanning for header */
	ScanState_Lines		/* Parsing lines */
};

/* Completion states of the data parser */
enum ParseState {
	ParseState_Continue,	/* Just parse next item */
	ParseState_NextFrame,	/* Frame done, send it to V4L */
	ParseState_Out,		/* Not enough data for frame */
	ParseState_EndParse	/* End parsing */
};

enum FrameState {
	FrameState_Unused,	/* Unused (no MCAPTURE) */
	FrameState_Ready,	/* Ready to start grabbing */
	FrameState_Grabbing,	/* In the process of being grabbed into */
	FrameState_Done,	/* Finished grabbing, but not been synced yet */
	FrameState_DoneHold,	/* Are syncing or reading */
	FrameState_Error,	/* Something bad happened while processing */
};

/* stream states */
enum StreamState {
	Stream_Off,
	Stream_Interrupt,
	Stream_On,
};

enum IsocState {
	IsocState_InFrame,	/* Isoc packet is member of frame */
	IsocState_NoFrame,	/* Isoc packet is not member of any frame */
};

struct usb_device;

struct usbvision_sbuf {
	char *data;
	struct urb *urb;
};

#define USBVISION_MAGIC_1      			0x55
#define USBVISION_MAGIC_2      			0xAA
#define USBVISION_HEADER_LENGTH			0x0c
#define USBVISION_SAA7111_ADDR			0x48
#define USBVISION_SAA7113_ADDR			0x4a
#define USBVISION_IIC_LRACK			0x20
#define USBVISION_IIC_LRNACK			0x30
#define USBVISION_FRAME_FORMAT_PARAM_INTRA	(1<<7)

struct usbvision_v4l2_format_st {
	int		supported;
	int		bytes_per_pixel;
	int		depth;
	int		format;
	char		*desc;
};
#define USBVISION_SUPPORTED_PALETTES ARRAY_SIZE(usbvision_v4l2_format)

struct usbvision_frame_header {
	unsigned char magic_1;				/* 0 magic */
	unsigned char magic_2;				/* 1  magic */
	unsigned char headerLength;			/* 2 */
	unsigned char frameNum;				/* 3 */
	unsigned char framePhase;			/* 4 */
	unsigned char frameLatency;			/* 5 */
	unsigned char dataFormat;			/* 6 */
	unsigned char formatParam;			/* 7 */
	unsigned char frameWidthLo;			/* 8 */
	unsigned char frameWidthHi;			/* 9 */
	unsigned char frameHeightLo;			/* 10 */
	unsigned char frameHeightHi;			/* 11 */
	__u16 frameWidth;				/* 8 - 9 after endian correction*/
	__u16 frameHeight;				/* 10 - 11 after endian correction*/
};

/* tvnorms */
struct usbvision_tvnorm {
	char *name;
	v4l2_std_id id;
	/* mode for saa7113h */
	int mode;
};

struct usbvision_frame {
	char *data;					/* Frame buffer */
	struct usbvision_frame_header isocHeader;	/* Header from stream */

	int width;					/* Width application is expecting */
	int height;					/* Height */
	int index;					/* Frame index */
	int frmwidth;					/* Width the frame actually is */
	int frmheight;					/* Height */

	volatile int grabstate;				/* State of grabbing */
	int scanstate;					/* State of scanning */

	struct list_head frame;

	int curline;					/* Line of frame we're working on */

	long scanlength;				/* uncompressed, raw data length of frame */
	long bytes_read;				/* amount of scanlength that has been read from data */
	struct usbvision_v4l2_format_st v4l2_format;	/* format the user needs*/
	int v4l2_linesize;				/* bytes for one videoline*/
	struct timeval timestamp;
	int sequence;					// How many video frames we send to user
};

#define CODEC_SAA7113	7113
#define CODEC_SAA7111	7111
#define BRIDGE_NT1003	1003
#define BRIDGE_NT1004	1004
#define BRIDGE_NT1005   1005

#define USBVISION_I2C_CLIENTS_MAX		8

struct usbvision_device_data_st {
	int idVendor;
	int idProduct;
	int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
	int Codec;
	int VideoChannels;
	__u64 VideoNorm;
	int AudioChannels;
	int Radio;
	int vbi;
	int Tuner;
	int TunerType;
	int Vin_Reg1;
	int Vin_Reg2;
	int X_Offset;
	int Y_Offset;
	int Dvi_yuv;
	char *ModelString;
};

/* Declared on usbvision-cards.c */
extern struct usbvision_device_data_st usbvision_device_data[];
extern struct usb_device_id usbvision_table[];

struct usb_usbvision {
	struct video_device *vdev;         				/* Video Device */
	struct video_device *rdev;               			/* Radio Device */
	struct video_device *vbi; 					/* VBI Device   */
	struct video_audio audio_dev;					/* Current audio params */

	/* i2c Declaration Section*/
	struct i2c_adapter i2c_adap;
	struct i2c_algo_usb_data i2c_algo;
	struct i2c_client i2c_client;
	int i2c_state, i2c_ok;
	struct i2c_client *i2c_clients[USBVISION_I2C_CLIENTS_MAX];

	struct urb *ctrlUrb;
	unsigned char ctrlUrbBuffer[8];
	int ctrlUrbBusy;
	struct usb_ctrlrequest ctrlUrbSetup;
	wait_queue_head_t ctrlUrb_wq;					// Processes waiting
	struct semaphore ctrlUrbLock;

	int have_tuner;
	int tuner_type;
	int bridgeType;							// NT1003, NT1004, NT1005
	int channel;
	int radio;
	int video_inputs;						// # of inputs
	unsigned long freq;
	int AudioMute;
	int AudioChannel;
	int isocMode;							// format of video data for the usb isoc-transfer
	unsigned int nr;						// Number of the device < MAX_USBVISION

	/* Device structure */
	struct usb_device *dev;
	unsigned char iface;						/* Video interface number */
	unsigned char ifaceAltActive, ifaceAltInactive;			/* Alt settings */
	unsigned char Vin_Reg2_Preset;
	struct semaphore lock;
	struct timer_list powerOffTimer;
	struct work_struct powerOffWork;
	int power;							/* is the device powered on? */
	int user;							/* user count for exclusive use */
	int usbvision_used;						/* Is this structure in use? */
	int initialized;						/* Had we already sent init sequence? */
	int DevModel;							/* What type of USBVISION device we got? */
	enum StreamState streaming;					/* Are we streaming Isochronous? */
	int last_error;							/* What calamity struck us? */
	int curwidth;							/* width of the frame the device is currently set to*/
	int curheight;      						/* height of the frame the device is currently set to*/
	int stretch_width;						/* stretch-factor for frame width (from usb to screen)*/
	int stretch_height;						/* stretch-factor for frame height (from usb to screen)*/
	char *fbuf;							/* Videodev buffer area for mmap*/
	int max_frame_size;						/* Bytes in one video frame */
	int fbuf_size;							/* Videodev buffer size */
	spinlock_t queue_lock;						/* spinlock for protecting mods on inqueue and outqueue */
	struct list_head inqueue, outqueue;                             /* queued frame list and ready to dequeue frame list */
	wait_queue_head_t wait_frame;					/* Processes waiting */
	wait_queue_head_t wait_stream;					/* Processes waiting */
	struct usbvision_frame *curFrame;				// pointer to current frame, set by usbvision_find_header
	struct usbvision_frame frame[USBVISION_NUMFRAMES];		// frame buffer
	int curSbufNum;							// number of current receiving sbuf
	struct usbvision_sbuf sbuf[USBVISION_NUMSBUF];			// S buffering
	volatile int remove_pending;					/* If set then about to exit */

	/* Scratch space from the Isochronous Pipe.*/
	unsigned char *scratch;
	int scratch_read_ptr;
	int scratch_write_ptr;
	int scratch_headermarker[USBVISION_NUM_HEADERMARKER];
	int scratch_headermarker_read_ptr;
	int scratch_headermarker_write_ptr;
	int isocstate;
	/* color controls */
	int saturation;
	int hue;
	int brightness;
	int contrast;
	int depth;
	struct usbvision_v4l2_format_st palette;

	struct v4l2_capability vcap;					/* Video capabilities */
	unsigned int ctl_input;						/* selected input */
	struct usbvision_tvnorm *tvnorm;				/* selected tv norm */
	unsigned char video_endp;					/* 0x82 for USBVISION devices based */

	// Overlay stuff:
	struct v4l2_framebuffer vid_buf;
	struct v4l2_format vid_win;
	int vid_buf_valid;						// Status: video buffer is valid (set)
	int vid_win_valid;						// Status: video window is valid (set)
	int	overlay;						/*Status: Are we overlaying? */
	unsigned int 	clipmask[USBVISION_CLIPMASK_SIZE / 4];
	unsigned char   *overlay_base;					/* Virtual base address of video buffer */
	unsigned char   *overlay_win;					/* virt start address of overlay window */
	struct usbvision_frame overlay_frame;

	// Decompression stuff:
	unsigned char *IntraFrameBuffer;				/* Buffer for reference frame */
	int BlockPos; 							//for test only
	int requestIntra;						// 0 = normal; 1 = intra frame is requested;
	int lastIsocFrameNum;						// check for lost isoc frames
	int isocPacketSize;						// need to calculate usedBandwidth
	int usedBandwidth;						// used bandwidth 0-100%, need to set comprLevel
	int comprLevel;							// How strong (100) or weak (0) is compression
	int lastComprLevel;						// How strong (100) or weak (0) was compression
	int usb_bandwidth;						/* Mbit/s */

	/* /proc entries, relative to /proc/video/usbvision/ */
	struct proc_dir_entry *proc_devdir;		/* Per-device proc directory */
	struct proc_dir_entry *proc_info;		/* <minor#>/info entry */
	struct proc_dir_entry *proc_register;		/* <minor#>/register entry */
	struct proc_dir_entry *proc_freq; 		/* <minor#>/freq entry */
	struct proc_dir_entry *proc_input; 		/* <minor#>/input entry */
	struct proc_dir_entry *proc_frame;		/* <minor#>/frame entry */
	struct proc_dir_entry *proc_button;		/* <minor#>/button entry */
	struct proc_dir_entry *proc_control;		/* <minor#>/control entry */

	/* Statistics that can be overlayed on the screen */
	unsigned long isocUrbCount;			// How many URBs we received so far
	unsigned long urb_length;			/* Length of last URB */
	unsigned long isocDataCount;			/* How many bytes we received */
	unsigned long header_count;			/* How many frame headers we found */
	unsigned long scratch_ovf_count;		/* How many times we overflowed scratch */
	unsigned long isocSkipCount;			/* How many empty ISO packets received */
	unsigned long isocErrCount;			/* How many bad ISO packets received */
	unsigned long isocPacketCount;			// How many packets we totally got
	unsigned long timeInIrq;			// How long do we need for interrupt
	int isocMeasureBandwidthCount;
	int frame_num;					// How many video frames we send to user
	int maxStripLen;				// How big is the biggest strip
	int comprBlockPos;
	int stripLenErrors;				// How many times was BlockPos greater than StripLen
	int stripMagicErrors;
	int stripLineNumberErrors;
	int ComprBlockTypes[4];
};

#endif									/* __LINUX_USBVISION_H */

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */