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