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
);