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>
15 * - remove "hacks" from memory allocation code and implement nopage()
16 * - check decimation, calculating and reporting image size when
18 * - check vino_acquire_input(), vino_set_input() and channel
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>
31 #include <linux/kernel.h>
33 #include <linux/interrupt.h>
34 #include <linux/dma-mapping.h>
35 #include <linux/time.h>
36 #include <linux/moduleparam.h>
39 #include <linux/kmod.h>
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>
51 #include <asm/sgi/ip22.h>
52 #include <asm/sgi/mc.h>
58 /* Uncomment the following line to get lots and lots of (mostly useless)
60 * Note that the debug output also slows down the driver significantly */
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))
75 #define dprintk(x...) printk("VINO: " x);
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 \
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 */
161 struct vino_clipping {
162 unsigned int left, right, top, bottom;
165 struct vino_data_format {
166 /* the description */
168 /* bytes per pixel */
170 /* V4L2 fourcc code */
172 /* V4L2 colorspace (duh!) */
173 enum v4l2_colorspace colorspace;
176 struct vino_data_norm {
178 unsigned int width, height;
179 struct vino_clipping odd;
180 struct vino_clipping even;
183 unsigned int fps_min, fps_max;
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) */
202 struct vino_framebuffer {
203 /* identifier nubmer */
205 /* the length of the whole buffer */
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 */
213 /* is the buffer mapped in user space? */
214 unsigned int map_count;
215 /* memory offset for mmap() */
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 {
234 unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT];
237 struct vino_framebuffer_queue {
240 /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
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;
259 unsigned int data_format;
260 unsigned int data_norm;
261 struct vino_clipping clipping;
262 unsigned int decimation;
263 unsigned int line_size;
266 unsigned int framert_reg;
268 unsigned int fifo_threshold;
270 struct vino_framebuffer_queue fb_queue;
272 /* number of the current field */
275 /* read in progress */
277 /* streaming is active */
279 /* the driver is currently processing the queue */
282 struct semaphore sem;
283 spinlock_t capture_lock;
288 struct video_device *v4l_device;
292 /* the channel which owns this client:
293 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
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
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[] = {
350 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
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",
364 .pixelformat = V4L2_PIX_FMT_GREY,
365 .colorspace = V4L2_COLORSPACE_SMPTE170M,
367 .description = "8-bit dithered RGB 3-3-2",
369 .pixelformat = V4L2_PIX_FMT_RGB332,
370 .colorspace = V4L2_COLORSPACE_SRGB,
372 .description = "32-bit RGB",
374 .pixelformat = V4L2_PIX_FMT_RGB32,
375 .colorspace = V4L2_COLORSPACE_SRGB,
377 .description = "YUV 4:2:2",
379 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
380 .colorspace = V4L2_COLORSPACE_SMPTE170M,
382 .description = "24-bit RGB",
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,
396 .width = VINO_NTSC_WIDTH,
397 .height = VINO_NTSC_HEIGHT,
399 .top = VINO_CLIPPING_START_ODD_NTSC,
401 .bottom = VINO_CLIPPING_START_ODD_NTSC
402 + VINO_NTSC_HEIGHT / 2 - 1,
403 .right = VINO_NTSC_WIDTH,
406 .top = VINO_CLIPPING_START_EVEN_NTSC,
408 .bottom = VINO_CLIPPING_START_EVEN_NTSC
409 + VINO_NTSC_HEIGHT / 2 - 1,
410 .right = VINO_NTSC_WIDTH,
413 .description = "PAL",
418 .width = VINO_PAL_WIDTH,
419 .height = VINO_PAL_HEIGHT,
421 .top = VINO_CLIPPING_START_ODD_PAL,
423 .bottom = VINO_CLIPPING_START_ODD_PAL
424 + VINO_PAL_HEIGHT / 2 - 1,
425 .right = VINO_PAL_WIDTH,
428 .top = VINO_CLIPPING_START_EVEN_PAL,
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,
440 .width = VINO_PAL_WIDTH,
441 .height = VINO_PAL_HEIGHT,
443 .top = VINO_CLIPPING_START_ODD_PAL,
445 .bottom = VINO_CLIPPING_START_ODD_PAL
446 + VINO_PAL_HEIGHT / 2 - 1,
447 .right = VINO_PAL_WIDTH,
450 .top = VINO_CLIPPING_START_EVEN_PAL,
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,
462 .width = VINO_NTSC_WIDTH,
463 .height = VINO_NTSC_HEIGHT,
465 .top = VINO_CLIPPING_START_ODD_D1,
467 .bottom = VINO_CLIPPING_START_ODD_D1
468 + VINO_NTSC_HEIGHT / 2 - 1,
469 .right = VINO_NTSC_WIDTH,
472 .top = VINO_CLIPPING_START_EVEN_D1,
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",
491 .default_value = INDYCAM_AGC_DEFAULT,
493 .reserved = { 0, 0 },
495 .id = V4L2_CID_AUTO_WHITE_BALANCE,
496 .type = V4L2_CTRL_TYPE_BOOLEAN,
497 .name = "Automatic White Balance",
501 .default_value = INDYCAM_AWB_DEFAULT,
503 .reserved = { 0, 0 },
506 .type = V4L2_CTRL_TYPE_INTEGER,
508 .minimum = INDYCAM_GAIN_MIN,
509 .maximum = INDYCAM_GAIN_MAX,
511 .default_value = INDYCAM_GAIN_DEFAULT,
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,
521 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
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,
531 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
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,
541 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
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,
551 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
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,
561 .default_value = INDYCAM_SHUTTER_DEFAULT,
563 .reserved = { 0, 0 },
565 .id = V4L2_CID_GAMMA,
566 .type = V4L2_CTRL_TYPE_INTEGER,
568 .minimum = INDYCAM_GAMMA_MIN,
569 .maximum = INDYCAM_GAMMA_MAX,
571 .default_value = INDYCAM_GAMMA_DEFAULT,
573 .reserved = { 0, 0 },
577 #define VINO_SAA7191_V4L2_CONTROL_COUNT 2
579 struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
582 .type = V4L2_CTRL_TYPE_INTEGER,
584 .minimum = SAA7191_HUE_MIN,
585 .maximum = SAA7191_HUE_MAX,
587 .default_value = SAA7191_HUE_DEFAULT,
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,
597 .default_value = SAA7191_VTRC_DEFAULT,
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,
636 * There are two possible clients on VINO I2C bus, so we limit usage only
639 static int i2c_vino_client_reg(struct i2c_client *client)
643 spin_lock(&vino_drvdata->input_lock);
644 switch (client->driver->id) {
645 case I2C_DRIVERID_SAA7191:
646 if (vino_drvdata->decoder.driver)
649 vino_drvdata->decoder.driver = client;
651 case I2C_DRIVERID_INDYCAM:
652 if (vino_drvdata->camera.driver)
655 vino_drvdata->camera.driver = client;
660 spin_unlock(&vino_drvdata->input_lock);
665 static int i2c_vino_client_unreg(struct i2c_client *client)
669 spin_lock(&vino_drvdata->input_lock);
670 if (client == vino_drvdata->decoder.driver) {
671 if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
674 vino_drvdata->decoder.driver = NULL;
675 } else if (client == vino_drvdata->camera.driver) {
676 if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
679 vino_drvdata->camera.driver = NULL;
681 spin_unlock(&vino_drvdata->input_lock);
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,
712 static int i2c_decoder_command(unsigned int cmd, void *arg)
714 return vino_drvdata->decoder.driver->
715 driver->command(vino_drvdata->decoder.driver,
719 /* VINO framebuffer/DMA descriptor management */
721 static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
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,
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,
753 unsigned int count, i, j;
756 dprintk("vino_allocate_buffer():\n");
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",
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)
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) {
782 goto out_free_virtual;
785 /* allocate pages for the buffer and acquire the according
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]) {
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;
815 /* the descriptor with index i doesn't contain
816 * a valid address yet */
817 vino_free_buffer_with_count(fb, i);
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;
830 kfree(fb->desc_table.virtual);
835 /* user buffers not fully implemented yet */
836 static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
840 unsigned int count, i, j;
843 dprintk("vino_prepare_user_buffer():\n");
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",
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)
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) {
869 goto out_free_virtual;
872 /* allocate pages for the buffer and acquire the according
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]) {
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;
902 /* the descriptor with index i doesn't contain
903 * a valid address yet */
904 vino_free_buffer_with_count(fb, i);
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;
916 kfree(fb->desc_table.virtual);
921 static void vino_sync_buffer(struct vino_framebuffer *fb)
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,
943 if (length > VINO_FRAMEBUFFER_MAX_COUNT)
944 length = VINO_FRAMEBUFFER_MAX_COUNT;
949 /* returns true/false */
950 static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
953 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
954 if (f->data[i] == id)
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)
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;
987 return VINO_QUEUE_ERROR;
993 static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
996 *id = f->data[f->head];
998 return VINO_QUEUE_ERROR;
1004 static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
1007 *id = f->data[f->head];
1008 f->head = (f->head + 1) % f->length;
1011 return VINO_QUEUE_ERROR;
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)
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;
1039 static void vino_queue_free(struct vino_framebuffer_queue *q)
1041 dprintk("vino_queue_free():\n");
1043 if (q->magic != VINO_QUEUE_MAGIC)
1045 if (q->type != VINO_MEMORY_MMAP)
1048 down(&q->queue_sem);
1050 vino_queue_free_with_count(q, q->length);
1055 static int vino_queue_init(struct vino_framebuffer_queue *q,
1056 unsigned int *length)
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");
1068 if (q->type != VINO_MEMORY_NONE) {
1069 dprintk("vino_queue_init(): queue already initialized!\n");
1076 down(&q->queue_sem);
1078 if (*length > VINO_FRAMEBUFFER_MAX_COUNT)
1079 *length = VINO_FRAMEBUFFER_MAX_COUNT;
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),
1087 if (!q->buffer[i]) {
1088 dprintk("vino_queue_init(): kmalloc() failed\n");
1093 ret = vino_allocate_buffer(q->buffer[i],
1094 VINO_FRAMEBUFFER_SIZE);
1096 kfree(q->buffer[i]);
1097 dprintk("vino_queue_init(): "
1098 "vino_allocate_buffer() failed\n");
1102 q->buffer[i]->id = i;
1104 q->buffer[i]->offset = q->buffer[i - 1]->offset +
1105 q->buffer[i - 1]->size;
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);
1118 vino_queue_free_with_count(q, i);
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;
1133 static struct vino_framebuffer *vino_queue_add(struct
1134 vino_framebuffer_queue *q,
1137 struct vino_framebuffer *ret = NULL;
1139 unsigned long flags;
1141 dprintk("vino_queue_add(): id = %d\n", id);
1143 if (q->magic != VINO_QUEUE_MAGIC) {
1147 spin_lock_irqsave(&q->queue_lock, flags);
1152 if (id >= q->length)
1155 /* not needed?: if (vino_fifo_full(&q->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)
1165 if (vino_fifo_enqueue(&q->in, id))
1168 ret = q->buffer[id];
1171 spin_unlock_irqrestore(&q->queue_lock, flags);
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;
1182 unsigned long flags;
1184 dprintk("vino_queue_transfer():\n");
1186 if (q->magic != VINO_QUEUE_MAGIC) {
1190 spin_lock_irqsave(&q->queue_lock, flags);
1195 // now this actually removes an entry from the incoming queue
1196 if (vino_fifo_dequeue(&q->in, &id)) {
1200 dprintk("vino_queue_transfer(): id = %d\n", 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");
1212 spin_unlock_irqrestore(&q->queue_lock, flags);
1217 /* returns true/false */
1218 static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1222 unsigned long flags;
1224 if (q->magic != VINO_QUEUE_MAGIC) {
1228 spin_lock_irqsave(&q->queue_lock, flags);
1233 ret = vino_fifo_has_id(&q->in, id);
1236 spin_unlock_irqrestore(&q->queue_lock, flags);
1241 /* returns true/false */
1242 static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1246 unsigned long flags;
1248 if (q->magic != VINO_QUEUE_MAGIC) {
1252 spin_lock_irqsave(&q->queue_lock, flags);
1257 ret = vino_fifo_has_id(&q->out, id);
1260 spin_unlock_irqrestore(&q->queue_lock, flags);
1265 static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
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;
1282 *used = vino_fifo_get_used(&q->in);
1285 spin_unlock_irqrestore(&q->queue_lock, flags);
1290 static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
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;
1307 *used = vino_fifo_get_used(&q->out);
1310 spin_unlock_irqrestore(&q->queue_lock, flags);
1315 static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1316 unsigned int *total)
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;
1332 *total = vino_fifo_get_used(&q->in) +
1333 vino_fifo_get_used(&q->out);
1336 spin_unlock_irqrestore(&q->queue_lock, flags);
1341 static struct vino_framebuffer *vino_queue_peek(struct
1342 vino_framebuffer_queue *q,
1345 struct vino_framebuffer *ret = NULL;
1346 unsigned long flags;
1348 if (q->magic != VINO_QUEUE_MAGIC) {
1352 spin_lock_irqsave(&q->queue_lock, flags);
1357 if (vino_fifo_peek(&q->in, id)) {
1361 ret = q->buffer[*id];
1363 spin_unlock_irqrestore(&q->queue_lock, flags);
1368 static struct vino_framebuffer *vino_queue_remove(struct
1369 vino_framebuffer_queue *q,
1372 struct vino_framebuffer *ret = NULL;
1373 unsigned long flags;
1374 dprintk("vino_queue_remove():\n");
1376 if (q->magic != VINO_QUEUE_MAGIC) {
1380 spin_lock_irqsave(&q->queue_lock, flags);
1385 if (vino_fifo_dequeue(&q->out, id)) {
1389 dprintk("vino_queue_remove(): id = %d\n", *id);
1390 ret = q->buffer[*id];
1392 spin_unlock_irqrestore(&q->queue_lock, flags);
1398 vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1401 struct vino_framebuffer *ret = NULL;
1402 unsigned long flags;
1404 if (q->magic != VINO_QUEUE_MAGIC) {
1408 spin_lock_irqsave(&q->queue_lock, flags);
1413 if (id >= q->length)
1416 ret = q->buffer[id];
1418 spin_unlock_irqrestore(&q->queue_lock, flags);
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) {
1432 spin_lock_irqsave(&q->queue_lock, flags);
1434 spin_unlock_irqrestore(&q->queue_lock, flags);
1439 static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1443 unsigned long flags;
1445 if (q->magic != VINO_QUEUE_MAGIC) {
1449 spin_lock_irqsave(&q->queue_lock, flags);
1450 for (i = 0; i < q->length; i++) {
1451 if (q->buffer[i]->map_count > 0) {
1456 spin_unlock_irqrestore(&q->queue_lock, flags);
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;
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;
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 */
1500 if (y > maxheight) {
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) {
1512 if ((w / d) < VINO_MIN_WIDTH)
1513 x = maxwidth - VINO_MIN_WIDTH * d;
1515 if ((y + h) > maxheight) {
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);
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,
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;
1611 mask = VINO_FRAMERT_FULL;
1613 vcs->framert_reg = VINO_FRAMERT_RT(mask);
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;
1641 mask = VINO_FRAMERT_FULL;
1643 vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
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)
1664 struct sgi_vino_channel *ch;
1665 const struct vino_data_norm *norm;
1667 dprintk("vino_dma_setup():\n");
1670 fb->frame_counter = 0;
1672 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1673 norm = &vino_data_norms[vcs->data_norm];
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) /
1709 ((vcs->clipping.bottom - vcs->clipping.top) /
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
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;
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;
1745 ctrl &= ~VINO_CTRL_A_SELECT;
1748 ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1749 VINO_CTRL_A_DITHER);
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;
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;
1769 ctrl &= ~VINO_CTRL_B_SELECT;
1771 ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1772 VINO_CTRL_B_DITHER);
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;
1783 case VINO_DATA_FMT_RGB32:
1784 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1785 VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1787 case VINO_DATA_FMT_YUV:
1788 /* nothing needs to be done */
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;
1797 vino->intr_status = intr;
1798 vino->control = ctrl;
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;
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)
1850 unsigned long flags, flags2;
1852 spin_lock_irqsave(&fb->state_lock, flags);
1854 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1856 fb->state = VINO_FRAMEBUFFER_IN_USE;
1858 spin_unlock_irqrestore(&fb->state_lock, flags);
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);
1876 struct vino_framebuffer *vino_capture_enqueue(struct
1877 vino_channel_settings *vcs,
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);
1889 dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
1894 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1899 static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1901 struct vino_framebuffer *fb;
1902 unsigned int incoming, id;
1904 unsigned long flags, flags2;
1906 dprintk("vino_capture_next():\n");
1908 spin_lock_irqsave(&vcs->capture_lock, flags);
1911 /* start capture only if capture isn't in progress already */
1912 if (vcs->capturing) {
1913 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1918 /* capture next frame:
1919 * stop capture if capturing is not set */
1920 if (!vcs->capturing) {
1921 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1926 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
1928 dprintk("vino_capture_next(): vino_queue_get_incoming() "
1933 if (incoming == 0) {
1934 dprintk("vino_capture_next(): no buffers available\n");
1938 fb = vino_queue_peek(&vcs->fb_queue, &id);
1940 dprintk("vino_capture_next(): vino_queue_peek() failed\n");
1945 spin_lock_irqsave(&fb->state_lock, flags2);
1946 fb->state = VINO_FRAMEBUFFER_UNUSED;
1947 spin_unlock_irqrestore(&fb->state_lock, flags2);
1953 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1955 err = vino_capture(vcs, fb);
1961 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1966 static int vino_is_capturing(struct vino_channel_settings *vcs)
1969 unsigned long flags;
1971 spin_lock_irqsave(&vcs->capture_lock, flags);
1973 ret = vcs->capturing;
1975 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1980 /* waits until a frame is captured */
1981 static int vino_wait_for_frame(struct vino_channel_settings *vcs)
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))
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");
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;
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) {
2020 pageptr[0] = pageptr[3];
2021 pageptr[1] = pageptr[2];
2022 pageptr[2] = pageptr[1];
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)
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:
2043 case VINO_FRAMEBUFFER_READY:
2044 vino_sync_buffer(fb);
2045 fb->state = VINO_FRAMEBUFFER_UNUSED;
2050 spin_unlock_irqrestore(&fb->state_lock, flags);
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);
2062 vino_clear_interrupt(vcs);
2063 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
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 */
2081 spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
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");
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");
2104 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2105 dprintk("vino_capture_stop(): "
2106 "vino_queue_get_outgoing() failed\n");
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");
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;
2130 dprintk("vino_capture_failed():\n");
2132 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
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");
2145 /* no buffers to process */
2149 fb = vino_queue_peek(&vcs->fb_queue, &i);
2151 dprintk("vino_queue_peek() failed\n");
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);
2168 static void vino_frame_done(struct vino_channel_settings *vcs,
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);
2177 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2178 dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
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)
2199 unsigned int fc_a, fc_b;
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;
2220 dprintk("intr: channel A end-of-field interrupt: "
2223 vino_dma_stop(&vino_drvdata->a);
2224 vino_clear_interrupt(&vino_drvdata->a);
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;
2238 dprintk("intr: channel B end-of-field interrupt: "
2241 vino_dma_stop(&vino_drvdata->b);
2242 vino_clear_interrupt(&vino_drvdata->b);
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);
2254 vino_frame_done(&vino_drvdata->a, fc_a);
2255 dprintk("channel A frame done, interrupt: %d\n", intr);
2258 vino_frame_done(&vino_drvdata->b, fc_b);
2259 dprintk("channel B frame done, interrupt: %d\n", intr);
2265 /* VINO video input management */
2267 static int vino_get_saa7191_input(int input)
2270 case VINO_INPUT_COMPOSITE:
2271 return SAA7191_INPUT_COMPOSITE;
2272 case VINO_INPUT_SVIDEO:
2273 return SAA7191_INPUT_SVIDEO;
2275 printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2276 "invalid input!\n");
2281 static int vino_get_saa7191_norm(int 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;
2293 printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
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);
2307 return (vino_drvdata->camera.owner == vcs->channel);
2313 static int vino_acquire_input(struct vino_channel_settings *vcs)
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)) {
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)) {
2337 if (i2c_use_client(vino_drvdata->decoder.driver)) {
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);
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) {
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);
2371 spin_unlock(&vino_drvdata->input_lock);
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;
2382 dprintk("vino_set_input():\n");
2384 spin_lock(&vino_drvdata->input_lock);
2386 if (vcs->input == input)
2390 case VINO_INPUT_COMPOSITE:
2391 case VINO_INPUT_SVIDEO:
2392 if (!vino_drvdata->decoder.driver) {
2397 if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
2398 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2402 vino_drvdata->decoder.owner = vcs->channel;
2405 if (vino_drvdata->decoder.owner == vcs->channel) {
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,
2418 if (vcs2->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;
2432 i2c_release_client(vino_drvdata->
2434 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2439 if (!vino_drvdata->camera.driver) {
2444 if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
2445 if (i2c_use_client(vino_drvdata->camera.driver)) {
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;
2458 i2c_release_client(vino_drvdata->
2460 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2465 vcs->data_norm = VINO_DATA_NORM_D1;
2472 vino_set_default_clipping(vcs);
2473 vino_set_default_framerate(vcs);
2475 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2478 spin_unlock(&vino_drvdata->input_lock);
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;
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;
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)
2522 switch (vcs->input) {
2524 /* only one "norm" supported */
2525 if (data_norm != VINO_DATA_NORM_D1)
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;
2543 /* V4L2 helper functions */
2545 static int vino_find_data_format(__u32 pixelformat)
2549 for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2550 if (vino_data_formats[i].pixelformat == pixelformat)
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:
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;
2575 data_norm = VINO_DATA_NORM_D1;
2579 spin_unlock(&vino_drvdata->input_lock);
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) {
2592 input = VINO_INPUT_COMPOSITE;
2595 input = VINO_INPUT_SVIDEO;
2598 input = VINO_INPUT_D1;
2601 } else if (vino_drvdata->decoder.driver) {
2604 input = VINO_INPUT_COMPOSITE;
2607 input = VINO_INPUT_SVIDEO;
2610 } else if (vino_drvdata->camera.driver) {
2613 input = VINO_INPUT_D1;
2617 spin_unlock(&vino_drvdata->input_lock);
2622 /* execute with input_lock locked */
2623 static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
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:
2633 case VINO_INPUT_SVIDEO:
2640 } else if (vino_drvdata->decoder.driver) {
2641 switch (vcs->input) {
2642 case VINO_INPUT_COMPOSITE:
2645 case VINO_INPUT_SVIDEO:
2649 } else if (vino_drvdata->camera.driver) {
2650 switch (vcs->input) {
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;
2671 V4L2_CAP_VIDEO_CAPTURE |
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;
2681 dprintk("requested index = %d\n", index);
2683 input = vino_enum_input(vcs, index);
2684 if (input == VINO_INPUT_NONE)
2687 memset(i, 0, sizeof(struct v4l2_input));
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;
2705 static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2706 struct v4l2_input *i)
2711 spin_lock(&vino_drvdata->input_lock);
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) {
2722 memset(i, 0, sizeof(struct v4l2_input));
2725 i->type = V4L2_INPUT_TYPE_CAMERA;
2726 i->std = vino_inputs[input].std;
2727 strcpy(i->name, vino_inputs[input].name);
2732 static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
2733 struct v4l2_input *i)
2736 dprintk("requested input = %d\n", i->index);
2738 input = vino_enum_input(vcs, i->index);
2739 if (input == VINO_INPUT_NONE)
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)
2755 dprintk("standard name = %s\n",
2756 vino_data_norms[data_norm].description);
2758 memset(s, 0, sizeof(struct v4l2_standard));
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;
2766 vino_data_norms[data_norm].framelines;
2768 vino_data_norms[data_norm].description);
2773 static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
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);
2784 static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
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)
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;
2819 spin_unlock(&vino_drvdata->input_lock);
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);
2832 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2833 if ((fd->index < 0) ||
2834 (fd->index >= VINO_DATA_FMT_COUNT))
2836 dprintk("format name = %s\n",
2837 vino_data_formats[index].description);
2839 memset(fd, 0, sizeof(struct v4l2_fmtdesc));
2842 fd->pixelformat = vino_data_formats[index].pixelformat;
2843 strcpy(fd->description, vino_data_formats[index].description);
2845 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2853 static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2854 struct v4l2_format *f)
2856 struct vino_channel_settings tempvcs;
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;
2873 vino_data_formats[tempvcs.data_format].
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) /
2885 pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
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) /
2894 vino_data_formats[tempvcs.data_format].colorspace;
2899 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2907 static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
2908 struct v4l2_format *f)
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) /
2917 pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
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) /
2928 vino_data_formats[vcs->data_format].colorspace;
2932 spin_unlock(&vino_drvdata->input_lock);
2935 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2943 static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
2944 struct v4l2_format *f)
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);
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;
2962 vino_data_formats[vcs->data_format].
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) /
2983 vino_data_formats[vcs->data_format].colorspace;
2987 spin_unlock(&vino_drvdata->input_lock);
2990 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
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;
3019 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3027 static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3028 struct v4l2_crop *c)
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);
3041 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3049 static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3050 struct v4l2_crop *c)
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);
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);
3065 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3073 static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3074 struct v4l2_streamparm *sp)
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;
3091 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3099 static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3100 struct v4l2_streamparm *sp)
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);
3112 if ((cp->timeperframe.numerator == 0) ||
3113 (cp->timeperframe.denominator == 0)) {
3114 /* reset framerate */
3115 vino_set_default_framerate(vcs);
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
3125 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3133 static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
3134 struct v4l2_requestbuffers *rb)
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");
3147 if (vino_is_capturing(vcs)) {
3148 dprintk("busy, capturing\n");
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");
3158 vino_queue_free(&vcs->fb_queue);
3159 vino_queue_init(&vcs->fb_queue, &rb->count);
3162 vino_capture_stop(vcs);
3163 vino_queue_free(&vcs->fb_queue);
3167 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
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,
3181 b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3182 b->flags |= V4L2_BUF_FLAG_DONE;
3183 } else if (vino_queue_incoming_contains(&vcs->fb_queue,
3185 b->flags &= ~V4L2_BUF_FLAG_DONE;
3186 b->flags |= V4L2_BUF_FLAG_QUEUED;
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;
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));
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)
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",
3230 fb = vino_queue_get_buffer(&vcs->fb_queue,
3233 dprintk("vino_queue_get_buffer() failed");
3237 vino_v4l2_get_buffer_status(vcs, fb, b);
3240 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3248 static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
3249 struct v4l2_buffer *b)
3255 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3256 struct vino_framebuffer *fb;
3259 // TODO: check queue type
3260 if (b->memory != V4L2_MEMORY_MMAP) {
3261 dprintk("type not mmap\n");
3265 fb = vino_capture_enqueue(vcs, b->index);
3269 vino_v4l2_get_buffer_status(vcs, fb, b);
3271 if (vcs->streaming) {
3272 ret = vino_capture_next(vcs, 1);
3278 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3286 static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3287 struct v4l2_buffer *b,
3288 unsigned int nonblocking)
3294 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3295 struct vino_framebuffer *fb;
3296 unsigned int incoming, outgoing;
3299 // TODO: check queue type
3301 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3303 dprintk("vino_queue_get_incoming() failed\n");
3306 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3308 dprintk("vino_queue_get_outgoing() failed\n");
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");
3320 dprintk("non-blocking I/O was selected and "
3321 "there are no buffers to dequeue\n");
3325 err = vino_wait_for_frame(vcs);
3327 err = vino_wait_for_frame(vcs);
3330 vino_capture_failed(vcs);
3336 fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3338 dprintk("vino_queue_remove() failed\n");
3342 err = vino_check_buffer(vcs, fb);
3346 vino_v4l2_get_buffer_status(vcs, fb, b);
3349 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3357 static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
3359 unsigned int incoming;
3367 // TODO: check queue type
3369 if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3370 dprintk("no buffers allocated\n");
3374 ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3376 dprintk("vino_queue_get_incoming() failed\n");
3383 ret = vino_capture_next(vcs, 1);
3387 dprintk("couldn't start capture\n");
3395 static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3400 if (!vcs->streaming)
3403 vino_capture_stop(vcs);
3409 static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3410 struct v4l2_queryctrl *queryctrl)
3415 spin_lock(&vino_drvdata->input_lock);
3417 switch (vcs->input) {
3419 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3420 if (vino_indycam_v4l2_controls[i].id ==
3423 &vino_indycam_v4l2_controls[i],
3424 sizeof(struct v4l2_queryctrl));
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 ==
3437 &vino_saa7191_v4l2_controls[i],
3438 sizeof(struct v4l2_queryctrl));
3450 spin_unlock(&vino_drvdata->input_lock);
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;
3462 spin_lock(&vino_drvdata->input_lock);
3464 switch (vcs->input) {
3466 i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS,
3469 switch(control->id) {
3470 case V4L2_CID_AUTOGAIN:
3471 control->value = indycam_ctrl.agc;
3473 case V4L2_CID_AUTO_WHITE_BALANCE:
3474 control->value = indycam_ctrl.awb;
3477 control->value = indycam_ctrl.gain;
3479 case V4L2_CID_PRIVATE_BASE:
3480 control->value = indycam_ctrl.red_saturation;
3482 case V4L2_CID_PRIVATE_BASE + 1:
3483 control->value = indycam_ctrl.blue_saturation;
3485 case V4L2_CID_RED_BALANCE:
3486 control->value = indycam_ctrl.red_balance;
3488 case V4L2_CID_BLUE_BALANCE:
3489 control->value = indycam_ctrl.blue_balance;
3491 case V4L2_CID_EXPOSURE:
3492 control->value = indycam_ctrl.shutter;
3494 case V4L2_CID_GAMMA:
3495 control->value = indycam_ctrl.gamma;
3501 case VINO_INPUT_COMPOSITE:
3502 case VINO_INPUT_SVIDEO:
3503 i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS,
3506 switch(control->id) {
3508 control->value = saa7191_ctrl.hue;
3510 case V4L2_CID_PRIVATE_BASE:
3511 control->value = saa7191_ctrl.vtrc;
3521 spin_unlock(&vino_drvdata->input_lock);
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;
3534 spin_lock(&vino_drvdata->input_lock);
3536 switch (vcs->input) {
3538 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3539 if (vino_indycam_v4l2_controls[i].id ==
3541 if ((control->value >=
3542 vino_indycam_v4l2_controls[i].minimum)
3543 && (control->value <=
3544 vino_indycam_v4l2_controls[i].
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;
3571 case V4L2_CID_AUTO_WHITE_BALANCE:
3572 indycam_ctrl.awb = control->value;
3575 indycam_ctrl.gain = control->value;
3577 case V4L2_CID_PRIVATE_BASE:
3578 indycam_ctrl.red_saturation = control->value;
3580 case V4L2_CID_PRIVATE_BASE + 1:
3581 indycam_ctrl.blue_saturation = control->value;
3583 case V4L2_CID_RED_BALANCE:
3584 indycam_ctrl.red_balance = control->value;
3586 case V4L2_CID_BLUE_BALANCE:
3587 indycam_ctrl.blue_balance = control->value;
3589 case V4L2_CID_EXPOSURE:
3590 indycam_ctrl.shutter = control->value;
3592 case V4L2_CID_GAMMA:
3593 indycam_ctrl.gamma = control->value;
3600 i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS,
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 ==
3608 if ((control->value >=
3609 vino_saa7191_v4l2_controls[i].minimum)
3610 && (control->value <=
3611 vino_saa7191_v4l2_controls[i].
3624 saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED;
3625 saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED;
3627 switch(control->id) {
3629 saa7191_ctrl.hue = control->value;
3631 case V4L2_CID_PRIVATE_BASE:
3632 saa7191_ctrl.vtrc = control->value;
3639 i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS,
3647 spin_unlock(&vino_drvdata->input_lock);
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);
3659 dprintk("open(): channel = %c\n",
3660 (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3665 dprintk("open(): driver busy\n");
3670 ret = vino_acquire_input(vcs);
3672 dprintk("open(): vino_acquire_input() failed\n");
3681 dprintk("open(): %s!\n", ret ? "failed" : "complete");
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");
3697 vino_release_input(vcs);
3699 /* stop DMA and free buffers */
3700 vino_capture_stop(vcs);
3701 vino_queue_free(&vcs->fb_queue);
3709 static void vino_vm_open(struct vm_area_struct *vma)
3711 struct vino_framebuffer *fb = vma->vm_private_data;
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;
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;
3743 dprintk("mmap():\n");
3745 // TODO: reject mmap if already mapped
3747 if (down_interruptible(&vcs->sem))
3755 // TODO: check queue type
3757 if (!(vma->vm_flags & VM_WRITE)) {
3758 dprintk("mmap(): app bug: PROT_WRITE please\n");
3762 if (!(vma->vm_flags & VM_SHARED)) {
3763 dprintk("mmap(): app bug: MAP_SHARED please\n");
3768 /* find the correct buffer using offset */
3769 length = vino_queue_get_length(&vcs->fb_queue);
3771 dprintk("mmap(): queue not initialized\n");
3776 for (i = 0; i < length; i++) {
3777 fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3779 dprintk("mmap(): vino_queue_get_buffer() failed\n");
3784 if (fb->offset == offset)
3788 dprintk("mmap(): invalid offset = %lu\n", offset);
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);
3802 for (i = 0; i < fb->desc_table.page_count; i++) {
3804 virt_to_phys((void *)fb->desc_table.virtual[i]) >>
3807 if (size < PAGE_SIZE)
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");
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;
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;
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");
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");
3865 dprintk("poll(): data %savailable\n",
3866 (outgoing > 0) ? "" : "not ");
3868 ret = POLLIN | POLLRDNORM;
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)) {
3884 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
3887 dprintk("ioctl(): V4L2 %s (0x%08x)\n",
3888 v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
3891 dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
3895 /* TODO: V4L1 interface (use compatibility layer?) */
3896 /* V4L2 interface */
3897 case VIDIOC_QUERYCAP: {
3898 vino_v4l2_querycap(arg);
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);
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);
3974 return -ENOIOCTLCMD;
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);
3987 if (down_interruptible(&vcs->sem))
3990 ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
3997 /* Initialization and cleanup */
4000 static int vino_init_stage = 0;
4002 static struct file_operations vino_fops = {
4003 .owner = THIS_MODULE,
4005 .release = vino_close,
4006 .ioctl = vino_ioctl,
4009 .llseek = no_llseek,
4012 static struct video_device v4l_device_template = {
4014 //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
4015 // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
4016 .hardware = VID_HARDWARE_VINO,
4021 static void vino_module_cleanup(int stage)
4025 video_unregister_device(vino_drvdata->b.v4l_device);
4026 vino_drvdata->b.v4l_device = NULL;
4028 video_unregister_device(vino_drvdata->a.v4l_device);
4029 vino_drvdata->a.v4l_device = NULL;
4033 free_irq(SGI_VINO_IRQ, NULL);
4035 if (vino_drvdata->b.v4l_device) {
4036 video_device_release(vino_drvdata->b.v4l_device);
4037 vino_drvdata->b.v4l_device = NULL;
4040 if (vino_drvdata->a.v4l_device) {
4041 video_device_release(vino_drvdata->a.v4l_device);
4042 vino_drvdata->a.v4l_device = NULL;
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);
4055 free_page(vino_drvdata->dummy_page);
4057 kfree(vino_drvdata);
4063 dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
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");
4077 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
4078 printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
4082 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
4084 printk(KERN_ERR "VINO: ioremap() failed\n");
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);
4095 if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
4096 printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
4098 vino_module_cleanup(vino_init_stage);
4102 printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n",
4103 VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id));
4108 static int vino_init(void)
4110 dma_addr_t dma_dummy_address;
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);
4119 memset(vino_drvdata, 0, sizeof(struct vino_settings));
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);
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);
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 */
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;
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;
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);
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);
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);
4204 static int __init vino_module_init(void)
4208 printk(KERN_INFO "SGI VINO driver version %s\n",
4209 VINO_MODULE_VERSION);
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);
4229 ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4230 vino_v4l_device_name_b);
4234 /* initialize hardware and register V4L devices */
4236 ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4237 vino_driver_description, NULL);
4239 printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
4241 vino_module_cleanup(vino_init_stage);
4246 ret = vino_i2c_add_bus();
4248 printk(KERN_ERR "VINO I2C bus registration failed\n");
4249 vino_module_cleanup(vino_init_stage);
4254 ret = video_register_device(vino_drvdata->a.v4l_device,
4255 VFL_TYPE_GRABBER, -1);
4257 printk(KERN_ERR "VINO channel A Video4Linux-device "
4258 "registration failed\n");
4259 vino_module_cleanup(vino_init_stage);
4264 ret = video_register_device(vino_drvdata->b.v4l_device,
4265 VFL_TYPE_GRABBER, -1);
4267 printk(KERN_ERR "VINO channel B Video4Linux-device "
4268 "registration failed\n");
4269 vino_module_cleanup(vino_init_stage);
4274 #if defined(CONFIG_KMOD) && defined(MODULE)
4275 request_module("saa7191");
4276 request_module("indycam");
4279 dprintk("init complete!\n");
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);