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