1/****************************************************************************** 2* * 3* easycap_ioctl.c * 4* * 5******************************************************************************/ 6/* 7 * 8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org> 9 * 10 * 11 * This is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * The software is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this software; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * 25*/ 26/*****************************************************************************/ 27 28#include <linux/smp_lock.h> 29#include "easycap.h" 30#include "easycap_debug.h" 31#include "easycap_standard.h" 32#include "easycap_ioctl.h" 33 34/*--------------------------------------------------------------------------*/ 35/* 36 * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE 37 * FOLLOWING: 38 * peasycap->standard_offset 39 * peasycap->fps 40 * peasycap->usec 41 * peasycap->tolerate 42 */ 43/*---------------------------------------------------------------------------*/ 44int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) 45{ 46struct easycap_standard const *peasycap_standard; 47__u16 reg, set; 48int ir, rc, need; 49unsigned int itwas, isnow; 50 51if ((struct usb_device *)NULL == peasycap->pusb_device) { 52 SAY("ERROR: peasycap->pusb_device is NULL\n"); 53 return -EFAULT; 54} 55peasycap_standard = &easycap_standard[0]; 56while (0xFFFF != peasycap_standard->mask) { 57 if (std_id & peasycap_standard->v4l2_standard.id) 58 break; 59 peasycap_standard++; 60} 61if (0xFFFF == peasycap_standard->mask) { 62 SAY("ERROR: 0x%08X=std_id: standard not found\n", \ 63 (unsigned int)std_id); 64 return -EINVAL; 65} 66SAY("user requests standard: %s\n", \ 67 &(peasycap_standard->v4l2_standard.name[0])); 68if (peasycap->standard_offset == \ 69 (int)(peasycap_standard - &easycap_standard[0])) { 70 SAY("requested standard already in effect\n"); 71 return 0; 72} 73peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); 74peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ 75 peasycap_standard->v4l2_standard.frameperiod.numerator; 76if (!peasycap->fps) { 77 SAY("MISTAKE: frames-per-second is zero\n"); 78 return -EFAULT; 79} 80JOT(8, "%i frames-per-second\n", peasycap->fps); 81peasycap->usec = 1000000 / (2 * peasycap->fps); 82peasycap->tolerate = 1000 * (25 / peasycap->fps); 83 84kill_video_urbs(peasycap); 85 86/*--------------------------------------------------------------------------*/ 87/* 88 * SAA7113H DATASHEET PAGE 44, TABLE 42 89 */ 90/*--------------------------------------------------------------------------*/ 91need = 0; itwas = 0; reg = 0x00; set = 0x00; 92switch (peasycap_standard->mask & 0x000F) { 93case NTSC_M_JP: { 94 reg = 0x0A; set = 0x95; 95 ir = read_saa(peasycap->pusb_device, reg); 96 if (0 > ir) 97 SAY("ERROR: cannot read SAA register 0x%02X\n", reg); 98 else 99 itwas = (unsigned int)ir; 100 101 102 set2to78(peasycap->pusb_device); 103 104 105 rc = write_saa(peasycap->pusb_device, reg, set); 106 if (0 != rc) 107 SAY("ERROR: failed to set SAA register " \ 108 "0x%02X to 0x%02X for JP standard\n", reg, set); 109 else { 110 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 111 if (0 > ir) 112 JOT(8, "SAA register 0x%02X changed " \ 113 "to 0x%02X\n", reg, isnow); 114 else 115 JOT(8, "SAA register 0x%02X changed " \ 116 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 117 118 set2to78(peasycap->pusb_device); 119 120 } 121 122 reg = 0x0B; set = 0x48; 123 ir = read_saa(peasycap->pusb_device, reg); 124 if (0 > ir) 125 SAY("ERROR: cannot read SAA register 0x%02X\n", reg); 126 else 127 itwas = (unsigned int)ir; 128 129 set2to78(peasycap->pusb_device); 130 131 rc = write_saa(peasycap->pusb_device, reg, set); 132 if (0 != rc) 133 SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ 134 "for JP standard\n", reg, set); 135 else { 136 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 137 if (0 > ir) 138 JOT(8, "SAA register 0x%02X changed " \ 139 "to 0x%02X\n", reg, isnow); 140 else 141 JOT(8, "SAA register 0x%02X changed " \ 142 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 143 144 set2to78(peasycap->pusb_device); 145 146 } 147/*--------------------------------------------------------------------------*/ 148/* 149 * NOTE: NO break HERE: RUN ON TO NEXT CASE 150 */ 151/*--------------------------------------------------------------------------*/ 152} 153case NTSC_M: 154case PAL_BGHIN: { 155 reg = 0x0E; set = 0x01; need = 1; break; 156} 157case NTSC_N_443: 158case PAL_60: { 159 reg = 0x0E; set = 0x11; need = 1; break; 160} 161case NTSC_443: 162case PAL_Nc: { 163 reg = 0x0E; set = 0x21; need = 1; break; 164} 165case NTSC_N: 166case PAL_M: { 167 reg = 0x0E; set = 0x31; need = 1; break; 168} 169case SECAM: { 170 reg = 0x0E; set = 0x51; need = 1; break; 171} 172default: 173 break; 174} 175/*--------------------------------------------------------------------------*/ 176if (need) { 177 ir = read_saa(peasycap->pusb_device, reg); 178 if (0 > ir) 179 SAY("ERROR: failed to read SAA register 0x%02X\n", reg); 180 else 181 itwas = (unsigned int)ir; 182 183 set2to78(peasycap->pusb_device); 184 185 rc = write_saa(peasycap->pusb_device, reg, set); 186 if (0 != write_saa(peasycap->pusb_device, reg, set)) { 187 SAY("ERROR: failed to set SAA register " \ 188 "0x%02X to 0x%02X for table 42\n", reg, set); 189 } else { 190 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 191 if (0 > ir) 192 JOT(8, "SAA register 0x%02X changed " \ 193 "to 0x%02X\n", reg, isnow); 194 else 195 JOT(8, "SAA register 0x%02X changed " \ 196 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 197 } 198} 199/*--------------------------------------------------------------------------*/ 200/* 201 * SAA7113H DATASHEET PAGE 41 202 */ 203/*--------------------------------------------------------------------------*/ 204reg = 0x08; 205ir = read_saa(peasycap->pusb_device, reg); 206if (0 > ir) 207 SAY("ERROR: failed to read SAA register 0x%02X " \ 208 "so cannot reset\n", reg); 209else { 210 itwas = (unsigned int)ir; 211 if (peasycap_standard->mask & 0x0001) 212 set = itwas | 0x40 ; 213 else 214 set = itwas & ~0x40 ; 215 216set2to78(peasycap->pusb_device); 217 218rc = write_saa(peasycap->pusb_device, reg, set); 219if (0 != rc) 220 SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); 221else { 222 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 223 if (0 > ir) 224 JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); 225 else 226 JOT(8, "SAA register 0x%02X changed " \ 227 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 228 } 229} 230/*--------------------------------------------------------------------------*/ 231/* 232 * SAA7113H DATASHEET PAGE 51, TABLE 57 233 */ 234/*---------------------------------------------------------------------------*/ 235reg = 0x40; 236ir = read_saa(peasycap->pusb_device, reg); 237if (0 > ir) 238 SAY("ERROR: failed to read SAA register 0x%02X " \ 239 "so cannot reset\n", reg); 240else { 241 itwas = (unsigned int)ir; 242 if (peasycap_standard->mask & 0x0001) 243 set = itwas | 0x80 ; 244 else 245 set = itwas & ~0x80 ; 246 247set2to78(peasycap->pusb_device); 248 249rc = write_saa(peasycap->pusb_device, reg, set); 250if (0 != rc) 251 SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); 252else { 253 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 254 if (0 > ir) 255 JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); 256 else 257 JOT(8, "SAA register 0x%02X changed " \ 258 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 259 } 260} 261/*--------------------------------------------------------------------------*/ 262/* 263 * SAA7113H DATASHEET PAGE 53, TABLE 66 264 */ 265/*--------------------------------------------------------------------------*/ 266reg = 0x5A; 267ir = read_saa(peasycap->pusb_device, reg); 268if (0 > ir) 269 SAY("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); 270 itwas = (unsigned int)ir; 271 if (peasycap_standard->mask & 0x0001) 272 set = 0x0A ; 273 else 274 set = 0x07 ; 275 276 set2to78(peasycap->pusb_device); 277 278 if (0 != write_saa(peasycap->pusb_device, reg, set)) 279 SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ 280 reg, set); 281 else { 282 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); 283 if (0 > ir) 284 JOT(8, "SAA register 0x%02X changed " 285 "to 0x%02X\n", reg, isnow); 286 else 287 JOT(8, "SAA register 0x%02X changed " 288 "from 0x%02X to 0x%02X\n", reg, itwas, isnow); 289 } 290 if (0 != check_saa(peasycap->pusb_device)) 291 SAY("ERROR: check_saa() failed\n"); 292return 0; 293} 294/*****************************************************************************/ 295/*--------------------------------------------------------------------------*/ 296/* 297 * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL DEPENDS ON THE 298 * CURRENT VALUE OF peasycap->standard_offset. 299 * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN 300 * THIS ROUTINE UPDATES THE FOLLOWING: 301 * peasycap->format_offset 302 * peasycap->pixelformat 303 * peasycap->field 304 * peasycap->height 305 * peasycap->width 306 * peasycap->bytesperpixel 307 * peasycap->byteswaporder 308 * peasycap->decimatepixel 309 * peasycap->frame_buffer_used 310 * peasycap->videofieldamount 311 * peasycap->offerfields 312 * 313 * IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[] 314 * IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER. 315 * ERRORS RETURN A NEGATIVE NUMBER. 316 */ 317/*--------------------------------------------------------------------------*/ 318int adjust_format(struct easycap *peasycap, \ 319 __u32 width, __u32 height, __u32 pixelformat, int field, bool try) 320{ 321struct easycap_format *peasycap_format, *peasycap_best_format; 322__u16 mask; 323struct usb_device *p; 324int miss, multiplier, best; 325char bf[5], *pc; 326__u32 uc; 327 328if ((struct easycap *)NULL == peasycap) { 329 SAY("ERROR: peasycap is NULL\n"); 330 return -EFAULT; 331} 332p = peasycap->pusb_device; 333if ((struct usb_device *)NULL == p) { 334 SAY("ERROR: peaycap->pusb_device is NULL\n"); 335 return -EFAULT; 336} 337pc = &bf[0]; 338uc = pixelformat; memcpy((void *)pc, (void *)(&uc), 4); bf[4] = 0; 339mask = easycap_standard[peasycap->standard_offset].mask; 340SAY("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ 341 width, height, pc, pixelformat, field, mask); 342if (V4L2_FIELD_ANY == field) { 343 field = V4L2_FIELD_INTERLACED; 344 SAY("prefer: V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n"); 345} 346peasycap_best_format = (struct easycap_format *)NULL; 347peasycap_format = &easycap_format[0]; 348while (0 != peasycap_format->v4l2_format.fmt.pix.width) { 349 JOT(16, ".> %i %i 0x%08X %ix%i\n", \ 350 peasycap_format->mask & 0x01, 351 peasycap_format->v4l2_format.fmt.pix.field, 352 peasycap_format->v4l2_format.fmt.pix.pixelformat, 353 peasycap_format->v4l2_format.fmt.pix.width, 354 peasycap_format->v4l2_format.fmt.pix.height); 355 356 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ 357 (peasycap_format->v4l2_format.fmt.pix.field == field) && \ 358 (peasycap_format->v4l2_format.fmt.pix.pixelformat == \ 359 pixelformat) && \ 360 (peasycap_format->v4l2_format.fmt.pix.width == width) && \ 361 (peasycap_format->v4l2_format.fmt.pix.height == height)) { 362 peasycap_best_format = peasycap_format; 363 break; 364 } 365 peasycap_format++; 366} 367if (0 == peasycap_format->v4l2_format.fmt.pix.width) { 368 SAY("cannot do: %ix%i with standard mask 0x%02X\n", \ 369 width, height, mask); 370 peasycap_format = &easycap_format[0]; best = -1; 371 while (0 != peasycap_format->v4l2_format.fmt.pix.width) { 372 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ 373 (peasycap_format->v4l2_format.fmt.pix\ 374 .field == field) && \ 375 (peasycap_format->v4l2_format.fmt.pix\ 376 .pixelformat == pixelformat)) { 377 miss = abs(peasycap_format->\ 378 v4l2_format.fmt.pix.width - width); 379 if ((best > miss) || (best < 0)) { 380 best = miss; 381 peasycap_best_format = peasycap_format; 382 if (!miss) 383 break; 384 } 385 } 386 peasycap_format++; 387 } 388 if (-1 == best) { 389 SAY("cannot do %ix... with standard mask 0x%02X\n", \ 390 width, mask); 391 SAY("cannot do ...x%i with standard mask 0x%02X\n", \ 392 height, mask); 393 SAY(" %ix%i unmatched\n", width, height); 394 return peasycap->format_offset; 395 } 396} 397if ((struct easycap_format *)NULL == peasycap_best_format) { 398 SAY("MISTAKE: peasycap_best_format is NULL"); 399 return -EINVAL; 400} 401peasycap_format = peasycap_best_format; 402 403/*...........................................................................*/ 404if (true == try) 405 return (int)(peasycap_best_format - &easycap_format[0]); 406/*...........................................................................*/ 407 408if (false != try) { 409 SAY("MISTAKE: true==try where is should be false\n"); 410 return -EINVAL; 411} 412SAY("actioning: %ix%i %s\n", \ 413 peasycap_format->v4l2_format.fmt.pix.width, \ 414 peasycap_format->v4l2_format.fmt.pix.height, 415 &peasycap_format->name[0]); 416peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; 417peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; 418peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; 419peasycap->field = peasycap_format->v4l2_format.fmt.pix.field; 420peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); 421peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ; 422if (0x0100 & peasycap_format->mask) 423 peasycap->byteswaporder = true; 424else 425 peasycap->byteswaporder = false; 426if (0x0800 & peasycap_format->mask) 427 peasycap->decimatepixel = true; 428else 429 peasycap->decimatepixel = false; 430if (0x1000 & peasycap_format->mask) 431 peasycap->offerfields = true; 432else 433 peasycap->offerfields = false; 434if (true == peasycap->decimatepixel) 435 multiplier = 2; 436else 437 multiplier = 1; 438peasycap->videofieldamount = multiplier * peasycap->width * \ 439 multiplier * peasycap->height; 440peasycap->frame_buffer_used = peasycap->bytesperpixel * \ 441 peasycap->width * peasycap->height; 442 443if (true == peasycap->offerfields) { 444 SAY("WARNING: %i=peasycap->field is untested: " \ 445 "please report problems\n", peasycap->field); 446 447 448 449 450 451} 452 453kill_video_urbs(peasycap); 454 455/*---------------------------------------------------------------------------*/ 456/* 457 * PAL 458 */ 459/*---------------------------------------------------------------------------*/ 460if (0 == (0x01 & peasycap_format->mask)) { 461 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ 462 (576 == \ 463 peasycap_format->v4l2_format.fmt.pix.height)) || \ 464 ((360 == \ 465 peasycap_format->v4l2_format.fmt.pix.width) && \ 466 (288 == \ 467 peasycap_format->v4l2_format.fmt.pix.height))) { 468 if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { 469 SAY("ERROR: set_resolution() failed\n"); 470 return -EINVAL; 471 } 472 } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \ 473 (576 == peasycap_format->v4l2_format.fmt.pix.height)) { 474 if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { 475 SAY("ERROR: set_resolution() failed\n"); 476 return -EINVAL; 477 } 478 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ 479 (480 == \ 480 peasycap_format->v4l2_format.fmt.pix.height)) || \ 481 ((320 == \ 482 peasycap_format->v4l2_format.fmt.pix.width) && \ 483 (240 == \ 484 peasycap_format->v4l2_format.fmt.pix.height))) { 485 if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { 486 SAY("ERROR: set_resolution() failed\n"); 487 return -EINVAL; 488 } 489 } else { 490 SAY("MISTAKE: bad format, cannot set resolution\n"); 491 return -EINVAL; 492 } 493/*---------------------------------------------------------------------------*/ 494/* 495 * NTSC 496 */ 497/*---------------------------------------------------------------------------*/ 498} else { 499 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ 500 (480 == \ 501 peasycap_format->v4l2_format.fmt.pix.height)) || \ 502 ((360 == \ 503 peasycap_format->v4l2_format.fmt.pix.width) && \ 504 (240 == \ 505 peasycap_format->v4l2_format.fmt.pix.height))) { 506 if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { 507 SAY("ERROR: set_resolution() failed\n"); 508 return -EINVAL; 509 } 510 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ 511 (480 == \ 512 peasycap_format->v4l2_format.fmt.pix.height)) || \ 513 ((320 == \ 514 peasycap_format->v4l2_format.fmt.pix.width) && \ 515 (240 == \ 516 peasycap_format->v4l2_format.fmt.pix.height))) { 517 if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { 518 SAY("ERROR: set_resolution() failed\n"); 519 return -EINVAL; 520 } 521 } else { 522 SAY("MISTAKE: bad format, cannot set resolution\n"); 523 return -EINVAL; 524 } 525} 526/*---------------------------------------------------------------------------*/ 527 528check_stk(peasycap->pusb_device); 529 530return (int)(peasycap_best_format - &easycap_format[0]); 531} 532/*****************************************************************************/ 533int adjust_brightness(struct easycap *peasycap, int value) 534{ 535unsigned int mood; 536int i1; 537 538if ((struct usb_device *)NULL == peasycap->pusb_device) { 539 SAY("ERROR: peasycap->pusb_device is NULL\n"); 540 return -EFAULT; 541} 542i1 = 0; 543while (0xFFFFFFFF != easycap_control[i1].id) { 544 if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { 545 if ((easycap_control[i1].minimum > value) || \ 546 (easycap_control[i1].maximum < value)) 547 value = easycap_control[i1].default_value; 548 peasycap->brightness = value; 549 mood = 0x00FF & (unsigned int)peasycap->brightness; 550 551 set2to78(peasycap->pusb_device); 552 553 if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { 554 SAY("adjusting brightness to 0x%02X\n", mood); 555 return 0; 556 } else { 557 SAY("WARNING: failed to adjust brightness " \ 558 "to 0x%02X\n", mood); 559 return -ENOENT; 560 } 561 562 set2to78(peasycap->pusb_device); 563 564 break; 565 } 566 i1++; 567} 568SAY("WARNING: failed to adjust brightness: control not found\n"); 569return -ENOENT; 570} 571/*****************************************************************************/ 572int adjust_contrast(struct easycap *peasycap, int value) 573{ 574unsigned int mood; 575int i1; 576 577if ((struct usb_device *)NULL == peasycap->pusb_device) { 578 SAY("ERROR: peasycap->pusb_device is NULL\n"); 579 return -EFAULT; 580} 581i1 = 0; 582while (0xFFFFFFFF != easycap_control[i1].id) { 583 if (V4L2_CID_CONTRAST == easycap_control[i1].id) { 584 if ((easycap_control[i1].minimum > value) || \ 585 (easycap_control[i1].maximum < value)) 586 value = easycap_control[i1].default_value; 587 peasycap->contrast = value; 588 mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); 589 590 set2to78(peasycap->pusb_device); 591 592 if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { 593 SAY("adjusting contrast to 0x%02X\n", mood); 594 return 0; 595 } else { 596 SAY("WARNING: failed to adjust contrast to " \ 597 "0x%02X\n", mood); 598 return -ENOENT; 599 } 600 601 set2to78(peasycap->pusb_device); 602 603 break; 604 } 605 i1++; 606} 607SAY("WARNING: failed to adjust contrast: control not found\n"); 608return -ENOENT; 609} 610/*****************************************************************************/ 611int adjust_saturation(struct easycap *peasycap, int value) 612{ 613unsigned int mood; 614int i1; 615 616if ((struct usb_device *)NULL == peasycap->pusb_device) { 617 SAY("ERROR: peasycap->pusb_device is NULL\n"); 618 return -EFAULT; 619} 620i1 = 0; 621while (0xFFFFFFFF != easycap_control[i1].id) { 622 if (V4L2_CID_SATURATION == easycap_control[i1].id) { 623 if ((easycap_control[i1].minimum > value) || \ 624 (easycap_control[i1].maximum < value)) 625 value = easycap_control[i1].default_value; 626 peasycap->saturation = value; 627 mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); 628 629 set2to78(peasycap->pusb_device); 630 631 if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { 632 SAY("adjusting saturation to 0x%02X\n", mood); 633 return 0; 634 } else { 635 SAY("WARNING: failed to adjust saturation to " \ 636 "0x%02X\n", mood); 637 return -ENOENT; 638 } 639 break; 640 641 set2to78(peasycap->pusb_device); 642 643 } 644 i1++; 645} 646SAY("WARNING: failed to adjust saturation: control not found\n"); 647return -ENOENT; 648} 649/*****************************************************************************/ 650int adjust_hue(struct easycap *peasycap, int value) 651{ 652unsigned int mood; 653int i1, i2; 654 655if ((struct usb_device *)NULL == peasycap->pusb_device) { 656 SAY("ERROR: peasycap->pusb_device is NULL\n"); 657 return -EFAULT; 658} 659i1 = 0; 660while (0xFFFFFFFF != easycap_control[i1].id) { 661 if (V4L2_CID_HUE == easycap_control[i1].id) { 662 if ((easycap_control[i1].minimum > value) || \ 663 (easycap_control[i1].maximum < value)) 664 value = easycap_control[i1].default_value; 665 peasycap->hue = value; 666 i2 = peasycap->hue - 128; 667 mood = 0x00FF & ((int) i2); 668 669 set2to78(peasycap->pusb_device); 670 671 if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { 672 SAY("adjusting hue to 0x%02X\n", mood); 673 return 0; 674 } else { 675 SAY("WARNING: failed to adjust hue to 0x%02X\n", mood); 676 return -ENOENT; 677 } 678 679 set2to78(peasycap->pusb_device); 680 681 break; 682 } 683 i1++; 684} 685SAY("WARNING: failed to adjust hue: control not found\n"); 686return -ENOENT; 687} 688/*****************************************************************************/ 689int adjust_volume(struct easycap *peasycap, int value) 690{ 691__s8 mood; 692int i1; 693 694if ((struct usb_device *)NULL == peasycap->pusb_device) { 695 SAY("ERROR: peasycap->pusb_device is NULL\n"); 696 return -EFAULT; 697} 698i1 = 0; 699while (0xFFFFFFFF != easycap_control[i1].id) { 700 if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { 701 if ((easycap_control[i1].minimum > value) || \ 702 (easycap_control[i1].maximum < value)) 703 value = easycap_control[i1].default_value; 704 peasycap->volume = value; 705 mood = (16 > peasycap->volume) ? 16 : \ 706 ((31 < peasycap->volume) ? 31 : \ 707 (__s8) peasycap->volume); 708 if (!audio_gainset(peasycap->pusb_device, mood)) { 709 SAY("adjusting volume to 0x%01X\n", mood); 710 return 0; 711 } else { 712 SAY("WARNING: failed to adjust volume to " \ 713 "0x%1X\n", mood); 714 return -ENOENT; 715 } 716 break; 717 } 718i1++; 719} 720SAY("WARNING: failed to adjust volume: control not found\n"); 721return -ENOENT; 722} 723/*****************************************************************************/ 724/*---------------------------------------------------------------------------*/ 725/* 726 * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE: 727 * usb_set_interface(peasycap->pusb_device, \ 728 * peasycap->audio_interface, \ 729 * peasycap->audio_altsetting_off); 730 * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS 731 * -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT 732 * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE. 733 */ 734/*---------------------------------------------------------------------------*/ 735int adjust_mute(struct easycap *peasycap, int value) 736{ 737int i1; 738 739if ((struct usb_device *)NULL == peasycap->pusb_device) { 740 SAY("ERROR: peasycap->pusb_device is NULL\n"); 741 return -EFAULT; 742} 743i1 = 0; 744while (0xFFFFFFFF != easycap_control[i1].id) { 745 if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) { 746 peasycap->mute = value; 747 switch (peasycap->mute) { 748 case 1: { 749 peasycap->audio_idle = 1; 750 peasycap->timeval0.tv_sec = 0; 751 SAY("adjusting mute: %i=peasycap->audio_idle\n", \ 752 peasycap->audio_idle); 753 return 0; 754 } 755 default: { 756 peasycap->audio_idle = 0; 757 SAY("adjusting mute: %i=peasycap->audio_idle\n", \ 758 peasycap->audio_idle); 759 return 0; 760 } 761 } 762 break; 763 } 764 i1++; 765} 766SAY("WARNING: failed to adjust mute: control not found\n"); 767return -ENOENT; 768} 769 770/*--------------------------------------------------------------------------*/ 771static int easycap_ioctl_bkl(struct inode *inode, struct file *file, 772 unsigned int cmd, unsigned long arg) 773{ 774static struct easycap *peasycap; 775static struct usb_device *p; 776static __u32 isequence; 777 778peasycap = file->private_data; 779if (NULL == peasycap) { 780 SAY("ERROR: peasycap is NULL\n"); 781 return -1; 782} 783p = peasycap->pusb_device; 784if ((struct usb_device *)NULL == p) { 785 SAY("ERROR: peasycap->pusb_device is NULL\n"); 786 return -EFAULT; 787} 788/*---------------------------------------------------------------------------*/ 789/* 790 * MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO 791 * DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND: 792 * easycap_ioctl.c: warning: 793 * the frame size of ... bytes is larger than 1024 bytes 794 */ 795/*---------------------------------------------------------------------------*/ 796switch (cmd) { 797case VIDIOC_QUERYCAP: { 798 static struct v4l2_capability v4l2_capability; 799 static char version[16], *p1, *p2; 800 static int i, rc, k[3]; 801 static long lng; 802 803 JOT(8, "VIDIOC_QUERYCAP\n"); 804 805 if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { 806 SAY("ERROR: bad driver version string\n"); return -EINVAL; 807 } 808 strcpy(&version[0], EASYCAP_DRIVER_VERSION); 809 for (i = 0; i < 3; i++) 810 k[i] = 0; 811 p2 = &version[0]; i = 0; 812 while (*p2) { 813 p1 = p2; 814 while (*p2 && ('.' != *p2)) 815 p2++; 816 if (*p2) 817 *p2++ = 0; 818 if (3 > i) { 819 rc = (int) strict_strtol(p1, 10, &lng); 820 if (0 != rc) { 821 SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \ 822 rc, p1); 823 return -EINVAL; 824 } 825 k[i] = (int)lng; 826 } 827 i++; 828 } 829 830 memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); 831 strlcpy(&v4l2_capability.driver[0], "easycap", \ 832 sizeof(v4l2_capability.driver)); 833 834 v4l2_capability.capabilities = \ 835 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ 836 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE; 837 838 v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); 839 JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); 840 841 strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \ 842 sizeof(v4l2_capability.card)); 843 844 if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\ 845 sizeof(v4l2_capability.bus_info)) < 0) { 846 strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \ 847 sizeof(v4l2_capability.bus_info)); 848 JOT(8, "%s=v4l2_capability.bus_info\n", \ 849 &v4l2_capability.bus_info[0]); 850 } 851 if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ 852 sizeof(struct v4l2_capability))) { 853 POUT; 854 return -EFAULT; 855 } 856 break; 857} 858/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 859case VIDIOC_ENUMINPUT: { 860 static struct v4l2_input v4l2_input; 861 static __u32 index; 862 863 JOT(8, "VIDIOC_ENUMINPUT\n"); 864 865 if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ 866 sizeof(struct v4l2_input))) { 867 POUT; 868 return -EFAULT; 869 } 870 871 index = v4l2_input.index; 872 memset(&v4l2_input, 0, sizeof(struct v4l2_input)); 873 874 switch (index) { 875 case 0: { 876 v4l2_input.index = index; 877 strcpy(&v4l2_input.name[0], "CVBS0"); 878 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 879 v4l2_input.audioset = 0x01; 880 v4l2_input.tuner = 0; 881 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 882 V4L2_STD_NTSC ; 883 v4l2_input.status = 0; 884 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 885 break; 886 } 887 case 1: { 888 v4l2_input.index = index; 889 strcpy(&v4l2_input.name[0], "CVBS1"); 890 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 891 v4l2_input.audioset = 0x01; 892 v4l2_input.tuner = 0; 893 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 894 V4L2_STD_NTSC ; 895 v4l2_input.status = 0; 896 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 897 break; 898 } 899 case 2: { 900 v4l2_input.index = index; 901 strcpy(&v4l2_input.name[0], "CVBS2"); 902 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 903 v4l2_input.audioset = 0x01; 904 v4l2_input.tuner = 0; 905 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 906 V4L2_STD_NTSC ; 907 v4l2_input.status = 0; 908 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 909 break; 910 } 911 case 3: { 912 v4l2_input.index = index; 913 strcpy(&v4l2_input.name[0], "CVBS3"); 914 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 915 v4l2_input.audioset = 0x01; 916 v4l2_input.tuner = 0; 917 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 918 V4L2_STD_NTSC ; 919 v4l2_input.status = 0; 920 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 921 break; 922 } 923 case 4: { 924 v4l2_input.index = index; 925 strcpy(&v4l2_input.name[0], "CVBS4"); 926 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 927 v4l2_input.audioset = 0x01; 928 v4l2_input.tuner = 0; 929 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 930 V4L2_STD_NTSC ; 931 v4l2_input.status = 0; 932 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 933 break; 934 } 935 case 5: { 936 v4l2_input.index = index; 937 strcpy(&v4l2_input.name[0], "S-VIDEO"); 938 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; 939 v4l2_input.audioset = 0x01; 940 v4l2_input.tuner = 0; 941 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ 942 V4L2_STD_NTSC ; 943 v4l2_input.status = 0; 944 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); 945 break; 946 } 947 default: { 948 JOT(8, "%i=index: exhausts inputs\n", index); 949 return -EINVAL; 950 } 951 } 952 953 if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ 954 sizeof(struct v4l2_input))) { 955 POUT; 956 return -EFAULT; 957 } 958 break; 959} 960/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 961case VIDIOC_G_INPUT: { 962 static __u32 index; 963 964 JOT(8, "VIDIOC_G_INPUT\n"); 965 index = (__u32)peasycap->input; 966 JOT(8, "user is told: %i\n", index); 967 if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { 968 POUT; 969 return -EFAULT; 970 } 971 break; 972} 973/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 974case VIDIOC_S_INPUT: 975 { 976 static __u32 index; 977 978 JOT(8, "VIDIOC_S_INPUT\n"); 979 980 if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { 981 POUT; 982 return -EFAULT; 983 } 984 985 JOT(8, "user requests input %i\n", index); 986 987 if ((int)index == peasycap->input) { 988 SAY("requested input already in effect\n"); 989 break; 990 } 991 992 if ((0 > index) || (5 < index)) { 993 JOT(8, "ERROR: bad requested input: %i\n", index); 994 return -EINVAL; 995 } 996 peasycap->input = (int)index; 997 998 select_input(peasycap->pusb_device, peasycap->input, 9); 999 1000 break; 1001} 1002/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1003case VIDIOC_ENUMAUDIO: { 1004 JOT(8, "VIDIOC_ENUMAUDIO\n"); 1005 return -EINVAL; 1006} 1007/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1008case VIDIOC_ENUMAUDOUT: { 1009 static struct v4l2_audioout v4l2_audioout; 1010 1011 JOT(8, "VIDIOC_ENUMAUDOUT\n"); 1012 1013 if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ 1014 sizeof(struct v4l2_audioout))) { 1015 POUT; 1016 return -EFAULT; 1017 } 1018 1019 if (0 != v4l2_audioout.index) 1020 return -EINVAL; 1021 memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); 1022 v4l2_audioout.index = 0; 1023 strcpy(&v4l2_audioout.name[0], "Soundtrack"); 1024 1025 if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ 1026 sizeof(struct v4l2_audioout))) { 1027 POUT; 1028 return -EFAULT; 1029 } 1030 break; 1031} 1032/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1033case VIDIOC_QUERYCTRL: { 1034 static int i1; 1035 static struct v4l2_queryctrl v4l2_queryctrl; 1036 1037 JOT(8, "VIDIOC_QUERYCTRL\n"); 1038 1039 if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ 1040 sizeof(struct v4l2_queryctrl))) { 1041 POUT; 1042 return -EFAULT; 1043 } 1044 1045 i1 = 0; 1046 while (0xFFFFFFFF != easycap_control[i1].id) { 1047 if (easycap_control[i1].id == v4l2_queryctrl.id) { 1048 JOT(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \ 1049 ".name\n", &easycap_control[i1].name[0], i1); 1050 memcpy(&v4l2_queryctrl, &easycap_control[i1], \ 1051 sizeof(struct v4l2_queryctrl)); 1052 break; 1053 } 1054 i1++; 1055 } 1056 if (0xFFFFFFFF == easycap_control[i1].id) { 1057 JOT(8, "%i=index: exhausts controls\n", i1); 1058 return -EINVAL; 1059 } 1060 if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ 1061 sizeof(struct v4l2_queryctrl))) { 1062 POUT; 1063 return -EFAULT; 1064 } 1065 break; 1066} 1067/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1068case VIDIOC_QUERYMENU: { 1069 JOT(8, "VIDIOC_QUERYMENU unsupported\n"); 1070 return -EINVAL; 1071 break; 1072} 1073/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1074case VIDIOC_G_CTRL: { 1075 static struct v4l2_control v4l2_control; 1076 1077 JOT(8, "VIDIOC_G_CTRL\n"); 1078 1079 if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ 1080 sizeof(struct v4l2_control))) { 1081 POUT; 1082 return -EFAULT; 1083 } 1084 1085 switch (v4l2_control.id) { 1086 case V4L2_CID_BRIGHTNESS: { 1087 v4l2_control.value = peasycap->brightness; 1088 JOT(8, "user enquires brightness: %i\n", v4l2_control.value); 1089 break; 1090 } 1091 case V4L2_CID_CONTRAST: { 1092 v4l2_control.value = peasycap->contrast; 1093 JOT(8, "user enquires contrast: %i\n", v4l2_control.value); 1094 break; 1095 } 1096 case V4L2_CID_SATURATION: { 1097 v4l2_control.value = peasycap->saturation; 1098 JOT(8, "user enquires saturation: %i\n", v4l2_control.value); 1099 break; 1100 } 1101 case V4L2_CID_HUE: { 1102 v4l2_control.value = peasycap->hue; 1103 JOT(8, "user enquires hue: %i\n", v4l2_control.value); 1104 break; 1105 } 1106 case V4L2_CID_AUDIO_VOLUME: { 1107 v4l2_control.value = peasycap->volume; 1108 JOT(8, "user enquires volume: %i\n", v4l2_control.value); 1109 break; 1110 } 1111 case V4L2_CID_AUDIO_MUTE: { 1112 if (1 == peasycap->mute) 1113 v4l2_control.value = true; 1114 else 1115 v4l2_control.value = false; 1116 JOT(8, "user enquires mute: %i\n", v4l2_control.value); 1117 break; 1118 } 1119 default: { 1120 SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ 1121 v4l2_control.id); 1122 explain_cid(v4l2_control.id); 1123 return -EINVAL; 1124 } 1125 } 1126 if (0 != copy_to_user((void __user *)arg, &v4l2_control, \ 1127 sizeof(struct v4l2_control))) { 1128 POUT; 1129 return -EFAULT; 1130 } 1131 break; 1132} 1133/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1134#if defined(VIDIOC_S_CTRL_OLD) 1135case VIDIOC_S_CTRL_OLD: { 1136 JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); 1137} 1138#endif /*VIDIOC_S_CTRL_OLD*/ 1139case VIDIOC_S_CTRL: 1140 { 1141 static struct v4l2_control v4l2_control; 1142 1143 JOT(8, "VIDIOC_S_CTRL\n"); 1144 1145 if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ 1146 sizeof(struct v4l2_control))) { 1147 POUT; 1148 return -EFAULT; 1149 } 1150 1151 switch (v4l2_control.id) { 1152 case V4L2_CID_BRIGHTNESS: { 1153 JOT(8, "user requests brightness %i\n", v4l2_control.value); 1154 if (0 != adjust_brightness(peasycap, v4l2_control.value)) 1155 ; 1156 break; 1157 } 1158 case V4L2_CID_CONTRAST: { 1159 JOT(8, "user requests contrast %i\n", v4l2_control.value); 1160 if (0 != adjust_contrast(peasycap, v4l2_control.value)) 1161 ; 1162 break; 1163 } 1164 case V4L2_CID_SATURATION: { 1165 JOT(8, "user requests saturation %i\n", v4l2_control.value); 1166 if (0 != adjust_saturation(peasycap, v4l2_control.value)) 1167 ; 1168 break; 1169 } 1170 case V4L2_CID_HUE: { 1171 JOT(8, "user requests hue %i\n", v4l2_control.value); 1172 if (0 != adjust_hue(peasycap, v4l2_control.value)) 1173 ; 1174 break; 1175 } 1176 case V4L2_CID_AUDIO_VOLUME: { 1177 JOT(8, "user requests volume %i\n", v4l2_control.value); 1178 if (0 != adjust_volume(peasycap, v4l2_control.value)) 1179 ; 1180 break; 1181 } 1182 case V4L2_CID_AUDIO_MUTE: { 1183 int mute; 1184 1185 JOT(8, "user requests mute %i\n", v4l2_control.value); 1186 if (true == v4l2_control.value) 1187 mute = 1; 1188 else 1189 mute = 0; 1190 1191 if (0 != adjust_mute(peasycap, mute)) 1192 SAY("WARNING: failed to adjust mute to %i\n", mute); 1193 break; 1194 } 1195 default: { 1196 SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ 1197 v4l2_control.id); 1198 explain_cid(v4l2_control.id); 1199 return -EINVAL; 1200 } 1201 } 1202 break; 1203} 1204/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1205case VIDIOC_S_EXT_CTRLS: { 1206 JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); 1207 return -EINVAL; 1208} 1209/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1210case VIDIOC_ENUM_FMT: { 1211 static __u32 index; 1212 static struct v4l2_fmtdesc v4l2_fmtdesc; 1213 1214 JOT(8, "VIDIOC_ENUM_FMT\n"); 1215 1216 if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ 1217 sizeof(struct v4l2_fmtdesc))) { 1218 POUT; 1219 return -EFAULT; 1220 } 1221 1222 index = v4l2_fmtdesc.index; 1223 memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); 1224 1225 v4l2_fmtdesc.index = index; 1226 v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1227 1228 switch (index) { 1229 case 0: { 1230 v4l2_fmtdesc.flags = 0; 1231 strcpy(&v4l2_fmtdesc.description[0], "uyvy"); 1232 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; 1233 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1234 break; 1235 } 1236 case 1: { 1237 v4l2_fmtdesc.flags = 0; 1238 strcpy(&v4l2_fmtdesc.description[0], "yuy2"); 1239 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; 1240 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1241 break; 1242 } 1243 case 2: { 1244 v4l2_fmtdesc.flags = 0; 1245 strcpy(&v4l2_fmtdesc.description[0], "rgb24"); 1246 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; 1247 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1248 break; 1249 } 1250 case 3: { 1251 v4l2_fmtdesc.flags = 0; 1252 strcpy(&v4l2_fmtdesc.description[0], "rgb32"); 1253 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; 1254 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1255 break; 1256 } 1257 case 4: { 1258 v4l2_fmtdesc.flags = 0; 1259 strcpy(&v4l2_fmtdesc.description[0], "bgr24"); 1260 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; 1261 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1262 break; 1263 } 1264 case 5: { 1265 v4l2_fmtdesc.flags = 0; 1266 strcpy(&v4l2_fmtdesc.description[0], "bgr32"); 1267 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; 1268 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); 1269 break; 1270 } 1271 default: { 1272 JOT(8, "%i=index: exhausts formats\n", index); 1273 return -EINVAL; 1274 } 1275 } 1276 if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ 1277 sizeof(struct v4l2_fmtdesc))) { 1278 POUT; 1279 return -EFAULT; 1280 } 1281 break; 1282} 1283/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1284case VIDIOC_ENUM_FRAMESIZES: { 1285 JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n"); 1286 return -EINVAL; 1287} 1288case VIDIOC_ENUM_FRAMEINTERVALS: { 1289 JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n"); 1290 return -EINVAL; 1291} 1292/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1293case VIDIOC_G_FMT: { 1294 static struct v4l2_format v4l2_format; 1295 static struct v4l2_pix_format v4l2_pix_format; 1296 1297 JOT(8, "VIDIOC_G_FMT\n"); 1298 1299 if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ 1300 sizeof(struct v4l2_format))) { 1301 POUT; 1302 return -EFAULT; 1303 } 1304 1305 if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1306 POUT; 1307 return -EINVAL; 1308 } 1309 1310 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); 1311 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1312 memcpy(&(v4l2_format.fmt.pix), \ 1313 &(easycap_format[peasycap->format_offset]\ 1314 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); 1315 JOT(8, "user is told: %s\n", \ 1316 &easycap_format[peasycap->format_offset].name[0]); 1317 1318 if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ 1319 sizeof(struct v4l2_format))) { 1320 POUT; 1321 return -EFAULT; 1322 } 1323 break; 1324} 1325/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1326case VIDIOC_TRY_FMT: 1327case VIDIOC_S_FMT: { 1328 static struct v4l2_format v4l2_format; 1329 static struct v4l2_pix_format v4l2_pix_format; 1330 static bool try; 1331 static int best_format; 1332 1333 if (VIDIOC_TRY_FMT == cmd) { 1334 JOT(8, "VIDIOC_TRY_FMT\n"); 1335 try = true; 1336 } else { 1337 JOT(8, "VIDIOC_S_FMT\n"); 1338 try = false; 1339 } 1340 1341 if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ 1342 sizeof(struct v4l2_format))) { 1343 POUT; 1344 return -EFAULT; 1345 } 1346 1347 best_format = adjust_format(peasycap, \ 1348 v4l2_format.fmt.pix.width, \ 1349 v4l2_format.fmt.pix.height, \ 1350 v4l2_format.fmt.pix.pixelformat, \ 1351 v4l2_format.fmt.pix.field, \ 1352 try); 1353 if (0 > best_format) { 1354 JOT(8, "WARNING: adjust_format() returned %i\n", best_format); 1355 return -ENOENT; 1356 } 1357/*...........................................................................*/ 1358 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); 1359 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1360 1361 memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\ 1362 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); 1363 JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]); 1364 1365 if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ 1366 sizeof(struct v4l2_format))) { 1367 POUT; 1368 return -EFAULT; 1369 } 1370 break; 1371} 1372/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1373case VIDIOC_CROPCAP: { 1374 static struct v4l2_cropcap v4l2_cropcap; 1375 1376 JOT(8, "VIDIOC_CROPCAP\n"); 1377 1378 if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ 1379 sizeof(struct v4l2_cropcap))) { 1380 POUT; 1381 return -EFAULT; 1382 } 1383 1384 if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1385 JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); 1386 1387 memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); 1388 v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1389 v4l2_cropcap.bounds.left = 0; 1390 v4l2_cropcap.bounds.top = 0; 1391 v4l2_cropcap.bounds.width = peasycap->width; 1392 v4l2_cropcap.bounds.height = peasycap->height; 1393 v4l2_cropcap.defrect.left = 0; 1394 v4l2_cropcap.defrect.top = 0; 1395 v4l2_cropcap.defrect.width = peasycap->width; 1396 v4l2_cropcap.defrect.height = peasycap->height; 1397 v4l2_cropcap.pixelaspect.numerator = 1; 1398 v4l2_cropcap.pixelaspect.denominator = 1; 1399 1400 JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); 1401 1402 if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ 1403 sizeof(struct v4l2_cropcap))) { 1404 POUT; 1405 return -EFAULT; 1406 } 1407 break; 1408} 1409/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1410case VIDIOC_G_CROP: 1411case VIDIOC_S_CROP: { 1412 JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); 1413 return -EINVAL; 1414} 1415/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1416case VIDIOC_QUERYSTD: { 1417 JOT(8, "VIDIOC_QUERYSTD: " \ 1418 "EasyCAP is incapable of detecting standard\n"); 1419 return -EINVAL; 1420 break; 1421} 1422/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1423/*---------------------------------------------------------------------------*/ 1424/*---------------------------------------------------------------------------*/ 1425case VIDIOC_ENUMSTD: { 1426 static int last0 = -1, last1 = -1, last2 = -1, last3 = -1; 1427 static struct v4l2_standard v4l2_standard; 1428 static __u32 index; 1429 static struct easycap_standard const *peasycap_standard; 1430 1431 JOT(8, "VIDIOC_ENUMSTD\n"); 1432 1433 if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ 1434 sizeof(struct v4l2_standard))) { 1435 POUT; 1436 return -EFAULT; 1437 } 1438 index = v4l2_standard.index; 1439 1440 last3 = last2; last2 = last1; last1 = last0; last0 = index; 1441 if ((index == last3) && (index == last2) && \ 1442 (index == last1) && (index == last0)) { 1443 index++; 1444 last3 = last2; last2 = last1; last1 = last0; last0 = index; 1445 } 1446 1447 memset(&v4l2_standard, 0, sizeof(struct v4l2_standard)); 1448 1449 peasycap_standard = &easycap_standard[0]; 1450 while (0xFFFF != peasycap_standard->mask) { 1451 if ((int)(peasycap_standard - &easycap_standard[0]) == index) 1452 break; 1453 peasycap_standard++; 1454 } 1455 if (0xFFFF == peasycap_standard->mask) { 1456 JOT(8, "%i=index: exhausts standards\n", index); 1457 return -EINVAL; 1458 } 1459 JOT(8, "%i=index: %s\n", index, \ 1460 &(peasycap_standard->v4l2_standard.name[0])); 1461 memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \ 1462 sizeof(struct v4l2_standard)); 1463 1464 v4l2_standard.index = index; 1465 1466 if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ 1467 sizeof(struct v4l2_standard))) { 1468 POUT; 1469 return -EFAULT; 1470 } 1471 break; 1472} 1473/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1474case VIDIOC_G_STD: { 1475 static v4l2_std_id std_id; 1476 static struct easycap_standard const *peasycap_standard; 1477 1478 JOT(8, "VIDIOC_G_STD\n"); 1479 1480 if (0 != copy_from_user(&std_id, (void __user *)arg, \ 1481 sizeof(v4l2_std_id))) { 1482 POUT; 1483 return -EFAULT; 1484 } 1485 1486 peasycap_standard = &easycap_standard[peasycap->standard_offset]; 1487 std_id = peasycap_standard->v4l2_standard.id; 1488 1489 JOT(8, "user is told: %s\n", \ 1490 &peasycap_standard->v4l2_standard.name[0]); 1491 1492 if (0 != copy_to_user((void __user *)arg, &std_id, \ 1493 sizeof(v4l2_std_id))) { 1494 POUT; 1495 return -EFAULT; 1496 } 1497 break; 1498} 1499/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1500case VIDIOC_S_STD: { 1501 static v4l2_std_id std_id; 1502 static int rc; 1503 1504 JOT(8, "VIDIOC_S_STD\n"); 1505 1506 if (0 != copy_from_user(&std_id, (void __user *)arg, \ 1507 sizeof(v4l2_std_id))) { 1508 POUT; 1509 return -EFAULT; 1510 } 1511 1512 rc = adjust_standard(peasycap, std_id); 1513 if (0 > rc) { 1514 JOT(8, "WARNING: adjust_standard() returned %i\n", rc); 1515 return -ENOENT; 1516 } 1517 break; 1518} 1519/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1520case VIDIOC_REQBUFS: { 1521 static int nbuffers; 1522 static struct v4l2_requestbuffers v4l2_requestbuffers; 1523 1524 JOT(8, "VIDIOC_REQBUFS\n"); 1525 1526 if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ 1527 sizeof(struct v4l2_requestbuffers))) { 1528 POUT; 1529 return -EFAULT; 1530 } 1531 1532 if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1533 return -EINVAL; 1534 if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { 1535 POUT; 1536 return -EINVAL; 1537 } 1538 nbuffers = v4l2_requestbuffers.count; 1539 JOT(8, " User requests %i buffers ...\n", nbuffers); 1540 if (nbuffers < 2) 1541 nbuffers = 2; 1542 if (nbuffers > FRAME_BUFFER_MANY) 1543 nbuffers = FRAME_BUFFER_MANY; 1544 if (v4l2_requestbuffers.count == nbuffers) { 1545 JOT(8, " ... agree to %i buffers\n", \ 1546 nbuffers); 1547 } else { 1548 JOT(8, " ... insist on %i buffers\n", \ 1549 nbuffers); 1550 v4l2_requestbuffers.count = nbuffers; 1551 } 1552 peasycap->frame_buffer_many = nbuffers; 1553 1554 if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ 1555 sizeof(struct v4l2_requestbuffers))) { 1556 POUT; 1557 return -EFAULT; 1558 } 1559 break; 1560} 1561/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1562case VIDIOC_QUERYBUF: { 1563 static __u32 index; 1564 static struct v4l2_buffer v4l2_buffer; 1565 1566 JOT(8, "VIDIOC_QUERYBUF\n"); 1567 1568 if (peasycap->video_eof) { 1569 JOT(8, "returning -1 because %i=video_eof\n", \ 1570 peasycap->video_eof); 1571 return -1; 1572 } 1573 1574 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ 1575 sizeof(struct v4l2_buffer))) { 1576 POUT; 1577 return -EFAULT; 1578 } 1579 1580 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1581 return -EINVAL; 1582 index = v4l2_buffer.index; 1583 if (index < 0 || index >= peasycap->frame_buffer_many) 1584 return -EINVAL; 1585 memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer)); 1586 v4l2_buffer.index = index; 1587 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1588 v4l2_buffer.bytesused = peasycap->frame_buffer_used; 1589 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \ 1590 peasycap->done[index] | \ 1591 peasycap->queued[index]; 1592 v4l2_buffer.field = peasycap->field; 1593 v4l2_buffer.memory = V4L2_MEMORY_MMAP; 1594 v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; 1595 v4l2_buffer.length = FRAME_BUFFER_SIZE; 1596 1597 JOT(16, " %10i=index\n", v4l2_buffer.index); 1598 JOT(16, " 0x%08X=type\n", v4l2_buffer.type); 1599 JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused); 1600 JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags); 1601 JOT(16, " %10i=field\n", v4l2_buffer.field); 1602 JOT(16, " %10li=timestamp.tv_usec\n", \ 1603 (long)v4l2_buffer.timestamp.tv_usec); 1604 JOT(16, " %10i=sequence\n", v4l2_buffer.sequence); 1605 JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory); 1606 JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset); 1607 JOT(16, " %10i=length\n", v4l2_buffer.length); 1608 1609 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ 1610 sizeof(struct v4l2_buffer))) { 1611 POUT; 1612 return -EFAULT; 1613 } 1614 break; 1615} 1616/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1617case VIDIOC_QBUF: { 1618 static struct v4l2_buffer v4l2_buffer; 1619 1620 JOT(8, "VIDIOC_QBUF\n"); 1621 1622 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ 1623 sizeof(struct v4l2_buffer))) { 1624 POUT; 1625 return -EFAULT; 1626 } 1627 1628 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1629 return -EINVAL; 1630 if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) 1631 return -EINVAL; 1632 if (v4l2_buffer.index < 0 || \ 1633 (v4l2_buffer.index >= peasycap->frame_buffer_many)) 1634 return -EINVAL; 1635 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; 1636 1637 peasycap->done[v4l2_buffer.index] = 0; 1638 peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; 1639 1640 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ 1641 sizeof(struct v4l2_buffer))) { 1642 POUT; 1643 return -EFAULT; 1644 } 1645 1646 JOT(8, "..... user queueing frame buffer %i\n", \ 1647 (int)v4l2_buffer.index); 1648 1649 peasycap->frame_lock = 0; 1650 1651 break; 1652} 1653/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1654case VIDIOC_DQBUF: 1655 { 1656#if defined(AUDIOTIME) 1657 static struct signed_div_result sdr; 1658 static long long int above, below, dnbydt, fudge, sll; 1659 static unsigned long long int ull; 1660 static struct timeval timeval0; 1661 struct timeval timeval1; 1662#endif /*AUDIOTIME*/ 1663 static struct timeval timeval, timeval2; 1664 static int i, j; 1665 static struct v4l2_buffer v4l2_buffer; 1666 1667 JOT(8, "VIDIOC_DQBUF\n"); 1668 1669 if ((peasycap->video_idle) || (peasycap->video_eof)) { 1670 JOT(8, "returning -EIO because " \ 1671 "%i=video_idle %i=video_eof\n", \ 1672 peasycap->video_idle, peasycap->video_eof); 1673 return -EIO; 1674 } 1675 1676 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ 1677 sizeof(struct v4l2_buffer))) { 1678 POUT; 1679 return -EFAULT; 1680 } 1681 1682 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1683 return -EINVAL; 1684 1685 if (!peasycap->video_isoc_streaming) { 1686 JOT(16, "returning -EIO because video urbs not streaming\n"); 1687 return -EIO; 1688 } 1689/*---------------------------------------------------------------------------*/ 1690/* 1691 * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING 1692 * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS 1693 * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read 1694 */ 1695/*---------------------------------------------------------------------------*/ 1696 1697 if (!peasycap->polled) { 1698 if (-EIO == easycap_dqbuf(peasycap, 0)) 1699 return -EIO; 1700 } else { 1701 if (peasycap->video_eof) 1702 return -EIO; 1703 } 1704 if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { 1705 SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ 1706 peasycap->done[peasycap->frame_read]); 1707 } 1708 peasycap->polled = 0; 1709 1710 if (!(isequence % 10)) { 1711 for (i = 0; i < 179; i++) 1712 peasycap->merit[i] = peasycap->merit[i+1]; 1713 peasycap->merit[179] = merit_saa(peasycap->pusb_device); 1714 j = 0; 1715 for (i = 0; i < 180; i++) 1716 j += peasycap->merit[i]; 1717 if (90 < j) { 1718 SAY("easycap driver shutting down " \ 1719 "on condition blue\n"); 1720 peasycap->video_eof = 1; peasycap->audio_eof = 1; 1721 } 1722 } 1723 1724 v4l2_buffer.index = peasycap->frame_read; 1725 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1726 v4l2_buffer.bytesused = peasycap->frame_buffer_used; 1727 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; 1728 v4l2_buffer.field = peasycap->field; 1729 if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field) 1730 v4l2_buffer.field = \ 1731 0x000F & (peasycap->\ 1732 frame_buffer[peasycap->frame_read][0].kount); 1733 do_gettimeofday(&timeval); 1734 timeval2 = timeval; 1735 1736#if defined(AUDIOTIME) 1737 if (!peasycap->timeval0.tv_sec) { 1738 timeval0 = timeval; 1739 timeval1 = timeval; 1740 timeval2 = timeval; 1741 dnbydt = 192000; 1742 1743 if (mutex_lock_interruptible(&(peasycap->mutex_timeval0))) 1744 return -ERESTARTSYS; 1745 peasycap->timeval0 = timeval0; 1746 mutex_unlock(&(peasycap->mutex_timeval0)); 1747 } else { 1748 if (mutex_lock_interruptible(&(peasycap->mutex_timeval1))) 1749 return -ERESTARTSYS; 1750 dnbydt = peasycap->dnbydt; 1751 timeval1 = peasycap->timeval1; 1752 mutex_unlock(&(peasycap->mutex_timeval1)); 1753 above = dnbydt * MICROSECONDS(timeval, timeval1); 1754 below = 192000; 1755 sdr = signed_div(above, below); 1756 1757 above = sdr.quotient + timeval1.tv_usec - 350000; 1758 1759 below = 1000000; 1760 sdr = signed_div(above, below); 1761 timeval2.tv_usec = sdr.remainder; 1762 timeval2.tv_sec = timeval1.tv_sec + sdr.quotient; 1763 } 1764 if (!(isequence % 500)) { 1765 fudge = ((long long int)(1000000)) * \ 1766 ((long long int)(timeval.tv_sec - \ 1767 timeval2.tv_sec)) + \ 1768 (long long int)(timeval.tv_usec - \ 1769 timeval2.tv_usec); 1770 sdr = signed_div(fudge, 1000); 1771 sll = sdr.quotient; 1772 ull = sdr.remainder; 1773 1774 SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull); 1775 } 1776#endif /*AUDIOTIME*/ 1777 1778 v4l2_buffer.timestamp = timeval2; 1779 v4l2_buffer.sequence = isequence++; 1780 v4l2_buffer.memory = V4L2_MEMORY_MMAP; 1781 v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; 1782 v4l2_buffer.length = FRAME_BUFFER_SIZE; 1783 1784 JOT(16, " %10i=index\n", v4l2_buffer.index); 1785 JOT(16, " 0x%08X=type\n", v4l2_buffer.type); 1786 JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused); 1787 JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags); 1788 JOT(16, " %10i=field\n", v4l2_buffer.field); 1789 JOT(16, " %10li=timestamp.tv_usec\n", \ 1790 (long)v4l2_buffer.timestamp.tv_usec); 1791 JOT(16, " %10i=sequence\n", v4l2_buffer.sequence); 1792 JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory); 1793 JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset); 1794 JOT(16, " %10i=length\n", v4l2_buffer.length); 1795 1796 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ 1797 sizeof(struct v4l2_buffer))) { 1798 POUT; 1799 return -EFAULT; 1800 } 1801 1802 JOT(8, "..... user is offered frame buffer %i\n", \ 1803 peasycap->frame_read); 1804 peasycap->frame_lock = 1; 1805 if (peasycap->frame_read == peasycap->frame_fill) { 1806 if (peasycap->frame_lock) { 1807 JOT(8, "ERROR: filling frame buffer " \ 1808 "while offered to user\n"); 1809 } 1810 } 1811 break; 1812} 1813/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1814/*---------------------------------------------------------------------------*/ 1815/* 1816 * AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED; 1817 * VIDEO URBS HAVE NOT. 1818 */ 1819/*---------------------------------------------------------------------------*/ 1820case VIDIOC_STREAMON: { 1821 static int i; 1822 1823 JOT(8, "VIDIOC_STREAMON\n"); 1824 1825 isequence = 0; 1826 for (i = 0; i < 180; i++) 1827 peasycap->merit[i] = 0; 1828 if ((struct usb_device *)NULL == peasycap->pusb_device) { 1829 SAY("ERROR: peasycap->pusb_device is NULL\n"); 1830 return -EFAULT; 1831 } 1832 submit_video_urbs(peasycap); 1833 peasycap->video_idle = 0; 1834 peasycap->audio_idle = 0; 1835 peasycap->video_eof = 0; 1836 peasycap->audio_eof = 0; 1837 break; 1838} 1839/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1840case VIDIOC_STREAMOFF: { 1841 JOT(8, "VIDIOC_STREAMOFF\n"); 1842 1843 if ((struct usb_device *)NULL == peasycap->pusb_device) { 1844 SAY("ERROR: peasycap->pusb_device is NULL\n"); 1845 return -EFAULT; 1846 } 1847 1848 peasycap->video_idle = 1; 1849 peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0; 1850/*---------------------------------------------------------------------------*/ 1851/* 1852 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND 1853 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. 1854 */ 1855/*---------------------------------------------------------------------------*/ 1856 JOT(8, "calling wake_up on wq_video and wq_audio\n"); 1857 wake_up_interruptible(&(peasycap->wq_video)); 1858 wake_up_interruptible(&(peasycap->wq_audio)); 1859/*---------------------------------------------------------------------------*/ 1860 break; 1861} 1862/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1863case VIDIOC_G_PARM: { 1864 static struct v4l2_streamparm v4l2_streamparm; 1865 1866 JOT(8, "VIDIOC_G_PARM\n"); 1867 1868 if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \ 1869 sizeof(struct v4l2_streamparm))) { 1870 POUT; 1871 return -EFAULT; 1872 } 1873 1874 if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1875 POUT; 1876 return -EINVAL; 1877 } 1878 v4l2_streamparm.parm.capture.capability = 0; 1879 v4l2_streamparm.parm.capture.capturemode = 0; 1880 v4l2_streamparm.parm.capture.timeperframe.numerator = 1; 1881 v4l2_streamparm.parm.capture.timeperframe.denominator = 30; 1882 v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many; 1883 v4l2_streamparm.parm.capture.extendedmode = 0; 1884 if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \ 1885 sizeof(struct v4l2_streamparm))) { 1886 POUT; 1887 return -EFAULT; 1888 } 1889 break; 1890} 1891/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1892case VIDIOC_S_PARM: { 1893 JOT(8, "VIDIOC_S_PARM unsupported\n"); 1894 return -EINVAL; 1895} 1896/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1897case VIDIOC_G_AUDIO: { 1898 JOT(8, "VIDIOC_G_AUDIO unsupported\n"); 1899 return -EINVAL; 1900} 1901/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1902case VIDIOC_S_AUDIO: { 1903 JOT(8, "VIDIOC_S_AUDIO unsupported\n"); 1904 return -EINVAL; 1905} 1906/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1907case VIDIOC_S_TUNER: { 1908 JOT(8, "VIDIOC_S_TUNER unsupported\n"); 1909 return -EINVAL; 1910} 1911/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1912case VIDIOC_G_FBUF: 1913case VIDIOC_S_FBUF: 1914case VIDIOC_OVERLAY: { 1915 JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); 1916 return -EINVAL; 1917} 1918/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1919case VIDIOC_G_TUNER: { 1920 JOT(8, "VIDIOC_G_TUNER unsupported\n"); 1921 return -EINVAL; 1922} 1923case VIDIOC_G_FREQUENCY: 1924case VIDIOC_S_FREQUENCY: { 1925 JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); 1926 return -EINVAL; 1927} 1928/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1929default: { 1930 JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); 1931 explain_ioctl(cmd); 1932 POUT; 1933 return -ENOIOCTLCMD; 1934} 1935} 1936return 0; 1937} 1938 1939long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1940{ 1941 struct inode *inode = file->f_dentry->d_inode; 1942 long ret; 1943 1944 lock_kernel(); 1945 ret = easycap_ioctl_bkl(inode, file, cmd, arg); 1946 unlock_kernel(); 1947 1948 return ret; 1949} 1950 1951/*--------------------------------------------------------------------------*/ 1952static int easysnd_ioctl_bkl(struct inode *inode, struct file *file, 1953 unsigned int cmd, unsigned long arg) 1954{ 1955struct easycap *peasycap; 1956struct usb_device *p; 1957 1958peasycap = file->private_data; 1959if (NULL == peasycap) { 1960 SAY("ERROR: peasycap is NULL.\n"); 1961 return -1; 1962} 1963p = peasycap->pusb_device; 1964/*---------------------------------------------------------------------------*/ 1965switch (cmd) { 1966case SNDCTL_DSP_GETCAPS: { 1967 int caps; 1968 JOT(8, "SNDCTL_DSP_GETCAPS\n"); 1969 1970#if defined(UPSAMPLE) 1971 if (true == peasycap->microphone) 1972 caps = 0x04400000; 1973 else 1974 caps = 0x04400000; 1975#else 1976 if (true == peasycap->microphone) 1977 caps = 0x02400000; 1978 else 1979 caps = 0x04400000; 1980#endif /*UPSAMPLE*/ 1981 1982 if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) 1983 return -EFAULT; 1984 break; 1985} 1986case SNDCTL_DSP_GETFMTS: { 1987 int incoming; 1988 JOT(8, "SNDCTL_DSP_GETFMTS\n"); 1989 1990#if defined(UPSAMPLE) 1991 if (true == peasycap->microphone) 1992 incoming = AFMT_S16_LE; 1993 else 1994 incoming = AFMT_S16_LE; 1995#else 1996 if (true == peasycap->microphone) 1997 incoming = AFMT_S16_LE; 1998 else 1999 incoming = AFMT_S16_LE; 2000#endif /*UPSAMPLE*/ 2001 2002 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) 2003 return -EFAULT; 2004 break; 2005} 2006case SNDCTL_DSP_SETFMT: { 2007 int incoming, outgoing; 2008 JOT(8, "SNDCTL_DSP_SETFMT\n"); 2009 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2010 return -EFAULT; 2011 JOT(8, "........... %i=incoming\n", incoming); 2012 2013#if defined(UPSAMPLE) 2014 if (true == peasycap->microphone) 2015 outgoing = AFMT_S16_LE; 2016 else 2017 outgoing = AFMT_S16_LE; 2018#else 2019 if (true == peasycap->microphone) 2020 outgoing = AFMT_S16_LE; 2021 else 2022 outgoing = AFMT_S16_LE; 2023#endif /*UPSAMPLE*/ 2024 2025 if (incoming != outgoing) { 2026 JOT(8, "........... %i=outgoing\n", outgoing); 2027 JOT(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); 2028 JOT(8, " cf. %i=AFMT_U8\n", AFMT_U8); 2029 if (0 != copy_to_user((void __user *)arg, &outgoing, \ 2030 sizeof(int))) 2031 return -EFAULT; 2032 return -EINVAL ; 2033 } 2034 break; 2035} 2036case SNDCTL_DSP_STEREO: { 2037 int incoming; 2038 JOT(8, "SNDCTL_DSP_STEREO\n"); 2039 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2040 return -EFAULT; 2041 JOT(8, "........... %i=incoming\n", incoming); 2042 2043#if defined(UPSAMPLE) 2044 if (true == peasycap->microphone) 2045 incoming = 1; 2046 else 2047 incoming = 1; 2048#else 2049 if (true == peasycap->microphone) 2050 incoming = 0; 2051 else 2052 incoming = 1; 2053#endif /*UPSAMPLE*/ 2054 2055 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) 2056 return -EFAULT; 2057 break; 2058} 2059case SNDCTL_DSP_SPEED: { 2060 int incoming; 2061 JOT(8, "SNDCTL_DSP_SPEED\n"); 2062 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2063 return -EFAULT; 2064 JOT(8, "........... %i=incoming\n", incoming); 2065 2066#if defined(UPSAMPLE) 2067 if (true == peasycap->microphone) 2068 incoming = 32000; 2069 else 2070 incoming = 48000; 2071#else 2072 if (true == peasycap->microphone) 2073 incoming = 8000; 2074 else 2075 incoming = 48000; 2076#endif /*UPSAMPLE*/ 2077 2078 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) 2079 return -EFAULT; 2080 break; 2081} 2082case SNDCTL_DSP_GETTRIGGER: { 2083 int incoming; 2084 JOT(8, "SNDCTL_DSP_GETTRIGGER\n"); 2085 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2086 return -EFAULT; 2087 JOT(8, "........... %i=incoming\n", incoming); 2088 2089 incoming = PCM_ENABLE_INPUT; 2090 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) 2091 return -EFAULT; 2092 break; 2093} 2094case SNDCTL_DSP_SETTRIGGER: { 2095 int incoming; 2096 JOT(8, "SNDCTL_DSP_SETTRIGGER\n"); 2097 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2098 return -EFAULT; 2099 JOT(8, "........... %i=incoming\n", incoming); 2100 JOT(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ 2101 "0x%x=PCM_ENABLE_OUTPUT\n", \ 2102 PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); 2103 ; 2104 ; 2105 ; 2106 ; 2107 break; 2108} 2109case SNDCTL_DSP_GETBLKSIZE: { 2110 int incoming; 2111 JOT(8, "SNDCTL_DSP_GETBLKSIZE\n"); 2112 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) 2113 return -EFAULT; 2114 JOT(8, "........... %i=incoming\n", incoming); 2115 incoming = peasycap->audio_bytes_per_fragment; 2116 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) 2117 return -EFAULT; 2118 break; 2119} 2120case SNDCTL_DSP_GETISPACE: { 2121 struct audio_buf_info audio_buf_info; 2122 2123 JOT(8, "SNDCTL_DSP_GETISPACE\n"); 2124 2125 audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; 2126 audio_buf_info.fragments = 1; 2127 audio_buf_info.fragsize = 0; 2128 audio_buf_info.fragstotal = 0; 2129 2130 if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \ 2131 sizeof(int))) 2132 return -EFAULT; 2133 break; 2134} 2135default: { 2136 JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); 2137 POUT; 2138 return -ENOIOCTLCMD; 2139} 2140} 2141return 0; 2142} 2143 2144long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2145{ 2146 struct inode *inode = file->f_dentry->d_inode; 2147 long ret; 2148 2149 lock_kernel(); 2150 ret = easysnd_ioctl_bkl(inode, file, cmd, arg); 2151 unlock_kernel(); 2152 2153 return ret; 2154} 2155 2156/*****************************************************************************/ 2157int explain_ioctl(__u32 wot) 2158{ 2159int k; 2160/*---------------------------------------------------------------------------*/ 2161/* 2162 * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING 2163 * SHELL SCRIPT: 2164 * # 2165 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \ 2166 * grep "^#define VIDIOC_" - | grep -v "_OLD" - | \ 2167 * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \ 2168 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ 2169 * sed -e "s, ,,g;s, ,,g" >ioctl.tmp 2170 * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp 2171 * exit 0 2172 * # 2173 * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY. 2174 * 2175 * THE DATA FOR THE ARRAY mess1 BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING 2176 * SHELL SCRIPT: 2177 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev.h | \ 2178 * grep "^#define VIDIOC" - | grep -v "_OLD" - | \ 2179 * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \ 2180 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ 2181 * sed -e "s, ,,g;s, ,,g" >ioctl.tmp 2182 * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp 2183 * exit 0 2184 * # 2185 */ 2186/*---------------------------------------------------------------------------*/ 2187static struct mess { 2188 __u32 command; 2189 char name[64]; 2190} mess[] = { 2191#if defined(VIDIOC_QUERYCAP) 2192{VIDIOC_QUERYCAP, "VIDIOC_QUERYCAP"}, 2193#endif 2194#if defined(VIDIOC_RESERVED) 2195{VIDIOC_RESERVED, "VIDIOC_RESERVED"}, 2196#endif 2197#if defined(VIDIOC_ENUM_FMT) 2198{VIDIOC_ENUM_FMT, "VIDIOC_ENUM_FMT"}, 2199#endif 2200#if defined(VIDIOC_G_FMT) 2201{VIDIOC_G_FMT, "VIDIOC_G_FMT"}, 2202#endif 2203#if defined(VIDIOC_S_FMT) 2204{VIDIOC_S_FMT, "VIDIOC_S_FMT"}, 2205#endif 2206#if defined(VIDIOC_REQBUFS) 2207{VIDIOC_REQBUFS, "VIDIOC_REQBUFS"}, 2208#endif 2209#if defined(VIDIOC_QUERYBUF) 2210{VIDIOC_QUERYBUF, "VIDIOC_QUERYBUF"}, 2211#endif 2212#if defined(VIDIOC_G_FBUF) 2213{VIDIOC_G_FBUF, "VIDIOC_G_FBUF"}, 2214#endif 2215#if defined(VIDIOC_S_FBUF) 2216{VIDIOC_S_FBUF, "VIDIOC_S_FBUF"}, 2217#endif 2218#if defined(VIDIOC_OVERLAY) 2219{VIDIOC_OVERLAY, "VIDIOC_OVERLAY"}, 2220#endif 2221#if defined(VIDIOC_QBUF) 2222{VIDIOC_QBUF, "VIDIOC_QBUF"}, 2223#endif 2224#if defined(VIDIOC_DQBUF) 2225{VIDIOC_DQBUF, "VIDIOC_DQBUF"}, 2226#endif 2227#if defined(VIDIOC_STREAMON) 2228{VIDIOC_STREAMON, "VIDIOC_STREAMON"}, 2229#endif 2230#if defined(VIDIOC_STREAMOFF) 2231{VIDIOC_STREAMOFF, "VIDIOC_STREAMOFF"}, 2232#endif 2233#if defined(VIDIOC_G_PARM) 2234{VIDIOC_G_PARM, "VIDIOC_G_PARM"}, 2235#endif 2236#if defined(VIDIOC_S_PARM) 2237{VIDIOC_S_PARM, "VIDIOC_S_PARM"}, 2238#endif 2239#if defined(VIDIOC_G_STD) 2240{VIDIOC_G_STD, "VIDIOC_G_STD"}, 2241#endif 2242#if defined(VIDIOC_S_STD) 2243{VIDIOC_S_STD, "VIDIOC_S_STD"}, 2244#endif 2245#if defined(VIDIOC_ENUMSTD) 2246{VIDIOC_ENUMSTD, "VIDIOC_ENUMSTD"}, 2247#endif 2248#if defined(VIDIOC_ENUMINPUT) 2249{VIDIOC_ENUMINPUT, "VIDIOC_ENUMINPUT"}, 2250#endif 2251#if defined(VIDIOC_G_CTRL) 2252{VIDIOC_G_CTRL, "VIDIOC_G_CTRL"}, 2253#endif 2254#if defined(VIDIOC_S_CTRL) 2255{VIDIOC_S_CTRL, "VIDIOC_S_CTRL"}, 2256#endif 2257#if defined(VIDIOC_G_TUNER) 2258{VIDIOC_G_TUNER, "VIDIOC_G_TUNER"}, 2259#endif 2260#if defined(VIDIOC_S_TUNER) 2261{VIDIOC_S_TUNER, "VIDIOC_S_TUNER"}, 2262#endif 2263#if defined(VIDIOC_G_AUDIO) 2264{VIDIOC_G_AUDIO, "VIDIOC_G_AUDIO"}, 2265#endif 2266#if defined(VIDIOC_S_AUDIO) 2267{VIDIOC_S_AUDIO, "VIDIOC_S_AUDIO"}, 2268#endif 2269#if defined(VIDIOC_QUERYCTRL) 2270{VIDIOC_QUERYCTRL, "VIDIOC_QUERYCTRL"}, 2271#endif 2272#if defined(VIDIOC_QUERYMENU) 2273{VIDIOC_QUERYMENU, "VIDIOC_QUERYMENU"}, 2274#endif 2275#if defined(VIDIOC_G_INPUT) 2276{VIDIOC_G_INPUT, "VIDIOC_G_INPUT"}, 2277#endif 2278#if defined(VIDIOC_S_INPUT) 2279{VIDIOC_S_INPUT, "VIDIOC_S_INPUT"}, 2280#endif 2281#if defined(VIDIOC_G_OUTPUT) 2282{VIDIOC_G_OUTPUT, "VIDIOC_G_OUTPUT"}, 2283#endif 2284#if defined(VIDIOC_S_OUTPUT) 2285{VIDIOC_S_OUTPUT, "VIDIOC_S_OUTPUT"}, 2286#endif 2287#if defined(VIDIOC_ENUMOUTPUT) 2288{VIDIOC_ENUMOUTPUT, "VIDIOC_ENUMOUTPUT"}, 2289#endif 2290#if defined(VIDIOC_G_AUDOUT) 2291{VIDIOC_G_AUDOUT, "VIDIOC_G_AUDOUT"}, 2292#endif 2293#if defined(VIDIOC_S_AUDOUT) 2294{VIDIOC_S_AUDOUT, "VIDIOC_S_AUDOUT"}, 2295#endif 2296#if defined(VIDIOC_G_MODULATOR) 2297{VIDIOC_G_MODULATOR, "VIDIOC_G_MODULATOR"}, 2298#endif 2299#if defined(VIDIOC_S_MODULATOR) 2300{VIDIOC_S_MODULATOR, "VIDIOC_S_MODULATOR"}, 2301#endif 2302#if defined(VIDIOC_G_FREQUENCY) 2303{VIDIOC_G_FREQUENCY, "VIDIOC_G_FREQUENCY"}, 2304#endif 2305#if defined(VIDIOC_S_FREQUENCY) 2306{VIDIOC_S_FREQUENCY, "VIDIOC_S_FREQUENCY"}, 2307#endif 2308#if defined(VIDIOC_CROPCAP) 2309{VIDIOC_CROPCAP, "VIDIOC_CROPCAP"}, 2310#endif 2311#if defined(VIDIOC_G_CROP) 2312{VIDIOC_G_CROP, "VIDIOC_G_CROP"}, 2313#endif 2314#if defined(VIDIOC_S_CROP) 2315{VIDIOC_S_CROP, "VIDIOC_S_CROP"}, 2316#endif 2317#if defined(VIDIOC_G_JPEGCOMP) 2318{VIDIOC_G_JPEGCOMP, "VIDIOC_G_JPEGCOMP"}, 2319#endif 2320#if defined(VIDIOC_S_JPEGCOMP) 2321{VIDIOC_S_JPEGCOMP, "VIDIOC_S_JPEGCOMP"}, 2322#endif 2323#if defined(VIDIOC_QUERYSTD) 2324{VIDIOC_QUERYSTD, "VIDIOC_QUERYSTD"}, 2325#endif 2326#if defined(VIDIOC_TRY_FMT) 2327{VIDIOC_TRY_FMT, "VIDIOC_TRY_FMT"}, 2328#endif 2329#if defined(VIDIOC_ENUMAUDIO) 2330{VIDIOC_ENUMAUDIO, "VIDIOC_ENUMAUDIO"}, 2331#endif 2332#if defined(VIDIOC_ENUMAUDOUT) 2333{VIDIOC_ENUMAUDOUT, "VIDIOC_ENUMAUDOUT"}, 2334#endif 2335#if defined(VIDIOC_G_PRIORITY) 2336{VIDIOC_G_PRIORITY, "VIDIOC_G_PRIORITY"}, 2337#endif 2338#if defined(VIDIOC_S_PRIORITY) 2339{VIDIOC_S_PRIORITY, "VIDIOC_S_PRIORITY"}, 2340#endif 2341#if defined(VIDIOC_G_SLICED_VBI_CAP) 2342{VIDIOC_G_SLICED_VBI_CAP, "VIDIOC_G_SLICED_VBI_CAP"}, 2343#endif 2344#if defined(VIDIOC_LOG_STATUS) 2345{VIDIOC_LOG_STATUS, "VIDIOC_LOG_STATUS"}, 2346#endif 2347#if defined(VIDIOC_G_EXT_CTRLS) 2348{VIDIOC_G_EXT_CTRLS, "VIDIOC_G_EXT_CTRLS"}, 2349#endif 2350#if defined(VIDIOC_S_EXT_CTRLS) 2351{VIDIOC_S_EXT_CTRLS, "VIDIOC_S_EXT_CTRLS"}, 2352#endif 2353#if defined(VIDIOC_TRY_EXT_CTRLS) 2354{VIDIOC_TRY_EXT_CTRLS, "VIDIOC_TRY_EXT_CTRLS"}, 2355#endif 2356#if defined(VIDIOC_ENUM_FRAMESIZES) 2357{VIDIOC_ENUM_FRAMESIZES, "VIDIOC_ENUM_FRAMESIZES"}, 2358#endif 2359#if defined(VIDIOC_ENUM_FRAMEINTERVALS) 2360{VIDIOC_ENUM_FRAMEINTERVALS, "VIDIOC_ENUM_FRAMEINTERVALS"}, 2361#endif 2362#if defined(VIDIOC_G_ENC_INDEX) 2363{VIDIOC_G_ENC_INDEX, "VIDIOC_G_ENC_INDEX"}, 2364#endif 2365#if defined(VIDIOC_ENCODER_CMD) 2366{VIDIOC_ENCODER_CMD, "VIDIOC_ENCODER_CMD"}, 2367#endif 2368#if defined(VIDIOC_TRY_ENCODER_CMD) 2369{VIDIOC_TRY_ENCODER_CMD, "VIDIOC_TRY_ENCODER_CMD"}, 2370#endif 2371#if defined(VIDIOC_G_CHIP_IDENT) 2372{VIDIOC_G_CHIP_IDENT, "VIDIOC_G_CHIP_IDENT"}, 2373#endif 2374 2375#if defined(VIDIOC_OVERLAY_OLD) 2376{VIDIOC_OVERLAY_OLD, "VIDIOC_OVERLAY_OLD"}, 2377#endif 2378#if defined(VIDIOC_S_PARM_OLD) 2379{VIDIOC_S_PARM_OLD, "VIDIOC_S_PARM_OLD"}, 2380#endif 2381#if defined(VIDIOC_S_CTRL_OLD) 2382{VIDIOC_S_CTRL_OLD, "VIDIOC_S_CTRL_OLD"}, 2383#endif 2384#if defined(VIDIOC_G_AUDIO_OLD) 2385{VIDIOC_G_AUDIO_OLD, "VIDIOC_G_AUDIO_OLD"}, 2386#endif 2387#if defined(VIDIOC_G_AUDOUT_OLD) 2388{VIDIOC_G_AUDOUT_OLD, "VIDIOC_G_AUDOUT_OLD"}, 2389#endif 2390#if defined(VIDIOC_CROPCAP_OLD) 2391{VIDIOC_CROPCAP_OLD, "VIDIOC_CROPCAP_OLD"}, 2392#endif 2393{0xFFFFFFFF, ""} 2394}; 2395 2396static struct mess mess1[] = \ 2397{ 2398#if defined(VIDIOCGCAP) 2399{VIDIOCGCAP, "VIDIOCGCAP"}, 2400#endif 2401#if defined(VIDIOCGCHAN) 2402{VIDIOCGCHAN, "VIDIOCGCHAN"}, 2403#endif 2404#if defined(VIDIOCSCHAN) 2405{VIDIOCSCHAN, "VIDIOCSCHAN"}, 2406#endif 2407#if defined(VIDIOCGTUNER) 2408{VIDIOCGTUNER, "VIDIOCGTUNER"}, 2409#endif 2410#if defined(VIDIOCSTUNER) 2411{VIDIOCSTUNER, "VIDIOCSTUNER"}, 2412#endif 2413#if defined(VIDIOCGPICT) 2414{VIDIOCGPICT, "VIDIOCGPICT"}, 2415#endif 2416#if defined(VIDIOCSPICT) 2417{VIDIOCSPICT, "VIDIOCSPICT"}, 2418#endif 2419#if defined(VIDIOCCAPTURE) 2420{VIDIOCCAPTURE, "VIDIOCCAPTURE"}, 2421#endif 2422#if defined(VIDIOCGWIN) 2423{VIDIOCGWIN, "VIDIOCGWIN"}, 2424#endif 2425#if defined(VIDIOCSWIN) 2426{VIDIOCSWIN, "VIDIOCSWIN"}, 2427#endif 2428#if defined(VIDIOCGFBUF) 2429{VIDIOCGFBUF, "VIDIOCGFBUF"}, 2430#endif 2431#if defined(VIDIOCSFBUF) 2432{VIDIOCSFBUF, "VIDIOCSFBUF"}, 2433#endif 2434#if defined(VIDIOCKEY) 2435{VIDIOCKEY, "VIDIOCKEY"}, 2436#endif 2437#if defined(VIDIOCGFREQ) 2438{VIDIOCGFREQ, "VIDIOCGFREQ"}, 2439#endif 2440#if defined(VIDIOCSFREQ) 2441{VIDIOCSFREQ, "VIDIOCSFREQ"}, 2442#endif 2443#if defined(VIDIOCGAUDIO) 2444{VIDIOCGAUDIO, "VIDIOCGAUDIO"}, 2445#endif 2446#if defined(VIDIOCSAUDIO) 2447{VIDIOCSAUDIO, "VIDIOCSAUDIO"}, 2448#endif 2449#if defined(VIDIOCSYNC) 2450{VIDIOCSYNC, "VIDIOCSYNC"}, 2451#endif 2452#if defined(VIDIOCMCAPTURE) 2453{VIDIOCMCAPTURE, "VIDIOCMCAPTURE"}, 2454#endif 2455#if defined(VIDIOCGMBUF) 2456{VIDIOCGMBUF, "VIDIOCGMBUF"}, 2457#endif 2458#if defined(VIDIOCGUNIT) 2459{VIDIOCGUNIT, "VIDIOCGUNIT"}, 2460#endif 2461#if defined(VIDIOCGCAPTURE) 2462{VIDIOCGCAPTURE, "VIDIOCGCAPTURE"}, 2463#endif 2464#if defined(VIDIOCSCAPTURE) 2465{VIDIOCSCAPTURE, "VIDIOCSCAPTURE"}, 2466#endif 2467#if defined(VIDIOCSPLAYMODE) 2468{VIDIOCSPLAYMODE, "VIDIOCSPLAYMODE"}, 2469#endif 2470#if defined(VIDIOCSWRITEMODE) 2471{VIDIOCSWRITEMODE, "VIDIOCSWRITEMODE"}, 2472#endif 2473#if defined(VIDIOCGPLAYINFO) 2474{VIDIOCGPLAYINFO, "VIDIOCGPLAYINFO"}, 2475#endif 2476#if defined(VIDIOCSMICROCODE) 2477{VIDIOCSMICROCODE, "VIDIOCSMICROCODE"}, 2478#endif 2479{0xFFFFFFFF, ""} 2480}; 2481 2482k = 0; 2483while (mess[k].name[0]) { 2484 if (wot == mess[k].command) { 2485 JOT(8, "ioctl 0x%08X is %s\n", \ 2486 mess[k].command, &mess[k].name[0]); 2487 return 0; 2488 } 2489 k++; 2490} 2491JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot); 2492 2493k = 0; 2494while (mess1[k].name[0]) { 2495 if (wot == mess1[k].command) { 2496 JOT(8, "ioctl 0x%08X is %s (V4L1)\n", \ 2497 mess1[k].command, &mess1[k].name[0]); 2498 return 0; 2499 } 2500 k++; 2501} 2502JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot); 2503return -1; 2504} 2505/*****************************************************************************/ 2506int explain_cid(__u32 wot) 2507{ 2508int k; 2509/*---------------------------------------------------------------------------*/ 2510/* 2511 * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING 2512 * SHELL SCRIPT: 2513 * # 2514 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \ 2515 * grep "^#define V4L2_CID_" | \ 2516 * sed -e "s,(.*$,,;p" | sed -e "N;s,\n,, " | \ 2517 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ 2518 * sed -e "s, ,,g;s, ,,g" | grep -v "_BASE" | grep -v "MPEG" >cid.tmp 2519 * echo "{0xFFFFFFFF,\"\"}" >>cid.tmp 2520 * exit 0 2521 * # 2522 */ 2523/*---------------------------------------------------------------------------*/ 2524static struct mess 2525{ 2526__u32 command; 2527char name[64]; 2528} mess[] = { 2529#if defined(V4L2_CID_USER_CLASS) 2530{V4L2_CID_USER_CLASS, "V4L2_CID_USER_CLASS"}, 2531#endif 2532#if defined(V4L2_CID_BRIGHTNESS) 2533{V4L2_CID_BRIGHTNESS, "V4L2_CID_BRIGHTNESS"}, 2534#endif 2535#if defined(V4L2_CID_CONTRAST) 2536{V4L2_CID_CONTRAST, "V4L2_CID_CONTRAST"}, 2537#endif 2538#if defined(V4L2_CID_SATURATION) 2539{V4L2_CID_SATURATION, "V4L2_CID_SATURATION"}, 2540#endif 2541#if defined(V4L2_CID_HUE) 2542{V4L2_CID_HUE, "V4L2_CID_HUE"}, 2543#endif 2544#if defined(V4L2_CID_AUDIO_VOLUME) 2545{V4L2_CID_AUDIO_VOLUME, "V4L2_CID_AUDIO_VOLUME"}, 2546#endif 2547#if defined(V4L2_CID_AUDIO_BALANCE) 2548{V4L2_CID_AUDIO_BALANCE, "V4L2_CID_AUDIO_BALANCE"}, 2549#endif 2550#if defined(V4L2_CID_AUDIO_BASS) 2551{V4L2_CID_AUDIO_BASS, "V4L2_CID_AUDIO_BASS"}, 2552#endif 2553#if defined(V4L2_CID_AUDIO_TREBLE) 2554{V4L2_CID_AUDIO_TREBLE, "V4L2_CID_AUDIO_TREBLE"}, 2555#endif 2556#if defined(V4L2_CID_AUDIO_MUTE) 2557{V4L2_CID_AUDIO_MUTE, "V4L2_CID_AUDIO_MUTE"}, 2558#endif 2559#if defined(V4L2_CID_AUDIO_LOUDNESS) 2560{V4L2_CID_AUDIO_LOUDNESS, "V4L2_CID_AUDIO_LOUDNESS"}, 2561#endif 2562#if defined(V4L2_CID_BLACK_LEVEL) 2563{V4L2_CID_BLACK_LEVEL, "V4L2_CID_BLACK_LEVEL"}, 2564#endif 2565#if defined(V4L2_CID_AUTO_WHITE_BALANCE) 2566{V4L2_CID_AUTO_WHITE_BALANCE, "V4L2_CID_AUTO_WHITE_BALANCE"}, 2567#endif 2568#if defined(V4L2_CID_DO_WHITE_BALANCE) 2569{V4L2_CID_DO_WHITE_BALANCE, "V4L2_CID_DO_WHITE_BALANCE"}, 2570#endif 2571#if defined(V4L2_CID_RED_BALANCE) 2572{V4L2_CID_RED_BALANCE, "V4L2_CID_RED_BALANCE"}, 2573#endif 2574#if defined(V4L2_CID_BLUE_BALANCE) 2575{V4L2_CID_BLUE_BALANCE, "V4L2_CID_BLUE_BALANCE"}, 2576#endif 2577#if defined(V4L2_CID_GAMMA) 2578{V4L2_CID_GAMMA, "V4L2_CID_GAMMA"}, 2579#endif 2580#if defined(V4L2_CID_WHITENESS) 2581{V4L2_CID_WHITENESS, "V4L2_CID_WHITENESS"}, 2582#endif 2583#if defined(V4L2_CID_EXPOSURE) 2584{V4L2_CID_EXPOSURE, "V4L2_CID_EXPOSURE"}, 2585#endif 2586#if defined(V4L2_CID_AUTOGAIN) 2587{V4L2_CID_AUTOGAIN, "V4L2_CID_AUTOGAIN"}, 2588#endif 2589#if defined(V4L2_CID_GAIN) 2590{V4L2_CID_GAIN, "V4L2_CID_GAIN"}, 2591#endif 2592#if defined(V4L2_CID_HFLIP) 2593{V4L2_CID_HFLIP, "V4L2_CID_HFLIP"}, 2594#endif 2595#if defined(V4L2_CID_VFLIP) 2596{V4L2_CID_VFLIP, "V4L2_CID_VFLIP"}, 2597#endif 2598#if defined(V4L2_CID_HCENTER) 2599{V4L2_CID_HCENTER, "V4L2_CID_HCENTER"}, 2600#endif 2601#if defined(V4L2_CID_VCENTER) 2602{V4L2_CID_VCENTER, "V4L2_CID_VCENTER"}, 2603#endif 2604#if defined(V4L2_CID_POWER_LINE_FREQUENCY) 2605{V4L2_CID_POWER_LINE_FREQUENCY, "V4L2_CID_POWER_LINE_FREQUENCY"}, 2606#endif 2607#if defined(V4L2_CID_HUE_AUTO) 2608{V4L2_CID_HUE_AUTO, "V4L2_CID_HUE_AUTO"}, 2609#endif 2610#if defined(V4L2_CID_WHITE_BALANCE_TEMPERATURE) 2611{V4L2_CID_WHITE_BALANCE_TEMPERATURE, "V4L2_CID_WHITE_BALANCE_TEMPERATURE"}, 2612#endif 2613#if defined(V4L2_CID_SHARPNESS) 2614{V4L2_CID_SHARPNESS, "V4L2_CID_SHARPNESS"}, 2615#endif 2616#if defined(V4L2_CID_BACKLIGHT_COMPENSATION) 2617{V4L2_CID_BACKLIGHT_COMPENSATION, "V4L2_CID_BACKLIGHT_COMPENSATION"}, 2618#endif 2619#if defined(V4L2_CID_CHROMA_AGC) 2620{V4L2_CID_CHROMA_AGC, "V4L2_CID_CHROMA_AGC"}, 2621#endif 2622#if defined(V4L2_CID_COLOR_KILLER) 2623{V4L2_CID_COLOR_KILLER, "V4L2_CID_COLOR_KILLER"}, 2624#endif 2625#if defined(V4L2_CID_LASTP1) 2626{V4L2_CID_LASTP1, "V4L2_CID_LASTP1"}, 2627#endif 2628#if defined(V4L2_CID_CAMERA_CLASS) 2629{V4L2_CID_CAMERA_CLASS, "V4L2_CID_CAMERA_CLASS"}, 2630#endif 2631#if defined(V4L2_CID_EXPOSURE_AUTO) 2632{V4L2_CID_EXPOSURE_AUTO, "V4L2_CID_EXPOSURE_AUTO"}, 2633#endif 2634#if defined(V4L2_CID_EXPOSURE_ABSOLUTE) 2635{V4L2_CID_EXPOSURE_ABSOLUTE, "V4L2_CID_EXPOSURE_ABSOLUTE"}, 2636#endif 2637#if defined(V4L2_CID_EXPOSURE_AUTO_PRIORITY) 2638{V4L2_CID_EXPOSURE_AUTO_PRIORITY, "V4L2_CID_EXPOSURE_AUTO_PRIORITY"}, 2639#endif 2640#if defined(V4L2_CID_PAN_RELATIVE) 2641{V4L2_CID_PAN_RELATIVE, "V4L2_CID_PAN_RELATIVE"}, 2642#endif 2643#if defined(V4L2_CID_TILT_RELATIVE) 2644{V4L2_CID_TILT_RELATIVE, "V4L2_CID_TILT_RELATIVE"}, 2645#endif 2646#if defined(V4L2_CID_PAN_RESET) 2647{V4L2_CID_PAN_RESET, "V4L2_CID_PAN_RESET"}, 2648#endif 2649#if defined(V4L2_CID_TILT_RESET) 2650{V4L2_CID_TILT_RESET, "V4L2_CID_TILT_RESET"}, 2651#endif 2652#if defined(V4L2_CID_PAN_ABSOLUTE) 2653{V4L2_CID_PAN_ABSOLUTE, "V4L2_CID_PAN_ABSOLUTE"}, 2654#endif 2655#if defined(V4L2_CID_TILT_ABSOLUTE) 2656{V4L2_CID_TILT_ABSOLUTE, "V4L2_CID_TILT_ABSOLUTE"}, 2657#endif 2658#if defined(V4L2_CID_FOCUS_ABSOLUTE) 2659{V4L2_CID_FOCUS_ABSOLUTE, "V4L2_CID_FOCUS_ABSOLUTE"}, 2660#endif 2661#if defined(V4L2_CID_FOCUS_RELATIVE) 2662{V4L2_CID_FOCUS_RELATIVE, "V4L2_CID_FOCUS_RELATIVE"}, 2663#endif 2664#if defined(V4L2_CID_FOCUS_AUTO) 2665{V4L2_CID_FOCUS_AUTO, "V4L2_CID_FOCUS_AUTO"}, 2666#endif 2667{0xFFFFFFFF, ""} 2668}; 2669 2670k = 0; 2671while (mess[k].name[0]) { 2672 if (wot == mess[k].command) { 2673 JOT(8, "ioctl 0x%08X is %s\n", \ 2674 mess[k].command, &mess[k].name[0]); 2675 return 0; 2676 } 2677 k++; 2678} 2679JOT(8, "cid 0x%08X is not in videodev2.h\n", wot); 2680return -1; 2681} 2682/*****************************************************************************/ 2683