Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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