1/*
2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
8 *
9 * Based on the previous version of the driver for 2.4 kernels by:
10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
11 */
12
13/*
14 * TODO:
15 * - remove "mark pages reserved-hacks" from memory allocation code
16 *   and implement nopage()
17 * - check decimation, calculating and reporting image size when
18 *   using decimation
19 * - implement read(), user mode buffers and overlay (?)
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/delay.h>
25#include <linux/dma-mapping.h>
26#include <linux/errno.h>
27#include <linux/fs.h>
28#include <linux/interrupt.h>
29#include <linux/kernel.h>
30#include <linux/mm.h>
31#include <linux/moduleparam.h>
32#include <linux/time.h>
33#include <linux/version.h>
34
35#ifdef CONFIG_KMOD
36#include <linux/kmod.h>
37#endif
38
39#include <linux/i2c.h>
40#include <linux/i2c-algo-sgi.h>
41
42#include <linux/videodev.h>
43#include <media/v4l2-common.h>
44#include <linux/video_decoder.h>
45#include <linux/mutex.h>
46
47#include <asm/paccess.h>
48#include <asm/io.h>
49#include <asm/sgi/ip22.h>
50#include <asm/sgi/mc.h>
51
52#include "vino.h"
53#include "saa7191.h"
54#include "indycam.h"
55
56/* Uncomment the following line to get lots and lots of (mostly useless)
57 * debug info.
58 * Note that the debug output also slows down the driver significantly */
59// #define VINO_DEBUG
60// #define VINO_DEBUG_INT
61
62#define VINO_MODULE_VERSION "0.0.5"
63#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)
64
65MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
66MODULE_VERSION(VINO_MODULE_VERSION);
67MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
68MODULE_LICENSE("GPL");
69
70#ifdef VINO_DEBUG
71#define dprintk(x...) printk("VINO: " x);
72#else
73#define dprintk(x...)
74#endif
75
76#define VINO_NO_CHANNEL			0
77#define VINO_CHANNEL_A			1
78#define VINO_CHANNEL_B			2
79
80#define VINO_PAL_WIDTH			768
81#define VINO_PAL_HEIGHT			576
82#define VINO_NTSC_WIDTH			640
83#define VINO_NTSC_HEIGHT		480
84
85#define VINO_MIN_WIDTH			32
86#define VINO_MIN_HEIGHT			32
87
88#define VINO_CLIPPING_START_ODD_D1	1
89#define VINO_CLIPPING_START_ODD_PAL	15
90#define VINO_CLIPPING_START_ODD_NTSC	12
91
92#define VINO_CLIPPING_START_EVEN_D1	2
93#define VINO_CLIPPING_START_EVEN_PAL	15
94#define VINO_CLIPPING_START_EVEN_NTSC	12
95
96#define VINO_INPUT_CHANNEL_COUNT	3
97
98/* the number is the index for vino_inputs */
99#define VINO_INPUT_NONE			-1
100#define VINO_INPUT_COMPOSITE		0
101#define VINO_INPUT_SVIDEO		1
102#define VINO_INPUT_D1			2
103
104#define VINO_PAGE_RATIO			(PAGE_SIZE / VINO_PAGE_SIZE)
105
106#define VINO_FIFO_THRESHOLD_DEFAULT	16
107
108#define VINO_FRAMEBUFFER_SIZE		((VINO_PAL_WIDTH \
109					  * VINO_PAL_HEIGHT * 4 \
110					  + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
111
112#define VINO_FRAMEBUFFER_COUNT_MAX	8
113
114#define VINO_FRAMEBUFFER_UNUSED		0
115#define VINO_FRAMEBUFFER_IN_USE		1
116#define VINO_FRAMEBUFFER_READY		2
117
118#define VINO_QUEUE_ERROR		-1
119#define VINO_QUEUE_MAGIC		0x20050125
120
121#define VINO_MEMORY_NONE		0
122#define VINO_MEMORY_MMAP		1
123#define VINO_MEMORY_USERPTR		2
124
125#define VINO_DUMMY_DESC_COUNT		4
126#define VINO_DESC_FETCH_DELAY		5	/* microseconds */
127
128#define VINO_MAX_FRAME_SKIP_COUNT	128
129
130/* the number is the index for vino_data_formats */
131#define VINO_DATA_FMT_NONE		-1
132#define VINO_DATA_FMT_GREY		0
133#define VINO_DATA_FMT_RGB332		1
134#define VINO_DATA_FMT_RGB32		2
135#define VINO_DATA_FMT_YUV		3
136
137#define VINO_DATA_FMT_COUNT		4
138
139/* the number is the index for vino_data_norms */
140#define VINO_DATA_NORM_NONE		-1
141#define VINO_DATA_NORM_NTSC		0
142#define VINO_DATA_NORM_PAL		1
143#define VINO_DATA_NORM_SECAM		2
144#define VINO_DATA_NORM_D1		3
145/* The following are special entries that can be used to
146 * autodetect the norm. */
147#define VINO_DATA_NORM_AUTO		0xfe
148#define VINO_DATA_NORM_AUTO_EXT		0xff
149
150#define VINO_DATA_NORM_COUNT		4
151
152/* Internal data structure definitions */
153
154struct vino_input {
155	char *name;
156	v4l2_std_id std;
157};
158
159struct vino_clipping {
160	unsigned int left, right, top, bottom;
161};
162
163struct vino_data_format {
164	/* the description */
165	char *description;
166	/* bytes per pixel */
167	unsigned int bpp;
168	/* V4L2 fourcc code */
169	__u32 pixelformat;
170	/* V4L2 colorspace (duh!) */
171	enum v4l2_colorspace colorspace;
172};
173
174struct vino_data_norm {
175	char *description;
176	unsigned int width, height;
177	struct vino_clipping odd;
178	struct vino_clipping even;
179
180	v4l2_std_id std;
181	unsigned int fps_min, fps_max;
182	__u32 framelines;
183};
184
185struct vino_descriptor_table {
186	/* the number of PAGE_SIZE sized pages in the buffer */
187	unsigned int page_count;
188	/* virtual (kmalloc'd) pointers to the actual data
189	 * (in PAGE_SIZE chunks, used with mmap streaming) */
190	unsigned long *virtual;
191
192	/* cpu address for the VINO descriptor table
193	 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
194	unsigned long *dma_cpu;
195	/* dma address for the VINO descriptor table
196	 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
197	dma_addr_t dma;
198};
199
200struct vino_framebuffer {
201	/* identifier nubmer */
202	unsigned int id;
203	/* the length of the whole buffer */
204	unsigned int size;
205	/* the length of actual data in buffer */
206	unsigned int data_size;
207	/* the data format */
208	unsigned int data_format;
209	/* the state of buffer data */
210	unsigned int state;
211	/* is the buffer mapped in user space? */
212	unsigned int map_count;
213	/* memory offset for mmap() */
214	unsigned int offset;
215	/* frame counter */
216	unsigned int frame_counter;
217	/* timestamp (written when image capture finishes) */
218	struct timeval timestamp;
219
220	struct vino_descriptor_table desc_table;
221
222	spinlock_t state_lock;
223};
224
225struct vino_framebuffer_fifo {
226	unsigned int length;
227
228	unsigned int used;
229	unsigned int head;
230	unsigned int tail;
231
232	unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
233};
234
235struct vino_framebuffer_queue {
236	unsigned int magic;
237
238	/* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
239	unsigned int type;
240	unsigned int length;
241
242	/* data field of in and out contain index numbers for buffer */
243	struct vino_framebuffer_fifo in;
244	struct vino_framebuffer_fifo out;
245
246	struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
247
248	spinlock_t queue_lock;
249	struct mutex queue_mutex;
250	wait_queue_head_t frame_wait_queue;
251};
252
253struct vino_interrupt_data {
254	struct timeval timestamp;
255	unsigned int frame_counter;
256	unsigned int skip_count;
257	unsigned int skip;
258};
259
260struct vino_channel_settings {
261	unsigned int channel;
262
263	int input;
264	unsigned int data_format;
265	unsigned int data_norm;
266	struct vino_clipping clipping;
267	unsigned int decimation;
268	unsigned int line_size;
269	unsigned int alpha;
270	unsigned int fps;
271	unsigned int framert_reg;
272
273	unsigned int fifo_threshold;
274
275	struct vino_framebuffer_queue fb_queue;
276
277	/* number of the current field */
278	unsigned int field;
279
280	/* read in progress */
281	int reading;
282	/* streaming is active */
283	int streaming;
284	/* the driver is currently processing the queue */
285	int capturing;
286
287	struct mutex mutex;
288	spinlock_t capture_lock;
289
290	unsigned int users;
291
292	struct vino_interrupt_data int_data;
293
294	/* V4L support */
295	struct video_device *v4l_device;
296};
297
298struct vino_client {
299	/* the channel which owns this client:
300	 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
301	unsigned int owner;
302	struct i2c_client *driver;
303};
304
305struct vino_settings {
306	struct vino_channel_settings a;
307	struct vino_channel_settings b;
308
309	struct vino_client decoder;
310	struct vino_client camera;
311
312	/* a lock for vino register access */
313	spinlock_t vino_lock;
314	/* a lock for channel input changes */
315	spinlock_t input_lock;
316
317	unsigned long dummy_page;
318	struct vino_descriptor_table dummy_desc_table;
319};
320
321/* Module parameters */
322
323/*
324 * Using vino_pixel_conversion the ABGR32-format pixels supplied
325 * by the VINO chip can be converted to more common formats
326 * like RGBA32 (or probably RGB24 in the future). This way we
327 * can give out data that can be specified correctly with
328 * the V4L2-definitions.
329 *
330 * The pixel format is specified as RGBA32 when no conversion
331 * is used.
332 *
333 * Note that this only affects the 32-bit bit depth.
334 *
335 * Use non-zero value to enable conversion.
336 */
337static int vino_pixel_conversion = 0;
338
339module_param_named(pixelconv, vino_pixel_conversion, int, 0);
340
341MODULE_PARM_DESC(pixelconv,
342		 "enable pixel conversion (non-zero value enables)");
343
344/* Internal data structures */
345
346static struct sgi_vino *vino;
347
348static struct vino_settings *vino_drvdata;
349
350static const char *vino_driver_name = "vino";
351static const char *vino_driver_description = "SGI VINO";
352static const char *vino_bus_name = "GIO64 bus";
353static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
354static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
355
356static void vino_capture_tasklet(unsigned long channel);
357
358DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
359DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
360
361static const struct vino_input vino_inputs[] = {
362	{
363		.name		= "Composite",
364		.std		= V4L2_STD_NTSC | V4L2_STD_PAL
365		| V4L2_STD_SECAM,
366	},{
367		.name		= "S-Video",
368		.std		= V4L2_STD_NTSC | V4L2_STD_PAL
369		| V4L2_STD_SECAM,
370	},{
371		.name		= "D1/IndyCam",
372		.std		= V4L2_STD_NTSC,
373	}
374};
375
376static const struct vino_data_format vino_data_formats[] = {
377	{
378		.description	= "8-bit greyscale",
379		.bpp		= 1,
380		.pixelformat	= V4L2_PIX_FMT_GREY,
381		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
382	},{
383		.description	= "8-bit dithered RGB 3-3-2",
384		.bpp		= 1,
385		.pixelformat	= V4L2_PIX_FMT_RGB332,
386		.colorspace	= V4L2_COLORSPACE_SRGB,
387	},{
388		.description	= "32-bit RGB",
389		.bpp		= 4,
390		.pixelformat	= V4L2_PIX_FMT_RGB32,
391		.colorspace	= V4L2_COLORSPACE_SRGB,
392	},{
393		.description	= "YUV 4:2:2",
394		.bpp		= 2,
395		.pixelformat	= V4L2_PIX_FMT_YUYV,
396		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
397	}
398};
399
400static const struct vino_data_norm vino_data_norms[] = {
401	{
402		.description	= "NTSC",
403		.std		= V4L2_STD_NTSC,
404		.fps_min	= 6,
405		.fps_max	= 30,
406		.framelines	= 525,
407		.width		= VINO_NTSC_WIDTH,
408		.height		= VINO_NTSC_HEIGHT,
409		.odd		= {
410			.top	= VINO_CLIPPING_START_ODD_NTSC,
411			.left	= 0,
412			.bottom	= VINO_CLIPPING_START_ODD_NTSC
413			+ VINO_NTSC_HEIGHT / 2 - 1,
414			.right	= VINO_NTSC_WIDTH,
415		},
416		.even		= {
417			.top	= VINO_CLIPPING_START_EVEN_NTSC,
418			.left	= 0,
419			.bottom	= VINO_CLIPPING_START_EVEN_NTSC
420			+ VINO_NTSC_HEIGHT / 2 - 1,
421			.right	= VINO_NTSC_WIDTH,
422		},
423	},{
424		.description	= "PAL",
425		.std		= V4L2_STD_PAL,
426		.fps_min	= 5,
427		.fps_max	= 25,
428		.framelines	= 625,
429		.width		= VINO_PAL_WIDTH,
430		.height		= VINO_PAL_HEIGHT,
431		.odd		= {
432			.top	= VINO_CLIPPING_START_ODD_PAL,
433			.left	= 0,
434			.bottom	= VINO_CLIPPING_START_ODD_PAL
435			+ VINO_PAL_HEIGHT / 2 - 1,
436			.right	= VINO_PAL_WIDTH,
437		},
438		.even		= {
439			.top	= VINO_CLIPPING_START_EVEN_PAL,
440			.left	= 0,
441			.bottom	= VINO_CLIPPING_START_EVEN_PAL
442			+ VINO_PAL_HEIGHT / 2 - 1,
443			.right	= VINO_PAL_WIDTH,
444		},
445	},{
446		.description	= "SECAM",
447		.std		= V4L2_STD_SECAM,
448		.fps_min	= 5,
449		.fps_max	= 25,
450		.framelines	= 625,
451		.width		= VINO_PAL_WIDTH,
452		.height		= VINO_PAL_HEIGHT,
453		.odd		= {
454			.top	= VINO_CLIPPING_START_ODD_PAL,
455			.left	= 0,
456			.bottom	= VINO_CLIPPING_START_ODD_PAL
457			+ VINO_PAL_HEIGHT / 2 - 1,
458			.right	= VINO_PAL_WIDTH,
459		},
460		.even		= {
461			.top	= VINO_CLIPPING_START_EVEN_PAL,
462			.left	= 0,
463			.bottom	= VINO_CLIPPING_START_EVEN_PAL
464			+ VINO_PAL_HEIGHT / 2 - 1,
465			.right	= VINO_PAL_WIDTH,
466		},
467	},{
468		.description	= "NTSC/D1",
469		.std		= V4L2_STD_NTSC,
470		.fps_min	= 6,
471		.fps_max	= 30,
472		.framelines	= 525,
473		.width		= VINO_NTSC_WIDTH,
474		.height		= VINO_NTSC_HEIGHT,
475		.odd		= {
476			.top	= VINO_CLIPPING_START_ODD_D1,
477			.left	= 0,
478			.bottom	= VINO_CLIPPING_START_ODD_D1
479			+ VINO_NTSC_HEIGHT / 2 - 1,
480			.right	= VINO_NTSC_WIDTH,
481		},
482		.even		= {
483			.top	= VINO_CLIPPING_START_EVEN_D1,
484			.left	= 0,
485			.bottom	= VINO_CLIPPING_START_EVEN_D1
486			+ VINO_NTSC_HEIGHT / 2 - 1,
487			.right	= VINO_NTSC_WIDTH,
488		},
489	}
490};
491
492#define VINO_INDYCAM_V4L2_CONTROL_COUNT		9
493
494struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
495	{
496		.id = V4L2_CID_AUTOGAIN,
497		.type = V4L2_CTRL_TYPE_BOOLEAN,
498		.name = "Automatic Gain Control",
499		.minimum = 0,
500		.maximum = 1,
501		.step = 1,
502		.default_value = INDYCAM_AGC_DEFAULT,
503		.flags = 0,
504		.reserved = { INDYCAM_CONTROL_AGC, 0 },
505	},{
506		.id = V4L2_CID_AUTO_WHITE_BALANCE,
507		.type = V4L2_CTRL_TYPE_BOOLEAN,
508		.name = "Automatic White Balance",
509		.minimum = 0,
510		.maximum = 1,
511		.step = 1,
512		.default_value = INDYCAM_AWB_DEFAULT,
513		.flags = 0,
514		.reserved = { INDYCAM_CONTROL_AWB, 0 },
515	},{
516		.id = V4L2_CID_GAIN,
517		.type = V4L2_CTRL_TYPE_INTEGER,
518		.name = "Gain",
519		.minimum = INDYCAM_GAIN_MIN,
520		.maximum = INDYCAM_GAIN_MAX,
521		.step = 1,
522		.default_value = INDYCAM_GAIN_DEFAULT,
523		.flags = 0,
524		.reserved = { INDYCAM_CONTROL_GAIN, 0 },
525	},{
526		.id = V4L2_CID_PRIVATE_BASE,
527		.type = V4L2_CTRL_TYPE_INTEGER,
528		.name = "Red Saturation",
529		.minimum = INDYCAM_RED_SATURATION_MIN,
530		.maximum = INDYCAM_RED_SATURATION_MAX,
531		.step = 1,
532		.default_value = INDYCAM_RED_SATURATION_DEFAULT,
533		.flags = 0,
534		.reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
535	},{
536		.id = V4L2_CID_PRIVATE_BASE + 1,
537		.type = V4L2_CTRL_TYPE_INTEGER,
538		.name = "Blue Saturation",
539		.minimum = INDYCAM_BLUE_SATURATION_MIN,
540		.maximum = INDYCAM_BLUE_SATURATION_MAX,
541		.step = 1,
542		.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
543		.flags = 0,
544		.reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
545	},{
546		.id = V4L2_CID_RED_BALANCE,
547		.type = V4L2_CTRL_TYPE_INTEGER,
548		.name = "Red Balance",
549		.minimum = INDYCAM_RED_BALANCE_MIN,
550		.maximum = INDYCAM_RED_BALANCE_MAX,
551		.step = 1,
552		.default_value = INDYCAM_RED_BALANCE_DEFAULT,
553		.flags = 0,
554		.reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
555	},{
556		.id = V4L2_CID_BLUE_BALANCE,
557		.type = V4L2_CTRL_TYPE_INTEGER,
558		.name = "Blue Balance",
559		.minimum = INDYCAM_BLUE_BALANCE_MIN,
560		.maximum = INDYCAM_BLUE_BALANCE_MAX,
561		.step = 1,
562		.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
563		.flags = 0,
564		.reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
565	},{
566		.id = V4L2_CID_EXPOSURE,
567		.type = V4L2_CTRL_TYPE_INTEGER,
568		.name = "Shutter Control",
569		.minimum = INDYCAM_SHUTTER_MIN,
570		.maximum = INDYCAM_SHUTTER_MAX,
571		.step = 1,
572		.default_value = INDYCAM_SHUTTER_DEFAULT,
573		.flags = 0,
574		.reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
575	},{
576		.id = V4L2_CID_GAMMA,
577		.type = V4L2_CTRL_TYPE_INTEGER,
578		.name = "Gamma",
579		.minimum = INDYCAM_GAMMA_MIN,
580		.maximum = INDYCAM_GAMMA_MAX,
581		.step = 1,
582		.default_value = INDYCAM_GAMMA_DEFAULT,
583		.flags = 0,
584		.reserved = { INDYCAM_CONTROL_GAMMA, 0 },
585	}
586};
587
588#define VINO_SAA7191_V4L2_CONTROL_COUNT		9
589
590struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
591	{
592		.id = V4L2_CID_HUE,
593		.type = V4L2_CTRL_TYPE_INTEGER,
594		.name = "Hue",
595		.minimum = SAA7191_HUE_MIN,
596		.maximum = SAA7191_HUE_MAX,
597		.step = 1,
598		.default_value = SAA7191_HUE_DEFAULT,
599		.flags = 0,
600		.reserved = { SAA7191_CONTROL_HUE, 0 },
601	},{
602		.id = V4L2_CID_PRIVATE_BASE,
603		.type = V4L2_CTRL_TYPE_INTEGER,
604		.name = "Luminance Bandpass",
605		.minimum = SAA7191_BANDPASS_MIN,
606		.maximum = SAA7191_BANDPASS_MAX,
607		.step = 1,
608		.default_value = SAA7191_BANDPASS_DEFAULT,
609		.flags = 0,
610		.reserved = { SAA7191_CONTROL_BANDPASS, 0 },
611	},{
612		.id = V4L2_CID_PRIVATE_BASE + 1,
613		.type = V4L2_CTRL_TYPE_INTEGER,
614		.name = "Luminance Bandpass Weight",
615		.minimum = SAA7191_BANDPASS_WEIGHT_MIN,
616		.maximum = SAA7191_BANDPASS_WEIGHT_MAX,
617		.step = 1,
618		.default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
619		.flags = 0,
620		.reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
621	},{
622		.id = V4L2_CID_PRIVATE_BASE + 2,
623		.type = V4L2_CTRL_TYPE_INTEGER,
624		.name = "HF Luminance Coring",
625		.minimum = SAA7191_CORING_MIN,
626		.maximum = SAA7191_CORING_MAX,
627		.step = 1,
628		.default_value = SAA7191_CORING_DEFAULT,
629		.flags = 0,
630		.reserved = { SAA7191_CONTROL_CORING, 0 },
631	},{
632		.id = V4L2_CID_PRIVATE_BASE + 3,
633		.type = V4L2_CTRL_TYPE_BOOLEAN,
634		.name = "Force Colour",
635		.minimum = SAA7191_FORCE_COLOUR_MIN,
636		.maximum = SAA7191_FORCE_COLOUR_MAX,
637		.step = 1,
638		.default_value = SAA7191_FORCE_COLOUR_DEFAULT,
639		.flags = 0,
640		.reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
641	},{
642		.id = V4L2_CID_PRIVATE_BASE + 4,
643		.type = V4L2_CTRL_TYPE_INTEGER,
644		.name = "Chrominance Gain Control",
645		.minimum = SAA7191_CHROMA_GAIN_MIN,
646		.maximum = SAA7191_CHROMA_GAIN_MAX,
647		.step = 1,
648		.default_value = SAA7191_CHROMA_GAIN_DEFAULT,
649		.flags = 0,
650		.reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
651	},{
652		.id = V4L2_CID_PRIVATE_BASE + 5,
653		.type = V4L2_CTRL_TYPE_BOOLEAN,
654		.name = "VTR Time Constant",
655		.minimum = SAA7191_VTRC_MIN,
656		.maximum = SAA7191_VTRC_MAX,
657		.step = 1,
658		.default_value = SAA7191_VTRC_DEFAULT,
659		.flags = 0,
660		.reserved = { SAA7191_CONTROL_VTRC, 0 },
661	},{
662		.id = V4L2_CID_PRIVATE_BASE + 6,
663		.type = V4L2_CTRL_TYPE_INTEGER,
664		.name = "Luminance Delay Compensation",
665		.minimum = SAA7191_LUMA_DELAY_MIN,
666		.maximum = SAA7191_LUMA_DELAY_MAX,
667		.step = 1,
668		.default_value = SAA7191_LUMA_DELAY_DEFAULT,
669		.flags = 0,
670		.reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
671	},{
672		.id = V4L2_CID_PRIVATE_BASE + 7,
673		.type = V4L2_CTRL_TYPE_INTEGER,
674		.name = "Vertical Noise Reduction",
675		.minimum = SAA7191_VNR_MIN,
676		.maximum = SAA7191_VNR_MAX,
677		.step = 1,
678		.default_value = SAA7191_VNR_DEFAULT,
679		.flags = 0,
680		.reserved = { SAA7191_CONTROL_VNR, 0 },
681	}
682};
683
684/* VINO I2C bus functions */
685
686unsigned i2c_vino_getctrl(void *data)
687{
688	return vino->i2c_control;
689}
690
691void i2c_vino_setctrl(void *data, unsigned val)
692{
693	vino->i2c_control = val;
694}
695
696unsigned i2c_vino_rdata(void *data)
697{
698	return vino->i2c_data;
699}
700
701void i2c_vino_wdata(void *data, unsigned val)
702{
703	vino->i2c_data = val;
704}
705
706static struct i2c_algo_sgi_data i2c_sgi_vino_data =
707{
708	.getctrl = &i2c_vino_getctrl,
709	.setctrl = &i2c_vino_setctrl,
710	.rdata   = &i2c_vino_rdata,
711	.wdata   = &i2c_vino_wdata,
712	.xfer_timeout = 200,
713	.ack_timeout  = 1000,
714};
715
716/*
717 * There are two possible clients on VINO I2C bus, so we limit usage only
718 * to them.
719 */
720static int i2c_vino_client_reg(struct i2c_client *client)
721{
722	unsigned long flags;
723	int ret = 0;
724
725	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
726	switch (client->driver->id) {
727	case I2C_DRIVERID_SAA7191:
728		if (vino_drvdata->decoder.driver)
729			ret = -EBUSY;
730		else
731			vino_drvdata->decoder.driver = client;
732		break;
733	case I2C_DRIVERID_INDYCAM:
734		if (vino_drvdata->camera.driver)
735			ret = -EBUSY;
736		else
737			vino_drvdata->camera.driver = client;
738		break;
739	default:
740		ret = -ENODEV;
741	}
742	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
743
744	return ret;
745}
746
747static int i2c_vino_client_unreg(struct i2c_client *client)
748{
749	unsigned long flags;
750	int ret = 0;
751
752	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
753	if (client == vino_drvdata->decoder.driver) {
754		if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
755			ret = -EBUSY;
756		else
757			vino_drvdata->decoder.driver = NULL;
758	} else if (client == vino_drvdata->camera.driver) {
759		if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
760			ret = -EBUSY;
761		else
762			vino_drvdata->camera.driver = NULL;
763	}
764	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
765
766	return ret;
767}
768
769static struct i2c_adapter vino_i2c_adapter =
770{
771	.name			= "VINO I2C bus",
772	.id			= I2C_HW_SGI_VINO,
773	.algo_data		= &i2c_sgi_vino_data,
774	.client_register	= &i2c_vino_client_reg,
775	.client_unregister	= &i2c_vino_client_unreg,
776};
777
778static int vino_i2c_add_bus(void)
779{
780	return i2c_sgi_add_bus(&vino_i2c_adapter);
781}
782
783static int vino_i2c_del_bus(void)
784{
785	return i2c_del_adapter(&vino_i2c_adapter);
786}
787
788static int i2c_camera_command(unsigned int cmd, void *arg)
789{
790	return vino_drvdata->camera.driver->
791		driver->command(vino_drvdata->camera.driver,
792				cmd, arg);
793}
794
795static int i2c_decoder_command(unsigned int cmd, void *arg)
796{
797	return vino_drvdata->decoder.driver->
798		driver->command(vino_drvdata->decoder.driver,
799				cmd, arg);
800}
801
802/* VINO framebuffer/DMA descriptor management */
803
804static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
805					       unsigned int count)
806{
807	unsigned int i;
808
809	dprintk("vino_free_buffer_with_count(): count = %d\n", count);
810
811	for (i = 0; i < count; i++) {
812		ClearPageReserved(virt_to_page(fb->desc_table.virtual[i]));
813		dma_unmap_single(NULL,
814				 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
815				 PAGE_SIZE, DMA_FROM_DEVICE);
816		free_page(fb->desc_table.virtual[i]);
817	}
818
819	dma_free_coherent(NULL,
820			  VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
821			  sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
822			  fb->desc_table.dma);
823	kfree(fb->desc_table.virtual);
824
825	memset(fb, 0, sizeof(struct vino_framebuffer));
826}
827
828static void vino_free_buffer(struct vino_framebuffer *fb)
829{
830	vino_free_buffer_with_count(fb, fb->desc_table.page_count);
831}
832
833static int vino_allocate_buffer(struct vino_framebuffer *fb,
834				unsigned int size)
835{
836	unsigned int count, i, j;
837	int ret = 0;
838
839	dprintk("vino_allocate_buffer():\n");
840
841	if (size < 1)
842		return -EINVAL;
843
844	memset(fb, 0, sizeof(struct vino_framebuffer));
845
846	count = ((size / PAGE_SIZE) + 4) & ~3;
847
848	dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
849		size, count);
850
851	/* allocate memory for table with virtual (page) addresses */
852	fb->desc_table.virtual = (unsigned long *)
853		kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
854	if (!fb->desc_table.virtual)
855		return -ENOMEM;
856
857	/* allocate memory for table with dma addresses
858	 * (has space for four extra descriptors) */
859	fb->desc_table.dma_cpu =
860		dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
861				   sizeof(dma_addr_t), &fb->desc_table.dma,
862				   GFP_KERNEL | GFP_DMA);
863	if (!fb->desc_table.dma_cpu) {
864		ret = -ENOMEM;
865		goto out_free_virtual;
866	}
867
868	/* allocate pages for the buffer and acquire the according
869	 * dma addresses */
870	for (i = 0; i < count; i++) {
871		dma_addr_t dma_data_addr;
872
873		fb->desc_table.virtual[i] =
874			get_zeroed_page(GFP_KERNEL | GFP_DMA);
875		if (!fb->desc_table.virtual[i]) {
876			ret = -ENOBUFS;
877			break;
878		}
879
880		dma_data_addr =
881			dma_map_single(NULL,
882				       (void *)fb->desc_table.virtual[i],
883				       PAGE_SIZE, DMA_FROM_DEVICE);
884
885		for (j = 0; j < VINO_PAGE_RATIO; j++) {
886			fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
887				dma_data_addr + VINO_PAGE_SIZE * j;
888		}
889
890		SetPageReserved(virt_to_page(fb->desc_table.virtual[i]));
891	}
892
893	/* page_count needs to be set anyway, because the descriptor table has
894	 * been allocated according to this number */
895	fb->desc_table.page_count = count;
896
897	if (ret) {
898		/* the descriptor with index i doesn't contain
899		 * a valid address yet */
900		vino_free_buffer_with_count(fb, i);
901		return ret;
902	}
903
904	//fb->size = size;
905	fb->size = count * PAGE_SIZE;
906	fb->data_format = VINO_DATA_FMT_NONE;
907
908	/* set the dma stop-bit for the last (count+1)th descriptor */
909	fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
910	return 0;
911
912 out_free_virtual:
913	kfree(fb->desc_table.virtual);
914	return ret;
915}
916
917
918static void vino_sync_buffer(struct vino_framebuffer *fb)
919{
920	int i;
921
922	dprintk("vino_sync_buffer():\n");
923
924	for (i = 0; i < fb->desc_table.page_count; i++)
925		dma_sync_single(NULL,
926				fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
927				PAGE_SIZE, DMA_FROM_DEVICE);
928}
929
930/* Framebuffer fifo functions (need to be locked externally) */
931
932static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
933			   unsigned int length)
934{
935	f->length = 0;
936	f->used = 0;
937	f->head = 0;
938	f->tail = 0;
939
940	if (length > VINO_FRAMEBUFFER_COUNT_MAX)
941		length = VINO_FRAMEBUFFER_COUNT_MAX;
942
943	f->length = length;
944}
945
946/* returns true/false */
947static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
948				   unsigned int id)
949{
950	unsigned int i;
951
952	for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
953		if (f->data[i] == id)
954			return 1;
955	}
956
957	return 0;
958}
959
960
961static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
962{
963	return f->used;
964}
965
966static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
967{
968	if (id >= f->length) {
969		return VINO_QUEUE_ERROR;
970	}
971
972	if (vino_fifo_has_id(f, id)) {
973		return VINO_QUEUE_ERROR;
974	}
975
976	if (f->used < f->length) {
977		f->data[f->tail] = id;
978		f->tail = (f->tail + 1) % f->length;
979		f->used++;
980	} else {
981		return VINO_QUEUE_ERROR;
982	}
983
984	return 0;
985}
986
987static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
988{
989	if (f->used > 0) {
990		*id = f->data[f->head];
991	} else {
992		return VINO_QUEUE_ERROR;
993	}
994
995	return 0;
996}
997
998static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
999{
1000	if (f->used > 0) {
1001		*id = f->data[f->head];
1002		f->head = (f->head + 1) % f->length;
1003		f->used--;
1004	} else {
1005		return VINO_QUEUE_ERROR;
1006	}
1007
1008	return 0;
1009}
1010
1011/* Framebuffer queue functions */
1012
1013/* execute with queue_lock locked */
1014static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
1015				       unsigned int length)
1016{
1017	unsigned int i;
1018
1019	q->length = 0;
1020	memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
1021	memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
1022	for (i = 0; i < length; i++) {
1023		dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
1024			i);
1025		vino_free_buffer(q->buffer[i]);
1026		kfree(q->buffer[i]);
1027	}
1028
1029	q->type = VINO_MEMORY_NONE;
1030	q->magic = 0;
1031}
1032
1033static void vino_queue_free(struct vino_framebuffer_queue *q)
1034{
1035	dprintk("vino_queue_free():\n");
1036
1037	if (q->magic != VINO_QUEUE_MAGIC)
1038		return;
1039	if (q->type != VINO_MEMORY_MMAP)
1040		return;
1041
1042	mutex_lock(&q->queue_mutex);
1043
1044	vino_queue_free_with_count(q, q->length);
1045
1046	mutex_unlock(&q->queue_mutex);
1047}
1048
1049static int vino_queue_init(struct vino_framebuffer_queue *q,
1050			   unsigned int *length)
1051{
1052	unsigned int i;
1053	int ret = 0;
1054
1055	dprintk("vino_queue_init(): length = %d\n", *length);
1056
1057	if (q->magic == VINO_QUEUE_MAGIC) {
1058		dprintk("vino_queue_init(): queue already initialized!\n");
1059		return -EINVAL;
1060	}
1061
1062	if (q->type != VINO_MEMORY_NONE) {
1063		dprintk("vino_queue_init(): queue already initialized!\n");
1064		return -EINVAL;
1065	}
1066
1067	if (*length < 1)
1068		return -EINVAL;
1069
1070	mutex_lock(&q->queue_mutex);
1071
1072	if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
1073		*length = VINO_FRAMEBUFFER_COUNT_MAX;
1074
1075	q->length = 0;
1076
1077	for (i = 0; i < *length; i++) {
1078		dprintk("vino_queue_init(): allocating buffer %d\n", i);
1079		q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
1080				       GFP_KERNEL);
1081		if (!q->buffer[i]) {
1082			dprintk("vino_queue_init(): kmalloc() failed\n");
1083			ret = -ENOMEM;
1084			break;
1085		}
1086
1087		ret = vino_allocate_buffer(q->buffer[i],
1088					   VINO_FRAMEBUFFER_SIZE);
1089		if (ret) {
1090			kfree(q->buffer[i]);
1091			dprintk("vino_queue_init(): "
1092				"vino_allocate_buffer() failed\n");
1093			break;
1094		}
1095
1096		q->buffer[i]->id = i;
1097		if (i > 0) {
1098			q->buffer[i]->offset = q->buffer[i - 1]->offset +
1099				q->buffer[i - 1]->size;
1100		} else {
1101			q->buffer[i]->offset = 0;
1102		}
1103
1104		spin_lock_init(&q->buffer[i]->state_lock);
1105
1106		dprintk("vino_queue_init(): buffer = %d, offset = %d, "
1107			"size = %d\n", i, q->buffer[i]->offset,
1108			q->buffer[i]->size);
1109	}
1110
1111	if (ret) {
1112		vino_queue_free_with_count(q, i);
1113		*length = 0;
1114	} else {
1115		q->length = *length;
1116		vino_fifo_init(&q->in, q->length);
1117		vino_fifo_init(&q->out, q->length);
1118		q->type = VINO_MEMORY_MMAP;
1119		q->magic = VINO_QUEUE_MAGIC;
1120	}
1121
1122	mutex_unlock(&q->queue_mutex);
1123
1124	return ret;
1125}
1126
1127static struct vino_framebuffer *vino_queue_add(struct
1128					       vino_framebuffer_queue *q,
1129					       unsigned int id)
1130{
1131	struct vino_framebuffer *ret = NULL;
1132	unsigned int total;
1133	unsigned long flags;
1134
1135	dprintk("vino_queue_add(): id = %d\n", id);
1136
1137	if (q->magic != VINO_QUEUE_MAGIC) {
1138		return ret;
1139	}
1140
1141	spin_lock_irqsave(&q->queue_lock, flags);
1142
1143	if (q->length == 0)
1144		goto out;
1145
1146	if (id >= q->length)
1147		goto out;
1148
1149	/* not needed?: if (vino_fifo_full(&q->out)) {
1150		goto out;
1151		}*/
1152	/* check that outgoing queue isn't already full
1153	 * (or that it won't become full) */
1154	total = vino_fifo_get_used(&q->in) +
1155		vino_fifo_get_used(&q->out);
1156	if (total >= q->length)
1157		goto out;
1158
1159	if (vino_fifo_enqueue(&q->in, id))
1160		goto out;
1161
1162	ret = q->buffer[id];
1163
1164out:
1165	spin_unlock_irqrestore(&q->queue_lock, flags);
1166
1167	return ret;
1168}
1169
1170static struct vino_framebuffer *vino_queue_transfer(struct
1171						    vino_framebuffer_queue *q)
1172{
1173	struct vino_framebuffer *ret = NULL;
1174	struct vino_framebuffer *fb;
1175	int id;
1176	unsigned long flags;
1177
1178	dprintk("vino_queue_transfer():\n");
1179
1180	if (q->magic != VINO_QUEUE_MAGIC) {
1181		return ret;
1182	}
1183
1184	spin_lock_irqsave(&q->queue_lock, flags);
1185
1186	if (q->length == 0)
1187		goto out;
1188
1189	// now this actually removes an entry from the incoming queue
1190	if (vino_fifo_dequeue(&q->in, &id)) {
1191		goto out;
1192	}
1193
1194	dprintk("vino_queue_transfer(): id = %d\n", id);
1195	fb = q->buffer[id];
1196
1197	// we have already checked that the outgoing queue is not full, but...
1198	if (vino_fifo_enqueue(&q->out, id)) {
1199		printk(KERN_ERR "vino_queue_transfer(): "
1200		       "outgoing queue is full, this shouldn't happen!\n");
1201		goto out;
1202	}
1203
1204	ret = fb;
1205out:
1206	spin_unlock_irqrestore(&q->queue_lock, flags);
1207
1208	return ret;
1209}
1210
1211/* returns true/false */
1212static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1213					unsigned int id)
1214{
1215	int ret = 0;
1216	unsigned long flags;
1217
1218	if (q->magic != VINO_QUEUE_MAGIC) {
1219		return ret;
1220	}
1221
1222	spin_lock_irqsave(&q->queue_lock, flags);
1223
1224	if (q->length == 0)
1225		goto out;
1226
1227	ret = vino_fifo_has_id(&q->in, id);
1228
1229out:
1230	spin_unlock_irqrestore(&q->queue_lock, flags);
1231
1232	return ret;
1233}
1234
1235/* returns true/false */
1236static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1237					unsigned int id)
1238{
1239	int ret = 0;
1240	unsigned long flags;
1241
1242	if (q->magic != VINO_QUEUE_MAGIC) {
1243		return ret;
1244	}
1245
1246	spin_lock_irqsave(&q->queue_lock, flags);
1247
1248	if (q->length == 0)
1249		goto out;
1250
1251	ret = vino_fifo_has_id(&q->out, id);
1252
1253out:
1254	spin_unlock_irqrestore(&q->queue_lock, flags);
1255
1256	return ret;
1257}
1258
1259static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
1260				   unsigned int *used)
1261{
1262	int ret = 0;
1263	unsigned long flags;
1264
1265	if (q->magic != VINO_QUEUE_MAGIC) {
1266		return VINO_QUEUE_ERROR;
1267	}
1268
1269	spin_lock_irqsave(&q->queue_lock, flags);
1270
1271	if (q->length == 0) {
1272		ret = VINO_QUEUE_ERROR;
1273		goto out;
1274	}
1275
1276	*used = vino_fifo_get_used(&q->in);
1277
1278out:
1279	spin_unlock_irqrestore(&q->queue_lock, flags);
1280
1281	return ret;
1282}
1283
1284static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
1285				   unsigned int *used)
1286{
1287	int ret = 0;
1288	unsigned long flags;
1289
1290	if (q->magic != VINO_QUEUE_MAGIC) {
1291		return VINO_QUEUE_ERROR;
1292	}
1293
1294	spin_lock_irqsave(&q->queue_lock, flags);
1295
1296	if (q->length == 0) {
1297		ret = VINO_QUEUE_ERROR;
1298		goto out;
1299	}
1300
1301	*used = vino_fifo_get_used(&q->out);
1302
1303out:
1304	spin_unlock_irqrestore(&q->queue_lock, flags);
1305
1306	return ret;
1307}
1308
1309
1310static struct vino_framebuffer *vino_queue_peek(struct
1311						vino_framebuffer_queue *q,
1312						unsigned int *id)
1313{
1314	struct vino_framebuffer *ret = NULL;
1315	unsigned long flags;
1316
1317	if (q->magic != VINO_QUEUE_MAGIC) {
1318		return ret;
1319	}
1320
1321	spin_lock_irqsave(&q->queue_lock, flags);
1322
1323	if (q->length == 0)
1324		goto out;
1325
1326	if (vino_fifo_peek(&q->in, id)) {
1327		goto out;
1328	}
1329
1330	ret = q->buffer[*id];
1331out:
1332	spin_unlock_irqrestore(&q->queue_lock, flags);
1333
1334	return ret;
1335}
1336
1337static struct vino_framebuffer *vino_queue_remove(struct
1338						  vino_framebuffer_queue *q,
1339						  unsigned int *id)
1340{
1341	struct vino_framebuffer *ret = NULL;
1342	unsigned long flags;
1343	dprintk("vino_queue_remove():\n");
1344
1345	if (q->magic != VINO_QUEUE_MAGIC) {
1346		return ret;
1347	}
1348
1349	spin_lock_irqsave(&q->queue_lock, flags);
1350
1351	if (q->length == 0)
1352		goto out;
1353
1354	if (vino_fifo_dequeue(&q->out, id)) {
1355		goto out;
1356	}
1357
1358	dprintk("vino_queue_remove(): id = %d\n", *id);
1359	ret = q->buffer[*id];
1360out:
1361	spin_unlock_irqrestore(&q->queue_lock, flags);
1362
1363	return ret;
1364}
1365
1366static struct
1367vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1368					unsigned int id)
1369{
1370	struct vino_framebuffer *ret = NULL;
1371	unsigned long flags;
1372
1373	if (q->magic != VINO_QUEUE_MAGIC) {
1374		return ret;
1375	}
1376
1377	spin_lock_irqsave(&q->queue_lock, flags);
1378
1379	if (q->length == 0)
1380		goto out;
1381
1382	if (id >= q->length)
1383		goto out;
1384
1385	ret = q->buffer[id];
1386 out:
1387	spin_unlock_irqrestore(&q->queue_lock, flags);
1388
1389	return ret;
1390}
1391
1392static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
1393{
1394	unsigned int length = 0;
1395	unsigned long flags;
1396
1397	if (q->magic != VINO_QUEUE_MAGIC) {
1398		return length;
1399	}
1400
1401	spin_lock_irqsave(&q->queue_lock, flags);
1402	length = q->length;
1403	spin_unlock_irqrestore(&q->queue_lock, flags);
1404
1405	return length;
1406}
1407
1408static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1409{
1410	unsigned int i;
1411	int ret = 0;
1412	unsigned long flags;
1413
1414	if (q->magic != VINO_QUEUE_MAGIC) {
1415		return ret;
1416	}
1417
1418	spin_lock_irqsave(&q->queue_lock, flags);
1419	for (i = 0; i < q->length; i++) {
1420		if (q->buffer[i]->map_count > 0) {
1421			ret = 1;
1422			break;
1423		}
1424	}
1425	spin_unlock_irqrestore(&q->queue_lock, flags);
1426
1427	return ret;
1428}
1429
1430/* VINO functions */
1431
1432/* execute with input_lock locked */
1433static void vino_update_line_size(struct vino_channel_settings *vcs)
1434{
1435	unsigned int w = vcs->clipping.right - vcs->clipping.left;
1436	unsigned int d = vcs->decimation;
1437	unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
1438	unsigned int lsize;
1439
1440	dprintk("update_line_size(): before: w = %d, d = %d, "
1441		"line_size = %d\n", w, d, vcs->line_size);
1442
1443	/* line size must be multiple of 8 bytes */
1444	lsize = (bpp * (w / d)) & ~7;
1445	w = (lsize / bpp) * d;
1446
1447	vcs->clipping.right = vcs->clipping.left + w;
1448	vcs->line_size = lsize;
1449
1450	dprintk("update_line_size(): after: w = %d, d = %d, "
1451		"line_size = %d\n", w, d, vcs->line_size);
1452}
1453
1454/* execute with input_lock locked */
1455static void vino_set_clipping(struct vino_channel_settings *vcs,
1456			      unsigned int x, unsigned int y,
1457			      unsigned int w, unsigned int h)
1458{
1459	unsigned int maxwidth, maxheight;
1460	unsigned int d;
1461
1462	maxwidth = vino_data_norms[vcs->data_norm].width;
1463	maxheight = vino_data_norms[vcs->data_norm].height;
1464	d = vcs->decimation;
1465
1466	y &= ~1;	/* odd/even fields */
1467
1468	if (x > maxwidth) {
1469		x = 0;
1470	}
1471	if (y > maxheight) {
1472		y = 0;
1473	}
1474
1475	if (((w / d) < VINO_MIN_WIDTH)
1476	    || ((h / d) < VINO_MIN_HEIGHT)) {
1477		w = VINO_MIN_WIDTH * d;
1478		h = VINO_MIN_HEIGHT * d;
1479	}
1480
1481	if ((x + w) > maxwidth) {
1482		w = maxwidth - x;
1483		if ((w / d) < VINO_MIN_WIDTH)
1484			x = maxwidth - VINO_MIN_WIDTH * d;
1485	}
1486	if ((y + h) > maxheight) {
1487		h = maxheight - y;
1488		if ((h / d) < VINO_MIN_HEIGHT)
1489			y = maxheight - VINO_MIN_HEIGHT * d;
1490	}
1491
1492	vcs->clipping.left = x;
1493	vcs->clipping.top = y;
1494	vcs->clipping.right = x + w;
1495	vcs->clipping.bottom = y + h;
1496
1497	vino_update_line_size(vcs);
1498
1499	dprintk("clipping %d, %d, %d, %d / %d - %d\n",
1500		vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
1501		vcs->clipping.bottom, vcs->decimation, vcs->line_size);
1502}
1503
1504/* execute with input_lock locked */
1505static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
1506{
1507	vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1508			  vino_data_norms[vcs->data_norm].height);
1509}
1510
1511/* execute with input_lock locked */
1512static void vino_set_scaling(struct vino_channel_settings *vcs,
1513			     unsigned int w, unsigned int h)
1514{
1515	unsigned int x, y, curw, curh, d;
1516
1517	x = vcs->clipping.left;
1518	y = vcs->clipping.top;
1519	curw = vcs->clipping.right - vcs->clipping.left;
1520	curh = vcs->clipping.bottom - vcs->clipping.top;
1521
1522	d = max(curw / w, curh / h);
1523
1524	dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
1525		w, h, curw, curh, d);
1526
1527	if (d < 1) {
1528		d = 1;
1529	} else if (d > 8) {
1530		d = 8;
1531	}
1532
1533	vcs->decimation = d;
1534	vino_set_clipping(vcs, x, y, w * d, h * d);
1535
1536	dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
1537		vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
1538		vcs->decimation, vcs->line_size);
1539}
1540
1541/* execute with input_lock locked */
1542static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
1543{
1544	vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1545			 vcs->clipping.bottom - vcs->clipping.top);
1546}
1547
1548/* execute with input_lock locked */
1549static void vino_set_framerate(struct vino_channel_settings *vcs,
1550			       unsigned int fps)
1551{
1552	unsigned int mask;
1553
1554	switch (vcs->data_norm) {
1555	case VINO_DATA_NORM_NTSC:
1556	case VINO_DATA_NORM_D1:
1557		fps = (unsigned int)(fps / 6) * 6;
1558
1559		if (fps < vino_data_norms[vcs->data_norm].fps_min)
1560			fps = vino_data_norms[vcs->data_norm].fps_min;
1561		if (fps > vino_data_norms[vcs->data_norm].fps_max)
1562			fps = vino_data_norms[vcs->data_norm].fps_max;
1563
1564		switch (fps) {
1565		case 6:
1566			mask = 0x003;
1567			break;
1568		case 12:
1569			mask = 0x0c3;
1570			break;
1571		case 18:
1572			mask = 0x333;
1573			break;
1574		case 24:
1575			mask = 0x3ff;
1576			break;
1577		case 30:
1578			mask = 0xfff;
1579			break;
1580		default:
1581			mask = VINO_FRAMERT_FULL;
1582		}
1583		vcs->framert_reg = VINO_FRAMERT_RT(mask);
1584		break;
1585	case VINO_DATA_NORM_PAL:
1586	case VINO_DATA_NORM_SECAM:
1587		fps = (unsigned int)(fps / 5) * 5;
1588
1589		if (fps < vino_data_norms[vcs->data_norm].fps_min)
1590			fps = vino_data_norms[vcs->data_norm].fps_min;
1591		if (fps > vino_data_norms[vcs->data_norm].fps_max)
1592			fps = vino_data_norms[vcs->data_norm].fps_max;
1593
1594		switch (fps) {
1595		case 5:
1596			mask = 0x003;
1597			break;
1598		case 10:
1599			mask = 0x0c3;
1600			break;
1601		case 15:
1602			mask = 0x333;
1603			break;
1604		case 20:
1605			mask = 0x0ff;
1606			break;
1607		case 25:
1608			mask = 0x3ff;
1609			break;
1610		default:
1611			mask = VINO_FRAMERT_FULL;
1612		}
1613		vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
1614		break;
1615	}
1616
1617	vcs->fps = fps;
1618}
1619
1620/* execute with input_lock locked */
1621static inline void vino_set_default_framerate(struct
1622					      vino_channel_settings *vcs)
1623{
1624	vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1625}
1626
1627/*
1628 * Prepare VINO for DMA transfer...
1629 * (execute only with vino_lock and input_lock locked)
1630 */
1631static int vino_dma_setup(struct vino_channel_settings *vcs,
1632			  struct vino_framebuffer *fb)
1633{
1634	u32 ctrl, intr;
1635	struct sgi_vino_channel *ch;
1636	const struct vino_data_norm *norm;
1637
1638	dprintk("vino_dma_setup():\n");
1639
1640	vcs->field = 0;
1641	fb->frame_counter = 0;
1642
1643	ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1644	norm = &vino_data_norms[vcs->data_norm];
1645
1646	ch->page_index = 0;
1647	ch->line_count = 0;
1648
1649	/* VINO line size register is set 8 bytes less than actual */
1650	ch->line_size = vcs->line_size - 8;
1651
1652	/* let VINO know where to transfer data */
1653	ch->start_desc_tbl = fb->desc_table.dma;
1654	ch->next_4_desc = fb->desc_table.dma;
1655
1656	/* give vino time to fetch the first four descriptors, 5 usec
1657	 * should be more than enough time */
1658	udelay(VINO_DESC_FETCH_DELAY);
1659
1660	dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
1661		ch->start_desc_tbl, ch->next_4_desc);
1662
1663	/* set the alpha register */
1664	ch->alpha = vcs->alpha;
1665
1666	/* set clipping registers */
1667	ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
1668		VINO_CLIP_EVEN(norm->even.top +
1669			       vcs->clipping.top / 2) |
1670		VINO_CLIP_X(vcs->clipping.left);
1671	ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
1672				     vcs->clipping.bottom / 2 - 1) |
1673		VINO_CLIP_EVEN(norm->even.top +
1674			       vcs->clipping.bottom / 2 - 1) |
1675		VINO_CLIP_X(vcs->clipping.right);
1676
1677	/* set the size of actual content in the buffer (DECIMATION !) */
1678	fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
1679			 vcs->decimation) *
1680		((vcs->clipping.bottom - vcs->clipping.top) /
1681		 vcs->decimation) *
1682		vino_data_formats[vcs->data_format].bpp;
1683
1684	ch->frame_rate = vcs->framert_reg;
1685
1686	ctrl = vino->control;
1687	intr = vino->intr_status;
1688
1689	if (vcs->channel == VINO_CHANNEL_A) {
1690		/* All interrupt conditions for this channel was cleared
1691		 * so clear the interrupt status register and enable
1692		 * interrupts */
1693		intr &=	~VINO_INTSTAT_A;
1694		ctrl |= VINO_CTRL_A_INT;
1695
1696		/* enable synchronization */
1697		ctrl |= VINO_CTRL_A_SYNC_ENBL;
1698
1699		/* enable frame assembly */
1700		ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
1701
1702		/* set decimation used */
1703		if (vcs->decimation < 2)
1704			ctrl &= ~VINO_CTRL_A_DEC_ENBL;
1705		else {
1706			ctrl |= VINO_CTRL_A_DEC_ENBL;
1707			ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
1708			ctrl |= (vcs->decimation - 1) <<
1709				VINO_CTRL_A_DEC_SCALE_SHIFT;
1710		}
1711
1712		/* select input interface */
1713		if (vcs->input == VINO_INPUT_D1)
1714			ctrl |= VINO_CTRL_A_SELECT;
1715		else
1716			ctrl &= ~VINO_CTRL_A_SELECT;
1717
1718		/* palette */
1719		ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1720			  VINO_CTRL_A_DITHER);
1721	} else {
1722		intr &= ~VINO_INTSTAT_B;
1723		ctrl |= VINO_CTRL_B_INT;
1724
1725		ctrl |= VINO_CTRL_B_SYNC_ENBL;
1726		ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
1727
1728		if (vcs->decimation < 2)
1729			ctrl &= ~VINO_CTRL_B_DEC_ENBL;
1730		else {
1731			ctrl |= VINO_CTRL_B_DEC_ENBL;
1732			ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
1733			ctrl |= (vcs->decimation - 1) <<
1734				VINO_CTRL_B_DEC_SCALE_SHIFT;
1735
1736		}
1737		if (vcs->input == VINO_INPUT_D1)
1738			ctrl |= VINO_CTRL_B_SELECT;
1739		else
1740			ctrl &= ~VINO_CTRL_B_SELECT;
1741
1742		ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1743			  VINO_CTRL_B_DITHER);
1744	}
1745
1746	/* set palette */
1747	fb->data_format = vcs->data_format;
1748
1749	switch (vcs->data_format) {
1750		case VINO_DATA_FMT_GREY:
1751			ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1752				VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
1753			break;
1754		case VINO_DATA_FMT_RGB32:
1755			ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1756				VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1757			break;
1758		case VINO_DATA_FMT_YUV:
1759			/* nothing needs to be done */
1760			break;
1761		case VINO_DATA_FMT_RGB332:
1762			ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1763				VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
1764				VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
1765			break;
1766	}
1767
1768	vino->intr_status = intr;
1769	vino->control = ctrl;
1770
1771	return 0;
1772}
1773
1774/* (execute only with vino_lock locked) */
1775static inline void vino_dma_start(struct vino_channel_settings *vcs)
1776{
1777	u32 ctrl = vino->control;
1778
1779	dprintk("vino_dma_start():\n");
1780	ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1781		VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
1782	vino->control = ctrl;
1783}
1784
1785/* (execute only with vino_lock locked) */
1786static inline void vino_dma_stop(struct vino_channel_settings *vcs)
1787{
1788	u32 ctrl = vino->control;
1789
1790	ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1791		~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1792	ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1793		~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
1794	vino->control = ctrl;
1795	dprintk("vino_dma_stop():\n");
1796}
1797
1798/*
1799 * Load dummy page to descriptor registers. This prevents generating of
1800 * spurious interrupts. (execute only with vino_lock locked)
1801 */
1802static void vino_clear_interrupt(struct vino_channel_settings *vcs)
1803{
1804	struct sgi_vino_channel *ch;
1805
1806	ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1807
1808	ch->page_index = 0;
1809	ch->line_count = 0;
1810
1811	ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
1812	ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
1813
1814	udelay(VINO_DESC_FETCH_DELAY);
1815	dprintk("channel %c clear interrupt condition\n",
1816	       (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
1817}
1818
1819static int vino_capture(struct vino_channel_settings *vcs,
1820			struct vino_framebuffer *fb)
1821{
1822	int err = 0;
1823	unsigned long flags, flags2;
1824
1825	spin_lock_irqsave(&fb->state_lock, flags);
1826
1827	if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1828		err = -EBUSY;
1829	fb->state = VINO_FRAMEBUFFER_IN_USE;
1830
1831	spin_unlock_irqrestore(&fb->state_lock, flags);
1832
1833	if (err)
1834		return err;
1835
1836	spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
1837	spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
1838
1839	vino_dma_setup(vcs, fb);
1840	vino_dma_start(vcs);
1841
1842	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
1843	spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
1844
1845	return err;
1846}
1847
1848static
1849struct vino_framebuffer *vino_capture_enqueue(struct
1850					      vino_channel_settings *vcs,
1851					      unsigned int index)
1852{
1853	struct vino_framebuffer *fb;
1854	unsigned long flags;
1855
1856	dprintk("vino_capture_enqueue():\n");
1857
1858	spin_lock_irqsave(&vcs->capture_lock, flags);
1859
1860	fb = vino_queue_add(&vcs->fb_queue, index);
1861	if (fb == NULL) {
1862		dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
1863			"queue full?\n");
1864		goto out;
1865	}
1866out:
1867	spin_unlock_irqrestore(&vcs->capture_lock, flags);
1868
1869	return fb;
1870}
1871
1872static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1873{
1874	struct vino_framebuffer *fb;
1875	unsigned int incoming, id;
1876	int err = 0;
1877	unsigned long flags;
1878
1879	dprintk("vino_capture_next():\n");
1880
1881	spin_lock_irqsave(&vcs->capture_lock, flags);
1882
1883	if (start) {
1884		/* start capture only if capture isn't in progress already */
1885		if (vcs->capturing) {
1886			spin_unlock_irqrestore(&vcs->capture_lock, flags);
1887			return 0;
1888		}
1889
1890	} else {
1891		/* capture next frame:
1892		 * stop capture if capturing is not set */
1893		if (!vcs->capturing) {
1894			spin_unlock_irqrestore(&vcs->capture_lock, flags);
1895			return 0;
1896		}
1897	}
1898
1899	err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
1900	if (err) {
1901		dprintk("vino_capture_next(): vino_queue_get_incoming() "
1902			"failed\n");
1903		err = -EINVAL;
1904		goto out;
1905	}
1906	if (incoming == 0) {
1907		dprintk("vino_capture_next(): no buffers available\n");
1908		goto out;
1909	}
1910
1911	fb = vino_queue_peek(&vcs->fb_queue, &id);
1912	if (fb == NULL) {
1913		dprintk("vino_capture_next(): vino_queue_peek() failed\n");
1914		err = -EINVAL;
1915		goto out;
1916	}
1917
1918	if (start) {
1919		vcs->capturing = 1;
1920	}
1921
1922	spin_unlock_irqrestore(&vcs->capture_lock, flags);
1923
1924	err = vino_capture(vcs, fb);
1925
1926	return err;
1927
1928out:
1929	vcs->capturing = 0;
1930	spin_unlock_irqrestore(&vcs->capture_lock, flags);
1931
1932	return err;
1933}
1934
1935static inline int vino_is_capturing(struct vino_channel_settings *vcs)
1936{
1937	int ret;
1938	unsigned long flags;
1939
1940	spin_lock_irqsave(&vcs->capture_lock, flags);
1941
1942	ret = vcs->capturing;
1943
1944	spin_unlock_irqrestore(&vcs->capture_lock, flags);
1945
1946	return ret;
1947}
1948
1949/* waits until a frame is captured */
1950static int vino_wait_for_frame(struct vino_channel_settings *vcs)
1951{
1952	wait_queue_t wait;
1953	int err = 0;
1954
1955	dprintk("vino_wait_for_frame():\n");
1956
1957	init_waitqueue_entry(&wait, current);
1958	/* add ourselves into wait queue */
1959	add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
1960	/* and set current state */
1961	set_current_state(TASK_INTERRUPTIBLE);
1962
1963	/* to ensure that schedule_timeout will return immediately
1964	 * if VINO interrupt was triggred meanwhile */
1965	schedule_timeout(HZ / 10);
1966
1967	if (signal_pending(current))
1968		err = -EINTR;
1969
1970	remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
1971
1972	dprintk("vino_wait_for_frame(): waiting for frame %s\n",
1973		err ? "failed" : "ok");
1974
1975	return err;
1976}
1977
1978/* the function assumes that PAGE_SIZE % 4 == 0 */
1979static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
1980	unsigned char *pageptr;
1981	unsigned int page, i;
1982	unsigned char a;
1983
1984	for (page = 0; page < fb->desc_table.page_count; page++) {
1985		pageptr = (unsigned char *)fb->desc_table.virtual[page];
1986
1987		for (i = 0; i < PAGE_SIZE; i += 4) {
1988			a = pageptr[0];
1989			pageptr[0] = pageptr[3];
1990			pageptr[1] = pageptr[2];
1991			pageptr[2] = pageptr[1];
1992			pageptr[3] = a;
1993			pageptr += 4;
1994		}
1995	}
1996}
1997
1998/* checks if the buffer is in correct state and syncs data */
1999static int vino_check_buffer(struct vino_channel_settings *vcs,
2000			     struct vino_framebuffer *fb)
2001{
2002	int err = 0;
2003	unsigned long flags;
2004
2005	dprintk("vino_check_buffer():\n");
2006
2007	spin_lock_irqsave(&fb->state_lock, flags);
2008	switch (fb->state) {
2009	case VINO_FRAMEBUFFER_IN_USE:
2010		err = -EIO;
2011		break;
2012	case VINO_FRAMEBUFFER_READY:
2013		vino_sync_buffer(fb);
2014		fb->state = VINO_FRAMEBUFFER_UNUSED;
2015		break;
2016	default:
2017		err = -EINVAL;
2018	}
2019	spin_unlock_irqrestore(&fb->state_lock, flags);
2020
2021	if (!err) {
2022		if (vino_pixel_conversion
2023		    && (fb->data_format == VINO_DATA_FMT_RGB32)) {
2024			vino_convert_to_rgba(fb);
2025		}
2026	} else if (err && (err != -EINVAL)) {
2027		dprintk("vino_check_buffer(): buffer not ready\n");
2028
2029		spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2030		vino_dma_stop(vcs);
2031		vino_clear_interrupt(vcs);
2032		spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2033	}
2034
2035	return err;
2036}
2037
2038/* forcefully terminates capture */
2039static void vino_capture_stop(struct vino_channel_settings *vcs)
2040{
2041	unsigned int incoming = 0, outgoing = 0, id;
2042	unsigned long flags, flags2;
2043
2044	dprintk("vino_capture_stop():\n");
2045
2046	spin_lock_irqsave(&vcs->capture_lock, flags);
2047
2048	/* unset capturing to stop queue processing */
2049	vcs->capturing = 0;
2050
2051	spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
2052
2053	vino_dma_stop(vcs);
2054	vino_clear_interrupt(vcs);
2055
2056	spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
2057
2058	/* remove all items from the queue */
2059	if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2060		dprintk("vino_capture_stop(): "
2061			"vino_queue_get_incoming() failed\n");
2062		goto out;
2063	}
2064	while (incoming > 0) {
2065		vino_queue_transfer(&vcs->fb_queue);
2066
2067		if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2068			dprintk("vino_capture_stop(): "
2069				"vino_queue_get_incoming() failed\n");
2070			goto out;
2071		}
2072	}
2073
2074	if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2075		dprintk("vino_capture_stop(): "
2076			"vino_queue_get_outgoing() failed\n");
2077		goto out;
2078	}
2079	while (outgoing > 0) {
2080		vino_queue_remove(&vcs->fb_queue, &id);
2081
2082		if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2083			dprintk("vino_capture_stop(): "
2084				"vino_queue_get_outgoing() failed\n");
2085			goto out;
2086		}
2087	}
2088
2089out:
2090	spin_unlock_irqrestore(&vcs->capture_lock, flags);
2091}
2092
2093
2094static void vino_skip_frame(struct vino_channel_settings *vcs)
2095{
2096	struct vino_framebuffer *fb;
2097	unsigned long flags;
2098	unsigned int id;
2099
2100	spin_lock_irqsave(&vcs->capture_lock, flags);
2101	fb = vino_queue_peek(&vcs->fb_queue, &id);
2102	if (!fb) {
2103		spin_unlock_irqrestore(&vcs->capture_lock, flags);
2104		dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
2105		return;
2106	}
2107	spin_unlock_irqrestore(&vcs->capture_lock, flags);
2108
2109	spin_lock_irqsave(&fb->state_lock, flags);
2110	fb->state = VINO_FRAMEBUFFER_UNUSED;
2111	spin_unlock_irqrestore(&fb->state_lock, flags);
2112
2113	vino_capture_next(vcs, 0);
2114}
2115
2116static void vino_frame_done(struct vino_channel_settings *vcs)
2117{
2118	struct vino_framebuffer *fb;
2119	unsigned long flags;
2120
2121	spin_lock_irqsave(&vcs->capture_lock, flags);
2122	fb = vino_queue_transfer(&vcs->fb_queue);
2123	if (!fb) {
2124		spin_unlock_irqrestore(&vcs->capture_lock, flags);
2125		dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
2126		return;
2127	}
2128	spin_unlock_irqrestore(&vcs->capture_lock, flags);
2129
2130	fb->frame_counter = vcs->int_data.frame_counter;
2131	memcpy(&fb->timestamp, &vcs->int_data.timestamp,
2132	       sizeof(struct timeval));
2133
2134	spin_lock_irqsave(&fb->state_lock, flags);
2135	if (fb->state == VINO_FRAMEBUFFER_IN_USE)
2136		fb->state = VINO_FRAMEBUFFER_READY;
2137	spin_unlock_irqrestore(&fb->state_lock, flags);
2138
2139	wake_up(&vcs->fb_queue.frame_wait_queue);
2140
2141	vino_capture_next(vcs, 0);
2142}
2143
2144static void vino_capture_tasklet(unsigned long channel) {
2145	struct vino_channel_settings *vcs;
2146
2147	vcs = (channel == VINO_CHANNEL_A)
2148		? &vino_drvdata->a : &vino_drvdata->b;
2149
2150	if (vcs->int_data.skip)
2151		vcs->int_data.skip_count++;
2152
2153	if (vcs->int_data.skip && (vcs->int_data.skip_count
2154				   <= VINO_MAX_FRAME_SKIP_COUNT)) {
2155		vino_skip_frame(vcs);
2156	} else {
2157		vcs->int_data.skip_count = 0;
2158		vino_frame_done(vcs);
2159	}
2160}
2161
2162static irqreturn_t vino_interrupt(int irq, void *dev_id)
2163{
2164	u32 ctrl, intr;
2165	unsigned int fc_a, fc_b;
2166	int handled_a = 0, skip_a = 0, done_a = 0;
2167	int handled_b = 0, skip_b = 0, done_b = 0;
2168
2169#ifdef VINO_DEBUG_INT
2170	int loop = 0;
2171	unsigned int line_count = vino->a.line_count,
2172		page_index = vino->a.page_index,
2173		field_counter = vino->a.field_counter,
2174		start_desc_tbl = vino->a.start_desc_tbl,
2175		next_4_desc = vino->a.next_4_desc;
2176	unsigned int line_count_2,
2177		page_index_2,
2178		field_counter_2,
2179		start_desc_tbl_2,
2180		next_4_desc_2;
2181#endif
2182
2183	spin_lock(&vino_drvdata->vino_lock);
2184
2185	while ((intr = vino->intr_status)) {
2186		fc_a = vino->a.field_counter >> 1;
2187		fc_b = vino->b.field_counter >> 1;
2188
2189		/* handle error-interrupts in some special way ?
2190		 * --> skips frames */
2191		if (intr & VINO_INTSTAT_A) {
2192			if (intr & VINO_INTSTAT_A_EOF) {
2193				vino_drvdata->a.field++;
2194				if (vino_drvdata->a.field > 1) {
2195					vino_dma_stop(&vino_drvdata->a);
2196					vino_clear_interrupt(&vino_drvdata->a);
2197					vino_drvdata->a.field = 0;
2198					done_a = 1;
2199				} else {
2200					if (vino->a.page_index
2201					    != vino_drvdata->a.line_size) {
2202						vino->a.line_count = 0;
2203						vino->a.page_index =
2204							vino_drvdata->
2205							a.line_size;
2206						vino->a.next_4_desc =
2207							vino->a.start_desc_tbl;
2208					}
2209				}
2210				dprintk("channel A end-of-field "
2211					"interrupt: %04x\n", intr);
2212			} else {
2213				vino_dma_stop(&vino_drvdata->a);
2214				vino_clear_interrupt(&vino_drvdata->a);
2215				vino_drvdata->a.field = 0;
2216				skip_a = 1;
2217				dprintk("channel A error interrupt: %04x\n",
2218					intr);
2219			}
2220
2221#ifdef VINO_DEBUG_INT
2222			line_count_2 = vino->a.line_count;
2223			page_index_2 = vino->a.page_index;
2224			field_counter_2 = vino->a.field_counter;
2225			start_desc_tbl_2 = vino->a.start_desc_tbl;
2226			next_4_desc_2 = vino->a.next_4_desc;
2227
2228			printk("intr = %04x, loop = %d, field = %d\n",
2229			       intr, loop, vino_drvdata->a.field);
2230			printk("1- line count = %04d, page index = %04d, "
2231			       "start = %08x, next = %08x\n"
2232			       "   fieldc = %d, framec = %d\n",
2233			       line_count, page_index, start_desc_tbl,
2234			       next_4_desc, field_counter, fc_a);
2235			printk("12-line count = %04d, page index = %04d, "
2236			       "   start = %08x, next = %08x\n",
2237			       line_count_2, page_index_2, start_desc_tbl_2,
2238			       next_4_desc_2);
2239
2240			if (done_a)
2241				printk("\n");
2242#endif
2243		}
2244
2245		if (intr & VINO_INTSTAT_B) {
2246			if (intr & VINO_INTSTAT_B_EOF) {
2247				vino_drvdata->b.field++;
2248				if (vino_drvdata->b.field > 1) {
2249					vino_dma_stop(&vino_drvdata->b);
2250					vino_clear_interrupt(&vino_drvdata->b);
2251					vino_drvdata->b.field = 0;
2252					done_b = 1;
2253				}
2254				dprintk("channel B end-of-field "
2255					"interrupt: %04x\n", intr);
2256			} else {
2257				vino_dma_stop(&vino_drvdata->b);
2258				vino_clear_interrupt(&vino_drvdata->b);
2259				vino_drvdata->b.field = 0;
2260				skip_b = 1;
2261				dprintk("channel B error interrupt: %04x\n",
2262					intr);
2263			}
2264		}
2265
2266		/* Always remember to clear interrupt status.
2267		 * Disable VINO interrupts while we do this. */
2268		ctrl = vino->control;
2269		vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
2270		vino->intr_status = ~intr;
2271		vino->control = ctrl;
2272
2273		spin_unlock(&vino_drvdata->vino_lock);
2274
2275		if ((!handled_a) && (done_a || skip_a)) {
2276			if (!skip_a) {
2277				do_gettimeofday(&vino_drvdata->
2278						a.int_data.timestamp);
2279				vino_drvdata->a.int_data.frame_counter = fc_a;
2280			}
2281			vino_drvdata->a.int_data.skip = skip_a;
2282
2283			dprintk("channel A %s, interrupt: %d\n",
2284				skip_a ? "skipping frame" : "frame done",
2285				intr);
2286			tasklet_hi_schedule(&vino_tasklet_a);
2287			handled_a = 1;
2288		}
2289
2290		if ((!handled_b) && (done_b || skip_b)) {
2291			if (!skip_b) {
2292				do_gettimeofday(&vino_drvdata->
2293						b.int_data.timestamp);
2294				vino_drvdata->b.int_data.frame_counter = fc_b;
2295			}
2296			vino_drvdata->b.int_data.skip = skip_b;
2297
2298			dprintk("channel B %s, interrupt: %d\n",
2299				skip_b ? "skipping frame" : "frame done",
2300				intr);
2301			tasklet_hi_schedule(&vino_tasklet_b);
2302			handled_b = 1;
2303		}
2304
2305#ifdef VINO_DEBUG_INT
2306		loop++;
2307#endif
2308		spin_lock(&vino_drvdata->vino_lock);
2309	}
2310
2311	spin_unlock(&vino_drvdata->vino_lock);
2312
2313	return IRQ_HANDLED;
2314}
2315
2316/* VINO video input management */
2317
2318static int vino_get_saa7191_input(int input)
2319{
2320	switch (input) {
2321	case VINO_INPUT_COMPOSITE:
2322		return SAA7191_INPUT_COMPOSITE;
2323	case VINO_INPUT_SVIDEO:
2324		return SAA7191_INPUT_SVIDEO;
2325	default:
2326		printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2327		       "invalid input!\n");
2328		return -1;
2329	}
2330}
2331
2332static int vino_get_saa7191_norm(unsigned int data_norm)
2333{
2334	switch (data_norm) {
2335	case VINO_DATA_NORM_AUTO:
2336		return SAA7191_NORM_AUTO;
2337	case VINO_DATA_NORM_AUTO_EXT:
2338		return SAA7191_NORM_AUTO_EXT;
2339	case VINO_DATA_NORM_PAL:
2340		return SAA7191_NORM_PAL;
2341	case VINO_DATA_NORM_NTSC:
2342		return SAA7191_NORM_NTSC;
2343	case VINO_DATA_NORM_SECAM:
2344		return SAA7191_NORM_SECAM;
2345	default:
2346		printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
2347		       "invalid norm!\n");
2348		return -1;
2349	}
2350}
2351
2352static int vino_get_from_saa7191_norm(int saa7191_norm)
2353{
2354	switch (saa7191_norm) {
2355	case SAA7191_NORM_PAL:
2356		return VINO_DATA_NORM_PAL;
2357	case SAA7191_NORM_NTSC:
2358		return VINO_DATA_NORM_NTSC;
2359	case SAA7191_NORM_SECAM:
2360		return VINO_DATA_NORM_SECAM;
2361	default:
2362		printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
2363		       "invalid norm!\n");
2364		return VINO_DATA_NORM_NONE;
2365	}
2366}
2367
2368static int vino_saa7191_set_norm(unsigned int *data_norm)
2369{
2370	int saa7191_norm, new_data_norm;
2371	int err = 0;
2372
2373	saa7191_norm = vino_get_saa7191_norm(*data_norm);
2374
2375	err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
2376				  &saa7191_norm);
2377	if (err)
2378		goto out;
2379
2380	if ((*data_norm == VINO_DATA_NORM_AUTO)
2381	    || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
2382		struct saa7191_status status;
2383
2384		err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
2385					  &status);
2386		if (err)
2387			goto out;
2388
2389		new_data_norm =
2390			vino_get_from_saa7191_norm(status.norm);
2391		if (new_data_norm == VINO_DATA_NORM_NONE) {
2392			err = -EINVAL;
2393			goto out;
2394		}
2395
2396		*data_norm = (unsigned int)new_data_norm;
2397	}
2398
2399out:
2400	return err;
2401}
2402
2403/* execute with input_lock locked */
2404static int vino_is_input_owner(struct vino_channel_settings *vcs)
2405{
2406	switch(vcs->input) {
2407	case VINO_INPUT_COMPOSITE:
2408	case VINO_INPUT_SVIDEO:
2409		return (vino_drvdata->decoder.owner == vcs->channel);
2410	case VINO_INPUT_D1:
2411		return (vino_drvdata->camera.owner == vcs->channel);
2412	default:
2413		return 0;
2414	}
2415}
2416
2417static int vino_acquire_input(struct vino_channel_settings *vcs)
2418{
2419	unsigned long flags;
2420	int ret = 0;
2421
2422	dprintk("vino_acquire_input():\n");
2423
2424	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2425
2426	/* First try D1 and then SAA7191 */
2427	if (vino_drvdata->camera.driver
2428	    && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
2429		if (i2c_use_client(vino_drvdata->camera.driver)) {
2430			ret = -ENODEV;
2431			goto out;
2432		}
2433
2434		vino_drvdata->camera.owner = vcs->channel;
2435		vcs->input = VINO_INPUT_D1;
2436		vcs->data_norm = VINO_DATA_NORM_D1;
2437	} else if (vino_drvdata->decoder.driver
2438		   && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
2439		int input, data_norm;
2440		int saa7191_input;
2441
2442		if (i2c_use_client(vino_drvdata->decoder.driver)) {
2443			ret = -ENODEV;
2444			goto out;
2445		}
2446
2447		input = VINO_INPUT_COMPOSITE;
2448
2449		saa7191_input = vino_get_saa7191_input(input);
2450		ret = i2c_decoder_command(DECODER_SET_INPUT,
2451					  &saa7191_input);
2452		if (ret) {
2453			ret = -EINVAL;
2454			goto out;
2455		}
2456
2457		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2458
2459		/* Don't hold spinlocks while auto-detecting norm
2460		 * as it may take a while... */
2461
2462		data_norm = VINO_DATA_NORM_AUTO_EXT;
2463
2464		ret = vino_saa7191_set_norm(&data_norm);
2465		if ((ret == -EBUSY) || (ret == -EAGAIN)) {
2466			data_norm = VINO_DATA_NORM_PAL;
2467			ret = vino_saa7191_set_norm(&data_norm);
2468		}
2469
2470		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2471
2472		if (ret) {
2473			ret = -EINVAL;
2474			goto out;
2475		}
2476
2477		vino_drvdata->decoder.owner = vcs->channel;
2478
2479		vcs->input = input;
2480		vcs->data_norm = data_norm;
2481	} else {
2482		vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2483			vino_drvdata->b.input : vino_drvdata->a.input;
2484		vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
2485			vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
2486	}
2487
2488	if (vcs->input == VINO_INPUT_NONE) {
2489		ret = -ENODEV;
2490		goto out;
2491	}
2492
2493	vino_set_default_clipping(vcs);
2494	vino_set_default_scaling(vcs);
2495	vino_set_default_framerate(vcs);
2496
2497	dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2498
2499out:
2500	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2501
2502	return ret;
2503}
2504
2505static int vino_set_input(struct vino_channel_settings *vcs, int input)
2506{
2507	struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2508		&vino_drvdata->b : &vino_drvdata->a;
2509	unsigned long flags;
2510	int ret = 0;
2511
2512	dprintk("vino_set_input():\n");
2513
2514	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2515
2516	if (vcs->input == input)
2517		goto out;
2518
2519	switch (input) {
2520	case VINO_INPUT_COMPOSITE:
2521	case VINO_INPUT_SVIDEO:
2522		if (!vino_drvdata->decoder.driver) {
2523			ret = -EINVAL;
2524			goto out;
2525		}
2526
2527		if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
2528			if (i2c_use_client(vino_drvdata->decoder.driver)) {
2529				ret = -ENODEV;
2530				goto out;
2531			}
2532			vino_drvdata->decoder.owner = vcs->channel;
2533		}
2534
2535		if (vino_drvdata->decoder.owner == vcs->channel) {
2536			int data_norm;
2537			int saa7191_input;
2538
2539			saa7191_input = vino_get_saa7191_input(input);
2540			ret = i2c_decoder_command(DECODER_SET_INPUT,
2541						  &saa7191_input);
2542			if (ret) {
2543				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2544				ret = -EINVAL;
2545				goto out;
2546			}
2547
2548			spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2549
2550			/* Don't hold spinlocks while auto-detecting norm
2551			 * as it may take a while... */
2552
2553			data_norm = VINO_DATA_NORM_AUTO_EXT;
2554
2555			ret = vino_saa7191_set_norm(&data_norm);
2556			if ((ret  == -EBUSY) || (ret == -EAGAIN)) {
2557				data_norm = VINO_DATA_NORM_PAL;
2558				ret = vino_saa7191_set_norm(&data_norm);
2559			}
2560
2561			spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2562
2563			if (ret) {
2564				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2565				ret = -EINVAL;
2566				goto out;
2567			}
2568
2569			vcs->input = input;
2570			vcs->data_norm = data_norm;
2571		} else {
2572			if (input != vcs2->input) {
2573				ret = -EBUSY;
2574				goto out;
2575			}
2576
2577			vcs->input = input;
2578			vcs->data_norm = vcs2->data_norm;
2579		}
2580
2581		if (vino_drvdata->camera.owner == vcs->channel) {
2582			/* Transfer the ownership or release the input */
2583			if (vcs2->input == VINO_INPUT_D1) {
2584				vino_drvdata->camera.owner = vcs2->channel;
2585			} else {
2586				i2c_release_client(vino_drvdata->
2587						   camera.driver);
2588				vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2589			}
2590		}
2591		break;
2592	case VINO_INPUT_D1:
2593		if (!vino_drvdata->camera.driver) {
2594			ret = -EINVAL;
2595			goto out;
2596		}
2597
2598		if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
2599			if (i2c_use_client(vino_drvdata->camera.driver)) {
2600				ret = -ENODEV;
2601				goto out;
2602			}
2603			vino_drvdata->camera.owner = vcs->channel;
2604		}
2605
2606		if (vino_drvdata->decoder.owner == vcs->channel) {
2607			/* Transfer the ownership or release the input */
2608			if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2609				 (vcs2->input == VINO_INPUT_SVIDEO)) {
2610				vino_drvdata->decoder.owner = vcs2->channel;
2611			} else {
2612				i2c_release_client(vino_drvdata->
2613						   decoder.driver);
2614				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2615			}
2616		}
2617
2618		vcs->input = input;
2619		vcs->data_norm = VINO_DATA_NORM_D1;
2620		break;
2621	default:
2622		ret = -EINVAL;
2623		goto out;
2624	}
2625
2626	vino_set_default_clipping(vcs);
2627	vino_set_default_scaling(vcs);
2628	vino_set_default_framerate(vcs);
2629
2630	dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2631
2632out:
2633	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2634
2635	return ret;
2636}
2637
2638static void vino_release_input(struct vino_channel_settings *vcs)
2639{
2640	struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2641		&vino_drvdata->b : &vino_drvdata->a;
2642	unsigned long flags;
2643
2644	dprintk("vino_release_input():\n");
2645
2646	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2647
2648	/* Release ownership of the channel
2649	 * and if the other channel takes input from
2650	 * the same source, transfer the ownership */
2651	if (vino_drvdata->camera.owner == vcs->channel) {
2652		if (vcs2->input == VINO_INPUT_D1) {
2653			vino_drvdata->camera.owner = vcs2->channel;
2654		} else {
2655			i2c_release_client(vino_drvdata->camera.driver);
2656			vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2657		}
2658	} else if (vino_drvdata->decoder.owner == vcs->channel) {
2659		if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2660			 (vcs2->input == VINO_INPUT_SVIDEO)) {
2661			vino_drvdata->decoder.owner = vcs2->channel;
2662		} else {
2663			i2c_release_client(vino_drvdata->decoder.driver);
2664			vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2665		}
2666	}
2667	vcs->input = VINO_INPUT_NONE;
2668
2669	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2670}
2671
2672/* execute with input_lock locked */
2673static int vino_set_data_norm(struct vino_channel_settings *vcs,
2674			      unsigned int data_norm,
2675			      unsigned long *flags)
2676{
2677	int err = 0;
2678
2679	if (data_norm == vcs->data_norm)
2680		return 0;
2681
2682	switch (vcs->input) {
2683	case VINO_INPUT_D1:
2684		/* only one "norm" supported */
2685		if ((data_norm != VINO_DATA_NORM_D1)
2686		    && (data_norm != VINO_DATA_NORM_AUTO)
2687		    && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2688			return -EINVAL;
2689		break;
2690	case VINO_INPUT_COMPOSITE:
2691	case VINO_INPUT_SVIDEO: {
2692		if ((data_norm != VINO_DATA_NORM_PAL)
2693		    && (data_norm != VINO_DATA_NORM_NTSC)
2694		    && (data_norm != VINO_DATA_NORM_SECAM)
2695		    && (data_norm != VINO_DATA_NORM_AUTO)
2696		    && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2697			return -EINVAL;
2698
2699		spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
2700
2701		/* Don't hold spinlocks while setting norm
2702		 * as it may take a while... */
2703
2704		err = vino_saa7191_set_norm(&data_norm);
2705
2706		spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
2707
2708		if (err)
2709			goto out;
2710
2711		vcs->data_norm = data_norm;
2712
2713		vino_set_default_clipping(vcs);
2714		vino_set_default_scaling(vcs);
2715		vino_set_default_framerate(vcs);
2716		break;
2717	}
2718	default:
2719		return -EINVAL;
2720	}
2721
2722out:
2723	return err;
2724}
2725
2726/* V4L2 helper functions */
2727
2728static int vino_find_data_format(__u32 pixelformat)
2729{
2730	int i;
2731
2732	for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2733		if (vino_data_formats[i].pixelformat == pixelformat)
2734			return i;
2735	}
2736
2737	return VINO_DATA_FMT_NONE;
2738}
2739
2740static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2741{
2742	int data_norm = VINO_DATA_NORM_NONE;
2743	unsigned long flags;
2744
2745	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2746	switch(vcs->input) {
2747	case VINO_INPUT_COMPOSITE:
2748	case VINO_INPUT_SVIDEO:
2749		if (index == 0) {
2750			data_norm = VINO_DATA_NORM_PAL;
2751		} else if (index == 1) {
2752			data_norm = VINO_DATA_NORM_NTSC;
2753		} else if (index == 2) {
2754			data_norm = VINO_DATA_NORM_SECAM;
2755		}
2756		break;
2757	case VINO_INPUT_D1:
2758		if (index == 0) {
2759			data_norm = VINO_DATA_NORM_D1;
2760		}
2761		break;
2762	}
2763	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2764
2765	return data_norm;
2766}
2767
2768static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
2769{
2770	int input = VINO_INPUT_NONE;
2771	unsigned long flags;
2772
2773	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2774	if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2775		switch (index) {
2776		case 0:
2777			input = VINO_INPUT_COMPOSITE;
2778			break;
2779		case 1:
2780			input = VINO_INPUT_SVIDEO;
2781			break;
2782		case 2:
2783			input = VINO_INPUT_D1;
2784			break;
2785		}
2786	} else if (vino_drvdata->decoder.driver) {
2787		switch (index) {
2788		case 0:
2789			input = VINO_INPUT_COMPOSITE;
2790			break;
2791		case 1:
2792			input = VINO_INPUT_SVIDEO;
2793			break;
2794		}
2795	} else if (vino_drvdata->camera.driver) {
2796		switch (index) {
2797		case 0:
2798			input = VINO_INPUT_D1;
2799			break;
2800		}
2801	}
2802	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2803
2804	return input;
2805}
2806
2807/* execute with input_lock locked */
2808static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
2809{
2810	__u32 index = 0;
2811
2812	if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2813		switch (vcs->input) {
2814		case VINO_INPUT_COMPOSITE:
2815			index = 0;
2816			break;
2817		case VINO_INPUT_SVIDEO:
2818			index = 1;
2819			break;
2820		case VINO_INPUT_D1:
2821			index = 2;
2822			break;
2823		}
2824	} else if (vino_drvdata->decoder.driver) {
2825		switch (vcs->input) {
2826		case VINO_INPUT_COMPOSITE:
2827			index = 0;
2828			break;
2829		case VINO_INPUT_SVIDEO:
2830			index = 1;
2831			break;
2832		}
2833	} else if (vino_drvdata->camera.driver) {
2834		switch (vcs->input) {
2835		case VINO_INPUT_D1:
2836			index = 0;
2837			break;
2838		}
2839	}
2840
2841	return index;
2842}
2843
2844/* V4L2 ioctls */
2845
2846static void vino_v4l2_querycap(struct v4l2_capability *cap)
2847{
2848	memset(cap, 0, sizeof(struct v4l2_capability));
2849
2850	strcpy(cap->driver, vino_driver_name);
2851	strcpy(cap->card, vino_driver_description);
2852	strcpy(cap->bus_info, vino_bus_name);
2853	cap->version = VINO_VERSION_CODE;
2854	cap->capabilities =
2855		V4L2_CAP_VIDEO_CAPTURE |
2856		V4L2_CAP_STREAMING;
2857	// V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
2858}
2859
2860static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
2861			       struct v4l2_input *i)
2862{
2863	__u32 index = i->index;
2864	int input;
2865	dprintk("requested index = %d\n", index);
2866
2867	input = vino_enum_input(vcs, index);
2868	if (input == VINO_INPUT_NONE)
2869		return -EINVAL;
2870
2871	memset(i, 0, sizeof(struct v4l2_input));
2872
2873	i->index = index;
2874	i->type = V4L2_INPUT_TYPE_CAMERA;
2875	i->std = vino_inputs[input].std;
2876	strcpy(i->name, vino_inputs[input].name);
2877
2878	if ((input == VINO_INPUT_COMPOSITE)
2879	    || (input == VINO_INPUT_SVIDEO)) {
2880		struct saa7191_status status;
2881		i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
2882		i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
2883		i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
2884	}
2885
2886	return 0;
2887}
2888
2889static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2890			     unsigned int *i)
2891{
2892	__u32 index;
2893	int input;
2894	unsigned long flags;
2895
2896	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2897	input = vcs->input;
2898	index = vino_find_input_index(vcs);
2899	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2900
2901	dprintk("input = %d\n", input);
2902
2903	if (input == VINO_INPUT_NONE) {
2904		return -EINVAL;
2905	}
2906
2907	*i = index;
2908
2909	return 0;
2910}
2911
2912static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
2913			     unsigned int *i)
2914{
2915	int input;
2916	dprintk("requested input = %d\n", *i);
2917
2918	input = vino_enum_input(vcs, *i);
2919	if (input == VINO_INPUT_NONE)
2920		return -EINVAL;
2921
2922	return vino_set_input(vcs, input);
2923}
2924
2925static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
2926			     struct v4l2_standard *s)
2927{
2928	int index = s->index;
2929	int data_norm;
2930
2931	data_norm = vino_enum_data_norm(vcs, index);
2932	dprintk("standard index = %d\n", index);
2933
2934	if (data_norm == VINO_DATA_NORM_NONE)
2935		return -EINVAL;
2936
2937	dprintk("standard name = %s\n",
2938	       vino_data_norms[data_norm].description);
2939
2940	memset(s, 0, sizeof(struct v4l2_standard));
2941	s->index = index;
2942
2943	s->id = vino_data_norms[data_norm].std;
2944	s->frameperiod.numerator = 1;
2945	s->frameperiod.denominator =
2946		vino_data_norms[data_norm].fps_max;
2947	s->framelines =
2948		vino_data_norms[data_norm].framelines;
2949	strcpy(s->name,
2950	       vino_data_norms[data_norm].description);
2951
2952	return 0;
2953}
2954
2955static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
2956			      v4l2_std_id *std)
2957{
2958	unsigned long flags;
2959	int err = 0;
2960
2961	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2962
2963	switch (vcs->input) {
2964	case VINO_INPUT_D1:
2965		*std = vino_inputs[vcs->input].std;
2966		break;
2967	case VINO_INPUT_COMPOSITE:
2968	case VINO_INPUT_SVIDEO: {
2969		struct saa7191_status status;
2970
2971		i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
2972
2973		if (status.signal) {
2974			if (status.signal_60hz) {
2975				*std = V4L2_STD_NTSC;
2976			} else {
2977				*std = V4L2_STD_PAL | V4L2_STD_SECAM;
2978			}
2979		} else {
2980			*std = vino_inputs[vcs->input].std;
2981		}
2982		break;
2983	}
2984	default:
2985		err = -EINVAL;
2986	}
2987
2988	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2989
2990	return err;
2991}
2992
2993static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
2994			   v4l2_std_id *std)
2995{
2996	unsigned long flags;
2997
2998	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2999
3000	*std = vino_data_norms[vcs->data_norm].std;
3001	dprintk("current standard = %d\n", vcs->data_norm);
3002
3003	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3004
3005	return 0;
3006}
3007
3008static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
3009			   v4l2_std_id *std)
3010{
3011	unsigned long flags;
3012	int ret = 0;
3013
3014	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3015
3016	if (!vino_is_input_owner(vcs)) {
3017		ret = -EBUSY;
3018		goto out;
3019	}
3020
3021	/* check if the standard is valid for the current input */
3022	if ((*std) & vino_inputs[vcs->input].std) {
3023		dprintk("standard accepted\n");
3024
3025		/* change the video norm for SAA7191
3026		 * and accept NTSC for D1 (do nothing) */
3027
3028		if (vcs->input == VINO_INPUT_D1)
3029			goto out;
3030
3031		if (((*std) & V4L2_STD_PAL)
3032		    && ((*std) & V4L2_STD_NTSC)
3033		    && ((*std) & V4L2_STD_SECAM)) {
3034			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
3035						 &flags);
3036		} else if ((*std) & V4L2_STD_PAL) {
3037			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
3038						 &flags);
3039		} else if ((*std) & V4L2_STD_NTSC) {
3040			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
3041						 &flags);
3042		} else if ((*std) & V4L2_STD_SECAM) {
3043			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
3044						 &flags);
3045		} else {
3046			ret = -EINVAL;
3047		}
3048
3049		if (ret) {
3050			ret = -EINVAL;
3051		}
3052	} else {
3053		ret = -EINVAL;
3054	}
3055
3056out:
3057	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3058
3059	return ret;
3060}
3061
3062static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
3063			      struct v4l2_fmtdesc *fd)
3064{
3065	enum v4l2_buf_type type = fd->type;
3066	int index = fd->index;
3067	dprintk("format index = %d\n", index);
3068
3069	switch (fd->type) {
3070	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3071		if ((fd->index < 0) ||
3072		    (fd->index >= VINO_DATA_FMT_COUNT))
3073			return -EINVAL;
3074		dprintk("format name = %s\n",
3075		       vino_data_formats[index].description);
3076
3077		memset(fd, 0, sizeof(struct v4l2_fmtdesc));
3078		fd->index = index;
3079		fd->type = type;
3080		fd->pixelformat = vino_data_formats[index].pixelformat;
3081		strcpy(fd->description, vino_data_formats[index].description);
3082		break;
3083	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3084	default:
3085		return -EINVAL;
3086	}
3087
3088	return 0;
3089}
3090
3091static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
3092			     struct v4l2_format *f)
3093{
3094	struct vino_channel_settings tempvcs;
3095	unsigned long flags;
3096
3097	switch (f->type) {
3098	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3099		struct v4l2_pix_format *pf = &f->fmt.pix;
3100
3101		dprintk("requested: w = %d, h = %d\n",
3102		       pf->width, pf->height);
3103
3104		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3105		memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
3106		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3107
3108		tempvcs.data_format = vino_find_data_format(pf->pixelformat);
3109		if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
3110			tempvcs.data_format = VINO_DATA_FMT_GREY;
3111			pf->pixelformat =
3112				vino_data_formats[tempvcs.data_format].
3113				pixelformat;
3114		}
3115
3116		/* data format must be set before clipping/scaling */
3117		vino_set_scaling(&tempvcs, pf->width, pf->height);
3118
3119		dprintk("data format = %s\n",
3120		       vino_data_formats[tempvcs.data_format].description);
3121
3122		pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
3123			tempvcs.decimation;
3124		pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
3125			tempvcs.decimation;
3126
3127		pf->field = V4L2_FIELD_INTERLACED;
3128		pf->bytesperline = tempvcs.line_size;
3129		pf->sizeimage = tempvcs.line_size *
3130			(tempvcs.clipping.bottom - tempvcs.clipping.top) /
3131			tempvcs.decimation;
3132		pf->colorspace =
3133			vino_data_formats[tempvcs.data_format].colorspace;
3134
3135		pf->priv = 0;
3136		break;
3137	}
3138	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3139	default:
3140		return -EINVAL;
3141	}
3142
3143	return 0;
3144}
3145
3146static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
3147			   struct v4l2_format *f)
3148{
3149	unsigned long flags;
3150
3151	switch (f->type) {
3152	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3153		struct v4l2_pix_format *pf = &f->fmt.pix;
3154
3155		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3156
3157		pf->width = (vcs->clipping.right - vcs->clipping.left) /
3158			vcs->decimation;
3159		pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
3160			vcs->decimation;
3161		pf->pixelformat =
3162			vino_data_formats[vcs->data_format].pixelformat;
3163
3164		pf->field = V4L2_FIELD_INTERLACED;
3165		pf->bytesperline = vcs->line_size;
3166		pf->sizeimage = vcs->line_size *
3167			(vcs->clipping.bottom - vcs->clipping.top) /
3168			vcs->decimation;
3169		pf->colorspace =
3170			vino_data_formats[vcs->data_format].colorspace;
3171
3172		pf->priv = 0;
3173
3174		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3175		break;
3176	}
3177	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3178	default:
3179		return -EINVAL;
3180	}
3181
3182	return 0;
3183}
3184
3185static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
3186			   struct v4l2_format *f)
3187{
3188	int data_format;
3189	unsigned long flags;
3190
3191	switch (f->type) {
3192	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3193		struct v4l2_pix_format *pf = &f->fmt.pix;
3194
3195		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3196
3197		data_format = vino_find_data_format(pf->pixelformat);
3198
3199		if (data_format == VINO_DATA_FMT_NONE) {
3200			vcs->data_format = VINO_DATA_FMT_GREY;
3201			pf->pixelformat =
3202				vino_data_formats[vcs->data_format].
3203				pixelformat;
3204		} else {
3205			vcs->data_format = data_format;
3206		}
3207
3208		/* data format must be set before clipping/scaling */
3209		vino_set_scaling(vcs, pf->width, pf->height);
3210
3211		dprintk("data format = %s\n",
3212		       vino_data_formats[vcs->data_format].description);
3213
3214		pf->width = vcs->clipping.right - vcs->clipping.left;
3215		pf->height = vcs->clipping.bottom - vcs->clipping.top;
3216
3217		pf->field = V4L2_FIELD_INTERLACED;
3218		pf->bytesperline = vcs->line_size;
3219		pf->sizeimage = vcs->line_size *
3220			(vcs->clipping.bottom - vcs->clipping.top) /
3221			vcs->decimation;
3222		pf->colorspace =
3223			vino_data_formats[vcs->data_format].colorspace;
3224
3225		pf->priv = 0;
3226
3227		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3228		break;
3229	}
3230	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3231	default:
3232		return -EINVAL;
3233	}
3234
3235	return 0;
3236}
3237
3238static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
3239			     struct v4l2_cropcap *ccap)
3240{
3241	const struct vino_data_norm *norm;
3242	unsigned long flags;
3243
3244	switch (ccap->type) {
3245	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3246		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3247
3248		norm = &vino_data_norms[vcs->data_norm];
3249
3250		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3251
3252		ccap->bounds.left = 0;
3253		ccap->bounds.top = 0;
3254		ccap->bounds.width = norm->width;
3255		ccap->bounds.height = norm->height;
3256		memcpy(&ccap->defrect, &ccap->bounds,
3257		       sizeof(struct v4l2_rect));
3258
3259		ccap->pixelaspect.numerator = 1;
3260		ccap->pixelaspect.denominator = 1;
3261		break;
3262	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3263	default:
3264		return -EINVAL;
3265	}
3266
3267	return 0;
3268}
3269
3270static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3271			    struct v4l2_crop *c)
3272{
3273	unsigned long flags;
3274
3275	switch (c->type) {
3276	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3277		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3278
3279		c->c.left = vcs->clipping.left;
3280		c->c.top = vcs->clipping.top;
3281		c->c.width = vcs->clipping.right - vcs->clipping.left;
3282		c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3283
3284		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3285		break;
3286	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3287	default:
3288		return -EINVAL;
3289	}
3290
3291	return 0;
3292}
3293
3294static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3295			    struct v4l2_crop *c)
3296{
3297	unsigned long flags;
3298
3299	switch (c->type) {
3300	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3301		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3302
3303		vino_set_clipping(vcs, c->c.left, c->c.top,
3304				  c->c.width, c->c.height);
3305
3306		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3307		break;
3308	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3309	default:
3310		return -EINVAL;
3311	}
3312
3313	return 0;
3314}
3315
3316static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3317			    struct v4l2_streamparm *sp)
3318{
3319	unsigned long flags;
3320
3321	switch (sp->type) {
3322	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3323		struct v4l2_captureparm *cp = &sp->parm.capture;
3324		memset(cp, 0, sizeof(struct v4l2_captureparm));
3325
3326		cp->capability = V4L2_CAP_TIMEPERFRAME;
3327		cp->timeperframe.numerator = 1;
3328
3329		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3330
3331		cp->timeperframe.denominator = vcs->fps;
3332
3333		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3334
3335		break;
3336	}
3337	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3338	default:
3339		return -EINVAL;
3340	}
3341
3342	return 0;
3343}
3344
3345static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3346			    struct v4l2_streamparm *sp)
3347{
3348	unsigned long flags;
3349
3350	switch (sp->type) {
3351	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3352		struct v4l2_captureparm *cp = &sp->parm.capture;
3353
3354		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3355
3356		if ((cp->timeperframe.numerator == 0) ||
3357		    (cp->timeperframe.denominator == 0)) {
3358			/* reset framerate */
3359			vino_set_default_framerate(vcs);
3360		} else {
3361			vino_set_framerate(vcs, cp->timeperframe.denominator /
3362					   cp->timeperframe.numerator);
3363		}
3364
3365		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3366
3367		// TODO: set buffers according to cp->readbuffers
3368		break;
3369	}
3370	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3371	default:
3372		return -EINVAL;
3373	}
3374
3375	return 0;
3376}
3377
3378static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
3379			     struct v4l2_requestbuffers *rb)
3380{
3381	if (vcs->reading)
3382		return -EBUSY;
3383
3384	switch (rb->type) {
3385	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3386		// TODO: check queue type
3387		if (rb->memory != V4L2_MEMORY_MMAP) {
3388			dprintk("type not mmap\n");
3389			return -EINVAL;
3390		}
3391
3392		dprintk("count = %d\n", rb->count);
3393		if (rb->count > 0) {
3394			if (vino_is_capturing(vcs)) {
3395				dprintk("busy, capturing\n");
3396				return -EBUSY;
3397			}
3398
3399			if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3400				dprintk("busy, buffers still mapped\n");
3401				return -EBUSY;
3402			} else {
3403				vcs->streaming = 0;
3404				vino_queue_free(&vcs->fb_queue);
3405				vino_queue_init(&vcs->fb_queue, &rb->count);
3406			}
3407		} else {
3408			vcs->streaming = 0;
3409			vino_capture_stop(vcs);
3410			vino_queue_free(&vcs->fb_queue);
3411		}
3412		break;
3413	}
3414	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3415	default:
3416		return -EINVAL;
3417	}
3418
3419	return 0;
3420}
3421
3422static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
3423					struct vino_framebuffer *fb,
3424					struct v4l2_buffer *b)
3425{
3426	if (vino_queue_outgoing_contains(&vcs->fb_queue,
3427					 fb->id)) {
3428		b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3429		b->flags |= V4L2_BUF_FLAG_DONE;
3430	} else if (vino_queue_incoming_contains(&vcs->fb_queue,
3431				       fb->id)) {
3432		b->flags &= ~V4L2_BUF_FLAG_DONE;
3433		b->flags |= V4L2_BUF_FLAG_QUEUED;
3434	} else {
3435		b->flags &= ~(V4L2_BUF_FLAG_DONE |
3436			      V4L2_BUF_FLAG_QUEUED);
3437	}
3438
3439	b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
3440
3441	if (fb->map_count > 0)
3442		b->flags |= V4L2_BUF_FLAG_MAPPED;
3443
3444	b->index = fb->id;
3445	b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
3446		V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
3447	b->m.offset = fb->offset;
3448	b->bytesused = fb->data_size;
3449	b->length = fb->size;
3450	b->field = V4L2_FIELD_INTERLACED;
3451	b->sequence = fb->frame_counter;
3452	memcpy(&b->timestamp, &fb->timestamp,
3453	       sizeof(struct timeval));
3454	// b->input ?
3455
3456	dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
3457		fb->id, fb->size, fb->data_size, fb->offset);
3458}
3459
3460static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
3461			      struct v4l2_buffer *b)
3462{
3463	if (vcs->reading)
3464		return -EBUSY;
3465
3466	switch (b->type) {
3467	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3468		struct vino_framebuffer *fb;
3469
3470		// TODO: check queue type
3471		if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3472			dprintk("invalid index = %d\n",
3473			       b->index);
3474			return -EINVAL;
3475		}
3476
3477		fb = vino_queue_get_buffer(&vcs->fb_queue,
3478					   b->index);
3479		if (fb == NULL) {
3480			dprintk("vino_queue_get_buffer() failed");
3481			return -EINVAL;
3482		}
3483
3484		vino_v4l2_get_buffer_status(vcs, fb, b);
3485		break;
3486	}
3487	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3488	default:
3489		return -EINVAL;
3490	}
3491
3492	return 0;
3493}
3494
3495static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
3496			  struct v4l2_buffer *b)
3497{
3498	if (vcs->reading)
3499		return -EBUSY;
3500
3501	switch (b->type) {
3502	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3503		struct vino_framebuffer *fb;
3504		int ret;
3505
3506		// TODO: check queue type
3507		if (b->memory != V4L2_MEMORY_MMAP) {
3508			dprintk("type not mmap\n");
3509			return -EINVAL;
3510		}
3511
3512		fb = vino_capture_enqueue(vcs, b->index);
3513		if (fb == NULL)
3514			return -EINVAL;
3515
3516		vino_v4l2_get_buffer_status(vcs, fb, b);
3517
3518		if (vcs->streaming) {
3519			ret = vino_capture_next(vcs, 1);
3520			if (ret)
3521				return ret;
3522		}
3523		break;
3524	}
3525	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3526	default:
3527		return -EINVAL;
3528	}
3529
3530	return 0;
3531}
3532
3533static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3534			   struct v4l2_buffer *b,
3535			   unsigned int nonblocking)
3536{
3537	if (vcs->reading)
3538		return -EBUSY;
3539
3540	switch (b->type) {
3541	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3542		struct vino_framebuffer *fb;
3543		unsigned int incoming, outgoing;
3544		int err;
3545
3546		// TODO: check queue type
3547
3548		err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3549		if (err) {
3550			dprintk("vino_queue_get_incoming() failed\n");
3551			return -EINVAL;
3552		}
3553		err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3554		if (err) {
3555			dprintk("vino_queue_get_outgoing() failed\n");
3556			return -EINVAL;
3557		}
3558
3559		dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3560
3561		if (outgoing == 0) {
3562			if (incoming == 0) {
3563				dprintk("no incoming or outgoing buffers\n");
3564				return -EINVAL;
3565			}
3566			if (nonblocking) {
3567				dprintk("non-blocking I/O was selected and "
3568					"there are no buffers to dequeue\n");
3569				return -EAGAIN;
3570			}
3571
3572			err = vino_wait_for_frame(vcs);
3573			if (err) {
3574				err = vino_wait_for_frame(vcs);
3575				if (err) {
3576					/* interrupted or
3577					 * no frames captured because
3578					 * of frame skipping */
3579					// vino_capture_failed(vcs);
3580					return -EIO;
3581				}
3582			}
3583		}
3584
3585		fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3586		if (fb == NULL) {
3587			dprintk("vino_queue_remove() failed\n");
3588			return -EINVAL;
3589		}
3590
3591		err = vino_check_buffer(vcs, fb);
3592
3593		vino_v4l2_get_buffer_status(vcs, fb, b);
3594
3595		if (err)
3596			return -EIO;
3597
3598		break;
3599	}
3600	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3601	default:
3602		return -EINVAL;
3603	}
3604
3605	return 0;
3606}
3607
3608static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
3609{
3610	unsigned int incoming;
3611	int ret;
3612	if (vcs->reading)
3613		return -EBUSY;
3614
3615	if (vcs->streaming)
3616		return 0;
3617
3618	// TODO: check queue type
3619
3620	if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3621		dprintk("no buffers allocated\n");
3622		return -EINVAL;
3623	}
3624
3625	ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3626	if (ret) {
3627		dprintk("vino_queue_get_incoming() failed\n");
3628		return -EINVAL;
3629	}
3630
3631	vcs->streaming = 1;
3632
3633	if (incoming > 0) {
3634		ret = vino_capture_next(vcs, 1);
3635		if (ret) {
3636			vcs->streaming = 0;
3637
3638			dprintk("couldn't start capture\n");
3639			return -EINVAL;
3640		}
3641	}
3642
3643	return 0;
3644}
3645
3646static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3647{
3648	if (vcs->reading)
3649		return -EBUSY;
3650
3651	if (!vcs->streaming)
3652		return 0;
3653
3654	vcs->streaming = 0;
3655	vino_capture_stop(vcs);
3656
3657	return 0;
3658}
3659
3660static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3661			       struct v4l2_queryctrl *queryctrl)
3662{
3663	unsigned long flags;
3664	int i;
3665	int err = 0;
3666
3667	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3668
3669	switch (vcs->input) {
3670	case VINO_INPUT_D1:
3671		for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3672			if (vino_indycam_v4l2_controls[i].id ==
3673			    queryctrl->id) {
3674				memcpy(queryctrl,
3675				       &vino_indycam_v4l2_controls[i],
3676				       sizeof(struct v4l2_queryctrl));
3677				queryctrl->reserved[0] = 0;
3678				goto found;
3679			}
3680		}
3681
3682		err =  -EINVAL;
3683		break;
3684	case VINO_INPUT_COMPOSITE:
3685	case VINO_INPUT_SVIDEO:
3686		for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3687			if (vino_saa7191_v4l2_controls[i].id ==
3688			    queryctrl->id) {
3689				memcpy(queryctrl,
3690				       &vino_saa7191_v4l2_controls[i],
3691				       sizeof(struct v4l2_queryctrl));
3692				queryctrl->reserved[0] = 0;
3693				goto found;
3694			}
3695		}
3696
3697		err =  -EINVAL;
3698		break;
3699	default:
3700		err =  -EINVAL;
3701	}
3702
3703 found:
3704	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3705
3706	return err;
3707}
3708
3709static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
3710			    struct v4l2_control *control)
3711{
3712	unsigned long flags;
3713	int i;
3714	int err = 0;
3715
3716	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3717
3718	switch (vcs->input) {
3719	case VINO_INPUT_D1: {
3720		struct indycam_control indycam_ctrl;
3721
3722		for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3723			if (vino_indycam_v4l2_controls[i].id ==
3724			    control->id) {
3725				goto found1;
3726			}
3727		}
3728
3729		err = -EINVAL;
3730		goto out;
3731
3732found1:
3733		indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
3734
3735		err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
3736					 &indycam_ctrl);
3737		if (err) {
3738			err = -EINVAL;
3739			goto out;
3740		}
3741
3742		control->value = indycam_ctrl.value;
3743		break;
3744	}
3745	case VINO_INPUT_COMPOSITE:
3746	case VINO_INPUT_SVIDEO: {
3747		struct saa7191_control saa7191_ctrl;
3748
3749		for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3750			if (vino_saa7191_v4l2_controls[i].id ==
3751			    control->id) {
3752				goto found2;
3753			}
3754		}
3755
3756		err = -EINVAL;
3757		goto out;
3758
3759found2:
3760		saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
3761
3762		err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
3763					  &saa7191_ctrl);
3764		if (err) {
3765			err = -EINVAL;
3766			goto out;
3767		}
3768
3769		control->value = saa7191_ctrl.value;
3770		break;
3771	}
3772	default:
3773		err =  -EINVAL;
3774	}
3775
3776out:
3777	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3778
3779	return err;
3780}
3781
3782static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
3783			    struct v4l2_control *control)
3784{
3785	unsigned long flags;
3786	int i;
3787	int err = 0;
3788
3789	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3790
3791	if (!vino_is_input_owner(vcs)) {
3792		err = -EBUSY;
3793		goto out;
3794	}
3795
3796	switch (vcs->input) {
3797	case VINO_INPUT_D1: {
3798		struct indycam_control indycam_ctrl;
3799
3800		for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3801			if (vino_indycam_v4l2_controls[i].id ==
3802			    control->id) {
3803				if ((control->value >=
3804				     vino_indycam_v4l2_controls[i].minimum)
3805				    && (control->value <=
3806					vino_indycam_v4l2_controls[i].
3807					maximum)) {
3808					goto found1;
3809				} else {
3810					err = -ERANGE;
3811					goto out;
3812				}
3813			}
3814		}
3815
3816		err = -EINVAL;
3817		goto out;
3818
3819found1:
3820		indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
3821		indycam_ctrl.value = control->value;
3822
3823		err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
3824					 &indycam_ctrl);
3825		if (err)
3826			err = -EINVAL;
3827		break;
3828	}
3829	case VINO_INPUT_COMPOSITE:
3830	case VINO_INPUT_SVIDEO: {
3831		struct saa7191_control saa7191_ctrl;
3832
3833		for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3834			if (vino_saa7191_v4l2_controls[i].id ==
3835			    control->id) {
3836				if ((control->value >=
3837				     vino_saa7191_v4l2_controls[i].minimum)
3838				    && (control->value <=
3839					vino_saa7191_v4l2_controls[i].
3840					maximum)) {
3841					goto found2;
3842				} else {
3843					err = -ERANGE;
3844					goto out;
3845				}
3846			}
3847		}
3848		err = -EINVAL;
3849		goto out;
3850
3851found2:
3852		saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
3853		saa7191_ctrl.value = control->value;
3854
3855		err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
3856					  &saa7191_ctrl);
3857		if (err)
3858			err = -EINVAL;
3859		break;
3860	}
3861	default:
3862		err =  -EINVAL;
3863	}
3864
3865out:
3866	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3867
3868	return err;
3869}
3870
3871/* File operations */
3872
3873static int vino_open(struct inode *inode, struct file *file)
3874{
3875	struct video_device *dev = video_devdata(file);
3876	struct vino_channel_settings *vcs = video_get_drvdata(dev);
3877	int ret = 0;
3878	dprintk("open(): channel = %c\n",
3879	       (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3880
3881	mutex_lock(&vcs->mutex);
3882
3883	if (vcs->users) {
3884		dprintk("open(): driver busy\n");
3885		ret = -EBUSY;
3886		goto out;
3887	}
3888
3889	ret = vino_acquire_input(vcs);
3890	if (ret) {
3891		dprintk("open(): vino_acquire_input() failed\n");
3892		goto out;
3893	}
3894
3895	vcs->users++;
3896
3897 out:
3898	mutex_unlock(&vcs->mutex);
3899
3900	dprintk("open(): %s!\n", ret ? "failed" : "complete");
3901
3902	return ret;
3903}
3904
3905static int vino_close(struct inode *inode, struct file *file)
3906{
3907	struct video_device *dev = video_devdata(file);
3908	struct vino_channel_settings *vcs = video_get_drvdata(dev);
3909	dprintk("close():\n");
3910
3911	mutex_lock(&vcs->mutex);
3912
3913	vcs->users--;
3914
3915	if (!vcs->users) {
3916		vino_release_input(vcs);
3917
3918		/* stop DMA and free buffers */
3919		vino_capture_stop(vcs);
3920		vino_queue_free(&vcs->fb_queue);
3921	}
3922
3923	mutex_unlock(&vcs->mutex);
3924
3925	return 0;
3926}
3927
3928static void vino_vm_open(struct vm_area_struct *vma)
3929{
3930	struct vino_framebuffer *fb = vma->vm_private_data;
3931
3932	fb->map_count++;
3933	dprintk("vino_vm_open(): count = %d\n", fb->map_count);
3934}
3935
3936static void vino_vm_close(struct vm_area_struct *vma)
3937{
3938	struct vino_framebuffer *fb = vma->vm_private_data;
3939
3940	fb->map_count--;
3941	dprintk("vino_vm_close(): count = %d\n", fb->map_count);
3942}
3943
3944static struct vm_operations_struct vino_vm_ops = {
3945	.open	= vino_vm_open,
3946	.close	= vino_vm_close,
3947};
3948
3949static int vino_mmap(struct file *file, struct vm_area_struct *vma)
3950{
3951	struct video_device *dev = video_devdata(file);
3952	struct vino_channel_settings *vcs = video_get_drvdata(dev);
3953
3954	unsigned long start = vma->vm_start;
3955	unsigned long size = vma->vm_end - vma->vm_start;
3956	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3957
3958	struct vino_framebuffer *fb = NULL;
3959	unsigned int i, length;
3960	int ret = 0;
3961
3962	dprintk("mmap():\n");
3963
3964	// TODO: reject mmap if already mapped
3965
3966	if (mutex_lock_interruptible(&vcs->mutex))
3967		return -EINTR;
3968
3969	if (vcs->reading) {
3970		ret = -EBUSY;
3971		goto out;
3972	}
3973
3974	// TODO: check queue type
3975
3976	if (!(vma->vm_flags & VM_WRITE)) {
3977		dprintk("mmap(): app bug: PROT_WRITE please\n");
3978		ret = -EINVAL;
3979		goto out;
3980	}
3981	if (!(vma->vm_flags & VM_SHARED)) {
3982		dprintk("mmap(): app bug: MAP_SHARED please\n");
3983		ret = -EINVAL;
3984		goto out;
3985	}
3986
3987	/* find the correct buffer using offset */
3988	length = vino_queue_get_length(&vcs->fb_queue);
3989	if (length == 0) {
3990		dprintk("mmap(): queue not initialized\n");
3991		ret = -EINVAL;
3992		goto out;
3993	}
3994
3995	for (i = 0; i < length; i++) {
3996		fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3997		if (fb == NULL) {
3998			dprintk("mmap(): vino_queue_get_buffer() failed\n");
3999			ret = -EINVAL;
4000			goto out;
4001		}
4002
4003		if (fb->offset == offset)
4004			goto found;
4005	}
4006
4007	dprintk("mmap(): invalid offset = %lu\n", offset);
4008	ret = -EINVAL;
4009	goto out;
4010
4011found:
4012	dprintk("mmap(): buffer = %d\n", i);
4013
4014	if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
4015		dprintk("mmap(): failed: size = %lu > %lu\n",
4016			size, fb->desc_table.page_count * PAGE_SIZE);
4017		ret = -EINVAL;
4018		goto out;
4019	}
4020
4021	for (i = 0; i < fb->desc_table.page_count; i++) {
4022		unsigned long pfn =
4023			virt_to_phys((void *)fb->desc_table.virtual[i]) >>
4024			PAGE_SHIFT;
4025
4026		if (size < PAGE_SIZE)
4027			break;
4028
4029		// protection was: PAGE_READONLY
4030		if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
4031				    vma->vm_page_prot)) {
4032			dprintk("mmap(): remap_pfn_range() failed\n");
4033			ret = -EAGAIN;
4034			goto out;
4035		}
4036
4037		start += PAGE_SIZE;
4038		size -= PAGE_SIZE;
4039	}
4040
4041	fb->map_count = 1;
4042
4043	vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
4044	vma->vm_flags &= ~VM_IO;
4045	vma->vm_private_data = fb;
4046	vma->vm_file = file;
4047	vma->vm_ops = &vino_vm_ops;
4048
4049out:
4050	mutex_unlock(&vcs->mutex);
4051
4052	return ret;
4053}
4054
4055static unsigned int vino_poll(struct file *file, poll_table *pt)
4056{
4057	struct video_device *dev = video_devdata(file);
4058	struct vino_channel_settings *vcs = video_get_drvdata(dev);
4059	unsigned int outgoing;
4060	unsigned int ret = 0;
4061
4062	// lock mutex (?)
4063	// TODO: this has to be corrected for different read modes
4064
4065	dprintk("poll():\n");
4066
4067	if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
4068		dprintk("poll(): vino_queue_get_outgoing() failed\n");
4069		ret = POLLERR;
4070		goto error;
4071	}
4072	if (outgoing > 0)
4073		goto over;
4074
4075	poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
4076
4077	if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
4078		dprintk("poll(): vino_queue_get_outgoing() failed\n");
4079		ret = POLLERR;
4080		goto error;
4081	}
4082
4083over:
4084	dprintk("poll(): data %savailable\n",
4085		(outgoing > 0) ? "" : "not ");
4086
4087	if (outgoing > 0)
4088		ret = POLLIN | POLLRDNORM;
4089
4090error:
4091
4092	return ret;
4093}
4094
4095static int vino_do_ioctl(struct inode *inode, struct file *file,
4096		      unsigned int cmd, void *arg)
4097{
4098	struct video_device *dev = video_devdata(file);
4099	struct vino_channel_settings *vcs = video_get_drvdata(dev);
4100
4101#ifdef VINO_DEBUG
4102	switch (_IOC_TYPE(cmd)) {
4103	case 'v':
4104		dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
4105		break;
4106	case 'V':
4107		dprintk("ioctl(): V4L2 %s (0x%08x)\n",
4108			v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
4109		break;
4110	default:
4111		dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
4112	}
4113#endif
4114
4115	switch (cmd) {
4116	/* V4L2 interface */
4117	case VIDIOC_QUERYCAP: {
4118		vino_v4l2_querycap(arg);
4119		break;
4120	}
4121	case VIDIOC_ENUMINPUT: {
4122		return vino_v4l2_enuminput(vcs, arg);
4123	}
4124	case VIDIOC_G_INPUT: {
4125		return vino_v4l2_g_input(vcs, arg);
4126	}
4127	case VIDIOC_S_INPUT: {
4128		return vino_v4l2_s_input(vcs, arg);
4129	}
4130	case VIDIOC_ENUMSTD: {
4131		return vino_v4l2_enumstd(vcs, arg);
4132	}
4133	case VIDIOC_QUERYSTD: {
4134		return vino_v4l2_querystd(vcs, arg);
4135	}
4136	case VIDIOC_G_STD: {
4137		return vino_v4l2_g_std(vcs, arg);
4138	}
4139	case VIDIOC_S_STD: {
4140		return vino_v4l2_s_std(vcs, arg);
4141	}
4142	case VIDIOC_ENUM_FMT: {
4143		return vino_v4l2_enum_fmt(vcs, arg);
4144	}
4145	case VIDIOC_TRY_FMT: {
4146		return vino_v4l2_try_fmt(vcs, arg);
4147	}
4148	case VIDIOC_G_FMT: {
4149		return vino_v4l2_g_fmt(vcs, arg);
4150	}
4151	case VIDIOC_S_FMT: {
4152		return vino_v4l2_s_fmt(vcs, arg);
4153	}
4154	case VIDIOC_CROPCAP: {
4155		return vino_v4l2_cropcap(vcs, arg);
4156	}
4157	case VIDIOC_G_CROP: {
4158		return vino_v4l2_g_crop(vcs, arg);
4159	}
4160	case VIDIOC_S_CROP: {
4161		return vino_v4l2_s_crop(vcs, arg);
4162	}
4163	case VIDIOC_G_PARM: {
4164		return vino_v4l2_g_parm(vcs, arg);
4165	}
4166	case VIDIOC_S_PARM: {
4167		return vino_v4l2_s_parm(vcs, arg);
4168	}
4169	case VIDIOC_REQBUFS: {
4170		return vino_v4l2_reqbufs(vcs, arg);
4171	}
4172	case VIDIOC_QUERYBUF: {
4173		return vino_v4l2_querybuf(vcs, arg);
4174	}
4175	case VIDIOC_QBUF: {
4176		return vino_v4l2_qbuf(vcs, arg);
4177	}
4178	case VIDIOC_DQBUF: {
4179		return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
4180	}
4181	case VIDIOC_STREAMON: {
4182		return vino_v4l2_streamon(vcs);
4183	}
4184	case VIDIOC_STREAMOFF: {
4185		return vino_v4l2_streamoff(vcs);
4186	}
4187	case VIDIOC_QUERYCTRL: {
4188		return vino_v4l2_queryctrl(vcs, arg);
4189	}
4190	case VIDIOC_G_CTRL: {
4191		return vino_v4l2_g_ctrl(vcs, arg);
4192	}
4193	case VIDIOC_S_CTRL: {
4194		return vino_v4l2_s_ctrl(vcs, arg);
4195	}
4196	default:
4197		return -ENOIOCTLCMD;
4198	}
4199
4200	return 0;
4201}
4202
4203static int vino_ioctl(struct inode *inode, struct file *file,
4204		      unsigned int cmd, unsigned long arg)
4205{
4206	struct video_device *dev = video_devdata(file);
4207	struct vino_channel_settings *vcs = video_get_drvdata(dev);
4208	int ret;
4209
4210	if (mutex_lock_interruptible(&vcs->mutex))
4211		return -EINTR;
4212
4213	ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
4214
4215	mutex_unlock(&vcs->mutex);
4216
4217	return ret;
4218}
4219
4220/* Initialization and cleanup */
4221
4222// __initdata
4223static int vino_init_stage = 0;
4224
4225static const struct file_operations vino_fops = {
4226	.owner		= THIS_MODULE,
4227	.open		= vino_open,
4228	.release	= vino_close,
4229	.ioctl		= vino_ioctl,
4230	.mmap		= vino_mmap,
4231	.poll		= vino_poll,
4232	.llseek		= no_llseek,
4233};
4234
4235static struct video_device v4l_device_template = {
4236	.name		= "NOT SET",
4237	//.type		= VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
4238	//	VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
4239	.fops		= &vino_fops,
4240	.minor		= -1,
4241};
4242
4243static void vino_module_cleanup(int stage)
4244{
4245	switch(stage) {
4246	case 10:
4247		video_unregister_device(vino_drvdata->b.v4l_device);
4248		vino_drvdata->b.v4l_device = NULL;
4249	case 9:
4250		video_unregister_device(vino_drvdata->a.v4l_device);
4251		vino_drvdata->a.v4l_device = NULL;
4252	case 8:
4253		vino_i2c_del_bus();
4254	case 7:
4255		free_irq(SGI_VINO_IRQ, NULL);
4256	case 6:
4257		if (vino_drvdata->b.v4l_device) {
4258			video_device_release(vino_drvdata->b.v4l_device);
4259			vino_drvdata->b.v4l_device = NULL;
4260		}
4261	case 5:
4262		if (vino_drvdata->a.v4l_device) {
4263			video_device_release(vino_drvdata->a.v4l_device);
4264			vino_drvdata->a.v4l_device = NULL;
4265		}
4266	case 4:
4267		/* all entries in dma_cpu dummy table have the same address */
4268		dma_unmap_single(NULL,
4269				 vino_drvdata->dummy_desc_table.dma_cpu[0],
4270				 PAGE_SIZE, DMA_FROM_DEVICE);
4271		dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
4272				  * sizeof(dma_addr_t),
4273				  (void *)vino_drvdata->
4274				  dummy_desc_table.dma_cpu,
4275				  vino_drvdata->dummy_desc_table.dma);
4276	case 3:
4277		free_page(vino_drvdata->dummy_page);
4278	case 2:
4279		kfree(vino_drvdata);
4280	case 1:
4281		iounmap(vino);
4282	case 0:
4283		break;
4284	default:
4285		dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
4286			stage);
4287	}
4288}
4289
4290static int vino_probe(void)
4291{
4292	unsigned long rev_id;
4293
4294	if (ip22_is_fullhouse()) {
4295		printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
4296		return -ENODEV;
4297	}
4298
4299	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
4300		printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
4301		return -ENODEV;
4302	}
4303
4304	vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
4305	if (!vino) {
4306		printk(KERN_ERR "VINO: ioremap() failed\n");
4307		return -EIO;
4308	}
4309	vino_init_stage++;
4310
4311	if (get_dbe(rev_id, &(vino->rev_id))) {
4312		printk(KERN_ERR "Failed to read VINO revision register\n");
4313		vino_module_cleanup(vino_init_stage);
4314		return -ENODEV;
4315	}
4316
4317	if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
4318		printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
4319		       rev_id);
4320		vino_module_cleanup(vino_init_stage);
4321		return -ENODEV;
4322	}
4323
4324	printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
4325
4326	return 0;
4327}
4328
4329static int vino_init(void)
4330{
4331	dma_addr_t dma_dummy_address;
4332	int i;
4333
4334	vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
4335	if (!vino_drvdata) {
4336		vino_module_cleanup(vino_init_stage);
4337		return -ENOMEM;
4338	}
4339	vino_init_stage++;
4340
4341	/* create a dummy dma descriptor */
4342	vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
4343	if (!vino_drvdata->dummy_page) {
4344		vino_module_cleanup(vino_init_stage);
4345		return -ENOMEM;
4346	}
4347	vino_init_stage++;
4348
4349	// TODO: use page_count in dummy_desc_table
4350
4351	vino_drvdata->dummy_desc_table.dma_cpu =
4352		dma_alloc_coherent(NULL,
4353		VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
4354		&vino_drvdata->dummy_desc_table.dma,
4355		GFP_KERNEL | GFP_DMA);
4356	if (!vino_drvdata->dummy_desc_table.dma_cpu) {
4357		vino_module_cleanup(vino_init_stage);
4358		return -ENOMEM;
4359	}
4360	vino_init_stage++;
4361
4362	dma_dummy_address = dma_map_single(NULL,
4363					   (void *)vino_drvdata->dummy_page,
4364					PAGE_SIZE, DMA_FROM_DEVICE);
4365	for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
4366		vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
4367	}
4368
4369	/* initialize VINO */
4370
4371	vino->control = 0;
4372	vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4373	vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4374	udelay(VINO_DESC_FETCH_DELAY);
4375
4376	vino->intr_status = 0;
4377
4378	vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4379	vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4380
4381	return 0;
4382}
4383
4384static int vino_init_channel_settings(struct vino_channel_settings *vcs,
4385				 unsigned int channel, const char *name)
4386{
4387	vcs->channel = channel;
4388	vcs->input = VINO_INPUT_NONE;
4389	vcs->alpha = 0;
4390	vcs->users = 0;
4391	vcs->data_format = VINO_DATA_FMT_GREY;
4392	vcs->data_norm = VINO_DATA_NORM_NTSC;
4393	vcs->decimation = 1;
4394	vino_set_default_clipping(vcs);
4395	vino_set_default_framerate(vcs);
4396
4397	vcs->capturing = 0;
4398
4399	mutex_init(&vcs->mutex);
4400	spin_lock_init(&vcs->capture_lock);
4401
4402	mutex_init(&vcs->fb_queue.queue_mutex);
4403	spin_lock_init(&vcs->fb_queue.queue_lock);
4404	init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
4405
4406	vcs->v4l_device = video_device_alloc();
4407	if (!vcs->v4l_device) {
4408		vino_module_cleanup(vino_init_stage);
4409		return -ENOMEM;
4410	}
4411	vino_init_stage++;
4412
4413	memcpy(vcs->v4l_device, &v4l_device_template,
4414	       sizeof(struct video_device));
4415	strcpy(vcs->v4l_device->name, name);
4416	vcs->v4l_device->release = video_device_release;
4417
4418	video_set_drvdata(vcs->v4l_device, vcs);
4419
4420	return 0;
4421}
4422
4423static int __init vino_module_init(void)
4424{
4425	int ret;
4426
4427	printk(KERN_INFO "SGI VINO driver version %s\n",
4428	       VINO_MODULE_VERSION);
4429
4430	ret = vino_probe();
4431	if (ret)
4432		return ret;
4433
4434	ret = vino_init();
4435	if (ret)
4436		return ret;
4437
4438	/* initialize data structures */
4439
4440	spin_lock_init(&vino_drvdata->vino_lock);
4441	spin_lock_init(&vino_drvdata->input_lock);
4442
4443	ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
4444				    vino_v4l_device_name_a);
4445	if (ret)
4446		return ret;
4447
4448	ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4449				    vino_v4l_device_name_b);
4450	if (ret)
4451		return ret;
4452
4453	/* initialize hardware and register V4L devices */
4454
4455	ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4456		vino_driver_description, NULL);
4457	if (ret) {
4458		printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
4459		       SGI_VINO_IRQ);
4460		vino_module_cleanup(vino_init_stage);
4461		return -EAGAIN;
4462	}
4463	vino_init_stage++;
4464
4465	ret = vino_i2c_add_bus();
4466	if (ret) {
4467		printk(KERN_ERR "VINO I2C bus registration failed\n");
4468		vino_module_cleanup(vino_init_stage);
4469		return ret;
4470	}
4471	vino_init_stage++;
4472
4473	ret = video_register_device(vino_drvdata->a.v4l_device,
4474				    VFL_TYPE_GRABBER, -1);
4475	if (ret < 0) {
4476		printk(KERN_ERR "VINO channel A Video4Linux-device "
4477		       "registration failed\n");
4478		vino_module_cleanup(vino_init_stage);
4479		return -EINVAL;
4480	}
4481	vino_init_stage++;
4482
4483	ret = video_register_device(vino_drvdata->b.v4l_device,
4484				    VFL_TYPE_GRABBER, -1);
4485	if (ret < 0) {
4486		printk(KERN_ERR "VINO channel B Video4Linux-device "
4487		       "registration failed\n");
4488		vino_module_cleanup(vino_init_stage);
4489		return -EINVAL;
4490	}
4491	vino_init_stage++;
4492
4493#if defined(CONFIG_KMOD) && defined(MODULE)
4494	request_module("saa7191");
4495	request_module("indycam");
4496#endif
4497
4498	dprintk("init complete!\n");
4499
4500	return 0;
4501}
4502
4503static void __exit vino_module_exit(void)
4504{
4505	dprintk("exiting, stage = %d ...\n", vino_init_stage);
4506	vino_module_cleanup(vino_init_stage);
4507	dprintk("cleanup complete, exit!\n");
4508}
4509
4510module_init(vino_module_init);
4511module_exit(vino_module_exit);
4512