[PATCH] UHCI: unify BIOS handoff and driver reset code
[linux-2.6/suspend2-2.6.18.git] / drivers / media / video / vino.c
blobd8a0f763ca101314d18f1c501631dca62d125f62
1 /*
2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
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.
7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
9 * Based on the previous version of the driver for 2.4 kernels by:
10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
14 * TODO:
15 * - remove "hacks" from memory allocation code and implement nopage()
16 * - check decimation, calculating and reporting image size when
17 * using decimation
18 * - check vino_acquire_input(), vino_set_input() and channel
19 * ownership handling
20 * - report VINO error-interrupts via ioctls ?
21 * - implement picture controls (all implemented?)
22 * - use macros for boolean values (?)
23 * - implement user mode buffers and overlay (?)
26 #include <linux/init.h>
27 #include <linux/module.h>
28 #include <linux/delay.h>
29 #include <linux/errno.h>
30 #include <linux/fs.h>
31 #include <linux/kernel.h>
32 #include <linux/mm.h>
33 #include <linux/interrupt.h>
34 #include <linux/dma-mapping.h>
35 #include <linux/time.h>
36 #include <linux/moduleparam.h>
38 #ifdef CONFIG_KMOD
39 #include <linux/kmod.h>
40 #endif
42 #include <linux/i2c.h>
43 #include <linux/i2c-algo-sgi.h>
45 #include <linux/videodev.h>
46 #include <linux/videodev2.h>
47 #include <linux/video_decoder.h>
49 #include <asm/paccess.h>
50 #include <asm/io.h>
51 #include <asm/sgi/ip22.h>
52 #include <asm/sgi/mc.h>
54 #include "vino.h"
55 #include "saa7191.h"
56 #include "indycam.h"
58 /* Uncomment the following line to get lots and lots of (mostly useless)
59 * debug info.
60 * Note that the debug output also slows down the driver significantly */
61 // #define VINO_DEBUG
63 #define VINO_MODULE_VERSION "0.0.3"
64 #define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 3)
66 MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
67 MODULE_VERSION(VINO_MODULE_VERSION);
68 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
69 MODULE_LICENSE("GPL");
71 #define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags))
72 #define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags))
74 #ifdef VINO_DEBUG
75 #define dprintk(x...) printk("VINO: " x);
76 #else
77 #define dprintk(x...)
78 #endif
80 #define VINO_NO_CHANNEL 0
81 #define VINO_CHANNEL_A 1
82 #define VINO_CHANNEL_B 2
84 #define VINO_PAL_WIDTH 768
85 #define VINO_PAL_HEIGHT 576
86 #define VINO_NTSC_WIDTH 640
87 #define VINO_NTSC_HEIGHT 480
89 #define VINO_MIN_WIDTH 32
90 #define VINO_MIN_HEIGHT 32
92 #define VINO_CLIPPING_START_ODD_D1 1
93 #define VINO_CLIPPING_START_ODD_PAL 1
94 #define VINO_CLIPPING_START_ODD_NTSC 1
96 #define VINO_CLIPPING_START_EVEN_D1 2
97 #define VINO_CLIPPING_START_EVEN_PAL 2
98 #define VINO_CLIPPING_START_EVEN_NTSC 2
100 #define VINO_INPUT_CHANNEL_COUNT 3
102 #define VINO_INPUT_NONE -1
103 #define VINO_INPUT_COMPOSITE 0
104 #define VINO_INPUT_SVIDEO 1
105 #define VINO_INPUT_D1 2
107 #define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
109 #define VINO_FIFO_THRESHOLD_DEFAULT 512
111 /*#define VINO_FRAMEBUFFER_SIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 \
112 + 2 * PAGE_SIZE)*/
113 #define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
114 * VINO_PAL_HEIGHT * 4 \
115 + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
117 #define VINO_FRAMEBUFFER_MAX_COUNT 8
119 #define VINO_FRAMEBUFFER_UNUSED 0
120 #define VINO_FRAMEBUFFER_IN_USE 1
121 #define VINO_FRAMEBUFFER_READY 2
123 #define VINO_QUEUE_ERROR -1
124 #define VINO_QUEUE_MAGIC 0x20050125
126 #define VINO_MEMORY_NONE 0
127 #define VINO_MEMORY_MMAP 1
128 #define VINO_MEMORY_USERPTR 2
130 #define VINO_DUMMY_DESC_COUNT 4
131 #define VINO_DESC_FETCH_DELAY 5 /* microseconds */
133 /* the number is the index for vino_data_formats */
134 #define VINO_DATA_FMT_NONE -1
135 #define VINO_DATA_FMT_GREY 0
136 #define VINO_DATA_FMT_RGB332 1
137 #define VINO_DATA_FMT_RGB32 2
138 #define VINO_DATA_FMT_YUV 3
139 //#define VINO_DATA_FMT_RGB24 4
141 #define VINO_DATA_FMT_COUNT 4
143 #define VINO_DATA_NORM_NONE -1
144 #define VINO_DATA_NORM_NTSC 0
145 #define VINO_DATA_NORM_PAL 1
146 #define VINO_DATA_NORM_SECAM 2
147 #define VINO_DATA_NORM_D1 3
148 /* The following is a special entry that can be used to
149 * autodetect the norm. */
150 #define VINO_DATA_NORM_AUTO 0xff
152 #define VINO_DATA_NORM_COUNT 4
154 /* Internal data structure definitions */
156 struct vino_input {
157 char *name;
158 v4l2_std_id std;
161 struct vino_clipping {
162 unsigned int left, right, top, bottom;
165 struct vino_data_format {
166 /* the description */
167 char *description;
168 /* bytes per pixel */
169 unsigned int bpp;
170 /* V4L2 fourcc code */
171 __u32 pixelformat;
172 /* V4L2 colorspace (duh!) */
173 enum v4l2_colorspace colorspace;
176 struct vino_data_norm {
177 char *description;
178 unsigned int width, height;
179 struct vino_clipping odd;
180 struct vino_clipping even;
182 v4l2_std_id std;
183 unsigned int fps_min, fps_max;
184 __u32 framelines;
187 struct vino_descriptor_table {
188 /* the number of PAGE_SIZE sized pages in the buffer */
189 unsigned int page_count;
190 /* virtual (kmalloc'd) pointers to the actual data
191 * (in PAGE_SIZE chunks, used with mmap streaming) */
192 unsigned long *virtual;
194 /* cpu address for the VINO descriptor table
195 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
196 unsigned long *dma_cpu;
197 /* dma address for the VINO descriptor table
198 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
199 dma_addr_t dma;
202 struct vino_framebuffer {
203 /* identifier nubmer */
204 unsigned int id;
205 /* the length of the whole buffer */
206 unsigned int size;
207 /* the length of actual data in buffer */
208 unsigned int data_size;
209 /* the data format */
210 unsigned int data_format;
211 /* the state of buffer data */
212 unsigned int state;
213 /* is the buffer mapped in user space? */
214 unsigned int map_count;
215 /* memory offset for mmap() */
216 unsigned int offset;
217 /* frame counter */
218 unsigned int frame_counter;
219 /* timestamp (written when image capture finishes) */
220 struct timeval timestamp;
222 struct vino_descriptor_table desc_table;
224 spinlock_t state_lock;
227 struct vino_framebuffer_fifo {
228 unsigned int length;
230 unsigned int used;
231 unsigned int head;
232 unsigned int tail;
234 unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT];
237 struct vino_framebuffer_queue {
238 unsigned int magic;
240 /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
241 unsigned int type;
242 unsigned int length;
244 /* data field of in and out contain index numbers for buffer */
245 struct vino_framebuffer_fifo in;
246 struct vino_framebuffer_fifo out;
248 struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_MAX_COUNT];
250 spinlock_t queue_lock;
251 struct semaphore queue_sem;
252 wait_queue_head_t frame_wait_queue;
255 struct vino_channel_settings {
256 unsigned int channel;
258 int input;
259 unsigned int data_format;
260 unsigned int data_norm;
261 struct vino_clipping clipping;
262 unsigned int decimation;
263 unsigned int line_size;
264 unsigned int alpha;
265 unsigned int fps;
266 unsigned int framert_reg;
268 unsigned int fifo_threshold;
270 struct vino_framebuffer_queue fb_queue;
272 /* number of the current field */
273 unsigned int field;
275 /* read in progress */
276 int reading;
277 /* streaming is active */
278 int streaming;
279 /* the driver is currently processing the queue */
280 int capturing;
282 struct semaphore sem;
283 spinlock_t capture_lock;
285 unsigned int users;
287 /* V4L support */
288 struct video_device *v4l_device;
291 struct vino_client {
292 /* the channel which owns this client:
293 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
294 unsigned int owner;
295 struct i2c_client *driver;
298 struct vino_settings {
299 struct vino_channel_settings a;
300 struct vino_channel_settings b;
302 struct vino_client decoder;
303 struct vino_client camera;
305 /* a lock for vino register access */
306 spinlock_t vino_lock;
307 /* a lock for channel input changes */
308 spinlock_t input_lock;
310 unsigned long dummy_page;
311 struct vino_descriptor_table dummy_desc_table;
314 /* Module parameters */
317 * Using vino_pixel_conversion the ARGB32-format pixels supplied
318 * by the VINO chip can be converted to more common formats
319 * like RGBA32 (or probably RGB24 in the future). This way we
320 * can give out data that can be specified correctly with
321 * the V4L2-definitions.
323 * The pixel format is specified as RGBA32 when no conversion
324 * is used.
326 * Note that this only affects the 32-bit bit depth.
328 * Use non-zero value to enable conversion.
330 static int vino_pixel_conversion = 0;
331 module_param_named(pixelconv, vino_pixel_conversion, int, 0);
332 MODULE_PARM_DESC(pixelconv,
333 "enable pixel conversion (non-zero value enables)");
335 /* Internal data structures */
337 static struct sgi_vino *vino;
339 static struct vino_settings *vino_drvdata;
341 static const char *vino_driver_name = "vino";
342 static const char *vino_driver_description = "SGI VINO";
343 static const char *vino_bus_name = "GIO64 bus";
344 static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
345 static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
347 static const struct vino_input vino_inputs[] = {
349 .name = "Composite",
350 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
352 .name = "S-Video",
353 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
355 .name = "D1 (IndyCam)",
356 .std = V4L2_STD_NTSC,
360 static const struct vino_data_format vino_data_formats[] = {
362 .description = "8-bit greyscale",
363 .bpp = 1,
364 .pixelformat = V4L2_PIX_FMT_GREY,
365 .colorspace = V4L2_COLORSPACE_SMPTE170M,
367 .description = "8-bit dithered RGB 3-3-2",
368 .bpp = 1,
369 .pixelformat = V4L2_PIX_FMT_RGB332,
370 .colorspace = V4L2_COLORSPACE_SRGB,
372 .description = "32-bit RGB",
373 .bpp = 4,
374 .pixelformat = V4L2_PIX_FMT_RGB32,
375 .colorspace = V4L2_COLORSPACE_SRGB,
377 .description = "YUV 4:2:2",
378 .bpp = 4,
379 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
380 .colorspace = V4L2_COLORSPACE_SMPTE170M,
381 }/*,{
382 .description = "24-bit RGB",
383 .bpp = 3,
384 .pixelformat = V4L2_PIX_FMT_RGB24,
385 .colorspace = V4L2_COLORSPACE_SRGB,
389 static const struct vino_data_norm vino_data_norms[] = {
391 .description = "NTSC",
392 .std = V4L2_STD_NTSC,
393 .fps_min = 6,
394 .fps_max = 30,
395 .framelines = 525,
396 .width = VINO_NTSC_WIDTH,
397 .height = VINO_NTSC_HEIGHT,
398 .odd = {
399 .top = VINO_CLIPPING_START_ODD_NTSC,
400 .left = 0,
401 .bottom = VINO_CLIPPING_START_ODD_NTSC
402 + VINO_NTSC_HEIGHT / 2 - 1,
403 .right = VINO_NTSC_WIDTH,
405 .even = {
406 .top = VINO_CLIPPING_START_EVEN_NTSC,
407 .left = 0,
408 .bottom = VINO_CLIPPING_START_EVEN_NTSC
409 + VINO_NTSC_HEIGHT / 2 - 1,
410 .right = VINO_NTSC_WIDTH,
413 .description = "PAL",
414 .std = V4L2_STD_PAL,
415 .fps_min = 5,
416 .fps_max = 25,
417 .framelines = 625,
418 .width = VINO_PAL_WIDTH,
419 .height = VINO_PAL_HEIGHT,
420 .odd = {
421 .top = VINO_CLIPPING_START_ODD_PAL,
422 .left = 0,
423 .bottom = VINO_CLIPPING_START_ODD_PAL
424 + VINO_PAL_HEIGHT / 2 - 1,
425 .right = VINO_PAL_WIDTH,
427 .even = {
428 .top = VINO_CLIPPING_START_EVEN_PAL,
429 .left = 0,
430 .bottom = VINO_CLIPPING_START_EVEN_PAL
431 + VINO_PAL_HEIGHT / 2 - 1,
432 .right = VINO_PAL_WIDTH,
435 .description = "SECAM",
436 .std = V4L2_STD_SECAM,
437 .fps_min = 5,
438 .fps_max = 25,
439 .framelines = 625,
440 .width = VINO_PAL_WIDTH,
441 .height = VINO_PAL_HEIGHT,
442 .odd = {
443 .top = VINO_CLIPPING_START_ODD_PAL,
444 .left = 0,
445 .bottom = VINO_CLIPPING_START_ODD_PAL
446 + VINO_PAL_HEIGHT / 2 - 1,
447 .right = VINO_PAL_WIDTH,
449 .even = {
450 .top = VINO_CLIPPING_START_EVEN_PAL,
451 .left = 0,
452 .bottom = VINO_CLIPPING_START_EVEN_PAL
453 + VINO_PAL_HEIGHT / 2 - 1,
454 .right = VINO_PAL_WIDTH,
457 .description = "NTSC (D1 input)",
458 .std = V4L2_STD_NTSC,
459 .fps_min = 6,
460 .fps_max = 30,
461 .framelines = 525,
462 .width = VINO_NTSC_WIDTH,
463 .height = VINO_NTSC_HEIGHT,
464 .odd = {
465 .top = VINO_CLIPPING_START_ODD_D1,
466 .left = 0,
467 .bottom = VINO_CLIPPING_START_ODD_D1
468 + VINO_NTSC_HEIGHT / 2 - 1,
469 .right = VINO_NTSC_WIDTH,
471 .even = {
472 .top = VINO_CLIPPING_START_EVEN_D1,
473 .left = 0,
474 .bottom = VINO_CLIPPING_START_EVEN_D1
475 + VINO_NTSC_HEIGHT / 2 - 1,
476 .right = VINO_NTSC_WIDTH,
481 #define VINO_INDYCAM_V4L2_CONTROL_COUNT 9
483 struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
485 .id = V4L2_CID_AUTOGAIN,
486 .type = V4L2_CTRL_TYPE_BOOLEAN,
487 .name = "Automatic Gain Control",
488 .minimum = 0,
489 .maximum = 1,
490 .step = 1,
491 .default_value = INDYCAM_AGC_DEFAULT,
492 .flags = 0,
493 .reserved = { 0, 0 },
495 .id = V4L2_CID_AUTO_WHITE_BALANCE,
496 .type = V4L2_CTRL_TYPE_BOOLEAN,
497 .name = "Automatic White Balance",
498 .minimum = 0,
499 .maximum = 1,
500 .step = 1,
501 .default_value = INDYCAM_AWB_DEFAULT,
502 .flags = 0,
503 .reserved = { 0, 0 },
505 .id = V4L2_CID_GAIN,
506 .type = V4L2_CTRL_TYPE_INTEGER,
507 .name = "Gain",
508 .minimum = INDYCAM_GAIN_MIN,
509 .maximum = INDYCAM_GAIN_MAX,
510 .step = 1,
511 .default_value = INDYCAM_GAIN_DEFAULT,
512 .flags = 0,
513 .reserved = { 0, 0 },
515 .id = V4L2_CID_PRIVATE_BASE,
516 .type = V4L2_CTRL_TYPE_INTEGER,
517 .name = "Red Saturation",
518 .minimum = INDYCAM_RED_SATURATION_MIN,
519 .maximum = INDYCAM_RED_SATURATION_MAX,
520 .step = 1,
521 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
522 .flags = 0,
523 .reserved = { 0, 0 },
525 .id = V4L2_CID_PRIVATE_BASE + 1,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 .name = "Blue Saturation",
528 .minimum = INDYCAM_BLUE_SATURATION_MIN,
529 .maximum = INDYCAM_BLUE_SATURATION_MAX,
530 .step = 1,
531 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
532 .flags = 0,
533 .reserved = { 0, 0 },
535 .id = V4L2_CID_RED_BALANCE,
536 .type = V4L2_CTRL_TYPE_INTEGER,
537 .name = "Red Balance",
538 .minimum = INDYCAM_RED_BALANCE_MIN,
539 .maximum = INDYCAM_RED_BALANCE_MAX,
540 .step = 1,
541 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
542 .flags = 0,
543 .reserved = { 0, 0 },
545 .id = V4L2_CID_BLUE_BALANCE,
546 .type = V4L2_CTRL_TYPE_INTEGER,
547 .name = "Blue Balance",
548 .minimum = INDYCAM_BLUE_BALANCE_MIN,
549 .maximum = INDYCAM_BLUE_BALANCE_MAX,
550 .step = 1,
551 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
552 .flags = 0,
553 .reserved = { 0, 0 },
555 .id = V4L2_CID_EXPOSURE,
556 .type = V4L2_CTRL_TYPE_INTEGER,
557 .name = "Shutter Control",
558 .minimum = INDYCAM_SHUTTER_MIN,
559 .maximum = INDYCAM_SHUTTER_MAX,
560 .step = 1,
561 .default_value = INDYCAM_SHUTTER_DEFAULT,
562 .flags = 0,
563 .reserved = { 0, 0 },
565 .id = V4L2_CID_GAMMA,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 .name = "Gamma",
568 .minimum = INDYCAM_GAMMA_MIN,
569 .maximum = INDYCAM_GAMMA_MAX,
570 .step = 1,
571 .default_value = INDYCAM_GAMMA_DEFAULT,
572 .flags = 0,
573 .reserved = { 0, 0 },
577 #define VINO_SAA7191_V4L2_CONTROL_COUNT 2
579 struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
581 .id = V4L2_CID_HUE,
582 .type = V4L2_CTRL_TYPE_INTEGER,
583 .name = "Hue",
584 .minimum = SAA7191_HUE_MIN,
585 .maximum = SAA7191_HUE_MAX,
586 .step = 1,
587 .default_value = SAA7191_HUE_DEFAULT,
588 .flags = 0,
589 .reserved = { 0, 0 },
591 .id = V4L2_CID_PRIVATE_BASE,
592 .type = V4L2_CTRL_TYPE_BOOLEAN,
593 .name = "VTR Time Constant",
594 .minimum = SAA7191_VTRC_MIN,
595 .maximum = SAA7191_VTRC_MAX,
596 .step = 1,
597 .default_value = SAA7191_VTRC_DEFAULT,
598 .flags = 0,
599 .reserved = { 0, 0 },
603 /* VINO I2C bus functions */
605 unsigned i2c_vino_getctrl(void *data)
607 return vino->i2c_control;
610 void i2c_vino_setctrl(void *data, unsigned val)
612 vino->i2c_control = val;
615 unsigned i2c_vino_rdata(void *data)
617 return vino->i2c_data;
620 void i2c_vino_wdata(void *data, unsigned val)
622 vino->i2c_data = val;
625 static struct i2c_algo_sgi_data i2c_sgi_vino_data =
627 .getctrl = &i2c_vino_getctrl,
628 .setctrl = &i2c_vino_setctrl,
629 .rdata = &i2c_vino_rdata,
630 .wdata = &i2c_vino_wdata,
631 .xfer_timeout = 200,
632 .ack_timeout = 1000,
636 * There are two possible clients on VINO I2C bus, so we limit usage only
637 * to them.
639 static int i2c_vino_client_reg(struct i2c_client *client)
641 int ret = 0;
643 spin_lock(&vino_drvdata->input_lock);
644 switch (client->driver->id) {
645 case I2C_DRIVERID_SAA7191:
646 if (vino_drvdata->decoder.driver)
647 ret = -EBUSY;
648 else
649 vino_drvdata->decoder.driver = client;
650 break;
651 case I2C_DRIVERID_INDYCAM:
652 if (vino_drvdata->camera.driver)
653 ret = -EBUSY;
654 else
655 vino_drvdata->camera.driver = client;
656 break;
657 default:
658 ret = -ENODEV;
660 spin_unlock(&vino_drvdata->input_lock);
662 return ret;
665 static int i2c_vino_client_unreg(struct i2c_client *client)
667 int ret = 0;
669 spin_lock(&vino_drvdata->input_lock);
670 if (client == vino_drvdata->decoder.driver) {
671 if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
672 ret = -EBUSY;
673 else
674 vino_drvdata->decoder.driver = NULL;
675 } else if (client == vino_drvdata->camera.driver) {
676 if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
677 ret = -EBUSY;
678 else
679 vino_drvdata->camera.driver = NULL;
681 spin_unlock(&vino_drvdata->input_lock);
683 return ret;
686 static struct i2c_adapter vino_i2c_adapter =
688 .name = "VINO I2C bus",
689 .id = I2C_HW_SGI_VINO,
690 .algo_data = &i2c_sgi_vino_data,
691 .client_register = &i2c_vino_client_reg,
692 .client_unregister = &i2c_vino_client_unreg,
695 static int vino_i2c_add_bus(void)
697 return i2c_sgi_add_bus(&vino_i2c_adapter);
700 static int vino_i2c_del_bus(void)
702 return i2c_sgi_del_bus(&vino_i2c_adapter);
705 static int i2c_camera_command(unsigned int cmd, void *arg)
707 return vino_drvdata->camera.driver->
708 driver->command(vino_drvdata->camera.driver,
709 cmd, arg);
712 static int i2c_decoder_command(unsigned int cmd, void *arg)
714 return vino_drvdata->decoder.driver->
715 driver->command(vino_drvdata->decoder.driver,
716 cmd, arg);
719 /* VINO framebuffer/DMA descriptor management */
721 static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
722 unsigned int count)
724 unsigned int i;
726 dprintk("vino_free_buffer_with_count(): count = %d\n", count);
728 for (i = 0; i < count; i++) {
729 mem_map_unreserve(virt_to_page(fb->desc_table.virtual[i]));
730 dma_unmap_single(NULL,
731 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
732 PAGE_SIZE, DMA_FROM_DEVICE);
733 free_page(fb->desc_table.virtual[i]);
736 dma_free_coherent(NULL,
737 VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
738 sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
739 fb->desc_table.dma);
740 kfree(fb->desc_table.virtual);
742 memset(fb, 0, sizeof(struct vino_framebuffer));
745 static void vino_free_buffer(struct vino_framebuffer *fb)
747 vino_free_buffer_with_count(fb, fb->desc_table.page_count);
750 static int vino_allocate_buffer(struct vino_framebuffer *fb,
751 unsigned int size)
753 unsigned int count, i, j;
754 int ret = 0;
756 dprintk("vino_allocate_buffer():\n");
758 if (size < 1)
759 return -EINVAL;
761 memset(fb, 0, sizeof(struct vino_framebuffer));
763 count = ((size / PAGE_SIZE) + 4) & ~3;
765 dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
766 size, count);
768 /* allocate memory for table with virtual (page) addresses */
769 fb->desc_table.virtual = (unsigned long *)
770 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
771 if (!fb->desc_table.virtual)
772 return -ENOMEM;
774 /* allocate memory for table with dma addresses
775 * (has space for four extra descriptors) */
776 fb->desc_table.dma_cpu =
777 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
778 sizeof(dma_addr_t), &fb->desc_table.dma,
779 GFP_KERNEL | GFP_DMA);
780 if (!fb->desc_table.dma_cpu) {
781 ret = -ENOMEM;
782 goto out_free_virtual;
785 /* allocate pages for the buffer and acquire the according
786 * dma addresses */
787 for (i = 0; i < count; i++) {
788 dma_addr_t dma_data_addr;
790 fb->desc_table.virtual[i] =
791 get_zeroed_page(GFP_KERNEL | GFP_DMA);
792 if (!fb->desc_table.virtual[i]) {
793 ret = -ENOBUFS;
794 break;
797 dma_data_addr =
798 dma_map_single(NULL,
799 (void *)fb->desc_table.virtual[i],
800 PAGE_SIZE, DMA_FROM_DEVICE);
802 for (j = 0; j < VINO_PAGE_RATIO; j++) {
803 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
804 dma_data_addr + VINO_PAGE_SIZE * j;
807 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
810 /* page_count needs to be set anyway, because the descriptor table has
811 * been allocated according to this number */
812 fb->desc_table.page_count = count;
814 if (ret) {
815 /* the descriptor with index i doesn't contain
816 * a valid address yet */
817 vino_free_buffer_with_count(fb, i);
818 return ret;
821 //fb->size = size;
822 fb->size = count * PAGE_SIZE;
823 fb->data_format = VINO_DATA_FMT_NONE;
825 /* set the dma stop-bit for the last (count+1)th descriptor */
826 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
827 return 0;
829 out_free_virtual:
830 kfree(fb->desc_table.virtual);
831 return ret;
834 #if 0
835 /* user buffers not fully implemented yet */
836 static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
837 void *user,
838 unsigned int size)
840 unsigned int count, i, j;
841 int ret = 0;
843 dprintk("vino_prepare_user_buffer():\n");
845 if (size < 1)
846 return -EINVAL;
848 memset(fb, 0, sizeof(struct vino_framebuffer));
850 count = ((size / PAGE_SIZE)) & ~3;
852 dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n",
853 size, count);
855 /* allocate memory for table with virtual (page) addresses */
856 fb->desc_table.virtual = (unsigned long *)
857 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
858 if (!fb->desc_table.virtual)
859 return -ENOMEM;
861 /* allocate memory for table with dma addresses
862 * (has space for four extra descriptors) */
863 fb->desc_table.dma_cpu =
864 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
865 sizeof(dma_addr_t), &fb->desc_table.dma,
866 GFP_KERNEL | GFP_DMA);
867 if (!fb->desc_table.dma_cpu) {
868 ret = -ENOMEM;
869 goto out_free_virtual;
872 /* allocate pages for the buffer and acquire the according
873 * dma addresses */
874 for (i = 0; i < count; i++) {
875 dma_addr_t dma_data_addr;
877 fb->desc_table.virtual[i] =
878 get_zeroed_page(GFP_KERNEL | GFP_DMA);
879 if (!fb->desc_table.virtual[i]) {
880 ret = -ENOBUFS;
881 break;
884 dma_data_addr =
885 dma_map_single(NULL,
886 (void *)fb->desc_table.virtual[i],
887 PAGE_SIZE, DMA_FROM_DEVICE);
889 for (j = 0; j < VINO_PAGE_RATIO; j++) {
890 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
891 dma_data_addr + VINO_PAGE_SIZE * j;
894 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
897 /* page_count needs to be set anyway, because the descriptor table has
898 * been allocated according to this number */
899 fb->desc_table.page_count = count;
901 if (ret) {
902 /* the descriptor with index i doesn't contain
903 * a valid address yet */
904 vino_free_buffer_with_count(fb, i);
905 return ret;
908 //fb->size = size;
909 fb->size = count * PAGE_SIZE;
911 /* set the dma stop-bit for the last (count+1)th descriptor */
912 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
913 return 0;
915 out_free_virtual:
916 kfree(fb->desc_table.virtual);
917 return ret;
919 #endif
921 static void vino_sync_buffer(struct vino_framebuffer *fb)
923 int i;
925 dprintk("vino_sync_buffer():\n");
927 for (i = 0; i < fb->desc_table.page_count; i++)
928 dma_sync_single(NULL,
929 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
930 PAGE_SIZE, DMA_FROM_DEVICE);
933 /* Framebuffer fifo functions (need to be locked externally) */
935 static void vino_fifo_init(struct vino_framebuffer_fifo *f,
936 unsigned int length)
938 f->length = 0;
939 f->used = 0;
940 f->head = 0;
941 f->tail = 0;
943 if (length > VINO_FRAMEBUFFER_MAX_COUNT)
944 length = VINO_FRAMEBUFFER_MAX_COUNT;
946 f->length = length;
949 /* returns true/false */
950 static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
952 unsigned int i;
953 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
954 if (f->data[i] == id)
955 return 1;
958 return 0;
961 /* returns true/false */
962 static int vino_fifo_full(struct vino_framebuffer_fifo *f)
964 return (f->used == f->length);
967 static unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
969 return f->used;
972 static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
974 if (id >= f->length) {
975 return VINO_QUEUE_ERROR;
978 if (vino_fifo_has_id(f, id)) {
979 return VINO_QUEUE_ERROR;
982 if (f->used < f->length) {
983 f->data[f->tail] = id;
984 f->tail = (f->tail + 1) % f->length;
985 f->used++;
986 } else {
987 return VINO_QUEUE_ERROR;
990 return 0;
993 static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
995 if (f->used > 0) {
996 *id = f->data[f->head];
997 } else {
998 return VINO_QUEUE_ERROR;
1001 return 0;
1004 static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
1006 if (f->used > 0) {
1007 *id = f->data[f->head];
1008 f->head = (f->head + 1) % f->length;
1009 f->used--;
1010 } else {
1011 return VINO_QUEUE_ERROR;
1014 return 0;
1017 /* Framebuffer queue functions */
1019 /* execute with queue_lock locked */
1020 static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
1021 unsigned int length)
1023 unsigned int i;
1025 q->length = 0;
1026 memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
1027 memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
1028 for (i = 0; i < length; i++) {
1029 dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
1031 vino_free_buffer(q->buffer[i]);
1032 kfree(q->buffer[i]);
1035 q->type = VINO_MEMORY_NONE;
1036 q->magic = 0;
1039 static void vino_queue_free(struct vino_framebuffer_queue *q)
1041 dprintk("vino_queue_free():\n");
1043 if (q->magic != VINO_QUEUE_MAGIC)
1044 return;
1045 if (q->type != VINO_MEMORY_MMAP)
1046 return;
1048 down(&q->queue_sem);
1050 vino_queue_free_with_count(q, q->length);
1052 up(&q->queue_sem);
1055 static int vino_queue_init(struct vino_framebuffer_queue *q,
1056 unsigned int *length)
1058 unsigned int i;
1059 int ret = 0;
1061 dprintk("vino_queue_init(): length = %d\n", *length);
1063 if (q->magic == VINO_QUEUE_MAGIC) {
1064 dprintk("vino_queue_init(): queue already initialized!\n");
1065 return -EINVAL;
1068 if (q->type != VINO_MEMORY_NONE) {
1069 dprintk("vino_queue_init(): queue already initialized!\n");
1070 return -EINVAL;
1073 if (*length < 1)
1074 return -EINVAL;
1076 down(&q->queue_sem);
1078 if (*length > VINO_FRAMEBUFFER_MAX_COUNT)
1079 *length = VINO_FRAMEBUFFER_MAX_COUNT;
1081 q->length = 0;
1083 for (i = 0; i < *length; i++) {
1084 dprintk("vino_queue_init(): allocating buffer %d\n", i);
1085 q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
1086 GFP_KERNEL);
1087 if (!q->buffer[i]) {
1088 dprintk("vino_queue_init(): kmalloc() failed\n");
1089 ret = -ENOMEM;
1090 break;
1093 ret = vino_allocate_buffer(q->buffer[i],
1094 VINO_FRAMEBUFFER_SIZE);
1095 if (ret) {
1096 kfree(q->buffer[i]);
1097 dprintk("vino_queue_init(): "
1098 "vino_allocate_buffer() failed\n");
1099 break;
1102 q->buffer[i]->id = i;
1103 if (i > 0) {
1104 q->buffer[i]->offset = q->buffer[i - 1]->offset +
1105 q->buffer[i - 1]->size;
1106 } else {
1107 q->buffer[i]->offset = 0;
1110 spin_lock_init(&q->buffer[i]->state_lock);
1112 dprintk("vino_queue_init(): buffer = %d, offset = %d, "
1113 "size = %d\n", i, q->buffer[i]->offset,
1114 q->buffer[i]->size);
1117 if (ret) {
1118 vino_queue_free_with_count(q, i);
1119 *length = 0;
1120 } else {
1121 q->length = *length;
1122 vino_fifo_init(&q->in, q->length);
1123 vino_fifo_init(&q->out, q->length);
1124 q->type = VINO_MEMORY_MMAP;
1125 q->magic = VINO_QUEUE_MAGIC;
1128 up(&q->queue_sem);
1130 return ret;
1133 static struct vino_framebuffer *vino_queue_add(struct
1134 vino_framebuffer_queue *q,
1135 unsigned int id)
1137 struct vino_framebuffer *ret = NULL;
1138 unsigned int total;
1139 unsigned long flags;
1141 dprintk("vino_queue_add(): id = %d\n", id);
1143 if (q->magic != VINO_QUEUE_MAGIC) {
1144 return ret;
1147 spin_lock_irqsave(&q->queue_lock, flags);
1149 if (q->length == 0)
1150 goto out;
1152 if (id >= q->length)
1153 goto out;
1155 /* not needed?: if (vino_fifo_full(&q->out)) {
1156 goto out;
1158 /* check that outgoing queue isn't already full
1159 * (or that it won't become full) */
1160 total = vino_fifo_get_used(&q->in) +
1161 vino_fifo_get_used(&q->out);
1162 if (total >= q->length)
1163 goto out;
1165 if (vino_fifo_enqueue(&q->in, id))
1166 goto out;
1168 ret = q->buffer[id];
1170 out:
1171 spin_unlock_irqrestore(&q->queue_lock, flags);
1173 return ret;
1176 static struct vino_framebuffer *vino_queue_transfer(struct
1177 vino_framebuffer_queue *q)
1179 struct vino_framebuffer *ret = NULL;
1180 struct vino_framebuffer *fb;
1181 int id;
1182 unsigned long flags;
1184 dprintk("vino_queue_transfer():\n");
1186 if (q->magic != VINO_QUEUE_MAGIC) {
1187 return ret;
1190 spin_lock_irqsave(&q->queue_lock, flags);
1192 if (q->length == 0)
1193 goto out;
1195 // now this actually removes an entry from the incoming queue
1196 if (vino_fifo_dequeue(&q->in, &id)) {
1197 goto out;
1200 dprintk("vino_queue_transfer(): id = %d\n", id);
1201 fb = q->buffer[id];
1203 // we have already checked that the outgoing queue is not full, but...
1204 if (vino_fifo_enqueue(&q->out, id)) {
1205 printk(KERN_ERR "vino_queue_transfer(): "
1206 "outgoing queue is full, this shouldn't happen!\n");
1207 goto out;
1210 ret = fb;
1211 out:
1212 spin_unlock_irqrestore(&q->queue_lock, flags);
1214 return ret;
1217 /* returns true/false */
1218 static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1219 unsigned int id)
1221 int ret = 0;
1222 unsigned long flags;
1224 if (q->magic != VINO_QUEUE_MAGIC) {
1225 return ret;
1228 spin_lock_irqsave(&q->queue_lock, flags);
1230 if (q->length == 0)
1231 goto out;
1233 ret = vino_fifo_has_id(&q->in, id);
1235 out:
1236 spin_unlock_irqrestore(&q->queue_lock, flags);
1238 return ret;
1241 /* returns true/false */
1242 static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1243 unsigned int id)
1245 int ret = 0;
1246 unsigned long flags;
1248 if (q->magic != VINO_QUEUE_MAGIC) {
1249 return ret;
1252 spin_lock_irqsave(&q->queue_lock, flags);
1254 if (q->length == 0)
1255 goto out;
1257 ret = vino_fifo_has_id(&q->out, id);
1259 out:
1260 spin_unlock_irqrestore(&q->queue_lock, flags);
1262 return ret;
1265 static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
1266 unsigned int *used)
1268 int ret = 0;
1269 unsigned long flags;
1271 if (q->magic != VINO_QUEUE_MAGIC) {
1272 return VINO_QUEUE_ERROR;
1275 spin_lock_irqsave(&q->queue_lock, flags);
1277 if (q->length == 0) {
1278 ret = VINO_QUEUE_ERROR;
1279 goto out;
1282 *used = vino_fifo_get_used(&q->in);
1284 out:
1285 spin_unlock_irqrestore(&q->queue_lock, flags);
1287 return ret;
1290 static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
1291 unsigned int *used)
1293 int ret = 0;
1294 unsigned long flags;
1296 if (q->magic != VINO_QUEUE_MAGIC) {
1297 return VINO_QUEUE_ERROR;
1300 spin_lock_irqsave(&q->queue_lock, flags);
1302 if (q->length == 0) {
1303 ret = VINO_QUEUE_ERROR;
1304 goto out;
1307 *used = vino_fifo_get_used(&q->out);
1309 out:
1310 spin_unlock_irqrestore(&q->queue_lock, flags);
1312 return ret;
1315 static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1316 unsigned int *total)
1318 int ret = 0;
1319 unsigned long flags;
1321 if (q->magic != VINO_QUEUE_MAGIC) {
1322 return VINO_QUEUE_ERROR;
1325 spin_lock_irqsave(&q->queue_lock, flags);
1327 if (q->length == 0) {
1328 ret = VINO_QUEUE_ERROR;
1329 goto out;
1332 *total = vino_fifo_get_used(&q->in) +
1333 vino_fifo_get_used(&q->out);
1335 out:
1336 spin_unlock_irqrestore(&q->queue_lock, flags);
1338 return ret;
1341 static struct vino_framebuffer *vino_queue_peek(struct
1342 vino_framebuffer_queue *q,
1343 unsigned int *id)
1345 struct vino_framebuffer *ret = NULL;
1346 unsigned long flags;
1348 if (q->magic != VINO_QUEUE_MAGIC) {
1349 return ret;
1352 spin_lock_irqsave(&q->queue_lock, flags);
1354 if (q->length == 0)
1355 goto out;
1357 if (vino_fifo_peek(&q->in, id)) {
1358 goto out;
1361 ret = q->buffer[*id];
1362 out:
1363 spin_unlock_irqrestore(&q->queue_lock, flags);
1365 return ret;
1368 static struct vino_framebuffer *vino_queue_remove(struct
1369 vino_framebuffer_queue *q,
1370 unsigned int *id)
1372 struct vino_framebuffer *ret = NULL;
1373 unsigned long flags;
1374 dprintk("vino_queue_remove():\n");
1376 if (q->magic != VINO_QUEUE_MAGIC) {
1377 return ret;
1380 spin_lock_irqsave(&q->queue_lock, flags);
1382 if (q->length == 0)
1383 goto out;
1385 if (vino_fifo_dequeue(&q->out, id)) {
1386 goto out;
1389 dprintk("vino_queue_remove(): id = %d\n", *id);
1390 ret = q->buffer[*id];
1391 out:
1392 spin_unlock_irqrestore(&q->queue_lock, flags);
1394 return ret;
1397 static struct
1398 vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1399 unsigned int id)
1401 struct vino_framebuffer *ret = NULL;
1402 unsigned long flags;
1404 if (q->magic != VINO_QUEUE_MAGIC) {
1405 return ret;
1408 spin_lock_irqsave(&q->queue_lock, flags);
1410 if (q->length == 0)
1411 goto out;
1413 if (id >= q->length)
1414 goto out;
1416 ret = q->buffer[id];
1417 out:
1418 spin_unlock_irqrestore(&q->queue_lock, flags);
1420 return ret;
1423 static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
1425 unsigned int length = 0;
1426 unsigned long flags;
1428 if (q->magic != VINO_QUEUE_MAGIC) {
1429 return length;
1432 spin_lock_irqsave(&q->queue_lock, flags);
1433 length = q->length;
1434 spin_unlock_irqrestore(&q->queue_lock, flags);
1436 return length;
1439 static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1441 unsigned int i;
1442 int ret = 0;
1443 unsigned long flags;
1445 if (q->magic != VINO_QUEUE_MAGIC) {
1446 return ret;
1449 spin_lock_irqsave(&q->queue_lock, flags);
1450 for (i = 0; i < q->length; i++) {
1451 if (q->buffer[i]->map_count > 0) {
1452 ret = 1;
1453 break;
1456 spin_unlock_irqrestore(&q->queue_lock, flags);
1458 return ret;
1461 /* VINO functions */
1463 /* execute with input_lock locked */
1464 static void vino_update_line_size(struct vino_channel_settings *vcs)
1466 unsigned int w = vcs->clipping.right - vcs->clipping.left;
1467 unsigned int d = vcs->decimation;
1468 unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
1469 unsigned int lsize;
1471 dprintk("update_line_size(): before: w = %d, d = %d, "
1472 "line_size = %d\n", w, d, vcs->line_size);
1473 /* line size must be multiple of 8 bytes */
1474 lsize = (bpp * (w / d)) & ~7;
1475 w = (lsize / bpp) * d;
1477 vcs->clipping.right = vcs->clipping.left + w;
1478 vcs->line_size = lsize;
1479 dprintk("update_line_size(): after: w = %d, d = %d, "
1480 "line_size = %d\n", w, d, vcs->line_size);
1483 /* execute with input_lock locked */
1484 static void vino_set_clipping(struct vino_channel_settings *vcs,
1485 unsigned int x, unsigned int y,
1486 unsigned int w, unsigned int h)
1488 unsigned int maxwidth, maxheight;
1489 unsigned int d;
1491 maxwidth = vino_data_norms[vcs->data_norm].width;
1492 maxheight = vino_data_norms[vcs->data_norm].height;
1493 d = vcs->decimation;
1495 y &= ~1; /* odd/even fields */
1497 if (x > maxwidth) {
1498 x = 0;
1500 if (y > maxheight) {
1501 y = 0;
1504 if (((w / d) < VINO_MIN_WIDTH)
1505 || ((h / d) < VINO_MIN_HEIGHT)) {
1506 w = VINO_MIN_WIDTH * d;
1507 h = VINO_MIN_HEIGHT * d;
1510 if ((x + w) > maxwidth) {
1511 w = maxwidth - x;
1512 if ((w / d) < VINO_MIN_WIDTH)
1513 x = maxwidth - VINO_MIN_WIDTH * d;
1515 if ((y + h) > maxheight) {
1516 h = maxheight - y;
1517 if ((h / d) < VINO_MIN_HEIGHT)
1518 y = maxheight - VINO_MIN_HEIGHT * d;
1521 vcs->clipping.left = x;
1522 vcs->clipping.top = y;
1523 vcs->clipping.right = x + w;
1524 vcs->clipping.bottom = y + h;
1526 vino_update_line_size(vcs);
1528 dprintk("clipping %d, %d, %d, %d / %d - %d\n",
1529 vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
1530 vcs->clipping.bottom, vcs->decimation, vcs->line_size);
1533 /* execute with input_lock locked */
1534 static void vino_set_default_clipping(struct vino_channel_settings *vcs)
1536 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1537 vino_data_norms[vcs->data_norm].height);
1540 /* execute with input_lock locked */
1541 static void vino_set_scaling(struct vino_channel_settings *vcs,
1542 unsigned int w, unsigned int h)
1544 unsigned int x, y, curw, curh, d;
1546 x = vcs->clipping.left;
1547 y = vcs->clipping.top;
1548 curw = vcs->clipping.right - vcs->clipping.left;
1549 curh = vcs->clipping.bottom - vcs->clipping.top;
1551 d = max(curw / w, curh / h);
1553 dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
1554 w, h, curw, curh, d);
1556 if (d < 1) {
1557 d = 1;
1559 if (d > 8) {
1560 d = 8;
1563 vcs->decimation = d;
1564 vino_set_clipping(vcs, x, y, w * d, h * d);
1566 dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
1567 vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
1568 vcs->decimation, vcs->line_size);
1571 /* execute with input_lock locked */
1572 static void vino_reset_scaling(struct vino_channel_settings *vcs)
1574 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1575 vcs->clipping.bottom - vcs->clipping.top);
1578 /* execute with input_lock locked */
1579 static void vino_set_framerate(struct vino_channel_settings *vcs,
1580 unsigned int fps)
1582 unsigned int mask;
1584 switch (vcs->data_norm) {
1585 case VINO_DATA_NORM_NTSC:
1586 case VINO_DATA_NORM_D1:
1587 fps = (unsigned int)(fps / 6) * 6; // FIXME: round!
1589 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1590 fps = vino_data_norms[vcs->data_norm].fps_min;
1591 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1592 fps = vino_data_norms[vcs->data_norm].fps_max;
1594 switch (fps) {
1595 case 6:
1596 mask = 0x003;
1597 break;
1598 case 12:
1599 mask = 0x0c3;
1600 break;
1601 case 18:
1602 mask = 0x333;
1603 break;
1604 case 24:
1605 mask = 0x3ff;
1606 break;
1607 case 30:
1608 mask = 0xfff;
1609 break;
1610 default:
1611 mask = VINO_FRAMERT_FULL;
1613 vcs->framert_reg = VINO_FRAMERT_RT(mask);
1614 break;
1615 case VINO_DATA_NORM_PAL:
1616 case VINO_DATA_NORM_SECAM:
1617 fps = (unsigned int)(fps / 5) * 5; // FIXME: round!
1619 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1620 fps = vino_data_norms[vcs->data_norm].fps_min;
1621 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1622 fps = vino_data_norms[vcs->data_norm].fps_max;
1624 switch (fps) {
1625 case 5:
1626 mask = 0x003;
1627 break;
1628 case 10:
1629 mask = 0x0c3;
1630 break;
1631 case 15:
1632 mask = 0x333;
1633 break;
1634 case 20:
1635 mask = 0x0ff;
1636 break;
1637 case 25:
1638 mask = 0x3ff;
1639 break;
1640 default:
1641 mask = VINO_FRAMERT_FULL;
1643 vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
1644 break;
1647 vcs->fps = fps;
1650 /* execute with input_lock locked */
1651 static void vino_set_default_framerate(struct vino_channel_settings *vcs)
1653 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1657 * Prepare VINO for DMA transfer...
1658 * (execute only with vino_lock and input_lock locked)
1660 static int vino_dma_setup(struct vino_channel_settings *vcs,
1661 struct vino_framebuffer *fb)
1663 u32 ctrl, intr;
1664 struct sgi_vino_channel *ch;
1665 const struct vino_data_norm *norm;
1667 dprintk("vino_dma_setup():\n");
1669 vcs->field = 0;
1670 fb->frame_counter = 0;
1672 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1673 norm = &vino_data_norms[vcs->data_norm];
1675 ch->page_index = 0;
1676 ch->line_count = 0;
1678 /* VINO line size register is set 8 bytes less than actual */
1679 ch->line_size = vcs->line_size - 8;
1681 /* let VINO know where to transfer data */
1682 ch->start_desc_tbl = fb->desc_table.dma;
1683 ch->next_4_desc = fb->desc_table.dma;
1685 /* give vino time to fetch the first four descriptors, 5 usec
1686 * should be more than enough time */
1687 udelay(VINO_DESC_FETCH_DELAY);
1689 /* set the alpha register */
1690 ch->alpha = vcs->alpha;
1692 /* set clipping registers */
1693 ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
1694 VINO_CLIP_EVEN(norm->even.top +
1695 vcs->clipping.top / 2) |
1696 VINO_CLIP_X(vcs->clipping.left);
1697 ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
1698 vcs->clipping.bottom / 2 - 1) |
1699 VINO_CLIP_EVEN(norm->even.top +
1700 vcs->clipping.bottom / 2 - 1) |
1701 VINO_CLIP_X(vcs->clipping.right);
1702 /* FIXME: end-of-field bug workaround
1703 VINO_CLIP_X(VINO_PAL_WIDTH);
1706 /* set the size of actual content in the buffer (DECIMATION !) */
1707 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
1708 vcs->decimation) *
1709 ((vcs->clipping.bottom - vcs->clipping.top) /
1710 vcs->decimation) *
1711 vino_data_formats[vcs->data_format].bpp;
1713 ch->frame_rate = vcs->framert_reg;
1715 ctrl = vino->control;
1716 intr = vino->intr_status;
1718 if (vcs->channel == VINO_CHANNEL_A) {
1719 /* All interrupt conditions for this channel was cleared
1720 * so clear the interrupt status register and enable
1721 * interrupts */
1722 intr &= ~VINO_INTSTAT_A;
1723 ctrl |= VINO_CTRL_A_INT;
1725 /* enable synchronization */
1726 ctrl |= VINO_CTRL_A_SYNC_ENBL;
1728 /* enable frame assembly */
1729 ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
1731 /* set decimation used */
1732 if (vcs->decimation < 2)
1733 ctrl &= ~VINO_CTRL_A_DEC_ENBL;
1734 else {
1735 ctrl |= VINO_CTRL_A_DEC_ENBL;
1736 ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
1737 ctrl |= (vcs->decimation - 1) <<
1738 VINO_CTRL_A_DEC_SCALE_SHIFT;
1741 /* select input interface */
1742 if (vcs->input == VINO_INPUT_D1)
1743 ctrl |= VINO_CTRL_A_SELECT;
1744 else
1745 ctrl &= ~VINO_CTRL_A_SELECT;
1747 /* palette */
1748 ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1749 VINO_CTRL_A_DITHER);
1750 } else {
1751 intr &= ~VINO_INTSTAT_B;
1752 ctrl |= VINO_CTRL_B_INT;
1754 ctrl |= VINO_CTRL_B_SYNC_ENBL;
1755 ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
1757 if (vcs->decimation < 2)
1758 ctrl &= ~VINO_CTRL_B_DEC_ENBL;
1759 else {
1760 ctrl |= VINO_CTRL_B_DEC_ENBL;
1761 ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
1762 ctrl |= (vcs->decimation - 1) <<
1763 VINO_CTRL_B_DEC_SCALE_SHIFT;
1766 if (vcs->input == VINO_INPUT_D1)
1767 ctrl |= VINO_CTRL_B_SELECT;
1768 else
1769 ctrl &= ~VINO_CTRL_B_SELECT;
1771 ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1772 VINO_CTRL_B_DITHER);
1775 /* set palette */
1776 fb->data_format = vcs->data_format;
1778 switch (vcs->data_format) {
1779 case VINO_DATA_FMT_GREY:
1780 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1781 VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
1782 break;
1783 case VINO_DATA_FMT_RGB32:
1784 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1785 VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1786 break;
1787 case VINO_DATA_FMT_YUV:
1788 /* nothing needs to be done */
1789 break;
1790 case VINO_DATA_FMT_RGB332:
1791 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1792 VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
1793 VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
1794 break;
1797 vino->intr_status = intr;
1798 vino->control = ctrl;
1800 return 0;
1803 /* (execute only with vino_lock locked) */
1804 static void vino_dma_start(struct vino_channel_settings *vcs)
1806 u32 ctrl = vino->control;
1808 dprintk("vino_dma_start():\n");
1809 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1810 VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
1811 vino->control = ctrl;
1814 /* (execute only with vino_lock locked) */
1815 static void vino_dma_stop(struct vino_channel_settings *vcs)
1817 u32 ctrl = vino->control;
1819 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1820 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1821 vino->control = ctrl;
1822 dprintk("vino_dma_stop():\n");
1826 * Load dummy page to descriptor registers. This prevents generating of
1827 * spurious interrupts. (execute only with vino_lock locked)
1829 static void vino_clear_interrupt(struct vino_channel_settings *vcs)
1831 struct sgi_vino_channel *ch;
1833 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1835 ch->page_index = 0;
1836 ch->line_count = 0;
1838 ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
1839 ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
1841 udelay(VINO_DESC_FETCH_DELAY);
1842 dprintk("channel %c clear interrupt condition\n",
1843 (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
1846 static int vino_capture(struct vino_channel_settings *vcs,
1847 struct vino_framebuffer *fb)
1849 int err = 0;
1850 unsigned long flags, flags2;
1852 spin_lock_irqsave(&fb->state_lock, flags);
1854 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1855 err = -EBUSY;
1856 fb->state = VINO_FRAMEBUFFER_IN_USE;
1858 spin_unlock_irqrestore(&fb->state_lock, flags);
1860 if (err)
1861 return err;
1863 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
1864 spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
1866 vino_dma_setup(vcs, fb);
1867 vino_dma_start(vcs);
1869 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
1870 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
1872 return err;
1875 static
1876 struct vino_framebuffer *vino_capture_enqueue(struct
1877 vino_channel_settings *vcs,
1878 unsigned int index)
1880 struct vino_framebuffer *fb;
1881 unsigned long flags;
1883 dprintk("vino_capture_enqueue():\n");
1885 spin_lock_irqsave(&vcs->capture_lock, flags);
1887 fb = vino_queue_add(&vcs->fb_queue, index);
1888 if (fb == NULL) {
1889 dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
1890 "queue full?\n");
1891 goto out;
1893 out:
1894 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1896 return fb;
1899 static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1901 struct vino_framebuffer *fb;
1902 unsigned int incoming, id;
1903 int err = 0;
1904 unsigned long flags, flags2;
1906 dprintk("vino_capture_next():\n");
1908 spin_lock_irqsave(&vcs->capture_lock, flags);
1910 if (start) {
1911 /* start capture only if capture isn't in progress already */
1912 if (vcs->capturing) {
1913 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1914 return 0;
1917 } else {
1918 /* capture next frame:
1919 * stop capture if capturing is not set */
1920 if (!vcs->capturing) {
1921 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1922 return 0;
1926 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
1927 if (err) {
1928 dprintk("vino_capture_next(): vino_queue_get_incoming() "
1929 "failed\n");
1930 err = -EINVAL;
1931 goto out;
1933 if (incoming == 0) {
1934 dprintk("vino_capture_next(): no buffers available\n");
1935 goto out;
1938 fb = vino_queue_peek(&vcs->fb_queue, &id);
1939 if (fb == NULL) {
1940 dprintk("vino_capture_next(): vino_queue_peek() failed\n");
1941 err = -EINVAL;
1942 goto out;
1945 spin_lock_irqsave(&fb->state_lock, flags2);
1946 fb->state = VINO_FRAMEBUFFER_UNUSED;
1947 spin_unlock_irqrestore(&fb->state_lock, flags2);
1949 if (start) {
1950 vcs->capturing = 1;
1953 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1955 err = vino_capture(vcs, fb);
1957 return err;
1959 out:
1960 vcs->capturing = 0;
1961 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1963 return err;
1966 static int vino_is_capturing(struct vino_channel_settings *vcs)
1968 int ret;
1969 unsigned long flags;
1971 spin_lock_irqsave(&vcs->capture_lock, flags);
1973 ret = vcs->capturing;
1975 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1977 return ret;
1980 /* waits until a frame is captured */
1981 static int vino_wait_for_frame(struct vino_channel_settings *vcs)
1983 wait_queue_t wait;
1984 int err = 0;
1986 dprintk("vino_wait_for_frame():\n");
1988 init_waitqueue_entry(&wait, current);
1989 /* add ourselves into wait queue */
1990 add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
1991 /* and set current state */
1992 set_current_state(TASK_INTERRUPTIBLE);
1994 /* to ensure that schedule_timeout will return immediately
1995 * if VINO interrupt was triggred meanwhile */
1996 schedule_timeout(HZ / 10);
1998 if (signal_pending(current))
1999 err = -EINTR;
2001 remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2003 dprintk("vino_wait_for_frame(): waiting for frame %s\n",
2004 err ? "failed" : "ok");
2006 return err;
2009 /* the function assumes that PAGE_SIZE % 4 == 0 */
2010 static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
2011 unsigned char *pageptr;
2012 unsigned int page, i;
2013 unsigned char a;
2015 for (page = 0; page < fb->desc_table.page_count; page++) {
2016 pageptr = (unsigned char *)fb->desc_table.virtual[page];
2018 for (i = 0; i < PAGE_SIZE; i += 4) {
2019 a = pageptr[0];
2020 pageptr[0] = pageptr[3];
2021 pageptr[1] = pageptr[2];
2022 pageptr[2] = pageptr[1];
2023 pageptr[3] = a;
2024 pageptr += 4;
2029 /* checks if the buffer is in correct state and syncs data */
2030 static int vino_check_buffer(struct vino_channel_settings *vcs,
2031 struct vino_framebuffer *fb)
2033 int err = 0;
2034 unsigned long flags;
2036 dprintk("vino_check_buffer():\n");
2038 spin_lock_irqsave(&fb->state_lock, flags);
2039 switch (fb->state) {
2040 case VINO_FRAMEBUFFER_IN_USE:
2041 err = -EIO;
2042 break;
2043 case VINO_FRAMEBUFFER_READY:
2044 vino_sync_buffer(fb);
2045 fb->state = VINO_FRAMEBUFFER_UNUSED;
2046 break;
2047 default:
2048 err = -EINVAL;
2050 spin_unlock_irqrestore(&fb->state_lock, flags);
2052 if (!err) {
2053 if (vino_pixel_conversion
2054 && (fb->data_format == VINO_DATA_FMT_RGB32)) {
2055 vino_convert_to_rgba(fb);
2057 } else if (err && (err != -EINVAL)) {
2058 dprintk("vino_check_buffer(): buffer not ready\n");
2060 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2061 vino_dma_stop(vcs);
2062 vino_clear_interrupt(vcs);
2063 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2066 return err;
2069 /* forcefully terminates capture */
2070 static void vino_capture_stop(struct vino_channel_settings *vcs)
2072 unsigned int incoming = 0, outgoing = 0, id;
2073 unsigned long flags, flags2;
2075 dprintk("vino_capture_stop():\n");
2077 spin_lock_irqsave(&vcs->capture_lock, flags);
2078 /* unset capturing to stop queue processing */
2079 vcs->capturing = 0;
2081 spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
2083 vino_dma_stop(vcs);
2084 vino_clear_interrupt(vcs);
2086 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
2088 /* remove all items from the queue */
2089 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2090 dprintk("vino_capture_stop(): "
2091 "vino_queue_get_incoming() failed\n");
2092 goto out;
2094 while (incoming > 0) {
2095 vino_queue_transfer(&vcs->fb_queue);
2097 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2098 dprintk("vino_capture_stop(): "
2099 "vino_queue_get_incoming() failed\n");
2100 goto out;
2104 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2105 dprintk("vino_capture_stop(): "
2106 "vino_queue_get_outgoing() failed\n");
2107 goto out;
2109 while (outgoing > 0) {
2110 vino_queue_remove(&vcs->fb_queue, &id);
2112 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2113 dprintk("vino_capture_stop(): "
2114 "vino_queue_get_outgoing() failed\n");
2115 goto out;
2119 out:
2120 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2123 static int vino_capture_failed(struct vino_channel_settings *vcs)
2125 struct vino_framebuffer *fb;
2126 unsigned long flags;
2127 unsigned int i;
2128 int ret;
2130 dprintk("vino_capture_failed():\n");
2132 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2134 vino_dma_stop(vcs);
2135 vino_clear_interrupt(vcs);
2137 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2139 ret = vino_queue_get_incoming(&vcs->fb_queue, &i);
2140 if (ret == VINO_QUEUE_ERROR) {
2141 dprintk("vino_queue_get_incoming() failed\n");
2142 return -EINVAL;
2144 if (i == 0) {
2145 /* no buffers to process */
2146 return 0;
2149 fb = vino_queue_peek(&vcs->fb_queue, &i);
2150 if (fb == NULL) {
2151 dprintk("vino_queue_peek() failed\n");
2152 return -EINVAL;
2155 spin_lock_irqsave(&fb->state_lock, flags);
2156 if (fb->state == VINO_FRAMEBUFFER_IN_USE) {
2157 fb->state = VINO_FRAMEBUFFER_UNUSED;
2158 vino_queue_transfer(&vcs->fb_queue);
2159 vino_queue_remove(&vcs->fb_queue, &i);
2160 /* we should actually discard the newest frame,
2161 * but who cares ... */
2163 spin_unlock_irqrestore(&fb->state_lock, flags);
2165 return 0;
2168 static void vino_frame_done(struct vino_channel_settings *vcs,
2169 unsigned int fc)
2171 struct vino_framebuffer *fb;
2172 unsigned long flags;
2174 spin_lock_irqsave(&vcs->capture_lock, flags);
2175 fb = vino_queue_transfer(&vcs->fb_queue);
2176 if (!fb) {
2177 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2178 dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
2179 return;
2181 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2183 fb->frame_counter = fc;
2184 do_gettimeofday(&fb->timestamp);
2186 spin_lock_irqsave(&fb->state_lock, flags);
2187 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
2188 fb->state = VINO_FRAMEBUFFER_READY;
2189 spin_unlock_irqrestore(&fb->state_lock, flags);
2191 wake_up(&vcs->fb_queue.frame_wait_queue);
2193 vino_capture_next(vcs, 0);
2196 static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2198 u32 intr;
2199 unsigned int fc_a, fc_b;
2200 int done_a = 0;
2201 int done_b = 0;
2203 spin_lock(&vino_drvdata->vino_lock);
2205 intr = vino->intr_status;
2206 fc_a = vino->a.field_counter / 2;
2207 fc_b = vino->b.field_counter / 2;
2209 // TODO: handle error-interrupts in some special way ?
2211 if (intr & VINO_INTSTAT_A) {
2212 if (intr & VINO_INTSTAT_A_EOF) {
2213 vino_drvdata->a.field++;
2214 if (vino_drvdata->a.field > 1) {
2215 vino_dma_stop(&vino_drvdata->a);
2216 vino_clear_interrupt(&vino_drvdata->a);
2217 vino_drvdata->a.field = 0;
2218 done_a = 1;
2220 dprintk("intr: channel A end-of-field interrupt: "
2221 "%04x\n", intr);
2222 } else {
2223 vino_dma_stop(&vino_drvdata->a);
2224 vino_clear_interrupt(&vino_drvdata->a);
2225 done_a = 1;
2226 dprintk("channel A error interrupt: %04x\n", intr);
2229 if (intr & VINO_INTSTAT_B) {
2230 if (intr & VINO_INTSTAT_B_EOF) {
2231 vino_drvdata->b.field++;
2232 if (vino_drvdata->b.field > 1) {
2233 vino_dma_stop(&vino_drvdata->b);
2234 vino_clear_interrupt(&vino_drvdata->b);
2235 vino_drvdata->b.field = 0;
2236 done_b = 1;
2238 dprintk("intr: channel B end-of-field interrupt: "
2239 "%04x\n", intr);
2240 } else {
2241 vino_dma_stop(&vino_drvdata->b);
2242 vino_clear_interrupt(&vino_drvdata->b);
2243 done_b = 1;
2244 dprintk("channel B error interrupt: %04x\n", intr);
2248 /* always remember to clear interrupt status */
2249 vino->intr_status = ~intr;
2251 spin_unlock(&vino_drvdata->vino_lock);
2253 if (done_a) {
2254 vino_frame_done(&vino_drvdata->a, fc_a);
2255 dprintk("channel A frame done, interrupt: %d\n", intr);
2257 if (done_b) {
2258 vino_frame_done(&vino_drvdata->b, fc_b);
2259 dprintk("channel B frame done, interrupt: %d\n", intr);
2262 return IRQ_HANDLED;
2265 /* VINO video input management */
2267 static int vino_get_saa7191_input(int input)
2269 switch (input) {
2270 case VINO_INPUT_COMPOSITE:
2271 return SAA7191_INPUT_COMPOSITE;
2272 case VINO_INPUT_SVIDEO:
2273 return SAA7191_INPUT_SVIDEO;
2274 default:
2275 printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2276 "invalid input!\n");
2277 return -1;
2281 static int vino_get_saa7191_norm(int norm)
2283 switch (norm) {
2284 case VINO_DATA_NORM_AUTO:
2285 return SAA7191_NORM_AUTO;
2286 case VINO_DATA_NORM_PAL:
2287 return SAA7191_NORM_PAL;
2288 case VINO_DATA_NORM_NTSC:
2289 return SAA7191_NORM_NTSC;
2290 case VINO_DATA_NORM_SECAM:
2291 return SAA7191_NORM_SECAM;
2292 default:
2293 printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
2294 "invalid norm!\n");
2295 return -1;
2299 /* execute with input_lock locked */
2300 static int vino_is_input_owner(struct vino_channel_settings *vcs)
2302 switch(vcs->input) {
2303 case VINO_INPUT_COMPOSITE:
2304 case VINO_INPUT_SVIDEO:
2305 return (vino_drvdata->decoder.owner == vcs->channel);
2306 case VINO_INPUT_D1:
2307 return (vino_drvdata->camera.owner == vcs->channel);
2308 default:
2309 return 0;
2313 static int vino_acquire_input(struct vino_channel_settings *vcs)
2315 int ret = 0;
2317 dprintk("vino_acquire_input():\n");
2319 spin_lock(&vino_drvdata->input_lock);
2321 /* First try D1 and then SAA7191 */
2322 if (vino_drvdata->camera.driver
2323 && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
2324 if (i2c_use_client(vino_drvdata->camera.driver)) {
2325 ret = -ENODEV;
2326 goto out;
2329 vino_drvdata->camera.owner = vcs->channel;
2330 vcs->input = VINO_INPUT_D1;
2331 vcs->data_norm = VINO_DATA_NORM_D1;
2332 } else if (vino_drvdata->decoder.driver
2333 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
2334 int saa7191_input;
2335 int saa7191_norm;
2337 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2338 ret = -ENODEV;
2339 goto out;
2342 vino_drvdata->decoder.owner = vcs->channel;
2343 vcs->input = VINO_INPUT_COMPOSITE;
2344 vcs->data_norm = VINO_DATA_NORM_PAL;
2346 saa7191_input = vino_get_saa7191_input(vcs->input);
2347 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
2349 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
2350 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
2351 } else {
2352 vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2353 vino_drvdata->b.input : vino_drvdata->a.input;
2354 vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
2355 vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
2358 if (vcs->input == VINO_INPUT_NONE) {
2359 ret = -ENODEV;
2360 goto out;
2363 if (vino_is_input_owner(vcs)) {
2364 vino_set_default_clipping(vcs);
2365 vino_set_default_framerate(vcs);
2368 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2370 out:
2371 spin_unlock(&vino_drvdata->input_lock);
2373 return ret;
2376 static int vino_set_input(struct vino_channel_settings *vcs, int input)
2378 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2379 &vino_drvdata->b : &vino_drvdata->a;
2380 int ret = 0;
2382 dprintk("vino_set_input():\n");
2384 spin_lock(&vino_drvdata->input_lock);
2386 if (vcs->input == input)
2387 goto out;
2389 switch(input) {
2390 case VINO_INPUT_COMPOSITE:
2391 case VINO_INPUT_SVIDEO:
2392 if (!vino_drvdata->decoder.driver) {
2393 ret = -EINVAL;
2394 goto out;
2397 if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
2398 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2399 ret = -ENODEV;
2400 goto out;
2402 vino_drvdata->decoder.owner = vcs->channel;
2405 if (vino_drvdata->decoder.owner == vcs->channel) {
2406 int saa7191_input;
2407 int saa7191_norm;
2409 vcs->input = input;
2410 vcs->data_norm = VINO_DATA_NORM_PAL;
2412 saa7191_input = vino_get_saa7191_input(vcs->input);
2413 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
2414 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
2415 i2c_decoder_command(DECODER_SAA7191_SET_NORM,
2416 &saa7191_norm);
2417 } else {
2418 if (vcs2->input != input) {
2419 ret = -EBUSY;
2420 goto out;
2423 vcs->input = input;
2424 vcs->data_norm = vcs2->data_norm;
2427 if (vino_drvdata->camera.owner == vcs->channel) {
2428 /* Transfer the ownership or release the input */
2429 if (vcs2->input == VINO_INPUT_D1) {
2430 vino_drvdata->camera.owner = vcs2->channel;
2431 } else {
2432 i2c_release_client(vino_drvdata->
2433 camera.driver);
2434 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2437 break;
2438 case VINO_INPUT_D1:
2439 if (!vino_drvdata->camera.driver) {
2440 ret = -EINVAL;
2441 goto out;
2444 if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
2445 if (i2c_use_client(vino_drvdata->camera.driver)) {
2446 ret = -ENODEV;
2447 goto out;
2449 vino_drvdata->camera.owner = vcs->channel;
2452 if (vino_drvdata->decoder.owner == vcs->channel) {
2453 /* Transfer the ownership or release the input */
2454 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2455 (vcs2->input == VINO_INPUT_SVIDEO)) {
2456 vino_drvdata->decoder.owner = vcs2->channel;
2457 } else {
2458 i2c_release_client(vino_drvdata->
2459 decoder.driver);
2460 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2464 vcs->input = input;
2465 vcs->data_norm = VINO_DATA_NORM_D1;
2466 break;
2467 default:
2468 ret = -EINVAL;
2469 goto out;
2472 vino_set_default_clipping(vcs);
2473 vino_set_default_framerate(vcs);
2475 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2477 out:
2478 spin_unlock(&vino_drvdata->input_lock);
2480 return ret;
2483 static void vino_release_input(struct vino_channel_settings *vcs)
2485 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2486 &vino_drvdata->b : &vino_drvdata->a;
2488 dprintk("vino_release_input():\n");
2490 spin_lock(&vino_drvdata->input_lock);
2492 /* Release ownership of the channel
2493 * and if the other channel takes input from
2494 * the same source, transfer the ownership */
2495 if (vino_drvdata->camera.owner == vcs->channel) {
2496 if (vcs2->input == VINO_INPUT_D1) {
2497 vino_drvdata->camera.owner = vcs2->channel;
2498 } else {
2499 i2c_release_client(vino_drvdata->camera.driver);
2500 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2502 } else if (vino_drvdata->decoder.owner == vcs->channel) {
2503 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2504 (vcs2->input == VINO_INPUT_SVIDEO)) {
2505 vino_drvdata->decoder.owner = vcs2->channel;
2506 } else {
2507 i2c_release_client(vino_drvdata->decoder.driver);
2508 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2511 vcs->input = VINO_INPUT_NONE;
2513 spin_unlock(&vino_drvdata->input_lock);
2516 /* execute with input_lock locked */
2517 static int vino_set_data_norm(struct vino_channel_settings *vcs,
2518 unsigned int data_norm)
2520 int saa7191_norm;
2522 switch (vcs->input) {
2523 case VINO_INPUT_D1:
2524 /* only one "norm" supported */
2525 if (data_norm != VINO_DATA_NORM_D1)
2526 return -EINVAL;
2527 break;
2528 case VINO_INPUT_COMPOSITE:
2529 case VINO_INPUT_SVIDEO:
2531 saa7191_norm = vino_get_saa7191_norm(data_norm);
2533 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
2534 vcs->data_norm = data_norm;
2535 break;
2536 default:
2537 return -EINVAL;
2540 return 0;
2543 /* V4L2 helper functions */
2545 static int vino_find_data_format(__u32 pixelformat)
2547 int i;
2549 for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2550 if (vino_data_formats[i].pixelformat == pixelformat)
2551 return i;
2554 return VINO_DATA_FMT_NONE;
2557 static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2559 int data_norm = VINO_DATA_NORM_NONE;
2561 spin_lock(&vino_drvdata->input_lock);
2562 switch(vcs->input) {
2563 case VINO_INPUT_COMPOSITE:
2564 case VINO_INPUT_SVIDEO:
2565 if (index == 0) {
2566 data_norm = VINO_DATA_NORM_PAL;
2567 } else if (index == 1) {
2568 data_norm = VINO_DATA_NORM_NTSC;
2569 } else if (index == 2) {
2570 data_norm = VINO_DATA_NORM_SECAM;
2572 break;
2573 case VINO_INPUT_D1:
2574 if (index == 0) {
2575 data_norm = VINO_DATA_NORM_D1;
2577 break;
2579 spin_unlock(&vino_drvdata->input_lock);
2581 return data_norm;
2584 static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
2586 int input = VINO_INPUT_NONE;
2588 spin_lock(&vino_drvdata->input_lock);
2589 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2590 switch (index) {
2591 case 0:
2592 input = VINO_INPUT_COMPOSITE;
2593 break;
2594 case 1:
2595 input = VINO_INPUT_SVIDEO;
2596 break;
2597 case 2:
2598 input = VINO_INPUT_D1;
2599 break;
2601 } else if (vino_drvdata->decoder.driver) {
2602 switch (index) {
2603 case 0:
2604 input = VINO_INPUT_COMPOSITE;
2605 break;
2606 case 1:
2607 input = VINO_INPUT_SVIDEO;
2608 break;
2610 } else if (vino_drvdata->camera.driver) {
2611 switch (index) {
2612 case 0:
2613 input = VINO_INPUT_D1;
2614 break;
2617 spin_unlock(&vino_drvdata->input_lock);
2619 return input;
2622 /* execute with input_lock locked */
2623 static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
2625 __u32 index = 0;
2626 // FIXME: detect when no inputs available
2628 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2629 switch (vcs->input) {
2630 case VINO_INPUT_COMPOSITE:
2631 index = 0;
2632 break;
2633 case VINO_INPUT_SVIDEO:
2634 index = 1;
2635 break;
2636 case VINO_INPUT_D1:
2637 index = 2;
2638 break;
2640 } else if (vino_drvdata->decoder.driver) {
2641 switch (vcs->input) {
2642 case VINO_INPUT_COMPOSITE:
2643 index = 0;
2644 break;
2645 case VINO_INPUT_SVIDEO:
2646 index = 1;
2647 break;
2649 } else if (vino_drvdata->camera.driver) {
2650 switch (vcs->input) {
2651 case VINO_INPUT_D1:
2652 index = 0;
2653 break;
2657 return index;
2660 /* V4L2 ioctls */
2662 static void vino_v4l2_querycap(struct v4l2_capability *cap)
2664 memset(cap, 0, sizeof(struct v4l2_capability));
2666 strcpy(cap->driver, vino_driver_name);
2667 strcpy(cap->card, vino_driver_description);
2668 strcpy(cap->bus_info, vino_bus_name);
2669 cap->version = VINO_VERSION_CODE;
2670 cap->capabilities =
2671 V4L2_CAP_VIDEO_CAPTURE |
2672 V4L2_CAP_STREAMING;
2673 // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
2676 static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
2677 struct v4l2_input *i)
2679 __u32 index = i->index;
2680 int input;
2681 dprintk("requested index = %d\n", index);
2683 input = vino_enum_input(vcs, index);
2684 if (input == VINO_INPUT_NONE)
2685 return -EINVAL;
2687 memset(i, 0, sizeof(struct v4l2_input));
2689 i->index = index;
2690 i->type = V4L2_INPUT_TYPE_CAMERA;
2691 i->std = vino_inputs[input].std;
2692 strcpy(i->name, vino_inputs[input].name);
2694 if ((input == VINO_INPUT_COMPOSITE)
2695 || (input == VINO_INPUT_SVIDEO)) {
2696 struct saa7191_status status;
2697 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
2698 i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
2699 i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
2702 return 0;
2705 static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2706 struct v4l2_input *i)
2708 __u32 index;
2709 int input;
2711 spin_lock(&vino_drvdata->input_lock);
2712 input = vcs->input;
2713 index = vino_find_input_index(vcs);
2714 spin_unlock(&vino_drvdata->input_lock);
2716 dprintk("input = %d\n", input);
2718 if (input == VINO_INPUT_NONE) {
2719 return -EINVAL;
2722 memset(i, 0, sizeof(struct v4l2_input));
2724 i->index = index;
2725 i->type = V4L2_INPUT_TYPE_CAMERA;
2726 i->std = vino_inputs[input].std;
2727 strcpy(i->name, vino_inputs[input].name);
2729 return 0;
2732 static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
2733 struct v4l2_input *i)
2735 int input;
2736 dprintk("requested input = %d\n", i->index);
2738 input = vino_enum_input(vcs, i->index);
2739 if (input == VINO_INPUT_NONE)
2740 return -EINVAL;
2742 return vino_set_input(vcs, input);
2745 static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
2746 struct v4l2_standard *s)
2748 int index = s->index;
2749 int data_norm = vino_enum_data_norm(vcs, index);
2750 dprintk("standard index = %d\n", index);
2752 if (data_norm == VINO_DATA_NORM_NONE)
2753 return -EINVAL;
2755 dprintk("standard name = %s\n",
2756 vino_data_norms[data_norm].description);
2758 memset(s, 0, sizeof(struct v4l2_standard));
2759 s->index = index;
2761 s->id = vino_data_norms[data_norm].std;
2762 s->frameperiod.numerator = 1;
2763 s->frameperiod.denominator =
2764 vino_data_norms[data_norm].fps_max;
2765 s->framelines =
2766 vino_data_norms[data_norm].framelines;
2767 strcpy(s->name,
2768 vino_data_norms[data_norm].description);
2770 return 0;
2773 static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
2774 v4l2_std_id *std)
2776 spin_lock(&vino_drvdata->input_lock);
2777 dprintk("current standard = %d\n", vcs->data_norm);
2778 *std = vino_data_norms[vcs->data_norm].std;
2779 spin_unlock(&vino_drvdata->input_lock);
2781 return 0;
2784 static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
2785 v4l2_std_id *std)
2787 int ret = 0;
2789 spin_lock(&vino_drvdata->input_lock);
2791 /* check if the standard is valid for the current input */
2792 if (vino_is_input_owner(vcs)
2793 && (vino_inputs[vcs->input].std & (*std))) {
2794 dprintk("standard accepted\n");
2796 /* change the video norm for SAA7191
2797 * and accept NTSC for D1 (do nothing) */
2799 if (vcs->input == VINO_INPUT_D1)
2800 goto out;
2802 if ((*std) & V4L2_STD_PAL) {
2803 vino_set_data_norm(vcs, VINO_DATA_NORM_PAL);
2804 vcs->data_norm = VINO_DATA_NORM_PAL;
2805 } else if ((*std) & V4L2_STD_NTSC) {
2806 vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC);
2807 vcs->data_norm = VINO_DATA_NORM_NTSC;
2808 } else if ((*std) & V4L2_STD_SECAM) {
2809 vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM);
2810 vcs->data_norm = VINO_DATA_NORM_SECAM;
2811 } else {
2812 ret = -EINVAL;
2814 } else {
2815 ret = -EINVAL;
2818 out:
2819 spin_unlock(&vino_drvdata->input_lock);
2821 return ret;
2824 static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
2825 struct v4l2_fmtdesc *fd)
2827 enum v4l2_buf_type type = fd->type;
2828 int index = fd->index;
2829 dprintk("format index = %d\n", index);
2831 switch (fd->type) {
2832 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2833 if ((fd->index < 0) ||
2834 (fd->index >= VINO_DATA_FMT_COUNT))
2835 return -EINVAL;
2836 dprintk("format name = %s\n",
2837 vino_data_formats[index].description);
2839 memset(fd, 0, sizeof(struct v4l2_fmtdesc));
2840 fd->index = index;
2841 fd->type = type;
2842 fd->pixelformat = vino_data_formats[index].pixelformat;
2843 strcpy(fd->description, vino_data_formats[index].description);
2844 break;
2845 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2846 default:
2847 return -EINVAL;
2850 return 0;
2853 static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2854 struct v4l2_format *f)
2856 struct vino_channel_settings tempvcs;
2858 switch (f->type) {
2859 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2860 struct v4l2_pix_format *pf = &f->fmt.pix;
2862 dprintk("requested: w = %d, h = %d\n",
2863 pf->width, pf->height);
2865 spin_lock(&vino_drvdata->input_lock);
2866 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
2867 spin_unlock(&vino_drvdata->input_lock);
2869 tempvcs.data_format = vino_find_data_format(pf->pixelformat);
2870 if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
2871 tempvcs.data_format = VINO_DATA_FMT_RGB32;
2872 pf->pixelformat =
2873 vino_data_formats[tempvcs.data_format].
2874 pixelformat;
2877 /* data format must be set before clipping/scaling */
2878 vino_set_scaling(&tempvcs, pf->width, pf->height);
2880 dprintk("data format = %s\n",
2881 vino_data_formats[tempvcs.data_format].description);
2883 pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
2884 tempvcs.decimation;
2885 pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
2886 tempvcs.decimation;
2888 pf->field = V4L2_FIELD_INTERLACED;
2889 pf->bytesperline = tempvcs.line_size;
2890 pf->sizeimage = tempvcs.line_size *
2891 (tempvcs.clipping.bottom - tempvcs.clipping.top) /
2892 tempvcs.decimation;
2893 pf->colorspace =
2894 vino_data_formats[tempvcs.data_format].colorspace;
2896 pf->priv = 0;
2897 break;
2899 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2900 default:
2901 return -EINVAL;
2904 return 0;
2907 static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
2908 struct v4l2_format *f)
2910 switch (f->type) {
2911 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2912 struct v4l2_pix_format *pf = &f->fmt.pix;
2913 spin_lock(&vino_drvdata->input_lock);
2915 pf->width = (vcs->clipping.right - vcs->clipping.left) /
2916 vcs->decimation;
2917 pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
2918 vcs->decimation;
2919 pf->pixelformat =
2920 vino_data_formats[vcs->data_format].pixelformat;
2922 pf->field = V4L2_FIELD_INTERLACED;
2923 pf->bytesperline = vcs->line_size;
2924 pf->sizeimage = vcs->line_size *
2925 (vcs->clipping.bottom - vcs->clipping.top) /
2926 vcs->decimation;
2927 pf->colorspace =
2928 vino_data_formats[vcs->data_format].colorspace;
2930 pf->priv = 0;
2932 spin_unlock(&vino_drvdata->input_lock);
2933 break;
2935 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2936 default:
2937 return -EINVAL;
2940 return 0;
2943 static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
2944 struct v4l2_format *f)
2946 int data_format;
2948 switch (f->type) {
2949 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2950 struct v4l2_pix_format *pf = &f->fmt.pix;
2951 spin_lock(&vino_drvdata->input_lock);
2953 if (!vino_is_input_owner(vcs)) {
2954 spin_unlock(&vino_drvdata->input_lock);
2955 return -EINVAL;
2958 data_format = vino_find_data_format(pf->pixelformat);
2959 if (data_format == VINO_DATA_FMT_NONE) {
2960 vcs->data_format = VINO_DATA_FMT_RGB32;
2961 pf->pixelformat =
2962 vino_data_formats[vcs->data_format].
2963 pixelformat;
2964 } else {
2965 vcs->data_format = data_format;
2968 /* data format must be set before clipping/scaling */
2969 vino_set_scaling(vcs, pf->width, pf->height);
2971 dprintk("data format = %s\n",
2972 vino_data_formats[vcs->data_format].description);
2974 pf->width = vcs->clipping.right - vcs->clipping.left;
2975 pf->height = vcs->clipping.bottom - vcs->clipping.top;
2977 pf->field = V4L2_FIELD_INTERLACED;
2978 pf->bytesperline = vcs->line_size;
2979 pf->sizeimage = vcs->line_size *
2980 (vcs->clipping.bottom - vcs->clipping.top) /
2981 vcs->decimation;
2982 pf->colorspace =
2983 vino_data_formats[vcs->data_format].colorspace;
2985 pf->priv = 0;
2987 spin_unlock(&vino_drvdata->input_lock);
2988 break;
2990 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2991 default:
2992 return -EINVAL;
2995 return 0;
2998 static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
2999 struct v4l2_cropcap *ccap)
3001 const struct vino_data_norm *norm;
3003 switch (ccap->type) {
3004 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3005 spin_lock(&vino_drvdata->input_lock);
3006 norm = &vino_data_norms[vcs->data_norm];
3007 spin_unlock(&vino_drvdata->input_lock);
3009 ccap->bounds.left = 0;
3010 ccap->bounds.top = 0;
3011 ccap->bounds.width = norm->width;
3012 ccap->bounds.height = norm->height;
3013 memcpy(&ccap->defrect, &ccap->bounds,
3014 sizeof(struct v4l2_rect));
3016 ccap->pixelaspect.numerator = 1;
3017 ccap->pixelaspect.denominator = 1;
3018 break;
3019 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3020 default:
3021 return -EINVAL;
3024 return 0;
3027 static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3028 struct v4l2_crop *c)
3030 switch (c->type) {
3031 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3032 spin_lock(&vino_drvdata->input_lock);
3034 c->c.left = vcs->clipping.left;
3035 c->c.top = vcs->clipping.top;
3036 c->c.width = vcs->clipping.right - vcs->clipping.left;
3037 c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3039 spin_unlock(&vino_drvdata->input_lock);
3040 break;
3041 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3042 default:
3043 return -EINVAL;
3046 return 0;
3049 static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3050 struct v4l2_crop *c)
3052 switch (c->type) {
3053 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3054 spin_lock(&vino_drvdata->input_lock);
3056 if (!vino_is_input_owner(vcs)) {
3057 spin_unlock(&vino_drvdata->input_lock);
3058 return -EINVAL;
3060 vino_set_clipping(vcs, c->c.left, c->c.top,
3061 c->c.width, c->c.height);
3063 spin_unlock(&vino_drvdata->input_lock);
3064 break;
3065 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3066 default:
3067 return -EINVAL;
3070 return 0;
3073 static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3074 struct v4l2_streamparm *sp)
3076 switch (sp->type) {
3077 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3078 struct v4l2_captureparm *cp = &sp->parm.capture;
3079 memset(cp, 0, sizeof(struct v4l2_captureparm));
3081 cp->capability = V4L2_CAP_TIMEPERFRAME;
3082 cp->timeperframe.numerator = 1;
3084 spin_lock(&vino_drvdata->input_lock);
3085 cp->timeperframe.denominator = vcs->fps;
3086 spin_unlock(&vino_drvdata->input_lock);
3088 // TODO: cp->readbuffers = xxx;
3089 break;
3091 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3092 default:
3093 return -EINVAL;
3096 return 0;
3099 static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3100 struct v4l2_streamparm *sp)
3102 switch (sp->type) {
3103 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3104 struct v4l2_captureparm *cp = &sp->parm.capture;
3106 spin_lock(&vino_drvdata->input_lock);
3107 if (!vino_is_input_owner(vcs)) {
3108 spin_unlock(&vino_drvdata->input_lock);
3109 return -EINVAL;
3112 if ((cp->timeperframe.numerator == 0) ||
3113 (cp->timeperframe.denominator == 0)) {
3114 /* reset framerate */
3115 vino_set_default_framerate(vcs);
3116 } else {
3117 vino_set_framerate(vcs, cp->timeperframe.denominator /
3118 cp->timeperframe.numerator);
3120 spin_unlock(&vino_drvdata->input_lock);
3122 // TODO: set buffers according to cp->readbuffers
3123 break;
3125 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3126 default:
3127 return -EINVAL;
3130 return 0;
3133 static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
3134 struct v4l2_requestbuffers *rb)
3136 if (vcs->reading)
3137 return -EBUSY;
3139 switch (rb->type) {
3140 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3141 // TODO: check queue type
3142 if (rb->memory != V4L2_MEMORY_MMAP) {
3143 dprintk("type not mmap\n");
3144 return -EINVAL;
3147 if (vino_is_capturing(vcs)) {
3148 dprintk("busy, capturing\n");
3149 return -EBUSY;
3152 dprintk("count = %d\n", rb->count);
3153 if (rb->count > 0) {
3154 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3155 dprintk("busy, buffers still mapped\n");
3156 return -EBUSY;
3157 } else {
3158 vino_queue_free(&vcs->fb_queue);
3159 vino_queue_init(&vcs->fb_queue, &rb->count);
3161 } else {
3162 vino_capture_stop(vcs);
3163 vino_queue_free(&vcs->fb_queue);
3165 break;
3167 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3168 default:
3169 return -EINVAL;
3172 return 0;
3175 static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
3176 struct vino_framebuffer *fb,
3177 struct v4l2_buffer *b)
3179 if (vino_queue_outgoing_contains(&vcs->fb_queue,
3180 fb->id)) {
3181 b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3182 b->flags |= V4L2_BUF_FLAG_DONE;
3183 } else if (vino_queue_incoming_contains(&vcs->fb_queue,
3184 fb->id)) {
3185 b->flags &= ~V4L2_BUF_FLAG_DONE;
3186 b->flags |= V4L2_BUF_FLAG_QUEUED;
3187 } else {
3188 b->flags &= ~(V4L2_BUF_FLAG_DONE |
3189 V4L2_BUF_FLAG_QUEUED);
3192 b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
3194 if (fb->map_count > 0)
3195 b->flags |= V4L2_BUF_FLAG_MAPPED;
3197 b->index = fb->id;
3198 b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
3199 V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
3200 b->m.offset = fb->offset;
3201 b->bytesused = fb->data_size;
3202 b->length = fb->size;
3203 b->field = V4L2_FIELD_INTERLACED;
3204 b->sequence = fb->frame_counter;
3205 memcpy(&b->timestamp, &fb->timestamp,
3206 sizeof(struct timeval));
3207 // b->input ?
3209 dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
3210 fb->id, fb->size, fb->data_size, fb->offset);
3213 static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
3214 struct v4l2_buffer *b)
3216 if (vcs->reading)
3217 return -EBUSY;
3219 switch (b->type) {
3220 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3221 struct vino_framebuffer *fb;
3223 // TODO: check queue type
3224 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3225 dprintk("invalid index = %d\n",
3226 b->index);
3227 return -EINVAL;
3230 fb = vino_queue_get_buffer(&vcs->fb_queue,
3231 b->index);
3232 if (fb == NULL) {
3233 dprintk("vino_queue_get_buffer() failed");
3234 return -EINVAL;
3237 vino_v4l2_get_buffer_status(vcs, fb, b);
3238 break;
3240 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3241 default:
3242 return -EINVAL;
3245 return 0;
3248 static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
3249 struct v4l2_buffer *b)
3251 if (vcs->reading)
3252 return -EBUSY;
3254 switch (b->type) {
3255 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3256 struct vino_framebuffer *fb;
3257 int ret;
3259 // TODO: check queue type
3260 if (b->memory != V4L2_MEMORY_MMAP) {
3261 dprintk("type not mmap\n");
3262 return -EINVAL;
3265 fb = vino_capture_enqueue(vcs, b->index);
3266 if (fb == NULL)
3267 return -EINVAL;
3269 vino_v4l2_get_buffer_status(vcs, fb, b);
3271 if (vcs->streaming) {
3272 ret = vino_capture_next(vcs, 1);
3273 if (ret)
3274 return ret;
3276 break;
3278 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3279 default:
3280 return -EINVAL;
3283 return 0;
3286 static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3287 struct v4l2_buffer *b,
3288 unsigned int nonblocking)
3290 if (vcs->reading)
3291 return -EBUSY;
3293 switch (b->type) {
3294 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3295 struct vino_framebuffer *fb;
3296 unsigned int incoming, outgoing;
3297 int err;
3299 // TODO: check queue type
3301 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3302 if (err) {
3303 dprintk("vino_queue_get_incoming() failed\n");
3304 return -EIO;
3306 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3307 if (err) {
3308 dprintk("vino_queue_get_outgoing() failed\n");
3309 return -EIO;
3312 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3314 if (outgoing == 0) {
3315 if (incoming == 0) {
3316 dprintk("no incoming or outgoing buffers\n");
3317 return -EINVAL;
3319 if (nonblocking) {
3320 dprintk("non-blocking I/O was selected and "
3321 "there are no buffers to dequeue\n");
3322 return -EAGAIN;
3325 err = vino_wait_for_frame(vcs);
3326 if (err) {
3327 err = vino_wait_for_frame(vcs);
3328 if (err) {
3329 /* interrupted */
3330 vino_capture_failed(vcs);
3331 return -EIO;
3336 fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3337 if (fb == NULL) {
3338 dprintk("vino_queue_remove() failed\n");
3339 return -EINVAL;
3342 err = vino_check_buffer(vcs, fb);
3343 if (err)
3344 return -EIO;
3346 vino_v4l2_get_buffer_status(vcs, fb, b);
3347 break;
3349 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3350 default:
3351 return -EINVAL;
3354 return 0;
3357 static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
3359 unsigned int incoming;
3360 int ret;
3361 if (vcs->reading)
3362 return -EBUSY;
3364 if (vcs->streaming)
3365 return 0;
3367 // TODO: check queue type
3369 if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3370 dprintk("no buffers allocated\n");
3371 return -EINVAL;
3374 ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3375 if (ret) {
3376 dprintk("vino_queue_get_incoming() failed\n");
3377 return -EINVAL;
3380 vcs->streaming = 1;
3382 if (incoming > 0) {
3383 ret = vino_capture_next(vcs, 1);
3384 if (ret) {
3385 vcs->streaming = 0;
3387 dprintk("couldn't start capture\n");
3388 return -EINVAL;
3392 return 0;
3395 static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3397 if (vcs->reading)
3398 return -EBUSY;
3400 if (!vcs->streaming)
3401 return 0;
3403 vino_capture_stop(vcs);
3404 vcs->streaming = 0;
3406 return 0;
3409 static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3410 struct v4l2_queryctrl *queryctrl)
3412 int i;
3413 int err = 0;
3415 spin_lock(&vino_drvdata->input_lock);
3417 switch (vcs->input) {
3418 case VINO_INPUT_D1:
3419 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3420 if (vino_indycam_v4l2_controls[i].id ==
3421 queryctrl->id) {
3422 memcpy(queryctrl,
3423 &vino_indycam_v4l2_controls[i],
3424 sizeof(struct v4l2_queryctrl));
3425 goto found;
3429 err = -EINVAL;
3430 break;
3431 case VINO_INPUT_COMPOSITE:
3432 case VINO_INPUT_SVIDEO:
3433 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3434 if (vino_saa7191_v4l2_controls[i].id ==
3435 queryctrl->id) {
3436 memcpy(queryctrl,
3437 &vino_saa7191_v4l2_controls[i],
3438 sizeof(struct v4l2_queryctrl));
3439 goto found;
3443 err = -EINVAL;
3444 break;
3445 default:
3446 err = -EINVAL;
3449 found:
3450 spin_unlock(&vino_drvdata->input_lock);
3452 return err;
3455 static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
3456 struct v4l2_control *control)
3458 struct indycam_control indycam_ctrl;
3459 struct saa7191_control saa7191_ctrl;
3460 int err = 0;
3462 spin_lock(&vino_drvdata->input_lock);
3464 switch (vcs->input) {
3465 case VINO_INPUT_D1:
3466 i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS,
3467 &indycam_ctrl);
3469 switch(control->id) {
3470 case V4L2_CID_AUTOGAIN:
3471 control->value = indycam_ctrl.agc;
3472 break;
3473 case V4L2_CID_AUTO_WHITE_BALANCE:
3474 control->value = indycam_ctrl.awb;
3475 break;
3476 case V4L2_CID_GAIN:
3477 control->value = indycam_ctrl.gain;
3478 break;
3479 case V4L2_CID_PRIVATE_BASE:
3480 control->value = indycam_ctrl.red_saturation;
3481 break;
3482 case V4L2_CID_PRIVATE_BASE + 1:
3483 control->value = indycam_ctrl.blue_saturation;
3484 break;
3485 case V4L2_CID_RED_BALANCE:
3486 control->value = indycam_ctrl.red_balance;
3487 break;
3488 case V4L2_CID_BLUE_BALANCE:
3489 control->value = indycam_ctrl.blue_balance;
3490 break;
3491 case V4L2_CID_EXPOSURE:
3492 control->value = indycam_ctrl.shutter;
3493 break;
3494 case V4L2_CID_GAMMA:
3495 control->value = indycam_ctrl.gamma;
3496 break;
3497 default:
3498 err = -EINVAL;
3500 break;
3501 case VINO_INPUT_COMPOSITE:
3502 case VINO_INPUT_SVIDEO:
3503 i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS,
3504 &saa7191_ctrl);
3506 switch(control->id) {
3507 case V4L2_CID_HUE:
3508 control->value = saa7191_ctrl.hue;
3509 break;
3510 case V4L2_CID_PRIVATE_BASE:
3511 control->value = saa7191_ctrl.vtrc;
3512 break;
3513 default:
3514 err = -EINVAL;
3516 break;
3517 default:
3518 err = -EINVAL;
3521 spin_unlock(&vino_drvdata->input_lock);
3523 return err;
3526 static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
3527 struct v4l2_control *control)
3529 struct indycam_control indycam_ctrl;
3530 struct saa7191_control saa7191_ctrl;
3531 int i;
3532 int err = 0;
3534 spin_lock(&vino_drvdata->input_lock);
3536 switch (vcs->input) {
3537 case VINO_INPUT_D1:
3538 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3539 if (vino_indycam_v4l2_controls[i].id ==
3540 control->id) {
3541 if ((control->value >=
3542 vino_indycam_v4l2_controls[i].minimum)
3543 && (control->value <=
3544 vino_indycam_v4l2_controls[i].
3545 maximum)) {
3546 goto ok1;
3547 } else {
3548 err = -ERANGE;
3549 goto error;
3553 err = -EINVAL;
3554 goto error;
3556 ok1:
3557 indycam_ctrl.agc = INDYCAM_VALUE_UNCHANGED;
3558 indycam_ctrl.awb = INDYCAM_VALUE_UNCHANGED;
3559 indycam_ctrl.shutter = INDYCAM_VALUE_UNCHANGED;
3560 indycam_ctrl.gain = INDYCAM_VALUE_UNCHANGED;
3561 indycam_ctrl.red_balance = INDYCAM_VALUE_UNCHANGED;
3562 indycam_ctrl.blue_balance = INDYCAM_VALUE_UNCHANGED;
3563 indycam_ctrl.red_saturation = INDYCAM_VALUE_UNCHANGED;
3564 indycam_ctrl.blue_saturation = INDYCAM_VALUE_UNCHANGED;
3565 indycam_ctrl.gamma = INDYCAM_VALUE_UNCHANGED;
3567 switch(control->id) {
3568 case V4L2_CID_AUTOGAIN:
3569 indycam_ctrl.agc = control->value;
3570 break;
3571 case V4L2_CID_AUTO_WHITE_BALANCE:
3572 indycam_ctrl.awb = control->value;
3573 break;
3574 case V4L2_CID_GAIN:
3575 indycam_ctrl.gain = control->value;
3576 break;
3577 case V4L2_CID_PRIVATE_BASE:
3578 indycam_ctrl.red_saturation = control->value;
3579 break;
3580 case V4L2_CID_PRIVATE_BASE + 1:
3581 indycam_ctrl.blue_saturation = control->value;
3582 break;
3583 case V4L2_CID_RED_BALANCE:
3584 indycam_ctrl.red_balance = control->value;
3585 break;
3586 case V4L2_CID_BLUE_BALANCE:
3587 indycam_ctrl.blue_balance = control->value;
3588 break;
3589 case V4L2_CID_EXPOSURE:
3590 indycam_ctrl.shutter = control->value;
3591 break;
3592 case V4L2_CID_GAMMA:
3593 indycam_ctrl.gamma = control->value;
3594 break;
3595 default:
3596 err = -EINVAL;
3599 if (!err)
3600 i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS,
3601 &indycam_ctrl);
3602 break;
3603 case VINO_INPUT_COMPOSITE:
3604 case VINO_INPUT_SVIDEO:
3605 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3606 if (vino_saa7191_v4l2_controls[i].id ==
3607 control->id) {
3608 if ((control->value >=
3609 vino_saa7191_v4l2_controls[i].minimum)
3610 && (control->value <=
3611 vino_saa7191_v4l2_controls[i].
3612 maximum)) {
3613 goto ok2;
3614 } else {
3615 err = -ERANGE;
3616 goto error;
3620 err = -EINVAL;
3621 goto error;
3623 ok2:
3624 saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED;
3625 saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED;
3627 switch(control->id) {
3628 case V4L2_CID_HUE:
3629 saa7191_ctrl.hue = control->value;
3630 break;
3631 case V4L2_CID_PRIVATE_BASE:
3632 saa7191_ctrl.vtrc = control->value;
3633 break;
3634 default:
3635 err = -EINVAL;
3638 if (!err)
3639 i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS,
3640 &saa7191_ctrl);
3641 break;
3642 default:
3643 err = -EINVAL;
3646 error:
3647 spin_unlock(&vino_drvdata->input_lock);
3649 return err;
3652 /* File operations */
3654 static int vino_open(struct inode *inode, struct file *file)
3656 struct video_device *dev = video_devdata(file);
3657 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3658 int ret = 0;
3659 dprintk("open(): channel = %c\n",
3660 (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3662 down(&vcs->sem);
3664 if (vcs->users) {
3665 dprintk("open(): driver busy\n");
3666 ret = -EBUSY;
3667 goto out;
3670 ret = vino_acquire_input(vcs);
3671 if (ret) {
3672 dprintk("open(): vino_acquire_input() failed\n");
3673 goto out;
3676 vcs->users++;
3678 out:
3679 up(&vcs->sem);
3681 dprintk("open(): %s!\n", ret ? "failed" : "complete");
3683 return ret;
3686 static int vino_close(struct inode *inode, struct file *file)
3688 struct video_device *dev = video_devdata(file);
3689 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3690 dprintk("close():\n");
3692 down(&vcs->sem);
3694 vcs->users--;
3696 if (!vcs->users) {
3697 vino_release_input(vcs);
3699 /* stop DMA and free buffers */
3700 vino_capture_stop(vcs);
3701 vino_queue_free(&vcs->fb_queue);
3704 up(&vcs->sem);
3706 return 0;
3709 static void vino_vm_open(struct vm_area_struct *vma)
3711 struct vino_framebuffer *fb = vma->vm_private_data;
3713 fb->map_count++;
3714 dprintk("vino_vm_open(): count = %d\n", fb->map_count);
3717 static void vino_vm_close(struct vm_area_struct *vma)
3719 struct vino_framebuffer *fb = vma->vm_private_data;
3721 fb->map_count--;
3722 dprintk("vino_vm_close(): count = %d\n", fb->map_count);
3725 static struct vm_operations_struct vino_vm_ops = {
3726 .open = vino_vm_open,
3727 .close = vino_vm_close,
3730 static int vino_mmap(struct file *file, struct vm_area_struct *vma)
3732 struct video_device *dev = video_devdata(file);
3733 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3735 unsigned long start = vma->vm_start;
3736 unsigned long size = vma->vm_end - vma->vm_start;
3737 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3739 struct vino_framebuffer *fb = NULL;
3740 unsigned int i, length;
3741 int ret = 0;
3743 dprintk("mmap():\n");
3745 // TODO: reject mmap if already mapped
3747 if (down_interruptible(&vcs->sem))
3748 return -EINTR;
3750 if (vcs->reading) {
3751 ret = -EBUSY;
3752 goto out;
3755 // TODO: check queue type
3757 if (!(vma->vm_flags & VM_WRITE)) {
3758 dprintk("mmap(): app bug: PROT_WRITE please\n");
3759 ret = -EINVAL;
3760 goto out;
3762 if (!(vma->vm_flags & VM_SHARED)) {
3763 dprintk("mmap(): app bug: MAP_SHARED please\n");
3764 ret = -EINVAL;
3765 goto out;
3768 /* find the correct buffer using offset */
3769 length = vino_queue_get_length(&vcs->fb_queue);
3770 if (length == 0) {
3771 dprintk("mmap(): queue not initialized\n");
3772 ret = -EINVAL;
3773 goto out;
3776 for (i = 0; i < length; i++) {
3777 fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3778 if (fb == NULL) {
3779 dprintk("mmap(): vino_queue_get_buffer() failed\n");
3780 ret = -EINVAL;
3781 goto out;
3784 if (fb->offset == offset)
3785 goto found;
3788 dprintk("mmap(): invalid offset = %lu\n", offset);
3789 ret = -EINVAL;
3790 goto out;
3792 found:
3793 dprintk("mmap(): buffer = %d\n", i);
3795 if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
3796 dprintk("mmap(): failed: size = %lu > %lu\n",
3797 size, fb->desc_table.page_count * PAGE_SIZE);
3798 ret = -EINVAL;
3799 goto out;
3802 for (i = 0; i < fb->desc_table.page_count; i++) {
3803 unsigned long pfn =
3804 virt_to_phys((void *)fb->desc_table.virtual[i]) >>
3805 PAGE_SHIFT;
3807 if (size < PAGE_SIZE)
3808 break;
3810 // protection was: PAGE_READONLY
3811 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
3812 vma->vm_page_prot)) {
3813 dprintk("mmap(): remap_pfn_range() failed\n");
3814 ret = -EAGAIN;
3815 goto out;
3818 start += PAGE_SIZE;
3819 size -= PAGE_SIZE;
3822 fb->map_count = 1;
3824 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
3825 vma->vm_flags &= ~VM_IO;
3826 vma->vm_private_data = fb;
3827 vma->vm_file = file;
3828 vma->vm_ops = &vino_vm_ops;
3830 out:
3831 up(&vcs->sem);
3833 return ret;
3836 static unsigned int vino_poll(struct file *file, poll_table *pt)
3838 struct video_device *dev = video_devdata(file);
3839 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3840 unsigned int outgoing;
3841 unsigned int ret = 0;
3843 // lock mutex (?)
3844 // TODO: this has to be corrected for different read modes
3846 dprintk("poll():\n");
3848 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3849 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3850 ret = POLLERR;
3851 goto error;
3853 if (outgoing > 0)
3854 goto over;
3856 poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
3858 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3859 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3860 ret = POLLERR;
3861 goto error;
3864 over:
3865 dprintk("poll(): data %savailable\n",
3866 (outgoing > 0) ? "" : "not ");
3867 if (outgoing > 0) {
3868 ret = POLLIN | POLLRDNORM;
3871 error:
3873 return ret;
3876 static int vino_do_ioctl(struct inode *inode, struct file *file,
3877 unsigned int cmd, void *arg)
3879 struct video_device *dev = video_devdata(file);
3880 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3882 switch (_IOC_TYPE(cmd)) {
3883 case 'v':
3884 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
3885 break;
3886 case 'V':
3887 dprintk("ioctl(): V4L2 %s (0x%08x)\n",
3888 v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
3889 break;
3890 default:
3891 dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
3894 switch (cmd) {
3895 /* TODO: V4L1 interface (use compatibility layer?) */
3896 /* V4L2 interface */
3897 case VIDIOC_QUERYCAP: {
3898 vino_v4l2_querycap(arg);
3899 break;
3901 case VIDIOC_ENUMINPUT: {
3902 return vino_v4l2_enuminput(vcs, arg);
3904 case VIDIOC_G_INPUT: {
3905 return vino_v4l2_g_input(vcs, arg);
3907 case VIDIOC_S_INPUT: {
3908 return vino_v4l2_s_input(vcs, arg);
3910 case VIDIOC_ENUMSTD: {
3911 return vino_v4l2_enumstd(vcs, arg);
3913 case VIDIOC_G_STD: {
3914 return vino_v4l2_g_std(vcs, arg);
3916 case VIDIOC_S_STD: {
3917 return vino_v4l2_s_std(vcs, arg);
3919 case VIDIOC_ENUM_FMT: {
3920 return vino_v4l2_enum_fmt(vcs, arg);
3922 case VIDIOC_TRY_FMT: {
3923 return vino_v4l2_try_fmt(vcs, arg);
3925 case VIDIOC_G_FMT: {
3926 return vino_v4l2_g_fmt(vcs, arg);
3928 case VIDIOC_S_FMT: {
3929 return vino_v4l2_s_fmt(vcs, arg);
3931 case VIDIOC_CROPCAP: {
3932 return vino_v4l2_cropcap(vcs, arg);
3934 case VIDIOC_G_CROP: {
3935 return vino_v4l2_g_crop(vcs, arg);
3937 case VIDIOC_S_CROP: {
3938 return vino_v4l2_s_crop(vcs, arg);
3940 case VIDIOC_G_PARM: {
3941 return vino_v4l2_g_parm(vcs, arg);
3943 case VIDIOC_S_PARM: {
3944 return vino_v4l2_s_parm(vcs, arg);
3946 case VIDIOC_REQBUFS: {
3947 return vino_v4l2_reqbufs(vcs, arg);
3949 case VIDIOC_QUERYBUF: {
3950 return vino_v4l2_querybuf(vcs, arg);
3952 case VIDIOC_QBUF: {
3953 return vino_v4l2_qbuf(vcs, arg);
3955 case VIDIOC_DQBUF: {
3956 return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
3958 case VIDIOC_STREAMON: {
3959 return vino_v4l2_streamon(vcs);
3961 case VIDIOC_STREAMOFF: {
3962 return vino_v4l2_streamoff(vcs);
3964 case VIDIOC_QUERYCTRL: {
3965 return vino_v4l2_queryctrl(vcs, arg);
3967 case VIDIOC_G_CTRL: {
3968 return vino_v4l2_g_ctrl(vcs, arg);
3970 case VIDIOC_S_CTRL: {
3971 return vino_v4l2_s_ctrl(vcs, arg);
3973 default:
3974 return -ENOIOCTLCMD;
3977 return 0;
3980 static int vino_ioctl(struct inode *inode, struct file *file,
3981 unsigned int cmd, unsigned long arg)
3983 struct video_device *dev = video_devdata(file);
3984 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3985 int ret;
3987 if (down_interruptible(&vcs->sem))
3988 return -EINTR;
3990 ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
3992 up(&vcs->sem);
3994 return ret;
3997 /* Initialization and cleanup */
3999 // __initdata
4000 static int vino_init_stage = 0;
4002 static struct file_operations vino_fops = {
4003 .owner = THIS_MODULE,
4004 .open = vino_open,
4005 .release = vino_close,
4006 .ioctl = vino_ioctl,
4007 .mmap = vino_mmap,
4008 .poll = vino_poll,
4009 .llseek = no_llseek,
4012 static struct video_device v4l_device_template = {
4013 .name = "NOT SET",
4014 //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
4015 // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
4016 .hardware = VID_HARDWARE_VINO,
4017 .fops = &vino_fops,
4018 .minor = -1,
4021 static void vino_module_cleanup(int stage)
4023 switch(stage) {
4024 case 10:
4025 video_unregister_device(vino_drvdata->b.v4l_device);
4026 vino_drvdata->b.v4l_device = NULL;
4027 case 9:
4028 video_unregister_device(vino_drvdata->a.v4l_device);
4029 vino_drvdata->a.v4l_device = NULL;
4030 case 8:
4031 vino_i2c_del_bus();
4032 case 7:
4033 free_irq(SGI_VINO_IRQ, NULL);
4034 case 6:
4035 if (vino_drvdata->b.v4l_device) {
4036 video_device_release(vino_drvdata->b.v4l_device);
4037 vino_drvdata->b.v4l_device = NULL;
4039 case 5:
4040 if (vino_drvdata->a.v4l_device) {
4041 video_device_release(vino_drvdata->a.v4l_device);
4042 vino_drvdata->a.v4l_device = NULL;
4044 case 4:
4045 /* all entries in dma_cpu dummy table have the same address */
4046 dma_unmap_single(NULL,
4047 vino_drvdata->dummy_desc_table.dma_cpu[0],
4048 PAGE_SIZE, DMA_FROM_DEVICE);
4049 dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
4050 * sizeof(dma_addr_t),
4051 (void *)vino_drvdata->
4052 dummy_desc_table.dma_cpu,
4053 vino_drvdata->dummy_desc_table.dma);
4054 case 3:
4055 free_page(vino_drvdata->dummy_page);
4056 case 2:
4057 kfree(vino_drvdata);
4058 case 1:
4059 iounmap(vino);
4060 case 0:
4061 break;
4062 default:
4063 dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
4064 stage);
4068 static int vino_probe(void)
4070 unsigned long rev_id;
4072 if (ip22_is_fullhouse()) {
4073 printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
4074 return -ENODEV;
4077 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
4078 printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
4079 return -ENODEV;
4082 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
4083 if (!vino) {
4084 printk(KERN_ERR "VINO: ioremap() failed\n");
4085 return -EIO;
4087 vino_init_stage++;
4089 if (get_dbe(rev_id, &(vino->rev_id))) {
4090 printk(KERN_ERR "Failed to read VINO revision register\n");
4091 vino_module_cleanup(vino_init_stage);
4092 return -ENODEV;
4095 if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
4096 printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
4097 rev_id);
4098 vino_module_cleanup(vino_init_stage);
4099 return -ENODEV;
4102 printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n",
4103 VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id));
4105 return 0;
4108 static int vino_init(void)
4110 dma_addr_t dma_dummy_address;
4111 int i;
4113 vino_drvdata = (struct vino_settings *)
4114 kmalloc(sizeof(struct vino_settings), GFP_KERNEL);
4115 if (!vino_drvdata) {
4116 vino_module_cleanup(vino_init_stage);
4117 return -ENOMEM;
4119 memset(vino_drvdata, 0, sizeof(struct vino_settings));
4120 vino_init_stage++;
4122 /* create a dummy dma descriptor */
4123 vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
4124 if (!vino_drvdata->dummy_page) {
4125 vino_module_cleanup(vino_init_stage);
4126 return -ENOMEM;
4128 vino_init_stage++;
4130 // TODO: use page_count in dummy_desc_table
4132 vino_drvdata->dummy_desc_table.dma_cpu =
4133 dma_alloc_coherent(NULL,
4134 VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
4135 &vino_drvdata->dummy_desc_table.dma,
4136 GFP_KERNEL | GFP_DMA);
4137 if (!vino_drvdata->dummy_desc_table.dma_cpu) {
4138 vino_module_cleanup(vino_init_stage);
4139 return -ENOMEM;
4141 vino_init_stage++;
4143 dma_dummy_address = dma_map_single(NULL,
4144 (void *)vino_drvdata->dummy_page,
4145 PAGE_SIZE, DMA_FROM_DEVICE);
4146 for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
4147 vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
4150 /* initialize VINO */
4152 vino->control = 0;
4153 vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4154 vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4155 udelay(VINO_DESC_FETCH_DELAY);
4157 vino->intr_status = 0;
4159 vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4160 vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4162 return 0;
4165 static int vino_init_channel_settings(struct vino_channel_settings *vcs,
4166 unsigned int channel, const char *name)
4168 vcs->channel = channel;
4169 vcs->input = VINO_INPUT_NONE;
4170 vcs->alpha = 0;
4171 vcs->users = 0;
4172 vcs->data_format = VINO_DATA_FMT_GREY;
4173 vcs->data_norm = VINO_DATA_NORM_NTSC;
4174 vcs->decimation = 1;
4175 vino_set_default_clipping(vcs);
4176 vino_set_default_framerate(vcs);
4178 vcs->capturing = 0;
4180 init_MUTEX(&vcs->sem);
4181 spin_lock_init(&vcs->capture_lock);
4183 init_MUTEX(&vcs->fb_queue.queue_sem);
4184 spin_lock_init(&vcs->fb_queue.queue_lock);
4185 init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
4187 vcs->v4l_device = video_device_alloc();
4188 if (!vcs->v4l_device) {
4189 vino_module_cleanup(vino_init_stage);
4190 return -ENOMEM;
4192 vino_init_stage++;
4194 memcpy(vcs->v4l_device, &v4l_device_template,
4195 sizeof(struct video_device));
4196 strcpy(vcs->v4l_device->name, name);
4197 vcs->v4l_device->release = video_device_release;
4199 video_set_drvdata(vcs->v4l_device, vcs);
4201 return 0;
4204 static int __init vino_module_init(void)
4206 int ret;
4208 printk(KERN_INFO "SGI VINO driver version %s\n",
4209 VINO_MODULE_VERSION);
4211 ret = vino_probe();
4212 if (ret)
4213 return ret;
4215 ret = vino_init();
4216 if (ret)
4217 return ret;
4219 /* initialize data structures */
4221 spin_lock_init(&vino_drvdata->vino_lock);
4222 spin_lock_init(&vino_drvdata->input_lock);
4224 ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
4225 vino_v4l_device_name_a);
4226 if (ret)
4227 return ret;
4229 ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4230 vino_v4l_device_name_b);
4231 if (ret)
4232 return ret;
4234 /* initialize hardware and register V4L devices */
4236 ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4237 vino_driver_description, NULL);
4238 if (ret) {
4239 printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
4240 SGI_VINO_IRQ);
4241 vino_module_cleanup(vino_init_stage);
4242 return -EAGAIN;
4244 vino_init_stage++;
4246 ret = vino_i2c_add_bus();
4247 if (ret) {
4248 printk(KERN_ERR "VINO I2C bus registration failed\n");
4249 vino_module_cleanup(vino_init_stage);
4250 return ret;
4252 vino_init_stage++;
4254 ret = video_register_device(vino_drvdata->a.v4l_device,
4255 VFL_TYPE_GRABBER, -1);
4256 if (ret < 0) {
4257 printk(KERN_ERR "VINO channel A Video4Linux-device "
4258 "registration failed\n");
4259 vino_module_cleanup(vino_init_stage);
4260 return -EINVAL;
4262 vino_init_stage++;
4264 ret = video_register_device(vino_drvdata->b.v4l_device,
4265 VFL_TYPE_GRABBER, -1);
4266 if (ret < 0) {
4267 printk(KERN_ERR "VINO channel B Video4Linux-device "
4268 "registration failed\n");
4269 vino_module_cleanup(vino_init_stage);
4270 return -EINVAL;
4272 vino_init_stage++;
4274 #if defined(CONFIG_KMOD) && defined(MODULE)
4275 request_module("saa7191");
4276 request_module("indycam");
4277 #endif
4279 dprintk("init complete!\n");
4281 return 0;
4284 static void __exit vino_module_exit(void)
4286 dprintk("exiting, stage = %d ...\n", vino_init_stage);
4287 vino_module_cleanup(vino_init_stage);
4288 dprintk("cleanup complete, exit!\n");
4291 module_init(vino_module_init);
4292 module_exit(vino_module_exit);