]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/video/vino.c
V4L/DVB (10864): vino: introduce v4l2_device.
[mv-sheeva.git] / drivers / media / video / vino.c
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
61 MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
62 MODULE_VERSION(VINO_MODULE_VERSION);
63 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
64 MODULE_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
146 struct vino_input {
147         char *name;
148         v4l2_std_id std;
149 };
150
151 struct vino_clipping {
152         unsigned int left, right, top, bottom;
153 };
154
155 struct 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
166 struct 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
177 struct 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
192 struct 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
217 struct 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
227 struct 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
245 struct vino_interrupt_data {
246         struct timeval timestamp;
247         unsigned int frame_counter;
248         unsigned int skip_count;
249         unsigned int skip;
250 };
251
252 struct 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
290 struct 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
297 struct 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  */
330 static int vino_pixel_conversion;
331
332 module_param_named(pixelconv, vino_pixel_conversion, int, 0);
333
334 MODULE_PARM_DESC(pixelconv,
335                  "enable pixel conversion (non-zero value enables)");
336
337 /* Internal data structures */
338
339 static struct sgi_vino *vino;
340
341 static struct vino_settings *vino_drvdata;
342
343 static const char *vino_driver_name = "vino";
344 static const char *vino_driver_description = "SGI VINO";
345 static const char *vino_bus_name = "GIO64 bus";
346 static const char *vino_vdev_name_a = "SGI VINO Channel A";
347 static const char *vino_vdev_name_b = "SGI VINO Channel B";
348
349 static void vino_capture_tasklet(unsigned long channel);
350
351 DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
352 DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
353
354 static 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
369 static 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
393 static 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
487 struct 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
565 struct 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
643 unsigned i2c_vino_getctrl(void *data)
644 {
645         return vino->i2c_control;
646 }
647
648 void i2c_vino_setctrl(void *data, unsigned val)
649 {
650         vino->i2c_control = val;
651 }
652
653 unsigned i2c_vino_rdata(void *data)
654 {
655         return vino->i2c_data;
656 }
657
658 void i2c_vino_wdata(void *data, unsigned val)
659 {
660         vino->i2c_data = val;
661 }
662
663 static 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  */
677 static 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
704 static 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
726 static 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
735 static int vino_i2c_add_bus(void)
736 {
737         return i2c_sgi_add_bus(&vino_i2c_adapter);
738 }
739
740 static int vino_i2c_del_bus(void)
741 {
742         return i2c_del_adapter(&vino_i2c_adapter);
743 }
744
745 static 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
752 static 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
761 static 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
785 static void vino_free_buffer(struct vino_framebuffer *fb)
786 {
787         vino_free_buffer_with_count(fb, fb->desc_table.page_count);
788 }
789
790 static 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 */
876 static 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
961 static 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
975 static 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 */
990 static 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 */
1005 static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
1006 {
1007         return (f->used == f->length);
1008 }
1009 #endif
1010
1011 static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
1012 {
1013         return f->used;
1014 }
1015
1016 static 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
1037 static 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
1048 static 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 */
1064 static 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
1083 static 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
1099 static 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
1177 static 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
1214 out:
1215         spin_unlock_irqrestore(&q->queue_lock, flags);
1216
1217         return ret;
1218 }
1219
1220 static 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;
1255 out:
1256         spin_unlock_irqrestore(&q->queue_lock, flags);
1257
1258         return ret;
1259 }
1260
1261 /* returns true/false */
1262 static 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
1279 out:
1280         spin_unlock_irqrestore(&q->queue_lock, flags);
1281
1282         return ret;
1283 }
1284
1285 /* returns true/false */
1286 static 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
1303 out:
1304         spin_unlock_irqrestore(&q->queue_lock, flags);
1305
1306         return ret;
1307 }
1308
1309 static 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
1328 out:
1329         spin_unlock_irqrestore(&q->queue_lock, flags);
1330
1331         return ret;
1332 }
1333
1334 static 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
1353 out:
1354         spin_unlock_irqrestore(&q->queue_lock, flags);
1355
1356         return ret;
1357 }
1358
1359 #if 0
1360 static 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
1380 out:
1381         spin_unlock_irqrestore(&q->queue_lock, flags);
1382
1383         return ret;
1384 }
1385 #endif
1386
1387 static 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];
1408 out:
1409         spin_unlock_irqrestore(&q->queue_lock, flags);
1410
1411         return ret;
1412 }
1413
1414 static 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];
1437 out:
1438         spin_unlock_irqrestore(&q->queue_lock, flags);
1439
1440         return ret;
1441 }
1442
1443 static struct
1444 vino_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
1469 static 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
1485 static 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 */
1510 static 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 */
1532 static 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 */
1582 static 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 */
1589 static 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 */
1619 static 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 */
1626 static 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 */
1698 static 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  */
1708 static 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) */
1852 static 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) */
1863 static 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  */
1879 static 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
1896 static 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
1925 static
1926 struct 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         }
1943 out:
1944         spin_unlock_irqrestore(&vcs->capture_lock, flags);
1945
1946         return fb;
1947 }
1948
1949 static 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
2005 out:
2006         vcs->capturing = 0;
2007         spin_unlock_irqrestore(&vcs->capture_lock, flags);
2008
2009         return err;
2010 }
2011
2012 static 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 */
2027 static 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 */
2054 static 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 */
2074 static 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 */
2114 static 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
2164 out:
2165         spin_unlock_irqrestore(&vcs->capture_lock, flags);
2166 }
2167
2168 #if 0
2169 static 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
2215 static 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
2237 static 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
2265 static 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
2283 static 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
2439 static 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 */
2454 static 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
2467 static 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
2545 out:
2546         spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2547
2548         return ret;
2549 }
2550
2551 static 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
2674 out:
2675         spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2676
2677         return ret;
2678 }
2679
2680 static 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 */
2715 static 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
2763 out:
2764         return err;
2765 }
2766
2767 /* V4L2 helper functions */
2768
2769 static 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
2781 static 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 */
2821 static __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
2860 static 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
2876 static 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
2900 static 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
2924 static 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
2938 static 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
2965 static 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
2981 static 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
3025 out:
3026         spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3027
3028         return ret;
3029 }
3030
3031 static 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
3053 static 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
3099 static 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
3129 static 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
3173 static 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
3206 static 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
3231 static 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
3254 static 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
3285 static 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
3319 static 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
3364 static 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
3402 static 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
3438 static 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
3477 static 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
3553 static 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
3593 static 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
3609 static 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
3659 static 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
3709 out:
3710         spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3711
3712         return err;
3713 }
3714
3715 static 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
3777 out:
3778         spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3779
3780         return err;
3781 }
3782
3783 /* File operations */
3784
3785 static 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
3816 static 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
3838 static 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
3846 static 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
3854 static struct vm_operations_struct vino_vm_ops = {
3855         .open   = vino_vm_open,
3856         .close  = vino_vm_close,
3857 };
3858
3859 static 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
3920 found:
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
3958 out:
3959         mutex_unlock(&vcs->mutex);
3960
3961         return ret;
3962 }
3963
3964 static 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
3991 over:
3992         dprintk("poll(): data %savailable\n",
3993                 (outgoing > 0) ? "" : "not ");
3994
3995         if (outgoing > 0)
3996                 ret = POLLIN | POLLRDNORM;
3997
3998 error:
3999         return ret;
4000 }
4001
4002 static 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 */
4021 static int vino_init_stage;
4022
4023 const 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
4051 static 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
4060 static 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
4068 static 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
4117 static 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
4156 static 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
4218 static 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
4258 static 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
4339 static 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
4346 module_init(vino_module_init);
4347 module_exit(vino_module_exit);