1/* 2 * Driver for the VINO (Video In No Out) system found in SGI Indys. 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License version 2 as published by the Free Software Foundation. 6 * 7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi> 8 * 9 * Based on the previous version of the driver for 2.4 kernels by: 10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> 11 */ 12 13/* 14 * TODO: 15 * - remove "mark pages reserved-hacks" from memory allocation code 16 * and implement nopage() 17 * - check decimation, calculating and reporting image size when 18 * using decimation 19 * - implement read(), user mode buffers and overlay (?) 20 */ 21 22#include <linux/init.h> 23#include <linux/module.h> 24#include <linux/delay.h> 25#include <linux/dma-mapping.h> 26#include <linux/errno.h> 27#include <linux/fs.h> 28#include <linux/interrupt.h> 29#include <linux/kernel.h> 30#include <linux/mm.h> 31#include <linux/moduleparam.h> 32#include <linux/time.h> 33#include <linux/version.h> 34 35#ifdef CONFIG_KMOD 36#include <linux/kmod.h> 37#endif 38 39#include <linux/i2c.h> 40#include <linux/i2c-algo-sgi.h> 41 42#include <linux/videodev.h> 43#include <media/v4l2-common.h> 44#include <linux/video_decoder.h> 45#include <linux/mutex.h> 46 47#include <asm/paccess.h> 48#include <asm/io.h> 49#include <asm/sgi/ip22.h> 50#include <asm/sgi/mc.h> 51 52#include "vino.h" 53#include "saa7191.h" 54#include "indycam.h" 55 56/* Uncomment the following line to get lots and lots of (mostly useless) 57 * debug info. 58 * Note that the debug output also slows down the driver significantly */ 59// #define VINO_DEBUG 60// #define VINO_DEBUG_INT 61 62#define VINO_MODULE_VERSION "0.0.5" 63#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5) 64 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, 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_del_adapter(&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 918static void vino_sync_buffer(struct vino_framebuffer *fb) 919{ 920 int i; 921 922 dprintk("vino_sync_buffer():\n"); 923 924 for (i = 0; i < fb->desc_table.page_count; i++) 925 dma_sync_single(NULL, 926 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], 927 PAGE_SIZE, DMA_FROM_DEVICE); 928} 929 930/* Framebuffer fifo functions (need to be locked externally) */ 931 932static inline void vino_fifo_init(struct vino_framebuffer_fifo *f, 933 unsigned int length) 934{ 935 f->length = 0; 936 f->used = 0; 937 f->head = 0; 938 f->tail = 0; 939 940 if (length > VINO_FRAMEBUFFER_COUNT_MAX) 941 length = VINO_FRAMEBUFFER_COUNT_MAX; 942 943 f->length = length; 944} 945 946/* returns true/false */ 947static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f, 948 unsigned int id) 949{ 950 unsigned int i; 951 952 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) { 953 if (f->data[i] == id) 954 return 1; 955 } 956 957 return 0; 958} 959 960 961static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f) 962{ 963 return f->used; 964} 965 966static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id) 967{ 968 if (id >= f->length) { 969 return VINO_QUEUE_ERROR; 970 } 971 972 if (vino_fifo_has_id(f, id)) { 973 return VINO_QUEUE_ERROR; 974 } 975 976 if (f->used < f->length) { 977 f->data[f->tail] = id; 978 f->tail = (f->tail + 1) % f->length; 979 f->used++; 980 } else { 981 return VINO_QUEUE_ERROR; 982 } 983 984 return 0; 985} 986 987static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id) 988{ 989 if (f->used > 0) { 990 *id = f->data[f->head]; 991 } else { 992 return VINO_QUEUE_ERROR; 993 } 994 995 return 0; 996} 997 998static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id) 999{ 1000 if (f->used > 0) { 1001 *id = f->data[f->head]; 1002 f->head = (f->head + 1) % f->length; 1003 f->used--; 1004 } else { 1005 return VINO_QUEUE_ERROR; 1006 } 1007 1008 return 0; 1009} 1010 1011/* Framebuffer queue functions */ 1012 1013/* execute with queue_lock locked */ 1014static void vino_queue_free_with_count(struct vino_framebuffer_queue *q, 1015 unsigned int length) 1016{ 1017 unsigned int i; 1018 1019 q->length = 0; 1020 memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo)); 1021 memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo)); 1022 for (i = 0; i < length; i++) { 1023 dprintk("vino_queue_free_with_count(): freeing buffer %d\n", 1024 i); 1025 vino_free_buffer(q->buffer[i]); 1026 kfree(q->buffer[i]); 1027 } 1028 1029 q->type = VINO_MEMORY_NONE; 1030 q->magic = 0; 1031} 1032 1033static void vino_queue_free(struct vino_framebuffer_queue *q) 1034{ 1035 dprintk("vino_queue_free():\n"); 1036 1037 if (q->magic != VINO_QUEUE_MAGIC) 1038 return; 1039 if (q->type != VINO_MEMORY_MMAP) 1040 return; 1041 1042 mutex_lock(&q->queue_mutex); 1043 1044 vino_queue_free_with_count(q, q->length); 1045 1046 mutex_unlock(&q->queue_mutex); 1047} 1048 1049static int vino_queue_init(struct vino_framebuffer_queue *q, 1050 unsigned int *length) 1051{ 1052 unsigned int i; 1053 int ret = 0; 1054 1055 dprintk("vino_queue_init(): length = %d\n", *length); 1056 1057 if (q->magic == VINO_QUEUE_MAGIC) { 1058 dprintk("vino_queue_init(): queue already initialized!\n"); 1059 return -EINVAL; 1060 } 1061 1062 if (q->type != VINO_MEMORY_NONE) { 1063 dprintk("vino_queue_init(): queue already initialized!\n"); 1064 return -EINVAL; 1065 } 1066 1067 if (*length < 1) 1068 return -EINVAL; 1069 1070 mutex_lock(&q->queue_mutex); 1071 1072 if (*length > VINO_FRAMEBUFFER_COUNT_MAX) 1073 *length = VINO_FRAMEBUFFER_COUNT_MAX; 1074 1075 q->length = 0; 1076 1077 for (i = 0; i < *length; i++) { 1078 dprintk("vino_queue_init(): allocating buffer %d\n", i); 1079 q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer), 1080 GFP_KERNEL); 1081 if (!q->buffer[i]) { 1082 dprintk("vino_queue_init(): kmalloc() failed\n"); 1083 ret = -ENOMEM; 1084 break; 1085 } 1086 1087 ret = vino_allocate_buffer(q->buffer[i], 1088 VINO_FRAMEBUFFER_SIZE); 1089 if (ret) { 1090 kfree(q->buffer[i]); 1091 dprintk("vino_queue_init(): " 1092 "vino_allocate_buffer() failed\n"); 1093 break; 1094 } 1095 1096 q->buffer[i]->id = i; 1097 if (i > 0) { 1098 q->buffer[i]->offset = q->buffer[i - 1]->offset + 1099 q->buffer[i - 1]->size; 1100 } else { 1101 q->buffer[i]->offset = 0; 1102 } 1103 1104 spin_lock_init(&q->buffer[i]->state_lock); 1105 1106 dprintk("vino_queue_init(): buffer = %d, offset = %d, " 1107 "size = %d\n", i, q->buffer[i]->offset, 1108 q->buffer[i]->size); 1109 } 1110 1111 if (ret) { 1112 vino_queue_free_with_count(q, i); 1113 *length = 0; 1114 } else { 1115 q->length = *length; 1116 vino_fifo_init(&q->in, q->length); 1117 vino_fifo_init(&q->out, q->length); 1118 q->type = VINO_MEMORY_MMAP; 1119 q->magic = VINO_QUEUE_MAGIC; 1120 } 1121 1122 mutex_unlock(&q->queue_mutex); 1123 1124 return ret; 1125} 1126 1127static struct vino_framebuffer *vino_queue_add(struct 1128 vino_framebuffer_queue *q, 1129 unsigned int id) 1130{ 1131 struct vino_framebuffer *ret = NULL; 1132 unsigned int total; 1133 unsigned long flags; 1134 1135 dprintk("vino_queue_add(): id = %d\n", id); 1136 1137 if (q->magic != VINO_QUEUE_MAGIC) { 1138 return ret; 1139 } 1140 1141 spin_lock_irqsave(&q->queue_lock, flags); 1142 1143 if (q->length == 0) 1144 goto out; 1145 1146 if (id >= q->length) 1147 goto out; 1148 1149 /* not needed?: if (vino_fifo_full(&q->out)) { 1150 goto out; 1151 }*/ 1152 /* check that outgoing queue isn't already full 1153 * (or that it won't become full) */ 1154 total = vino_fifo_get_used(&q->in) + 1155 vino_fifo_get_used(&q->out); 1156 if (total >= q->length) 1157 goto out; 1158 1159 if (vino_fifo_enqueue(&q->in, id)) 1160 goto out; 1161 1162 ret = q->buffer[id]; 1163 1164out: 1165 spin_unlock_irqrestore(&q->queue_lock, flags); 1166 1167 return ret; 1168} 1169 1170static struct vino_framebuffer *vino_queue_transfer(struct 1171 vino_framebuffer_queue *q) 1172{ 1173 struct vino_framebuffer *ret = NULL; 1174 struct vino_framebuffer *fb; 1175 int id; 1176 unsigned long flags; 1177 1178 dprintk("vino_queue_transfer():\n"); 1179 1180 if (q->magic != VINO_QUEUE_MAGIC) { 1181 return ret; 1182 } 1183 1184 spin_lock_irqsave(&q->queue_lock, flags); 1185 1186 if (q->length == 0) 1187 goto out; 1188 1189 // now this actually removes an entry from the incoming queue 1190 if (vino_fifo_dequeue(&q->in, &id)) { 1191 goto out; 1192 } 1193 1194 dprintk("vino_queue_transfer(): id = %d\n", id); 1195 fb = q->buffer[id]; 1196 1197 // we have already checked that the outgoing queue is not full, but... 1198 if (vino_fifo_enqueue(&q->out, id)) { 1199 printk(KERN_ERR "vino_queue_transfer(): " 1200 "outgoing queue is full, this shouldn't happen!\n"); 1201 goto out; 1202 } 1203 1204 ret = fb; 1205out: 1206 spin_unlock_irqrestore(&q->queue_lock, flags); 1207 1208 return ret; 1209} 1210 1211/* returns true/false */ 1212static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q, 1213 unsigned int id) 1214{ 1215 int ret = 0; 1216 unsigned long flags; 1217 1218 if (q->magic != VINO_QUEUE_MAGIC) { 1219 return ret; 1220 } 1221 1222 spin_lock_irqsave(&q->queue_lock, flags); 1223 1224 if (q->length == 0) 1225 goto out; 1226 1227 ret = vino_fifo_has_id(&q->in, id); 1228 1229out: 1230 spin_unlock_irqrestore(&q->queue_lock, flags); 1231 1232 return ret; 1233} 1234 1235/* returns true/false */ 1236static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q, 1237 unsigned int id) 1238{ 1239 int ret = 0; 1240 unsigned long flags; 1241 1242 if (q->magic != VINO_QUEUE_MAGIC) { 1243 return ret; 1244 } 1245 1246 spin_lock_irqsave(&q->queue_lock, flags); 1247 1248 if (q->length == 0) 1249 goto out; 1250 1251 ret = vino_fifo_has_id(&q->out, id); 1252 1253out: 1254 spin_unlock_irqrestore(&q->queue_lock, flags); 1255 1256 return ret; 1257} 1258 1259static int vino_queue_get_incoming(struct vino_framebuffer_queue *q, 1260 unsigned int *used) 1261{ 1262 int ret = 0; 1263 unsigned long flags; 1264 1265 if (q->magic != VINO_QUEUE_MAGIC) { 1266 return VINO_QUEUE_ERROR; 1267 } 1268 1269 spin_lock_irqsave(&q->queue_lock, flags); 1270 1271 if (q->length == 0) { 1272 ret = VINO_QUEUE_ERROR; 1273 goto out; 1274 } 1275 1276 *used = vino_fifo_get_used(&q->in); 1277 1278out: 1279 spin_unlock_irqrestore(&q->queue_lock, flags); 1280 1281 return ret; 1282} 1283 1284static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q, 1285 unsigned int *used) 1286{ 1287 int ret = 0; 1288 unsigned long flags; 1289 1290 if (q->magic != VINO_QUEUE_MAGIC) { 1291 return VINO_QUEUE_ERROR; 1292 } 1293 1294 spin_lock_irqsave(&q->queue_lock, flags); 1295 1296 if (q->length == 0) { 1297 ret = VINO_QUEUE_ERROR; 1298 goto out; 1299 } 1300 1301 *used = vino_fifo_get_used(&q->out); 1302 1303out: 1304 spin_unlock_irqrestore(&q->queue_lock, flags); 1305 1306 return ret; 1307} 1308 1309 1310static struct vino_framebuffer *vino_queue_peek(struct 1311 vino_framebuffer_queue *q, 1312 unsigned int *id) 1313{ 1314 struct vino_framebuffer *ret = NULL; 1315 unsigned long flags; 1316 1317 if (q->magic != VINO_QUEUE_MAGIC) { 1318 return ret; 1319 } 1320 1321 spin_lock_irqsave(&q->queue_lock, flags); 1322 1323 if (q->length == 0) 1324 goto out; 1325 1326 if (vino_fifo_peek(&q->in, id)) { 1327 goto out; 1328 } 1329 1330 ret = q->buffer[*id]; 1331out: 1332 spin_unlock_irqrestore(&q->queue_lock, flags); 1333 1334 return ret; 1335} 1336 1337static struct vino_framebuffer *vino_queue_remove(struct 1338 vino_framebuffer_queue *q, 1339 unsigned int *id) 1340{ 1341 struct vino_framebuffer *ret = NULL; 1342 unsigned long flags; 1343 dprintk("vino_queue_remove():\n"); 1344 1345 if (q->magic != VINO_QUEUE_MAGIC) { 1346 return ret; 1347 } 1348 1349 spin_lock_irqsave(&q->queue_lock, flags); 1350 1351 if (q->length == 0) 1352 goto out; 1353 1354 if (vino_fifo_dequeue(&q->out, id)) { 1355 goto out; 1356 } 1357 1358 dprintk("vino_queue_remove(): id = %d\n", *id); 1359 ret = q->buffer[*id]; 1360out: 1361 spin_unlock_irqrestore(&q->queue_lock, flags); 1362 1363 return ret; 1364} 1365 1366static struct 1367vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q, 1368 unsigned int id) 1369{ 1370 struct vino_framebuffer *ret = NULL; 1371 unsigned long flags; 1372 1373 if (q->magic != VINO_QUEUE_MAGIC) { 1374 return ret; 1375 } 1376 1377 spin_lock_irqsave(&q->queue_lock, flags); 1378 1379 if (q->length == 0) 1380 goto out; 1381 1382 if (id >= q->length) 1383 goto out; 1384 1385 ret = q->buffer[id]; 1386 out: 1387 spin_unlock_irqrestore(&q->queue_lock, flags); 1388 1389 return ret; 1390} 1391 1392static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q) 1393{ 1394 unsigned int length = 0; 1395 unsigned long flags; 1396 1397 if (q->magic != VINO_QUEUE_MAGIC) { 1398 return length; 1399 } 1400 1401 spin_lock_irqsave(&q->queue_lock, flags); 1402 length = q->length; 1403 spin_unlock_irqrestore(&q->queue_lock, flags); 1404 1405 return length; 1406} 1407 1408static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q) 1409{ 1410 unsigned int i; 1411 int ret = 0; 1412 unsigned long flags; 1413 1414 if (q->magic != VINO_QUEUE_MAGIC) { 1415 return ret; 1416 } 1417 1418 spin_lock_irqsave(&q->queue_lock, flags); 1419 for (i = 0; i < q->length; i++) { 1420 if (q->buffer[i]->map_count > 0) { 1421 ret = 1; 1422 break; 1423 } 1424 } 1425 spin_unlock_irqrestore(&q->queue_lock, flags); 1426 1427 return ret; 1428} 1429 1430/* VINO functions */ 1431 1432/* execute with input_lock locked */ 1433static void vino_update_line_size(struct vino_channel_settings *vcs) 1434{ 1435 unsigned int w = vcs->clipping.right - vcs->clipping.left; 1436 unsigned int d = vcs->decimation; 1437 unsigned int bpp = vino_data_formats[vcs->data_format].bpp; 1438 unsigned int lsize; 1439 1440 dprintk("update_line_size(): before: w = %d, d = %d, " 1441 "line_size = %d\n", w, d, vcs->line_size); 1442 1443 /* line size must be multiple of 8 bytes */ 1444 lsize = (bpp * (w / d)) & ~7; 1445 w = (lsize / bpp) * d; 1446 1447 vcs->clipping.right = vcs->clipping.left + w; 1448 vcs->line_size = lsize; 1449 1450 dprintk("update_line_size(): after: w = %d, d = %d, " 1451 "line_size = %d\n", w, d, vcs->line_size); 1452} 1453 1454/* execute with input_lock locked */ 1455static void vino_set_clipping(struct vino_channel_settings *vcs, 1456 unsigned int x, unsigned int y, 1457 unsigned int w, unsigned int h) 1458{ 1459 unsigned int maxwidth, maxheight; 1460 unsigned int d; 1461 1462 maxwidth = vino_data_norms[vcs->data_norm].width; 1463 maxheight = vino_data_norms[vcs->data_norm].height; 1464 d = vcs->decimation; 1465 1466 y &= ~1; /* odd/even fields */ 1467 1468 if (x > maxwidth) { 1469 x = 0; 1470 } 1471 if (y > maxheight) { 1472 y = 0; 1473 } 1474 1475 if (((w / d) < VINO_MIN_WIDTH) 1476 || ((h / d) < VINO_MIN_HEIGHT)) { 1477 w = VINO_MIN_WIDTH * d; 1478 h = VINO_MIN_HEIGHT * d; 1479 } 1480 1481 if ((x + w) > maxwidth) { 1482 w = maxwidth - x; 1483 if ((w / d) < VINO_MIN_WIDTH) 1484 x = maxwidth - VINO_MIN_WIDTH * d; 1485 } 1486 if ((y + h) > maxheight) { 1487 h = maxheight - y; 1488 if ((h / d) < VINO_MIN_HEIGHT) 1489 y = maxheight - VINO_MIN_HEIGHT * d; 1490 } 1491 1492 vcs->clipping.left = x; 1493 vcs->clipping.top = y; 1494 vcs->clipping.right = x + w; 1495 vcs->clipping.bottom = y + h; 1496 1497 vino_update_line_size(vcs); 1498 1499 dprintk("clipping %d, %d, %d, %d / %d - %d\n", 1500 vcs->clipping.left, vcs->clipping.top, vcs->clipping.right, 1501 vcs->clipping.bottom, vcs->decimation, vcs->line_size); 1502} 1503 1504/* execute with input_lock locked */ 1505static inline void vino_set_default_clipping(struct vino_channel_settings *vcs) 1506{ 1507 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width, 1508 vino_data_norms[vcs->data_norm].height); 1509} 1510 1511/* execute with input_lock locked */ 1512static void vino_set_scaling(struct vino_channel_settings *vcs, 1513 unsigned int w, unsigned int h) 1514{ 1515 unsigned int x, y, curw, curh, d; 1516 1517 x = vcs->clipping.left; 1518 y = vcs->clipping.top; 1519 curw = vcs->clipping.right - vcs->clipping.left; 1520 curh = vcs->clipping.bottom - vcs->clipping.top; 1521 1522 d = max(curw / w, curh / h); 1523 1524 dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n", 1525 w, h, curw, curh, d); 1526 1527 if (d < 1) { 1528 d = 1; 1529 } else if (d > 8) { 1530 d = 8; 1531 } 1532 1533 vcs->decimation = d; 1534 vino_set_clipping(vcs, x, y, w * d, h * d); 1535 1536 dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left, 1537 vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom, 1538 vcs->decimation, vcs->line_size); 1539} 1540 1541/* execute with input_lock locked */ 1542static inline void vino_set_default_scaling(struct vino_channel_settings *vcs) 1543{ 1544 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left, 1545 vcs->clipping.bottom - vcs->clipping.top); 1546} 1547 1548/* execute with input_lock locked */ 1549static void vino_set_framerate(struct vino_channel_settings *vcs, 1550 unsigned int fps) 1551{ 1552 unsigned int mask; 1553 1554 switch (vcs->data_norm) { 1555 case VINO_DATA_NORM_NTSC: 1556 case VINO_DATA_NORM_D1: 1557 fps = (unsigned int)(fps / 6) * 6; 1558 1559 if (fps < vino_data_norms[vcs->data_norm].fps_min) 1560 fps = vino_data_norms[vcs->data_norm].fps_min; 1561 if (fps > vino_data_norms[vcs->data_norm].fps_max) 1562 fps = vino_data_norms[vcs->data_norm].fps_max; 1563 1564 switch (fps) { 1565 case 6: 1566 mask = 0x003; 1567 break; 1568 case 12: 1569 mask = 0x0c3; 1570 break; 1571 case 18: 1572 mask = 0x333; 1573 break; 1574 case 24: 1575 mask = 0x3ff; 1576 break; 1577 case 30: 1578 mask = 0xfff; 1579 break; 1580 default: 1581 mask = VINO_FRAMERT_FULL; 1582 } 1583 vcs->framert_reg = VINO_FRAMERT_RT(mask); 1584 break; 1585 case VINO_DATA_NORM_PAL: 1586 case VINO_DATA_NORM_SECAM: 1587 fps = (unsigned int)(fps / 5) * 5; 1588 1589 if (fps < vino_data_norms[vcs->data_norm].fps_min) 1590 fps = vino_data_norms[vcs->data_norm].fps_min; 1591 if (fps > vino_data_norms[vcs->data_norm].fps_max) 1592 fps = vino_data_norms[vcs->data_norm].fps_max; 1593 1594 switch (fps) { 1595 case 5: 1596 mask = 0x003; 1597 break; 1598 case 10: 1599 mask = 0x0c3; 1600 break; 1601 case 15: 1602 mask = 0x333; 1603 break; 1604 case 20: 1605 mask = 0x0ff; 1606 break; 1607 case 25: 1608 mask = 0x3ff; 1609 break; 1610 default: 1611 mask = VINO_FRAMERT_FULL; 1612 } 1613 vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL; 1614 break; 1615 } 1616 1617 vcs->fps = fps; 1618} 1619 1620/* execute with input_lock locked */ 1621static inline void vino_set_default_framerate(struct 1622 vino_channel_settings *vcs) 1623{ 1624 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max); 1625} 1626 1627/* 1628 * Prepare VINO for DMA transfer... 1629 * (execute only with vino_lock and input_lock locked) 1630 */ 1631static int vino_dma_setup(struct vino_channel_settings *vcs, 1632 struct vino_framebuffer *fb) 1633{ 1634 u32 ctrl, intr; 1635 struct sgi_vino_channel *ch; 1636 const struct vino_data_norm *norm; 1637 1638 dprintk("vino_dma_setup():\n"); 1639 1640 vcs->field = 0; 1641 fb->frame_counter = 0; 1642 1643 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b; 1644 norm = &vino_data_norms[vcs->data_norm]; 1645 1646 ch->page_index = 0; 1647 ch->line_count = 0; 1648 1649 /* VINO line size register is set 8 bytes less than actual */ 1650 ch->line_size = vcs->line_size - 8; 1651 1652 /* let VINO know where to transfer data */ 1653 ch->start_desc_tbl = fb->desc_table.dma; 1654 ch->next_4_desc = fb->desc_table.dma; 1655 1656 /* give vino time to fetch the first four descriptors, 5 usec 1657 * should be more than enough time */ 1658 udelay(VINO_DESC_FETCH_DELAY); 1659 1660 dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n", 1661 ch->start_desc_tbl, ch->next_4_desc); 1662 1663 /* set the alpha register */ 1664 ch->alpha = vcs->alpha; 1665 1666 /* set clipping registers */ 1667 ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) | 1668 VINO_CLIP_EVEN(norm->even.top + 1669 vcs->clipping.top / 2) | 1670 VINO_CLIP_X(vcs->clipping.left); 1671 ch->clip_end = VINO_CLIP_ODD(norm->odd.top + 1672 vcs->clipping.bottom / 2 - 1) | 1673 VINO_CLIP_EVEN(norm->even.top + 1674 vcs->clipping.bottom / 2 - 1) | 1675 VINO_CLIP_X(vcs->clipping.right); 1676 1677 /* set the size of actual content in the buffer (DECIMATION !) */ 1678 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) / 1679 vcs->decimation) * 1680 ((vcs->clipping.bottom - vcs->clipping.top) / 1681 vcs->decimation) * 1682 vino_data_formats[vcs->data_format].bpp; 1683 1684 ch->frame_rate = vcs->framert_reg; 1685 1686 ctrl = vino->control; 1687 intr = vino->intr_status; 1688 1689 if (vcs->channel == VINO_CHANNEL_A) { 1690 /* All interrupt conditions for this channel was cleared 1691 * so clear the interrupt status register and enable 1692 * interrupts */ 1693 intr &= ~VINO_INTSTAT_A; 1694 ctrl |= VINO_CTRL_A_INT; 1695 1696 /* enable synchronization */ 1697 ctrl |= VINO_CTRL_A_SYNC_ENBL; 1698 1699 /* enable frame assembly */ 1700 ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL; 1701 1702 /* set decimation used */ 1703 if (vcs->decimation < 2) 1704 ctrl &= ~VINO_CTRL_A_DEC_ENBL; 1705 else { 1706 ctrl |= VINO_CTRL_A_DEC_ENBL; 1707 ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK; 1708 ctrl |= (vcs->decimation - 1) << 1709 VINO_CTRL_A_DEC_SCALE_SHIFT; 1710 } 1711 1712 /* select input interface */ 1713 if (vcs->input == VINO_INPUT_D1) 1714 ctrl |= VINO_CTRL_A_SELECT; 1715 else 1716 ctrl &= ~VINO_CTRL_A_SELECT; 1717 1718 /* palette */ 1719 ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB | 1720 VINO_CTRL_A_DITHER); 1721 } else { 1722 intr &= ~VINO_INTSTAT_B; 1723 ctrl |= VINO_CTRL_B_INT; 1724 1725 ctrl |= VINO_CTRL_B_SYNC_ENBL; 1726 ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL; 1727 1728 if (vcs->decimation < 2) 1729 ctrl &= ~VINO_CTRL_B_DEC_ENBL; 1730 else { 1731 ctrl |= VINO_CTRL_B_DEC_ENBL; 1732 ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK; 1733 ctrl |= (vcs->decimation - 1) << 1734 VINO_CTRL_B_DEC_SCALE_SHIFT; 1735 1736 } 1737 if (vcs->input == VINO_INPUT_D1) 1738 ctrl |= VINO_CTRL_B_SELECT; 1739 else 1740 ctrl &= ~VINO_CTRL_B_SELECT; 1741 1742 ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB | 1743 VINO_CTRL_B_DITHER); 1744 } 1745 1746 /* set palette */ 1747 fb->data_format = vcs->data_format; 1748 1749 switch (vcs->data_format) { 1750 case VINO_DATA_FMT_GREY: 1751 ctrl |= (vcs->channel == VINO_CHANNEL_A) ? 1752 VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY; 1753 break; 1754 case VINO_DATA_FMT_RGB32: 1755 ctrl |= (vcs->channel == VINO_CHANNEL_A) ? 1756 VINO_CTRL_A_RGB : VINO_CTRL_B_RGB; 1757 break; 1758 case VINO_DATA_FMT_YUV: 1759 /* nothing needs to be done */ 1760 break; 1761 case VINO_DATA_FMT_RGB332: 1762 ctrl |= (vcs->channel == VINO_CHANNEL_A) ? 1763 VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER : 1764 VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER; 1765 break; 1766 } 1767 1768 vino->intr_status = intr; 1769 vino->control = ctrl; 1770 1771 return 0; 1772} 1773 1774/* (execute only with vino_lock locked) */ 1775static inline void vino_dma_start(struct vino_channel_settings *vcs) 1776{ 1777 u32 ctrl = vino->control; 1778 1779 dprintk("vino_dma_start():\n"); 1780 ctrl |= (vcs->channel == VINO_CHANNEL_A) ? 1781 VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL; 1782 vino->control = ctrl; 1783} 1784 1785/* (execute only with vino_lock locked) */ 1786static inline void vino_dma_stop(struct vino_channel_settings *vcs) 1787{ 1788 u32 ctrl = vino->control; 1789 1790 ctrl &= (vcs->channel == VINO_CHANNEL_A) ? 1791 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL; 1792 ctrl &= (vcs->channel == VINO_CHANNEL_A) ? 1793 ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT; 1794 vino->control = ctrl; 1795 dprintk("vino_dma_stop():\n"); 1796} 1797 1798/* 1799 * Load dummy page to descriptor registers. This prevents generating of 1800 * spurious interrupts. (execute only with vino_lock locked) 1801 */ 1802static void vino_clear_interrupt(struct vino_channel_settings *vcs) 1803{ 1804 struct sgi_vino_channel *ch; 1805 1806 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b; 1807 1808 ch->page_index = 0; 1809 ch->line_count = 0; 1810 1811 ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma; 1812 ch->next_4_desc = vino_drvdata->dummy_desc_table.dma; 1813 1814 udelay(VINO_DESC_FETCH_DELAY); 1815 dprintk("channel %c clear interrupt condition\n", 1816 (vcs->channel == VINO_CHANNEL_A) ? 'A':'B'); 1817} 1818 1819static int vino_capture(struct vino_channel_settings *vcs, 1820 struct vino_framebuffer *fb) 1821{ 1822 int err = 0; 1823 unsigned long flags, flags2; 1824 1825 spin_lock_irqsave(&fb->state_lock, flags); 1826 1827 if (fb->state == VINO_FRAMEBUFFER_IN_USE) 1828 err = -EBUSY; 1829 fb->state = VINO_FRAMEBUFFER_IN_USE; 1830 1831 spin_unlock_irqrestore(&fb->state_lock, flags); 1832 1833 if (err) 1834 return err; 1835 1836 spin_lock_irqsave(&vino_drvdata->vino_lock, flags); 1837 spin_lock_irqsave(&vino_drvdata->input_lock, flags2); 1838 1839 vino_dma_setup(vcs, fb); 1840 vino_dma_start(vcs); 1841 1842 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2); 1843 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags); 1844 1845 return err; 1846} 1847 1848static 1849struct vino_framebuffer *vino_capture_enqueue(struct 1850 vino_channel_settings *vcs, 1851 unsigned int index) 1852{ 1853 struct vino_framebuffer *fb; 1854 unsigned long flags; 1855 1856 dprintk("vino_capture_enqueue():\n"); 1857 1858 spin_lock_irqsave(&vcs->capture_lock, flags); 1859 1860 fb = vino_queue_add(&vcs->fb_queue, index); 1861 if (fb == NULL) { 1862 dprintk("vino_capture_enqueue(): vino_queue_add() failed, " 1863 "queue full?\n"); 1864 goto out; 1865 } 1866out: 1867 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1868 1869 return fb; 1870} 1871 1872static int vino_capture_next(struct vino_channel_settings *vcs, int start) 1873{ 1874 struct vino_framebuffer *fb; 1875 unsigned int incoming, id; 1876 int err = 0; 1877 unsigned long flags; 1878 1879 dprintk("vino_capture_next():\n"); 1880 1881 spin_lock_irqsave(&vcs->capture_lock, flags); 1882 1883 if (start) { 1884 /* start capture only if capture isn't in progress already */ 1885 if (vcs->capturing) { 1886 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1887 return 0; 1888 } 1889 1890 } else { 1891 /* capture next frame: 1892 * stop capture if capturing is not set */ 1893 if (!vcs->capturing) { 1894 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1895 return 0; 1896 } 1897 } 1898 1899 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); 1900 if (err) { 1901 dprintk("vino_capture_next(): vino_queue_get_incoming() " 1902 "failed\n"); 1903 err = -EINVAL; 1904 goto out; 1905 } 1906 if (incoming == 0) { 1907 dprintk("vino_capture_next(): no buffers available\n"); 1908 goto out; 1909 } 1910 1911 fb = vino_queue_peek(&vcs->fb_queue, &id); 1912 if (fb == NULL) { 1913 dprintk("vino_capture_next(): vino_queue_peek() failed\n"); 1914 err = -EINVAL; 1915 goto out; 1916 } 1917 1918 if (start) { 1919 vcs->capturing = 1; 1920 } 1921 1922 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1923 1924 err = vino_capture(vcs, fb); 1925 1926 return err; 1927 1928out: 1929 vcs->capturing = 0; 1930 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1931 1932 return err; 1933} 1934 1935static inline int vino_is_capturing(struct vino_channel_settings *vcs) 1936{ 1937 int ret; 1938 unsigned long flags; 1939 1940 spin_lock_irqsave(&vcs->capture_lock, flags); 1941 1942 ret = vcs->capturing; 1943 1944 spin_unlock_irqrestore(&vcs->capture_lock, flags); 1945 1946 return ret; 1947} 1948 1949/* waits until a frame is captured */ 1950static int vino_wait_for_frame(struct vino_channel_settings *vcs) 1951{ 1952 wait_queue_t wait; 1953 int err = 0; 1954 1955 dprintk("vino_wait_for_frame():\n"); 1956 1957 init_waitqueue_entry(&wait, current); 1958 /* add ourselves into wait queue */ 1959 add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); 1960 /* and set current state */ 1961 set_current_state(TASK_INTERRUPTIBLE); 1962 1963 /* to ensure that schedule_timeout will return immediately 1964 * if VINO interrupt was triggred meanwhile */ 1965 schedule_timeout(HZ / 10); 1966 1967 if (signal_pending(current)) 1968 err = -EINTR; 1969 1970 remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); 1971 1972 dprintk("vino_wait_for_frame(): waiting for frame %s\n", 1973 err ? "failed" : "ok"); 1974 1975 return err; 1976} 1977 1978/* the function assumes that PAGE_SIZE % 4 == 0 */ 1979static void vino_convert_to_rgba(struct vino_framebuffer *fb) { 1980 unsigned char *pageptr; 1981 unsigned int page, i; 1982 unsigned char a; 1983 1984 for (page = 0; page < fb->desc_table.page_count; page++) { 1985 pageptr = (unsigned char *)fb->desc_table.virtual[page]; 1986 1987 for (i = 0; i < PAGE_SIZE; i += 4) { 1988 a = pageptr[0]; 1989 pageptr[0] = pageptr[3]; 1990 pageptr[1] = pageptr[2]; 1991 pageptr[2] = pageptr[1]; 1992 pageptr[3] = a; 1993 pageptr += 4; 1994 } 1995 } 1996} 1997 1998/* checks if the buffer is in correct state and syncs data */ 1999static int vino_check_buffer(struct vino_channel_settings *vcs, 2000 struct vino_framebuffer *fb) 2001{ 2002 int err = 0; 2003 unsigned long flags; 2004 2005 dprintk("vino_check_buffer():\n"); 2006 2007 spin_lock_irqsave(&fb->state_lock, flags); 2008 switch (fb->state) { 2009 case VINO_FRAMEBUFFER_IN_USE: 2010 err = -EIO; 2011 break; 2012 case VINO_FRAMEBUFFER_READY: 2013 vino_sync_buffer(fb); 2014 fb->state = VINO_FRAMEBUFFER_UNUSED; 2015 break; 2016 default: 2017 err = -EINVAL; 2018 } 2019 spin_unlock_irqrestore(&fb->state_lock, flags); 2020 2021 if (!err) { 2022 if (vino_pixel_conversion 2023 && (fb->data_format == VINO_DATA_FMT_RGB32)) { 2024 vino_convert_to_rgba(fb); 2025 } 2026 } else if (err && (err != -EINVAL)) { 2027 dprintk("vino_check_buffer(): buffer not ready\n"); 2028 2029 spin_lock_irqsave(&vino_drvdata->vino_lock, flags); 2030 vino_dma_stop(vcs); 2031 vino_clear_interrupt(vcs); 2032 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags); 2033 } 2034 2035 return err; 2036} 2037 2038/* forcefully terminates capture */ 2039static void vino_capture_stop(struct vino_channel_settings *vcs) 2040{ 2041 unsigned int incoming = 0, outgoing = 0, id; 2042 unsigned long flags, flags2; 2043 2044 dprintk("vino_capture_stop():\n"); 2045 2046 spin_lock_irqsave(&vcs->capture_lock, flags); 2047 2048 /* unset capturing to stop queue processing */ 2049 vcs->capturing = 0; 2050 2051 spin_lock_irqsave(&vino_drvdata->vino_lock, flags2); 2052 2053 vino_dma_stop(vcs); 2054 vino_clear_interrupt(vcs); 2055 2056 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2); 2057 2058 /* remove all items from the queue */ 2059 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) { 2060 dprintk("vino_capture_stop(): " 2061 "vino_queue_get_incoming() failed\n"); 2062 goto out; 2063 } 2064 while (incoming > 0) { 2065 vino_queue_transfer(&vcs->fb_queue); 2066 2067 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) { 2068 dprintk("vino_capture_stop(): " 2069 "vino_queue_get_incoming() failed\n"); 2070 goto out; 2071 } 2072 } 2073 2074 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { 2075 dprintk("vino_capture_stop(): " 2076 "vino_queue_get_outgoing() failed\n"); 2077 goto out; 2078 } 2079 while (outgoing > 0) { 2080 vino_queue_remove(&vcs->fb_queue, &id); 2081 2082 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { 2083 dprintk("vino_capture_stop(): " 2084 "vino_queue_get_outgoing() failed\n"); 2085 goto out; 2086 } 2087 } 2088 2089out: 2090 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2091} 2092 2093 2094static void vino_skip_frame(struct vino_channel_settings *vcs) 2095{ 2096 struct vino_framebuffer *fb; 2097 unsigned long flags; 2098 unsigned int id; 2099 2100 spin_lock_irqsave(&vcs->capture_lock, flags); 2101 fb = vino_queue_peek(&vcs->fb_queue, &id); 2102 if (!fb) { 2103 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2104 dprintk("vino_skip_frame(): vino_queue_peek() failed!\n"); 2105 return; 2106 } 2107 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2108 2109 spin_lock_irqsave(&fb->state_lock, flags); 2110 fb->state = VINO_FRAMEBUFFER_UNUSED; 2111 spin_unlock_irqrestore(&fb->state_lock, flags); 2112 2113 vino_capture_next(vcs, 0); 2114} 2115 2116static void vino_frame_done(struct vino_channel_settings *vcs) 2117{ 2118 struct vino_framebuffer *fb; 2119 unsigned long flags; 2120 2121 spin_lock_irqsave(&vcs->capture_lock, flags); 2122 fb = vino_queue_transfer(&vcs->fb_queue); 2123 if (!fb) { 2124 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2125 dprintk("vino_frame_done(): vino_queue_transfer() failed!\n"); 2126 return; 2127 } 2128 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2129 2130 fb->frame_counter = vcs->int_data.frame_counter; 2131 memcpy(&fb->timestamp, &vcs->int_data.timestamp, 2132 sizeof(struct timeval)); 2133 2134 spin_lock_irqsave(&fb->state_lock, flags); 2135 if (fb->state == VINO_FRAMEBUFFER_IN_USE) 2136 fb->state = VINO_FRAMEBUFFER_READY; 2137 spin_unlock_irqrestore(&fb->state_lock, flags); 2138 2139 wake_up(&vcs->fb_queue.frame_wait_queue); 2140 2141 vino_capture_next(vcs, 0); 2142} 2143 2144static void vino_capture_tasklet(unsigned long channel) { 2145 struct vino_channel_settings *vcs; 2146 2147 vcs = (channel == VINO_CHANNEL_A) 2148 ? &vino_drvdata->a : &vino_drvdata->b; 2149 2150 if (vcs->int_data.skip) 2151 vcs->int_data.skip_count++; 2152 2153 if (vcs->int_data.skip && (vcs->int_data.skip_count 2154 <= VINO_MAX_FRAME_SKIP_COUNT)) { 2155 vino_skip_frame(vcs); 2156 } else { 2157 vcs->int_data.skip_count = 0; 2158 vino_frame_done(vcs); 2159 } 2160} 2161 2162static irqreturn_t vino_interrupt(int irq, void *dev_id) 2163{ 2164 u32 ctrl, intr; 2165 unsigned int fc_a, fc_b; 2166 int handled_a = 0, skip_a = 0, done_a = 0; 2167 int handled_b = 0, skip_b = 0, done_b = 0; 2168 2169#ifdef VINO_DEBUG_INT 2170 int loop = 0; 2171 unsigned int line_count = vino->a.line_count, 2172 page_index = vino->a.page_index, 2173 field_counter = vino->a.field_counter, 2174 start_desc_tbl = vino->a.start_desc_tbl, 2175 next_4_desc = vino->a.next_4_desc; 2176 unsigned int line_count_2, 2177 page_index_2, 2178 field_counter_2, 2179 start_desc_tbl_2, 2180 next_4_desc_2; 2181#endif 2182 2183 spin_lock(&vino_drvdata->vino_lock); 2184 2185 while ((intr = vino->intr_status)) { 2186 fc_a = vino->a.field_counter >> 1; 2187 fc_b = vino->b.field_counter >> 1; 2188 2189 /* handle error-interrupts in some special way ? 2190 * --> skips frames */ 2191 if (intr & VINO_INTSTAT_A) { 2192 if (intr & VINO_INTSTAT_A_EOF) { 2193 vino_drvdata->a.field++; 2194 if (vino_drvdata->a.field > 1) { 2195 vino_dma_stop(&vino_drvdata->a); 2196 vino_clear_interrupt(&vino_drvdata->a); 2197 vino_drvdata->a.field = 0; 2198 done_a = 1; 2199 } else { 2200 if (vino->a.page_index 2201 != vino_drvdata->a.line_size) { 2202 vino->a.line_count = 0; 2203 vino->a.page_index = 2204 vino_drvdata-> 2205 a.line_size; 2206 vino->a.next_4_desc = 2207 vino->a.start_desc_tbl; 2208 } 2209 } 2210 dprintk("channel A end-of-field " 2211 "interrupt: %04x\n", intr); 2212 } else { 2213 vino_dma_stop(&vino_drvdata->a); 2214 vino_clear_interrupt(&vino_drvdata->a); 2215 vino_drvdata->a.field = 0; 2216 skip_a = 1; 2217 dprintk("channel A error interrupt: %04x\n", 2218 intr); 2219 } 2220 2221#ifdef VINO_DEBUG_INT 2222 line_count_2 = vino->a.line_count; 2223 page_index_2 = vino->a.page_index; 2224 field_counter_2 = vino->a.field_counter; 2225 start_desc_tbl_2 = vino->a.start_desc_tbl; 2226 next_4_desc_2 = vino->a.next_4_desc; 2227 2228 printk("intr = %04x, loop = %d, field = %d\n", 2229 intr, loop, vino_drvdata->a.field); 2230 printk("1- line count = %04d, page index = %04d, " 2231 "start = %08x, next = %08x\n" 2232 " fieldc = %d, framec = %d\n", 2233 line_count, page_index, start_desc_tbl, 2234 next_4_desc, field_counter, fc_a); 2235 printk("12-line count = %04d, page index = %04d, " 2236 " start = %08x, next = %08x\n", 2237 line_count_2, page_index_2, start_desc_tbl_2, 2238 next_4_desc_2); 2239 2240 if (done_a) 2241 printk("\n"); 2242#endif 2243 } 2244 2245 if (intr & VINO_INTSTAT_B) { 2246 if (intr & VINO_INTSTAT_B_EOF) { 2247 vino_drvdata->b.field++; 2248 if (vino_drvdata->b.field > 1) { 2249 vino_dma_stop(&vino_drvdata->b); 2250 vino_clear_interrupt(&vino_drvdata->b); 2251 vino_drvdata->b.field = 0; 2252 done_b = 1; 2253 } 2254 dprintk("channel B end-of-field " 2255 "interrupt: %04x\n", intr); 2256 } else { 2257 vino_dma_stop(&vino_drvdata->b); 2258 vino_clear_interrupt(&vino_drvdata->b); 2259 vino_drvdata->b.field = 0; 2260 skip_b = 1; 2261 dprintk("channel B error interrupt: %04x\n", 2262 intr); 2263 } 2264 } 2265 2266 /* Always remember to clear interrupt status. 2267 * Disable VINO interrupts while we do this. */ 2268 ctrl = vino->control; 2269 vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT); 2270 vino->intr_status = ~intr; 2271 vino->control = ctrl; 2272 2273 spin_unlock(&vino_drvdata->vino_lock); 2274 2275 if ((!handled_a) && (done_a || skip_a)) { 2276 if (!skip_a) { 2277 do_gettimeofday(&vino_drvdata-> 2278 a.int_data.timestamp); 2279 vino_drvdata->a.int_data.frame_counter = fc_a; 2280 } 2281 vino_drvdata->a.int_data.skip = skip_a; 2282 2283 dprintk("channel A %s, interrupt: %d\n", 2284 skip_a ? "skipping frame" : "frame done", 2285 intr); 2286 tasklet_hi_schedule(&vino_tasklet_a); 2287 handled_a = 1; 2288 } 2289 2290 if ((!handled_b) && (done_b || skip_b)) { 2291 if (!skip_b) { 2292 do_gettimeofday(&vino_drvdata-> 2293 b.int_data.timestamp); 2294 vino_drvdata->b.int_data.frame_counter = fc_b; 2295 } 2296 vino_drvdata->b.int_data.skip = skip_b; 2297 2298 dprintk("channel B %s, interrupt: %d\n", 2299 skip_b ? "skipping frame" : "frame done", 2300 intr); 2301 tasklet_hi_schedule(&vino_tasklet_b); 2302 handled_b = 1; 2303 } 2304 2305#ifdef VINO_DEBUG_INT 2306 loop++; 2307#endif 2308 spin_lock(&vino_drvdata->vino_lock); 2309 } 2310 2311 spin_unlock(&vino_drvdata->vino_lock); 2312 2313 return IRQ_HANDLED; 2314} 2315 2316/* VINO video input management */ 2317 2318static int vino_get_saa7191_input(int input) 2319{ 2320 switch (input) { 2321 case VINO_INPUT_COMPOSITE: 2322 return SAA7191_INPUT_COMPOSITE; 2323 case VINO_INPUT_SVIDEO: 2324 return SAA7191_INPUT_SVIDEO; 2325 default: 2326 printk(KERN_ERR "VINO: vino_get_saa7191_input(): " 2327 "invalid input!\n"); 2328 return -1; 2329 } 2330} 2331 2332static int vino_get_saa7191_norm(unsigned int data_norm) 2333{ 2334 switch (data_norm) { 2335 case VINO_DATA_NORM_AUTO: 2336 return SAA7191_NORM_AUTO; 2337 case VINO_DATA_NORM_AUTO_EXT: 2338 return SAA7191_NORM_AUTO_EXT; 2339 case VINO_DATA_NORM_PAL: 2340 return SAA7191_NORM_PAL; 2341 case VINO_DATA_NORM_NTSC: 2342 return SAA7191_NORM_NTSC; 2343 case VINO_DATA_NORM_SECAM: 2344 return SAA7191_NORM_SECAM; 2345 default: 2346 printk(KERN_ERR "VINO: vino_get_saa7191_norm(): " 2347 "invalid norm!\n"); 2348 return -1; 2349 } 2350} 2351 2352static int vino_get_from_saa7191_norm(int saa7191_norm) 2353{ 2354 switch (saa7191_norm) { 2355 case SAA7191_NORM_PAL: 2356 return VINO_DATA_NORM_PAL; 2357 case SAA7191_NORM_NTSC: 2358 return VINO_DATA_NORM_NTSC; 2359 case SAA7191_NORM_SECAM: 2360 return VINO_DATA_NORM_SECAM; 2361 default: 2362 printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): " 2363 "invalid norm!\n"); 2364 return VINO_DATA_NORM_NONE; 2365 } 2366} 2367 2368static int vino_saa7191_set_norm(unsigned int *data_norm) 2369{ 2370 int saa7191_norm, new_data_norm; 2371 int err = 0; 2372 2373 saa7191_norm = vino_get_saa7191_norm(*data_norm); 2374 2375 err = i2c_decoder_command(DECODER_SAA7191_SET_NORM, 2376 &saa7191_norm); 2377 if (err) 2378 goto out; 2379 2380 if ((*data_norm == VINO_DATA_NORM_AUTO) 2381 || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) { 2382 struct saa7191_status status; 2383 2384 err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS, 2385 &status); 2386 if (err) 2387 goto out; 2388 2389 new_data_norm = 2390 vino_get_from_saa7191_norm(status.norm); 2391 if (new_data_norm == VINO_DATA_NORM_NONE) { 2392 err = -EINVAL; 2393 goto out; 2394 } 2395 2396 *data_norm = (unsigned int)new_data_norm; 2397 } 2398 2399out: 2400 return err; 2401} 2402 2403/* execute with input_lock locked */ 2404static int vino_is_input_owner(struct vino_channel_settings *vcs) 2405{ 2406 switch(vcs->input) { 2407 case VINO_INPUT_COMPOSITE: 2408 case VINO_INPUT_SVIDEO: 2409 return (vino_drvdata->decoder.owner == vcs->channel); 2410 case VINO_INPUT_D1: 2411 return (vino_drvdata->camera.owner == vcs->channel); 2412 default: 2413 return 0; 2414 } 2415} 2416 2417static int vino_acquire_input(struct vino_channel_settings *vcs) 2418{ 2419 unsigned long flags; 2420 int ret = 0; 2421 2422 dprintk("vino_acquire_input():\n"); 2423 2424 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2425 2426 /* First try D1 and then SAA7191 */ 2427 if (vino_drvdata->camera.driver 2428 && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { 2429 if (i2c_use_client(vino_drvdata->camera.driver)) { 2430 ret = -ENODEV; 2431 goto out; 2432 } 2433 2434 vino_drvdata->camera.owner = vcs->channel; 2435 vcs->input = VINO_INPUT_D1; 2436 vcs->data_norm = VINO_DATA_NORM_D1; 2437 } else if (vino_drvdata->decoder.driver 2438 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { 2439 int input, data_norm; 2440 int saa7191_input; 2441 2442 if (i2c_use_client(vino_drvdata->decoder.driver)) { 2443 ret = -ENODEV; 2444 goto out; 2445 } 2446 2447 input = VINO_INPUT_COMPOSITE; 2448 2449 saa7191_input = vino_get_saa7191_input(input); 2450 ret = i2c_decoder_command(DECODER_SET_INPUT, 2451 &saa7191_input); 2452 if (ret) { 2453 ret = -EINVAL; 2454 goto out; 2455 } 2456 2457 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2458 2459 /* Don't hold spinlocks while auto-detecting norm 2460 * as it may take a while... */ 2461 2462 data_norm = VINO_DATA_NORM_AUTO_EXT; 2463 2464 ret = vino_saa7191_set_norm(&data_norm); 2465 if ((ret == -EBUSY) || (ret == -EAGAIN)) { 2466 data_norm = VINO_DATA_NORM_PAL; 2467 ret = vino_saa7191_set_norm(&data_norm); 2468 } 2469 2470 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2471 2472 if (ret) { 2473 ret = -EINVAL; 2474 goto out; 2475 } 2476 2477 vino_drvdata->decoder.owner = vcs->channel; 2478 2479 vcs->input = input; 2480 vcs->data_norm = data_norm; 2481 } else { 2482 vcs->input = (vcs->channel == VINO_CHANNEL_A) ? 2483 vino_drvdata->b.input : vino_drvdata->a.input; 2484 vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ? 2485 vino_drvdata->b.data_norm : vino_drvdata->a.data_norm; 2486 } 2487 2488 if (vcs->input == VINO_INPUT_NONE) { 2489 ret = -ENODEV; 2490 goto out; 2491 } 2492 2493 vino_set_default_clipping(vcs); 2494 vino_set_default_scaling(vcs); 2495 vino_set_default_framerate(vcs); 2496 2497 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name); 2498 2499out: 2500 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2501 2502 return ret; 2503} 2504 2505static int vino_set_input(struct vino_channel_settings *vcs, int input) 2506{ 2507 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? 2508 &vino_drvdata->b : &vino_drvdata->a; 2509 unsigned long flags; 2510 int ret = 0; 2511 2512 dprintk("vino_set_input():\n"); 2513 2514 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2515 2516 if (vcs->input == input) 2517 goto out; 2518 2519 switch (input) { 2520 case VINO_INPUT_COMPOSITE: 2521 case VINO_INPUT_SVIDEO: 2522 if (!vino_drvdata->decoder.driver) { 2523 ret = -EINVAL; 2524 goto out; 2525 } 2526 2527 if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { 2528 if (i2c_use_client(vino_drvdata->decoder.driver)) { 2529 ret = -ENODEV; 2530 goto out; 2531 } 2532 vino_drvdata->decoder.owner = vcs->channel; 2533 } 2534 2535 if (vino_drvdata->decoder.owner == vcs->channel) { 2536 int data_norm; 2537 int saa7191_input; 2538 2539 saa7191_input = vino_get_saa7191_input(input); 2540 ret = i2c_decoder_command(DECODER_SET_INPUT, 2541 &saa7191_input); 2542 if (ret) { 2543 vino_drvdata->decoder.owner = VINO_NO_CHANNEL; 2544 ret = -EINVAL; 2545 goto out; 2546 } 2547 2548 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2549 2550 /* Don't hold spinlocks while auto-detecting norm 2551 * as it may take a while... */ 2552 2553 data_norm = VINO_DATA_NORM_AUTO_EXT; 2554 2555 ret = vino_saa7191_set_norm(&data_norm); 2556 if ((ret == -EBUSY) || (ret == -EAGAIN)) { 2557 data_norm = VINO_DATA_NORM_PAL; 2558 ret = vino_saa7191_set_norm(&data_norm); 2559 } 2560 2561 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2562 2563 if (ret) { 2564 vino_drvdata->decoder.owner = VINO_NO_CHANNEL; 2565 ret = -EINVAL; 2566 goto out; 2567 } 2568 2569 vcs->input = input; 2570 vcs->data_norm = data_norm; 2571 } else { 2572 if (input != vcs2->input) { 2573 ret = -EBUSY; 2574 goto out; 2575 } 2576 2577 vcs->input = input; 2578 vcs->data_norm = vcs2->data_norm; 2579 } 2580 2581 if (vino_drvdata->camera.owner == vcs->channel) { 2582 /* Transfer the ownership or release the input */ 2583 if (vcs2->input == VINO_INPUT_D1) { 2584 vino_drvdata->camera.owner = vcs2->channel; 2585 } else { 2586 i2c_release_client(vino_drvdata-> 2587 camera.driver); 2588 vino_drvdata->camera.owner = VINO_NO_CHANNEL; 2589 } 2590 } 2591 break; 2592 case VINO_INPUT_D1: 2593 if (!vino_drvdata->camera.driver) { 2594 ret = -EINVAL; 2595 goto out; 2596 } 2597 2598 if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { 2599 if (i2c_use_client(vino_drvdata->camera.driver)) { 2600 ret = -ENODEV; 2601 goto out; 2602 } 2603 vino_drvdata->camera.owner = vcs->channel; 2604 } 2605 2606 if (vino_drvdata->decoder.owner == vcs->channel) { 2607 /* Transfer the ownership or release the input */ 2608 if ((vcs2->input == VINO_INPUT_COMPOSITE) || 2609 (vcs2->input == VINO_INPUT_SVIDEO)) { 2610 vino_drvdata->decoder.owner = vcs2->channel; 2611 } else { 2612 i2c_release_client(vino_drvdata-> 2613 decoder.driver); 2614 vino_drvdata->decoder.owner = VINO_NO_CHANNEL; 2615 } 2616 } 2617 2618 vcs->input = input; 2619 vcs->data_norm = VINO_DATA_NORM_D1; 2620 break; 2621 default: 2622 ret = -EINVAL; 2623 goto out; 2624 } 2625 2626 vino_set_default_clipping(vcs); 2627 vino_set_default_scaling(vcs); 2628 vino_set_default_framerate(vcs); 2629 2630 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name); 2631 2632out: 2633 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2634 2635 return ret; 2636} 2637 2638static void vino_release_input(struct vino_channel_settings *vcs) 2639{ 2640 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? 2641 &vino_drvdata->b : &vino_drvdata->a; 2642 unsigned long flags; 2643 2644 dprintk("vino_release_input():\n"); 2645 2646 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2647 2648 /* Release ownership of the channel 2649 * and if the other channel takes input from 2650 * the same source, transfer the ownership */ 2651 if (vino_drvdata->camera.owner == vcs->channel) { 2652 if (vcs2->input == VINO_INPUT_D1) { 2653 vino_drvdata->camera.owner = vcs2->channel; 2654 } else { 2655 i2c_release_client(vino_drvdata->camera.driver); 2656 vino_drvdata->camera.owner = VINO_NO_CHANNEL; 2657 } 2658 } else if (vino_drvdata->decoder.owner == vcs->channel) { 2659 if ((vcs2->input == VINO_INPUT_COMPOSITE) || 2660 (vcs2->input == VINO_INPUT_SVIDEO)) { 2661 vino_drvdata->decoder.owner = vcs2->channel; 2662 } else { 2663 i2c_release_client(vino_drvdata->decoder.driver); 2664 vino_drvdata->decoder.owner = VINO_NO_CHANNEL; 2665 } 2666 } 2667 vcs->input = VINO_INPUT_NONE; 2668 2669 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2670} 2671 2672/* execute with input_lock locked */ 2673static int vino_set_data_norm(struct vino_channel_settings *vcs, 2674 unsigned int data_norm, 2675 unsigned long *flags) 2676{ 2677 int err = 0; 2678 2679 if (data_norm == vcs->data_norm) 2680 return 0; 2681 2682 switch (vcs->input) { 2683 case VINO_INPUT_D1: 2684 /* only one "norm" supported */ 2685 if ((data_norm != VINO_DATA_NORM_D1) 2686 && (data_norm != VINO_DATA_NORM_AUTO) 2687 && (data_norm != VINO_DATA_NORM_AUTO_EXT)) 2688 return -EINVAL; 2689 break; 2690 case VINO_INPUT_COMPOSITE: 2691 case VINO_INPUT_SVIDEO: { 2692 if ((data_norm != VINO_DATA_NORM_PAL) 2693 && (data_norm != VINO_DATA_NORM_NTSC) 2694 && (data_norm != VINO_DATA_NORM_SECAM) 2695 && (data_norm != VINO_DATA_NORM_AUTO) 2696 && (data_norm != VINO_DATA_NORM_AUTO_EXT)) 2697 return -EINVAL; 2698 2699 spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags); 2700 2701 /* Don't hold spinlocks while setting norm 2702 * as it may take a while... */ 2703 2704 err = vino_saa7191_set_norm(&data_norm); 2705 2706 spin_lock_irqsave(&vino_drvdata->input_lock, *flags); 2707 2708 if (err) 2709 goto out; 2710 2711 vcs->data_norm = data_norm; 2712 2713 vino_set_default_clipping(vcs); 2714 vino_set_default_scaling(vcs); 2715 vino_set_default_framerate(vcs); 2716 break; 2717 } 2718 default: 2719 return -EINVAL; 2720 } 2721 2722out: 2723 return err; 2724} 2725 2726/* V4L2 helper functions */ 2727 2728static int vino_find_data_format(__u32 pixelformat) 2729{ 2730 int i; 2731 2732 for (i = 0; i < VINO_DATA_FMT_COUNT; i++) { 2733 if (vino_data_formats[i].pixelformat == pixelformat) 2734 return i; 2735 } 2736 2737 return VINO_DATA_FMT_NONE; 2738} 2739 2740static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index) 2741{ 2742 int data_norm = VINO_DATA_NORM_NONE; 2743 unsigned long flags; 2744 2745 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2746 switch(vcs->input) { 2747 case VINO_INPUT_COMPOSITE: 2748 case VINO_INPUT_SVIDEO: 2749 if (index == 0) { 2750 data_norm = VINO_DATA_NORM_PAL; 2751 } else if (index == 1) { 2752 data_norm = VINO_DATA_NORM_NTSC; 2753 } else if (index == 2) { 2754 data_norm = VINO_DATA_NORM_SECAM; 2755 } 2756 break; 2757 case VINO_INPUT_D1: 2758 if (index == 0) { 2759 data_norm = VINO_DATA_NORM_D1; 2760 } 2761 break; 2762 } 2763 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2764 2765 return data_norm; 2766} 2767 2768static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index) 2769{ 2770 int input = VINO_INPUT_NONE; 2771 unsigned long flags; 2772 2773 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2774 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { 2775 switch (index) { 2776 case 0: 2777 input = VINO_INPUT_COMPOSITE; 2778 break; 2779 case 1: 2780 input = VINO_INPUT_SVIDEO; 2781 break; 2782 case 2: 2783 input = VINO_INPUT_D1; 2784 break; 2785 } 2786 } else if (vino_drvdata->decoder.driver) { 2787 switch (index) { 2788 case 0: 2789 input = VINO_INPUT_COMPOSITE; 2790 break; 2791 case 1: 2792 input = VINO_INPUT_SVIDEO; 2793 break; 2794 } 2795 } else if (vino_drvdata->camera.driver) { 2796 switch (index) { 2797 case 0: 2798 input = VINO_INPUT_D1; 2799 break; 2800 } 2801 } 2802 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2803 2804 return input; 2805} 2806 2807/* execute with input_lock locked */ 2808static __u32 vino_find_input_index(struct vino_channel_settings *vcs) 2809{ 2810 __u32 index = 0; 2811 2812 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { 2813 switch (vcs->input) { 2814 case VINO_INPUT_COMPOSITE: 2815 index = 0; 2816 break; 2817 case VINO_INPUT_SVIDEO: 2818 index = 1; 2819 break; 2820 case VINO_INPUT_D1: 2821 index = 2; 2822 break; 2823 } 2824 } else if (vino_drvdata->decoder.driver) { 2825 switch (vcs->input) { 2826 case VINO_INPUT_COMPOSITE: 2827 index = 0; 2828 break; 2829 case VINO_INPUT_SVIDEO: 2830 index = 1; 2831 break; 2832 } 2833 } else if (vino_drvdata->camera.driver) { 2834 switch (vcs->input) { 2835 case VINO_INPUT_D1: 2836 index = 0; 2837 break; 2838 } 2839 } 2840 2841 return index; 2842} 2843 2844/* V4L2 ioctls */ 2845 2846static void vino_v4l2_querycap(struct v4l2_capability *cap) 2847{ 2848 memset(cap, 0, sizeof(struct v4l2_capability)); 2849 2850 strcpy(cap->driver, vino_driver_name); 2851 strcpy(cap->card, vino_driver_description); 2852 strcpy(cap->bus_info, vino_bus_name); 2853 cap->version = VINO_VERSION_CODE; 2854 cap->capabilities = 2855 V4L2_CAP_VIDEO_CAPTURE | 2856 V4L2_CAP_STREAMING; 2857 // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE 2858} 2859 2860static int vino_v4l2_enuminput(struct vino_channel_settings *vcs, 2861 struct v4l2_input *i) 2862{ 2863 __u32 index = i->index; 2864 int input; 2865 dprintk("requested index = %d\n", index); 2866 2867 input = vino_enum_input(vcs, index); 2868 if (input == VINO_INPUT_NONE) 2869 return -EINVAL; 2870 2871 memset(i, 0, sizeof(struct v4l2_input)); 2872 2873 i->index = index; 2874 i->type = V4L2_INPUT_TYPE_CAMERA; 2875 i->std = vino_inputs[input].std; 2876 strcpy(i->name, vino_inputs[input].name); 2877 2878 if ((input == VINO_INPUT_COMPOSITE) 2879 || (input == VINO_INPUT_SVIDEO)) { 2880 struct saa7191_status status; 2881 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); 2882 i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL; 2883 i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR; 2884 } 2885 2886 return 0; 2887} 2888 2889static int vino_v4l2_g_input(struct vino_channel_settings *vcs, 2890 unsigned int *i) 2891{ 2892 __u32 index; 2893 int input; 2894 unsigned long flags; 2895 2896 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2897 input = vcs->input; 2898 index = vino_find_input_index(vcs); 2899 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2900 2901 dprintk("input = %d\n", input); 2902 2903 if (input == VINO_INPUT_NONE) { 2904 return -EINVAL; 2905 } 2906 2907 *i = index; 2908 2909 return 0; 2910} 2911 2912static int vino_v4l2_s_input(struct vino_channel_settings *vcs, 2913 unsigned int *i) 2914{ 2915 int input; 2916 dprintk("requested input = %d\n", *i); 2917 2918 input = vino_enum_input(vcs, *i); 2919 if (input == VINO_INPUT_NONE) 2920 return -EINVAL; 2921 2922 return vino_set_input(vcs, input); 2923} 2924 2925static int vino_v4l2_enumstd(struct vino_channel_settings *vcs, 2926 struct v4l2_standard *s) 2927{ 2928 int index = s->index; 2929 int data_norm; 2930 2931 data_norm = vino_enum_data_norm(vcs, index); 2932 dprintk("standard index = %d\n", index); 2933 2934 if (data_norm == VINO_DATA_NORM_NONE) 2935 return -EINVAL; 2936 2937 dprintk("standard name = %s\n", 2938 vino_data_norms[data_norm].description); 2939 2940 memset(s, 0, sizeof(struct v4l2_standard)); 2941 s->index = index; 2942 2943 s->id = vino_data_norms[data_norm].std; 2944 s->frameperiod.numerator = 1; 2945 s->frameperiod.denominator = 2946 vino_data_norms[data_norm].fps_max; 2947 s->framelines = 2948 vino_data_norms[data_norm].framelines; 2949 strcpy(s->name, 2950 vino_data_norms[data_norm].description); 2951 2952 return 0; 2953} 2954 2955static int vino_v4l2_querystd(struct vino_channel_settings *vcs, 2956 v4l2_std_id *std) 2957{ 2958 unsigned long flags; 2959 int err = 0; 2960 2961 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2962 2963 switch (vcs->input) { 2964 case VINO_INPUT_D1: 2965 *std = vino_inputs[vcs->input].std; 2966 break; 2967 case VINO_INPUT_COMPOSITE: 2968 case VINO_INPUT_SVIDEO: { 2969 struct saa7191_status status; 2970 2971 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); 2972 2973 if (status.signal) { 2974 if (status.signal_60hz) { 2975 *std = V4L2_STD_NTSC; 2976 } else { 2977 *std = V4L2_STD_PAL | V4L2_STD_SECAM; 2978 } 2979 } else { 2980 *std = vino_inputs[vcs->input].std; 2981 } 2982 break; 2983 } 2984 default: 2985 err = -EINVAL; 2986 } 2987 2988 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 2989 2990 return err; 2991} 2992 2993static int vino_v4l2_g_std(struct vino_channel_settings *vcs, 2994 v4l2_std_id *std) 2995{ 2996 unsigned long flags; 2997 2998 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2999 3000 *std = vino_data_norms[vcs->data_norm].std; 3001 dprintk("current standard = %d\n", vcs->data_norm); 3002 3003 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3004 3005 return 0; 3006} 3007 3008static int vino_v4l2_s_std(struct vino_channel_settings *vcs, 3009 v4l2_std_id *std) 3010{ 3011 unsigned long flags; 3012 int ret = 0; 3013 3014 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3015 3016 if (!vino_is_input_owner(vcs)) { 3017 ret = -EBUSY; 3018 goto out; 3019 } 3020 3021 /* check if the standard is valid for the current input */ 3022 if ((*std) & vino_inputs[vcs->input].std) { 3023 dprintk("standard accepted\n"); 3024 3025 /* change the video norm for SAA7191 3026 * and accept NTSC for D1 (do nothing) */ 3027 3028 if (vcs->input == VINO_INPUT_D1) 3029 goto out; 3030 3031 if (((*std) & V4L2_STD_PAL) 3032 && ((*std) & V4L2_STD_NTSC) 3033 && ((*std) & V4L2_STD_SECAM)) { 3034 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT, 3035 &flags); 3036 } else if ((*std) & V4L2_STD_PAL) { 3037 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL, 3038 &flags); 3039 } else if ((*std) & V4L2_STD_NTSC) { 3040 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC, 3041 &flags); 3042 } else if ((*std) & V4L2_STD_SECAM) { 3043 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM, 3044 &flags); 3045 } else { 3046 ret = -EINVAL; 3047 } 3048 3049 if (ret) { 3050 ret = -EINVAL; 3051 } 3052 } else { 3053 ret = -EINVAL; 3054 } 3055 3056out: 3057 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3058 3059 return ret; 3060} 3061 3062static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs, 3063 struct v4l2_fmtdesc *fd) 3064{ 3065 enum v4l2_buf_type type = fd->type; 3066 int index = fd->index; 3067 dprintk("format index = %d\n", index); 3068 3069 switch (fd->type) { 3070 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3071 if ((fd->index < 0) || 3072 (fd->index >= VINO_DATA_FMT_COUNT)) 3073 return -EINVAL; 3074 dprintk("format name = %s\n", 3075 vino_data_formats[index].description); 3076 3077 memset(fd, 0, sizeof(struct v4l2_fmtdesc)); 3078 fd->index = index; 3079 fd->type = type; 3080 fd->pixelformat = vino_data_formats[index].pixelformat; 3081 strcpy(fd->description, vino_data_formats[index].description); 3082 break; 3083 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3084 default: 3085 return -EINVAL; 3086 } 3087 3088 return 0; 3089} 3090 3091static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs, 3092 struct v4l2_format *f) 3093{ 3094 struct vino_channel_settings tempvcs; 3095 unsigned long flags; 3096 3097 switch (f->type) { 3098 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3099 struct v4l2_pix_format *pf = &f->fmt.pix; 3100 3101 dprintk("requested: w = %d, h = %d\n", 3102 pf->width, pf->height); 3103 3104 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3105 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); 3106 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3107 3108 tempvcs.data_format = vino_find_data_format(pf->pixelformat); 3109 if (tempvcs.data_format == VINO_DATA_FMT_NONE) { 3110 tempvcs.data_format = VINO_DATA_FMT_GREY; 3111 pf->pixelformat = 3112 vino_data_formats[tempvcs.data_format]. 3113 pixelformat; 3114 } 3115 3116 /* data format must be set before clipping/scaling */ 3117 vino_set_scaling(&tempvcs, pf->width, pf->height); 3118 3119 dprintk("data format = %s\n", 3120 vino_data_formats[tempvcs.data_format].description); 3121 3122 pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / 3123 tempvcs.decimation; 3124 pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / 3125 tempvcs.decimation; 3126 3127 pf->field = V4L2_FIELD_INTERLACED; 3128 pf->bytesperline = tempvcs.line_size; 3129 pf->sizeimage = tempvcs.line_size * 3130 (tempvcs.clipping.bottom - tempvcs.clipping.top) / 3131 tempvcs.decimation; 3132 pf->colorspace = 3133 vino_data_formats[tempvcs.data_format].colorspace; 3134 3135 pf->priv = 0; 3136 break; 3137 } 3138 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3139 default: 3140 return -EINVAL; 3141 } 3142 3143 return 0; 3144} 3145 3146static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs, 3147 struct v4l2_format *f) 3148{ 3149 unsigned long flags; 3150 3151 switch (f->type) { 3152 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3153 struct v4l2_pix_format *pf = &f->fmt.pix; 3154 3155 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3156 3157 pf->width = (vcs->clipping.right - vcs->clipping.left) / 3158 vcs->decimation; 3159 pf->height = (vcs->clipping.bottom - vcs->clipping.top) / 3160 vcs->decimation; 3161 pf->pixelformat = 3162 vino_data_formats[vcs->data_format].pixelformat; 3163 3164 pf->field = V4L2_FIELD_INTERLACED; 3165 pf->bytesperline = vcs->line_size; 3166 pf->sizeimage = vcs->line_size * 3167 (vcs->clipping.bottom - vcs->clipping.top) / 3168 vcs->decimation; 3169 pf->colorspace = 3170 vino_data_formats[vcs->data_format].colorspace; 3171 3172 pf->priv = 0; 3173 3174 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3175 break; 3176 } 3177 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3178 default: 3179 return -EINVAL; 3180 } 3181 3182 return 0; 3183} 3184 3185static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs, 3186 struct v4l2_format *f) 3187{ 3188 int data_format; 3189 unsigned long flags; 3190 3191 switch (f->type) { 3192 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3193 struct v4l2_pix_format *pf = &f->fmt.pix; 3194 3195 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3196 3197 data_format = vino_find_data_format(pf->pixelformat); 3198 3199 if (data_format == VINO_DATA_FMT_NONE) { 3200 vcs->data_format = VINO_DATA_FMT_GREY; 3201 pf->pixelformat = 3202 vino_data_formats[vcs->data_format]. 3203 pixelformat; 3204 } else { 3205 vcs->data_format = data_format; 3206 } 3207 3208 /* data format must be set before clipping/scaling */ 3209 vino_set_scaling(vcs, pf->width, pf->height); 3210 3211 dprintk("data format = %s\n", 3212 vino_data_formats[vcs->data_format].description); 3213 3214 pf->width = vcs->clipping.right - vcs->clipping.left; 3215 pf->height = vcs->clipping.bottom - vcs->clipping.top; 3216 3217 pf->field = V4L2_FIELD_INTERLACED; 3218 pf->bytesperline = vcs->line_size; 3219 pf->sizeimage = vcs->line_size * 3220 (vcs->clipping.bottom - vcs->clipping.top) / 3221 vcs->decimation; 3222 pf->colorspace = 3223 vino_data_formats[vcs->data_format].colorspace; 3224 3225 pf->priv = 0; 3226 3227 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3228 break; 3229 } 3230 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3231 default: 3232 return -EINVAL; 3233 } 3234 3235 return 0; 3236} 3237 3238static int vino_v4l2_cropcap(struct vino_channel_settings *vcs, 3239 struct v4l2_cropcap *ccap) 3240{ 3241 const struct vino_data_norm *norm; 3242 unsigned long flags; 3243 3244 switch (ccap->type) { 3245 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3246 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3247 3248 norm = &vino_data_norms[vcs->data_norm]; 3249 3250 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3251 3252 ccap->bounds.left = 0; 3253 ccap->bounds.top = 0; 3254 ccap->bounds.width = norm->width; 3255 ccap->bounds.height = norm->height; 3256 memcpy(&ccap->defrect, &ccap->bounds, 3257 sizeof(struct v4l2_rect)); 3258 3259 ccap->pixelaspect.numerator = 1; 3260 ccap->pixelaspect.denominator = 1; 3261 break; 3262 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3263 default: 3264 return -EINVAL; 3265 } 3266 3267 return 0; 3268} 3269 3270static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, 3271 struct v4l2_crop *c) 3272{ 3273 unsigned long flags; 3274 3275 switch (c->type) { 3276 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3277 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3278 3279 c->c.left = vcs->clipping.left; 3280 c->c.top = vcs->clipping.top; 3281 c->c.width = vcs->clipping.right - vcs->clipping.left; 3282 c->c.height = vcs->clipping.bottom - vcs->clipping.top; 3283 3284 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3285 break; 3286 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3287 default: 3288 return -EINVAL; 3289 } 3290 3291 return 0; 3292} 3293 3294static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, 3295 struct v4l2_crop *c) 3296{ 3297 unsigned long flags; 3298 3299 switch (c->type) { 3300 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3301 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3302 3303 vino_set_clipping(vcs, c->c.left, c->c.top, 3304 c->c.width, c->c.height); 3305 3306 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3307 break; 3308 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3309 default: 3310 return -EINVAL; 3311 } 3312 3313 return 0; 3314} 3315 3316static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, 3317 struct v4l2_streamparm *sp) 3318{ 3319 unsigned long flags; 3320 3321 switch (sp->type) { 3322 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3323 struct v4l2_captureparm *cp = &sp->parm.capture; 3324 memset(cp, 0, sizeof(struct v4l2_captureparm)); 3325 3326 cp->capability = V4L2_CAP_TIMEPERFRAME; 3327 cp->timeperframe.numerator = 1; 3328 3329 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3330 3331 cp->timeperframe.denominator = vcs->fps; 3332 3333 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3334 3335 break; 3336 } 3337 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3338 default: 3339 return -EINVAL; 3340 } 3341 3342 return 0; 3343} 3344 3345static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, 3346 struct v4l2_streamparm *sp) 3347{ 3348 unsigned long flags; 3349 3350 switch (sp->type) { 3351 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3352 struct v4l2_captureparm *cp = &sp->parm.capture; 3353 3354 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3355 3356 if ((cp->timeperframe.numerator == 0) || 3357 (cp->timeperframe.denominator == 0)) { 3358 /* reset framerate */ 3359 vino_set_default_framerate(vcs); 3360 } else { 3361 vino_set_framerate(vcs, cp->timeperframe.denominator / 3362 cp->timeperframe.numerator); 3363 } 3364 3365 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3366 3367 // TODO: set buffers according to cp->readbuffers 3368 break; 3369 } 3370 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3371 default: 3372 return -EINVAL; 3373 } 3374 3375 return 0; 3376} 3377 3378static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs, 3379 struct v4l2_requestbuffers *rb) 3380{ 3381 if (vcs->reading) 3382 return -EBUSY; 3383 3384 switch (rb->type) { 3385 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3386 // TODO: check queue type 3387 if (rb->memory != V4L2_MEMORY_MMAP) { 3388 dprintk("type not mmap\n"); 3389 return -EINVAL; 3390 } 3391 3392 dprintk("count = %d\n", rb->count); 3393 if (rb->count > 0) { 3394 if (vino_is_capturing(vcs)) { 3395 dprintk("busy, capturing\n"); 3396 return -EBUSY; 3397 } 3398 3399 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { 3400 dprintk("busy, buffers still mapped\n"); 3401 return -EBUSY; 3402 } else { 3403 vcs->streaming = 0; 3404 vino_queue_free(&vcs->fb_queue); 3405 vino_queue_init(&vcs->fb_queue, &rb->count); 3406 } 3407 } else { 3408 vcs->streaming = 0; 3409 vino_capture_stop(vcs); 3410 vino_queue_free(&vcs->fb_queue); 3411 } 3412 break; 3413 } 3414 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3415 default: 3416 return -EINVAL; 3417 } 3418 3419 return 0; 3420} 3421 3422static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs, 3423 struct vino_framebuffer *fb, 3424 struct v4l2_buffer *b) 3425{ 3426 if (vino_queue_outgoing_contains(&vcs->fb_queue, 3427 fb->id)) { 3428 b->flags &= ~V4L2_BUF_FLAG_QUEUED; 3429 b->flags |= V4L2_BUF_FLAG_DONE; 3430 } else if (vino_queue_incoming_contains(&vcs->fb_queue, 3431 fb->id)) { 3432 b->flags &= ~V4L2_BUF_FLAG_DONE; 3433 b->flags |= V4L2_BUF_FLAG_QUEUED; 3434 } else { 3435 b->flags &= ~(V4L2_BUF_FLAG_DONE | 3436 V4L2_BUF_FLAG_QUEUED); 3437 } 3438 3439 b->flags &= ~(V4L2_BUF_FLAG_TIMECODE); 3440 3441 if (fb->map_count > 0) 3442 b->flags |= V4L2_BUF_FLAG_MAPPED; 3443 3444 b->index = fb->id; 3445 b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ? 3446 V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR; 3447 b->m.offset = fb->offset; 3448 b->bytesused = fb->data_size; 3449 b->length = fb->size; 3450 b->field = V4L2_FIELD_INTERLACED; 3451 b->sequence = fb->frame_counter; 3452 memcpy(&b->timestamp, &fb->timestamp, 3453 sizeof(struct timeval)); 3454 // b->input ? 3455 3456 dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n", 3457 fb->id, fb->size, fb->data_size, fb->offset); 3458} 3459 3460static int vino_v4l2_querybuf(struct vino_channel_settings *vcs, 3461 struct v4l2_buffer *b) 3462{ 3463 if (vcs->reading) 3464 return -EBUSY; 3465 3466 switch (b->type) { 3467 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3468 struct vino_framebuffer *fb; 3469 3470 // TODO: check queue type 3471 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) { 3472 dprintk("invalid index = %d\n", 3473 b->index); 3474 return -EINVAL; 3475 } 3476 3477 fb = vino_queue_get_buffer(&vcs->fb_queue, 3478 b->index); 3479 if (fb == NULL) { 3480 dprintk("vino_queue_get_buffer() failed"); 3481 return -EINVAL; 3482 } 3483 3484 vino_v4l2_get_buffer_status(vcs, fb, b); 3485 break; 3486 } 3487 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3488 default: 3489 return -EINVAL; 3490 } 3491 3492 return 0; 3493} 3494 3495static int vino_v4l2_qbuf(struct vino_channel_settings *vcs, 3496 struct v4l2_buffer *b) 3497{ 3498 if (vcs->reading) 3499 return -EBUSY; 3500 3501 switch (b->type) { 3502 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3503 struct vino_framebuffer *fb; 3504 int ret; 3505 3506 // TODO: check queue type 3507 if (b->memory != V4L2_MEMORY_MMAP) { 3508 dprintk("type not mmap\n"); 3509 return -EINVAL; 3510 } 3511 3512 fb = vino_capture_enqueue(vcs, b->index); 3513 if (fb == NULL) 3514 return -EINVAL; 3515 3516 vino_v4l2_get_buffer_status(vcs, fb, b); 3517 3518 if (vcs->streaming) { 3519 ret = vino_capture_next(vcs, 1); 3520 if (ret) 3521 return ret; 3522 } 3523 break; 3524 } 3525 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3526 default: 3527 return -EINVAL; 3528 } 3529 3530 return 0; 3531} 3532 3533static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs, 3534 struct v4l2_buffer *b, 3535 unsigned int nonblocking) 3536{ 3537 if (vcs->reading) 3538 return -EBUSY; 3539 3540 switch (b->type) { 3541 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3542 struct vino_framebuffer *fb; 3543 unsigned int incoming, outgoing; 3544 int err; 3545 3546 // TODO: check queue type 3547 3548 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); 3549 if (err) { 3550 dprintk("vino_queue_get_incoming() failed\n"); 3551 return -EINVAL; 3552 } 3553 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); 3554 if (err) { 3555 dprintk("vino_queue_get_outgoing() failed\n"); 3556 return -EINVAL; 3557 } 3558 3559 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); 3560 3561 if (outgoing == 0) { 3562 if (incoming == 0) { 3563 dprintk("no incoming or outgoing buffers\n"); 3564 return -EINVAL; 3565 } 3566 if (nonblocking) { 3567 dprintk("non-blocking I/O was selected and " 3568 "there are no buffers to dequeue\n"); 3569 return -EAGAIN; 3570 } 3571 3572 err = vino_wait_for_frame(vcs); 3573 if (err) { 3574 err = vino_wait_for_frame(vcs); 3575 if (err) { 3576 /* interrupted or 3577 * no frames captured because 3578 * of frame skipping */ 3579 // vino_capture_failed(vcs); 3580 return -EIO; 3581 } 3582 } 3583 } 3584 3585 fb = vino_queue_remove(&vcs->fb_queue, &b->index); 3586 if (fb == NULL) { 3587 dprintk("vino_queue_remove() failed\n"); 3588 return -EINVAL; 3589 } 3590 3591 err = vino_check_buffer(vcs, fb); 3592 3593 vino_v4l2_get_buffer_status(vcs, fb, b); 3594 3595 if (err) 3596 return -EIO; 3597 3598 break; 3599 } 3600 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3601 default: 3602 return -EINVAL; 3603 } 3604 3605 return 0; 3606} 3607 3608static int vino_v4l2_streamon(struct vino_channel_settings *vcs) 3609{ 3610 unsigned int incoming; 3611 int ret; 3612 if (vcs->reading) 3613 return -EBUSY; 3614 3615 if (vcs->streaming) 3616 return 0; 3617 3618 // TODO: check queue type 3619 3620 if (vino_queue_get_length(&vcs->fb_queue) < 1) { 3621 dprintk("no buffers allocated\n"); 3622 return -EINVAL; 3623 } 3624 3625 ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming); 3626 if (ret) { 3627 dprintk("vino_queue_get_incoming() failed\n"); 3628 return -EINVAL; 3629 } 3630 3631 vcs->streaming = 1; 3632 3633 if (incoming > 0) { 3634 ret = vino_capture_next(vcs, 1); 3635 if (ret) { 3636 vcs->streaming = 0; 3637 3638 dprintk("couldn't start capture\n"); 3639 return -EINVAL; 3640 } 3641 } 3642 3643 return 0; 3644} 3645 3646static int vino_v4l2_streamoff(struct vino_channel_settings *vcs) 3647{ 3648 if (vcs->reading) 3649 return -EBUSY; 3650 3651 if (!vcs->streaming) 3652 return 0; 3653 3654 vcs->streaming = 0; 3655 vino_capture_stop(vcs); 3656 3657 return 0; 3658} 3659 3660static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, 3661 struct v4l2_queryctrl *queryctrl) 3662{ 3663 unsigned long flags; 3664 int i; 3665 int err = 0; 3666 3667 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3668 3669 switch (vcs->input) { 3670 case VINO_INPUT_D1: 3671 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3672 if (vino_indycam_v4l2_controls[i].id == 3673 queryctrl->id) { 3674 memcpy(queryctrl, 3675 &vino_indycam_v4l2_controls[i], 3676 sizeof(struct v4l2_queryctrl)); 3677 queryctrl->reserved[0] = 0; 3678 goto found; 3679 } 3680 } 3681 3682 err = -EINVAL; 3683 break; 3684 case VINO_INPUT_COMPOSITE: 3685 case VINO_INPUT_SVIDEO: 3686 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 3687 if (vino_saa7191_v4l2_controls[i].id == 3688 queryctrl->id) { 3689 memcpy(queryctrl, 3690 &vino_saa7191_v4l2_controls[i], 3691 sizeof(struct v4l2_queryctrl)); 3692 queryctrl->reserved[0] = 0; 3693 goto found; 3694 } 3695 } 3696 3697 err = -EINVAL; 3698 break; 3699 default: 3700 err = -EINVAL; 3701 } 3702 3703 found: 3704 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3705 3706 return err; 3707} 3708 3709static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs, 3710 struct v4l2_control *control) 3711{ 3712 unsigned long flags; 3713 int i; 3714 int err = 0; 3715 3716 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3717 3718 switch (vcs->input) { 3719 case VINO_INPUT_D1: { 3720 struct indycam_control indycam_ctrl; 3721 3722 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3723 if (vino_indycam_v4l2_controls[i].id == 3724 control->id) { 3725 goto found1; 3726 } 3727 } 3728 3729 err = -EINVAL; 3730 goto out; 3731 3732found1: 3733 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; 3734 3735 err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL, 3736 &indycam_ctrl); 3737 if (err) { 3738 err = -EINVAL; 3739 goto out; 3740 } 3741 3742 control->value = indycam_ctrl.value; 3743 break; 3744 } 3745 case VINO_INPUT_COMPOSITE: 3746 case VINO_INPUT_SVIDEO: { 3747 struct saa7191_control saa7191_ctrl; 3748 3749 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 3750 if (vino_saa7191_v4l2_controls[i].id == 3751 control->id) { 3752 goto found2; 3753 } 3754 } 3755 3756 err = -EINVAL; 3757 goto out; 3758 3759found2: 3760 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; 3761 3762 err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL, 3763 &saa7191_ctrl); 3764 if (err) { 3765 err = -EINVAL; 3766 goto out; 3767 } 3768 3769 control->value = saa7191_ctrl.value; 3770 break; 3771 } 3772 default: 3773 err = -EINVAL; 3774 } 3775 3776out: 3777 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3778 3779 return err; 3780} 3781 3782static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, 3783 struct v4l2_control *control) 3784{ 3785 unsigned long flags; 3786 int i; 3787 int err = 0; 3788 3789 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3790 3791 if (!vino_is_input_owner(vcs)) { 3792 err = -EBUSY; 3793 goto out; 3794 } 3795 3796 switch (vcs->input) { 3797 case VINO_INPUT_D1: { 3798 struct indycam_control indycam_ctrl; 3799 3800 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3801 if (vino_indycam_v4l2_controls[i].id == 3802 control->id) { 3803 if ((control->value >= 3804 vino_indycam_v4l2_controls[i].minimum) 3805 && (control->value <= 3806 vino_indycam_v4l2_controls[i]. 3807 maximum)) { 3808 goto found1; 3809 } else { 3810 err = -ERANGE; 3811 goto out; 3812 } 3813 } 3814 } 3815 3816 err = -EINVAL; 3817 goto out; 3818 3819found1: 3820 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; 3821 indycam_ctrl.value = control->value; 3822 3823 err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL, 3824 &indycam_ctrl); 3825 if (err) 3826 err = -EINVAL; 3827 break; 3828 } 3829 case VINO_INPUT_COMPOSITE: 3830 case VINO_INPUT_SVIDEO: { 3831 struct saa7191_control saa7191_ctrl; 3832 3833 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 3834 if (vino_saa7191_v4l2_controls[i].id == 3835 control->id) { 3836 if ((control->value >= 3837 vino_saa7191_v4l2_controls[i].minimum) 3838 && (control->value <= 3839 vino_saa7191_v4l2_controls[i]. 3840 maximum)) { 3841 goto found2; 3842 } else { 3843 err = -ERANGE; 3844 goto out; 3845 } 3846 } 3847 } 3848 err = -EINVAL; 3849 goto out; 3850 3851found2: 3852 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; 3853 saa7191_ctrl.value = control->value; 3854 3855 err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL, 3856 &saa7191_ctrl); 3857 if (err) 3858 err = -EINVAL; 3859 break; 3860 } 3861 default: 3862 err = -EINVAL; 3863 } 3864 3865out: 3866 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3867 3868 return err; 3869} 3870 3871/* File operations */ 3872 3873static int vino_open(struct inode *inode, struct file *file) 3874{ 3875 struct video_device *dev = video_devdata(file); 3876 struct vino_channel_settings *vcs = video_get_drvdata(dev); 3877 int ret = 0; 3878 dprintk("open(): channel = %c\n", 3879 (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); 3880 3881 mutex_lock(&vcs->mutex); 3882 3883 if (vcs->users) { 3884 dprintk("open(): driver busy\n"); 3885 ret = -EBUSY; 3886 goto out; 3887 } 3888 3889 ret = vino_acquire_input(vcs); 3890 if (ret) { 3891 dprintk("open(): vino_acquire_input() failed\n"); 3892 goto out; 3893 } 3894 3895 vcs->users++; 3896 3897 out: 3898 mutex_unlock(&vcs->mutex); 3899 3900 dprintk("open(): %s!\n", ret ? "failed" : "complete"); 3901 3902 return ret; 3903} 3904 3905static int vino_close(struct inode *inode, struct file *file) 3906{ 3907 struct video_device *dev = video_devdata(file); 3908 struct vino_channel_settings *vcs = video_get_drvdata(dev); 3909 dprintk("close():\n"); 3910 3911 mutex_lock(&vcs->mutex); 3912 3913 vcs->users--; 3914 3915 if (!vcs->users) { 3916 vino_release_input(vcs); 3917 3918 /* stop DMA and free buffers */ 3919 vino_capture_stop(vcs); 3920 vino_queue_free(&vcs->fb_queue); 3921 } 3922 3923 mutex_unlock(&vcs->mutex); 3924 3925 return 0; 3926} 3927 3928static void vino_vm_open(struct vm_area_struct *vma) 3929{ 3930 struct vino_framebuffer *fb = vma->vm_private_data; 3931 3932 fb->map_count++; 3933 dprintk("vino_vm_open(): count = %d\n", fb->map_count); 3934} 3935 3936static void vino_vm_close(struct vm_area_struct *vma) 3937{ 3938 struct vino_framebuffer *fb = vma->vm_private_data; 3939 3940 fb->map_count--; 3941 dprintk("vino_vm_close(): count = %d\n", fb->map_count); 3942} 3943 3944static struct vm_operations_struct vino_vm_ops = { 3945 .open = vino_vm_open, 3946 .close = vino_vm_close, 3947}; 3948 3949static int vino_mmap(struct file *file, struct vm_area_struct *vma) 3950{ 3951 struct video_device *dev = video_devdata(file); 3952 struct vino_channel_settings *vcs = video_get_drvdata(dev); 3953 3954 unsigned long start = vma->vm_start; 3955 unsigned long size = vma->vm_end - vma->vm_start; 3956 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 3957 3958 struct vino_framebuffer *fb = NULL; 3959 unsigned int i, length; 3960 int ret = 0; 3961 3962 dprintk("mmap():\n"); 3963 3964 // TODO: reject mmap if already mapped 3965 3966 if (mutex_lock_interruptible(&vcs->mutex)) 3967 return -EINTR; 3968 3969 if (vcs->reading) { 3970 ret = -EBUSY; 3971 goto out; 3972 } 3973 3974 // TODO: check queue type 3975 3976 if (!(vma->vm_flags & VM_WRITE)) { 3977 dprintk("mmap(): app bug: PROT_WRITE please\n"); 3978 ret = -EINVAL; 3979 goto out; 3980 } 3981 if (!(vma->vm_flags & VM_SHARED)) { 3982 dprintk("mmap(): app bug: MAP_SHARED please\n"); 3983 ret = -EINVAL; 3984 goto out; 3985 } 3986 3987 /* find the correct buffer using offset */ 3988 length = vino_queue_get_length(&vcs->fb_queue); 3989 if (length == 0) { 3990 dprintk("mmap(): queue not initialized\n"); 3991 ret = -EINVAL; 3992 goto out; 3993 } 3994 3995 for (i = 0; i < length; i++) { 3996 fb = vino_queue_get_buffer(&vcs->fb_queue, i); 3997 if (fb == NULL) { 3998 dprintk("mmap(): vino_queue_get_buffer() failed\n"); 3999 ret = -EINVAL; 4000 goto out; 4001 } 4002 4003 if (fb->offset == offset) 4004 goto found; 4005 } 4006 4007 dprintk("mmap(): invalid offset = %lu\n", offset); 4008 ret = -EINVAL; 4009 goto out; 4010 4011found: 4012 dprintk("mmap(): buffer = %d\n", i); 4013 4014 if (size > (fb->desc_table.page_count * PAGE_SIZE)) { 4015 dprintk("mmap(): failed: size = %lu > %lu\n", 4016 size, fb->desc_table.page_count * PAGE_SIZE); 4017 ret = -EINVAL; 4018 goto out; 4019 } 4020 4021 for (i = 0; i < fb->desc_table.page_count; i++) { 4022 unsigned long pfn = 4023 virt_to_phys((void *)fb->desc_table.virtual[i]) >> 4024 PAGE_SHIFT; 4025 4026 if (size < PAGE_SIZE) 4027 break; 4028 4029 // protection was: PAGE_READONLY 4030 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, 4031 vma->vm_page_prot)) { 4032 dprintk("mmap(): remap_pfn_range() failed\n"); 4033 ret = -EAGAIN; 4034 goto out; 4035 } 4036 4037 start += PAGE_SIZE; 4038 size -= PAGE_SIZE; 4039 } 4040 4041 fb->map_count = 1; 4042 4043 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; 4044 vma->vm_flags &= ~VM_IO; 4045 vma->vm_private_data = fb; 4046 vma->vm_file = file; 4047 vma->vm_ops = &vino_vm_ops; 4048 4049out: 4050 mutex_unlock(&vcs->mutex); 4051 4052 return ret; 4053} 4054 4055static unsigned int vino_poll(struct file *file, poll_table *pt) 4056{ 4057 struct video_device *dev = video_devdata(file); 4058 struct vino_channel_settings *vcs = video_get_drvdata(dev); 4059 unsigned int outgoing; 4060 unsigned int ret = 0; 4061 4062 // lock mutex (?) 4063 // TODO: this has to be corrected for different read modes 4064 4065 dprintk("poll():\n"); 4066 4067 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { 4068 dprintk("poll(): vino_queue_get_outgoing() failed\n"); 4069 ret = POLLERR; 4070 goto error; 4071 } 4072 if (outgoing > 0) 4073 goto over; 4074 4075 poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt); 4076 4077 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { 4078 dprintk("poll(): vino_queue_get_outgoing() failed\n"); 4079 ret = POLLERR; 4080 goto error; 4081 } 4082 4083over: 4084 dprintk("poll(): data %savailable\n", 4085 (outgoing > 0) ? "" : "not "); 4086 4087 if (outgoing > 0) 4088 ret = POLLIN | POLLRDNORM; 4089 4090error: 4091 4092 return ret; 4093} 4094 4095static int vino_do_ioctl(struct inode *inode, struct file *file, 4096 unsigned int cmd, void *arg) 4097{ 4098 struct video_device *dev = video_devdata(file); 4099 struct vino_channel_settings *vcs = video_get_drvdata(dev); 4100 4101#ifdef VINO_DEBUG 4102 switch (_IOC_TYPE(cmd)) { 4103 case 'v': 4104 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd); 4105 break; 4106 case 'V': 4107 dprintk("ioctl(): V4L2 %s (0x%08x)\n", 4108 v4l2_ioctl_names[_IOC_NR(cmd)], cmd); 4109 break; 4110 default: 4111 dprintk("ioctl(): unsupported command 0x%08x\n", cmd); 4112 } 4113#endif 4114 4115 switch (cmd) { 4116 /* V4L2 interface */ 4117 case VIDIOC_QUERYCAP: { 4118 vino_v4l2_querycap(arg); 4119 break; 4120 } 4121 case VIDIOC_ENUMINPUT: { 4122 return vino_v4l2_enuminput(vcs, arg); 4123 } 4124 case VIDIOC_G_INPUT: { 4125 return vino_v4l2_g_input(vcs, arg); 4126 } 4127 case VIDIOC_S_INPUT: { 4128 return vino_v4l2_s_input(vcs, arg); 4129 } 4130 case VIDIOC_ENUMSTD: { 4131 return vino_v4l2_enumstd(vcs, arg); 4132 } 4133 case VIDIOC_QUERYSTD: { 4134 return vino_v4l2_querystd(vcs, arg); 4135 } 4136 case VIDIOC_G_STD: { 4137 return vino_v4l2_g_std(vcs, arg); 4138 } 4139 case VIDIOC_S_STD: { 4140 return vino_v4l2_s_std(vcs, arg); 4141 } 4142 case VIDIOC_ENUM_FMT: { 4143 return vino_v4l2_enum_fmt(vcs, arg); 4144 } 4145 case VIDIOC_TRY_FMT: { 4146 return vino_v4l2_try_fmt(vcs, arg); 4147 } 4148 case VIDIOC_G_FMT: { 4149 return vino_v4l2_g_fmt(vcs, arg); 4150 } 4151 case VIDIOC_S_FMT: { 4152 return vino_v4l2_s_fmt(vcs, arg); 4153 } 4154 case VIDIOC_CROPCAP: { 4155 return vino_v4l2_cropcap(vcs, arg); 4156 } 4157 case VIDIOC_G_CROP: { 4158 return vino_v4l2_g_crop(vcs, arg); 4159 } 4160 case VIDIOC_S_CROP: { 4161 return vino_v4l2_s_crop(vcs, arg); 4162 } 4163 case VIDIOC_G_PARM: { 4164 return vino_v4l2_g_parm(vcs, arg); 4165 } 4166 case VIDIOC_S_PARM: { 4167 return vino_v4l2_s_parm(vcs, arg); 4168 } 4169 case VIDIOC_REQBUFS: { 4170 return vino_v4l2_reqbufs(vcs, arg); 4171 } 4172 case VIDIOC_QUERYBUF: { 4173 return vino_v4l2_querybuf(vcs, arg); 4174 } 4175 case VIDIOC_QBUF: { 4176 return vino_v4l2_qbuf(vcs, arg); 4177 } 4178 case VIDIOC_DQBUF: { 4179 return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK); 4180 } 4181 case VIDIOC_STREAMON: { 4182 return vino_v4l2_streamon(vcs); 4183 } 4184 case VIDIOC_STREAMOFF: { 4185 return vino_v4l2_streamoff(vcs); 4186 } 4187 case VIDIOC_QUERYCTRL: { 4188 return vino_v4l2_queryctrl(vcs, arg); 4189 } 4190 case VIDIOC_G_CTRL: { 4191 return vino_v4l2_g_ctrl(vcs, arg); 4192 } 4193 case VIDIOC_S_CTRL: { 4194 return vino_v4l2_s_ctrl(vcs, arg); 4195 } 4196 default: 4197 return -ENOIOCTLCMD; 4198 } 4199 4200 return 0; 4201} 4202 4203static int vino_ioctl(struct inode *inode, struct file *file, 4204 unsigned int cmd, unsigned long arg) 4205{ 4206 struct video_device *dev = video_devdata(file); 4207 struct vino_channel_settings *vcs = video_get_drvdata(dev); 4208 int ret; 4209 4210 if (mutex_lock_interruptible(&vcs->mutex)) 4211 return -EINTR; 4212 4213 ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); 4214 4215 mutex_unlock(&vcs->mutex); 4216 4217 return ret; 4218} 4219 4220/* Initialization and cleanup */ 4221 4222// __initdata 4223static int vino_init_stage = 0; 4224 4225static const struct file_operations vino_fops = { 4226 .owner = THIS_MODULE, 4227 .open = vino_open, 4228 .release = vino_close, 4229 .ioctl = vino_ioctl, 4230 .mmap = vino_mmap, 4231 .poll = vino_poll, 4232 .llseek = no_llseek, 4233}; 4234 4235static struct video_device v4l_device_template = { 4236 .name = "NOT SET", 4237 //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | 4238 // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY 4239 .fops = &vino_fops, 4240 .minor = -1, 4241}; 4242 4243static void vino_module_cleanup(int stage) 4244{ 4245 switch(stage) { 4246 case 10: 4247 video_unregister_device(vino_drvdata->b.v4l_device); 4248 vino_drvdata->b.v4l_device = NULL; 4249 case 9: 4250 video_unregister_device(vino_drvdata->a.v4l_device); 4251 vino_drvdata->a.v4l_device = NULL; 4252 case 8: 4253 vino_i2c_del_bus(); 4254 case 7: 4255 free_irq(SGI_VINO_IRQ, NULL); 4256 case 6: 4257 if (vino_drvdata->b.v4l_device) { 4258 video_device_release(vino_drvdata->b.v4l_device); 4259 vino_drvdata->b.v4l_device = NULL; 4260 } 4261 case 5: 4262 if (vino_drvdata->a.v4l_device) { 4263 video_device_release(vino_drvdata->a.v4l_device); 4264 vino_drvdata->a.v4l_device = NULL; 4265 } 4266 case 4: 4267 /* all entries in dma_cpu dummy table have the same address */ 4268 dma_unmap_single(NULL, 4269 vino_drvdata->dummy_desc_table.dma_cpu[0], 4270 PAGE_SIZE, DMA_FROM_DEVICE); 4271 dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT 4272 * sizeof(dma_addr_t), 4273 (void *)vino_drvdata-> 4274 dummy_desc_table.dma_cpu, 4275 vino_drvdata->dummy_desc_table.dma); 4276 case 3: 4277 free_page(vino_drvdata->dummy_page); 4278 case 2: 4279 kfree(vino_drvdata); 4280 case 1: 4281 iounmap(vino); 4282 case 0: 4283 break; 4284 default: 4285 dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n", 4286 stage); 4287 } 4288} 4289 4290static int vino_probe(void) 4291{ 4292 unsigned long rev_id; 4293 4294 if (ip22_is_fullhouse()) { 4295 printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n"); 4296 return -ENODEV; 4297 } 4298 4299 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { 4300 printk(KERN_ERR "VINO is not found (EISA BUS not present)\n"); 4301 return -ENODEV; 4302 } 4303 4304 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); 4305 if (!vino) { 4306 printk(KERN_ERR "VINO: ioremap() failed\n"); 4307 return -EIO; 4308 } 4309 vino_init_stage++; 4310 4311 if (get_dbe(rev_id, &(vino->rev_id))) { 4312 printk(KERN_ERR "Failed to read VINO revision register\n"); 4313 vino_module_cleanup(vino_init_stage); 4314 return -ENODEV; 4315 } 4316 4317 if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) { 4318 printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n", 4319 rev_id); 4320 vino_module_cleanup(vino_init_stage); 4321 return -ENODEV; 4322 } 4323 4324 printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id)); 4325 4326 return 0; 4327} 4328 4329static int vino_init(void) 4330{ 4331 dma_addr_t dma_dummy_address; 4332 int i; 4333 4334 vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL); 4335 if (!vino_drvdata) { 4336 vino_module_cleanup(vino_init_stage); 4337 return -ENOMEM; 4338 } 4339 vino_init_stage++; 4340 4341 /* create a dummy dma descriptor */ 4342 vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); 4343 if (!vino_drvdata->dummy_page) { 4344 vino_module_cleanup(vino_init_stage); 4345 return -ENOMEM; 4346 } 4347 vino_init_stage++; 4348 4349 // TODO: use page_count in dummy_desc_table 4350 4351 vino_drvdata->dummy_desc_table.dma_cpu = 4352 dma_alloc_coherent(NULL, 4353 VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t), 4354 &vino_drvdata->dummy_desc_table.dma, 4355 GFP_KERNEL | GFP_DMA); 4356 if (!vino_drvdata->dummy_desc_table.dma_cpu) { 4357 vino_module_cleanup(vino_init_stage); 4358 return -ENOMEM; 4359 } 4360 vino_init_stage++; 4361 4362 dma_dummy_address = dma_map_single(NULL, 4363 (void *)vino_drvdata->dummy_page, 4364 PAGE_SIZE, DMA_FROM_DEVICE); 4365 for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) { 4366 vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address; 4367 } 4368 4369 /* initialize VINO */ 4370 4371 vino->control = 0; 4372 vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma; 4373 vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma; 4374 udelay(VINO_DESC_FETCH_DELAY); 4375 4376 vino->intr_status = 0; 4377 4378 vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT; 4379 vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT; 4380 4381 return 0; 4382} 4383 4384static int vino_init_channel_settings(struct vino_channel_settings *vcs, 4385 unsigned int channel, const char *name) 4386{ 4387 vcs->channel = channel; 4388 vcs->input = VINO_INPUT_NONE; 4389 vcs->alpha = 0; 4390 vcs->users = 0; 4391 vcs->data_format = VINO_DATA_FMT_GREY; 4392 vcs->data_norm = VINO_DATA_NORM_NTSC; 4393 vcs->decimation = 1; 4394 vino_set_default_clipping(vcs); 4395 vino_set_default_framerate(vcs); 4396 4397 vcs->capturing = 0; 4398 4399 mutex_init(&vcs->mutex); 4400 spin_lock_init(&vcs->capture_lock); 4401 4402 mutex_init(&vcs->fb_queue.queue_mutex); 4403 spin_lock_init(&vcs->fb_queue.queue_lock); 4404 init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); 4405 4406 vcs->v4l_device = video_device_alloc(); 4407 if (!vcs->v4l_device) { 4408 vino_module_cleanup(vino_init_stage); 4409 return -ENOMEM; 4410 } 4411 vino_init_stage++; 4412 4413 memcpy(vcs->v4l_device, &v4l_device_template, 4414 sizeof(struct video_device)); 4415 strcpy(vcs->v4l_device->name, name); 4416 vcs->v4l_device->release = video_device_release; 4417 4418 video_set_drvdata(vcs->v4l_device, vcs); 4419 4420 return 0; 4421} 4422 4423static int __init vino_module_init(void) 4424{ 4425 int ret; 4426 4427 printk(KERN_INFO "SGI VINO driver version %s\n", 4428 VINO_MODULE_VERSION); 4429 4430 ret = vino_probe(); 4431 if (ret) 4432 return ret; 4433 4434 ret = vino_init(); 4435 if (ret) 4436 return ret; 4437 4438 /* initialize data structures */ 4439 4440 spin_lock_init(&vino_drvdata->vino_lock); 4441 spin_lock_init(&vino_drvdata->input_lock); 4442 4443 ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A, 4444 vino_v4l_device_name_a); 4445 if (ret) 4446 return ret; 4447 4448 ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B, 4449 vino_v4l_device_name_b); 4450 if (ret) 4451 return ret; 4452 4453 /* initialize hardware and register V4L devices */ 4454 4455 ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0, 4456 vino_driver_description, NULL); 4457 if (ret) { 4458 printk(KERN_ERR "VINO: requesting IRQ %02d failed\n", 4459 SGI_VINO_IRQ); 4460 vino_module_cleanup(vino_init_stage); 4461 return -EAGAIN; 4462 } 4463 vino_init_stage++; 4464 4465 ret = vino_i2c_add_bus(); 4466 if (ret) { 4467 printk(KERN_ERR "VINO I2C bus registration failed\n"); 4468 vino_module_cleanup(vino_init_stage); 4469 return ret; 4470 } 4471 vino_init_stage++; 4472 4473 ret = video_register_device(vino_drvdata->a.v4l_device, 4474 VFL_TYPE_GRABBER, -1); 4475 if (ret < 0) { 4476 printk(KERN_ERR "VINO channel A Video4Linux-device " 4477 "registration failed\n"); 4478 vino_module_cleanup(vino_init_stage); 4479 return -EINVAL; 4480 } 4481 vino_init_stage++; 4482 4483 ret = video_register_device(vino_drvdata->b.v4l_device, 4484 VFL_TYPE_GRABBER, -1); 4485 if (ret < 0) { 4486 printk(KERN_ERR "VINO channel B Video4Linux-device " 4487 "registration failed\n"); 4488 vino_module_cleanup(vino_init_stage); 4489 return -EINVAL; 4490 } 4491 vino_init_stage++; 4492 4493#if defined(CONFIG_KMOD) && defined(MODULE) 4494 request_module("saa7191"); 4495 request_module("indycam"); 4496#endif 4497 4498 dprintk("init complete!\n"); 4499 4500 return 0; 4501} 4502 4503static void __exit vino_module_exit(void) 4504{ 4505 dprintk("exiting, stage = %d ...\n", vino_init_stage); 4506 vino_module_cleanup(vino_init_stage); 4507 dprintk("cleanup complete, exit!\n"); 4508} 4509 4510module_init(vino_module_init); 4511module_exit(vino_module_exit); 4512