staging/easycap: fix missing backslash in ifdef statement
[pandora-kernel.git] / drivers / staging / easycap / easycap_ioctl.c
1 /******************************************************************************
2 *                                                                             *
3 *  easycap_ioctl.c                                                            *
4 *                                                                             *
5 ******************************************************************************/
6 /*
7  *
8  *  Copyright (C) 2010 R.M. Thomas  <rmthomas@sciolus.org>
9  *
10  *
11  *  This is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  The software is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this software; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25 */
26 /*****************************************************************************/
27
28 #include <linux/smp_lock.h>
29 #include "easycap.h"
30
31 /*--------------------------------------------------------------------------*/
32 /*
33  *  UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
34  *  FOLLOWING:
35  *          peasycap->standard_offset
36  *          peasycap->inputset[peasycap->input].standard_offset
37  *          peasycap->fps
38  *          peasycap->usec
39  *          peasycap->tolerate
40  *          peasycap->skip
41  */
42 /*---------------------------------------------------------------------------*/
43 int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
44 {
45 struct easycap_standard const *peasycap_standard;
46 __u16 reg, set;
47 int ir, rc, need, k;
48 unsigned int itwas, isnow;
49 bool resubmit;
50
51 if (NULL == peasycap) {
52         SAY("ERROR: peasycap is NULL\n");
53         return -EFAULT;
54 }
55 if ((struct usb_device *)NULL == peasycap->pusb_device) {
56         SAM("ERROR: peasycap->pusb_device is NULL\n");
57         return -EFAULT;
58 }
59 peasycap_standard = &easycap_standard[0];
60 while (0xFFFF != peasycap_standard->mask) {
61         if (std_id == peasycap_standard->v4l2_standard.id)
62                 break;
63         peasycap_standard++;
64 }
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)
69                         break;
70                 peasycap_standard++;
71         }
72 }
73 if (0xFFFF == peasycap_standard->mask) {
74         SAM("ERROR: 0x%08X=std_id: standard not found\n",
75                                                         (unsigned int)std_id);
76         return -EINVAL;
77 }
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");
83         return 0;
84 }
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;
90         }
91 }
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;
96 } else
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) {
101 case 6:
102 case 30: {
103         peasycap->ntsc = true;
104         break;
105 }
106 case 5:
107 case 25: {
108         peasycap->ntsc = false;
109         break;
110 }
111 default: {
112         SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
113         return -ENOENT;
114 }
115 }
116 JOM(8, "%i frames-per-second\n", peasycap->fps);
117 if (0x8000 & peasycap_standard->mask) {
118         peasycap->skip = 5;
119         peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
120         peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
121 } else {
122         peasycap->skip = 0;
123         peasycap->usec = 1000000 / (2 * peasycap->fps);
124         peasycap->tolerate = 1000 * (25 / peasycap->fps);
125 }
126 if (peasycap->video_isoc_streaming) {
127         resubmit = true;
128         kill_video_urbs(peasycap);
129 } else
130         resubmit = false;
131 /*--------------------------------------------------------------------------*/
132 /*
133  *  SAA7113H DATASHEET PAGE 44, TABLE 42
134  */
135 /*--------------------------------------------------------------------------*/
136 need = 0;  itwas = 0;  reg = 0x00;  set = 0x00;
137 switch (peasycap_standard->mask & 0x000F) {
138 case NTSC_M_JP: {
139         reg = 0x0A;  set = 0x95;
140         ir = read_saa(peasycap->pusb_device, reg);
141         if (0 > ir)
142                 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
143         else
144                 itwas = (unsigned int)ir;
145         rc = write_saa(peasycap->pusb_device, reg, set);
146         if (0 != rc)
147                 SAM("ERROR: failed to set SAA register "
148                         "0x%02X to 0x%02X for JP standard\n", reg, set);
149         else {
150                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
151                 if (0 > ir)
152                         JOM(8, "SAA register 0x%02X changed "
153                                 "to 0x%02X\n", reg, isnow);
154                 else
155                         JOM(8, "SAA register 0x%02X changed "
156                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
157         }
158
159         reg = 0x0B;  set = 0x48;
160         ir = read_saa(peasycap->pusb_device, reg);
161         if (0 > ir)
162                 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
163         else
164                 itwas = (unsigned int)ir;
165         rc = write_saa(peasycap->pusb_device, reg, set);
166         if (0 != rc)
167                 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X "
168                                                 "for JP standard\n", reg, set);
169         else {
170                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
171                 if (0 > ir)
172                         JOM(8, "SAA register 0x%02X changed "
173                                 "to 0x%02X\n", reg, isnow);
174                 else
175                         JOM(8, "SAA register 0x%02X changed "
176                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
177         }
178 /*--------------------------------------------------------------------------*/
179 /*
180  *  NOTE:  NO break HERE:  RUN ON TO NEXT CASE
181  */
182 /*--------------------------------------------------------------------------*/
183 }
184 case NTSC_M:
185 case PAL_BGHIN: {
186         reg = 0x0E;  set = 0x01;  need = 1;  break;
187 }
188 case NTSC_N_443:
189 case PAL_60: {
190         reg = 0x0E;  set = 0x11;  need = 1;  break;
191 }
192 case NTSC_443:
193 case PAL_Nc: {
194         reg = 0x0E;  set = 0x21;  need = 1;  break;
195 }
196 case NTSC_N:
197 case PAL_M: {
198         reg = 0x0E;  set = 0x31;  need = 1;  break;
199 }
200 case SECAM: {
201         reg = 0x0E;  set = 0x51;  need = 1;  break;
202 }
203 default:
204         break;
205 }
206 /*--------------------------------------------------------------------------*/
207 if (need) {
208         ir = read_saa(peasycap->pusb_device, reg);
209         if (0 > ir)
210                 SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
211         else
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);
217         } else {
218                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
219                 if (0 > ir)
220                         JOM(8, "SAA register 0x%02X changed "
221                                 "to 0x%02X\n", reg, isnow);
222                 else
223                         JOM(8, "SAA register 0x%02X changed "
224                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
225         }
226 }
227 /*--------------------------------------------------------------------------*/
228 /*
229  *  SAA7113H DATASHEET PAGE 41
230  */
231 /*--------------------------------------------------------------------------*/
232 reg = 0x08;
233 ir = read_saa(peasycap->pusb_device, reg);
234 if (0 > ir)
235         SAM("ERROR: failed to read SAA register 0x%02X "
236                                                 "so cannot reset\n", reg);
237 else {
238         itwas = (unsigned int)ir;
239         if (peasycap_standard->mask & 0x0001)
240                 set = itwas | 0x40 ;
241         else
242                 set = itwas & ~0x40 ;
243         rc  = write_saa(peasycap->pusb_device, reg, set);
244         if (0 != rc)
245                 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
246                                                                 reg, set);
247         else {
248                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
249                 if (0 > ir)
250                         JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
251                                                                 reg, isnow);
252                 else
253                         JOM(8, "SAA register 0x%02X changed "
254                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
255         }
256 }
257 /*--------------------------------------------------------------------------*/
258 /*
259  *  SAA7113H DATASHEET PAGE 51, TABLE 57
260  */
261 /*---------------------------------------------------------------------------*/
262 reg = 0x40;
263 ir = read_saa(peasycap->pusb_device, reg);
264 if (0 > ir)
265         SAM("ERROR: failed to read SAA register 0x%02X "
266                                                 "so cannot reset\n", reg);
267 else {
268         itwas = (unsigned int)ir;
269         if (peasycap_standard->mask & 0x0001)
270                 set = itwas | 0x80 ;
271         else
272                 set = itwas & ~0x80 ;
273         rc = write_saa(peasycap->pusb_device, reg, set);
274         if (0 != rc)
275                 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
276                                                                 reg, set);
277         else {
278                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
279                 if (0 > ir)
280                         JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
281                                                                 reg, isnow);
282                 else
283                         JOM(8, "SAA register 0x%02X changed "
284                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
285         }
286 }
287 /*--------------------------------------------------------------------------*/
288 /*
289  *  SAA7113H DATASHEET PAGE 53, TABLE 66
290  */
291 /*--------------------------------------------------------------------------*/
292 reg = 0x5A;
293 ir = read_saa(peasycap->pusb_device, reg);
294 if (0 > ir)
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)
298                 set = 0x0A ;
299         else
300                 set = 0x07 ;
301         if (0 != write_saa(peasycap->pusb_device, reg, set))
302                 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
303                                                                 reg, set);
304         else {
305                 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
306                 if (0 > ir)
307                         JOM(8, "SAA register 0x%02X changed "
308                                 "to 0x%02X\n", reg, isnow);
309                 else
310                         JOM(8, "SAA register 0x%02X changed "
311                                 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
312         }
313 if (true == resubmit)
314         submit_video_urbs(peasycap);
315 return 0;
316 }
317 /*****************************************************************************/
318 /*--------------------------------------------------------------------------*/
319 /*
320  *  THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
321  *  A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
322  *
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
328  *          peasycap->height
329  *          peasycap->width
330  *          peasycap->bytesperpixel
331  *          peasycap->byteswaporder
332  *          peasycap->decimatepixel
333  *          peasycap->frame_buffer_used
334  *          peasycap->videofieldamount
335  *          peasycap->offerfields
336  *
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.
340  */
341 /*--------------------------------------------------------------------------*/
342 int adjust_format(struct easycap *peasycap,
343         __u32 width, __u32 height, __u32 pixelformat, int field, bool try)
344 {
345 struct easycap_format *peasycap_format, *peasycap_best_format;
346 __u16 mask;
347 struct usb_device *p;
348 int miss, multiplier, best, k;
349 char bf[5], fo[32], *pc;
350 __u32 uc;
351 bool resubmit;
352
353 if (NULL == peasycap) {
354         SAY("ERROR: peasycap is NULL\n");
355         return -EFAULT;
356 }
357 if (0 > peasycap->standard_offset) {
358         JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
359         return -EBUSY;
360 }
361 p = peasycap->pusb_device;
362 if ((struct usb_device *)NULL == p) {
363         SAM("ERROR: peaycap->pusb_device is NULL\n");
364         return -EFAULT;
365 }
366 pc = &bf[0];
367 uc = pixelformat;
368 memcpy((void *)pc, (void *)(&uc), 4);
369 bf[4] = 0;
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);
373 switch (field) {
374 case V4L2_FIELD_ANY: {
375         strcpy(&fo[0], "V4L2_FIELD_ANY ");
376         break;
377 }
378 case V4L2_FIELD_NONE: {
379         strcpy(&fo[0], "V4L2_FIELD_NONE");
380         break;
381 }
382 case V4L2_FIELD_TOP: {
383         strcpy(&fo[0], "V4L2_FIELD_TOP");
384         break;
385 }
386 case V4L2_FIELD_BOTTOM: {
387         strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
388         break;
389 }
390 case V4L2_FIELD_INTERLACED: {
391         strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
392         break;
393 }
394 case V4L2_FIELD_SEQ_TB: {
395         strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
396         break;
397 }
398 case V4L2_FIELD_SEQ_BT: {
399         strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
400         break;
401 }
402 case V4L2_FIELD_ALTERNATE: {
403         strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
404         break;
405 }
406 case V4L2_FIELD_INTERLACED_TB: {
407         strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
408         break;
409 }
410 case V4L2_FIELD_INTERLACED_BT: {
411         strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
412         break;
413 }
414 default: {
415         strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN  ");
416         break;
417 }
418 }
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");
423 }
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);
433
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 ==
437                                                         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;
441                         break;
442                 }
443         peasycap_format++;
444 }
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
452                                                 .field == field) &&
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)) {
458                                 best = miss;
459                                 peasycap_best_format = peasycap_format;
460                                 if (!miss)
461                                         break;
462                         }
463                 }
464                 peasycap_format++;
465         }
466         if (-1 == best) {
467                 SAM("cannot do %ix... with standard mask 0x%02X\n",
468                                                                 width, mask);
469                 SAM("cannot do ...x%i with standard mask 0x%02X\n",
470                                                                 height, mask);
471                 SAM("           %ix%i unmatched\n", width, height);
472                 return peasycap->format_offset;
473         }
474 }
475 if ((struct easycap_format *)NULL == peasycap_best_format) {
476         SAM("MISTAKE: peasycap_best_format is NULL");
477         return -EINVAL;
478 }
479 peasycap_format = peasycap_best_format;
480
481 /*...........................................................................*/
482 if (true == try)
483         return (int)(peasycap_best_format - &easycap_format[0]);
484 /*...........................................................................*/
485
486 if (false != try) {
487         SAM("MISTAKE: true==try where is should be false\n");
488         return -EINVAL;
489 }
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]);
498
499
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;
504         }
505 }
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;
510 } else
511         JOM(8, "%i=peasycap->input\n", peasycap->input);
512
513
514
515 peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
516 if (0x0100 & peasycap_format->mask)
517         peasycap->byteswaporder = true;
518 else
519         peasycap->byteswaporder = false;
520 if (0x0200 & peasycap_format->mask)
521         peasycap->skip = 5;
522 else
523         peasycap->skip = 0;
524 if (0x0800 & peasycap_format->mask)
525         peasycap->decimatepixel = true;
526 else
527         peasycap->decimatepixel = false;
528 if (0x1000 & peasycap_format->mask)
529         peasycap->offerfields = true;
530 else
531         peasycap->offerfields = false;
532 if (true == peasycap->decimatepixel)
533         multiplier = 2;
534 else
535         multiplier = 1;
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) {
541         resubmit = true;
542         kill_video_urbs(peasycap);
543 } else
544         resubmit = false;
545 /*---------------------------------------------------------------------------*/
546 /*
547  *  PAL
548  */
549 /*---------------------------------------------------------------------------*/
550 if (0 == (0x01 & peasycap_format->mask)) {
551         if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
552                         (576 ==
553                         peasycap_format->v4l2_format.fmt.pix.height)) ||
554                         ((360 ==
555                         peasycap_format->v4l2_format.fmt.pix.width) &&
556                         (288 ==
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");
560                         return -EINVAL;
561                 }
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");
566                         return -EINVAL;
567                 }
568         } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
569                         (480 ==
570                         peasycap_format->v4l2_format.fmt.pix.height)) ||
571                         ((320 ==
572                         peasycap_format->v4l2_format.fmt.pix.width) &&
573                         (240 ==
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");
577                         return -EINVAL;
578                 }
579         } else {
580                 SAM("MISTAKE: bad format, cannot set resolution\n");
581                 return -EINVAL;
582         }
583 /*---------------------------------------------------------------------------*/
584 /*
585  *  NTSC
586  */
587 /*---------------------------------------------------------------------------*/
588 } else {
589         if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
590                         (480 ==
591                         peasycap_format->v4l2_format.fmt.pix.height)) ||
592                         ((360 ==
593                         peasycap_format->v4l2_format.fmt.pix.width) &&
594                         (240 ==
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");
598                         return -EINVAL;
599                 }
600         } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
601                         (480 ==
602                         peasycap_format->v4l2_format.fmt.pix.height)) ||
603                         ((320 ==
604                         peasycap_format->v4l2_format.fmt.pix.width) &&
605                         (240 ==
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");
609                         return -EINVAL;
610                 }
611         } else {
612                 SAM("MISTAKE: bad format, cannot set resolution\n");
613                 return -EINVAL;
614         }
615 }
616 /*---------------------------------------------------------------------------*/
617 if (true == resubmit)
618         submit_video_urbs(peasycap);
619 return (int)(peasycap_best_format - &easycap_format[0]);
620 }
621 /*****************************************************************************/
622 int adjust_brightness(struct easycap *peasycap, int value)
623 {
624 unsigned int mood;
625 int i1, k;
626
627 if (NULL == peasycap) {
628         SAY("ERROR: peasycap is NULL\n");
629         return -EFAULT;
630 }
631 if ((struct usb_device *)NULL == peasycap->pusb_device) {
632         SAM("ERROR: peasycap->pusb_device is NULL\n");
633         return -EFAULT;
634 }
635 i1 = 0;
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;
641
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",
647                                                                 value);
648                                 return 0;
649                         }
650                 }
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;
656                 }
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;
661                 } else
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);
666                         return 0;
667                 } else {
668                         SAM("WARNING: failed to adjust brightness "
669                                                         "to 0x%02X\n", mood);
670                         return -ENOENT;
671                 }
672                 break;
673         }
674         i1++;
675 }
676 SAM("WARNING: failed to adjust brightness: control not found\n");
677 return -ENOENT;
678 }
679 /*****************************************************************************/
680 int adjust_contrast(struct easycap *peasycap, int value)
681 {
682 unsigned int mood;
683 int i1, k;
684
685 if (NULL == peasycap) {
686         SAY("ERROR: peasycap is NULL\n");
687         return -EFAULT;
688 }
689 if ((struct usb_device *)NULL == peasycap->pusb_device) {
690         SAM("ERROR: peasycap->pusb_device is NULL\n");
691         return -EFAULT;
692 }
693 i1 = 0;
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;
699
700
701
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);
707                                 return 0;
708                         }
709                 }
710                 peasycap->contrast = value;
711                 for (k = 0; k < INPUT_MANY; k++) {
712                         if (!peasycap->inputset[k].contrast_ok) {
713                                 peasycap->inputset[k].contrast =
714                                                         peasycap->contrast;
715                         }
716                 }
717                 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
718                         peasycap->inputset[peasycap->input].contrast =
719                                                         peasycap->contrast;
720                         peasycap->inputset[peasycap->input].contrast_ok = 1;
721                 } else
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);
726                         return 0;
727                 } else {
728                         SAM("WARNING: failed to adjust contrast to "
729                                                         "0x%02X\n", mood);
730                         return -ENOENT;
731                 }
732                 break;
733         }
734         i1++;
735 }
736 SAM("WARNING: failed to adjust contrast: control not found\n");
737 return -ENOENT;
738 }
739 /*****************************************************************************/
740 int adjust_saturation(struct easycap *peasycap, int value)
741 {
742 unsigned int mood;
743 int i1, k;
744
745 if (NULL == peasycap) {
746         SAY("ERROR: peasycap is NULL\n");
747         return -EFAULT;
748 }
749 if ((struct usb_device *)NULL == peasycap->pusb_device) {
750         SAM("ERROR: peasycap->pusb_device is NULL\n");
751         return -EFAULT;
752 }
753 i1 = 0;
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;
759
760
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",
766                                                                 value);
767                                 return 0;
768                         }
769                 }
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;
775                         }
776                 }
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;
781                 } else
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);
786                         return 0;
787                 } else {
788                         SAM("WARNING: failed to adjust saturation to "
789                                                         "0x%02X\n", mood);
790                         return -ENOENT;
791                 }
792                 break;
793         }
794         i1++;
795 }
796 SAM("WARNING: failed to adjust saturation: control not found\n");
797 return -ENOENT;
798 }
799 /*****************************************************************************/
800 int adjust_hue(struct easycap *peasycap, int value)
801 {
802 unsigned int mood;
803 int i1, i2, k;
804
805 if (NULL == peasycap) {
806         SAY("ERROR: peasycap is NULL\n");
807         return -EFAULT;
808 }
809 if ((struct usb_device *)NULL == peasycap->pusb_device) {
810         SAM("ERROR: peasycap->pusb_device is NULL\n");
811         return -EFAULT;
812 }
813 i1 = 0;
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;
819
820                 if ((easycap_control[i1].minimum <= peasycap->hue) &&
821                                         (easycap_control[i1].maximum >=
822                                                         peasycap->hue)) {
823                         if (peasycap->hue == value) {
824                                 SAM("unchanged hue at  0x%02X\n", value);
825                                 return 0;
826                         }
827                 }
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;
832                 }
833                 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
834                         peasycap->inputset[peasycap->input].hue =
835                                                         peasycap->hue;
836                         peasycap->inputset[peasycap->input].hue_ok = 1;
837                 } else
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);
843                         return 0;
844                 } else {
845                         SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
846                         return -ENOENT;
847                 }
848                 break;
849         }
850         i1++;
851 }
852 SAM("WARNING: failed to adjust hue: control not found\n");
853 return -ENOENT;
854 }
855 /*****************************************************************************/
856 int adjust_volume(struct easycap *peasycap, int value)
857 {
858 __s8 mood;
859 int i1;
860
861 if (NULL == peasycap) {
862         SAY("ERROR: peasycap is NULL\n");
863         return -EFAULT;
864 }
865 if ((struct usb_device *)NULL == peasycap->pusb_device) {
866         SAM("ERROR: peasycap->pusb_device is NULL\n");
867         return -EFAULT;
868 }
869 i1 = 0;
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 >=
877                                                         peasycap->volume)) {
878                         if (peasycap->volume == value) {
879                                 SAM("unchanged volume at  0x%02X\n", value);
880                                 return 0;
881                         }
882                 }
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);
889                         return 0;
890                 } else {
891                         SAM("WARNING: failed to adjust volume to "
892                                                         "0x%2X\n", mood);
893                         return -ENOENT;
894                 }
895                 break;
896         }
897 i1++;
898 }
899 SAM("WARNING: failed to adjust volume: control not found\n");
900 return -ENOENT;
901 }
902 /*****************************************************************************/
903 /*---------------------------------------------------------------------------*/
904 /*
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.
912  */
913 /*---------------------------------------------------------------------------*/
914 static int adjust_mute(struct easycap *peasycap, int value)
915 {
916 int i1;
917
918 if (NULL == peasycap) {
919         SAY("ERROR: peasycap is NULL\n");
920         return -EFAULT;
921 }
922 if ((struct usb_device *)NULL == peasycap->pusb_device) {
923         SAM("ERROR: peasycap->pusb_device is NULL\n");
924         return -EFAULT;
925 }
926 i1 = 0;
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) {
931                 case 1: {
932                         peasycap->audio_idle = 1;
933                         peasycap->timeval0.tv_sec = 0;
934                         SAM("adjusting mute: %i=peasycap->audio_idle\n",
935                                                         peasycap->audio_idle);
936                         return 0;
937                 }
938                 default: {
939                         peasycap->audio_idle = 0;
940                         SAM("adjusting mute: %i=peasycap->audio_idle\n",
941                                                         peasycap->audio_idle);
942                         return 0;
943                 }
944                 }
945                 break;
946         }
947         i1++;
948 }
949 SAM("WARNING: failed to adjust mute: control not found\n");
950 return -ENOENT;
951 }
952 /*****************************************************************************/
953 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
954 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
955         (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
956 long
957 easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
958         return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg);
959 }
960 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
961 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
962 /*---------------------------------------------------------------------------*/
963 int
964 easycap_ioctl(struct inode *inode, struct file *file,
965                                         unsigned int cmd, unsigned long arg)
966 {
967 struct easycap *peasycap;
968 struct usb_device *p;
969 int kd;
970
971 if (NULL == file) {
972         SAY("ERROR:  file is NULL\n");
973         return -ERESTARTSYS;
974 }
975 peasycap = file->private_data;
976 if (NULL == peasycap) {
977         SAY("ERROR:  peasycap is NULL\n");
978         return -1;
979 }
980 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
981         SAY("ERROR: bad peasycap\n");
982         return -EFAULT;
983 }
984 p = peasycap->pusb_device;
985 if (NULL == p) {
986         SAM("ERROR: peasycap->pusb_device is NULL\n");
987         return -EFAULT;
988 }
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);
994                 return -ERESTARTSYS;
995         }
996         JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
997 /*---------------------------------------------------------------------------*/
998 /*
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.
1002 */
1003 /*---------------------------------------------------------------------------*/
1004         if (kd != isdongle(peasycap))
1005                 return -ERESTARTSYS;
1006         if (NULL == file) {
1007                 SAY("ERROR:  file is NULL\n");
1008                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1009                 return -ERESTARTSYS;
1010         }
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;
1016         }
1017         if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1018                 SAY("ERROR: bad peasycap\n");
1019                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1020                 return -EFAULT;
1021         }
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;
1027         }
1028 } else {
1029 /*---------------------------------------------------------------------------*/
1030 /*
1031  *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1032  *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
1033 */
1034 /*---------------------------------------------------------------------------*/
1035         return -ERESTARTSYS;
1036 }
1037 /*---------------------------------------------------------------------------*/
1038 switch (cmd) {
1039 case VIDIOC_QUERYCAP: {
1040         struct v4l2_capability v4l2_capability;
1041         char version[16], *p1, *p2;
1042         int i, rc, k[3];
1043         long lng;
1044
1045         JOM(8, "VIDIOC_QUERYCAP\n");
1046
1047         if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
1048                 SAM("ERROR: bad driver version string\n");
1049                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1050                 return -EINVAL;
1051         }
1052         strcpy(&version[0], EASYCAP_DRIVER_VERSION);
1053         for (i = 0; i < 3; i++)
1054                 k[i] = 0;
1055         p2 = &version[0];  i = 0;
1056         while (*p2) {
1057                 p1 = p2;
1058                 while (*p2 && ('.' != *p2))
1059                         p2++;
1060                 if (*p2)
1061                         *p2++ = 0;
1062                 if (3 > i) {
1063                         rc = (int) strict_strtol(p1, 10, &lng);
1064                         if (0 != rc) {
1065                                 SAM("ERROR: %i=strict_strtol(%s,.,,)\n",
1066                                                                 rc, p1);
1067                                 mutex_unlock(&easycapdc60_dongle[kd].
1068                                                                 mutex_video);
1069                                 return -EINVAL;
1070                         }
1071                         k[i] = (int)lng;
1072                 }
1073                 i++;
1074         }
1075
1076         memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
1077         strlcpy(&v4l2_capability.driver[0], "easycap",
1078                                         sizeof(v4l2_capability.driver));
1079
1080         v4l2_capability.capabilities =
1081                                 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1082                                 V4L2_CAP_AUDIO         | V4L2_CAP_READWRITE;
1083
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]);
1086
1087         strlcpy(&v4l2_capability.card[0], "EasyCAP DC60",
1088                 sizeof(v4l2_capability.card));
1089
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]);
1096         }
1097         if (0 != copy_to_user((void __user *)arg, &v4l2_capability,
1098                                         sizeof(struct v4l2_capability))) {
1099                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1100                 return -EFAULT;
1101         }
1102         break;
1103 }
1104 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1105 case VIDIOC_ENUMINPUT: {
1106         struct v4l2_input v4l2_input;
1107         __u32 index;
1108
1109         JOM(8, "VIDIOC_ENUMINPUT\n");
1110
1111         if (0 != copy_from_user(&v4l2_input, (void __user *)arg,
1112                                         sizeof(struct v4l2_input))) {
1113                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1114                 return -EFAULT;
1115         }
1116
1117         index = v4l2_input.index;
1118         memset(&v4l2_input, 0, sizeof(struct v4l2_input));
1119
1120         switch (index) {
1121         case 0: {
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 |
1128                                 V4L2_STD_NTSC ;
1129                 v4l2_input.status = 0;
1130                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1131                 break;
1132         }
1133         case 1: {
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 |
1140                                 V4L2_STD_NTSC ;
1141                 v4l2_input.status = 0;
1142                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1143                 break;
1144         }
1145         case 2: {
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 |
1152                                 V4L2_STD_NTSC ;
1153                 v4l2_input.status = 0;
1154                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1155                 break;
1156         }
1157         case 3: {
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 |
1164                                 V4L2_STD_NTSC ;
1165                 v4l2_input.status = 0;
1166                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1167                 break;
1168         }
1169         case 4: {
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 |
1176                                 V4L2_STD_NTSC ;
1177                 v4l2_input.status = 0;
1178                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1179                 break;
1180         }
1181         case 5: {
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 |
1188                                 V4L2_STD_NTSC ;
1189                 v4l2_input.status = 0;
1190                 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1191                 break;
1192         }
1193         default: {
1194                 JOM(8, "%i=index: exhausts inputs\n", index);
1195                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1196                 return -EINVAL;
1197         }
1198         }
1199
1200         if (0 != copy_to_user((void __user *)arg, &v4l2_input,
1201                                                 sizeof(struct v4l2_input))) {
1202                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1203                 return -EFAULT;
1204         }
1205         break;
1206 }
1207 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1208 case VIDIOC_G_INPUT: {
1209         __u32 index;
1210
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);
1216                 return -EFAULT;
1217         }
1218         break;
1219 }
1220 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1221 case VIDIOC_S_INPUT:
1222         {
1223         __u32 index;
1224         int rc;
1225
1226         JOM(8, "VIDIOC_S_INPUT\n");
1227
1228         if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
1229                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1230                 return -EFAULT;
1231         }
1232
1233         JOM(8, "user requests input %i\n", index);
1234
1235         if ((int)index == peasycap->input) {
1236                 SAM("requested input already in effect\n");
1237                 break;
1238         }
1239
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);
1243                 return -EINVAL;
1244         }
1245
1246         rc = newinput(peasycap, (int)index);
1247         if (0 == rc) {
1248                 JOM(8, "newinput(.,%i) OK\n", (int)index);
1249         } else {
1250                 SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
1251                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1252                 return -EFAULT;
1253         }
1254         break;
1255 }
1256 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1257 case VIDIOC_ENUMAUDIO: {
1258         JOM(8, "VIDIOC_ENUMAUDIO\n");
1259         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1260         return -EINVAL;
1261 }
1262 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1263 case VIDIOC_ENUMAUDOUT: {
1264         struct v4l2_audioout v4l2_audioout;
1265
1266         JOM(8, "VIDIOC_ENUMAUDOUT\n");
1267
1268         if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg,
1269                                         sizeof(struct v4l2_audioout))) {
1270                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1271                 return -EFAULT;
1272         }
1273
1274         if (0 != v4l2_audioout.index) {
1275                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1276                 return -EINVAL;
1277         }
1278         memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1279         v4l2_audioout.index = 0;
1280         strcpy(&v4l2_audioout.name[0], "Soundtrack");
1281
1282         if (0 != copy_to_user((void __user *)arg, &v4l2_audioout,
1283                                         sizeof(struct v4l2_audioout))) {
1284                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1285                 return -EFAULT;
1286         }
1287         break;
1288 }
1289 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1290 case VIDIOC_QUERYCTRL: {
1291         int i1;
1292         struct v4l2_queryctrl v4l2_queryctrl;
1293
1294         JOM(8, "VIDIOC_QUERYCTRL\n");
1295
1296         if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg,
1297                                         sizeof(struct v4l2_queryctrl))) {
1298                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1299                 return -EFAULT;
1300         }
1301
1302         i1 = 0;
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));
1309                         break;
1310                 }
1311                 i1++;
1312         }
1313         if (0xFFFFFFFF == easycap_control[i1].id) {
1314                 JOM(8, "%i=index: exhausts controls\n", i1);
1315                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1316                 return -EINVAL;
1317         }
1318         if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl,
1319                                         sizeof(struct v4l2_queryctrl))) {
1320                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1321                 return -EFAULT;
1322         }
1323         break;
1324 }
1325 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1326 case VIDIOC_QUERYMENU: {
1327         JOM(8, "VIDIOC_QUERYMENU unsupported\n");
1328         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1329         return -EINVAL;
1330 }
1331 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1332 case VIDIOC_G_CTRL: {
1333         struct v4l2_control *pv4l2_control;
1334
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);
1340                 return -ENOMEM;
1341         }
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);
1346                 return -EFAULT;
1347         }
1348
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);
1353                 break;
1354         }
1355         case V4L2_CID_CONTRAST: {
1356                 pv4l2_control->value = peasycap->contrast;
1357                 JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
1358                 break;
1359         }
1360         case V4L2_CID_SATURATION: {
1361                 pv4l2_control->value = peasycap->saturation;
1362                 JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
1363                 break;
1364         }
1365         case V4L2_CID_HUE: {
1366                 pv4l2_control->value = peasycap->hue;
1367                 JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
1368                 break;
1369         }
1370         case V4L2_CID_AUDIO_VOLUME: {
1371                 pv4l2_control->value = peasycap->volume;
1372                 JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
1373                 break;
1374         }
1375         case V4L2_CID_AUDIO_MUTE: {
1376                 if (1 == peasycap->mute)
1377                         pv4l2_control->value = true;
1378                 else
1379                         pv4l2_control->value = false;
1380                 JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
1381                 break;
1382         }
1383         default: {
1384                 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1385                                                         pv4l2_control->id);
1386                 kfree(pv4l2_control);
1387                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1388                 return -EINVAL;
1389         }
1390         }
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);
1395                 return -EFAULT;
1396         }
1397         kfree(pv4l2_control);
1398         break;
1399 }
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");
1404 }
1405 #endif /*VIDIOC_S_CTRL_OLD*/
1406 case VIDIOC_S_CTRL:
1407         {
1408         struct v4l2_control v4l2_control;
1409
1410         JOM(8, "VIDIOC_S_CTRL\n");
1411
1412         if (0 != copy_from_user(&v4l2_control, (void __user *)arg,
1413                                         sizeof(struct v4l2_control))) {
1414                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1415                 return -EFAULT;
1416         }
1417
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))
1422                         ;
1423                 break;
1424         }
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))
1428                         ;
1429                 break;
1430         }
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))
1434                         ;
1435                 break;
1436         }
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))
1440                         ;
1441                 break;
1442         }
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))
1446                         ;
1447                 break;
1448         }
1449         case V4L2_CID_AUDIO_MUTE: {
1450                 int mute;
1451
1452                 JOM(8, "user requests mute %i\n", v4l2_control.value);
1453                 if (true == v4l2_control.value)
1454                         mute = 1;
1455                 else
1456                         mute = 0;
1457
1458                 if (0 != adjust_mute(peasycap, mute))
1459                         SAM("WARNING: failed to adjust mute to %i\n", mute);
1460                 break;
1461         }
1462         default: {
1463                 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1464                                                         v4l2_control.id);
1465                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1466                 return -EINVAL;
1467         }
1468         }
1469         break;
1470 }
1471 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1472 case VIDIOC_S_EXT_CTRLS: {
1473         JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1474         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1475         return -EINVAL;
1476 }
1477 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1478 case VIDIOC_ENUM_FMT: {
1479         __u32 index;
1480         struct v4l2_fmtdesc v4l2_fmtdesc;
1481
1482         JOM(8, "VIDIOC_ENUM_FMT\n");
1483
1484         if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg,
1485                                         sizeof(struct v4l2_fmtdesc))) {
1486                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1487                 return -EFAULT;
1488         }
1489
1490         index = v4l2_fmtdesc.index;
1491         memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1492
1493         v4l2_fmtdesc.index = index;
1494         v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1495
1496         switch (index) {
1497         case 0: {
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]);
1502                 break;
1503         }
1504         case 1: {
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]);
1509                 break;
1510         }
1511         case 2: {
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]);
1516                 break;
1517         }
1518         case 3: {
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]);
1523                 break;
1524         }
1525         case 4: {
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]);
1530                 break;
1531         }
1532         case 5: {
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]);
1537                 break;
1538         }
1539         default: {
1540                 JOM(8, "%i=index: exhausts formats\n", index);
1541                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1542                 return -EINVAL;
1543         }
1544         }
1545         if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc,
1546                                         sizeof(struct v4l2_fmtdesc))) {
1547                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1548                 return -EFAULT;
1549         }
1550         break;
1551 }
1552 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1553 /*
1554  *  THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
1555  *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
1556 */
1557 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1558 case VIDIOC_ENUM_FRAMESIZES: {
1559         __u32 index;
1560         struct v4l2_frmsizeenum v4l2_frmsizeenum;
1561
1562         JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
1563
1564         if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg,
1565                                         sizeof(struct v4l2_frmsizeenum))) {
1566                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1567                 return -EFAULT;
1568         }
1569
1570         index = v4l2_frmsizeenum.index;
1571
1572         v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;
1573
1574         if (true == peasycap->ntsc) {
1575                 switch (index) {
1576                 case 0: {
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.
1581                                                  discrete.width),
1582                                         (int)(v4l2_frmsizeenum.
1583                                                 discrete.height));
1584                         break;
1585                 }
1586                 case 1: {
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.
1591                                                 discrete.width),
1592                                         (int)(v4l2_frmsizeenum.
1593                                                 discrete.height));
1594                         break;
1595                 }
1596                 case 2: {
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.
1601                                                 discrete.width),
1602                                         (int)(v4l2_frmsizeenum.
1603                                                 discrete.height));
1604                         break;
1605                 }
1606                 case 3: {
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.
1611                                                 discrete.width),
1612                                         (int)(v4l2_frmsizeenum.
1613                                                 discrete.height));
1614                         break;
1615                 }
1616                 default: {
1617                         JOM(8, "%i=index: exhausts framesizes\n", index);
1618                         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1619                         return -EINVAL;
1620                 }
1621                 }
1622         } else {
1623                 switch (index) {
1624                 case 0: {
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.
1629                                                 discrete.width),
1630                                         (int)(v4l2_frmsizeenum.
1631                                                 discrete.height));
1632                         break;
1633                 }
1634                 case 1: {
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.
1639                                                 discrete.width),
1640                                         (int)(v4l2_frmsizeenum.
1641                                                 discrete.height));
1642                         break;
1643                 }
1644                 case 2: {
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.
1649                                                 discrete.width),
1650                                         (int)(v4l2_frmsizeenum.
1651                                                 discrete.height));
1652                         break;
1653                 }
1654                 case 3: {
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.
1659                                                 discrete.width),
1660                                         (int)(v4l2_frmsizeenum.
1661                                                 discrete.height));
1662                         break;
1663                 }
1664                 case 4: {
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.
1669                                                 discrete.width),
1670                                         (int)(v4l2_frmsizeenum.
1671                                                 discrete.height));
1672                         break;
1673                 }
1674                 default: {
1675                         JOM(8, "%i=index: exhausts framesizes\n", index);
1676                         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1677                         return -EINVAL;
1678                 }
1679                 }
1680         }
1681         if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum,
1682                                         sizeof(struct v4l2_frmsizeenum))) {
1683                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1684                 return -EFAULT;
1685         }
1686         break;
1687 }
1688 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1689 /*
1690  *  THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
1691  *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
1692 */
1693 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1694 case VIDIOC_ENUM_FRAMEINTERVALS: {
1695         __u32 index;
1696         int denominator;
1697         struct v4l2_frmivalenum v4l2_frmivalenum;
1698
1699         JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
1700
1701         if (peasycap->fps)
1702                 denominator = peasycap->fps;
1703         else {
1704                 if (true == peasycap->ntsc)
1705                         denominator = 30;
1706                 else
1707                         denominator = 25;
1708         }
1709
1710         if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg,
1711                                         sizeof(struct v4l2_frmivalenum))) {
1712                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1713                 return -EFAULT;
1714         }
1715
1716         index = v4l2_frmivalenum.index;
1717
1718         v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;
1719
1720         switch (index) {
1721         case 0: {
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));
1727                 break;
1728         }
1729         case 1: {
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));
1735                 break;
1736         }
1737         default: {
1738                 JOM(8, "%i=index: exhausts frameintervals\n", index);
1739                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1740                 return -EINVAL;
1741         }
1742         }
1743         if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum,
1744                                         sizeof(struct v4l2_frmivalenum))) {
1745                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1746                 return -EFAULT;
1747         }
1748         break;
1749 }
1750 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1751 case VIDIOC_G_FMT: {
1752         struct v4l2_format *pv4l2_format;
1753         struct v4l2_pix_format *pv4l2_pix_format;
1754
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);
1760                 return -ENOMEM;
1761         }
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);
1767                 return -ENOMEM;
1768         }
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);
1774                 return -EFAULT;
1775         }
1776
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);
1781                 return -EINVAL;
1782         }
1783
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]);
1791
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);
1797                 return -EFAULT;
1798         }
1799         kfree(pv4l2_format);
1800         kfree(pv4l2_pix_format);
1801         break;
1802 }
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;
1808         bool try;
1809         int best_format;
1810
1811         if (VIDIOC_TRY_FMT == cmd) {
1812                 JOM(8, "VIDIOC_TRY_FMT\n");
1813                 try = true;
1814         } else {
1815                 JOM(8, "VIDIOC_S_FMT\n");
1816                 try = false;
1817         }
1818
1819         if (0 != copy_from_user(&v4l2_format, (void __user *)arg,
1820                                         sizeof(struct v4l2_format))) {
1821                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1822                 return -EFAULT;
1823         }
1824
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,
1830                                         try);
1831         if (0 > best_format) {
1832                 if (-EBUSY == best_format) {
1833                         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1834                         return -EBUSY;
1835                 }
1836                 JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
1837                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1838                 return -ENOENT;
1839         }
1840 /*...........................................................................*/
1841         memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1842         v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1843
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]);
1847
1848         if (0 != copy_to_user((void __user *)arg, &v4l2_format,
1849                                         sizeof(struct v4l2_format))) {
1850                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1851                 return -EFAULT;
1852         }
1853         break;
1854 }
1855 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1856 case VIDIOC_CROPCAP: {
1857         struct v4l2_cropcap v4l2_cropcap;
1858
1859         JOM(8, "VIDIOC_CROPCAP\n");
1860
1861         if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg,
1862                                         sizeof(struct v4l2_cropcap))) {
1863                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1864                 return -EFAULT;
1865         }
1866
1867         if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1868                 JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1869
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;
1882
1883         JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1884
1885         if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap,
1886                                         sizeof(struct v4l2_cropcap))) {
1887                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1888                 return -EFAULT;
1889         }
1890         break;
1891 }
1892 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1893 case VIDIOC_G_CROP:
1894 case VIDIOC_S_CROP: {
1895         JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP  unsupported\n");
1896         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1897         return -EINVAL;
1898 }
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);
1904         return -EINVAL;
1905         break;
1906 }
1907 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1908 /*---------------------------------------------------------------------------*/
1909 /*
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.
1913  */
1914 /*---------------------------------------------------------------------------*/
1915 case VIDIOC_ENUMSTD: {
1916         int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1917         struct v4l2_standard v4l2_standard;
1918         __u32 index;
1919         struct easycap_standard const *peasycap_standard;
1920
1921         JOM(8, "VIDIOC_ENUMSTD\n");
1922
1923         if (0 != copy_from_user(&v4l2_standard, (void __user *)arg,
1924                                         sizeof(struct v4l2_standard))) {
1925                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1926                 return -EFAULT;
1927         }
1928         index = v4l2_standard.index;
1929
1930         last3 = last2; last2 = last1; last1 = last0; last0 = index;
1931         if ((index == last3) && (index == last2) &&
1932                         (index == last1) && (index == last0)) {
1933                 index++;
1934                 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1935         }
1936
1937         memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1938
1939         peasycap_standard = &easycap_standard[0];
1940         while (0xFFFF != peasycap_standard->mask) {
1941                 if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1942                         break;
1943                 peasycap_standard++;
1944         }
1945         if (0xFFFF == peasycap_standard->mask) {
1946                 JOM(8, "%i=index: exhausts standards\n", index);
1947                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1948                 return -EINVAL;
1949         }
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));
1954
1955         v4l2_standard.index = index;
1956
1957         if (0 != copy_to_user((void __user *)arg, &v4l2_standard,
1958                                         sizeof(struct v4l2_standard))) {
1959                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1960                 return -EFAULT;
1961         }
1962         break;
1963 }
1964 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1965 case VIDIOC_G_STD: {
1966         v4l2_std_id std_id;
1967         struct easycap_standard const *peasycap_standard;
1968
1969         JOM(8, "VIDIOC_G_STD\n");
1970
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);
1975                 return -EBUSY;
1976         }
1977
1978         if (0 != copy_from_user(&std_id, (void __user *)arg,
1979                                                 sizeof(v4l2_std_id))) {
1980                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1981                 return -EFAULT;
1982         }
1983
1984         peasycap_standard = &easycap_standard[peasycap->standard_offset];
1985         std_id = peasycap_standard->v4l2_standard.id;
1986
1987         JOM(8, "user is told: %s\n",
1988                                 &peasycap_standard->v4l2_standard.name[0]);
1989
1990         if (0 != copy_to_user((void __user *)arg, &std_id,
1991                                                 sizeof(v4l2_std_id))) {
1992                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1993                 return -EFAULT;
1994         }
1995         break;
1996 }
1997 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1998 case VIDIOC_S_STD: {
1999         v4l2_std_id std_id;
2000         int rc;
2001
2002         JOM(8, "VIDIOC_S_STD\n");
2003
2004         if (0 != copy_from_user(&std_id, (void __user *)arg,
2005                                                 sizeof(v4l2_std_id))) {
2006                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2007                 return -EFAULT;
2008         }
2009
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)));
2013
2014         rc = adjust_standard(peasycap, std_id);
2015         if (0 > rc) {
2016                 JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
2017                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2018                 return -ENOENT;
2019         }
2020         break;
2021 }
2022 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2023 case VIDIOC_REQBUFS: {
2024         int nbuffers;
2025         struct v4l2_requestbuffers v4l2_requestbuffers;
2026
2027         JOM(8, "VIDIOC_REQBUFS\n");
2028
2029         if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg,
2030                                 sizeof(struct v4l2_requestbuffers))) {
2031                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2032                 return -EFAULT;
2033         }
2034
2035         if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2036                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2037                 return -EINVAL;
2038         }
2039         if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
2040                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2041                 return -EINVAL;
2042         }
2043         nbuffers = v4l2_requestbuffers.count;
2044         JOM(8, "                   User requests %i buffers ...\n", nbuffers);
2045         if (nbuffers < 2)
2046                 nbuffers = 2;
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",
2051                                                                 nbuffers);
2052         } else {
2053                 JOM(8, "                  ... insist on  %i buffers\n",
2054                                                                 nbuffers);
2055                 v4l2_requestbuffers.count = nbuffers;
2056         }
2057         peasycap->frame_buffer_many = nbuffers;
2058
2059         if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers,
2060                                 sizeof(struct v4l2_requestbuffers))) {
2061                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2062                 return -EFAULT;
2063         }
2064         break;
2065 }
2066 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2067 case VIDIOC_QUERYBUF: {
2068         __u32 index;
2069         struct v4l2_buffer v4l2_buffer;
2070
2071         JOM(8, "VIDIOC_QUERYBUF\n");
2072
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);
2077                 return -EIO;
2078         }
2079
2080         if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2081                                         sizeof(struct v4l2_buffer))) {
2082                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2083                 return -EFAULT;
2084         }
2085
2086         if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2087                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2088                 return -EINVAL;
2089         }
2090         index = v4l2_buffer.index;
2091         if (index < 0 || index >= peasycap->frame_buffer_many)
2092                 return -EINVAL;
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;
2104
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);
2116
2117         if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2118                                         sizeof(struct v4l2_buffer))) {
2119                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2120                 return -EFAULT;
2121         }
2122         break;
2123 }
2124 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2125 case VIDIOC_QBUF: {
2126         struct v4l2_buffer v4l2_buffer;
2127
2128         JOM(8, "VIDIOC_QBUF\n");
2129
2130         if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2131                                         sizeof(struct v4l2_buffer))) {
2132                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2133                 return -EFAULT;
2134         }
2135
2136         if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2137                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2138                 return -EINVAL;
2139         }
2140         if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
2141                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2142                 return -EINVAL;
2143         }
2144         if (v4l2_buffer.index < 0 ||
2145                  (v4l2_buffer.index >= peasycap->frame_buffer_many)) {
2146                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2147                 return -EINVAL;
2148         }
2149         v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
2150
2151         peasycap->done[v4l2_buffer.index]   = 0;
2152         peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
2153
2154         if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2155                                         sizeof(struct v4l2_buffer))) {
2156                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2157                 return -EFAULT;
2158         }
2159
2160         JOM(8, ".....   user queueing frame buffer %i\n",
2161                                                 (int)v4l2_buffer.index);
2162
2163         peasycap->frame_lock = 0;
2164
2165         break;
2166 }
2167 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2168 case VIDIOC_DQBUF:
2169         {
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;
2178         int i, j;
2179         struct v4l2_buffer v4l2_buffer;
2180         int rcdq;
2181         __u16 input;
2182
2183         JOM(8, "VIDIOC_DQBUF\n");
2184
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);
2190                 return -EIO;
2191         }
2192
2193         if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2194                                         sizeof(struct v4l2_buffer))) {
2195                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2196                 return -EFAULT;
2197         }
2198
2199         if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2200                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2201                 return -EINVAL;
2202         }
2203
2204         if (true == peasycap->offerfields) {
2205                 /*-----------------------------------------------------------*/
2206                 /*
2207                  *  IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
2208                  *  V4L2_FIELD_BOTTOM
2209                 */
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");
2217                 else
2218                         JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n",
2219                                                         v4l2_buffer.field);
2220         }
2221
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);
2225                 return -EIO;
2226         }
2227 /*---------------------------------------------------------------------------*/
2228 /*
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
2232  */
2233 /*---------------------------------------------------------------------------*/
2234
2235         if (!peasycap->polled) {
2236                 do {
2237                         rcdq = easycap_dqbuf(peasycap, 0);
2238                         if (-EIO == rcdq) {
2239                                 JOM(8, "returning -EIO because "
2240                                                 "dqbuf() returned -EIO\n");
2241                                 mutex_unlock(&easycapdc60_dongle[kd].
2242                                                                 mutex_video);
2243                                 return -EIO;
2244                         }
2245                 } while (0 != rcdq);
2246         } else {
2247                 if (peasycap->video_eof) {
2248                         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2249                         return -EIO;
2250                 }
2251         }
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]);
2255         }
2256         peasycap->polled = 0;
2257
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);
2262                 j = 0;
2263                 for (i = 0; i < 180; i++)
2264                         j += peasycap->merit[i];
2265                 if (90 < j) {
2266                         SAM("easycap driver shutting down "
2267                                                         "on condition blue\n");
2268                         peasycap->video_eof = 1; peasycap->audio_eof = 1;
2269                 }
2270         }
2271
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;
2278         else
2279                 v4l2_buffer.field = V4L2_FIELD_NONE;
2280         do_gettimeofday(&timeval);
2281         timeval2 = timeval;
2282
2283 #if defined(AUDIOTIME)
2284         if (!peasycap->timeval0.tv_sec) {
2285                 timeval8 = timeval;
2286                 timeval1 = timeval;
2287                 timeval2 = timeval;
2288                 dnbydt = 192000;
2289                 peasycap->timeval0 = timeval8;
2290         } else {
2291                 dnbydt = peasycap->dnbydt;
2292                 timeval1 = peasycap->timeval1;
2293                 above = dnbydt * MICROSECONDS(timeval, timeval1);
2294                 below = 192000;
2295                 sdr = signed_div(above, below);
2296
2297                 above = sdr.quotient + timeval1.tv_usec - 350000;
2298
2299                 below = 1000000;
2300                 sdr = signed_div(above, below);
2301                 timeval2.tv_usec = sdr.remainder;
2302                 timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
2303         }
2304         if (!(peasycap->isequence % 500)) {
2305                 fudge = ((long long int)(1000000)) *
2306                                 ((long long int)(timeval.tv_sec -
2307                                                 timeval2.tv_sec)) +
2308                                 (long long int)(timeval.tv_usec -
2309                                                 timeval2.tv_usec);
2310                 sdr = signed_div(fudge, 1000);
2311                 sll = sdr.quotient;
2312                 ull = sdr.remainder;
2313
2314                 SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
2315         }
2316 #endif /*AUDIOTIME*/
2317
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;
2323
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);
2337
2338         if (0 != copy_to_user((void __user *)arg, &v4l2_buffer,
2339                                                 sizeof(struct v4l2_buffer))) {
2340                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2341                 return -EFAULT;
2342         }
2343
2344         input = peasycap->frame_buffer[peasycap->frame_read][0].input;
2345         if (0x08 & input) {
2346                 JOM(8, "user is offered frame buffer %i, input %i\n",
2347                                         peasycap->frame_read, (0x07 & input));
2348         } else {
2349                 JOM(8, "user is offered frame buffer %i\n",
2350                                                         peasycap->frame_read);
2351         }
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");
2358                 }
2359         }
2360         break;
2361 }
2362 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2363 case VIDIOC_STREAMON: {
2364         int i;
2365
2366         JOM(8, "VIDIOC_STREAMON\n");
2367
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);
2374                 return -EFAULT;
2375         }
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;
2381         break;
2382 }
2383 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2384 case VIDIOC_STREAMOFF: {
2385         JOM(8, "VIDIOC_STREAMOFF\n");
2386
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);
2390                 return -EFAULT;
2391         }
2392
2393         peasycap->video_idle = 1;
2394         peasycap->audio_idle = 1;  peasycap->timeval0.tv_sec = 0;
2395 /*---------------------------------------------------------------------------*/
2396 /*
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.
2399  */
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);
2406 #else
2407         wake_up_interruptible(&(peasycap->wq_audio));
2408 #endif /*EASYCAP_NEEDS_ALSA*/
2409 /*---------------------------------------------------------------------------*/
2410         break;
2411 }
2412 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2413 case VIDIOC_G_PARM: {
2414         struct v4l2_streamparm *pv4l2_streamparm;
2415
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);
2421                 return -ENOMEM;
2422         }
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);
2427                 return -EFAULT;
2428         }
2429
2430         if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2431                 kfree(pv4l2_streamparm);
2432                 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2433                 return -EINVAL;
2434         }
2435         pv4l2_streamparm->parm.capture.capability = 0;
2436         pv4l2_streamparm->parm.capture.capturemode = 0;
2437         pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
2438
2439         if (peasycap->fps) {
2440                 pv4l2_streamparm->parm.capture.timeperframe.
2441                                                 denominator = peasycap->fps;
2442         } else {
2443                 if (true == peasycap->ntsc) {
2444                         pv4l2_streamparm->parm.capture.timeperframe.
2445                                                 denominator = 30;
2446                 } else {
2447                         pv4l2_streamparm->parm.capture.timeperframe.
2448                                                 denominator = 25;
2449                 }
2450         }
2451
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);
2459                 return -EFAULT;
2460         }
2461         kfree(pv4l2_streamparm);
2462         break;
2463 }
2464 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2465 case VIDIOC_S_PARM: {
2466         JOM(8, "VIDIOC_S_PARM unsupported\n");
2467         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2468         return -EINVAL;
2469 }
2470 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2471 case VIDIOC_G_AUDIO: {
2472         JOM(8, "VIDIOC_G_AUDIO unsupported\n");
2473         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2474         return -EINVAL;
2475 }
2476 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2477 case VIDIOC_S_AUDIO: {
2478         JOM(8, "VIDIOC_S_AUDIO unsupported\n");
2479         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2480         return -EINVAL;
2481 }
2482 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2483 case VIDIOC_S_TUNER: {
2484         JOM(8, "VIDIOC_S_TUNER unsupported\n");
2485         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2486         return -EINVAL;
2487 }
2488 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2489 case VIDIOC_G_FBUF:
2490 case VIDIOC_S_FBUF:
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);
2494         return -EINVAL;
2495 }
2496 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2497 case VIDIOC_G_TUNER: {
2498         JOM(8, "VIDIOC_G_TUNER unsupported\n");
2499         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2500         return -EINVAL;
2501 }
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);
2506         return -EINVAL;
2507 }
2508 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2509 default: {
2510         JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
2511         mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2512         return -ENOIOCTLCMD;
2513 }
2514 }
2515 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2516 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
2517 return 0;
2518 }
2519 /*****************************************************************************/
2520 #if !defined(EASYCAP_NEEDS_ALSA)
2521 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2522 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
2523         (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
2524 long
2525 easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
2526         return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg);
2527 }
2528 #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
2529 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
2530 /*---------------------------------------------------------------------------*/
2531 int
2532 easyoss_ioctl(struct inode *inode, struct file *file,
2533                                         unsigned int cmd, unsigned long arg)
2534 {
2535 struct easycap *peasycap;
2536 struct usb_device *p;
2537 int kd;
2538
2539 if (NULL == file) {
2540         SAY("ERROR:  file is NULL\n");
2541         return -ERESTARTSYS;
2542 }
2543 peasycap = file->private_data;
2544 if (NULL == peasycap) {
2545         SAY("ERROR:  peasycap is NULL.\n");
2546         return -EFAULT;
2547 }
2548 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2549         SAY("ERROR: bad peasycap\n");
2550         return -EFAULT;
2551 }
2552 p = peasycap->pusb_device;
2553 if (NULL == p) {
2554         SAM("ERROR: peasycap->pusb_device is NULL\n");
2555         return -EFAULT;
2556 }
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;
2563         }
2564         JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
2565 /*---------------------------------------------------------------------------*/
2566 /*
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.
2570 */
2571 /*---------------------------------------------------------------------------*/
2572         if (kd != isdongle(peasycap))
2573                 return -ERESTARTSYS;
2574         if (NULL == file) {
2575                 SAY("ERROR:  file is NULL\n");
2576                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2577                 return -ERESTARTSYS;
2578         }
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;
2584         }
2585         if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2586                 SAY("ERROR: bad peasycap\n");
2587                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2588                 return -EFAULT;
2589         }
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;
2595         }
2596 } else {
2597 /*---------------------------------------------------------------------------*/
2598 /*
2599  *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
2600  *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
2601 */
2602 /*---------------------------------------------------------------------------*/
2603         return -ERESTARTSYS;
2604 }
2605 /*---------------------------------------------------------------------------*/
2606 switch (cmd) {
2607 case SNDCTL_DSP_GETCAPS: {
2608         int caps;
2609         JOM(8, "SNDCTL_DSP_GETCAPS\n");
2610
2611 #if defined(UPSAMPLE)
2612         if (true == peasycap->microphone)
2613                 caps = 0x04400000;
2614         else
2615                 caps = 0x04400000;
2616 #else
2617         if (true == peasycap->microphone)
2618                 caps = 0x02400000;
2619         else
2620                 caps = 0x04400000;
2621 #endif /*UPSAMPLE*/
2622
2623         if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
2624                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2625                 return -EFAULT;
2626         }
2627         break;
2628 }
2629 case SNDCTL_DSP_GETFMTS: {
2630         int incoming;
2631         JOM(8, "SNDCTL_DSP_GETFMTS\n");
2632
2633 #if defined(UPSAMPLE)
2634         if (true == peasycap->microphone)
2635                 incoming = AFMT_S16_LE;
2636         else
2637                 incoming = AFMT_S16_LE;
2638 #else
2639         if (true == peasycap->microphone)
2640                 incoming = AFMT_S16_LE;
2641         else
2642                 incoming = AFMT_S16_LE;
2643 #endif /*UPSAMPLE*/
2644
2645         if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2646                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2647                 return -EFAULT;
2648         }
2649         break;
2650 }
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);
2656                 return -EFAULT;
2657         }
2658         JOM(8, "........... %i=incoming\n", incoming);
2659
2660 #if defined(UPSAMPLE)
2661         if (true == peasycap->microphone)
2662                 outgoing = AFMT_S16_LE;
2663         else
2664                 outgoing = AFMT_S16_LE;
2665 #else
2666         if (true == peasycap->microphone)
2667                 outgoing = AFMT_S16_LE;
2668         else
2669                 outgoing = AFMT_S16_LE;
2670 #endif /*UPSAMPLE*/
2671
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,
2677                                                                 sizeof(int))) {
2678                         mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2679                         return -EFAULT;
2680                 }
2681                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2682                 return -EINVAL ;
2683         }
2684         break;
2685 }
2686 case SNDCTL_DSP_STEREO: {
2687         int incoming;
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);
2691                 return -EFAULT;
2692         }
2693         JOM(8, "........... %i=incoming\n", incoming);
2694
2695 #if defined(UPSAMPLE)
2696         if (true == peasycap->microphone)
2697                 incoming = 1;
2698         else
2699                 incoming = 1;
2700 #else
2701         if (true == peasycap->microphone)
2702                 incoming = 0;
2703         else
2704                 incoming = 1;
2705 #endif /*UPSAMPLE*/
2706
2707         if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2708                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2709                 return -EFAULT;
2710         }
2711         break;
2712 }
2713 case SNDCTL_DSP_SPEED: {
2714         int incoming;
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);
2718                 return -EFAULT;
2719         }
2720         JOM(8, "........... %i=incoming\n", incoming);
2721
2722 #if defined(UPSAMPLE)
2723         if (true == peasycap->microphone)
2724                 incoming = 32000;
2725         else
2726                 incoming = 48000;
2727 #else
2728         if (true == peasycap->microphone)
2729                 incoming = 8000;
2730         else
2731                 incoming = 48000;
2732 #endif /*UPSAMPLE*/
2733
2734         if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2735                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2736                 return -EFAULT;
2737         }
2738         break;
2739 }
2740 case SNDCTL_DSP_GETTRIGGER: {
2741         int incoming;
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);
2745                 return -EFAULT;
2746         }
2747         JOM(8, "........... %i=incoming\n", incoming);
2748
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);
2752                 return -EFAULT;
2753         }
2754         break;
2755 }
2756 case SNDCTL_DSP_SETTRIGGER: {
2757         int incoming;
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);
2761                 return -EFAULT;
2762         }
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);
2767         ;
2768         ;
2769         ;
2770         ;
2771         break;
2772 }
2773 case SNDCTL_DSP_GETBLKSIZE: {
2774         int incoming;
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);
2778                 return -EFAULT;
2779         }
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);
2784                 return -EFAULT;
2785         }
2786         break;
2787 }
2788 case SNDCTL_DSP_GETISPACE: {
2789         struct audio_buf_info audio_buf_info;
2790
2791         JOM(8, "SNDCTL_DSP_GETISPACE\n");
2792
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;
2797
2798         if (0 != copy_to_user((void __user *)arg, &audio_buf_info,
2799                                                                 sizeof(int))) {
2800                 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2801                 return -EFAULT;
2802         }
2803         break;
2804 }
2805 case 0x00005401:
2806 case 0x00005402:
2807 case 0x00005403:
2808 case 0x00005404:
2809 case 0x00005405:
2810 case 0x00005406: {
2811         JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
2812         mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2813         return -ENOIOCTLCMD;
2814 }
2815 default: {
2816         JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2817         mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2818         return -ENOIOCTLCMD;
2819 }
2820 }
2821 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
2822 return 0;
2823 }
2824 #endif /*EASYCAP_NEEDS_ALSA*/
2825 /*****************************************************************************/
2826