GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / easycap / easycap_ioctl.c
blob342f7724845924884109761e6028395a4898600e
1 /******************************************************************************
2 * *
3 * easycap_ioctl.c *
4 * *
5 ******************************************************************************/
6 /*
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * The software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /*****************************************************************************/
28 #include <linux/smp_lock.h>
29 #include "easycap.h"
30 #include "easycap_debug.h"
31 #include "easycap_standard.h"
32 #include "easycap_ioctl.h"
34 /*--------------------------------------------------------------------------*/
36 * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
37 * FOLLOWING:
38 * peasycap->standard_offset
39 * peasycap->fps
40 * peasycap->usec
41 * peasycap->tolerate
43 /*---------------------------------------------------------------------------*/
44 int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
46 struct easycap_standard const *peasycap_standard;
47 __u16 reg, set;
48 int ir, rc, need;
49 unsigned int itwas, isnow;
51 if ((struct usb_device *)NULL == peasycap->pusb_device) {
52 SAY("ERROR: peasycap->pusb_device is NULL\n");
53 return -EFAULT;
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++;
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;
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;
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;
80 JOT(8, "%i frames-per-second\n", peasycap->fps);
81 peasycap->usec = 1000000 / (2 * peasycap->fps);
82 peasycap->tolerate = 1000 * (25 / peasycap->fps);
84 kill_video_urbs(peasycap);
86 /*--------------------------------------------------------------------------*/
88 * SAA7113H DATASHEET PAGE 44, TABLE 42
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;
102 set2to78(peasycap->pusb_device);
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);
118 set2to78(peasycap->pusb_device);
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;
129 set2to78(peasycap->pusb_device);
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);
144 set2to78(peasycap->pusb_device);
147 /*--------------------------------------------------------------------------*/
149 * NOTE: NO break HERE: RUN ON TO NEXT CASE
151 /*--------------------------------------------------------------------------*/
153 case NTSC_M:
154 case PAL_BGHIN: {
155 reg = 0x0E; set = 0x01; need = 1; break;
157 case NTSC_N_443:
158 case PAL_60: {
159 reg = 0x0E; set = 0x11; need = 1; break;
161 case NTSC_443:
162 case PAL_Nc: {
163 reg = 0x0E; set = 0x21; need = 1; break;
165 case NTSC_N:
166 case PAL_M: {
167 reg = 0x0E; set = 0x31; need = 1; break;
169 case SECAM: {
170 reg = 0x0E; set = 0x51; need = 1; break;
172 default:
173 break;
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;
183 set2to78(peasycap->pusb_device);
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);
199 /*--------------------------------------------------------------------------*/
201 * SAA7113H DATASHEET PAGE 41
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 ;
216 set2to78(peasycap->pusb_device);
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);
230 /*--------------------------------------------------------------------------*/
232 * SAA7113H DATASHEET PAGE 51, TABLE 57
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 ;
247 set2to78(peasycap->pusb_device);
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);
261 /*--------------------------------------------------------------------------*/
263 * SAA7113H DATASHEET PAGE 53, TABLE 66
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 ;
276 set2to78(peasycap->pusb_device);
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);
290 if (0 != check_saa(peasycap->pusb_device))
291 SAY("ERROR: check_saa() failed\n");
292 return 0;
294 /*****************************************************************************/
295 /*--------------------------------------------------------------------------*/
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
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.
317 /*--------------------------------------------------------------------------*/
318 int adjust_format(struct easycap *peasycap, \
319 __u32 width, __u32 height, __u32 pixelformat, int field, bool try)
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;
328 if ((struct easycap *)NULL == peasycap) {
329 SAY("ERROR: peasycap is NULL\n");
330 return -EFAULT;
332 p = peasycap->pusb_device;
333 if ((struct usb_device *)NULL == p) {
334 SAY("ERROR: peaycap->pusb_device is NULL\n");
335 return -EFAULT;
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");
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);
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;
365 peasycap_format++;
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;
386 peasycap_format++;
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;
397 if ((struct easycap_format *)NULL == peasycap_best_format) {
398 SAY("MISTAKE: peasycap_best_format is NULL");
399 return -EINVAL;
401 peasycap_format = peasycap_best_format;
403 /*...........................................................................*/
404 if (true == try)
405 return (int)(peasycap_best_format - &easycap_format[0]);
406 /*...........................................................................*/
408 if (false != try) {
409 SAY("MISTAKE: true==try where is should be false\n");
410 return -EINVAL;
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;
443 if (true == peasycap->offerfields) {
444 SAY("WARNING: %i=peasycap->field is untested: " \
445 "please report problems\n", peasycap->field);
453 kill_video_urbs(peasycap);
455 /*---------------------------------------------------------------------------*/
457 * PAL
459 /*---------------------------------------------------------------------------*/
460 if (0 == (0x01 & peasycap_format->mask)) {
461 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
462 (576 == \
463 peasycap_format->v4l2_format.fmt.pix.height)) || \
464 ((360 == \
465 peasycap_format->v4l2_format.fmt.pix.width) && \
466 (288 == \
467 peasycap_format->v4l2_format.fmt.pix.height))) {
468 if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
469 SAY("ERROR: set_resolution() failed\n");
470 return -EINVAL;
472 } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \
473 (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
474 if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
475 SAY("ERROR: set_resolution() failed\n");
476 return -EINVAL;
478 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
479 (480 == \
480 peasycap_format->v4l2_format.fmt.pix.height)) || \
481 ((320 == \
482 peasycap_format->v4l2_format.fmt.pix.width) && \
483 (240 == \
484 peasycap_format->v4l2_format.fmt.pix.height))) {
485 if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
486 SAY("ERROR: set_resolution() failed\n");
487 return -EINVAL;
489 } else {
490 SAY("MISTAKE: bad format, cannot set resolution\n");
491 return -EINVAL;
493 /*---------------------------------------------------------------------------*/
495 * NTSC
497 /*---------------------------------------------------------------------------*/
498 } else {
499 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
500 (480 == \
501 peasycap_format->v4l2_format.fmt.pix.height)) || \
502 ((360 == \
503 peasycap_format->v4l2_format.fmt.pix.width) && \
504 (240 == \
505 peasycap_format->v4l2_format.fmt.pix.height))) {
506 if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
507 SAY("ERROR: set_resolution() failed\n");
508 return -EINVAL;
510 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
511 (480 == \
512 peasycap_format->v4l2_format.fmt.pix.height)) || \
513 ((320 == \
514 peasycap_format->v4l2_format.fmt.pix.width) && \
515 (240 == \
516 peasycap_format->v4l2_format.fmt.pix.height))) {
517 if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
518 SAY("ERROR: set_resolution() failed\n");
519 return -EINVAL;
521 } else {
522 SAY("MISTAKE: bad format, cannot set resolution\n");
523 return -EINVAL;
526 /*---------------------------------------------------------------------------*/
528 check_stk(peasycap->pusb_device);
530 return (int)(peasycap_best_format - &easycap_format[0]);
532 /*****************************************************************************/
533 int adjust_brightness(struct easycap *peasycap, int value)
535 unsigned int mood;
536 int i1;
538 if ((struct usb_device *)NULL == peasycap->pusb_device) {
539 SAY("ERROR: peasycap->pusb_device is NULL\n");
540 return -EFAULT;
542 i1 = 0;
543 while (0xFFFFFFFF != easycap_control[i1].id) {
544 if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
545 if ((easycap_control[i1].minimum > value) || \
546 (easycap_control[i1].maximum < value))
547 value = easycap_control[i1].default_value;
548 peasycap->brightness = value;
549 mood = 0x00FF & (unsigned int)peasycap->brightness;
551 set2to78(peasycap->pusb_device);
553 if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
554 SAY("adjusting brightness to 0x%02X\n", mood);
555 return 0;
556 } else {
557 SAY("WARNING: failed to adjust brightness " \
558 "to 0x%02X\n", mood);
559 return -ENOENT;
562 set2to78(peasycap->pusb_device);
564 break;
566 i1++;
568 SAY("WARNING: failed to adjust brightness: control not found\n");
569 return -ENOENT;
571 /*****************************************************************************/
572 int adjust_contrast(struct easycap *peasycap, int value)
574 unsigned int mood;
575 int i1;
577 if ((struct usb_device *)NULL == peasycap->pusb_device) {
578 SAY("ERROR: peasycap->pusb_device is NULL\n");
579 return -EFAULT;
581 i1 = 0;
582 while (0xFFFFFFFF != easycap_control[i1].id) {
583 if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
584 if ((easycap_control[i1].minimum > value) || \
585 (easycap_control[i1].maximum < value))
586 value = easycap_control[i1].default_value;
587 peasycap->contrast = value;
588 mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
590 set2to78(peasycap->pusb_device);
592 if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
593 SAY("adjusting contrast to 0x%02X\n", mood);
594 return 0;
595 } else {
596 SAY("WARNING: failed to adjust contrast to " \
597 "0x%02X\n", mood);
598 return -ENOENT;
601 set2to78(peasycap->pusb_device);
603 break;
605 i1++;
607 SAY("WARNING: failed to adjust contrast: control not found\n");
608 return -ENOENT;
610 /*****************************************************************************/
611 int adjust_saturation(struct easycap *peasycap, int value)
613 unsigned int mood;
614 int i1;
616 if ((struct usb_device *)NULL == peasycap->pusb_device) {
617 SAY("ERROR: peasycap->pusb_device is NULL\n");
618 return -EFAULT;
620 i1 = 0;
621 while (0xFFFFFFFF != easycap_control[i1].id) {
622 if (V4L2_CID_SATURATION == easycap_control[i1].id) {
623 if ((easycap_control[i1].minimum > value) || \
624 (easycap_control[i1].maximum < value))
625 value = easycap_control[i1].default_value;
626 peasycap->saturation = value;
627 mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
629 set2to78(peasycap->pusb_device);
631 if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
632 SAY("adjusting saturation to 0x%02X\n", mood);
633 return 0;
634 } else {
635 SAY("WARNING: failed to adjust saturation to " \
636 "0x%02X\n", mood);
637 return -ENOENT;
639 break;
641 set2to78(peasycap->pusb_device);
644 i1++;
646 SAY("WARNING: failed to adjust saturation: control not found\n");
647 return -ENOENT;
649 /*****************************************************************************/
650 int adjust_hue(struct easycap *peasycap, int value)
652 unsigned int mood;
653 int i1, i2;
655 if ((struct usb_device *)NULL == peasycap->pusb_device) {
656 SAY("ERROR: peasycap->pusb_device is NULL\n");
657 return -EFAULT;
659 i1 = 0;
660 while (0xFFFFFFFF != easycap_control[i1].id) {
661 if (V4L2_CID_HUE == easycap_control[i1].id) {
662 if ((easycap_control[i1].minimum > value) || \
663 (easycap_control[i1].maximum < value))
664 value = easycap_control[i1].default_value;
665 peasycap->hue = value;
666 i2 = peasycap->hue - 128;
667 mood = 0x00FF & ((int) i2);
669 set2to78(peasycap->pusb_device);
671 if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
672 SAY("adjusting hue to 0x%02X\n", mood);
673 return 0;
674 } else {
675 SAY("WARNING: failed to adjust hue to 0x%02X\n", mood);
676 return -ENOENT;
679 set2to78(peasycap->pusb_device);
681 break;
683 i1++;
685 SAY("WARNING: failed to adjust hue: control not found\n");
686 return -ENOENT;
688 /*****************************************************************************/
689 int adjust_volume(struct easycap *peasycap, int value)
691 __s8 mood;
692 int i1;
694 if ((struct usb_device *)NULL == peasycap->pusb_device) {
695 SAY("ERROR: peasycap->pusb_device is NULL\n");
696 return -EFAULT;
698 i1 = 0;
699 while (0xFFFFFFFF != easycap_control[i1].id) {
700 if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
701 if ((easycap_control[i1].minimum > value) || \
702 (easycap_control[i1].maximum < value))
703 value = easycap_control[i1].default_value;
704 peasycap->volume = value;
705 mood = (16 > peasycap->volume) ? 16 : \
706 ((31 < peasycap->volume) ? 31 : \
707 (__s8) peasycap->volume);
708 if (!audio_gainset(peasycap->pusb_device, mood)) {
709 SAY("adjusting volume to 0x%01X\n", mood);
710 return 0;
711 } else {
712 SAY("WARNING: failed to adjust volume to " \
713 "0x%1X\n", mood);
714 return -ENOENT;
716 break;
718 i1++;
720 SAY("WARNING: failed to adjust volume: control not found\n");
721 return -ENOENT;
723 /*****************************************************************************/
724 /*---------------------------------------------------------------------------*/
726 * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
727 * usb_set_interface(peasycap->pusb_device, \
728 * peasycap->audio_interface, \
729 * peasycap->audio_altsetting_off);
730 * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
731 * -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT
732 * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
734 /*---------------------------------------------------------------------------*/
735 int adjust_mute(struct easycap *peasycap, int value)
737 int i1;
739 if ((struct usb_device *)NULL == peasycap->pusb_device) {
740 SAY("ERROR: peasycap->pusb_device is NULL\n");
741 return -EFAULT;
743 i1 = 0;
744 while (0xFFFFFFFF != easycap_control[i1].id) {
745 if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
746 peasycap->mute = value;
747 switch (peasycap->mute) {
748 case 1: {
749 peasycap->audio_idle = 1;
750 peasycap->timeval0.tv_sec = 0;
751 SAY("adjusting mute: %i=peasycap->audio_idle\n", \
752 peasycap->audio_idle);
753 return 0;
755 default: {
756 peasycap->audio_idle = 0;
757 SAY("adjusting mute: %i=peasycap->audio_idle\n", \
758 peasycap->audio_idle);
759 return 0;
762 break;
764 i1++;
766 SAY("WARNING: failed to adjust mute: control not found\n");
767 return -ENOENT;
770 /*--------------------------------------------------------------------------*/
771 static int easycap_ioctl_bkl(struct inode *inode, struct file *file,
772 unsigned int cmd, unsigned long arg)
774 static struct easycap *peasycap;
775 static struct usb_device *p;
776 static __u32 isequence;
778 peasycap = file->private_data;
779 if (NULL == peasycap) {
780 SAY("ERROR: peasycap is NULL\n");
781 return -1;
783 p = peasycap->pusb_device;
784 if ((struct usb_device *)NULL == p) {
785 SAY("ERROR: peasycap->pusb_device is NULL\n");
786 return -EFAULT;
788 /*---------------------------------------------------------------------------*/
790 * MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO
791 * DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND:
792 * easycap_ioctl.c: warning:
793 * the frame size of ... bytes is larger than 1024 bytes
795 /*---------------------------------------------------------------------------*/
796 switch (cmd) {
797 case VIDIOC_QUERYCAP: {
798 static struct v4l2_capability v4l2_capability;
799 static char version[16], *p1, *p2;
800 static int i, rc, k[3];
801 static long lng;
803 JOT(8, "VIDIOC_QUERYCAP\n");
805 if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
806 SAY("ERROR: bad driver version string\n"); return -EINVAL;
808 strcpy(&version[0], EASYCAP_DRIVER_VERSION);
809 for (i = 0; i < 3; i++)
810 k[i] = 0;
811 p2 = &version[0]; i = 0;
812 while (*p2) {
813 p1 = p2;
814 while (*p2 && ('.' != *p2))
815 p2++;
816 if (*p2)
817 *p2++ = 0;
818 if (3 > i) {
819 rc = (int) strict_strtol(p1, 10, &lng);
820 if (0 != rc) {
821 SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \
822 rc, p1);
823 return -EINVAL;
825 k[i] = (int)lng;
827 i++;
830 memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
831 strlcpy(&v4l2_capability.driver[0], "easycap", \
832 sizeof(v4l2_capability.driver));
834 v4l2_capability.capabilities = \
835 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
836 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE;
838 v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
839 JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
841 strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
842 sizeof(v4l2_capability.card));
844 if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\
845 sizeof(v4l2_capability.bus_info)) < 0) {
846 strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
847 sizeof(v4l2_capability.bus_info));
848 JOT(8, "%s=v4l2_capability.bus_info\n", \
849 &v4l2_capability.bus_info[0]);
851 if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
852 sizeof(struct v4l2_capability))) {
853 POUT;
854 return -EFAULT;
856 break;
858 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
859 case VIDIOC_ENUMINPUT: {
860 static struct v4l2_input v4l2_input;
861 static __u32 index;
863 JOT(8, "VIDIOC_ENUMINPUT\n");
865 if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
866 sizeof(struct v4l2_input))) {
867 POUT;
868 return -EFAULT;
871 index = v4l2_input.index;
872 memset(&v4l2_input, 0, sizeof(struct v4l2_input));
874 switch (index) {
875 case 0: {
876 v4l2_input.index = index;
877 strcpy(&v4l2_input.name[0], "CVBS0");
878 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
879 v4l2_input.audioset = 0x01;
880 v4l2_input.tuner = 0;
881 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
882 V4L2_STD_NTSC ;
883 v4l2_input.status = 0;
884 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
885 break;
887 case 1: {
888 v4l2_input.index = index;
889 strcpy(&v4l2_input.name[0], "CVBS1");
890 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
891 v4l2_input.audioset = 0x01;
892 v4l2_input.tuner = 0;
893 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
894 V4L2_STD_NTSC ;
895 v4l2_input.status = 0;
896 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
897 break;
899 case 2: {
900 v4l2_input.index = index;
901 strcpy(&v4l2_input.name[0], "CVBS2");
902 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
903 v4l2_input.audioset = 0x01;
904 v4l2_input.tuner = 0;
905 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
906 V4L2_STD_NTSC ;
907 v4l2_input.status = 0;
908 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
909 break;
911 case 3: {
912 v4l2_input.index = index;
913 strcpy(&v4l2_input.name[0], "CVBS3");
914 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
915 v4l2_input.audioset = 0x01;
916 v4l2_input.tuner = 0;
917 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
918 V4L2_STD_NTSC ;
919 v4l2_input.status = 0;
920 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
921 break;
923 case 4: {
924 v4l2_input.index = index;
925 strcpy(&v4l2_input.name[0], "CVBS4");
926 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
927 v4l2_input.audioset = 0x01;
928 v4l2_input.tuner = 0;
929 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
930 V4L2_STD_NTSC ;
931 v4l2_input.status = 0;
932 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
933 break;
935 case 5: {
936 v4l2_input.index = index;
937 strcpy(&v4l2_input.name[0], "S-VIDEO");
938 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
939 v4l2_input.audioset = 0x01;
940 v4l2_input.tuner = 0;
941 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
942 V4L2_STD_NTSC ;
943 v4l2_input.status = 0;
944 JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
945 break;
947 default: {
948 JOT(8, "%i=index: exhausts inputs\n", index);
949 return -EINVAL;
953 if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
954 sizeof(struct v4l2_input))) {
955 POUT;
956 return -EFAULT;
958 break;
960 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
961 case VIDIOC_G_INPUT: {
962 static __u32 index;
964 JOT(8, "VIDIOC_G_INPUT\n");
965 index = (__u32)peasycap->input;
966 JOT(8, "user is told: %i\n", index);
967 if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
968 POUT;
969 return -EFAULT;
971 break;
973 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
974 case VIDIOC_S_INPUT:
976 static __u32 index;
978 JOT(8, "VIDIOC_S_INPUT\n");
980 if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
981 POUT;
982 return -EFAULT;
985 JOT(8, "user requests input %i\n", index);
987 if ((int)index == peasycap->input) {
988 SAY("requested input already in effect\n");
989 break;
992 if ((0 > index) || (5 < index)) {
993 JOT(8, "ERROR: bad requested input: %i\n", index);
994 return -EINVAL;
996 peasycap->input = (int)index;
998 select_input(peasycap->pusb_device, peasycap->input, 9);
1000 break;
1002 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1003 case VIDIOC_ENUMAUDIO: {
1004 JOT(8, "VIDIOC_ENUMAUDIO\n");
1005 return -EINVAL;
1007 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1008 case VIDIOC_ENUMAUDOUT: {
1009 static struct v4l2_audioout v4l2_audioout;
1011 JOT(8, "VIDIOC_ENUMAUDOUT\n");
1013 if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
1014 sizeof(struct v4l2_audioout))) {
1015 POUT;
1016 return -EFAULT;
1019 if (0 != v4l2_audioout.index)
1020 return -EINVAL;
1021 memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1022 v4l2_audioout.index = 0;
1023 strcpy(&v4l2_audioout.name[0], "Soundtrack");
1025 if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
1026 sizeof(struct v4l2_audioout))) {
1027 POUT;
1028 return -EFAULT;
1030 break;
1032 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1033 case VIDIOC_QUERYCTRL: {
1034 static int i1;
1035 static struct v4l2_queryctrl v4l2_queryctrl;
1037 JOT(8, "VIDIOC_QUERYCTRL\n");
1039 if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
1040 sizeof(struct v4l2_queryctrl))) {
1041 POUT;
1042 return -EFAULT;
1045 i1 = 0;
1046 while (0xFFFFFFFF != easycap_control[i1].id) {
1047 if (easycap_control[i1].id == v4l2_queryctrl.id) {
1048 JOT(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \
1049 ".name\n", &easycap_control[i1].name[0], i1);
1050 memcpy(&v4l2_queryctrl, &easycap_control[i1], \
1051 sizeof(struct v4l2_queryctrl));
1052 break;
1054 i1++;
1056 if (0xFFFFFFFF == easycap_control[i1].id) {
1057 JOT(8, "%i=index: exhausts controls\n", i1);
1058 return -EINVAL;
1060 if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
1061 sizeof(struct v4l2_queryctrl))) {
1062 POUT;
1063 return -EFAULT;
1065 break;
1067 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1068 case VIDIOC_QUERYMENU: {
1069 JOT(8, "VIDIOC_QUERYMENU unsupported\n");
1070 return -EINVAL;
1071 break;
1073 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1074 case VIDIOC_G_CTRL: {
1075 static struct v4l2_control v4l2_control;
1077 JOT(8, "VIDIOC_G_CTRL\n");
1079 if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1080 sizeof(struct v4l2_control))) {
1081 POUT;
1082 return -EFAULT;
1085 switch (v4l2_control.id) {
1086 case V4L2_CID_BRIGHTNESS: {
1087 v4l2_control.value = peasycap->brightness;
1088 JOT(8, "user enquires brightness: %i\n", v4l2_control.value);
1089 break;
1091 case V4L2_CID_CONTRAST: {
1092 v4l2_control.value = peasycap->contrast;
1093 JOT(8, "user enquires contrast: %i\n", v4l2_control.value);
1094 break;
1096 case V4L2_CID_SATURATION: {
1097 v4l2_control.value = peasycap->saturation;
1098 JOT(8, "user enquires saturation: %i\n", v4l2_control.value);
1099 break;
1101 case V4L2_CID_HUE: {
1102 v4l2_control.value = peasycap->hue;
1103 JOT(8, "user enquires hue: %i\n", v4l2_control.value);
1104 break;
1106 case V4L2_CID_AUDIO_VOLUME: {
1107 v4l2_control.value = peasycap->volume;
1108 JOT(8, "user enquires volume: %i\n", v4l2_control.value);
1109 break;
1111 case V4L2_CID_AUDIO_MUTE: {
1112 if (1 == peasycap->mute)
1113 v4l2_control.value = true;
1114 else
1115 v4l2_control.value = false;
1116 JOT(8, "user enquires mute: %i\n", v4l2_control.value);
1117 break;
1119 default: {
1120 SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1121 v4l2_control.id);
1122 explain_cid(v4l2_control.id);
1123 return -EINVAL;
1126 if (0 != copy_to_user((void __user *)arg, &v4l2_control, \
1127 sizeof(struct v4l2_control))) {
1128 POUT;
1129 return -EFAULT;
1131 break;
1133 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1134 #if defined(VIDIOC_S_CTRL_OLD)
1135 case VIDIOC_S_CTRL_OLD: {
1136 JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
1138 #endif /*VIDIOC_S_CTRL_OLD*/
1139 case VIDIOC_S_CTRL:
1141 static struct v4l2_control v4l2_control;
1143 JOT(8, "VIDIOC_S_CTRL\n");
1145 if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1146 sizeof(struct v4l2_control))) {
1147 POUT;
1148 return -EFAULT;
1151 switch (v4l2_control.id) {
1152 case V4L2_CID_BRIGHTNESS: {
1153 JOT(8, "user requests brightness %i\n", v4l2_control.value);
1154 if (0 != adjust_brightness(peasycap, v4l2_control.value))
1156 break;
1158 case V4L2_CID_CONTRAST: {
1159 JOT(8, "user requests contrast %i\n", v4l2_control.value);
1160 if (0 != adjust_contrast(peasycap, v4l2_control.value))
1162 break;
1164 case V4L2_CID_SATURATION: {
1165 JOT(8, "user requests saturation %i\n", v4l2_control.value);
1166 if (0 != adjust_saturation(peasycap, v4l2_control.value))
1168 break;
1170 case V4L2_CID_HUE: {
1171 JOT(8, "user requests hue %i\n", v4l2_control.value);
1172 if (0 != adjust_hue(peasycap, v4l2_control.value))
1174 break;
1176 case V4L2_CID_AUDIO_VOLUME: {
1177 JOT(8, "user requests volume %i\n", v4l2_control.value);
1178 if (0 != adjust_volume(peasycap, v4l2_control.value))
1180 break;
1182 case V4L2_CID_AUDIO_MUTE: {
1183 int mute;
1185 JOT(8, "user requests mute %i\n", v4l2_control.value);
1186 if (true == v4l2_control.value)
1187 mute = 1;
1188 else
1189 mute = 0;
1191 if (0 != adjust_mute(peasycap, mute))
1192 SAY("WARNING: failed to adjust mute to %i\n", mute);
1193 break;
1195 default: {
1196 SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1197 v4l2_control.id);
1198 explain_cid(v4l2_control.id);
1199 return -EINVAL;
1202 break;
1204 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1205 case VIDIOC_S_EXT_CTRLS: {
1206 JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1207 return -EINVAL;
1209 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1210 case VIDIOC_ENUM_FMT: {
1211 static __u32 index;
1212 static struct v4l2_fmtdesc v4l2_fmtdesc;
1214 JOT(8, "VIDIOC_ENUM_FMT\n");
1216 if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
1217 sizeof(struct v4l2_fmtdesc))) {
1218 POUT;
1219 return -EFAULT;
1222 index = v4l2_fmtdesc.index;
1223 memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1225 v4l2_fmtdesc.index = index;
1226 v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1228 switch (index) {
1229 case 0: {
1230 v4l2_fmtdesc.flags = 0;
1231 strcpy(&v4l2_fmtdesc.description[0], "uyvy");
1232 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
1233 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1234 break;
1236 case 1: {
1237 v4l2_fmtdesc.flags = 0;
1238 strcpy(&v4l2_fmtdesc.description[0], "yuy2");
1239 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1240 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1241 break;
1243 case 2: {
1244 v4l2_fmtdesc.flags = 0;
1245 strcpy(&v4l2_fmtdesc.description[0], "rgb24");
1246 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
1247 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1248 break;
1250 case 3: {
1251 v4l2_fmtdesc.flags = 0;
1252 strcpy(&v4l2_fmtdesc.description[0], "rgb32");
1253 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
1254 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1255 break;
1257 case 4: {
1258 v4l2_fmtdesc.flags = 0;
1259 strcpy(&v4l2_fmtdesc.description[0], "bgr24");
1260 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
1261 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1262 break;
1264 case 5: {
1265 v4l2_fmtdesc.flags = 0;
1266 strcpy(&v4l2_fmtdesc.description[0], "bgr32");
1267 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
1268 JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1269 break;
1271 default: {
1272 JOT(8, "%i=index: exhausts formats\n", index);
1273 return -EINVAL;
1276 if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
1277 sizeof(struct v4l2_fmtdesc))) {
1278 POUT;
1279 return -EFAULT;
1281 break;
1283 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1284 case VIDIOC_ENUM_FRAMESIZES: {
1285 JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
1286 return -EINVAL;
1288 case VIDIOC_ENUM_FRAMEINTERVALS: {
1289 JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
1290 return -EINVAL;
1292 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1293 case VIDIOC_G_FMT: {
1294 static struct v4l2_format v4l2_format;
1295 static struct v4l2_pix_format v4l2_pix_format;
1297 JOT(8, "VIDIOC_G_FMT\n");
1299 if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1300 sizeof(struct v4l2_format))) {
1301 POUT;
1302 return -EFAULT;
1305 if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1306 POUT;
1307 return -EINVAL;
1310 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1311 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1312 memcpy(&(v4l2_format.fmt.pix), \
1313 &(easycap_format[peasycap->format_offset]\
1314 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
1315 JOT(8, "user is told: %s\n", \
1316 &easycap_format[peasycap->format_offset].name[0]);
1318 if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1319 sizeof(struct v4l2_format))) {
1320 POUT;
1321 return -EFAULT;
1323 break;
1325 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1326 case VIDIOC_TRY_FMT:
1327 case VIDIOC_S_FMT: {
1328 static struct v4l2_format v4l2_format;
1329 static struct v4l2_pix_format v4l2_pix_format;
1330 static bool try;
1331 static int best_format;
1333 if (VIDIOC_TRY_FMT == cmd) {
1334 JOT(8, "VIDIOC_TRY_FMT\n");
1335 try = true;
1336 } else {
1337 JOT(8, "VIDIOC_S_FMT\n");
1338 try = false;
1341 if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1342 sizeof(struct v4l2_format))) {
1343 POUT;
1344 return -EFAULT;
1347 best_format = adjust_format(peasycap, \
1348 v4l2_format.fmt.pix.width, \
1349 v4l2_format.fmt.pix.height, \
1350 v4l2_format.fmt.pix.pixelformat, \
1351 v4l2_format.fmt.pix.field, \
1352 try);
1353 if (0 > best_format) {
1354 JOT(8, "WARNING: adjust_format() returned %i\n", best_format);
1355 return -ENOENT;
1357 /*...........................................................................*/
1358 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1359 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1361 memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
1362 .v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
1363 JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
1365 if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1366 sizeof(struct v4l2_format))) {
1367 POUT;
1368 return -EFAULT;
1370 break;
1372 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1373 case VIDIOC_CROPCAP: {
1374 static struct v4l2_cropcap v4l2_cropcap;
1376 JOT(8, "VIDIOC_CROPCAP\n");
1378 if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
1379 sizeof(struct v4l2_cropcap))) {
1380 POUT;
1381 return -EFAULT;
1384 if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1385 JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1387 memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
1388 v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1389 v4l2_cropcap.bounds.left = 0;
1390 v4l2_cropcap.bounds.top = 0;
1391 v4l2_cropcap.bounds.width = peasycap->width;
1392 v4l2_cropcap.bounds.height = peasycap->height;
1393 v4l2_cropcap.defrect.left = 0;
1394 v4l2_cropcap.defrect.top = 0;
1395 v4l2_cropcap.defrect.width = peasycap->width;
1396 v4l2_cropcap.defrect.height = peasycap->height;
1397 v4l2_cropcap.pixelaspect.numerator = 1;
1398 v4l2_cropcap.pixelaspect.denominator = 1;
1400 JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1402 if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
1403 sizeof(struct v4l2_cropcap))) {
1404 POUT;
1405 return -EFAULT;
1407 break;
1409 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1410 case VIDIOC_G_CROP:
1411 case VIDIOC_S_CROP: {
1412 JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
1413 return -EINVAL;
1415 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1416 case VIDIOC_QUERYSTD: {
1417 JOT(8, "VIDIOC_QUERYSTD: " \
1418 "EasyCAP is incapable of detecting standard\n");
1419 return -EINVAL;
1420 break;
1422 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1423 /*---------------------------------------------------------------------------*/
1424 /*---------------------------------------------------------------------------*/
1425 case VIDIOC_ENUMSTD: {
1426 static int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1427 static struct v4l2_standard v4l2_standard;
1428 static __u32 index;
1429 static struct easycap_standard const *peasycap_standard;
1431 JOT(8, "VIDIOC_ENUMSTD\n");
1433 if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
1434 sizeof(struct v4l2_standard))) {
1435 POUT;
1436 return -EFAULT;
1438 index = v4l2_standard.index;
1440 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1441 if ((index == last3) && (index == last2) && \
1442 (index == last1) && (index == last0)) {
1443 index++;
1444 last3 = last2; last2 = last1; last1 = last0; last0 = index;
1447 memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1449 peasycap_standard = &easycap_standard[0];
1450 while (0xFFFF != peasycap_standard->mask) {
1451 if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1452 break;
1453 peasycap_standard++;
1455 if (0xFFFF == peasycap_standard->mask) {
1456 JOT(8, "%i=index: exhausts standards\n", index);
1457 return -EINVAL;
1459 JOT(8, "%i=index: %s\n", index, \
1460 &(peasycap_standard->v4l2_standard.name[0]));
1461 memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
1462 sizeof(struct v4l2_standard));
1464 v4l2_standard.index = index;
1466 if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
1467 sizeof(struct v4l2_standard))) {
1468 POUT;
1469 return -EFAULT;
1471 break;
1473 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1474 case VIDIOC_G_STD: {
1475 static v4l2_std_id std_id;
1476 static struct easycap_standard const *peasycap_standard;
1478 JOT(8, "VIDIOC_G_STD\n");
1480 if (0 != copy_from_user(&std_id, (void __user *)arg, \
1481 sizeof(v4l2_std_id))) {
1482 POUT;
1483 return -EFAULT;
1486 peasycap_standard = &easycap_standard[peasycap->standard_offset];
1487 std_id = peasycap_standard->v4l2_standard.id;
1489 JOT(8, "user is told: %s\n", \
1490 &peasycap_standard->v4l2_standard.name[0]);
1492 if (0 != copy_to_user((void __user *)arg, &std_id, \
1493 sizeof(v4l2_std_id))) {
1494 POUT;
1495 return -EFAULT;
1497 break;
1499 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1500 case VIDIOC_S_STD: {
1501 static v4l2_std_id std_id;
1502 static int rc;
1504 JOT(8, "VIDIOC_S_STD\n");
1506 if (0 != copy_from_user(&std_id, (void __user *)arg, \
1507 sizeof(v4l2_std_id))) {
1508 POUT;
1509 return -EFAULT;
1512 rc = adjust_standard(peasycap, std_id);
1513 if (0 > rc) {
1514 JOT(8, "WARNING: adjust_standard() returned %i\n", rc);
1515 return -ENOENT;
1517 break;
1519 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1520 case VIDIOC_REQBUFS: {
1521 static int nbuffers;
1522 static struct v4l2_requestbuffers v4l2_requestbuffers;
1524 JOT(8, "VIDIOC_REQBUFS\n");
1526 if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
1527 sizeof(struct v4l2_requestbuffers))) {
1528 POUT;
1529 return -EFAULT;
1532 if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1533 return -EINVAL;
1534 if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
1535 POUT;
1536 return -EINVAL;
1538 nbuffers = v4l2_requestbuffers.count;
1539 JOT(8, " User requests %i buffers ...\n", nbuffers);
1540 if (nbuffers < 2)
1541 nbuffers = 2;
1542 if (nbuffers > FRAME_BUFFER_MANY)
1543 nbuffers = FRAME_BUFFER_MANY;
1544 if (v4l2_requestbuffers.count == nbuffers) {
1545 JOT(8, " ... agree to %i buffers\n", \
1546 nbuffers);
1547 } else {
1548 JOT(8, " ... insist on %i buffers\n", \
1549 nbuffers);
1550 v4l2_requestbuffers.count = nbuffers;
1552 peasycap->frame_buffer_many = nbuffers;
1554 if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
1555 sizeof(struct v4l2_requestbuffers))) {
1556 POUT;
1557 return -EFAULT;
1559 break;
1561 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1562 case VIDIOC_QUERYBUF: {
1563 static __u32 index;
1564 static struct v4l2_buffer v4l2_buffer;
1566 JOT(8, "VIDIOC_QUERYBUF\n");
1568 if (peasycap->video_eof) {
1569 JOT(8, "returning -1 because %i=video_eof\n", \
1570 peasycap->video_eof);
1571 return -1;
1574 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1575 sizeof(struct v4l2_buffer))) {
1576 POUT;
1577 return -EFAULT;
1580 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1581 return -EINVAL;
1582 index = v4l2_buffer.index;
1583 if (index < 0 || index >= peasycap->frame_buffer_many)
1584 return -EINVAL;
1585 memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
1586 v4l2_buffer.index = index;
1587 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1588 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
1589 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
1590 peasycap->done[index] | \
1591 peasycap->queued[index];
1592 v4l2_buffer.field = peasycap->field;
1593 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
1594 v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
1595 v4l2_buffer.length = FRAME_BUFFER_SIZE;
1597 JOT(16, " %10i=index\n", v4l2_buffer.index);
1598 JOT(16, " 0x%08X=type\n", v4l2_buffer.type);
1599 JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
1600 JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags);
1601 JOT(16, " %10i=field\n", v4l2_buffer.field);
1602 JOT(16, " %10li=timestamp.tv_usec\n", \
1603 (long)v4l2_buffer.timestamp.tv_usec);
1604 JOT(16, " %10i=sequence\n", v4l2_buffer.sequence);
1605 JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory);
1606 JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
1607 JOT(16, " %10i=length\n", v4l2_buffer.length);
1609 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1610 sizeof(struct v4l2_buffer))) {
1611 POUT;
1612 return -EFAULT;
1614 break;
1616 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1617 case VIDIOC_QBUF: {
1618 static struct v4l2_buffer v4l2_buffer;
1620 JOT(8, "VIDIOC_QBUF\n");
1622 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1623 sizeof(struct v4l2_buffer))) {
1624 POUT;
1625 return -EFAULT;
1628 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1629 return -EINVAL;
1630 if (v4l2_buffer.memory != V4L2_MEMORY_MMAP)
1631 return -EINVAL;
1632 if (v4l2_buffer.index < 0 || \
1633 (v4l2_buffer.index >= peasycap->frame_buffer_many))
1634 return -EINVAL;
1635 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
1637 peasycap->done[v4l2_buffer.index] = 0;
1638 peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
1640 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1641 sizeof(struct v4l2_buffer))) {
1642 POUT;
1643 return -EFAULT;
1646 JOT(8, "..... user queueing frame buffer %i\n", \
1647 (int)v4l2_buffer.index);
1649 peasycap->frame_lock = 0;
1651 break;
1653 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1654 case VIDIOC_DQBUF:
1656 #if defined(AUDIOTIME)
1657 static struct signed_div_result sdr;
1658 static long long int above, below, dnbydt, fudge, sll;
1659 static unsigned long long int ull;
1660 static struct timeval timeval0;
1661 struct timeval timeval1;
1662 #endif /*AUDIOTIME*/
1663 static struct timeval timeval, timeval2;
1664 static int i, j;
1665 static struct v4l2_buffer v4l2_buffer;
1667 JOT(8, "VIDIOC_DQBUF\n");
1669 if ((peasycap->video_idle) || (peasycap->video_eof)) {
1670 JOT(8, "returning -EIO because " \
1671 "%i=video_idle %i=video_eof\n", \
1672 peasycap->video_idle, peasycap->video_eof);
1673 return -EIO;
1676 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1677 sizeof(struct v4l2_buffer))) {
1678 POUT;
1679 return -EFAULT;
1682 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1683 return -EINVAL;
1685 if (!peasycap->video_isoc_streaming) {
1686 JOT(16, "returning -EIO because video urbs not streaming\n");
1687 return -EIO;
1689 /*---------------------------------------------------------------------------*/
1691 * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
1692 * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS
1693 * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
1695 /*---------------------------------------------------------------------------*/
1697 if (!peasycap->polled) {
1698 if (-EIO == easycap_dqbuf(peasycap, 0))
1699 return -EIO;
1700 } else {
1701 if (peasycap->video_eof)
1702 return -EIO;
1704 if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
1705 SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
1706 peasycap->done[peasycap->frame_read]);
1708 peasycap->polled = 0;
1710 if (!(isequence % 10)) {
1711 for (i = 0; i < 179; i++)
1712 peasycap->merit[i] = peasycap->merit[i+1];
1713 peasycap->merit[179] = merit_saa(peasycap->pusb_device);
1714 j = 0;
1715 for (i = 0; i < 180; i++)
1716 j += peasycap->merit[i];
1717 if (90 < j) {
1718 SAY("easycap driver shutting down " \
1719 "on condition blue\n");
1720 peasycap->video_eof = 1; peasycap->audio_eof = 1;
1724 v4l2_buffer.index = peasycap->frame_read;
1725 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1726 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
1727 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
1728 v4l2_buffer.field = peasycap->field;
1729 if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field)
1730 v4l2_buffer.field = \
1731 0x000F & (peasycap->\
1732 frame_buffer[peasycap->frame_read][0].kount);
1733 do_gettimeofday(&timeval);
1734 timeval2 = timeval;
1736 #if defined(AUDIOTIME)
1737 if (!peasycap->timeval0.tv_sec) {
1738 timeval0 = timeval;
1739 timeval1 = timeval;
1740 timeval2 = timeval;
1741 dnbydt = 192000;
1743 if (mutex_lock_interruptible(&(peasycap->mutex_timeval0)))
1744 return -ERESTARTSYS;
1745 peasycap->timeval0 = timeval0;
1746 mutex_unlock(&(peasycap->mutex_timeval0));
1747 } else {
1748 if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
1749 return -ERESTARTSYS;
1750 dnbydt = peasycap->dnbydt;
1751 timeval1 = peasycap->timeval1;
1752 mutex_unlock(&(peasycap->mutex_timeval1));
1753 above = dnbydt * MICROSECONDS(timeval, timeval1);
1754 below = 192000;
1755 sdr = signed_div(above, below);
1757 above = sdr.quotient + timeval1.tv_usec - 350000;
1759 below = 1000000;
1760 sdr = signed_div(above, below);
1761 timeval2.tv_usec = sdr.remainder;
1762 timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
1764 if (!(isequence % 500)) {
1765 fudge = ((long long int)(1000000)) * \
1766 ((long long int)(timeval.tv_sec - \
1767 timeval2.tv_sec)) + \
1768 (long long int)(timeval.tv_usec - \
1769 timeval2.tv_usec);
1770 sdr = signed_div(fudge, 1000);
1771 sll = sdr.quotient;
1772 ull = sdr.remainder;
1774 SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
1776 #endif /*AUDIOTIME*/
1778 v4l2_buffer.timestamp = timeval2;
1779 v4l2_buffer.sequence = isequence++;
1780 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
1781 v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
1782 v4l2_buffer.length = FRAME_BUFFER_SIZE;
1784 JOT(16, " %10i=index\n", v4l2_buffer.index);
1785 JOT(16, " 0x%08X=type\n", v4l2_buffer.type);
1786 JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
1787 JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags);
1788 JOT(16, " %10i=field\n", v4l2_buffer.field);
1789 JOT(16, " %10li=timestamp.tv_usec\n", \
1790 (long)v4l2_buffer.timestamp.tv_usec);
1791 JOT(16, " %10i=sequence\n", v4l2_buffer.sequence);
1792 JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory);
1793 JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
1794 JOT(16, " %10i=length\n", v4l2_buffer.length);
1796 if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1797 sizeof(struct v4l2_buffer))) {
1798 POUT;
1799 return -EFAULT;
1802 JOT(8, "..... user is offered frame buffer %i\n", \
1803 peasycap->frame_read);
1804 peasycap->frame_lock = 1;
1805 if (peasycap->frame_read == peasycap->frame_fill) {
1806 if (peasycap->frame_lock) {
1807 JOT(8, "ERROR: filling frame buffer " \
1808 "while offered to user\n");
1811 break;
1813 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1814 /*---------------------------------------------------------------------------*/
1816 * AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED;
1817 * VIDEO URBS HAVE NOT.
1819 /*---------------------------------------------------------------------------*/
1820 case VIDIOC_STREAMON: {
1821 static int i;
1823 JOT(8, "VIDIOC_STREAMON\n");
1825 isequence = 0;
1826 for (i = 0; i < 180; i++)
1827 peasycap->merit[i] = 0;
1828 if ((struct usb_device *)NULL == peasycap->pusb_device) {
1829 SAY("ERROR: peasycap->pusb_device is NULL\n");
1830 return -EFAULT;
1832 submit_video_urbs(peasycap);
1833 peasycap->video_idle = 0;
1834 peasycap->audio_idle = 0;
1835 peasycap->video_eof = 0;
1836 peasycap->audio_eof = 0;
1837 break;
1839 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1840 case VIDIOC_STREAMOFF: {
1841 JOT(8, "VIDIOC_STREAMOFF\n");
1843 if ((struct usb_device *)NULL == peasycap->pusb_device) {
1844 SAY("ERROR: peasycap->pusb_device is NULL\n");
1845 return -EFAULT;
1848 peasycap->video_idle = 1;
1849 peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0;
1850 /*---------------------------------------------------------------------------*/
1852 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
1853 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
1855 /*---------------------------------------------------------------------------*/
1856 JOT(8, "calling wake_up on wq_video and wq_audio\n");
1857 wake_up_interruptible(&(peasycap->wq_video));
1858 wake_up_interruptible(&(peasycap->wq_audio));
1859 /*---------------------------------------------------------------------------*/
1860 break;
1862 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1863 case VIDIOC_G_PARM: {
1864 static struct v4l2_streamparm v4l2_streamparm;
1866 JOT(8, "VIDIOC_G_PARM\n");
1868 if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \
1869 sizeof(struct v4l2_streamparm))) {
1870 POUT;
1871 return -EFAULT;
1874 if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1875 POUT;
1876 return -EINVAL;
1878 v4l2_streamparm.parm.capture.capability = 0;
1879 v4l2_streamparm.parm.capture.capturemode = 0;
1880 v4l2_streamparm.parm.capture.timeperframe.numerator = 1;
1881 v4l2_streamparm.parm.capture.timeperframe.denominator = 30;
1882 v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many;
1883 v4l2_streamparm.parm.capture.extendedmode = 0;
1884 if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \
1885 sizeof(struct v4l2_streamparm))) {
1886 POUT;
1887 return -EFAULT;
1889 break;
1891 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1892 case VIDIOC_S_PARM: {
1893 JOT(8, "VIDIOC_S_PARM unsupported\n");
1894 return -EINVAL;
1896 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1897 case VIDIOC_G_AUDIO: {
1898 JOT(8, "VIDIOC_G_AUDIO unsupported\n");
1899 return -EINVAL;
1901 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1902 case VIDIOC_S_AUDIO: {
1903 JOT(8, "VIDIOC_S_AUDIO unsupported\n");
1904 return -EINVAL;
1906 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1907 case VIDIOC_S_TUNER: {
1908 JOT(8, "VIDIOC_S_TUNER unsupported\n");
1909 return -EINVAL;
1911 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1912 case VIDIOC_G_FBUF:
1913 case VIDIOC_S_FBUF:
1914 case VIDIOC_OVERLAY: {
1915 JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
1916 return -EINVAL;
1918 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1919 case VIDIOC_G_TUNER: {
1920 JOT(8, "VIDIOC_G_TUNER unsupported\n");
1921 return -EINVAL;
1923 case VIDIOC_G_FREQUENCY:
1924 case VIDIOC_S_FREQUENCY: {
1925 JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
1926 return -EINVAL;
1928 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1929 default: {
1930 JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
1931 explain_ioctl(cmd);
1932 POUT;
1933 return -ENOIOCTLCMD;
1936 return 0;
1939 long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1941 struct inode *inode = file->f_dentry->d_inode;
1942 long ret;
1944 lock_kernel();
1945 ret = easycap_ioctl_bkl(inode, file, cmd, arg);
1946 unlock_kernel();
1948 return ret;
1951 /*--------------------------------------------------------------------------*/
1952 static int easysnd_ioctl_bkl(struct inode *inode, struct file *file,
1953 unsigned int cmd, unsigned long arg)
1955 struct easycap *peasycap;
1956 struct usb_device *p;
1958 peasycap = file->private_data;
1959 if (NULL == peasycap) {
1960 SAY("ERROR: peasycap is NULL.\n");
1961 return -1;
1963 p = peasycap->pusb_device;
1964 /*---------------------------------------------------------------------------*/
1965 switch (cmd) {
1966 case SNDCTL_DSP_GETCAPS: {
1967 int caps;
1968 JOT(8, "SNDCTL_DSP_GETCAPS\n");
1970 #if defined(UPSAMPLE)
1971 if (true == peasycap->microphone)
1972 caps = 0x04400000;
1973 else
1974 caps = 0x04400000;
1975 #else
1976 if (true == peasycap->microphone)
1977 caps = 0x02400000;
1978 else
1979 caps = 0x04400000;
1980 #endif /*UPSAMPLE*/
1982 if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int)))
1983 return -EFAULT;
1984 break;
1986 case SNDCTL_DSP_GETFMTS: {
1987 int incoming;
1988 JOT(8, "SNDCTL_DSP_GETFMTS\n");
1990 #if defined(UPSAMPLE)
1991 if (true == peasycap->microphone)
1992 incoming = AFMT_S16_LE;
1993 else
1994 incoming = AFMT_S16_LE;
1995 #else
1996 if (true == peasycap->microphone)
1997 incoming = AFMT_S16_LE;
1998 else
1999 incoming = AFMT_S16_LE;
2000 #endif /*UPSAMPLE*/
2002 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2003 return -EFAULT;
2004 break;
2006 case SNDCTL_DSP_SETFMT: {
2007 int incoming, outgoing;
2008 JOT(8, "SNDCTL_DSP_SETFMT\n");
2009 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2010 return -EFAULT;
2011 JOT(8, "........... %i=incoming\n", incoming);
2013 #if defined(UPSAMPLE)
2014 if (true == peasycap->microphone)
2015 outgoing = AFMT_S16_LE;
2016 else
2017 outgoing = AFMT_S16_LE;
2018 #else
2019 if (true == peasycap->microphone)
2020 outgoing = AFMT_S16_LE;
2021 else
2022 outgoing = AFMT_S16_LE;
2023 #endif /*UPSAMPLE*/
2025 if (incoming != outgoing) {
2026 JOT(8, "........... %i=outgoing\n", outgoing);
2027 JOT(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
2028 JOT(8, " cf. %i=AFMT_U8\n", AFMT_U8);
2029 if (0 != copy_to_user((void __user *)arg, &outgoing, \
2030 sizeof(int)))
2031 return -EFAULT;
2032 return -EINVAL ;
2034 break;
2036 case SNDCTL_DSP_STEREO: {
2037 int incoming;
2038 JOT(8, "SNDCTL_DSP_STEREO\n");
2039 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2040 return -EFAULT;
2041 JOT(8, "........... %i=incoming\n", incoming);
2043 #if defined(UPSAMPLE)
2044 if (true == peasycap->microphone)
2045 incoming = 1;
2046 else
2047 incoming = 1;
2048 #else
2049 if (true == peasycap->microphone)
2050 incoming = 0;
2051 else
2052 incoming = 1;
2053 #endif /*UPSAMPLE*/
2055 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2056 return -EFAULT;
2057 break;
2059 case SNDCTL_DSP_SPEED: {
2060 int incoming;
2061 JOT(8, "SNDCTL_DSP_SPEED\n");
2062 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2063 return -EFAULT;
2064 JOT(8, "........... %i=incoming\n", incoming);
2066 #if defined(UPSAMPLE)
2067 if (true == peasycap->microphone)
2068 incoming = 32000;
2069 else
2070 incoming = 48000;
2071 #else
2072 if (true == peasycap->microphone)
2073 incoming = 8000;
2074 else
2075 incoming = 48000;
2076 #endif /*UPSAMPLE*/
2078 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2079 return -EFAULT;
2080 break;
2082 case SNDCTL_DSP_GETTRIGGER: {
2083 int incoming;
2084 JOT(8, "SNDCTL_DSP_GETTRIGGER\n");
2085 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2086 return -EFAULT;
2087 JOT(8, "........... %i=incoming\n", incoming);
2089 incoming = PCM_ENABLE_INPUT;
2090 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2091 return -EFAULT;
2092 break;
2094 case SNDCTL_DSP_SETTRIGGER: {
2095 int incoming;
2096 JOT(8, "SNDCTL_DSP_SETTRIGGER\n");
2097 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2098 return -EFAULT;
2099 JOT(8, "........... %i=incoming\n", incoming);
2100 JOT(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
2101 "0x%x=PCM_ENABLE_OUTPUT\n", \
2102 PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
2107 break;
2109 case SNDCTL_DSP_GETBLKSIZE: {
2110 int incoming;
2111 JOT(8, "SNDCTL_DSP_GETBLKSIZE\n");
2112 if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
2113 return -EFAULT;
2114 JOT(8, "........... %i=incoming\n", incoming);
2115 incoming = peasycap->audio_bytes_per_fragment;
2116 if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2117 return -EFAULT;
2118 break;
2120 case SNDCTL_DSP_GETISPACE: {
2121 struct audio_buf_info audio_buf_info;
2123 JOT(8, "SNDCTL_DSP_GETISPACE\n");
2125 audio_buf_info.bytes = peasycap->audio_bytes_per_fragment;
2126 audio_buf_info.fragments = 1;
2127 audio_buf_info.fragsize = 0;
2128 audio_buf_info.fragstotal = 0;
2130 if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
2131 sizeof(int)))
2132 return -EFAULT;
2133 break;
2135 default: {
2136 JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2137 POUT;
2138 return -ENOIOCTLCMD;
2141 return 0;
2144 long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2146 struct inode *inode = file->f_dentry->d_inode;
2147 long ret;
2149 lock_kernel();
2150 ret = easysnd_ioctl_bkl(inode, file, cmd, arg);
2151 unlock_kernel();
2153 return ret;
2156 /*****************************************************************************/
2157 int explain_ioctl(__u32 wot)
2159 int k;
2160 /*---------------------------------------------------------------------------*/
2162 * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
2163 * SHELL SCRIPT:
2165 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
2166 * grep "^#define VIDIOC_" - | grep -v "_OLD" - | \
2167 * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
2168 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \
2169 * sed -e "s, ,,g;s, ,,g" >ioctl.tmp
2170 * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
2171 * exit 0
2173 * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY.
2175 * THE DATA FOR THE ARRAY mess1 BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
2176 * SHELL SCRIPT:
2177 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev.h | \
2178 * grep "^#define VIDIOC" - | grep -v "_OLD" - | \
2179 * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
2180 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \
2181 * sed -e "s, ,,g;s, ,,g" >ioctl.tmp
2182 * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
2183 * exit 0
2186 /*---------------------------------------------------------------------------*/
2187 static struct mess {
2188 __u32 command;
2189 char name[64];
2190 } mess[] = {
2191 #if defined(VIDIOC_QUERYCAP)
2192 {VIDIOC_QUERYCAP, "VIDIOC_QUERYCAP"},
2193 #endif
2194 #if defined(VIDIOC_RESERVED)
2195 {VIDIOC_RESERVED, "VIDIOC_RESERVED"},
2196 #endif
2197 #if defined(VIDIOC_ENUM_FMT)
2198 {VIDIOC_ENUM_FMT, "VIDIOC_ENUM_FMT"},
2199 #endif
2200 #if defined(VIDIOC_G_FMT)
2201 {VIDIOC_G_FMT, "VIDIOC_G_FMT"},
2202 #endif
2203 #if defined(VIDIOC_S_FMT)
2204 {VIDIOC_S_FMT, "VIDIOC_S_FMT"},
2205 #endif
2206 #if defined(VIDIOC_REQBUFS)
2207 {VIDIOC_REQBUFS, "VIDIOC_REQBUFS"},
2208 #endif
2209 #if defined(VIDIOC_QUERYBUF)
2210 {VIDIOC_QUERYBUF, "VIDIOC_QUERYBUF"},
2211 #endif
2212 #if defined(VIDIOC_G_FBUF)
2213 {VIDIOC_G_FBUF, "VIDIOC_G_FBUF"},
2214 #endif
2215 #if defined(VIDIOC_S_FBUF)
2216 {VIDIOC_S_FBUF, "VIDIOC_S_FBUF"},
2217 #endif
2218 #if defined(VIDIOC_OVERLAY)
2219 {VIDIOC_OVERLAY, "VIDIOC_OVERLAY"},
2220 #endif
2221 #if defined(VIDIOC_QBUF)
2222 {VIDIOC_QBUF, "VIDIOC_QBUF"},
2223 #endif
2224 #if defined(VIDIOC_DQBUF)
2225 {VIDIOC_DQBUF, "VIDIOC_DQBUF"},
2226 #endif
2227 #if defined(VIDIOC_STREAMON)
2228 {VIDIOC_STREAMON, "VIDIOC_STREAMON"},
2229 #endif
2230 #if defined(VIDIOC_STREAMOFF)
2231 {VIDIOC_STREAMOFF, "VIDIOC_STREAMOFF"},
2232 #endif
2233 #if defined(VIDIOC_G_PARM)
2234 {VIDIOC_G_PARM, "VIDIOC_G_PARM"},
2235 #endif
2236 #if defined(VIDIOC_S_PARM)
2237 {VIDIOC_S_PARM, "VIDIOC_S_PARM"},
2238 #endif
2239 #if defined(VIDIOC_G_STD)
2240 {VIDIOC_G_STD, "VIDIOC_G_STD"},
2241 #endif
2242 #if defined(VIDIOC_S_STD)
2243 {VIDIOC_S_STD, "VIDIOC_S_STD"},
2244 #endif
2245 #if defined(VIDIOC_ENUMSTD)
2246 {VIDIOC_ENUMSTD, "VIDIOC_ENUMSTD"},
2247 #endif
2248 #if defined(VIDIOC_ENUMINPUT)
2249 {VIDIOC_ENUMINPUT, "VIDIOC_ENUMINPUT"},
2250 #endif
2251 #if defined(VIDIOC_G_CTRL)
2252 {VIDIOC_G_CTRL, "VIDIOC_G_CTRL"},
2253 #endif
2254 #if defined(VIDIOC_S_CTRL)
2255 {VIDIOC_S_CTRL, "VIDIOC_S_CTRL"},
2256 #endif
2257 #if defined(VIDIOC_G_TUNER)
2258 {VIDIOC_G_TUNER, "VIDIOC_G_TUNER"},
2259 #endif
2260 #if defined(VIDIOC_S_TUNER)
2261 {VIDIOC_S_TUNER, "VIDIOC_S_TUNER"},
2262 #endif
2263 #if defined(VIDIOC_G_AUDIO)
2264 {VIDIOC_G_AUDIO, "VIDIOC_G_AUDIO"},
2265 #endif
2266 #if defined(VIDIOC_S_AUDIO)
2267 {VIDIOC_S_AUDIO, "VIDIOC_S_AUDIO"},
2268 #endif
2269 #if defined(VIDIOC_QUERYCTRL)
2270 {VIDIOC_QUERYCTRL, "VIDIOC_QUERYCTRL"},
2271 #endif
2272 #if defined(VIDIOC_QUERYMENU)
2273 {VIDIOC_QUERYMENU, "VIDIOC_QUERYMENU"},
2274 #endif
2275 #if defined(VIDIOC_G_INPUT)
2276 {VIDIOC_G_INPUT, "VIDIOC_G_INPUT"},
2277 #endif
2278 #if defined(VIDIOC_S_INPUT)
2279 {VIDIOC_S_INPUT, "VIDIOC_S_INPUT"},
2280 #endif
2281 #if defined(VIDIOC_G_OUTPUT)
2282 {VIDIOC_G_OUTPUT, "VIDIOC_G_OUTPUT"},
2283 #endif
2284 #if defined(VIDIOC_S_OUTPUT)
2285 {VIDIOC_S_OUTPUT, "VIDIOC_S_OUTPUT"},
2286 #endif
2287 #if defined(VIDIOC_ENUMOUTPUT)
2288 {VIDIOC_ENUMOUTPUT, "VIDIOC_ENUMOUTPUT"},
2289 #endif
2290 #if defined(VIDIOC_G_AUDOUT)
2291 {VIDIOC_G_AUDOUT, "VIDIOC_G_AUDOUT"},
2292 #endif
2293 #if defined(VIDIOC_S_AUDOUT)
2294 {VIDIOC_S_AUDOUT, "VIDIOC_S_AUDOUT"},
2295 #endif
2296 #if defined(VIDIOC_G_MODULATOR)
2297 {VIDIOC_G_MODULATOR, "VIDIOC_G_MODULATOR"},
2298 #endif
2299 #if defined(VIDIOC_S_MODULATOR)
2300 {VIDIOC_S_MODULATOR, "VIDIOC_S_MODULATOR"},
2301 #endif
2302 #if defined(VIDIOC_G_FREQUENCY)
2303 {VIDIOC_G_FREQUENCY, "VIDIOC_G_FREQUENCY"},
2304 #endif
2305 #if defined(VIDIOC_S_FREQUENCY)
2306 {VIDIOC_S_FREQUENCY, "VIDIOC_S_FREQUENCY"},
2307 #endif
2308 #if defined(VIDIOC_CROPCAP)
2309 {VIDIOC_CROPCAP, "VIDIOC_CROPCAP"},
2310 #endif
2311 #if defined(VIDIOC_G_CROP)
2312 {VIDIOC_G_CROP, "VIDIOC_G_CROP"},
2313 #endif
2314 #if defined(VIDIOC_S_CROP)
2315 {VIDIOC_S_CROP, "VIDIOC_S_CROP"},
2316 #endif
2317 #if defined(VIDIOC_G_JPEGCOMP)
2318 {VIDIOC_G_JPEGCOMP, "VIDIOC_G_JPEGCOMP"},
2319 #endif
2320 #if defined(VIDIOC_S_JPEGCOMP)
2321 {VIDIOC_S_JPEGCOMP, "VIDIOC_S_JPEGCOMP"},
2322 #endif
2323 #if defined(VIDIOC_QUERYSTD)
2324 {VIDIOC_QUERYSTD, "VIDIOC_QUERYSTD"},
2325 #endif
2326 #if defined(VIDIOC_TRY_FMT)
2327 {VIDIOC_TRY_FMT, "VIDIOC_TRY_FMT"},
2328 #endif
2329 #if defined(VIDIOC_ENUMAUDIO)
2330 {VIDIOC_ENUMAUDIO, "VIDIOC_ENUMAUDIO"},
2331 #endif
2332 #if defined(VIDIOC_ENUMAUDOUT)
2333 {VIDIOC_ENUMAUDOUT, "VIDIOC_ENUMAUDOUT"},
2334 #endif
2335 #if defined(VIDIOC_G_PRIORITY)
2336 {VIDIOC_G_PRIORITY, "VIDIOC_G_PRIORITY"},
2337 #endif
2338 #if defined(VIDIOC_S_PRIORITY)
2339 {VIDIOC_S_PRIORITY, "VIDIOC_S_PRIORITY"},
2340 #endif
2341 #if defined(VIDIOC_G_SLICED_VBI_CAP)
2342 {VIDIOC_G_SLICED_VBI_CAP, "VIDIOC_G_SLICED_VBI_CAP"},
2343 #endif
2344 #if defined(VIDIOC_LOG_STATUS)
2345 {VIDIOC_LOG_STATUS, "VIDIOC_LOG_STATUS"},
2346 #endif
2347 #if defined(VIDIOC_G_EXT_CTRLS)
2348 {VIDIOC_G_EXT_CTRLS, "VIDIOC_G_EXT_CTRLS"},
2349 #endif
2350 #if defined(VIDIOC_S_EXT_CTRLS)
2351 {VIDIOC_S_EXT_CTRLS, "VIDIOC_S_EXT_CTRLS"},
2352 #endif
2353 #if defined(VIDIOC_TRY_EXT_CTRLS)
2354 {VIDIOC_TRY_EXT_CTRLS, "VIDIOC_TRY_EXT_CTRLS"},
2355 #endif
2356 #if defined(VIDIOC_ENUM_FRAMESIZES)
2357 {VIDIOC_ENUM_FRAMESIZES, "VIDIOC_ENUM_FRAMESIZES"},
2358 #endif
2359 #if defined(VIDIOC_ENUM_FRAMEINTERVALS)
2360 {VIDIOC_ENUM_FRAMEINTERVALS, "VIDIOC_ENUM_FRAMEINTERVALS"},
2361 #endif
2362 #if defined(VIDIOC_G_ENC_INDEX)
2363 {VIDIOC_G_ENC_INDEX, "VIDIOC_G_ENC_INDEX"},
2364 #endif
2365 #if defined(VIDIOC_ENCODER_CMD)
2366 {VIDIOC_ENCODER_CMD, "VIDIOC_ENCODER_CMD"},
2367 #endif
2368 #if defined(VIDIOC_TRY_ENCODER_CMD)
2369 {VIDIOC_TRY_ENCODER_CMD, "VIDIOC_TRY_ENCODER_CMD"},
2370 #endif
2371 #if defined(VIDIOC_G_CHIP_IDENT)
2372 {VIDIOC_G_CHIP_IDENT, "VIDIOC_G_CHIP_IDENT"},
2373 #endif
2375 #if defined(VIDIOC_OVERLAY_OLD)
2376 {VIDIOC_OVERLAY_OLD, "VIDIOC_OVERLAY_OLD"},
2377 #endif
2378 #if defined(VIDIOC_S_PARM_OLD)
2379 {VIDIOC_S_PARM_OLD, "VIDIOC_S_PARM_OLD"},
2380 #endif
2381 #if defined(VIDIOC_S_CTRL_OLD)
2382 {VIDIOC_S_CTRL_OLD, "VIDIOC_S_CTRL_OLD"},
2383 #endif
2384 #if defined(VIDIOC_G_AUDIO_OLD)
2385 {VIDIOC_G_AUDIO_OLD, "VIDIOC_G_AUDIO_OLD"},
2386 #endif
2387 #if defined(VIDIOC_G_AUDOUT_OLD)
2388 {VIDIOC_G_AUDOUT_OLD, "VIDIOC_G_AUDOUT_OLD"},
2389 #endif
2390 #if defined(VIDIOC_CROPCAP_OLD)
2391 {VIDIOC_CROPCAP_OLD, "VIDIOC_CROPCAP_OLD"},
2392 #endif
2393 {0xFFFFFFFF, ""}
2396 static struct mess mess1[] = \
2398 #if defined(VIDIOCGCAP)
2399 {VIDIOCGCAP, "VIDIOCGCAP"},
2400 #endif
2401 #if defined(VIDIOCGCHAN)
2402 {VIDIOCGCHAN, "VIDIOCGCHAN"},
2403 #endif
2404 #if defined(VIDIOCSCHAN)
2405 {VIDIOCSCHAN, "VIDIOCSCHAN"},
2406 #endif
2407 #if defined(VIDIOCGTUNER)
2408 {VIDIOCGTUNER, "VIDIOCGTUNER"},
2409 #endif
2410 #if defined(VIDIOCSTUNER)
2411 {VIDIOCSTUNER, "VIDIOCSTUNER"},
2412 #endif
2413 #if defined(VIDIOCGPICT)
2414 {VIDIOCGPICT, "VIDIOCGPICT"},
2415 #endif
2416 #if defined(VIDIOCSPICT)
2417 {VIDIOCSPICT, "VIDIOCSPICT"},
2418 #endif
2419 #if defined(VIDIOCCAPTURE)
2420 {VIDIOCCAPTURE, "VIDIOCCAPTURE"},
2421 #endif
2422 #if defined(VIDIOCGWIN)
2423 {VIDIOCGWIN, "VIDIOCGWIN"},
2424 #endif
2425 #if defined(VIDIOCSWIN)
2426 {VIDIOCSWIN, "VIDIOCSWIN"},
2427 #endif
2428 #if defined(VIDIOCGFBUF)
2429 {VIDIOCGFBUF, "VIDIOCGFBUF"},
2430 #endif
2431 #if defined(VIDIOCSFBUF)
2432 {VIDIOCSFBUF, "VIDIOCSFBUF"},
2433 #endif
2434 #if defined(VIDIOCKEY)
2435 {VIDIOCKEY, "VIDIOCKEY"},
2436 #endif
2437 #if defined(VIDIOCGFREQ)
2438 {VIDIOCGFREQ, "VIDIOCGFREQ"},
2439 #endif
2440 #if defined(VIDIOCSFREQ)
2441 {VIDIOCSFREQ, "VIDIOCSFREQ"},
2442 #endif
2443 #if defined(VIDIOCGAUDIO)
2444 {VIDIOCGAUDIO, "VIDIOCGAUDIO"},
2445 #endif
2446 #if defined(VIDIOCSAUDIO)
2447 {VIDIOCSAUDIO, "VIDIOCSAUDIO"},
2448 #endif
2449 #if defined(VIDIOCSYNC)
2450 {VIDIOCSYNC, "VIDIOCSYNC"},
2451 #endif
2452 #if defined(VIDIOCMCAPTURE)
2453 {VIDIOCMCAPTURE, "VIDIOCMCAPTURE"},
2454 #endif
2455 #if defined(VIDIOCGMBUF)
2456 {VIDIOCGMBUF, "VIDIOCGMBUF"},
2457 #endif
2458 #if defined(VIDIOCGUNIT)
2459 {VIDIOCGUNIT, "VIDIOCGUNIT"},
2460 #endif
2461 #if defined(VIDIOCGCAPTURE)
2462 {VIDIOCGCAPTURE, "VIDIOCGCAPTURE"},
2463 #endif
2464 #if defined(VIDIOCSCAPTURE)
2465 {VIDIOCSCAPTURE, "VIDIOCSCAPTURE"},
2466 #endif
2467 #if defined(VIDIOCSPLAYMODE)
2468 {VIDIOCSPLAYMODE, "VIDIOCSPLAYMODE"},
2469 #endif
2470 #if defined(VIDIOCSWRITEMODE)
2471 {VIDIOCSWRITEMODE, "VIDIOCSWRITEMODE"},
2472 #endif
2473 #if defined(VIDIOCGPLAYINFO)
2474 {VIDIOCGPLAYINFO, "VIDIOCGPLAYINFO"},
2475 #endif
2476 #if defined(VIDIOCSMICROCODE)
2477 {VIDIOCSMICROCODE, "VIDIOCSMICROCODE"},
2478 #endif
2479 {0xFFFFFFFF, ""}
2482 k = 0;
2483 while (mess[k].name[0]) {
2484 if (wot == mess[k].command) {
2485 JOT(8, "ioctl 0x%08X is %s\n", \
2486 mess[k].command, &mess[k].name[0]);
2487 return 0;
2489 k++;
2491 JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot);
2493 k = 0;
2494 while (mess1[k].name[0]) {
2495 if (wot == mess1[k].command) {
2496 JOT(8, "ioctl 0x%08X is %s (V4L1)\n", \
2497 mess1[k].command, &mess1[k].name[0]);
2498 return 0;
2500 k++;
2502 JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot);
2503 return -1;
2505 /*****************************************************************************/
2506 int explain_cid(__u32 wot)
2508 int k;
2509 /*---------------------------------------------------------------------------*/
2511 * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
2512 * SHELL SCRIPT:
2514 * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
2515 * grep "^#define V4L2_CID_" | \
2516 * sed -e "s,(.*$,,;p" | sed -e "N;s,\n,, " | \
2517 * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \
2518 * sed -e "s, ,,g;s, ,,g" | grep -v "_BASE" | grep -v "MPEG" >cid.tmp
2519 * echo "{0xFFFFFFFF,\"\"}" >>cid.tmp
2520 * exit 0
2523 /*---------------------------------------------------------------------------*/
2524 static struct mess
2526 __u32 command;
2527 char name[64];
2528 } mess[] = {
2529 #if defined(V4L2_CID_USER_CLASS)
2530 {V4L2_CID_USER_CLASS, "V4L2_CID_USER_CLASS"},
2531 #endif
2532 #if defined(V4L2_CID_BRIGHTNESS)
2533 {V4L2_CID_BRIGHTNESS, "V4L2_CID_BRIGHTNESS"},
2534 #endif
2535 #if defined(V4L2_CID_CONTRAST)
2536 {V4L2_CID_CONTRAST, "V4L2_CID_CONTRAST"},
2537 #endif
2538 #if defined(V4L2_CID_SATURATION)
2539 {V4L2_CID_SATURATION, "V4L2_CID_SATURATION"},
2540 #endif
2541 #if defined(V4L2_CID_HUE)
2542 {V4L2_CID_HUE, "V4L2_CID_HUE"},
2543 #endif
2544 #if defined(V4L2_CID_AUDIO_VOLUME)
2545 {V4L2_CID_AUDIO_VOLUME, "V4L2_CID_AUDIO_VOLUME"},
2546 #endif
2547 #if defined(V4L2_CID_AUDIO_BALANCE)
2548 {V4L2_CID_AUDIO_BALANCE, "V4L2_CID_AUDIO_BALANCE"},
2549 #endif
2550 #if defined(V4L2_CID_AUDIO_BASS)
2551 {V4L2_CID_AUDIO_BASS, "V4L2_CID_AUDIO_BASS"},
2552 #endif
2553 #if defined(V4L2_CID_AUDIO_TREBLE)
2554 {V4L2_CID_AUDIO_TREBLE, "V4L2_CID_AUDIO_TREBLE"},
2555 #endif
2556 #if defined(V4L2_CID_AUDIO_MUTE)
2557 {V4L2_CID_AUDIO_MUTE, "V4L2_CID_AUDIO_MUTE"},
2558 #endif
2559 #if defined(V4L2_CID_AUDIO_LOUDNESS)
2560 {V4L2_CID_AUDIO_LOUDNESS, "V4L2_CID_AUDIO_LOUDNESS"},
2561 #endif
2562 #if defined(V4L2_CID_BLACK_LEVEL)
2563 {V4L2_CID_BLACK_LEVEL, "V4L2_CID_BLACK_LEVEL"},
2564 #endif
2565 #if defined(V4L2_CID_AUTO_WHITE_BALANCE)
2566 {V4L2_CID_AUTO_WHITE_BALANCE, "V4L2_CID_AUTO_WHITE_BALANCE"},
2567 #endif
2568 #if defined(V4L2_CID_DO_WHITE_BALANCE)
2569 {V4L2_CID_DO_WHITE_BALANCE, "V4L2_CID_DO_WHITE_BALANCE"},
2570 #endif
2571 #if defined(V4L2_CID_RED_BALANCE)
2572 {V4L2_CID_RED_BALANCE, "V4L2_CID_RED_BALANCE"},
2573 #endif
2574 #if defined(V4L2_CID_BLUE_BALANCE)
2575 {V4L2_CID_BLUE_BALANCE, "V4L2_CID_BLUE_BALANCE"},
2576 #endif
2577 #if defined(V4L2_CID_GAMMA)
2578 {V4L2_CID_GAMMA, "V4L2_CID_GAMMA"},
2579 #endif
2580 #if defined(V4L2_CID_WHITENESS)
2581 {V4L2_CID_WHITENESS, "V4L2_CID_WHITENESS"},
2582 #endif
2583 #if defined(V4L2_CID_EXPOSURE)
2584 {V4L2_CID_EXPOSURE, "V4L2_CID_EXPOSURE"},
2585 #endif
2586 #if defined(V4L2_CID_AUTOGAIN)
2587 {V4L2_CID_AUTOGAIN, "V4L2_CID_AUTOGAIN"},
2588 #endif
2589 #if defined(V4L2_CID_GAIN)
2590 {V4L2_CID_GAIN, "V4L2_CID_GAIN"},
2591 #endif
2592 #if defined(V4L2_CID_HFLIP)
2593 {V4L2_CID_HFLIP, "V4L2_CID_HFLIP"},
2594 #endif
2595 #if defined(V4L2_CID_VFLIP)
2596 {V4L2_CID_VFLIP, "V4L2_CID_VFLIP"},
2597 #endif
2598 #if defined(V4L2_CID_HCENTER)
2599 {V4L2_CID_HCENTER, "V4L2_CID_HCENTER"},
2600 #endif
2601 #if defined(V4L2_CID_VCENTER)
2602 {V4L2_CID_VCENTER, "V4L2_CID_VCENTER"},
2603 #endif
2604 #if defined(V4L2_CID_POWER_LINE_FREQUENCY)
2605 {V4L2_CID_POWER_LINE_FREQUENCY, "V4L2_CID_POWER_LINE_FREQUENCY"},
2606 #endif
2607 #if defined(V4L2_CID_HUE_AUTO)
2608 {V4L2_CID_HUE_AUTO, "V4L2_CID_HUE_AUTO"},
2609 #endif
2610 #if defined(V4L2_CID_WHITE_BALANCE_TEMPERATURE)
2611 {V4L2_CID_WHITE_BALANCE_TEMPERATURE, "V4L2_CID_WHITE_BALANCE_TEMPERATURE"},
2612 #endif
2613 #if defined(V4L2_CID_SHARPNESS)
2614 {V4L2_CID_SHARPNESS, "V4L2_CID_SHARPNESS"},
2615 #endif
2616 #if defined(V4L2_CID_BACKLIGHT_COMPENSATION)
2617 {V4L2_CID_BACKLIGHT_COMPENSATION, "V4L2_CID_BACKLIGHT_COMPENSATION"},
2618 #endif
2619 #if defined(V4L2_CID_CHROMA_AGC)
2620 {V4L2_CID_CHROMA_AGC, "V4L2_CID_CHROMA_AGC"},
2621 #endif
2622 #if defined(V4L2_CID_COLOR_KILLER)
2623 {V4L2_CID_COLOR_KILLER, "V4L2_CID_COLOR_KILLER"},
2624 #endif
2625 #if defined(V4L2_CID_LASTP1)
2626 {V4L2_CID_LASTP1, "V4L2_CID_LASTP1"},
2627 #endif
2628 #if defined(V4L2_CID_CAMERA_CLASS)
2629 {V4L2_CID_CAMERA_CLASS, "V4L2_CID_CAMERA_CLASS"},
2630 #endif
2631 #if defined(V4L2_CID_EXPOSURE_AUTO)
2632 {V4L2_CID_EXPOSURE_AUTO, "V4L2_CID_EXPOSURE_AUTO"},
2633 #endif
2634 #if defined(V4L2_CID_EXPOSURE_ABSOLUTE)
2635 {V4L2_CID_EXPOSURE_ABSOLUTE, "V4L2_CID_EXPOSURE_ABSOLUTE"},
2636 #endif
2637 #if defined(V4L2_CID_EXPOSURE_AUTO_PRIORITY)
2638 {V4L2_CID_EXPOSURE_AUTO_PRIORITY, "V4L2_CID_EXPOSURE_AUTO_PRIORITY"},
2639 #endif
2640 #if defined(V4L2_CID_PAN_RELATIVE)
2641 {V4L2_CID_PAN_RELATIVE, "V4L2_CID_PAN_RELATIVE"},
2642 #endif
2643 #if defined(V4L2_CID_TILT_RELATIVE)
2644 {V4L2_CID_TILT_RELATIVE, "V4L2_CID_TILT_RELATIVE"},
2645 #endif
2646 #if defined(V4L2_CID_PAN_RESET)
2647 {V4L2_CID_PAN_RESET, "V4L2_CID_PAN_RESET"},
2648 #endif
2649 #if defined(V4L2_CID_TILT_RESET)
2650 {V4L2_CID_TILT_RESET, "V4L2_CID_TILT_RESET"},
2651 #endif
2652 #if defined(V4L2_CID_PAN_ABSOLUTE)
2653 {V4L2_CID_PAN_ABSOLUTE, "V4L2_CID_PAN_ABSOLUTE"},
2654 #endif
2655 #if defined(V4L2_CID_TILT_ABSOLUTE)
2656 {V4L2_CID_TILT_ABSOLUTE, "V4L2_CID_TILT_ABSOLUTE"},
2657 #endif
2658 #if defined(V4L2_CID_FOCUS_ABSOLUTE)
2659 {V4L2_CID_FOCUS_ABSOLUTE, "V4L2_CID_FOCUS_ABSOLUTE"},
2660 #endif
2661 #if defined(V4L2_CID_FOCUS_RELATIVE)
2662 {V4L2_CID_FOCUS_RELATIVE, "V4L2_CID_FOCUS_RELATIVE"},
2663 #endif
2664 #if defined(V4L2_CID_FOCUS_AUTO)
2665 {V4L2_CID_FOCUS_AUTO, "V4L2_CID_FOCUS_AUTO"},
2666 #endif
2667 {0xFFFFFFFF, ""}
2670 k = 0;
2671 while (mess[k].name[0]) {
2672 if (wot == mess[k].command) {
2673 JOT(8, "ioctl 0x%08X is %s\n", \
2674 mess[k].command, &mess[k].name[0]);
2675 return 0;
2677 k++;
2679 JOT(8, "cid 0x%08X is not in videodev2.h\n", wot);
2680 return -1;
2682 /*****************************************************************************/