• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/staging/easycap/
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/*---------------------------------------------------------------------------*/
44int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
45{
46struct easycap_standard const *peasycap_standard;
47__u16 reg, set;
48int ir, rc, need;
49unsigned int itwas, isnow;
50
51if ((struct usb_device *)NULL == peasycap->pusb_device) {
52	SAY("ERROR: peasycap->pusb_device is NULL\n");
53	return -EFAULT;
54}
55peasycap_standard = &easycap_standard[0];
56while (0xFFFF != peasycap_standard->mask) {
57	if (std_id & peasycap_standard->v4l2_standard.id)
58		break;
59	peasycap_standard++;
60}
61if (0xFFFF == peasycap_standard->mask) {
62	SAY("ERROR: 0x%08X=std_id: standard not found\n", \
63							(unsigned int)std_id);
64	return -EINVAL;
65}
66SAY("user requests standard: %s\n", \
67			&(peasycap_standard->v4l2_standard.name[0]));
68if (peasycap->standard_offset == \
69			(int)(peasycap_standard - &easycap_standard[0])) {
70	SAY("requested standard already in effect\n");
71	return 0;
72}
73peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
74peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
75		peasycap_standard->v4l2_standard.frameperiod.numerator;
76if (!peasycap->fps) {
77	SAY("MISTAKE: frames-per-second is zero\n");
78	return -EFAULT;
79}
80JOT(8, "%i frames-per-second\n", peasycap->fps);
81peasycap->usec = 1000000 / (2 * peasycap->fps);
82peasycap->tolerate = 1000 * (25 / peasycap->fps);
83
84kill_video_urbs(peasycap);
85
86/*--------------------------------------------------------------------------*/
87/*
88 *  SAA7113H DATASHEET PAGE 44, TABLE 42
89 */
90/*--------------------------------------------------------------------------*/
91need = 0;  itwas = 0;  reg = 0x00;  set = 0x00;
92switch (peasycap_standard->mask & 0x000F) {
93case 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}
153case NTSC_M:
154case PAL_BGHIN: {
155	reg = 0x0E;  set = 0x01;  need = 1;  break;
156}
157case NTSC_N_443:
158case PAL_60: {
159	reg = 0x0E;  set = 0x11;  need = 1;  break;
160}
161case NTSC_443:
162case PAL_Nc: {
163	reg = 0x0E;  set = 0x21;  need = 1;  break;
164}
165case NTSC_N:
166case PAL_M: {
167	reg = 0x0E;  set = 0x31;  need = 1;  break;
168}
169case SECAM: {
170	reg = 0x0E;  set = 0x51;  need = 1;  break;
171}
172default:
173	break;
174}
175/*--------------------------------------------------------------------------*/
176if (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/*--------------------------------------------------------------------------*/
204reg = 0x08;
205ir = read_saa(peasycap->pusb_device, reg);
206if (0 > ir)
207	SAY("ERROR: failed to read SAA register 0x%02X " \
208						"so cannot reset\n", reg);
209else {
210	itwas = (unsigned int)ir;
211	if (peasycap_standard->mask & 0x0001)
212		set = itwas | 0x40 ;
213	else
214		set = itwas & ~0x40 ;
215
216set2to78(peasycap->pusb_device);
217
218rc  = write_saa(peasycap->pusb_device, reg, set);
219if (0 != rc)
220	SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
221else {
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/*---------------------------------------------------------------------------*/
235reg = 0x40;
236ir = read_saa(peasycap->pusb_device, reg);
237if (0 > ir)
238	SAY("ERROR: failed to read SAA register 0x%02X " \
239						"so cannot reset\n", reg);
240else {
241	itwas = (unsigned int)ir;
242	if (peasycap_standard->mask & 0x0001)
243		set = itwas | 0x80 ;
244	else
245		set = itwas & ~0x80 ;
246
247set2to78(peasycap->pusb_device);
248
249rc = write_saa(peasycap->pusb_device, reg, set);
250if (0 != rc)
251	SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
252else {
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/*--------------------------------------------------------------------------*/
266reg = 0x5A;
267ir = read_saa(peasycap->pusb_device, reg);
268if (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");
292return 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/*--------------------------------------------------------------------------*/
318int adjust_format(struct easycap *peasycap, \
319	__u32 width, __u32 height, __u32 pixelformat, int field, bool try)
320{
321struct easycap_format *peasycap_format, *peasycap_best_format;
322__u16 mask;
323struct usb_device *p;
324int miss, multiplier, best;
325char bf[5], *pc;
326__u32 uc;
327
328if ((struct easycap *)NULL == peasycap) {
329	SAY("ERROR: peasycap is NULL\n");
330	return -EFAULT;
331}
332p = peasycap->pusb_device;
333if ((struct usb_device *)NULL == p) {
334	SAY("ERROR: peaycap->pusb_device is NULL\n");
335	return -EFAULT;
336}
337pc = &bf[0];
338uc = pixelformat;  memcpy((void *)pc, (void *)(&uc), 4);  bf[4] = 0;
339mask = easycap_standard[peasycap->standard_offset].mask;
340SAY("sought:    %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
341				width, height, pc, pixelformat, field, mask);
342if (V4L2_FIELD_ANY == field) {
343	field = V4L2_FIELD_INTERLACED;
344	SAY("prefer:    V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n");
345}
346peasycap_best_format = (struct easycap_format *)NULL;
347peasycap_format = &easycap_format[0];
348while (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}
367if (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}
397if ((struct easycap_format *)NULL == peasycap_best_format) {
398	SAY("MISTAKE: peasycap_best_format is NULL");
399	return -EINVAL;
400}
401peasycap_format = peasycap_best_format;
402
403/*...........................................................................*/
404if (true == try)
405	return (int)(peasycap_best_format - &easycap_format[0]);
406/*...........................................................................*/
407
408if (false != try) {
409	SAY("MISTAKE: true==try where is should be false\n");
410	return -EINVAL;
411}
412SAY("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]);
416peasycap->height        = peasycap_format->v4l2_format.fmt.pix.height;
417peasycap->width         = peasycap_format->v4l2_format.fmt.pix.width;
418peasycap->pixelformat   = peasycap_format->v4l2_format.fmt.pix.pixelformat;
419peasycap->field         = peasycap_format->v4l2_format.fmt.pix.field;
420peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
421peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ;
422if (0x0100 & peasycap_format->mask)
423	peasycap->byteswaporder = true;
424else
425	peasycap->byteswaporder = false;
426if (0x0800 & peasycap_format->mask)
427	peasycap->decimatepixel = true;
428else
429	peasycap->decimatepixel = false;
430if (0x1000 & peasycap_format->mask)
431	peasycap->offerfields = true;
432else
433	peasycap->offerfields = false;
434if (true == peasycap->decimatepixel)
435	multiplier = 2;
436else
437	multiplier = 1;
438peasycap->videofieldamount = multiplier * peasycap->width * \
439					multiplier * peasycap->height;
440peasycap->frame_buffer_used = peasycap->bytesperpixel * \
441					peasycap->width * peasycap->height;
442
443if (true == peasycap->offerfields) {
444	SAY("WARNING: %i=peasycap->field is untested: " \
445				"please report problems\n", peasycap->field);
446
447
448
449
450
451}
452
453kill_video_urbs(peasycap);
454
455/*---------------------------------------------------------------------------*/
456/*
457 *  PAL
458 */
459/*---------------------------------------------------------------------------*/
460if (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;
471		}
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;
477		}
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;
488		}
489	} else {
490		SAY("MISTAKE: bad format, cannot set resolution\n");
491		return -EINVAL;
492	}
493/*---------------------------------------------------------------------------*/
494/*
495 *  NTSC
496 */
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;
509		}
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;
520		}
521	} else {
522		SAY("MISTAKE: bad format, cannot set resolution\n");
523		return -EINVAL;
524	}
525}
526/*---------------------------------------------------------------------------*/
527
528check_stk(peasycap->pusb_device);
529
530return (int)(peasycap_best_format - &easycap_format[0]);
531}
532/*****************************************************************************/
533int adjust_brightness(struct easycap *peasycap, int value)
534{
535unsigned int mood;
536int i1;
537
538if ((struct usb_device *)NULL == peasycap->pusb_device) {
539	SAY("ERROR: peasycap->pusb_device is NULL\n");
540	return -EFAULT;
541}
542i1 = 0;
543while (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;
550
551		set2to78(peasycap->pusb_device);
552
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;
560		}
561
562		set2to78(peasycap->pusb_device);
563
564		break;
565	}
566	i1++;
567}
568SAY("WARNING: failed to adjust brightness: control not found\n");
569return -ENOENT;
570}
571/*****************************************************************************/
572int adjust_contrast(struct easycap *peasycap, int value)
573{
574unsigned int mood;
575int i1;
576
577if ((struct usb_device *)NULL == peasycap->pusb_device) {
578	SAY("ERROR: peasycap->pusb_device is NULL\n");
579	return -EFAULT;
580}
581i1 = 0;
582while (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);
589
590		set2to78(peasycap->pusb_device);
591
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;
599		}
600
601		set2to78(peasycap->pusb_device);
602
603		break;
604	}
605	i1++;
606}
607SAY("WARNING: failed to adjust contrast: control not found\n");
608return -ENOENT;
609}
610/*****************************************************************************/
611int adjust_saturation(struct easycap *peasycap, int value)
612{
613unsigned int mood;
614int i1;
615
616if ((struct usb_device *)NULL == peasycap->pusb_device) {
617	SAY("ERROR: peasycap->pusb_device is NULL\n");
618	return -EFAULT;
619}
620i1 = 0;
621while (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);
628
629		set2to78(peasycap->pusb_device);
630
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;
638		}
639		break;
640
641		set2to78(peasycap->pusb_device);
642
643	}
644	i1++;
645}
646SAY("WARNING: failed to adjust saturation: control not found\n");
647return -ENOENT;
648}
649/*****************************************************************************/
650int adjust_hue(struct easycap *peasycap, int value)
651{
652unsigned int mood;
653int i1, i2;
654
655if ((struct usb_device *)NULL == peasycap->pusb_device) {
656	SAY("ERROR: peasycap->pusb_device is NULL\n");
657	return -EFAULT;
658}
659i1 = 0;
660while (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);
668
669		set2to78(peasycap->pusb_device);
670
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;
677		}
678
679		set2to78(peasycap->pusb_device);
680
681		break;
682	}
683	i1++;
684}
685SAY("WARNING: failed to adjust hue: control not found\n");
686return -ENOENT;
687}
688/*****************************************************************************/
689int adjust_volume(struct easycap *peasycap, int value)
690{
691__s8 mood;
692int i1;
693
694if ((struct usb_device *)NULL == peasycap->pusb_device) {
695	SAY("ERROR: peasycap->pusb_device is NULL\n");
696	return -EFAULT;
697}
698i1 = 0;
699while (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;
715		}
716		break;
717	}
718i1++;
719}
720SAY("WARNING: failed to adjust volume: control not found\n");
721return -ENOENT;
722}
723/*****************************************************************************/
724/*---------------------------------------------------------------------------*/
725/*
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.
733 */
734/*---------------------------------------------------------------------------*/
735int adjust_mute(struct easycap *peasycap, int value)
736{
737int i1;
738
739if ((struct usb_device *)NULL == peasycap->pusb_device) {
740	SAY("ERROR: peasycap->pusb_device is NULL\n");
741	return -EFAULT;
742}
743i1 = 0;
744while (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;
754		}
755		default: {
756			peasycap->audio_idle = 0;
757			SAY("adjusting mute: %i=peasycap->audio_idle\n", \
758							peasycap->audio_idle);
759			return 0;
760		}
761		}
762		break;
763	}
764	i1++;
765}
766SAY("WARNING: failed to adjust mute: control not found\n");
767return -ENOENT;
768}
769
770/*--------------------------------------------------------------------------*/
771static int easycap_ioctl_bkl(struct inode *inode, struct file *file,
772			     unsigned int cmd, unsigned long arg)
773{
774static struct easycap *peasycap;
775static struct usb_device *p;
776static __u32 isequence;
777
778peasycap = file->private_data;
779if (NULL == peasycap) {
780	SAY("ERROR:  peasycap is NULL\n");
781	return -1;
782}
783p = peasycap->pusb_device;
784if ((struct usb_device *)NULL == p) {
785	SAY("ERROR: peasycap->pusb_device is NULL\n");
786	return -EFAULT;
787}
788/*---------------------------------------------------------------------------*/
789/*
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
794 */
795/*---------------------------------------------------------------------------*/
796switch (cmd) {
797case 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;
802
803	JOT(8, "VIDIOC_QUERYCAP\n");
804
805	if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
806		SAY("ERROR: bad driver version string\n"); return -EINVAL;
807	}
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;
824			}
825			k[i] = (int)lng;
826		}
827		i++;
828	}
829
830	memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
831	strlcpy(&v4l2_capability.driver[0], "easycap", \
832					sizeof(v4l2_capability.driver));
833
834	v4l2_capability.capabilities = \
835				V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
836				V4L2_CAP_AUDIO         | V4L2_CAP_READWRITE;
837
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]);
840
841	strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
842		sizeof(v4l2_capability.card));
843
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]);
850	}
851	if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
852					sizeof(struct v4l2_capability))) {
853		POUT;
854		return -EFAULT;
855	}
856	break;
857}
858/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
859case VIDIOC_ENUMINPUT: {
860	static struct v4l2_input v4l2_input;
861	static __u32 index;
862
863	JOT(8, "VIDIOC_ENUMINPUT\n");
864
865	if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
866					sizeof(struct v4l2_input))) {
867		POUT;
868		return -EFAULT;
869	}
870
871	index = v4l2_input.index;
872	memset(&v4l2_input, 0, sizeof(struct v4l2_input));
873
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;
886	}
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;
898	}
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;
910	}
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;
922	}
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;
934	}
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;
946	}
947	default: {
948		JOT(8, "%i=index: exhausts inputs\n", index);
949		return -EINVAL;
950	}
951	}
952
953	if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
954						sizeof(struct v4l2_input))) {
955		POUT;
956		return -EFAULT;
957	}
958	break;
959}
960/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
961case VIDIOC_G_INPUT: {
962	static __u32 index;
963
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;
970	}
971	break;
972}
973/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
974case VIDIOC_S_INPUT:
975	{
976	static __u32 index;
977
978	JOT(8, "VIDIOC_S_INPUT\n");
979
980	if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
981		POUT;
982		return -EFAULT;
983	}
984
985	JOT(8, "user requests input %i\n", index);
986
987	if ((int)index == peasycap->input) {
988		SAY("requested input already in effect\n");
989		break;
990	}
991
992	if ((0 > index) || (5 < index)) {
993		JOT(8, "ERROR:  bad requested input: %i\n", index);
994		return -EINVAL;
995	}
996	peasycap->input = (int)index;
997
998	select_input(peasycap->pusb_device, peasycap->input, 9);
999
1000	break;
1001}
1002/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1003case VIDIOC_ENUMAUDIO: {
1004	JOT(8, "VIDIOC_ENUMAUDIO\n");
1005	return -EINVAL;
1006}
1007/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1008case VIDIOC_ENUMAUDOUT: {
1009	static struct v4l2_audioout v4l2_audioout;
1010
1011	JOT(8, "VIDIOC_ENUMAUDOUT\n");
1012
1013	if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
1014					sizeof(struct v4l2_audioout))) {
1015		POUT;
1016		return -EFAULT;
1017	}
1018
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");
1024
1025	if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
1026					sizeof(struct v4l2_audioout))) {
1027		POUT;
1028		return -EFAULT;
1029	}
1030	break;
1031}
1032/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1033case VIDIOC_QUERYCTRL: {
1034	static int i1;
1035	static struct v4l2_queryctrl v4l2_queryctrl;
1036
1037	JOT(8, "VIDIOC_QUERYCTRL\n");
1038
1039	if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
1040					sizeof(struct v4l2_queryctrl))) {
1041		POUT;
1042		return -EFAULT;
1043	}
1044
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;
1053		}
1054		i1++;
1055	}
1056	if (0xFFFFFFFF == easycap_control[i1].id) {
1057		JOT(8, "%i=index: exhausts controls\n", i1);
1058		return -EINVAL;
1059	}
1060	if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
1061					sizeof(struct v4l2_queryctrl))) {
1062		POUT;
1063		return -EFAULT;
1064	}
1065	break;
1066}
1067/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1068case VIDIOC_QUERYMENU: {
1069	JOT(8, "VIDIOC_QUERYMENU unsupported\n");
1070	return -EINVAL;
1071	break;
1072}
1073/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1074case VIDIOC_G_CTRL: {
1075	static struct v4l2_control v4l2_control;
1076
1077	JOT(8, "VIDIOC_G_CTRL\n");
1078
1079	if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1080					sizeof(struct v4l2_control))) {
1081		POUT;
1082		return -EFAULT;
1083	}
1084
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;
1090	}
1091	case V4L2_CID_CONTRAST: {
1092		v4l2_control.value = peasycap->contrast;
1093		JOT(8, "user enquires contrast: %i\n", v4l2_control.value);
1094		break;
1095	}
1096	case V4L2_CID_SATURATION: {
1097		v4l2_control.value = peasycap->saturation;
1098		JOT(8, "user enquires saturation: %i\n", v4l2_control.value);
1099		break;
1100	}
1101	case V4L2_CID_HUE: {
1102		v4l2_control.value = peasycap->hue;
1103		JOT(8, "user enquires hue: %i\n", v4l2_control.value);
1104		break;
1105	}
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;
1110	}
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;
1118	}
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;
1124	}
1125	}
1126	if (0 != copy_to_user((void __user *)arg, &v4l2_control, \
1127					sizeof(struct v4l2_control))) {
1128		POUT;
1129		return -EFAULT;
1130	}
1131	break;
1132}
1133/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1134#if defined(VIDIOC_S_CTRL_OLD)
1135case VIDIOC_S_CTRL_OLD: {
1136	JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
1137}
1138#endif /*VIDIOC_S_CTRL_OLD*/
1139case VIDIOC_S_CTRL:
1140	{
1141	static struct v4l2_control v4l2_control;
1142
1143	JOT(8, "VIDIOC_S_CTRL\n");
1144
1145	if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1146					sizeof(struct v4l2_control))) {
1147		POUT;
1148		return -EFAULT;
1149	}
1150
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))
1155			;
1156		break;
1157	}
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))
1161			;
1162		break;
1163	}
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))
1167			;
1168		break;
1169	}
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))
1173			;
1174		break;
1175	}
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))
1179			;
1180		break;
1181	}
1182	case V4L2_CID_AUDIO_MUTE: {
1183		int mute;
1184
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;
1190
1191		if (0 != adjust_mute(peasycap, mute))
1192			SAY("WARNING: failed to adjust mute to %i\n", mute);
1193		break;
1194	}
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;
1200			}
1201		}
1202	break;
1203}
1204/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1205case VIDIOC_S_EXT_CTRLS: {
1206	JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1207	return -EINVAL;
1208}
1209/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1210case VIDIOC_ENUM_FMT: {
1211	static __u32 index;
1212	static struct v4l2_fmtdesc v4l2_fmtdesc;
1213
1214	JOT(8, "VIDIOC_ENUM_FMT\n");
1215
1216	if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
1217					sizeof(struct v4l2_fmtdesc))) {
1218		POUT;
1219		return -EFAULT;
1220	}
1221
1222	index = v4l2_fmtdesc.index;
1223	memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1224
1225	v4l2_fmtdesc.index = index;
1226	v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1227
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;
1235	}
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;
1242	}
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;
1249	}
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;
1256	}
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;
1263	}
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;
1270	}
1271	default: {
1272		JOT(8, "%i=index: exhausts formats\n", index);
1273		return -EINVAL;
1274	}
1275	}
1276	if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
1277					sizeof(struct v4l2_fmtdesc))) {
1278		POUT;
1279		return -EFAULT;
1280	}
1281	break;
1282}
1283/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1284case VIDIOC_ENUM_FRAMESIZES: {
1285	JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
1286	return -EINVAL;
1287}
1288case VIDIOC_ENUM_FRAMEINTERVALS: {
1289	JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
1290	return -EINVAL;
1291}
1292/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1293case VIDIOC_G_FMT: {
1294	static struct v4l2_format v4l2_format;
1295	static struct v4l2_pix_format v4l2_pix_format;
1296
1297	JOT(8, "VIDIOC_G_FMT\n");
1298
1299	if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1300					sizeof(struct v4l2_format))) {
1301		POUT;
1302		return -EFAULT;
1303	}
1304
1305	if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1306		POUT;
1307		return -EINVAL;
1308	}
1309
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]);
1317
1318	if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1319					sizeof(struct v4l2_format))) {
1320		POUT;
1321		return -EFAULT;
1322	}
1323	break;
1324}
1325/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1326case VIDIOC_TRY_FMT:
1327case 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;
1332
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;
1339	}
1340
1341	if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1342					sizeof(struct v4l2_format))) {
1343		POUT;
1344		return -EFAULT;
1345	}
1346
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;
1356	}
1357/*...........................................................................*/
1358	memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1359	v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1360
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]);
1364
1365	if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1366					sizeof(struct v4l2_format))) {
1367		POUT;
1368		return -EFAULT;
1369	}
1370	break;
1371}
1372/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1373case VIDIOC_CROPCAP: {
1374	static struct v4l2_cropcap v4l2_cropcap;
1375
1376	JOT(8, "VIDIOC_CROPCAP\n");
1377
1378	if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
1379					sizeof(struct v4l2_cropcap))) {
1380		POUT;
1381		return -EFAULT;
1382	}
1383
1384	if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1385		JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1386
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;
1399
1400	JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1401
1402	if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
1403					sizeof(struct v4l2_cropcap))) {
1404		POUT;
1405		return -EFAULT;
1406	}
1407	break;
1408}
1409/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1410case VIDIOC_G_CROP:
1411case VIDIOC_S_CROP: {
1412	JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP  unsupported\n");
1413	return -EINVAL;
1414}
1415/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1416case VIDIOC_QUERYSTD: {
1417	JOT(8, "VIDIOC_QUERYSTD: " \
1418			"EasyCAP is incapable of detecting standard\n");
1419	return -EINVAL;
1420	break;
1421}
1422/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1423/*---------------------------------------------------------------------------*/
1424/*---------------------------------------------------------------------------*/
1425case 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;
1430
1431	JOT(8, "VIDIOC_ENUMSTD\n");
1432
1433	if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
1434					sizeof(struct v4l2_standard))) {
1435		POUT;
1436		return -EFAULT;
1437	}
1438	index = v4l2_standard.index;
1439
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;
1445	}
1446
1447	memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1448
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++;
1454	}
1455	if (0xFFFF == peasycap_standard->mask) {
1456		JOT(8, "%i=index: exhausts standards\n", index);
1457		return -EINVAL;
1458	}
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));
1463
1464	v4l2_standard.index = index;
1465
1466	if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
1467					sizeof(struct v4l2_standard))) {
1468		POUT;
1469		return -EFAULT;
1470	}
1471	break;
1472}
1473/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1474case VIDIOC_G_STD: {
1475	static v4l2_std_id std_id;
1476	static struct easycap_standard const *peasycap_standard;
1477
1478	JOT(8, "VIDIOC_G_STD\n");
1479
1480	if (0 != copy_from_user(&std_id, (void __user *)arg, \
1481						sizeof(v4l2_std_id))) {
1482		POUT;
1483		return -EFAULT;
1484	}
1485
1486	peasycap_standard = &easycap_standard[peasycap->standard_offset];
1487	std_id = peasycap_standard->v4l2_standard.id;
1488
1489	JOT(8, "user is told: %s\n", \
1490				&peasycap_standard->v4l2_standard.name[0]);
1491
1492	if (0 != copy_to_user((void __user *)arg, &std_id, \
1493						sizeof(v4l2_std_id))) {
1494		POUT;
1495		return -EFAULT;
1496	}
1497	break;
1498}
1499/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1500case VIDIOC_S_STD: {
1501	static v4l2_std_id std_id;
1502	static int rc;
1503
1504	JOT(8, "VIDIOC_S_STD\n");
1505
1506	if (0 != copy_from_user(&std_id, (void __user *)arg, \
1507						sizeof(v4l2_std_id))) {
1508		POUT;
1509		return -EFAULT;
1510	}
1511
1512	rc = adjust_standard(peasycap, std_id);
1513	if (0 > rc) {
1514		JOT(8, "WARNING: adjust_standard() returned %i\n", rc);
1515		return -ENOENT;
1516	}
1517	break;
1518}
1519/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1520case VIDIOC_REQBUFS: {
1521	static int nbuffers;
1522	static struct v4l2_requestbuffers v4l2_requestbuffers;
1523
1524	JOT(8, "VIDIOC_REQBUFS\n");
1525
1526	if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
1527				sizeof(struct v4l2_requestbuffers))) {
1528		POUT;
1529		return -EFAULT;
1530	}
1531
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;
1537	}
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;
1551	}
1552	peasycap->frame_buffer_many = nbuffers;
1553
1554	if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
1555				sizeof(struct v4l2_requestbuffers))) {
1556		POUT;
1557		return -EFAULT;
1558	}
1559	break;
1560}
1561/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1562case VIDIOC_QUERYBUF: {
1563	static __u32 index;
1564	static struct v4l2_buffer v4l2_buffer;
1565
1566	JOT(8, "VIDIOC_QUERYBUF\n");
1567
1568	if (peasycap->video_eof) {
1569		JOT(8, "returning -1 because  %i=video_eof\n", \
1570							peasycap->video_eof);
1571		return -1;
1572	}
1573
1574	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1575					sizeof(struct v4l2_buffer))) {
1576		POUT;
1577		return -EFAULT;
1578	}
1579
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;
1596
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);
1608
1609	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1610					sizeof(struct v4l2_buffer))) {
1611		POUT;
1612		return -EFAULT;
1613	}
1614	break;
1615}
1616/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1617case VIDIOC_QBUF: {
1618	static struct v4l2_buffer v4l2_buffer;
1619
1620	JOT(8, "VIDIOC_QBUF\n");
1621
1622	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1623					sizeof(struct v4l2_buffer))) {
1624		POUT;
1625		return -EFAULT;
1626	}
1627
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;
1636
1637	peasycap->done[v4l2_buffer.index]   = 0;
1638	peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
1639
1640	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1641					sizeof(struct v4l2_buffer))) {
1642		POUT;
1643		return -EFAULT;
1644	}
1645
1646	JOT(8, ".....   user queueing frame buffer %i\n", \
1647						(int)v4l2_buffer.index);
1648
1649	peasycap->frame_lock = 0;
1650
1651	break;
1652}
1653/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1654case VIDIOC_DQBUF:
1655	{
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;
1666
1667	JOT(8, "VIDIOC_DQBUF\n");
1668
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;
1674	}
1675
1676	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
1677					sizeof(struct v4l2_buffer))) {
1678		POUT;
1679		return -EFAULT;
1680	}
1681
1682	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1683		return -EINVAL;
1684
1685	if (!peasycap->video_isoc_streaming) {
1686		JOT(16, "returning -EIO because video urbs not streaming\n");
1687		return -EIO;
1688	}
1689/*---------------------------------------------------------------------------*/
1690/*
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
1694 */
1695/*---------------------------------------------------------------------------*/
1696
1697	if (!peasycap->polled) {
1698		if (-EIO == easycap_dqbuf(peasycap, 0))
1699			return -EIO;
1700	} else {
1701		if (peasycap->video_eof)
1702			return -EIO;
1703	}
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]);
1707	}
1708	peasycap->polled = 0;
1709
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;
1721		}
1722	}
1723
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;
1735
1736#if defined(AUDIOTIME)
1737	if (!peasycap->timeval0.tv_sec) {
1738		timeval0 = timeval;
1739		timeval1 = timeval;
1740		timeval2 = timeval;
1741		dnbydt = 192000;
1742
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);
1756
1757		above = sdr.quotient + timeval1.tv_usec - 350000;
1758
1759		below = 1000000;
1760		sdr = signed_div(above, below);
1761		timeval2.tv_usec = sdr.remainder;
1762		timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
1763	}
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;
1773
1774		SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
1775	}
1776#endif /*AUDIOTIME*/
1777
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;
1783
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);
1795
1796	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
1797						sizeof(struct v4l2_buffer))) {
1798		POUT;
1799		return -EFAULT;
1800	}
1801
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");
1809		}
1810	}
1811	break;
1812}
1813/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1814/*---------------------------------------------------------------------------*/
1815/*
1816 *  AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED;
1817 *  VIDEO URBS HAVE NOT.
1818 */
1819/*---------------------------------------------------------------------------*/
1820case VIDIOC_STREAMON: {
1821	static int i;
1822
1823	JOT(8, "VIDIOC_STREAMON\n");
1824
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;
1831	}
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;
1838}
1839/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1840case VIDIOC_STREAMOFF: {
1841	JOT(8, "VIDIOC_STREAMOFF\n");
1842
1843	if ((struct usb_device *)NULL == peasycap->pusb_device) {
1844		SAY("ERROR: peasycap->pusb_device is NULL\n");
1845		return -EFAULT;
1846	}
1847
1848	peasycap->video_idle = 1;
1849	peasycap->audio_idle = 1;  peasycap->timeval0.tv_sec = 0;
1850/*---------------------------------------------------------------------------*/
1851/*
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.
1854 */
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;
1861}
1862/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1863case VIDIOC_G_PARM: {
1864	static struct v4l2_streamparm v4l2_streamparm;
1865
1866	JOT(8, "VIDIOC_G_PARM\n");
1867
1868	if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \
1869					sizeof(struct v4l2_streamparm))) {
1870		POUT;
1871		return -EFAULT;
1872	}
1873
1874	if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1875		POUT;
1876		return -EINVAL;
1877	}
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;
1888	}
1889	break;
1890}
1891/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1892case VIDIOC_S_PARM: {
1893	JOT(8, "VIDIOC_S_PARM unsupported\n");
1894	return -EINVAL;
1895}
1896/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1897case VIDIOC_G_AUDIO: {
1898	JOT(8, "VIDIOC_G_AUDIO unsupported\n");
1899	return -EINVAL;
1900}
1901/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1902case VIDIOC_S_AUDIO: {
1903	JOT(8, "VIDIOC_S_AUDIO unsupported\n");
1904	return -EINVAL;
1905}
1906/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1907case VIDIOC_S_TUNER: {
1908	JOT(8, "VIDIOC_S_TUNER unsupported\n");
1909	return -EINVAL;
1910}
1911/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1912case VIDIOC_G_FBUF:
1913case VIDIOC_S_FBUF:
1914case VIDIOC_OVERLAY: {
1915	JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
1916	return -EINVAL;
1917}
1918/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1919case VIDIOC_G_TUNER: {
1920	JOT(8, "VIDIOC_G_TUNER unsupported\n");
1921	return -EINVAL;
1922}
1923case VIDIOC_G_FREQUENCY:
1924case VIDIOC_S_FREQUENCY: {
1925	JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
1926	return -EINVAL;
1927}
1928/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1929default: {
1930	JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
1931	explain_ioctl(cmd);
1932	POUT;
1933	return -ENOIOCTLCMD;
1934}
1935}
1936return 0;
1937}
1938
1939long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1940{
1941	struct inode *inode = file->f_dentry->d_inode;
1942	long ret;
1943
1944	lock_kernel();
1945	ret = easycap_ioctl_bkl(inode, file, cmd, arg);
1946	unlock_kernel();
1947
1948	return ret;
1949}
1950
1951/*--------------------------------------------------------------------------*/
1952static int easysnd_ioctl_bkl(struct inode *inode, struct file *file,
1953			     unsigned int cmd, unsigned long arg)
1954{
1955struct easycap *peasycap;
1956struct usb_device *p;
1957
1958peasycap = file->private_data;
1959if (NULL == peasycap) {
1960	SAY("ERROR:  peasycap is NULL.\n");
1961	return -1;
1962}
1963p = peasycap->pusb_device;
1964/*---------------------------------------------------------------------------*/
1965switch (cmd) {
1966case SNDCTL_DSP_GETCAPS: {
1967	int caps;
1968	JOT(8, "SNDCTL_DSP_GETCAPS\n");
1969
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*/
1981
1982	if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int)))
1983		return -EFAULT;
1984	break;
1985}
1986case SNDCTL_DSP_GETFMTS: {
1987	int incoming;
1988	JOT(8, "SNDCTL_DSP_GETFMTS\n");
1989
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*/
2001
2002	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2003		return -EFAULT;
2004	break;
2005}
2006case 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);
2012
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*/
2024
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 ;
2033	}
2034	break;
2035}
2036case 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);
2042
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*/
2054
2055	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2056		return -EFAULT;
2057	break;
2058}
2059case 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);
2065
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*/
2077
2078	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2079		return -EFAULT;
2080	break;
2081}
2082case 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);
2088
2089	incoming = PCM_ENABLE_INPUT;
2090	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
2091		return -EFAULT;
2092	break;
2093}
2094case 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);
2103	;
2104	;
2105	;
2106	;
2107	break;
2108}
2109case 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;
2119}
2120case SNDCTL_DSP_GETISPACE: {
2121	struct audio_buf_info audio_buf_info;
2122
2123	JOT(8, "SNDCTL_DSP_GETISPACE\n");
2124
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;
2129
2130	if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
2131								sizeof(int)))
2132		return -EFAULT;
2133	break;
2134}
2135default: {
2136	JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2137	POUT;
2138	return -ENOIOCTLCMD;
2139}
2140}
2141return 0;
2142}
2143
2144long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2145{
2146	struct inode *inode = file->f_dentry->d_inode;
2147	long ret;
2148
2149	lock_kernel();
2150	ret = easysnd_ioctl_bkl(inode, file, cmd, arg);
2151	unlock_kernel();
2152
2153	return ret;
2154}
2155
2156/*****************************************************************************/
2157int explain_ioctl(__u32 wot)
2158{
2159int k;
2160/*---------------------------------------------------------------------------*/
2161/*
2162 *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
2163 *  SHELL SCRIPT:
2164 *  #
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
2172 *  #
2173 * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY.
2174 *
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
2184 *  #
2185 */
2186/*---------------------------------------------------------------------------*/
2187static 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
2374
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, ""}
2394};
2395
2396static struct mess mess1[] = \
2397{
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, ""}
2480};
2481
2482k = 0;
2483while (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;
2488	}
2489	k++;
2490}
2491JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot);
2492
2493k = 0;
2494while (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;
2499	}
2500	k++;
2501}
2502JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot);
2503return -1;
2504}
2505/*****************************************************************************/
2506int explain_cid(__u32 wot)
2507{
2508int k;
2509/*---------------------------------------------------------------------------*/
2510/*
2511 *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
2512 *  SHELL SCRIPT:
2513 *  #
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
2521 *  #
2522 */
2523/*---------------------------------------------------------------------------*/
2524static struct mess
2525{
2526__u32 command;
2527char  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, ""}
2668};
2669
2670k = 0;
2671while (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;
2676	}
2677	k++;
2678}
2679JOT(8, "cid 0x%08X is not in videodev2.h\n", wot);
2680return -1;
2681}
2682/*****************************************************************************/
2683