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