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