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