1 /******************************************************************************
5 ******************************************************************************/
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>
30 #include "easycap_debug.h"
31 #include "easycap_standard.h"
32 #include "easycap_ioctl.h"
34 /*--------------------------------------------------------------------------*/
36 * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
38 * peasycap->standard_offset
39 * peasycap->inputset[peasycap->input].standard_offset
45 /*---------------------------------------------------------------------------*/
46 int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
48 struct easycap_standard const *peasycap_standard;
51 unsigned int itwas, isnow;
54 if (NULL == peasycap) {
55 SAY("ERROR: peasycap is NULL\n");
58 if ((struct usb_device *)NULL == peasycap->pusb_device) {
59 SAM("ERROR: peasycap->pusb_device is NULL\n");
62 peasycap_standard = &easycap_standard[0];
63 while (0xFFFF != peasycap_standard->mask) {
64 if (std_id == peasycap_standard->v4l2_standard.id)
68 if (0xFFFF == peasycap_standard->mask) {
69 peasycap_standard = &easycap_standard[0];
70 while (0xFFFF != peasycap_standard->mask) {
71 if (std_id & peasycap_standard->v4l2_standard.id)
76 if (0xFFFF == peasycap_standard->mask) {
77 SAM("ERROR: 0x%08X=std_id: standard not found\n", \
78 (unsigned int)std_id);
81 SAM("selected standard: %s\n", \
82 &(peasycap_standard->v4l2_standard.name[0]));
83 if (peasycap->standard_offset == \
84 (int)(peasycap_standard - &easycap_standard[0])) {
85 SAM("requested standard already in effect\n");
88 peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
89 for (k = 0; k < INPUT_MANY; k++) {
90 if (!peasycap->inputset[k].standard_offset_ok) {
91 peasycap->inputset[k].standard_offset = \
92 peasycap->standard_offset;
95 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
96 peasycap->inputset[peasycap->input].standard_offset = \
97 peasycap->standard_offset;
98 peasycap->inputset[peasycap->input].standard_offset_ok = 1;
100 JOM(8, "%i=peasycap->input\n", peasycap->input);
101 peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
102 peasycap_standard->v4l2_standard.frameperiod.numerator;
103 switch (peasycap->fps) {
106 peasycap->ntsc = true;
111 peasycap->ntsc = false;
115 SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
119 JOM(8, "%i frames-per-second\n", peasycap->fps);
120 if (0x8000 & peasycap_standard->mask) {
122 peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
123 peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
126 peasycap->usec = 1000000 / (2 * peasycap->fps);
127 peasycap->tolerate = 1000 * (25 / peasycap->fps);
129 if (peasycap->video_isoc_streaming) {
131 kill_video_urbs(peasycap);
134 /*--------------------------------------------------------------------------*/
136 * SAA7113H DATASHEET PAGE 44, TABLE 42
138 /*--------------------------------------------------------------------------*/
139 need = 0; itwas = 0; reg = 0x00; set = 0x00;
140 switch (peasycap_standard->mask & 0x000F) {
142 reg = 0x0A; set = 0x95;
143 ir = read_saa(peasycap->pusb_device, reg);
145 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
147 itwas = (unsigned int)ir;
148 rc = write_saa(peasycap->pusb_device, reg, set);
150 SAM("ERROR: failed to set SAA register " \
151 "0x%02X to 0x%02X for JP standard\n", reg, set);
153 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
155 JOM(8, "SAA register 0x%02X changed " \
156 "to 0x%02X\n", reg, isnow);
158 JOM(8, "SAA register 0x%02X changed " \
159 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
162 reg = 0x0B; set = 0x48;
163 ir = read_saa(peasycap->pusb_device, reg);
165 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
167 itwas = (unsigned int)ir;
168 rc = write_saa(peasycap->pusb_device, reg, set);
170 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \
171 "for JP standard\n", reg, set);
173 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
175 JOM(8, "SAA register 0x%02X changed " \
176 "to 0x%02X\n", reg, isnow);
178 JOM(8, "SAA register 0x%02X changed " \
179 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
181 /*--------------------------------------------------------------------------*/
183 * NOTE: NO break HERE: RUN ON TO NEXT CASE
185 /*--------------------------------------------------------------------------*/
189 reg = 0x0E; set = 0x01; need = 1; break;
193 reg = 0x0E; set = 0x11; need = 1; break;
197 reg = 0x0E; set = 0x21; need = 1; break;
201 reg = 0x0E; set = 0x31; need = 1; break;
204 reg = 0x0E; set = 0x51; need = 1; break;
209 /*--------------------------------------------------------------------------*/
211 ir = read_saa(peasycap->pusb_device, reg);
213 SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
215 itwas = (unsigned int)ir;
216 rc = write_saa(peasycap->pusb_device, reg, set);
217 if (0 != write_saa(peasycap->pusb_device, reg, set)) {
218 SAM("ERROR: failed to set SAA register " \
219 "0x%02X to 0x%02X for table 42\n", reg, set);
221 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
223 JOM(8, "SAA register 0x%02X changed " \
224 "to 0x%02X\n", reg, isnow);
226 JOM(8, "SAA register 0x%02X changed " \
227 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
230 /*--------------------------------------------------------------------------*/
232 * SAA7113H DATASHEET PAGE 41
234 /*--------------------------------------------------------------------------*/
236 ir = read_saa(peasycap->pusb_device, reg);
238 SAM("ERROR: failed to read SAA register 0x%02X " \
239 "so cannot reset\n", reg);
241 itwas = (unsigned int)ir;
242 if (peasycap_standard->mask & 0x0001)
245 set = itwas & ~0x40 ;
246 rc = write_saa(peasycap->pusb_device, reg, set);
248 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
251 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
253 JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
256 JOM(8, "SAA register 0x%02X changed " \
257 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
260 /*--------------------------------------------------------------------------*/
262 * SAA7113H DATASHEET PAGE 51, TABLE 57
264 /*---------------------------------------------------------------------------*/
266 ir = read_saa(peasycap->pusb_device, reg);
268 SAM("ERROR: failed to read SAA register 0x%02X " \
269 "so cannot reset\n", reg);
271 itwas = (unsigned int)ir;
272 if (peasycap_standard->mask & 0x0001)
275 set = itwas & ~0x80 ;
276 rc = write_saa(peasycap->pusb_device, reg, set);
278 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
281 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
283 JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
286 JOM(8, "SAA register 0x%02X changed " \
287 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
290 /*--------------------------------------------------------------------------*/
292 * SAA7113H DATASHEET PAGE 53, TABLE 66
294 /*--------------------------------------------------------------------------*/
296 ir = read_saa(peasycap->pusb_device, reg);
298 SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
299 itwas = (unsigned int)ir;
300 if (peasycap_standard->mask & 0x0001)
304 if (0 != write_saa(peasycap->pusb_device, reg, set))
305 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
308 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
310 JOM(8, "SAA register 0x%02X changed "
311 "to 0x%02X\n", reg, isnow);
313 JOM(8, "SAA register 0x%02X changed "
314 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
316 if (true == resubmit)
317 submit_video_urbs(peasycap);
320 /*****************************************************************************/
321 /*--------------------------------------------------------------------------*/
323 * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
324 * A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
326 * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
327 * THIS ROUTINE UPDATES THE FOLLOWING:
328 * peasycap->format_offset
329 * peasycap->inputset[peasycap->input].format_offset
330 * peasycap->pixelformat
333 * peasycap->bytesperpixel
334 * peasycap->byteswaporder
335 * peasycap->decimatepixel
336 * peasycap->frame_buffer_used
337 * peasycap->videofieldamount
338 * peasycap->offerfields
340 * IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
341 * IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
342 * ERRORS RETURN A NEGATIVE NUMBER.
344 /*--------------------------------------------------------------------------*/
345 int adjust_format(struct easycap *peasycap, \
346 __u32 width, __u32 height, __u32 pixelformat, int field, bool try)
348 struct easycap_format *peasycap_format, *peasycap_best_format;
350 struct usb_device *p;
351 int miss, multiplier, best, k;
352 char bf[5], fo[32], *pc;
356 if (NULL == peasycap) {
357 SAY("ERROR: peasycap is NULL\n");
360 if (0 > peasycap->standard_offset) {
361 JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
364 p = peasycap->pusb_device;
365 if ((struct usb_device *)NULL == p) {
366 SAM("ERROR: peaycap->pusb_device is NULL\n");
371 memcpy((void *)pc, (void *)(&uc), 4);
373 mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
374 SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
375 width, height, pc, pixelformat, field, mask);
377 case V4L2_FIELD_ANY: {
378 strcpy(&fo[0], "V4L2_FIELD_ANY ");
381 case V4L2_FIELD_NONE: {
382 strcpy(&fo[0], "V4L2_FIELD_NONE");
385 case V4L2_FIELD_TOP: {
386 strcpy(&fo[0], "V4L2_FIELD_TOP");
389 case V4L2_FIELD_BOTTOM: {
390 strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
393 case V4L2_FIELD_INTERLACED: {
394 strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
397 case V4L2_FIELD_SEQ_TB: {
398 strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
401 case V4L2_FIELD_SEQ_BT: {
402 strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
405 case V4L2_FIELD_ALTERNATE: {
406 strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
409 case V4L2_FIELD_INTERLACED_TB: {
410 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
413 case V4L2_FIELD_INTERLACED_BT: {
414 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
418 strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN ");
422 SAM("sought: %s\n", &fo[0]);
423 if (V4L2_FIELD_ANY == field) {
424 field = V4L2_FIELD_NONE;
425 SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
427 peasycap_best_format = (struct easycap_format *)NULL;
428 peasycap_format = &easycap_format[0];
429 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
430 JOM(16, ".> %i %i 0x%08X %ix%i\n", \
431 peasycap_format->mask & 0x01,
432 peasycap_format->v4l2_format.fmt.pix.field,
433 peasycap_format->v4l2_format.fmt.pix.pixelformat,
434 peasycap_format->v4l2_format.fmt.pix.width,
435 peasycap_format->v4l2_format.fmt.pix.height);
437 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
438 (peasycap_format->v4l2_format.fmt.pix.field == field) && \
439 (peasycap_format->v4l2_format.fmt.pix.pixelformat == \
441 (peasycap_format->v4l2_format.fmt.pix.width == width) && \
442 (peasycap_format->v4l2_format.fmt.pix.height == height)) {
443 peasycap_best_format = peasycap_format;
448 if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
449 SAM("cannot do: %ix%i with standard mask 0x%02X\n", \
450 width, height, mask);
451 peasycap_format = &easycap_format[0]; best = -1;
452 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
453 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
454 (peasycap_format->v4l2_format.fmt.pix\
455 .field == field) && \
456 (peasycap_format->v4l2_format.fmt.pix\
457 .pixelformat == pixelformat)) {
458 miss = abs(peasycap_format->\
459 v4l2_format.fmt.pix.width - width);
460 if ((best > miss) || (best < 0)) {
462 peasycap_best_format = peasycap_format;
470 SAM("cannot do %ix... with standard mask 0x%02X\n", \
472 SAM("cannot do ...x%i with standard mask 0x%02X\n", \
474 SAM(" %ix%i unmatched\n", width, height);
475 return peasycap->format_offset;
478 if ((struct easycap_format *)NULL == peasycap_best_format) {
479 SAM("MISTAKE: peasycap_best_format is NULL");
482 peasycap_format = peasycap_best_format;
484 /*...........................................................................*/
486 return (int)(peasycap_best_format - &easycap_format[0]);
487 /*...........................................................................*/
490 SAM("MISTAKE: true==try where is should be false\n");
493 SAM("actioning: %ix%i %s\n", \
494 peasycap_format->v4l2_format.fmt.pix.width, \
495 peasycap_format->v4l2_format.fmt.pix.height,
496 &peasycap_format->name[0]);
497 peasycap->height = peasycap_format->v4l2_format.fmt.pix.height;
498 peasycap->width = peasycap_format->v4l2_format.fmt.pix.width;
499 peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat;
500 peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
503 for (k = 0; k < INPUT_MANY; k++) {
504 if (!peasycap->inputset[k].format_offset_ok) {
505 peasycap->inputset[k].format_offset = \
506 peasycap->format_offset;
509 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
510 peasycap->inputset[peasycap->input].format_offset = \
511 peasycap->format_offset;
512 peasycap->inputset[peasycap->input].format_offset_ok = 1;
514 JOM(8, "%i=peasycap->input\n", peasycap->input);
518 peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
519 if (0x0100 & peasycap_format->mask)
520 peasycap->byteswaporder = true;
522 peasycap->byteswaporder = false;
523 if (0x0200 & peasycap_format->mask)
527 if (0x0800 & peasycap_format->mask)
528 peasycap->decimatepixel = true;
530 peasycap->decimatepixel = false;
531 if (0x1000 & peasycap_format->mask)
532 peasycap->offerfields = true;
534 peasycap->offerfields = false;
535 if (true == peasycap->decimatepixel)
539 peasycap->videofieldamount = multiplier * peasycap->width * \
540 multiplier * peasycap->height;
541 peasycap->frame_buffer_used = peasycap->bytesperpixel * \
542 peasycap->width * peasycap->height;
543 if (peasycap->video_isoc_streaming) {
545 kill_video_urbs(peasycap);
548 /*---------------------------------------------------------------------------*/
552 /*---------------------------------------------------------------------------*/
553 if (0 == (0x01 & peasycap_format->mask)) {
554 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
556 peasycap_format->v4l2_format.fmt.pix.height)) || \
558 peasycap_format->v4l2_format.fmt.pix.width) && \
560 peasycap_format->v4l2_format.fmt.pix.height))) {
561 if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
562 SAM("ERROR: set_resolution() failed\n");
565 } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \
566 (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
567 if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
568 SAM("ERROR: set_resolution() failed\n");
571 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
573 peasycap_format->v4l2_format.fmt.pix.height)) || \
575 peasycap_format->v4l2_format.fmt.pix.width) && \
577 peasycap_format->v4l2_format.fmt.pix.height))) {
578 if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
579 SAM("ERROR: set_resolution() failed\n");
583 SAM("MISTAKE: bad format, cannot set resolution\n");
586 /*---------------------------------------------------------------------------*/
590 /*---------------------------------------------------------------------------*/
592 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
594 peasycap_format->v4l2_format.fmt.pix.height)) || \
596 peasycap_format->v4l2_format.fmt.pix.width) && \
598 peasycap_format->v4l2_format.fmt.pix.height))) {
599 if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
600 SAM("ERROR: set_resolution() failed\n");
603 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
605 peasycap_format->v4l2_format.fmt.pix.height)) || \
607 peasycap_format->v4l2_format.fmt.pix.width) && \
609 peasycap_format->v4l2_format.fmt.pix.height))) {
610 if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
611 SAM("ERROR: set_resolution() failed\n");
615 SAM("MISTAKE: bad format, cannot set resolution\n");
619 /*---------------------------------------------------------------------------*/
620 if (true == resubmit)
621 submit_video_urbs(peasycap);
622 return (int)(peasycap_best_format - &easycap_format[0]);
624 /*****************************************************************************/
625 int adjust_brightness(struct easycap *peasycap, int value)
630 if (NULL == peasycap) {
631 SAY("ERROR: peasycap is NULL\n");
634 if ((struct usb_device *)NULL == peasycap->pusb_device) {
635 SAM("ERROR: peasycap->pusb_device is NULL\n");
639 while (0xFFFFFFFF != easycap_control[i1].id) {
640 if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
641 if ((easycap_control[i1].minimum > value) || \
642 (easycap_control[i1].maximum < value))
643 value = easycap_control[i1].default_value;
645 if ((easycap_control[i1].minimum <= peasycap->brightness) && \
646 (easycap_control[i1].maximum >= \
647 peasycap->brightness)) {
648 if (peasycap->brightness == value) {
649 SAM("unchanged brightness at 0x%02X\n", \
654 peasycap->brightness = value;
655 for (k = 0; k < INPUT_MANY; k++) {
656 if (!peasycap->inputset[k].brightness_ok)
657 peasycap->inputset[k].brightness = \
658 peasycap->brightness;
660 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
661 peasycap->inputset[peasycap->input].brightness = \
662 peasycap->brightness;
663 peasycap->inputset[peasycap->input].brightness_ok = 1;
665 JOM(8, "%i=peasycap->input\n", peasycap->input);
666 mood = 0x00FF & (unsigned int)peasycap->brightness;
667 if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
668 SAM("adjusting brightness to 0x%02X\n", mood);
671 SAM("WARNING: failed to adjust brightness " \
672 "to 0x%02X\n", mood);
679 SAM("WARNING: failed to adjust brightness: control not found\n");
682 /*****************************************************************************/
683 int adjust_contrast(struct easycap *peasycap, int value)
688 if (NULL == peasycap) {
689 SAY("ERROR: peasycap is NULL\n");
692 if ((struct usb_device *)NULL == peasycap->pusb_device) {
693 SAM("ERROR: peasycap->pusb_device is NULL\n");
697 while (0xFFFFFFFF != easycap_control[i1].id) {
698 if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
699 if ((easycap_control[i1].minimum > value) || \
700 (easycap_control[i1].maximum < value))
701 value = easycap_control[i1].default_value;
705 if ((easycap_control[i1].minimum <= peasycap->contrast) && \
706 (easycap_control[i1].maximum >= \
707 peasycap->contrast)) {
708 if (peasycap->contrast == value) {
709 SAM("unchanged contrast at 0x%02X\n", value);
713 peasycap->contrast = value;
714 for (k = 0; k < INPUT_MANY; k++) {
715 if (!peasycap->inputset[k].contrast_ok) {
716 peasycap->inputset[k].contrast = \
720 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
721 peasycap->inputset[peasycap->input].contrast = \
723 peasycap->inputset[peasycap->input].contrast_ok = 1;
725 JOM(8, "%i=peasycap->input\n", peasycap->input);
726 mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
727 if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
728 SAM("adjusting contrast to 0x%02X\n", mood);
731 SAM("WARNING: failed to adjust contrast to " \
739 SAM("WARNING: failed to adjust contrast: control not found\n");
742 /*****************************************************************************/
743 int adjust_saturation(struct easycap *peasycap, int value)
748 if (NULL == peasycap) {
749 SAY("ERROR: peasycap is NULL\n");
752 if ((struct usb_device *)NULL == peasycap->pusb_device) {
753 SAM("ERROR: peasycap->pusb_device is NULL\n");
757 while (0xFFFFFFFF != easycap_control[i1].id) {
758 if (V4L2_CID_SATURATION == easycap_control[i1].id) {
759 if ((easycap_control[i1].minimum > value) || \
760 (easycap_control[i1].maximum < value))
761 value = easycap_control[i1].default_value;
764 if ((easycap_control[i1].minimum <= peasycap->saturation) && \
765 (easycap_control[i1].maximum >= \
766 peasycap->saturation)) {
767 if (peasycap->saturation == value) {
768 SAM("unchanged saturation at 0x%02X\n", \
773 peasycap->saturation = value;
774 for (k = 0; k < INPUT_MANY; k++) {
775 if (!peasycap->inputset[k].saturation_ok) {
776 peasycap->inputset[k].saturation = \
777 peasycap->saturation;
780 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
781 peasycap->inputset[peasycap->input].saturation = \
782 peasycap->saturation;
783 peasycap->inputset[peasycap->input].saturation_ok = 1;
785 JOM(8, "%i=peasycap->input\n", peasycap->input);
786 mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
787 if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
788 SAM("adjusting saturation to 0x%02X\n", mood);
791 SAM("WARNING: failed to adjust saturation to " \
799 SAM("WARNING: failed to adjust saturation: control not found\n");
802 /*****************************************************************************/
803 int adjust_hue(struct easycap *peasycap, int value)
808 if (NULL == peasycap) {
809 SAY("ERROR: peasycap is NULL\n");
812 if ((struct usb_device *)NULL == peasycap->pusb_device) {
813 SAM("ERROR: peasycap->pusb_device is NULL\n");
817 while (0xFFFFFFFF != easycap_control[i1].id) {
818 if (V4L2_CID_HUE == easycap_control[i1].id) {
819 if ((easycap_control[i1].minimum > value) || \
820 (easycap_control[i1].maximum < value))
821 value = easycap_control[i1].default_value;
823 if ((easycap_control[i1].minimum <= peasycap->hue) && \
824 (easycap_control[i1].maximum >= \
826 if (peasycap->hue == value) {
827 SAM("unchanged hue at 0x%02X\n", value);
831 peasycap->hue = value;
832 for (k = 0; k < INPUT_MANY; k++) {
833 if (!peasycap->inputset[k].hue_ok)
834 peasycap->inputset[k].hue = peasycap->hue;
836 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
837 peasycap->inputset[peasycap->input].hue = \
839 peasycap->inputset[peasycap->input].hue_ok = 1;
841 JOM(8, "%i=peasycap->input\n", peasycap->input);
842 i2 = peasycap->hue - 128;
843 mood = 0x00FF & ((int) i2);
844 if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
845 SAM("adjusting hue to 0x%02X\n", mood);
848 SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
855 SAM("WARNING: failed to adjust hue: control not found\n");
858 /*****************************************************************************/
859 int adjust_volume(struct easycap *peasycap, int value)
864 if (NULL == peasycap) {
865 SAY("ERROR: peasycap is NULL\n");
868 if ((struct usb_device *)NULL == peasycap->pusb_device) {
869 SAM("ERROR: peasycap->pusb_device is NULL\n");
873 while (0xFFFFFFFF != easycap_control[i1].id) {
874 if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
875 if ((easycap_control[i1].minimum > value) || \
876 (easycap_control[i1].maximum < value))
877 value = easycap_control[i1].default_value;
878 if ((easycap_control[i1].minimum <= peasycap->volume) && \
879 (easycap_control[i1].maximum >= \
881 if (peasycap->volume == value) {
882 SAM("unchanged volume at 0x%02X\n", value);
886 peasycap->volume = value;
887 mood = (16 > peasycap->volume) ? 16 : \
888 ((31 < peasycap->volume) ? 31 : \
889 (__s8) peasycap->volume);
890 if (!audio_gainset(peasycap->pusb_device, mood)) {
891 SAM("adjusting volume to 0x%02X\n", mood);
894 SAM("WARNING: failed to adjust volume to " \
902 SAM("WARNING: failed to adjust volume: control not found\n");
905 /*****************************************************************************/
906 /*---------------------------------------------------------------------------*/
908 * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
909 * usb_set_interface(peasycap->pusb_device, \
910 * peasycap->audio_interface, \
911 * peasycap->audio_altsetting_off);
912 * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
913 * -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT
914 * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
916 /*---------------------------------------------------------------------------*/
917 int adjust_mute(struct easycap *peasycap, int value)
921 if (NULL == peasycap) {
922 SAY("ERROR: peasycap is NULL\n");
925 if ((struct usb_device *)NULL == peasycap->pusb_device) {
926 SAM("ERROR: peasycap->pusb_device is NULL\n");
930 while (0xFFFFFFFF != easycap_control[i1].id) {
931 if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
932 peasycap->mute = value;
933 switch (peasycap->mute) {
935 peasycap->audio_idle = 1;
936 peasycap->timeval0.tv_sec = 0;
937 SAM("adjusting mute: %i=peasycap->audio_idle\n", \
938 peasycap->audio_idle);
942 peasycap->audio_idle = 0;
943 SAM("adjusting mute: %i=peasycap->audio_idle\n", \
944 peasycap->audio_idle);
952 SAM("WARNING: failed to adjust mute: control not found\n");
955 /*****************************************************************************/
956 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
957 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
958 (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
960 easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
961 return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg);
963 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
964 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
965 /*---------------------------------------------------------------------------*/
967 easycap_ioctl(struct inode *inode, struct file *file,
968 unsigned int cmd, unsigned long arg)
970 struct easycap *peasycap;
971 struct usb_device *p;
975 SAY("ERROR: file is NULL\n");
978 peasycap = file->private_data;
979 if (NULL == peasycap) {
980 SAY("ERROR: peasycap is NULL\n");
983 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
984 SAY("ERROR: bad peasycap\n");
987 p = peasycap->pusb_device;
989 SAM("ERROR: peasycap->pusb_device is NULL\n");
992 kd = isdongle(peasycap);
993 if (0 <= kd && DONGLE_MANY > kd) {
994 if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
995 SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd);
998 JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
999 /*---------------------------------------------------------------------------*/
1001 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
1002 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
1003 * IF NECESSARY, BAIL OUT.
1005 /*---------------------------------------------------------------------------*/
1006 if (kd != isdongle(peasycap))
1007 return -ERESTARTSYS;
1009 SAY("ERROR: file is NULL\n");
1010 mutex_unlock(&easycap_dongle[kd].mutex_video);
1011 return -ERESTARTSYS;
1013 peasycap = file->private_data;
1014 if (NULL == peasycap) {
1015 SAY("ERROR: peasycap is NULL\n");
1016 mutex_unlock(&easycap_dongle[kd].mutex_video);
1017 return -ERESTARTSYS;
1019 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1020 SAY("ERROR: bad peasycap\n");
1021 mutex_unlock(&easycap_dongle[kd].mutex_video);
1024 p = peasycap->pusb_device;
1025 if (NULL == peasycap->pusb_device) {
1026 SAM("ERROR: peasycap->pusb_device is NULL\n");
1027 mutex_unlock(&easycap_dongle[kd].mutex_video);
1028 return -ERESTARTSYS;
1031 /*---------------------------------------------------------------------------*/
1033 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1034 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
1036 /*---------------------------------------------------------------------------*/
1037 return -ERESTARTSYS;
1039 /*---------------------------------------------------------------------------*/
1041 case VIDIOC_QUERYCAP: {
1042 struct v4l2_capability v4l2_capability;
1043 char version[16], *p1, *p2;
1047 JOM(8, "VIDIOC_QUERYCAP\n");
1049 if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
1050 SAM("ERROR: bad driver version string\n");
1051 mutex_unlock(&easycap_dongle[kd].mutex_video);
1054 strcpy(&version[0], EASYCAP_DRIVER_VERSION);
1055 for (i = 0; i < 3; i++)
1057 p2 = &version[0]; i = 0;
1060 while (*p2 && ('.' != *p2))
1065 rc = (int) strict_strtol(p1, 10, &lng);
1067 SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \
1069 mutex_unlock(&easycap_dongle[kd].mutex_video);
1077 memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
1078 strlcpy(&v4l2_capability.driver[0], "easycap", \
1079 sizeof(v4l2_capability.driver));
1081 v4l2_capability.capabilities = \
1082 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
1083 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE;
1085 v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
1086 JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
1088 strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
1089 sizeof(v4l2_capability.card));
1091 if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\
1092 sizeof(v4l2_capability.bus_info)) < 0) {
1093 strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
1094 sizeof(v4l2_capability.bus_info));
1095 JOM(8, "%s=v4l2_capability.bus_info\n", \
1096 &v4l2_capability.bus_info[0]);
1098 if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
1099 sizeof(struct v4l2_capability))) {
1100 mutex_unlock(&easycap_dongle[kd].mutex_video);
1105 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1106 case VIDIOC_ENUMINPUT: {
1107 struct v4l2_input v4l2_input;
1110 JOM(8, "VIDIOC_ENUMINPUT\n");
1112 if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
1113 sizeof(struct v4l2_input))) {
1114 mutex_unlock(&easycap_dongle[kd].mutex_video);
1118 index = v4l2_input.index;
1119 memset(&v4l2_input, 0, sizeof(struct v4l2_input));
1123 v4l2_input.index = index;
1124 strcpy(&v4l2_input.name[0], "CVBS0");
1125 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1126 v4l2_input.audioset = 0x01;
1127 v4l2_input.tuner = 0;
1128 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1130 v4l2_input.status = 0;
1131 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1135 v4l2_input.index = index;
1136 strcpy(&v4l2_input.name[0], "CVBS1");
1137 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1138 v4l2_input.audioset = 0x01;
1139 v4l2_input.tuner = 0;
1140 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1142 v4l2_input.status = 0;
1143 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1147 v4l2_input.index = index;
1148 strcpy(&v4l2_input.name[0], "CVBS2");
1149 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1150 v4l2_input.audioset = 0x01;
1151 v4l2_input.tuner = 0;
1152 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1154 v4l2_input.status = 0;
1155 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1159 v4l2_input.index = index;
1160 strcpy(&v4l2_input.name[0], "CVBS3");
1161 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1162 v4l2_input.audioset = 0x01;
1163 v4l2_input.tuner = 0;
1164 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1166 v4l2_input.status = 0;
1167 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1171 v4l2_input.index = index;
1172 strcpy(&v4l2_input.name[0], "CVBS4");
1173 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1174 v4l2_input.audioset = 0x01;
1175 v4l2_input.tuner = 0;
1176 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1178 v4l2_input.status = 0;
1179 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1183 v4l2_input.index = index;
1184 strcpy(&v4l2_input.name[0], "S-VIDEO");
1185 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1186 v4l2_input.audioset = 0x01;
1187 v4l2_input.tuner = 0;
1188 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1190 v4l2_input.status = 0;
1191 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1195 JOM(8, "%i=index: exhausts inputs\n", index);
1196 mutex_unlock(&easycap_dongle[kd].mutex_video);
1201 if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
1202 sizeof(struct v4l2_input))) {
1203 mutex_unlock(&easycap_dongle[kd].mutex_video);
1208 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1209 case VIDIOC_G_INPUT: {
1212 JOM(8, "VIDIOC_G_INPUT\n");
1213 index = (__u32)peasycap->input;
1214 JOM(8, "user is told: %i\n", index);
1215 if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
1216 mutex_unlock(&easycap_dongle[kd].mutex_video);
1221 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1222 case VIDIOC_S_INPUT:
1227 JOM(8, "VIDIOC_S_INPUT\n");
1229 if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
1230 mutex_unlock(&easycap_dongle[kd].mutex_video);
1234 JOM(8, "user requests input %i\n", index);
1236 if ((int)index == peasycap->input) {
1237 SAM("requested input already in effect\n");
1241 if ((0 > index) || (INPUT_MANY <= index)) {
1242 JOM(8, "ERROR: bad requested input: %i\n", index);
1243 mutex_unlock(&easycap_dongle[kd].mutex_video);
1247 rc = newinput(peasycap, (int)index);
1249 JOM(8, "newinput(.,%i) OK\n", (int)index);
1251 SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
1252 mutex_unlock(&easycap_dongle[kd].mutex_video);
1257 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1258 case VIDIOC_ENUMAUDIO: {
1259 JOM(8, "VIDIOC_ENUMAUDIO\n");
1260 mutex_unlock(&easycap_dongle[kd].mutex_video);
1263 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1264 case VIDIOC_ENUMAUDOUT: {
1265 struct v4l2_audioout v4l2_audioout;
1267 JOM(8, "VIDIOC_ENUMAUDOUT\n");
1269 if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
1270 sizeof(struct v4l2_audioout))) {
1271 mutex_unlock(&easycap_dongle[kd].mutex_video);
1275 if (0 != v4l2_audioout.index) {
1276 mutex_unlock(&easycap_dongle[kd].mutex_video);
1279 memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1280 v4l2_audioout.index = 0;
1281 strcpy(&v4l2_audioout.name[0], "Soundtrack");
1283 if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
1284 sizeof(struct v4l2_audioout))) {
1285 mutex_unlock(&easycap_dongle[kd].mutex_video);
1290 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1291 case VIDIOC_QUERYCTRL: {
1293 struct v4l2_queryctrl v4l2_queryctrl;
1295 JOM(8, "VIDIOC_QUERYCTRL\n");
1297 if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
1298 sizeof(struct v4l2_queryctrl))) {
1299 mutex_unlock(&easycap_dongle[kd].mutex_video);
1304 while (0xFFFFFFFF != easycap_control[i1].id) {
1305 if (easycap_control[i1].id == v4l2_queryctrl.id) {
1306 JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \
1307 ".name\n", &easycap_control[i1].name[0], i1);
1308 memcpy(&v4l2_queryctrl, &easycap_control[i1], \
1309 sizeof(struct v4l2_queryctrl));
1314 if (0xFFFFFFFF == easycap_control[i1].id) {
1315 JOM(8, "%i=index: exhausts controls\n", i1);
1316 mutex_unlock(&easycap_dongle[kd].mutex_video);
1319 if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
1320 sizeof(struct v4l2_queryctrl))) {
1321 mutex_unlock(&easycap_dongle[kd].mutex_video);
1326 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1327 case VIDIOC_QUERYMENU: {
1328 JOM(8, "VIDIOC_QUERYMENU unsupported\n");
1329 mutex_unlock(&easycap_dongle[kd].mutex_video);
1332 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1333 case VIDIOC_G_CTRL: {
1334 struct v4l2_control *pv4l2_control;
1336 JOM(8, "VIDIOC_G_CTRL\n");
1337 pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL);
1338 if (!pv4l2_control) {
1339 SAM("ERROR: out of memory\n");
1340 mutex_unlock(&easycap_dongle[kd].mutex_video);
1343 if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \
1344 sizeof(struct v4l2_control))) {
1345 kfree(pv4l2_control);
1346 mutex_unlock(&easycap_dongle[kd].mutex_video);
1350 switch (pv4l2_control->id) {
1351 case V4L2_CID_BRIGHTNESS: {
1352 pv4l2_control->value = peasycap->brightness;
1353 JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
1356 case V4L2_CID_CONTRAST: {
1357 pv4l2_control->value = peasycap->contrast;
1358 JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
1361 case V4L2_CID_SATURATION: {
1362 pv4l2_control->value = peasycap->saturation;
1363 JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
1366 case V4L2_CID_HUE: {
1367 pv4l2_control->value = peasycap->hue;
1368 JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
1371 case V4L2_CID_AUDIO_VOLUME: {
1372 pv4l2_control->value = peasycap->volume;
1373 JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
1376 case V4L2_CID_AUDIO_MUTE: {
1377 if (1 == peasycap->mute)
1378 pv4l2_control->value = true;
1380 pv4l2_control->value = false;
1381 JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
1385 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1387 kfree(pv4l2_control);
1388 mutex_unlock(&easycap_dongle[kd].mutex_video);
1392 if (0 != copy_to_user((void __user *)arg, pv4l2_control, \
1393 sizeof(struct v4l2_control))) {
1394 kfree(pv4l2_control);
1395 mutex_unlock(&easycap_dongle[kd].mutex_video);
1398 kfree(pv4l2_control);
1401 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1404 struct v4l2_control v4l2_control;
1406 JOM(8, "VIDIOC_S_CTRL\n");
1408 if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1409 sizeof(struct v4l2_control))) {
1410 mutex_unlock(&easycap_dongle[kd].mutex_video);
1414 switch (v4l2_control.id) {
1415 case V4L2_CID_BRIGHTNESS: {
1416 JOM(8, "user requests brightness %i\n", v4l2_control.value);
1417 if (0 != adjust_brightness(peasycap, v4l2_control.value))
1421 case V4L2_CID_CONTRAST: {
1422 JOM(8, "user requests contrast %i\n", v4l2_control.value);
1423 if (0 != adjust_contrast(peasycap, v4l2_control.value))
1427 case V4L2_CID_SATURATION: {
1428 JOM(8, "user requests saturation %i\n", v4l2_control.value);
1429 if (0 != adjust_saturation(peasycap, v4l2_control.value))
1433 case V4L2_CID_HUE: {
1434 JOM(8, "user requests hue %i\n", v4l2_control.value);
1435 if (0 != adjust_hue(peasycap, v4l2_control.value))
1439 case V4L2_CID_AUDIO_VOLUME: {
1440 JOM(8, "user requests volume %i\n", v4l2_control.value);
1441 if (0 != adjust_volume(peasycap, v4l2_control.value))
1445 case V4L2_CID_AUDIO_MUTE: {
1448 JOM(8, "user requests mute %i\n", v4l2_control.value);
1449 if (true == v4l2_control.value)
1454 if (0 != adjust_mute(peasycap, mute))
1455 SAM("WARNING: failed to adjust mute to %i\n", mute);
1459 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1461 mutex_unlock(&easycap_dongle[kd].mutex_video);
1467 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1468 case VIDIOC_S_EXT_CTRLS: {
1469 JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1470 mutex_unlock(&easycap_dongle[kd].mutex_video);
1473 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1474 case VIDIOC_ENUM_FMT: {
1476 struct v4l2_fmtdesc v4l2_fmtdesc;
1478 JOM(8, "VIDIOC_ENUM_FMT\n");
1480 if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
1481 sizeof(struct v4l2_fmtdesc))) {
1482 mutex_unlock(&easycap_dongle[kd].mutex_video);
1486 index = v4l2_fmtdesc.index;
1487 memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1489 v4l2_fmtdesc.index = index;
1490 v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1494 v4l2_fmtdesc.flags = 0;
1495 strcpy(&v4l2_fmtdesc.description[0], "uyvy");
1496 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
1497 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1501 v4l2_fmtdesc.flags = 0;
1502 strcpy(&v4l2_fmtdesc.description[0], "yuy2");
1503 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1504 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1508 v4l2_fmtdesc.flags = 0;
1509 strcpy(&v4l2_fmtdesc.description[0], "rgb24");
1510 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
1511 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1515 v4l2_fmtdesc.flags = 0;
1516 strcpy(&v4l2_fmtdesc.description[0], "rgb32");
1517 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
1518 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1522 v4l2_fmtdesc.flags = 0;
1523 strcpy(&v4l2_fmtdesc.description[0], "bgr24");
1524 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
1525 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1529 v4l2_fmtdesc.flags = 0;
1530 strcpy(&v4l2_fmtdesc.description[0], "bgr32");
1531 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
1532 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1536 JOM(8, "%i=index: exhausts formats\n", index);
1537 mutex_unlock(&easycap_dongle[kd].mutex_video);
1541 if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
1542 sizeof(struct v4l2_fmtdesc))) {
1543 mutex_unlock(&easycap_dongle[kd].mutex_video);
1548 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1550 * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
1551 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1553 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1554 case VIDIOC_ENUM_FRAMESIZES: {
1556 struct v4l2_frmsizeenum v4l2_frmsizeenum;
1558 JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
1560 if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \
1561 sizeof(struct v4l2_frmsizeenum))) {
1562 mutex_unlock(&easycap_dongle[kd].mutex_video);
1566 index = v4l2_frmsizeenum.index;
1568 v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;
1570 if (true == peasycap->ntsc) {
1573 v4l2_frmsizeenum.discrete.width = 640;
1574 v4l2_frmsizeenum.discrete.height = 480;
1575 JOM(8, "%i=index: %ix%i\n", index, \
1576 (int)(v4l2_frmsizeenum.\
1578 (int)(v4l2_frmsizeenum.\
1583 v4l2_frmsizeenum.discrete.width = 320;
1584 v4l2_frmsizeenum.discrete.height = 240;
1585 JOM(8, "%i=index: %ix%i\n", index, \
1586 (int)(v4l2_frmsizeenum.\
1588 (int)(v4l2_frmsizeenum.\
1593 v4l2_frmsizeenum.discrete.width = 720;
1594 v4l2_frmsizeenum.discrete.height = 480;
1595 JOM(8, "%i=index: %ix%i\n", index, \
1596 (int)(v4l2_frmsizeenum.\
1598 (int)(v4l2_frmsizeenum.\
1603 v4l2_frmsizeenum.discrete.width = 360;
1604 v4l2_frmsizeenum.discrete.height = 240;
1605 JOM(8, "%i=index: %ix%i\n", index, \
1606 (int)(v4l2_frmsizeenum.\
1608 (int)(v4l2_frmsizeenum.\
1613 JOM(8, "%i=index: exhausts framesizes\n", index);
1614 mutex_unlock(&easycap_dongle[kd].mutex_video);
1621 v4l2_frmsizeenum.discrete.width = 640;
1622 v4l2_frmsizeenum.discrete.height = 480;
1623 JOM(8, "%i=index: %ix%i\n", index, \
1624 (int)(v4l2_frmsizeenum.\
1626 (int)(v4l2_frmsizeenum.\
1631 v4l2_frmsizeenum.discrete.width = 320;
1632 v4l2_frmsizeenum.discrete.height = 240;
1633 JOM(8, "%i=index: %ix%i\n", index, \
1634 (int)(v4l2_frmsizeenum.\
1636 (int)(v4l2_frmsizeenum.\
1641 v4l2_frmsizeenum.discrete.width = 704;
1642 v4l2_frmsizeenum.discrete.height = 576;
1643 JOM(8, "%i=index: %ix%i\n", index, \
1644 (int)(v4l2_frmsizeenum.\
1646 (int)(v4l2_frmsizeenum.\
1651 v4l2_frmsizeenum.discrete.width = 720;
1652 v4l2_frmsizeenum.discrete.height = 576;
1653 JOM(8, "%i=index: %ix%i\n", index, \
1654 (int)(v4l2_frmsizeenum.\
1656 (int)(v4l2_frmsizeenum.\
1661 v4l2_frmsizeenum.discrete.width = 360;
1662 v4l2_frmsizeenum.discrete.height = 288;
1663 JOM(8, "%i=index: %ix%i\n", index, \
1664 (int)(v4l2_frmsizeenum.\
1666 (int)(v4l2_frmsizeenum.\
1671 JOM(8, "%i=index: exhausts framesizes\n", index);
1672 mutex_unlock(&easycap_dongle[kd].mutex_video);
1677 if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \
1678 sizeof(struct v4l2_frmsizeenum))) {
1679 mutex_unlock(&easycap_dongle[kd].mutex_video);
1684 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1686 * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
1687 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1689 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1690 case VIDIOC_ENUM_FRAMEINTERVALS: {
1693 struct v4l2_frmivalenum v4l2_frmivalenum;
1695 JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
1698 denominator = peasycap->fps;
1700 if (true == peasycap->ntsc)
1706 if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \
1707 sizeof(struct v4l2_frmivalenum))) {
1708 mutex_unlock(&easycap_dongle[kd].mutex_video);
1712 index = v4l2_frmivalenum.index;
1714 v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;
1718 v4l2_frmivalenum.discrete.numerator = 1;
1719 v4l2_frmivalenum.discrete.denominator = denominator;
1720 JOM(8, "%i=index: %i/%i\n", index, \
1721 (int)(v4l2_frmivalenum.discrete.numerator), \
1722 (int)(v4l2_frmivalenum.discrete.denominator));
1726 v4l2_frmivalenum.discrete.numerator = 1;
1727 v4l2_frmivalenum.discrete.denominator = denominator/5;
1728 JOM(8, "%i=index: %i/%i\n", index, \
1729 (int)(v4l2_frmivalenum.discrete.numerator), \
1730 (int)(v4l2_frmivalenum.discrete.denominator));
1734 JOM(8, "%i=index: exhausts frameintervals\n", index);
1735 mutex_unlock(&easycap_dongle[kd].mutex_video);
1739 if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \
1740 sizeof(struct v4l2_frmivalenum))) {
1741 mutex_unlock(&easycap_dongle[kd].mutex_video);
1746 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1747 case VIDIOC_G_FMT: {
1748 struct v4l2_format *pv4l2_format;
1749 struct v4l2_pix_format *pv4l2_pix_format;
1751 JOM(8, "VIDIOC_G_FMT\n");
1752 pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
1753 if (!pv4l2_format) {
1754 SAM("ERROR: out of memory\n");
1755 mutex_unlock(&easycap_dongle[kd].mutex_video);
1758 pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
1759 if (!pv4l2_pix_format) {
1760 SAM("ERROR: out of memory\n");
1761 kfree(pv4l2_format);
1762 mutex_unlock(&easycap_dongle[kd].mutex_video);
1765 if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \
1766 sizeof(struct v4l2_format))) {
1767 kfree(pv4l2_format);
1768 kfree(pv4l2_pix_format);
1769 mutex_unlock(&easycap_dongle[kd].mutex_video);
1773 if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1774 kfree(pv4l2_format);
1775 kfree(pv4l2_pix_format);
1776 mutex_unlock(&easycap_dongle[kd].mutex_video);
1780 memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1781 pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1782 memcpy(&pv4l2_format->fmt.pix, \
1783 &easycap_format[peasycap->format_offset]\
1784 .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
1785 JOM(8, "user is told: %s\n", \
1786 &easycap_format[peasycap->format_offset].name[0]);
1788 if (0 != copy_to_user((void __user *)arg, pv4l2_format, \
1789 sizeof(struct v4l2_format))) {
1790 kfree(pv4l2_format);
1791 kfree(pv4l2_pix_format);
1792 mutex_unlock(&easycap_dongle[kd].mutex_video);
1795 kfree(pv4l2_format);
1796 kfree(pv4l2_pix_format);
1799 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1800 case VIDIOC_TRY_FMT:
1801 case VIDIOC_S_FMT: {
1802 struct v4l2_format v4l2_format;
1803 struct v4l2_pix_format v4l2_pix_format;
1807 if (VIDIOC_TRY_FMT == cmd) {
1808 JOM(8, "VIDIOC_TRY_FMT\n");
1811 JOM(8, "VIDIOC_S_FMT\n");
1815 if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1816 sizeof(struct v4l2_format))) {
1817 mutex_unlock(&easycap_dongle[kd].mutex_video);
1821 best_format = adjust_format(peasycap, \
1822 v4l2_format.fmt.pix.width, \
1823 v4l2_format.fmt.pix.height, \
1824 v4l2_format.fmt.pix.pixelformat, \
1825 v4l2_format.fmt.pix.field, \
1827 if (0 > best_format) {
1828 if (-EBUSY == best_format) {
1829 mutex_unlock(&easycap_dongle[kd].mutex_video);
1832 JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
1833 mutex_unlock(&easycap_dongle[kd].mutex_video);
1836 /*...........................................................................*/
1837 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1838 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1840 memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
1841 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
1842 JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
1844 if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1845 sizeof(struct v4l2_format))) {
1846 mutex_unlock(&easycap_dongle[kd].mutex_video);
1851 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1852 case VIDIOC_CROPCAP: {
1853 struct v4l2_cropcap v4l2_cropcap;
1855 JOM(8, "VIDIOC_CROPCAP\n");
1857 if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
1858 sizeof(struct v4l2_cropcap))) {
1859 mutex_unlock(&easycap_dongle[kd].mutex_video);
1863 if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1864 JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1866 memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
1867 v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1868 v4l2_cropcap.bounds.left = 0;
1869 v4l2_cropcap.bounds.top = 0;
1870 v4l2_cropcap.bounds.width = peasycap->width;
1871 v4l2_cropcap.bounds.height = peasycap->height;
1872 v4l2_cropcap.defrect.left = 0;
1873 v4l2_cropcap.defrect.top = 0;
1874 v4l2_cropcap.defrect.width = peasycap->width;
1875 v4l2_cropcap.defrect.height = peasycap->height;
1876 v4l2_cropcap.pixelaspect.numerator = 1;
1877 v4l2_cropcap.pixelaspect.denominator = 1;
1879 JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1881 if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
1882 sizeof(struct v4l2_cropcap))) {
1883 mutex_unlock(&easycap_dongle[kd].mutex_video);
1888 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1890 case VIDIOC_S_CROP: {
1891 JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
1892 mutex_unlock(&easycap_dongle[kd].mutex_video);
1895 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1896 case VIDIOC_QUERYSTD: {
1897 JOM(8, "VIDIOC_QUERYSTD: " \
1898 "EasyCAP is incapable of detecting standard\n");
1899 mutex_unlock(&easycap_dongle[kd].mutex_video);
1903 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1904 /*---------------------------------------------------------------------------*/
1906 * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND
1907 * FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer.
1908 * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
1910 /*---------------------------------------------------------------------------*/
1911 case VIDIOC_ENUMSTD: {
1912 int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1913 struct v4l2_standard v4l2_standard;
1915 struct easycap_standard const *peasycap_standard;
1917 JOM(8, "VIDIOC_ENUMSTD\n");
1919 if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
1920 sizeof(struct v4l2_standard))) {
1921 mutex_unlock(&easycap_dongle[kd].mutex_video);
1924 index = v4l2_standard.index;
1926 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1927 if ((index == last3) && (index == last2) && \
1928 (index == last1) && (index == last0)) {
1930 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1933 memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1935 peasycap_standard = &easycap_standard[0];
1936 while (0xFFFF != peasycap_standard->mask) {
1937 if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1939 peasycap_standard++;
1941 if (0xFFFF == peasycap_standard->mask) {
1942 JOM(8, "%i=index: exhausts standards\n", index);
1943 mutex_unlock(&easycap_dongle[kd].mutex_video);
1946 JOM(8, "%i=index: %s\n", index, \
1947 &(peasycap_standard->v4l2_standard.name[0]));
1948 memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
1949 sizeof(struct v4l2_standard));
1951 v4l2_standard.index = index;
1953 if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
1954 sizeof(struct v4l2_standard))) {
1955 mutex_unlock(&easycap_dongle[kd].mutex_video);
1960 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1961 case VIDIOC_G_STD: {
1963 struct easycap_standard const *peasycap_standard;
1965 JOM(8, "VIDIOC_G_STD\n");
1967 if (0 > peasycap->standard_offset) {
1968 JOM(8, "%i=peasycap->standard_offset\n", \
1969 peasycap->standard_offset);
1970 mutex_unlock(&easycap_dongle[kd].mutex_video);
1974 if (0 != copy_from_user(&std_id, (void __user *)arg, \
1975 sizeof(v4l2_std_id))) {
1976 mutex_unlock(&easycap_dongle[kd].mutex_video);
1980 peasycap_standard = &easycap_standard[peasycap->standard_offset];
1981 std_id = peasycap_standard->v4l2_standard.id;
1983 JOM(8, "user is told: %s\n", \
1984 &peasycap_standard->v4l2_standard.name[0]);
1986 if (0 != copy_to_user((void __user *)arg, &std_id, \
1987 sizeof(v4l2_std_id))) {
1988 mutex_unlock(&easycap_dongle[kd].mutex_video);
1993 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1994 case VIDIOC_S_STD: {
1998 JOM(8, "VIDIOC_S_STD\n");
2000 if (0 != copy_from_user(&std_id, (void __user *)arg, \
2001 sizeof(v4l2_std_id))) {
2002 mutex_unlock(&easycap_dongle[kd].mutex_video);
2006 JOM(8, "User requests standard: 0x%08X%08X\n", \
2007 (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \
2008 (int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
2010 rc = adjust_standard(peasycap, std_id);
2012 JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
2013 mutex_unlock(&easycap_dongle[kd].mutex_video);
2018 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2019 case VIDIOC_REQBUFS: {
2021 struct v4l2_requestbuffers v4l2_requestbuffers;
2023 JOM(8, "VIDIOC_REQBUFS\n");
2025 if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
2026 sizeof(struct v4l2_requestbuffers))) {
2027 mutex_unlock(&easycap_dongle[kd].mutex_video);
2031 if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2032 mutex_unlock(&easycap_dongle[kd].mutex_video);
2035 if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
2036 mutex_unlock(&easycap_dongle[kd].mutex_video);
2039 nbuffers = v4l2_requestbuffers.count;
2040 JOM(8, " User requests %i buffers ...\n", nbuffers);
2043 if (nbuffers > FRAME_BUFFER_MANY)
2044 nbuffers = FRAME_BUFFER_MANY;
2045 if (v4l2_requestbuffers.count == nbuffers) {
2046 JOM(8, " ... agree to %i buffers\n", \
2049 JOM(8, " ... insist on %i buffers\n", \
2051 v4l2_requestbuffers.count = nbuffers;
2053 peasycap->frame_buffer_many = nbuffers;
2055 if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
2056 sizeof(struct v4l2_requestbuffers))) {
2057 mutex_unlock(&easycap_dongle[kd].mutex_video);
2062 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2063 case VIDIOC_QUERYBUF: {
2065 struct v4l2_buffer v4l2_buffer;
2067 JOM(8, "VIDIOC_QUERYBUF\n");
2069 if (peasycap->video_eof) {
2070 JOM(8, "returning -EIO because %i=video_eof\n", \
2071 peasycap->video_eof);
2072 mutex_unlock(&easycap_dongle[kd].mutex_video);
2076 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2077 sizeof(struct v4l2_buffer))) {
2078 mutex_unlock(&easycap_dongle[kd].mutex_video);
2082 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2083 mutex_unlock(&easycap_dongle[kd].mutex_video);
2086 index = v4l2_buffer.index;
2087 if (index < 0 || index >= peasycap->frame_buffer_many)
2089 memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
2090 v4l2_buffer.index = index;
2091 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2092 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2093 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
2094 peasycap->done[index] | \
2095 peasycap->queued[index];
2096 v4l2_buffer.field = V4L2_FIELD_NONE;
2097 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2098 v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
2099 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2101 JOM(16, " %10i=index\n", v4l2_buffer.index);
2102 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2103 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2104 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2105 JOM(16, " %10i=field\n", v4l2_buffer.field);
2106 JOM(16, " %10li=timestamp.tv_usec\n", \
2107 (long)v4l2_buffer.timestamp.tv_usec);
2108 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2109 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2110 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2111 JOM(16, " %10i=length\n", v4l2_buffer.length);
2113 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2114 sizeof(struct v4l2_buffer))) {
2115 mutex_unlock(&easycap_dongle[kd].mutex_video);
2120 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2122 struct v4l2_buffer v4l2_buffer;
2124 JOM(8, "VIDIOC_QBUF\n");
2126 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2127 sizeof(struct v4l2_buffer))) {
2128 mutex_unlock(&easycap_dongle[kd].mutex_video);
2132 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2133 mutex_unlock(&easycap_dongle[kd].mutex_video);
2136 if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
2137 mutex_unlock(&easycap_dongle[kd].mutex_video);
2140 if (v4l2_buffer.index < 0 || \
2141 (v4l2_buffer.index >= peasycap->frame_buffer_many)) {
2142 mutex_unlock(&easycap_dongle[kd].mutex_video);
2145 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
2147 peasycap->done[v4l2_buffer.index] = 0;
2148 peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
2150 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2151 sizeof(struct v4l2_buffer))) {
2152 mutex_unlock(&easycap_dongle[kd].mutex_video);
2156 JOM(8, "..... user queueing frame buffer %i\n", \
2157 (int)v4l2_buffer.index);
2159 peasycap->frame_lock = 0;
2163 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2166 #if defined(AUDIOTIME)
2167 struct signed_div_result sdr;
2168 long long int above, below, dnbydt, fudge, sll;
2169 unsigned long long int ull;
2170 struct timeval timeval8;
2171 struct timeval timeval1;
2172 #endif /*AUDIOTIME*/
2173 struct timeval timeval, timeval2;
2175 struct v4l2_buffer v4l2_buffer;
2179 JOM(8, "VIDIOC_DQBUF\n");
2181 if ((peasycap->video_idle) || (peasycap->video_eof)) {
2182 JOM(8, "returning -EIO because " \
2183 "%i=video_idle %i=video_eof\n", \
2184 peasycap->video_idle, peasycap->video_eof);
2185 mutex_unlock(&easycap_dongle[kd].mutex_video);
2189 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2190 sizeof(struct v4l2_buffer))) {
2191 mutex_unlock(&easycap_dongle[kd].mutex_video);
2195 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2196 mutex_unlock(&easycap_dongle[kd].mutex_video);
2200 if (true == peasycap->offerfields) {
2201 /*-----------------------------------------------------------*/
2203 * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
2206 /*-----------------------------------------------------------*/
2207 if (V4L2_FIELD_TOP == v4l2_buffer.field)
2208 JOM(8, "user wants V4L2_FIELD_TOP\n");
2209 else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
2210 JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
2211 else if (V4L2_FIELD_ANY == v4l2_buffer.field)
2212 JOM(8, "user wants V4L2_FIELD_ANY\n");
2214 JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \
2218 if (!peasycap->video_isoc_streaming) {
2219 JOM(16, "returning -EIO because video urbs not streaming\n");
2220 mutex_unlock(&easycap_dongle[kd].mutex_video);
2223 /*---------------------------------------------------------------------------*/
2225 * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
2226 * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS
2227 * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
2229 /*---------------------------------------------------------------------------*/
2231 if (!peasycap->polled) {
2233 rcdq = easycap_dqbuf(peasycap, 0);
2235 JOM(8, "returning -EIO because " \
2236 "dqbuf() returned -EIO\n");
2237 mutex_unlock(&easycap_dongle[kd].mutex_video);
2240 } while (0 != rcdq);
2242 if (peasycap->video_eof) {
2243 mutex_unlock(&easycap_dongle[kd].mutex_video);
2247 if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
2248 SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
2249 peasycap->done[peasycap->frame_read]);
2251 peasycap->polled = 0;
2253 if (!(peasycap->isequence % 10)) {
2254 for (i = 0; i < 179; i++)
2255 peasycap->merit[i] = peasycap->merit[i+1];
2256 peasycap->merit[179] = merit_saa(peasycap->pusb_device);
2258 for (i = 0; i < 180; i++)
2259 j += peasycap->merit[i];
2261 SAM("easycap driver shutting down " \
2262 "on condition blue\n");
2263 peasycap->video_eof = 1; peasycap->audio_eof = 1;
2267 v4l2_buffer.index = peasycap->frame_read;
2268 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2269 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2270 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
2271 if (true == peasycap->offerfields)
2272 v4l2_buffer.field = V4L2_FIELD_BOTTOM;
2274 v4l2_buffer.field = V4L2_FIELD_NONE;
2275 do_gettimeofday(&timeval);
2278 #if defined(AUDIOTIME)
2279 if (!peasycap->timeval0.tv_sec) {
2284 peasycap->timeval0 = timeval8;
2286 dnbydt = peasycap->dnbydt;
2287 timeval1 = peasycap->timeval1;
2288 above = dnbydt * MICROSECONDS(timeval, timeval1);
2290 sdr = signed_div(above, below);
2292 above = sdr.quotient + timeval1.tv_usec - 350000;
2295 sdr = signed_div(above, below);
2296 timeval2.tv_usec = sdr.remainder;
2297 timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
2299 if (!(peasycap->isequence % 500)) {
2300 fudge = ((long long int)(1000000)) * \
2301 ((long long int)(timeval.tv_sec - \
2302 timeval2.tv_sec)) + \
2303 (long long int)(timeval.tv_usec - \
2305 sdr = signed_div(fudge, 1000);
2307 ull = sdr.remainder;
2309 SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
2311 #endif /*AUDIOTIME*/
2313 v4l2_buffer.timestamp = timeval2;
2314 v4l2_buffer.sequence = peasycap->isequence++;
2315 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2316 v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
2317 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2319 JOM(16, " %10i=index\n", v4l2_buffer.index);
2320 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2321 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2322 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2323 JOM(16, " %10i=field\n", v4l2_buffer.field);
2324 JOM(16, " %10li=timestamp.tv_sec\n", \
2325 (long)v4l2_buffer.timestamp.tv_sec);
2326 JOM(16, " %10li=timestamp.tv_usec\n", \
2327 (long)v4l2_buffer.timestamp.tv_usec);
2328 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2329 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2330 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2331 JOM(16, " %10i=length\n", v4l2_buffer.length);
2333 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2334 sizeof(struct v4l2_buffer))) {
2335 mutex_unlock(&easycap_dongle[kd].mutex_video);
2339 input = peasycap->frame_buffer[peasycap->frame_read][0].input;
2341 JOM(8, "user is offered frame buffer %i, input %i\n", \
2342 peasycap->frame_read, (0x07 & input));
2344 JOM(8, "user is offered frame buffer %i\n", \
2345 peasycap->frame_read);
2347 peasycap->frame_lock = 1;
2348 JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
2349 if (peasycap->frame_read == peasycap->frame_fill) {
2350 if (peasycap->frame_lock) {
2351 JOM(8, "WORRY: filling frame buffer " \
2352 "while offered to user\n");
2357 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2358 case VIDIOC_STREAMON: {
2361 JOM(8, "VIDIOC_STREAMON\n");
2363 peasycap->isequence = 0;
2364 for (i = 0; i < 180; i++)
2365 peasycap->merit[i] = 0;
2366 if ((struct usb_device *)NULL == peasycap->pusb_device) {
2367 SAM("ERROR: peasycap->pusb_device is NULL\n");
2368 mutex_unlock(&easycap_dongle[kd].mutex_video);
2371 submit_video_urbs(peasycap);
2372 peasycap->video_idle = 0;
2373 peasycap->audio_idle = 0;
2374 peasycap->video_eof = 0;
2375 peasycap->audio_eof = 0;
2378 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2379 case VIDIOC_STREAMOFF: {
2380 JOM(8, "VIDIOC_STREAMOFF\n");
2382 if ((struct usb_device *)NULL == peasycap->pusb_device) {
2383 SAM("ERROR: peasycap->pusb_device is NULL\n");
2384 mutex_unlock(&easycap_dongle[kd].mutex_video);
2388 peasycap->video_idle = 1;
2389 peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0;
2390 /*---------------------------------------------------------------------------*/
2392 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
2393 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2395 /*---------------------------------------------------------------------------*/
2396 JOM(8, "calling wake_up on wq_video and wq_audio\n");
2397 wake_up_interruptible(&(peasycap->wq_video));
2398 wake_up_interruptible(&(peasycap->wq_audio));
2399 /*---------------------------------------------------------------------------*/
2402 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2403 case VIDIOC_G_PARM: {
2404 struct v4l2_streamparm *pv4l2_streamparm;
2406 JOM(8, "VIDIOC_G_PARM\n");
2407 pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL);
2408 if (!pv4l2_streamparm) {
2409 SAM("ERROR: out of memory\n");
2410 mutex_unlock(&easycap_dongle[kd].mutex_video);
2413 if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \
2414 sizeof(struct v4l2_streamparm))) {
2415 kfree(pv4l2_streamparm);
2416 mutex_unlock(&easycap_dongle[kd].mutex_video);
2420 if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2421 kfree(pv4l2_streamparm);
2422 mutex_unlock(&easycap_dongle[kd].mutex_video);
2425 pv4l2_streamparm->parm.capture.capability = 0;
2426 pv4l2_streamparm->parm.capture.capturemode = 0;
2427 pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
2429 if (peasycap->fps) {
2430 pv4l2_streamparm->parm.capture.timeperframe.\
2431 denominator = peasycap->fps;
2433 if (true == peasycap->ntsc) {
2434 pv4l2_streamparm->parm.capture.timeperframe.\
2437 pv4l2_streamparm->parm.capture.timeperframe.\
2442 pv4l2_streamparm->parm.capture.readbuffers = \
2443 peasycap->frame_buffer_many;
2444 pv4l2_streamparm->parm.capture.extendedmode = 0;
2445 if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \
2446 sizeof(struct v4l2_streamparm))) {
2447 kfree(pv4l2_streamparm);
2448 mutex_unlock(&easycap_dongle[kd].mutex_video);
2451 kfree(pv4l2_streamparm);
2454 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2455 case VIDIOC_S_PARM: {
2456 JOM(8, "VIDIOC_S_PARM unsupported\n");
2457 mutex_unlock(&easycap_dongle[kd].mutex_video);
2460 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2461 case VIDIOC_G_AUDIO: {
2462 JOM(8, "VIDIOC_G_AUDIO unsupported\n");
2463 mutex_unlock(&easycap_dongle[kd].mutex_video);
2466 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2467 case VIDIOC_S_AUDIO: {
2468 JOM(8, "VIDIOC_S_AUDIO unsupported\n");
2469 mutex_unlock(&easycap_dongle[kd].mutex_video);
2472 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2473 case VIDIOC_S_TUNER: {
2474 JOM(8, "VIDIOC_S_TUNER unsupported\n");
2475 mutex_unlock(&easycap_dongle[kd].mutex_video);
2478 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2481 case VIDIOC_OVERLAY: {
2482 JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
2483 mutex_unlock(&easycap_dongle[kd].mutex_video);
2486 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2487 case VIDIOC_G_TUNER: {
2488 JOM(8, "VIDIOC_G_TUNER unsupported\n");
2489 mutex_unlock(&easycap_dongle[kd].mutex_video);
2492 case VIDIOC_G_FREQUENCY:
2493 case VIDIOC_S_FREQUENCY: {
2494 JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
2495 mutex_unlock(&easycap_dongle[kd].mutex_video);
2498 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2500 JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
2501 mutex_unlock(&easycap_dongle[kd].mutex_video);
2502 return -ENOIOCTLCMD;
2505 mutex_unlock(&easycap_dongle[kd].mutex_video);
2506 JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
2509 /*****************************************************************************/
2510 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2511 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
2512 (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
2514 easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
2515 return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg);
2517 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
2518 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
2519 /*---------------------------------------------------------------------------*/
2521 easysnd_ioctl(struct inode *inode, struct file *file,
2522 unsigned int cmd, unsigned long arg)
2524 struct easycap *peasycap;
2525 struct usb_device *p;
2529 SAY("ERROR: file is NULL\n");
2530 return -ERESTARTSYS;
2532 peasycap = file->private_data;
2533 if (NULL == peasycap) {
2534 SAY("ERROR: peasycap is NULL.\n");
2537 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2538 SAY("ERROR: bad peasycap\n");
2541 p = peasycap->pusb_device;
2543 SAM("ERROR: peasycap->pusb_device is NULL\n");
2546 kd = isdongle(peasycap);
2547 if (0 <= kd && DONGLE_MANY > kd) {
2548 if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
2549 SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd);
2550 return -ERESTARTSYS;
2552 JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
2553 /*---------------------------------------------------------------------------*/
2555 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
2556 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
2557 * IF NECESSARY, BAIL OUT.
2559 /*---------------------------------------------------------------------------*/
2560 if (kd != isdongle(peasycap))
2561 return -ERESTARTSYS;
2563 SAY("ERROR: file is NULL\n");
2564 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2565 return -ERESTARTSYS;
2567 peasycap = file->private_data;
2568 if (NULL == peasycap) {
2569 SAY("ERROR: peasycap is NULL\n");
2570 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2571 return -ERESTARTSYS;
2573 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2574 SAY("ERROR: bad peasycap\n");
2575 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2578 p = peasycap->pusb_device;
2579 if (NULL == peasycap->pusb_device) {
2580 SAM("ERROR: peasycap->pusb_device is NULL\n");
2581 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2582 return -ERESTARTSYS;
2585 /*---------------------------------------------------------------------------*/
2587 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
2588 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
2590 /*---------------------------------------------------------------------------*/
2591 return -ERESTARTSYS;
2593 /*---------------------------------------------------------------------------*/
2595 case SNDCTL_DSP_GETCAPS: {
2597 JOM(8, "SNDCTL_DSP_GETCAPS\n");
2599 #if defined(UPSAMPLE)
2600 if (true == peasycap->microphone)
2605 if (true == peasycap->microphone)
2611 if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
2612 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2617 case SNDCTL_DSP_GETFMTS: {
2619 JOM(8, "SNDCTL_DSP_GETFMTS\n");
2621 #if defined(UPSAMPLE)
2622 if (true == peasycap->microphone)
2623 incoming = AFMT_S16_LE;
2625 incoming = AFMT_S16_LE;
2627 if (true == peasycap->microphone)
2628 incoming = AFMT_S16_LE;
2630 incoming = AFMT_S16_LE;
2633 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2634 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2639 case SNDCTL_DSP_SETFMT: {
2640 int incoming, outgoing;
2641 JOM(8, "SNDCTL_DSP_SETFMT\n");
2642 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2643 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2646 JOM(8, "........... %i=incoming\n", incoming);
2648 #if defined(UPSAMPLE)
2649 if (true == peasycap->microphone)
2650 outgoing = AFMT_S16_LE;
2652 outgoing = AFMT_S16_LE;
2654 if (true == peasycap->microphone)
2655 outgoing = AFMT_S16_LE;
2657 outgoing = AFMT_S16_LE;
2660 if (incoming != outgoing) {
2661 JOM(8, "........... %i=outgoing\n", outgoing);
2662 JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
2663 JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8);
2664 if (0 != copy_to_user((void __user *)arg, &outgoing, \
2666 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2669 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2674 case SNDCTL_DSP_STEREO: {
2676 JOM(8, "SNDCTL_DSP_STEREO\n");
2677 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2678 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2681 JOM(8, "........... %i=incoming\n", incoming);
2683 #if defined(UPSAMPLE)
2684 if (true == peasycap->microphone)
2689 if (true == peasycap->microphone)
2695 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2696 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2701 case SNDCTL_DSP_SPEED: {
2703 JOM(8, "SNDCTL_DSP_SPEED\n");
2704 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2705 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2708 JOM(8, "........... %i=incoming\n", incoming);
2710 #if defined(UPSAMPLE)
2711 if (true == peasycap->microphone)
2716 if (true == peasycap->microphone)
2722 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2723 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2728 case SNDCTL_DSP_GETTRIGGER: {
2730 JOM(8, "SNDCTL_DSP_GETTRIGGER\n");
2731 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2732 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2735 JOM(8, "........... %i=incoming\n", incoming);
2737 incoming = PCM_ENABLE_INPUT;
2738 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2739 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2744 case SNDCTL_DSP_SETTRIGGER: {
2746 JOM(8, "SNDCTL_DSP_SETTRIGGER\n");
2747 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2748 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2751 JOM(8, "........... %i=incoming\n", incoming);
2752 JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
2753 "0x%x=PCM_ENABLE_OUTPUT\n", \
2754 PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
2761 case SNDCTL_DSP_GETBLKSIZE: {
2763 JOM(8, "SNDCTL_DSP_GETBLKSIZE\n");
2764 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2765 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2768 JOM(8, "........... %i=incoming\n", incoming);
2769 incoming = peasycap->audio_bytes_per_fragment;
2770 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2771 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2776 case SNDCTL_DSP_GETISPACE: {
2777 struct audio_buf_info audio_buf_info;
2779 JOM(8, "SNDCTL_DSP_GETISPACE\n");
2781 audio_buf_info.bytes = peasycap->audio_bytes_per_fragment;
2782 audio_buf_info.fragments = 1;
2783 audio_buf_info.fragsize = 0;
2784 audio_buf_info.fragstotal = 0;
2786 if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
2788 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2799 JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
2800 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2801 return -ENOIOCTLCMD;
2804 JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2805 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2806 return -ENOIOCTLCMD;
2809 mutex_unlock(&easycap_dongle[kd].mutex_audio);
2812 /*****************************************************************************/