1 /******************************************************************************
5 ******************************************************************************/
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
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.
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.
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
26 /*****************************************************************************/
28 #include <linux/smp_lock.h>
31 /*--------------------------------------------------------------------------*/
33 * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
35 * peasycap->standard_offset
36 * peasycap->inputset[peasycap->input].standard_offset
42 /*---------------------------------------------------------------------------*/
43 int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
45 struct easycap_standard const *peasycap_standard;
48 unsigned int itwas, isnow;
51 if (NULL == peasycap) {
52 SAY("ERROR: peasycap is NULL\n");
55 if ((struct usb_device *)NULL == peasycap->pusb_device) {
56 SAM("ERROR: peasycap->pusb_device is NULL\n");
59 peasycap_standard = &easycap_standard[0];
60 while (0xFFFF != peasycap_standard->mask) {
61 if (std_id == peasycap_standard->v4l2_standard.id)
65 if (0xFFFF == peasycap_standard->mask) {
66 peasycap_standard = &easycap_standard[0];
67 while (0xFFFF != peasycap_standard->mask) {
68 if (std_id & peasycap_standard->v4l2_standard.id)
73 if (0xFFFF == peasycap_standard->mask) {
74 SAM("ERROR: 0x%08X=std_id: standard not found\n",
75 (unsigned int)std_id);
78 SAM("selected standard: %s\n",
79 &(peasycap_standard->v4l2_standard.name[0]));
80 if (peasycap->standard_offset ==
81 (int)(peasycap_standard - &easycap_standard[0])) {
82 SAM("requested standard already in effect\n");
85 peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
86 for (k = 0; k < INPUT_MANY; k++) {
87 if (!peasycap->inputset[k].standard_offset_ok) {
88 peasycap->inputset[k].standard_offset =
89 peasycap->standard_offset;
92 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
93 peasycap->inputset[peasycap->input].standard_offset =
94 peasycap->standard_offset;
95 peasycap->inputset[peasycap->input].standard_offset_ok = 1;
97 JOM(8, "%i=peasycap->input\n", peasycap->input);
98 peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator /
99 peasycap_standard->v4l2_standard.frameperiod.numerator;
100 switch (peasycap->fps) {
103 peasycap->ntsc = true;
108 peasycap->ntsc = false;
112 SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
116 JOM(8, "%i frames-per-second\n", peasycap->fps);
117 if (0x8000 & peasycap_standard->mask) {
119 peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
120 peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
123 peasycap->usec = 1000000 / (2 * peasycap->fps);
124 peasycap->tolerate = 1000 * (25 / peasycap->fps);
126 if (peasycap->video_isoc_streaming) {
128 kill_video_urbs(peasycap);
131 /*--------------------------------------------------------------------------*/
133 * SAA7113H DATASHEET PAGE 44, TABLE 42
135 /*--------------------------------------------------------------------------*/
136 need = 0; itwas = 0; reg = 0x00; set = 0x00;
137 switch (peasycap_standard->mask & 0x000F) {
139 reg = 0x0A; set = 0x95;
140 ir = read_saa(peasycap->pusb_device, reg);
142 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
144 itwas = (unsigned int)ir;
145 rc = write_saa(peasycap->pusb_device, reg, set);
147 SAM("ERROR: failed to set SAA register "
148 "0x%02X to 0x%02X for JP standard\n", reg, set);
150 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
152 JOM(8, "SAA register 0x%02X changed "
153 "to 0x%02X\n", reg, isnow);
155 JOM(8, "SAA register 0x%02X changed "
156 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
159 reg = 0x0B; set = 0x48;
160 ir = read_saa(peasycap->pusb_device, reg);
162 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
164 itwas = (unsigned int)ir;
165 rc = write_saa(peasycap->pusb_device, reg, set);
167 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X "
168 "for JP standard\n", reg, set);
170 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
172 JOM(8, "SAA register 0x%02X changed "
173 "to 0x%02X\n", reg, isnow);
175 JOM(8, "SAA register 0x%02X changed "
176 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
178 /*--------------------------------------------------------------------------*/
180 * NOTE: NO break HERE: RUN ON TO NEXT CASE
182 /*--------------------------------------------------------------------------*/
186 reg = 0x0E; set = 0x01; need = 1; break;
190 reg = 0x0E; set = 0x11; need = 1; break;
194 reg = 0x0E; set = 0x21; need = 1; break;
198 reg = 0x0E; set = 0x31; need = 1; break;
201 reg = 0x0E; set = 0x51; need = 1; break;
206 /*--------------------------------------------------------------------------*/
208 ir = read_saa(peasycap->pusb_device, reg);
210 SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
212 itwas = (unsigned int)ir;
213 rc = write_saa(peasycap->pusb_device, reg, set);
214 if (0 != write_saa(peasycap->pusb_device, reg, set)) {
215 SAM("ERROR: failed to set SAA register "
216 "0x%02X to 0x%02X for table 42\n", reg, set);
218 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
220 JOM(8, "SAA register 0x%02X changed "
221 "to 0x%02X\n", reg, isnow);
223 JOM(8, "SAA register 0x%02X changed "
224 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
227 /*--------------------------------------------------------------------------*/
229 * SAA7113H DATASHEET PAGE 41
231 /*--------------------------------------------------------------------------*/
233 ir = read_saa(peasycap->pusb_device, reg);
235 SAM("ERROR: failed to read SAA register 0x%02X "
236 "so cannot reset\n", reg);
238 itwas = (unsigned int)ir;
239 if (peasycap_standard->mask & 0x0001)
242 set = itwas & ~0x40 ;
243 rc = write_saa(peasycap->pusb_device, reg, set);
245 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
248 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
250 JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
253 JOM(8, "SAA register 0x%02X changed "
254 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
257 /*--------------------------------------------------------------------------*/
259 * SAA7113H DATASHEET PAGE 51, TABLE 57
261 /*---------------------------------------------------------------------------*/
263 ir = read_saa(peasycap->pusb_device, reg);
265 SAM("ERROR: failed to read SAA register 0x%02X "
266 "so cannot reset\n", reg);
268 itwas = (unsigned int)ir;
269 if (peasycap_standard->mask & 0x0001)
272 set = itwas & ~0x80 ;
273 rc = write_saa(peasycap->pusb_device, reg, set);
275 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
278 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
280 JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
283 JOM(8, "SAA register 0x%02X changed "
284 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
287 /*--------------------------------------------------------------------------*/
289 * SAA7113H DATASHEET PAGE 53, TABLE 66
291 /*--------------------------------------------------------------------------*/
293 ir = read_saa(peasycap->pusb_device, reg);
295 SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
296 itwas = (unsigned int)ir;
297 if (peasycap_standard->mask & 0x0001)
301 if (0 != write_saa(peasycap->pusb_device, reg, set))
302 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
305 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
307 JOM(8, "SAA register 0x%02X changed "
308 "to 0x%02X\n", reg, isnow);
310 JOM(8, "SAA register 0x%02X changed "
311 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
313 if (true == resubmit)
314 submit_video_urbs(peasycap);
317 /*****************************************************************************/
318 /*--------------------------------------------------------------------------*/
320 * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
321 * A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
323 * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
324 * THIS ROUTINE UPDATES THE FOLLOWING:
325 * peasycap->format_offset
326 * peasycap->inputset[peasycap->input].format_offset
327 * peasycap->pixelformat
330 * peasycap->bytesperpixel
331 * peasycap->byteswaporder
332 * peasycap->decimatepixel
333 * peasycap->frame_buffer_used
334 * peasycap->videofieldamount
335 * peasycap->offerfields
337 * IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
338 * IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
339 * ERRORS RETURN A NEGATIVE NUMBER.
341 /*--------------------------------------------------------------------------*/
342 int adjust_format(struct easycap *peasycap,
343 __u32 width, __u32 height, __u32 pixelformat, int field, bool try)
345 struct easycap_format *peasycap_format, *peasycap_best_format;
347 struct usb_device *p;
348 int miss, multiplier, best, k;
349 char bf[5], fo[32], *pc;
353 if (NULL == peasycap) {
354 SAY("ERROR: peasycap is NULL\n");
357 if (0 > peasycap->standard_offset) {
358 JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
361 p = peasycap->pusb_device;
362 if ((struct usb_device *)NULL == p) {
363 SAM("ERROR: peaycap->pusb_device is NULL\n");
368 memcpy((void *)pc, (void *)(&uc), 4);
370 mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
371 SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n",
372 width, height, pc, pixelformat, field, mask);
374 case V4L2_FIELD_ANY: {
375 strcpy(&fo[0], "V4L2_FIELD_ANY ");
378 case V4L2_FIELD_NONE: {
379 strcpy(&fo[0], "V4L2_FIELD_NONE");
382 case V4L2_FIELD_TOP: {
383 strcpy(&fo[0], "V4L2_FIELD_TOP");
386 case V4L2_FIELD_BOTTOM: {
387 strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
390 case V4L2_FIELD_INTERLACED: {
391 strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
394 case V4L2_FIELD_SEQ_TB: {
395 strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
398 case V4L2_FIELD_SEQ_BT: {
399 strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
402 case V4L2_FIELD_ALTERNATE: {
403 strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
406 case V4L2_FIELD_INTERLACED_TB: {
407 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
410 case V4L2_FIELD_INTERLACED_BT: {
411 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
415 strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN ");
419 SAM("sought: %s\n", &fo[0]);
420 if (V4L2_FIELD_ANY == field) {
421 field = V4L2_FIELD_NONE;
422 SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
424 peasycap_best_format = (struct easycap_format *)NULL;
425 peasycap_format = &easycap_format[0];
426 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
427 JOM(16, ".> %i %i 0x%08X %ix%i\n",
428 peasycap_format->mask & 0x01,
429 peasycap_format->v4l2_format.fmt.pix.field,
430 peasycap_format->v4l2_format.fmt.pix.pixelformat,
431 peasycap_format->v4l2_format.fmt.pix.width,
432 peasycap_format->v4l2_format.fmt.pix.height);
434 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
435 (peasycap_format->v4l2_format.fmt.pix.field == field) &&
436 (peasycap_format->v4l2_format.fmt.pix.pixelformat ==
438 (peasycap_format->v4l2_format.fmt.pix.width == width) &&
439 (peasycap_format->v4l2_format.fmt.pix.height == height)) {
440 peasycap_best_format = peasycap_format;
445 if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
446 SAM("cannot do: %ix%i with standard mask 0x%02X\n",
447 width, height, mask);
448 peasycap_format = &easycap_format[0]; best = -1;
449 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
450 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
451 (peasycap_format->v4l2_format.fmt.pix
453 (peasycap_format->v4l2_format.fmt.pix
454 .pixelformat == pixelformat)) {
455 miss = abs(peasycap_format->
456 v4l2_format.fmt.pix.width - width);
457 if ((best > miss) || (best < 0)) {
459 peasycap_best_format = peasycap_format;
467 SAM("cannot do %ix... with standard mask 0x%02X\n",
469 SAM("cannot do ...x%i with standard mask 0x%02X\n",
471 SAM(" %ix%i unmatched\n", width, height);
472 return peasycap->format_offset;
475 if ((struct easycap_format *)NULL == peasycap_best_format) {
476 SAM("MISTAKE: peasycap_best_format is NULL");
479 peasycap_format = peasycap_best_format;
481 /*...........................................................................*/
483 return (int)(peasycap_best_format - &easycap_format[0]);
484 /*...........................................................................*/
487 SAM("MISTAKE: true==try where is should be false\n");
490 SAM("actioning: %ix%i %s\n",
491 peasycap_format->v4l2_format.fmt.pix.width,
492 peasycap_format->v4l2_format.fmt.pix.height,
493 &peasycap_format->name[0]);
494 peasycap->height = peasycap_format->v4l2_format.fmt.pix.height;
495 peasycap->width = peasycap_format->v4l2_format.fmt.pix.width;
496 peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat;
497 peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
500 for (k = 0; k < INPUT_MANY; k++) {
501 if (!peasycap->inputset[k].format_offset_ok) {
502 peasycap->inputset[k].format_offset =
503 peasycap->format_offset;
506 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
507 peasycap->inputset[peasycap->input].format_offset =
508 peasycap->format_offset;
509 peasycap->inputset[peasycap->input].format_offset_ok = 1;
511 JOM(8, "%i=peasycap->input\n", peasycap->input);
515 peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
516 if (0x0100 & peasycap_format->mask)
517 peasycap->byteswaporder = true;
519 peasycap->byteswaporder = false;
520 if (0x0200 & peasycap_format->mask)
524 if (0x0800 & peasycap_format->mask)
525 peasycap->decimatepixel = true;
527 peasycap->decimatepixel = false;
528 if (0x1000 & peasycap_format->mask)
529 peasycap->offerfields = true;
531 peasycap->offerfields = false;
532 if (true == peasycap->decimatepixel)
536 peasycap->videofieldamount = multiplier * peasycap->width *
537 multiplier * peasycap->height;
538 peasycap->frame_buffer_used = peasycap->bytesperpixel *
539 peasycap->width * peasycap->height;
540 if (peasycap->video_isoc_streaming) {
542 kill_video_urbs(peasycap);
545 /*---------------------------------------------------------------------------*/
549 /*---------------------------------------------------------------------------*/
550 if (0 == (0x01 & peasycap_format->mask)) {
551 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
553 peasycap_format->v4l2_format.fmt.pix.height)) ||
555 peasycap_format->v4l2_format.fmt.pix.width) &&
557 peasycap_format->v4l2_format.fmt.pix.height))) {
558 if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
559 SAM("ERROR: set_resolution() failed\n");
562 } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) &&
563 (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
564 if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
565 SAM("ERROR: set_resolution() failed\n");
568 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
570 peasycap_format->v4l2_format.fmt.pix.height)) ||
572 peasycap_format->v4l2_format.fmt.pix.width) &&
574 peasycap_format->v4l2_format.fmt.pix.height))) {
575 if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
576 SAM("ERROR: set_resolution() failed\n");
580 SAM("MISTAKE: bad format, cannot set resolution\n");
583 /*---------------------------------------------------------------------------*/
587 /*---------------------------------------------------------------------------*/
589 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
591 peasycap_format->v4l2_format.fmt.pix.height)) ||
593 peasycap_format->v4l2_format.fmt.pix.width) &&
595 peasycap_format->v4l2_format.fmt.pix.height))) {
596 if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
597 SAM("ERROR: set_resolution() failed\n");
600 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
602 peasycap_format->v4l2_format.fmt.pix.height)) ||
604 peasycap_format->v4l2_format.fmt.pix.width) &&
606 peasycap_format->v4l2_format.fmt.pix.height))) {
607 if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
608 SAM("ERROR: set_resolution() failed\n");
612 SAM("MISTAKE: bad format, cannot set resolution\n");
616 /*---------------------------------------------------------------------------*/
617 if (true == resubmit)
618 submit_video_urbs(peasycap);
619 return (int)(peasycap_best_format - &easycap_format[0]);
621 /*****************************************************************************/
622 int adjust_brightness(struct easycap *peasycap, int value)
627 if (NULL == peasycap) {
628 SAY("ERROR: peasycap is NULL\n");
631 if ((struct usb_device *)NULL == peasycap->pusb_device) {
632 SAM("ERROR: peasycap->pusb_device is NULL\n");
636 while (0xFFFFFFFF != easycap_control[i1].id) {
637 if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
638 if ((easycap_control[i1].minimum > value) ||
639 (easycap_control[i1].maximum < value))
640 value = easycap_control[i1].default_value;
642 if ((easycap_control[i1].minimum <= peasycap->brightness) &&
643 (easycap_control[i1].maximum >=
644 peasycap->brightness)) {
645 if (peasycap->brightness == value) {
646 SAM("unchanged brightness at 0x%02X\n",
651 peasycap->brightness = value;
652 for (k = 0; k < INPUT_MANY; k++) {
653 if (!peasycap->inputset[k].brightness_ok)
654 peasycap->inputset[k].brightness =
655 peasycap->brightness;
657 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
658 peasycap->inputset[peasycap->input].brightness =
659 peasycap->brightness;
660 peasycap->inputset[peasycap->input].brightness_ok = 1;
662 JOM(8, "%i=peasycap->input\n", peasycap->input);
663 mood = 0x00FF & (unsigned int)peasycap->brightness;
664 if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
665 SAM("adjusting brightness to 0x%02X\n", mood);
668 SAM("WARNING: failed to adjust brightness "
669 "to 0x%02X\n", mood);
676 SAM("WARNING: failed to adjust brightness: control not found\n");
679 /*****************************************************************************/
680 int adjust_contrast(struct easycap *peasycap, int value)
685 if (NULL == peasycap) {
686 SAY("ERROR: peasycap is NULL\n");
689 if ((struct usb_device *)NULL == peasycap->pusb_device) {
690 SAM("ERROR: peasycap->pusb_device is NULL\n");
694 while (0xFFFFFFFF != easycap_control[i1].id) {
695 if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
696 if ((easycap_control[i1].minimum > value) ||
697 (easycap_control[i1].maximum < value))
698 value = easycap_control[i1].default_value;
702 if ((easycap_control[i1].minimum <= peasycap->contrast) &&
703 (easycap_control[i1].maximum >=
704 peasycap->contrast)) {
705 if (peasycap->contrast == value) {
706 SAM("unchanged contrast at 0x%02X\n", value);
710 peasycap->contrast = value;
711 for (k = 0; k < INPUT_MANY; k++) {
712 if (!peasycap->inputset[k].contrast_ok) {
713 peasycap->inputset[k].contrast =
717 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
718 peasycap->inputset[peasycap->input].contrast =
720 peasycap->inputset[peasycap->input].contrast_ok = 1;
722 JOM(8, "%i=peasycap->input\n", peasycap->input);
723 mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
724 if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
725 SAM("adjusting contrast to 0x%02X\n", mood);
728 SAM("WARNING: failed to adjust contrast to "
736 SAM("WARNING: failed to adjust contrast: control not found\n");
739 /*****************************************************************************/
740 int adjust_saturation(struct easycap *peasycap, int value)
745 if (NULL == peasycap) {
746 SAY("ERROR: peasycap is NULL\n");
749 if ((struct usb_device *)NULL == peasycap->pusb_device) {
750 SAM("ERROR: peasycap->pusb_device is NULL\n");
754 while (0xFFFFFFFF != easycap_control[i1].id) {
755 if (V4L2_CID_SATURATION == easycap_control[i1].id) {
756 if ((easycap_control[i1].minimum > value) ||
757 (easycap_control[i1].maximum < value))
758 value = easycap_control[i1].default_value;
761 if ((easycap_control[i1].minimum <= peasycap->saturation) &&
762 (easycap_control[i1].maximum >=
763 peasycap->saturation)) {
764 if (peasycap->saturation == value) {
765 SAM("unchanged saturation at 0x%02X\n",
770 peasycap->saturation = value;
771 for (k = 0; k < INPUT_MANY; k++) {
772 if (!peasycap->inputset[k].saturation_ok) {
773 peasycap->inputset[k].saturation =
774 peasycap->saturation;
777 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
778 peasycap->inputset[peasycap->input].saturation =
779 peasycap->saturation;
780 peasycap->inputset[peasycap->input].saturation_ok = 1;
782 JOM(8, "%i=peasycap->input\n", peasycap->input);
783 mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
784 if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
785 SAM("adjusting saturation to 0x%02X\n", mood);
788 SAM("WARNING: failed to adjust saturation to "
796 SAM("WARNING: failed to adjust saturation: control not found\n");
799 /*****************************************************************************/
800 int adjust_hue(struct easycap *peasycap, int value)
805 if (NULL == peasycap) {
806 SAY("ERROR: peasycap is NULL\n");
809 if ((struct usb_device *)NULL == peasycap->pusb_device) {
810 SAM("ERROR: peasycap->pusb_device is NULL\n");
814 while (0xFFFFFFFF != easycap_control[i1].id) {
815 if (V4L2_CID_HUE == easycap_control[i1].id) {
816 if ((easycap_control[i1].minimum > value) ||
817 (easycap_control[i1].maximum < value))
818 value = easycap_control[i1].default_value;
820 if ((easycap_control[i1].minimum <= peasycap->hue) &&
821 (easycap_control[i1].maximum >=
823 if (peasycap->hue == value) {
824 SAM("unchanged hue at 0x%02X\n", value);
828 peasycap->hue = value;
829 for (k = 0; k < INPUT_MANY; k++) {
830 if (!peasycap->inputset[k].hue_ok)
831 peasycap->inputset[k].hue = peasycap->hue;
833 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
834 peasycap->inputset[peasycap->input].hue =
836 peasycap->inputset[peasycap->input].hue_ok = 1;
838 JOM(8, "%i=peasycap->input\n", peasycap->input);
839 i2 = peasycap->hue - 128;
840 mood = 0x00FF & ((int) i2);
841 if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
842 SAM("adjusting hue to 0x%02X\n", mood);
845 SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
852 SAM("WARNING: failed to adjust hue: control not found\n");
855 /*****************************************************************************/
856 int adjust_volume(struct easycap *peasycap, int value)
861 if (NULL == peasycap) {
862 SAY("ERROR: peasycap is NULL\n");
865 if ((struct usb_device *)NULL == peasycap->pusb_device) {
866 SAM("ERROR: peasycap->pusb_device is NULL\n");
870 while (0xFFFFFFFF != easycap_control[i1].id) {
871 if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
872 if ((easycap_control[i1].minimum > value) ||
873 (easycap_control[i1].maximum < value))
874 value = easycap_control[i1].default_value;
875 if ((easycap_control[i1].minimum <= peasycap->volume) &&
876 (easycap_control[i1].maximum >=
878 if (peasycap->volume == value) {
879 SAM("unchanged volume at 0x%02X\n", value);
883 peasycap->volume = value;
884 mood = (16 > peasycap->volume) ? 16 :
885 ((31 < peasycap->volume) ? 31 :
886 (__s8) peasycap->volume);
887 if (!audio_gainset(peasycap->pusb_device, mood)) {
888 SAM("adjusting volume to 0x%02X\n", mood);
891 SAM("WARNING: failed to adjust volume to "
899 SAM("WARNING: failed to adjust volume: control not found\n");
902 /*****************************************************************************/
903 /*---------------------------------------------------------------------------*/
905 * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
906 * usb_set_interface(peasycap->pusb_device,
907 * peasycap->audio_interface,
908 * peasycap->audio_altsetting_off);
909 * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
910 * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT
911 * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
913 /*---------------------------------------------------------------------------*/
914 static int adjust_mute(struct easycap *peasycap, int value)
918 if (NULL == peasycap) {
919 SAY("ERROR: peasycap is NULL\n");
922 if ((struct usb_device *)NULL == peasycap->pusb_device) {
923 SAM("ERROR: peasycap->pusb_device is NULL\n");
927 while (0xFFFFFFFF != easycap_control[i1].id) {
928 if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
929 peasycap->mute = value;
930 switch (peasycap->mute) {
932 peasycap->audio_idle = 1;
933 peasycap->timeval0.tv_sec = 0;
934 SAM("adjusting mute: %i=peasycap->audio_idle\n",
935 peasycap->audio_idle);
939 peasycap->audio_idle = 0;
940 SAM("adjusting mute: %i=peasycap->audio_idle\n",
941 peasycap->audio_idle);
949 SAM("WARNING: failed to adjust mute: control not found\n");
952 /*****************************************************************************/
953 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
954 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
955 (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
957 easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
958 return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg);
960 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
961 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
962 /*---------------------------------------------------------------------------*/
964 easycap_ioctl(struct inode *inode, struct file *file,
965 unsigned int cmd, unsigned long arg)
967 struct easycap *peasycap;
968 struct usb_device *p;
972 SAY("ERROR: file is NULL\n");
975 peasycap = file->private_data;
976 if (NULL == peasycap) {
977 SAY("ERROR: peasycap is NULL\n");
980 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
981 SAY("ERROR: bad peasycap\n");
984 p = peasycap->pusb_device;
986 SAM("ERROR: peasycap->pusb_device is NULL\n");
989 kd = isdongle(peasycap);
990 if (0 <= kd && DONGLE_MANY > kd) {
991 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
992 SAY("ERROR: cannot lock "
993 "easycapdc60_dongle[%i].mutex_video\n", kd);
996 JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
997 /*---------------------------------------------------------------------------*/
999 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
1000 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
1001 * IF NECESSARY, BAIL OUT.
1003 /*---------------------------------------------------------------------------*/
1004 if (kd != isdongle(peasycap))
1005 return -ERESTARTSYS;
1007 SAY("ERROR: file is NULL\n");
1008 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1009 return -ERESTARTSYS;
1011 peasycap = file->private_data;
1012 if (NULL == peasycap) {
1013 SAY("ERROR: peasycap is NULL\n");
1014 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1015 return -ERESTARTSYS;
1017 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1018 SAY("ERROR: bad peasycap\n");
1019 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1022 p = peasycap->pusb_device;
1023 if (NULL == peasycap->pusb_device) {
1024 SAM("ERROR: peasycap->pusb_device is NULL\n");
1025 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1026 return -ERESTARTSYS;
1029 /*---------------------------------------------------------------------------*/
1031 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1032 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
1034 /*---------------------------------------------------------------------------*/
1035 return -ERESTARTSYS;
1037 /*---------------------------------------------------------------------------*/
1039 case VIDIOC_QUERYCAP: {
1040 struct v4l2_capability v4l2_capability;
1041 char version[16], *p1, *p2;
1045 JOM(8, "VIDIOC_QUERYCAP\n");
1047 if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
1048 SAM("ERROR: bad driver version string\n");
1049 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1052 strcpy(&version[0], EASYCAP_DRIVER_VERSION);
1053 for (i = 0; i < 3; i++)
1055 p2 = &version[0]; i = 0;
1058 while (*p2 && ('.' != *p2))
1063 rc = (int) strict_strtol(p1, 10, &lng);
1065 SAM("ERROR: %i=strict_strtol(%s,.,,)\n",
1067 mutex_unlock(&easycapdc60_dongle[kd].
1076 memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
1077 strlcpy(&v4l2_capability.driver[0], "easycap",
1078 sizeof(v4l2_capability.driver));
1080 v4l2_capability.capabilities =
1081 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1082 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE;
1084 v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
1085 JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
1087 strlcpy(&v4l2_capability.card[0], "EasyCAP DC60",
1088 sizeof(v4l2_capability.card));
1090 if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],
1091 sizeof(v4l2_capability.bus_info)) < 0) {
1092 strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info",
1093 sizeof(v4l2_capability.bus_info));
1094 JOM(8, "%s=v4l2_capability.bus_info\n",
1095 &v4l2_capability.bus_info[0]);
1097 if (0 != copy_to_user((void __user *)arg, &v4l2_capability,
1098 sizeof(struct v4l2_capability))) {
1099 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1104 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1105 case VIDIOC_ENUMINPUT: {
1106 struct v4l2_input v4l2_input;
1109 JOM(8, "VIDIOC_ENUMINPUT\n");
1111 if (0 != copy_from_user(&v4l2_input, (void __user *)arg,
1112 sizeof(struct v4l2_input))) {
1113 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1117 index = v4l2_input.index;
1118 memset(&v4l2_input, 0, sizeof(struct v4l2_input));
1122 v4l2_input.index = index;
1123 strcpy(&v4l2_input.name[0], "CVBS0");
1124 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1125 v4l2_input.audioset = 0x01;
1126 v4l2_input.tuner = 0;
1127 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1129 v4l2_input.status = 0;
1130 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1134 v4l2_input.index = index;
1135 strcpy(&v4l2_input.name[0], "CVBS1");
1136 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1137 v4l2_input.audioset = 0x01;
1138 v4l2_input.tuner = 0;
1139 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1141 v4l2_input.status = 0;
1142 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1146 v4l2_input.index = index;
1147 strcpy(&v4l2_input.name[0], "CVBS2");
1148 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1149 v4l2_input.audioset = 0x01;
1150 v4l2_input.tuner = 0;
1151 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1153 v4l2_input.status = 0;
1154 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1158 v4l2_input.index = index;
1159 strcpy(&v4l2_input.name[0], "CVBS3");
1160 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1161 v4l2_input.audioset = 0x01;
1162 v4l2_input.tuner = 0;
1163 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1165 v4l2_input.status = 0;
1166 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1170 v4l2_input.index = index;
1171 strcpy(&v4l2_input.name[0], "CVBS4");
1172 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1173 v4l2_input.audioset = 0x01;
1174 v4l2_input.tuner = 0;
1175 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1177 v4l2_input.status = 0;
1178 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1182 v4l2_input.index = index;
1183 strcpy(&v4l2_input.name[0], "S-VIDEO");
1184 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1185 v4l2_input.audioset = 0x01;
1186 v4l2_input.tuner = 0;
1187 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1189 v4l2_input.status = 0;
1190 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1194 JOM(8, "%i=index: exhausts inputs\n", index);
1195 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1200 if (0 != copy_to_user((void __user *)arg, &v4l2_input,
1201 sizeof(struct v4l2_input))) {
1202 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1207 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1208 case VIDIOC_G_INPUT: {
1211 JOM(8, "VIDIOC_G_INPUT\n");
1212 index = (__u32)peasycap->input;
1213 JOM(8, "user is told: %i\n", index);
1214 if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
1215 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1220 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1221 case VIDIOC_S_INPUT:
1226 JOM(8, "VIDIOC_S_INPUT\n");
1228 if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
1229 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1233 JOM(8, "user requests input %i\n", index);
1235 if ((int)index == peasycap->input) {
1236 SAM("requested input already in effect\n");
1240 if ((0 > index) || (INPUT_MANY <= index)) {
1241 JOM(8, "ERROR: bad requested input: %i\n", index);
1242 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1246 rc = newinput(peasycap, (int)index);
1248 JOM(8, "newinput(.,%i) OK\n", (int)index);
1250 SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
1251 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1256 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1257 case VIDIOC_ENUMAUDIO: {
1258 JOM(8, "VIDIOC_ENUMAUDIO\n");
1259 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1262 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1263 case VIDIOC_ENUMAUDOUT: {
1264 struct v4l2_audioout v4l2_audioout;
1266 JOM(8, "VIDIOC_ENUMAUDOUT\n");
1268 if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg,
1269 sizeof(struct v4l2_audioout))) {
1270 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1274 if (0 != v4l2_audioout.index) {
1275 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1278 memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1279 v4l2_audioout.index = 0;
1280 strcpy(&v4l2_audioout.name[0], "Soundtrack");
1282 if (0 != copy_to_user((void __user *)arg, &v4l2_audioout,
1283 sizeof(struct v4l2_audioout))) {
1284 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1289 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1290 case VIDIOC_QUERYCTRL: {
1292 struct v4l2_queryctrl v4l2_queryctrl;
1294 JOM(8, "VIDIOC_QUERYCTRL\n");
1296 if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg,
1297 sizeof(struct v4l2_queryctrl))) {
1298 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1303 while (0xFFFFFFFF != easycap_control[i1].id) {
1304 if (easycap_control[i1].id == v4l2_queryctrl.id) {
1305 JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]"
1306 ".name\n", &easycap_control[i1].name[0], i1);
1307 memcpy(&v4l2_queryctrl, &easycap_control[i1],
1308 sizeof(struct v4l2_queryctrl));
1313 if (0xFFFFFFFF == easycap_control[i1].id) {
1314 JOM(8, "%i=index: exhausts controls\n", i1);
1315 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1318 if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl,
1319 sizeof(struct v4l2_queryctrl))) {
1320 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1325 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1326 case VIDIOC_QUERYMENU: {
1327 JOM(8, "VIDIOC_QUERYMENU unsupported\n");
1328 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1331 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1332 case VIDIOC_G_CTRL: {
1333 struct v4l2_control *pv4l2_control;
1335 JOM(8, "VIDIOC_G_CTRL\n");
1336 pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL);
1337 if (!pv4l2_control) {
1338 SAM("ERROR: out of memory\n");
1339 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1342 if (0 != copy_from_user(pv4l2_control, (void __user *)arg,
1343 sizeof(struct v4l2_control))) {
1344 kfree(pv4l2_control);
1345 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1349 switch (pv4l2_control->id) {
1350 case V4L2_CID_BRIGHTNESS: {
1351 pv4l2_control->value = peasycap->brightness;
1352 JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
1355 case V4L2_CID_CONTRAST: {
1356 pv4l2_control->value = peasycap->contrast;
1357 JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
1360 case V4L2_CID_SATURATION: {
1361 pv4l2_control->value = peasycap->saturation;
1362 JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
1365 case V4L2_CID_HUE: {
1366 pv4l2_control->value = peasycap->hue;
1367 JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
1370 case V4L2_CID_AUDIO_VOLUME: {
1371 pv4l2_control->value = peasycap->volume;
1372 JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
1375 case V4L2_CID_AUDIO_MUTE: {
1376 if (1 == peasycap->mute)
1377 pv4l2_control->value = true;
1379 pv4l2_control->value = false;
1380 JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
1384 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1386 kfree(pv4l2_control);
1387 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1391 if (0 != copy_to_user((void __user *)arg, pv4l2_control,
1392 sizeof(struct v4l2_control))) {
1393 kfree(pv4l2_control);
1394 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1397 kfree(pv4l2_control);
1400 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1401 #if defined(VIDIOC_S_CTRL_OLD)
1402 case VIDIOC_S_CTRL_OLD: {
1403 JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
1405 #endif /*VIDIOC_S_CTRL_OLD*/
1408 struct v4l2_control v4l2_control;
1410 JOM(8, "VIDIOC_S_CTRL\n");
1412 if (0 != copy_from_user(&v4l2_control, (void __user *)arg,
1413 sizeof(struct v4l2_control))) {
1414 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1418 switch (v4l2_control.id) {
1419 case V4L2_CID_BRIGHTNESS: {
1420 JOM(8, "user requests brightness %i\n", v4l2_control.value);
1421 if (0 != adjust_brightness(peasycap, v4l2_control.value))
1425 case V4L2_CID_CONTRAST: {
1426 JOM(8, "user requests contrast %i\n", v4l2_control.value);
1427 if (0 != adjust_contrast(peasycap, v4l2_control.value))
1431 case V4L2_CID_SATURATION: {
1432 JOM(8, "user requests saturation %i\n", v4l2_control.value);
1433 if (0 != adjust_saturation(peasycap, v4l2_control.value))
1437 case V4L2_CID_HUE: {
1438 JOM(8, "user requests hue %i\n", v4l2_control.value);
1439 if (0 != adjust_hue(peasycap, v4l2_control.value))
1443 case V4L2_CID_AUDIO_VOLUME: {
1444 JOM(8, "user requests volume %i\n", v4l2_control.value);
1445 if (0 != adjust_volume(peasycap, v4l2_control.value))
1449 case V4L2_CID_AUDIO_MUTE: {
1452 JOM(8, "user requests mute %i\n", v4l2_control.value);
1453 if (true == v4l2_control.value)
1458 if (0 != adjust_mute(peasycap, mute))
1459 SAM("WARNING: failed to adjust mute to %i\n", mute);
1463 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1465 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1471 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1472 case VIDIOC_S_EXT_CTRLS: {
1473 JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1474 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1477 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1478 case VIDIOC_ENUM_FMT: {
1480 struct v4l2_fmtdesc v4l2_fmtdesc;
1482 JOM(8, "VIDIOC_ENUM_FMT\n");
1484 if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg,
1485 sizeof(struct v4l2_fmtdesc))) {
1486 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1490 index = v4l2_fmtdesc.index;
1491 memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1493 v4l2_fmtdesc.index = index;
1494 v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1498 v4l2_fmtdesc.flags = 0;
1499 strcpy(&v4l2_fmtdesc.description[0], "uyvy");
1500 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
1501 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1505 v4l2_fmtdesc.flags = 0;
1506 strcpy(&v4l2_fmtdesc.description[0], "yuy2");
1507 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1508 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1512 v4l2_fmtdesc.flags = 0;
1513 strcpy(&v4l2_fmtdesc.description[0], "rgb24");
1514 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
1515 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1519 v4l2_fmtdesc.flags = 0;
1520 strcpy(&v4l2_fmtdesc.description[0], "rgb32");
1521 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
1522 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1526 v4l2_fmtdesc.flags = 0;
1527 strcpy(&v4l2_fmtdesc.description[0], "bgr24");
1528 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
1529 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1533 v4l2_fmtdesc.flags = 0;
1534 strcpy(&v4l2_fmtdesc.description[0], "bgr32");
1535 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
1536 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1540 JOM(8, "%i=index: exhausts formats\n", index);
1541 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1545 if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc,
1546 sizeof(struct v4l2_fmtdesc))) {
1547 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1552 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1554 * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
1555 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1557 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1558 case VIDIOC_ENUM_FRAMESIZES: {
1560 struct v4l2_frmsizeenum v4l2_frmsizeenum;
1562 JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
1564 if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg,
1565 sizeof(struct v4l2_frmsizeenum))) {
1566 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1570 index = v4l2_frmsizeenum.index;
1572 v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;
1574 if (true == peasycap->ntsc) {
1577 v4l2_frmsizeenum.discrete.width = 640;
1578 v4l2_frmsizeenum.discrete.height = 480;
1579 JOM(8, "%i=index: %ix%i\n", index,
1580 (int)(v4l2_frmsizeenum.
1582 (int)(v4l2_frmsizeenum.
1587 v4l2_frmsizeenum.discrete.width = 320;
1588 v4l2_frmsizeenum.discrete.height = 240;
1589 JOM(8, "%i=index: %ix%i\n", index,
1590 (int)(v4l2_frmsizeenum.
1592 (int)(v4l2_frmsizeenum.
1597 v4l2_frmsizeenum.discrete.width = 720;
1598 v4l2_frmsizeenum.discrete.height = 480;
1599 JOM(8, "%i=index: %ix%i\n", index,
1600 (int)(v4l2_frmsizeenum.
1602 (int)(v4l2_frmsizeenum.
1607 v4l2_frmsizeenum.discrete.width = 360;
1608 v4l2_frmsizeenum.discrete.height = 240;
1609 JOM(8, "%i=index: %ix%i\n", index,
1610 (int)(v4l2_frmsizeenum.
1612 (int)(v4l2_frmsizeenum.
1617 JOM(8, "%i=index: exhausts framesizes\n", index);
1618 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1625 v4l2_frmsizeenum.discrete.width = 640;
1626 v4l2_frmsizeenum.discrete.height = 480;
1627 JOM(8, "%i=index: %ix%i\n", index,
1628 (int)(v4l2_frmsizeenum.
1630 (int)(v4l2_frmsizeenum.
1635 v4l2_frmsizeenum.discrete.width = 320;
1636 v4l2_frmsizeenum.discrete.height = 240;
1637 JOM(8, "%i=index: %ix%i\n", index,
1638 (int)(v4l2_frmsizeenum.
1640 (int)(v4l2_frmsizeenum.
1645 v4l2_frmsizeenum.discrete.width = 704;
1646 v4l2_frmsizeenum.discrete.height = 576;
1647 JOM(8, "%i=index: %ix%i\n", index,
1648 (int)(v4l2_frmsizeenum.
1650 (int)(v4l2_frmsizeenum.
1655 v4l2_frmsizeenum.discrete.width = 720;
1656 v4l2_frmsizeenum.discrete.height = 576;
1657 JOM(8, "%i=index: %ix%i\n", index,
1658 (int)(v4l2_frmsizeenum.
1660 (int)(v4l2_frmsizeenum.
1665 v4l2_frmsizeenum.discrete.width = 360;
1666 v4l2_frmsizeenum.discrete.height = 288;
1667 JOM(8, "%i=index: %ix%i\n", index,
1668 (int)(v4l2_frmsizeenum.
1670 (int)(v4l2_frmsizeenum.
1675 JOM(8, "%i=index: exhausts framesizes\n", index);
1676 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1681 if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum,
1682 sizeof(struct v4l2_frmsizeenum))) {
1683 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1688 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1690 * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
1691 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1693 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1694 case VIDIOC_ENUM_FRAMEINTERVALS: {
1697 struct v4l2_frmivalenum v4l2_frmivalenum;
1699 JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
1702 denominator = peasycap->fps;
1704 if (true == peasycap->ntsc)
1710 if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg,
1711 sizeof(struct v4l2_frmivalenum))) {
1712 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1716 index = v4l2_frmivalenum.index;
1718 v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;
1722 v4l2_frmivalenum.discrete.numerator = 1;
1723 v4l2_frmivalenum.discrete.denominator = denominator;
1724 JOM(8, "%i=index: %i/%i\n", index,
1725 (int)(v4l2_frmivalenum.discrete.numerator),
1726 (int)(v4l2_frmivalenum.discrete.denominator));
1730 v4l2_frmivalenum.discrete.numerator = 1;
1731 v4l2_frmivalenum.discrete.denominator = denominator/5;
1732 JOM(8, "%i=index: %i/%i\n", index,
1733 (int)(v4l2_frmivalenum.discrete.numerator),
1734 (int)(v4l2_frmivalenum.discrete.denominator));
1738 JOM(8, "%i=index: exhausts frameintervals\n", index);
1739 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1743 if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum,
1744 sizeof(struct v4l2_frmivalenum))) {
1745 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1750 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1751 case VIDIOC_G_FMT: {
1752 struct v4l2_format *pv4l2_format;
1753 struct v4l2_pix_format *pv4l2_pix_format;
1755 JOM(8, "VIDIOC_G_FMT\n");
1756 pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
1757 if (!pv4l2_format) {
1758 SAM("ERROR: out of memory\n");
1759 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1762 pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
1763 if (!pv4l2_pix_format) {
1764 SAM("ERROR: out of memory\n");
1765 kfree(pv4l2_format);
1766 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1769 if (0 != copy_from_user(pv4l2_format, (void __user *)arg,
1770 sizeof(struct v4l2_format))) {
1771 kfree(pv4l2_format);
1772 kfree(pv4l2_pix_format);
1773 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1777 if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1778 kfree(pv4l2_format);
1779 kfree(pv4l2_pix_format);
1780 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1784 memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1785 pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1786 memcpy(&pv4l2_format->fmt.pix,
1787 &easycap_format[peasycap->format_offset]
1788 .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
1789 JOM(8, "user is told: %s\n",
1790 &easycap_format[peasycap->format_offset].name[0]);
1792 if (0 != copy_to_user((void __user *)arg, pv4l2_format,
1793 sizeof(struct v4l2_format))) {
1794 kfree(pv4l2_format);
1795 kfree(pv4l2_pix_format);
1796 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1799 kfree(pv4l2_format);
1800 kfree(pv4l2_pix_format);
1803 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1804 case VIDIOC_TRY_FMT:
1805 case VIDIOC_S_FMT: {
1806 struct v4l2_format v4l2_format;
1807 struct v4l2_pix_format v4l2_pix_format;
1811 if (VIDIOC_TRY_FMT == cmd) {
1812 JOM(8, "VIDIOC_TRY_FMT\n");
1815 JOM(8, "VIDIOC_S_FMT\n");
1819 if (0 != copy_from_user(&v4l2_format, (void __user *)arg,
1820 sizeof(struct v4l2_format))) {
1821 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1825 best_format = adjust_format(peasycap,
1826 v4l2_format.fmt.pix.width,
1827 v4l2_format.fmt.pix.height,
1828 v4l2_format.fmt.pix.pixelformat,
1829 v4l2_format.fmt.pix.field,
1831 if (0 > best_format) {
1832 if (-EBUSY == best_format) {
1833 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1836 JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
1837 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1840 /*...........................................................................*/
1841 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1842 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1844 memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]
1845 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
1846 JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
1848 if (0 != copy_to_user((void __user *)arg, &v4l2_format,
1849 sizeof(struct v4l2_format))) {
1850 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1855 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1856 case VIDIOC_CROPCAP: {
1857 struct v4l2_cropcap v4l2_cropcap;
1859 JOM(8, "VIDIOC_CROPCAP\n");
1861 if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg,
1862 sizeof(struct v4l2_cropcap))) {
1863 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1867 if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1868 JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1870 memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
1871 v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1872 v4l2_cropcap.bounds.left = 0;
1873 v4l2_cropcap.bounds.top = 0;
1874 v4l2_cropcap.bounds.width = peasycap->width;
1875 v4l2_cropcap.bounds.height = peasycap->height;
1876 v4l2_cropcap.defrect.left = 0;
1877 v4l2_cropcap.defrect.top = 0;
1878 v4l2_cropcap.defrect.width = peasycap->width;
1879 v4l2_cropcap.defrect.height = peasycap->height;
1880 v4l2_cropcap.pixelaspect.numerator = 1;
1881 v4l2_cropcap.pixelaspect.denominator = 1;
1883 JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1885 if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap,
1886 sizeof(struct v4l2_cropcap))) {
1887 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1892 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1894 case VIDIOC_S_CROP: {
1895 JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
1896 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1899 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1900 case VIDIOC_QUERYSTD: {
1901 JOM(8, "VIDIOC_QUERYSTD: "
1902 "EasyCAP is incapable of detecting standard\n");
1903 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1907 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1908 /*---------------------------------------------------------------------------*/
1910 * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND
1911 * FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer.
1912 * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
1914 /*---------------------------------------------------------------------------*/
1915 case VIDIOC_ENUMSTD: {
1916 int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1917 struct v4l2_standard v4l2_standard;
1919 struct easycap_standard const *peasycap_standard;
1921 JOM(8, "VIDIOC_ENUMSTD\n");
1923 if (0 != copy_from_user(&v4l2_standard, (void __user *)arg,
1924 sizeof(struct v4l2_standard))) {
1925 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1928 index = v4l2_standard.index;
1930 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1931 if ((index == last3) && (index == last2) &&
1932 (index == last1) && (index == last0)) {
1934 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1937 memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1939 peasycap_standard = &easycap_standard[0];
1940 while (0xFFFF != peasycap_standard->mask) {
1941 if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1943 peasycap_standard++;
1945 if (0xFFFF == peasycap_standard->mask) {
1946 JOM(8, "%i=index: exhausts standards\n", index);
1947 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1950 JOM(8, "%i=index: %s\n", index,
1951 &(peasycap_standard->v4l2_standard.name[0]));
1952 memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard),
1953 sizeof(struct v4l2_standard));
1955 v4l2_standard.index = index;
1957 if (0 != copy_to_user((void __user *)arg, &v4l2_standard,
1958 sizeof(struct v4l2_standard))) {
1959 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1964 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1965 case VIDIOC_G_STD: {
1967 struct easycap_standard const *peasycap_standard;
1969 JOM(8, "VIDIOC_G_STD\n");
1971 if (0 > peasycap->standard_offset) {
1972 JOM(8, "%i=peasycap->standard_offset\n",
1973 peasycap->standard_offset);
1974 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1978 if (0 != copy_from_user(&std_id, (void __user *)arg,
1979 sizeof(v4l2_std_id))) {
1980 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1984 peasycap_standard = &easycap_standard[peasycap->standard_offset];
1985 std_id = peasycap_standard->v4l2_standard.id;
1987 JOM(8, "user is told: %s\n",
1988 &peasycap_standard->v4l2_standard.name[0]);
1990 if (0 != copy_to_user((void __user *)arg, &std_id,
1991 sizeof(v4l2_std_id))) {
1992 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1997 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1998 case VIDIOC_S_STD: {
2002 JOM(8, "VIDIOC_S_STD\n");
2004 if (0 != copy_from_user(&std_id, (void __user *)arg,
2005 sizeof(v4l2_std_id))) {
2006 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2010 JOM(8, "User requests standard: 0x%08X%08X\n",
2011 (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32),
2012 (int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
2014 rc = adjust_standard(peasycap, std_id);
2016 JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
2017 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2022 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2023 case VIDIOC_REQBUFS: {
2025 struct v4l2_requestbuffers v4l2_requestbuffers;
2027 JOM(8, "VIDIOC_REQBUFS\n");
2029 if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg,
2030 sizeof(struct v4l2_requestbuffers))) {
2031 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2035 if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2036 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2039 if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
2040 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2043 nbuffers = v4l2_requestbuffers.count;
2044 JOM(8, " User requests %i buffers ...\n", nbuffers);
2047 if (nbuffers > FRAME_BUFFER_MANY)
2048 nbuffers = FRAME_BUFFER_MANY;
2049 if (v4l2_requestbuffers.count == nbuffers) {
2050 JOM(8, " ... agree to %i buffers\n",
2053 JOM(8, " ... insist on %i buffers\n",
2055 v4l2_requestbuffers.count = nbuffers;
2057 peasycap->frame_buffer_many = nbuffers;
2059 if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers,
2060 sizeof(struct v4l2_requestbuffers))) {
2061 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2066 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2067 case VIDIOC_QUERYBUF: {
2069 struct v4l2_buffer v4l2_buffer;
2071 JOM(8, "VIDIOC_QUERYBUF\n");
2073 if (peasycap->video_eof) {
2074 JOM(8, "returning -EIO because %i=video_eof\n",
2075 peasycap->video_eof);
2076 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2080 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2081 sizeof(struct v4l2_buffer))) {
2082 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2086 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2087 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2090 index = v4l2_buffer.index;
2091 if (index < 0 || index >= peasycap->frame_buffer_many)
2093 memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
2094 v4l2_buffer.index = index;
2095 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2096 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2097 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED |
2098 peasycap->done[index] |
2099 peasycap->queued[index];
2100 v4l2_buffer.field = V4L2_FIELD_NONE;
2101 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2102 v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
2103 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2105 JOM(16, " %10i=index\n", v4l2_buffer.index);
2106 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2107 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2108 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2109 JOM(16, " %10i=field\n", v4l2_buffer.field);
2110 JOM(16, " %10li=timestamp.tv_usec\n",
2111 (long)v4l2_buffer.timestamp.tv_usec);
2112 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2113 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2114 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2115 JOM(16, " %10i=length\n", v4l2_buffer.length);
2117 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2118 sizeof(struct v4l2_buffer))) {
2119 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2124 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2126 struct v4l2_buffer v4l2_buffer;
2128 JOM(8, "VIDIOC_QBUF\n");
2130 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2131 sizeof(struct v4l2_buffer))) {
2132 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2136 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2137 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2140 if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
2141 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2144 if (v4l2_buffer.index < 0 ||
2145 (v4l2_buffer.index >= peasycap->frame_buffer_many)) {
2146 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2149 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
2151 peasycap->done[v4l2_buffer.index] = 0;
2152 peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
2154 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2155 sizeof(struct v4l2_buffer))) {
2156 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2160 JOM(8, "..... user queueing frame buffer %i\n",
2161 (int)v4l2_buffer.index);
2163 peasycap->frame_lock = 0;
2167 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2170 #if defined(AUDIOTIME)
2171 struct signed_div_result sdr;
2172 long long int above, below, dnbydt, fudge, sll;
2173 unsigned long long int ull;
2174 struct timeval timeval8;
2175 struct timeval timeval1;
2176 #endif /*AUDIOTIME*/
2177 struct timeval timeval, timeval2;
2179 struct v4l2_buffer v4l2_buffer;
2183 JOM(8, "VIDIOC_DQBUF\n");
2185 if ((peasycap->video_idle) || (peasycap->video_eof)) {
2186 JOM(8, "returning -EIO because "
2187 "%i=video_idle %i=video_eof\n",
2188 peasycap->video_idle, peasycap->video_eof);
2189 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2193 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2194 sizeof(struct v4l2_buffer))) {
2195 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2199 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2200 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2204 if (true == peasycap->offerfields) {
2205 /*-----------------------------------------------------------*/
2207 * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
2210 /*-----------------------------------------------------------*/
2211 if (V4L2_FIELD_TOP == v4l2_buffer.field)
2212 JOM(8, "user wants V4L2_FIELD_TOP\n");
2213 else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
2214 JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
2215 else if (V4L2_FIELD_ANY == v4l2_buffer.field)
2216 JOM(8, "user wants V4L2_FIELD_ANY\n");
2218 JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n",
2222 if (!peasycap->video_isoc_streaming) {
2223 JOM(16, "returning -EIO because video urbs not streaming\n");
2224 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2227 /*---------------------------------------------------------------------------*/
2229 * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
2230 * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS
2231 * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
2233 /*---------------------------------------------------------------------------*/
2235 if (!peasycap->polled) {
2237 rcdq = easycap_dqbuf(peasycap, 0);
2239 JOM(8, "returning -EIO because "
2240 "dqbuf() returned -EIO\n");
2241 mutex_unlock(&easycapdc60_dongle[kd].
2245 } while (0 != rcdq);
2247 if (peasycap->video_eof) {
2248 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2252 if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
2253 JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n",
2254 peasycap->done[peasycap->frame_read]);
2256 peasycap->polled = 0;
2258 if (!(peasycap->isequence % 10)) {
2259 for (i = 0; i < 179; i++)
2260 peasycap->merit[i] = peasycap->merit[i+1];
2261 peasycap->merit[179] = merit_saa(peasycap->pusb_device);
2263 for (i = 0; i < 180; i++)
2264 j += peasycap->merit[i];
2266 SAM("easycap driver shutting down "
2267 "on condition blue\n");
2268 peasycap->video_eof = 1; peasycap->audio_eof = 1;
2272 v4l2_buffer.index = peasycap->frame_read;
2273 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2274 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2275 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
2276 if (true == peasycap->offerfields)
2277 v4l2_buffer.field = V4L2_FIELD_BOTTOM;
2279 v4l2_buffer.field = V4L2_FIELD_NONE;
2280 do_gettimeofday(&timeval);
2283 #if defined(AUDIOTIME)
2284 if (!peasycap->timeval0.tv_sec) {
2289 peasycap->timeval0 = timeval8;
2291 dnbydt = peasycap->dnbydt;
2292 timeval1 = peasycap->timeval1;
2293 above = dnbydt * MICROSECONDS(timeval, timeval1);
2295 sdr = signed_div(above, below);
2297 above = sdr.quotient + timeval1.tv_usec - 350000;
2300 sdr = signed_div(above, below);
2301 timeval2.tv_usec = sdr.remainder;
2302 timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
2304 if (!(peasycap->isequence % 500)) {
2305 fudge = ((long long int)(1000000)) *
2306 ((long long int)(timeval.tv_sec -
2308 (long long int)(timeval.tv_usec -
2310 sdr = signed_div(fudge, 1000);
2312 ull = sdr.remainder;
2314 SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
2316 #endif /*AUDIOTIME*/
2318 v4l2_buffer.timestamp = timeval2;
2319 v4l2_buffer.sequence = peasycap->isequence++;
2320 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2321 v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
2322 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2324 JOM(16, " %10i=index\n", v4l2_buffer.index);
2325 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2326 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2327 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2328 JOM(16, " %10i=field\n", v4l2_buffer.field);
2329 JOM(16, " %10li=timestamp.tv_sec\n",
2330 (long)v4l2_buffer.timestamp.tv_sec);
2331 JOM(16, " %10li=timestamp.tv_usec\n",
2332 (long)v4l2_buffer.timestamp.tv_usec);
2333 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2334 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2335 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2336 JOM(16, " %10i=length\n", v4l2_buffer.length);
2338 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2339 sizeof(struct v4l2_buffer))) {
2340 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2344 input = peasycap->frame_buffer[peasycap->frame_read][0].input;
2346 JOM(8, "user is offered frame buffer %i, input %i\n",
2347 peasycap->frame_read, (0x07 & input));
2349 JOM(8, "user is offered frame buffer %i\n",
2350 peasycap->frame_read);
2352 peasycap->frame_lock = 1;
2353 JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
2354 if (peasycap->frame_read == peasycap->frame_fill) {
2355 if (peasycap->frame_lock) {
2356 JOM(8, "WORRY: filling frame buffer "
2357 "while offered to user\n");
2362 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2363 case VIDIOC_STREAMON: {
2366 JOM(8, "VIDIOC_STREAMON\n");
2368 peasycap->isequence = 0;
2369 for (i = 0; i < 180; i++)
2370 peasycap->merit[i] = 0;
2371 if ((struct usb_device *)NULL == peasycap->pusb_device) {
2372 SAM("ERROR: peasycap->pusb_device is NULL\n");
2373 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2376 submit_video_urbs(peasycap);
2377 peasycap->video_idle = 0;
2378 peasycap->audio_idle = 0;
2379 peasycap->video_eof = 0;
2380 peasycap->audio_eof = 0;
2383 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2384 case VIDIOC_STREAMOFF: {
2385 JOM(8, "VIDIOC_STREAMOFF\n");
2387 if ((struct usb_device *)NULL == peasycap->pusb_device) {
2388 SAM("ERROR: peasycap->pusb_device is NULL\n");
2389 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2393 peasycap->video_idle = 1;
2394 peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0;
2395 /*---------------------------------------------------------------------------*/
2397 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
2398 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2400 /*---------------------------------------------------------------------------*/
2401 JOM(8, "calling wake_up on wq_video and wq_audio\n");
2402 wake_up_interruptible(&(peasycap->wq_video));
2403 #if defined(EASYCAP_NEEDS_ALSA)
2404 if (NULL != peasycap->psubstream)
2405 snd_pcm_period_elapsed(peasycap->psubstream);
2407 wake_up_interruptible(&(peasycap->wq_audio));
2408 #endif /*EASYCAP_NEEDS_ALSA*/
2409 /*---------------------------------------------------------------------------*/
2412 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2413 case VIDIOC_G_PARM: {
2414 struct v4l2_streamparm *pv4l2_streamparm;
2416 JOM(8, "VIDIOC_G_PARM\n");
2417 pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL);
2418 if (!pv4l2_streamparm) {
2419 SAM("ERROR: out of memory\n");
2420 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2423 if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg,
2424 sizeof(struct v4l2_streamparm))) {
2425 kfree(pv4l2_streamparm);
2426 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2430 if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2431 kfree(pv4l2_streamparm);
2432 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2435 pv4l2_streamparm->parm.capture.capability = 0;
2436 pv4l2_streamparm->parm.capture.capturemode = 0;
2437 pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
2439 if (peasycap->fps) {
2440 pv4l2_streamparm->parm.capture.timeperframe.
2441 denominator = peasycap->fps;
2443 if (true == peasycap->ntsc) {
2444 pv4l2_streamparm->parm.capture.timeperframe.
2447 pv4l2_streamparm->parm.capture.timeperframe.
2452 pv4l2_streamparm->parm.capture.readbuffers =
2453 peasycap->frame_buffer_many;
2454 pv4l2_streamparm->parm.capture.extendedmode = 0;
2455 if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm,
2456 sizeof(struct v4l2_streamparm))) {
2457 kfree(pv4l2_streamparm);
2458 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2461 kfree(pv4l2_streamparm);
2464 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2465 case VIDIOC_S_PARM: {
2466 JOM(8, "VIDIOC_S_PARM unsupported\n");
2467 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2470 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2471 case VIDIOC_G_AUDIO: {
2472 JOM(8, "VIDIOC_G_AUDIO unsupported\n");
2473 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2476 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2477 case VIDIOC_S_AUDIO: {
2478 JOM(8, "VIDIOC_S_AUDIO unsupported\n");
2479 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2482 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2483 case VIDIOC_S_TUNER: {
2484 JOM(8, "VIDIOC_S_TUNER unsupported\n");
2485 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2488 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2491 case VIDIOC_OVERLAY: {
2492 JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
2493 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2496 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2497 case VIDIOC_G_TUNER: {
2498 JOM(8, "VIDIOC_G_TUNER unsupported\n");
2499 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2502 case VIDIOC_G_FREQUENCY:
2503 case VIDIOC_S_FREQUENCY: {
2504 JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
2505 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2508 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2510 JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
2511 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2512 return -ENOIOCTLCMD;
2515 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2516 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
2519 /*****************************************************************************/
2520 #ifdef CONFIG_EASYCAP_OSS
2521 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2522 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
2523 (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
2525 easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
2526 return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg);
2528 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
2529 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
2530 /*---------------------------------------------------------------------------*/
2532 easyoss_ioctl(struct inode *inode, struct file *file,
2533 unsigned int cmd, unsigned long arg)
2535 struct easycap *peasycap;
2536 struct usb_device *p;
2540 SAY("ERROR: file is NULL\n");
2541 return -ERESTARTSYS;
2543 peasycap = file->private_data;
2544 if (NULL == peasycap) {
2545 SAY("ERROR: peasycap is NULL.\n");
2548 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2549 SAY("ERROR: bad peasycap\n");
2552 p = peasycap->pusb_device;
2554 SAM("ERROR: peasycap->pusb_device is NULL\n");
2557 kd = isdongle(peasycap);
2558 if (0 <= kd && DONGLE_MANY > kd) {
2559 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
2560 SAY("ERROR: cannot lock "
2561 "easycapdc60_dongle[%i].mutex_audio\n", kd);
2562 return -ERESTARTSYS;
2564 JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
2565 /*---------------------------------------------------------------------------*/
2567 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
2568 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
2569 * IF NECESSARY, BAIL OUT.
2571 /*---------------------------------------------------------------------------*/
2572 if (kd != isdongle(peasycap))
2573 return -ERESTARTSYS;
2575 SAY("ERROR: file is NULL\n");
2576 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2577 return -ERESTARTSYS;
2579 peasycap = file->private_data;
2580 if (NULL == peasycap) {
2581 SAY("ERROR: peasycap is NULL\n");
2582 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2583 return -ERESTARTSYS;
2585 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2586 SAY("ERROR: bad peasycap\n");
2587 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2590 p = peasycap->pusb_device;
2591 if (NULL == peasycap->pusb_device) {
2592 SAM("ERROR: peasycap->pusb_device is NULL\n");
2593 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2594 return -ERESTARTSYS;
2597 /*---------------------------------------------------------------------------*/
2599 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
2600 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
2602 /*---------------------------------------------------------------------------*/
2603 return -ERESTARTSYS;
2605 /*---------------------------------------------------------------------------*/
2607 case SNDCTL_DSP_GETCAPS: {
2609 JOM(8, "SNDCTL_DSP_GETCAPS\n");
2611 #if defined(UPSAMPLE)
2612 if (true == peasycap->microphone)
2617 if (true == peasycap->microphone)
2623 if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
2624 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2629 case SNDCTL_DSP_GETFMTS: {
2631 JOM(8, "SNDCTL_DSP_GETFMTS\n");
2633 #if defined(UPSAMPLE)
2634 if (true == peasycap->microphone)
2635 incoming = AFMT_S16_LE;
2637 incoming = AFMT_S16_LE;
2639 if (true == peasycap->microphone)
2640 incoming = AFMT_S16_LE;
2642 incoming = AFMT_S16_LE;
2645 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2646 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2651 case SNDCTL_DSP_SETFMT: {
2652 int incoming, outgoing;
2653 JOM(8, "SNDCTL_DSP_SETFMT\n");
2654 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2655 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2658 JOM(8, "........... %i=incoming\n", incoming);
2660 #if defined(UPSAMPLE)
2661 if (true == peasycap->microphone)
2662 outgoing = AFMT_S16_LE;
2664 outgoing = AFMT_S16_LE;
2666 if (true == peasycap->microphone)
2667 outgoing = AFMT_S16_LE;
2669 outgoing = AFMT_S16_LE;
2672 if (incoming != outgoing) {
2673 JOM(8, "........... %i=outgoing\n", outgoing);
2674 JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
2675 JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8);
2676 if (0 != copy_to_user((void __user *)arg, &outgoing,
2678 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2681 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2686 case SNDCTL_DSP_STEREO: {
2688 JOM(8, "SNDCTL_DSP_STEREO\n");
2689 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2690 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2693 JOM(8, "........... %i=incoming\n", incoming);
2695 #if defined(UPSAMPLE)
2696 if (true == peasycap->microphone)
2701 if (true == peasycap->microphone)
2707 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2708 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2713 case SNDCTL_DSP_SPEED: {
2715 JOM(8, "SNDCTL_DSP_SPEED\n");
2716 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2717 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2720 JOM(8, "........... %i=incoming\n", incoming);
2722 #if defined(UPSAMPLE)
2723 if (true == peasycap->microphone)
2728 if (true == peasycap->microphone)
2734 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2735 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2740 case SNDCTL_DSP_GETTRIGGER: {
2742 JOM(8, "SNDCTL_DSP_GETTRIGGER\n");
2743 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2744 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2747 JOM(8, "........... %i=incoming\n", incoming);
2749 incoming = PCM_ENABLE_INPUT;
2750 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2751 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2756 case SNDCTL_DSP_SETTRIGGER: {
2758 JOM(8, "SNDCTL_DSP_SETTRIGGER\n");
2759 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2760 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2763 JOM(8, "........... %i=incoming\n", incoming);
2764 JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT "
2765 "0x%x=PCM_ENABLE_OUTPUT\n",
2766 PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
2773 case SNDCTL_DSP_GETBLKSIZE: {
2775 JOM(8, "SNDCTL_DSP_GETBLKSIZE\n");
2776 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2777 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2780 JOM(8, "........... %i=incoming\n", incoming);
2781 incoming = peasycap->audio_bytes_per_fragment;
2782 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2783 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2788 case SNDCTL_DSP_GETISPACE: {
2789 struct audio_buf_info audio_buf_info;
2791 JOM(8, "SNDCTL_DSP_GETISPACE\n");
2793 audio_buf_info.bytes = peasycap->audio_bytes_per_fragment;
2794 audio_buf_info.fragments = 1;
2795 audio_buf_info.fragsize = 0;
2796 audio_buf_info.fragstotal = 0;
2798 if (0 != copy_to_user((void __user *)arg, &audio_buf_info,
2800 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2811 JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
2812 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2813 return -ENOIOCTLCMD;
2816 JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2817 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2818 return -ENOIOCTLCMD;
2821 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2824 #endif /* CONFIG_EASYCAP_OSS */
2825 /*****************************************************************************/