1
/******************************************************************************
5
******************************************************************************/
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>
30
#include "easycap_debug.h"
31
#include "easycap_standard.h"
32
#include "easycap_ioctl.h"
34
/*--------------------------------------------------------------------------*/
36
* UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
38
* peasycap->standard_offset
39
* peasycap->inputset[peasycap->input].standard_offset
45
/*---------------------------------------------------------------------------*/
46
int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
48
struct easycap_standard const *peasycap_standard;
51
unsigned int itwas, isnow;
54
if (NULL == peasycap) {
55
SAY("ERROR: peasycap is NULL\n");
58
if ((struct usb_device *)NULL == peasycap->pusb_device) {
59
SAM("ERROR: peasycap->pusb_device is NULL\n");
62
peasycap_standard = &easycap_standard[0];
63
while (0xFFFF != peasycap_standard->mask) {
64
if (std_id == peasycap_standard->v4l2_standard.id)
68
if (0xFFFF == peasycap_standard->mask) {
69
peasycap_standard = &easycap_standard[0];
70
while (0xFFFF != peasycap_standard->mask) {
71
if (std_id & peasycap_standard->v4l2_standard.id)
76
if (0xFFFF == peasycap_standard->mask) {
77
SAM("ERROR: 0x%08X=std_id: standard not found\n", \
78
(unsigned int)std_id);
81
SAM("selected standard: %s\n", \
82
&(peasycap_standard->v4l2_standard.name[0]));
83
if (peasycap->standard_offset == \
84
(int)(peasycap_standard - &easycap_standard[0])) {
85
SAM("requested standard already in effect\n");
88
peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
89
for (k = 0; k < INPUT_MANY; k++) {
90
if (!peasycap->inputset[k].standard_offset_ok) {
91
peasycap->inputset[k].standard_offset = \
92
peasycap->standard_offset;
95
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
96
peasycap->inputset[peasycap->input].standard_offset = \
97
peasycap->standard_offset;
98
peasycap->inputset[peasycap->input].standard_offset_ok = 1;
100
JOM(8, "%i=peasycap->input\n", peasycap->input);
101
peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
102
peasycap_standard->v4l2_standard.frameperiod.numerator;
103
switch (peasycap->fps) {
106
peasycap->ntsc = true;
111
peasycap->ntsc = false;
115
SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
119
JOM(8, "%i frames-per-second\n", peasycap->fps);
120
if (0x8000 & peasycap_standard->mask) {
122
peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
123
peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
126
peasycap->usec = 1000000 / (2 * peasycap->fps);
127
peasycap->tolerate = 1000 * (25 / peasycap->fps);
129
if (peasycap->video_isoc_streaming) {
131
kill_video_urbs(peasycap);
134
/*--------------------------------------------------------------------------*/
136
* SAA7113H DATASHEET PAGE 44, TABLE 42
138
/*--------------------------------------------------------------------------*/
139
need = 0; itwas = 0; reg = 0x00; set = 0x00;
140
switch (peasycap_standard->mask & 0x000F) {
142
reg = 0x0A; set = 0x95;
143
ir = read_saa(peasycap->pusb_device, reg);
145
SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
147
itwas = (unsigned int)ir;
148
rc = write_saa(peasycap->pusb_device, reg, set);
150
SAM("ERROR: failed to set SAA register " \
151
"0x%02X to 0x%02X for JP standard\n", reg, set);
153
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
155
JOM(8, "SAA register 0x%02X changed " \
156
"to 0x%02X\n", reg, isnow);
158
JOM(8, "SAA register 0x%02X changed " \
159
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
162
reg = 0x0B; set = 0x48;
163
ir = read_saa(peasycap->pusb_device, reg);
165
SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
167
itwas = (unsigned int)ir;
168
rc = write_saa(peasycap->pusb_device, reg, set);
170
SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \
171
"for JP standard\n", reg, set);
173
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
175
JOM(8, "SAA register 0x%02X changed " \
176
"to 0x%02X\n", reg, isnow);
178
JOM(8, "SAA register 0x%02X changed " \
179
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
181
/*--------------------------------------------------------------------------*/
183
* NOTE: NO break HERE: RUN ON TO NEXT CASE
185
/*--------------------------------------------------------------------------*/
189
reg = 0x0E; set = 0x01; need = 1; break;
193
reg = 0x0E; set = 0x11; need = 1; break;
197
reg = 0x0E; set = 0x21; need = 1; break;
201
reg = 0x0E; set = 0x31; need = 1; break;
204
reg = 0x0E; set = 0x51; need = 1; break;
209
/*--------------------------------------------------------------------------*/
211
ir = read_saa(peasycap->pusb_device, reg);
213
SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
215
itwas = (unsigned int)ir;
216
rc = write_saa(peasycap->pusb_device, reg, set);
217
if (0 != write_saa(peasycap->pusb_device, reg, set)) {
218
SAM("ERROR: failed to set SAA register " \
219
"0x%02X to 0x%02X for table 42\n", reg, set);
221
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
223
JOM(8, "SAA register 0x%02X changed " \
224
"to 0x%02X\n", reg, isnow);
226
JOM(8, "SAA register 0x%02X changed " \
227
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
230
/*--------------------------------------------------------------------------*/
232
* SAA7113H DATASHEET PAGE 41
234
/*--------------------------------------------------------------------------*/
236
ir = read_saa(peasycap->pusb_device, reg);
238
SAM("ERROR: failed to read SAA register 0x%02X " \
239
"so cannot reset\n", reg);
241
itwas = (unsigned int)ir;
242
if (peasycap_standard->mask & 0x0001)
245
set = itwas & ~0x40 ;
246
rc = write_saa(peasycap->pusb_device, reg, set);
248
SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
251
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
253
JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
256
JOM(8, "SAA register 0x%02X changed " \
257
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
260
/*--------------------------------------------------------------------------*/
262
* SAA7113H DATASHEET PAGE 51, TABLE 57
264
/*---------------------------------------------------------------------------*/
266
ir = read_saa(peasycap->pusb_device, reg);
268
SAM("ERROR: failed to read SAA register 0x%02X " \
269
"so cannot reset\n", reg);
271
itwas = (unsigned int)ir;
272
if (peasycap_standard->mask & 0x0001)
275
set = itwas & ~0x80 ;
276
rc = write_saa(peasycap->pusb_device, reg, set);
278
SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
281
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
283
JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
286
JOM(8, "SAA register 0x%02X changed " \
287
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
290
/*--------------------------------------------------------------------------*/
292
* SAA7113H DATASHEET PAGE 53, TABLE 66
294
/*--------------------------------------------------------------------------*/
296
ir = read_saa(peasycap->pusb_device, reg);
298
SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
299
itwas = (unsigned int)ir;
300
if (peasycap_standard->mask & 0x0001)
304
if (0 != write_saa(peasycap->pusb_device, reg, set))
305
SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
308
isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
310
JOM(8, "SAA register 0x%02X changed "
311
"to 0x%02X\n", reg, isnow);
313
JOM(8, "SAA register 0x%02X changed "
314
"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
316
if (true == resubmit)
317
submit_video_urbs(peasycap);
320
/*****************************************************************************/
321
/*--------------------------------------------------------------------------*/
323
* THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
324
* A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
326
* PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
327
* THIS ROUTINE UPDATES THE FOLLOWING:
328
* peasycap->format_offset
329
* peasycap->inputset[peasycap->input].format_offset
330
* peasycap->pixelformat
333
* peasycap->bytesperpixel
334
* peasycap->byteswaporder
335
* peasycap->decimatepixel
336
* peasycap->frame_buffer_used
337
* peasycap->videofieldamount
338
* peasycap->offerfields
340
* IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
341
* IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
342
* ERRORS RETURN A NEGATIVE NUMBER.
344
/*--------------------------------------------------------------------------*/
345
int adjust_format(struct easycap *peasycap, \
346
__u32 width, __u32 height, __u32 pixelformat, int field, bool try)
348
struct easycap_format *peasycap_format, *peasycap_best_format;
350
struct usb_device *p;
351
int miss, multiplier, best, k;
352
char bf[5], fo[32], *pc;
356
if (NULL == peasycap) {
357
SAY("ERROR: peasycap is NULL\n");
360
if (0 > peasycap->standard_offset) {
361
JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
364
p = peasycap->pusb_device;
365
if ((struct usb_device *)NULL == p) {
366
SAM("ERROR: peaycap->pusb_device is NULL\n");
371
memcpy((void *)pc, (void *)(&uc), 4);
373
mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
374
SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
375
width, height, pc, pixelformat, field, mask);
377
case V4L2_FIELD_ANY: {
378
strcpy(&fo[0], "V4L2_FIELD_ANY ");
381
case V4L2_FIELD_NONE: {
382
strcpy(&fo[0], "V4L2_FIELD_NONE");
385
case V4L2_FIELD_TOP: {
386
strcpy(&fo[0], "V4L2_FIELD_TOP");
389
case V4L2_FIELD_BOTTOM: {
390
strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
393
case V4L2_FIELD_INTERLACED: {
394
strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
397
case V4L2_FIELD_SEQ_TB: {
398
strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
401
case V4L2_FIELD_SEQ_BT: {
402
strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
405
case V4L2_FIELD_ALTERNATE: {
406
strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
409
case V4L2_FIELD_INTERLACED_TB: {
410
strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
413
case V4L2_FIELD_INTERLACED_BT: {
414
strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
418
strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN ");
422
SAM("sought: %s\n", &fo[0]);
423
if (V4L2_FIELD_ANY == field) {
424
field = V4L2_FIELD_NONE;
425
SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
427
peasycap_best_format = (struct easycap_format *)NULL;
428
peasycap_format = &easycap_format[0];
429
while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
430
JOM(16, ".> %i %i 0x%08X %ix%i\n", \
431
peasycap_format->mask & 0x01,
432
peasycap_format->v4l2_format.fmt.pix.field,
433
peasycap_format->v4l2_format.fmt.pix.pixelformat,
434
peasycap_format->v4l2_format.fmt.pix.width,
435
peasycap_format->v4l2_format.fmt.pix.height);
437
if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
438
(peasycap_format->v4l2_format.fmt.pix.field == field) && \
439
(peasycap_format->v4l2_format.fmt.pix.pixelformat == \
441
(peasycap_format->v4l2_format.fmt.pix.width == width) && \
442
(peasycap_format->v4l2_format.fmt.pix.height == height)) {
443
peasycap_best_format = peasycap_format;
448
if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
449
SAM("cannot do: %ix%i with standard mask 0x%02X\n", \
450
width, height, mask);
451
peasycap_format = &easycap_format[0]; best = -1;
452
while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
453
if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
454
(peasycap_format->v4l2_format.fmt.pix\
455
.field == field) && \
456
(peasycap_format->v4l2_format.fmt.pix\
457
.pixelformat == pixelformat)) {
458
miss = abs(peasycap_format->\
459
v4l2_format.fmt.pix.width - width);
460
if ((best > miss) || (best < 0)) {
462
peasycap_best_format = peasycap_format;
470
SAM("cannot do %ix... with standard mask 0x%02X\n", \
472
SAM("cannot do ...x%i with standard mask 0x%02X\n", \
474
SAM(" %ix%i unmatched\n", width, height);
475
return peasycap->format_offset;
478
if ((struct easycap_format *)NULL == peasycap_best_format) {
479
SAM("MISTAKE: peasycap_best_format is NULL");
482
peasycap_format = peasycap_best_format;
484
/*...........................................................................*/
486
return (int)(peasycap_best_format - &easycap_format[0]);
487
/*...........................................................................*/
490
SAM("MISTAKE: true==try where is should be false\n");
493
SAM("actioning: %ix%i %s\n", \
494
peasycap_format->v4l2_format.fmt.pix.width, \
495
peasycap_format->v4l2_format.fmt.pix.height,
496
&peasycap_format->name[0]);
497
peasycap->height = peasycap_format->v4l2_format.fmt.pix.height;
498
peasycap->width = peasycap_format->v4l2_format.fmt.pix.width;
499
peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat;
500
peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
503
for (k = 0; k < INPUT_MANY; k++) {
504
if (!peasycap->inputset[k].format_offset_ok) {
505
peasycap->inputset[k].format_offset = \
506
peasycap->format_offset;
509
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
510
peasycap->inputset[peasycap->input].format_offset = \
511
peasycap->format_offset;
512
peasycap->inputset[peasycap->input].format_offset_ok = 1;
514
JOM(8, "%i=peasycap->input\n", peasycap->input);
518
peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
519
if (0x0100 & peasycap_format->mask)
520
peasycap->byteswaporder = true;
522
peasycap->byteswaporder = false;
523
if (0x0200 & peasycap_format->mask)
527
if (0x0800 & peasycap_format->mask)
528
peasycap->decimatepixel = true;
530
peasycap->decimatepixel = false;
531
if (0x1000 & peasycap_format->mask)
532
peasycap->offerfields = true;
534
peasycap->offerfields = false;
535
if (true == peasycap->decimatepixel)
539
peasycap->videofieldamount = multiplier * peasycap->width * \
540
multiplier * peasycap->height;
541
peasycap->frame_buffer_used = peasycap->bytesperpixel * \
542
peasycap->width * peasycap->height;
543
if (peasycap->video_isoc_streaming) {
545
kill_video_urbs(peasycap);
548
/*---------------------------------------------------------------------------*/
552
/*---------------------------------------------------------------------------*/
553
if (0 == (0x01 & peasycap_format->mask)) {
554
if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
556
peasycap_format->v4l2_format.fmt.pix.height)) || \
558
peasycap_format->v4l2_format.fmt.pix.width) && \
560
peasycap_format->v4l2_format.fmt.pix.height))) {
561
if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
562
SAM("ERROR: set_resolution() failed\n");
565
} else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \
566
(576 == peasycap_format->v4l2_format.fmt.pix.height)) {
567
if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
568
SAM("ERROR: set_resolution() failed\n");
571
} else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
573
peasycap_format->v4l2_format.fmt.pix.height)) || \
575
peasycap_format->v4l2_format.fmt.pix.width) && \
577
peasycap_format->v4l2_format.fmt.pix.height))) {
578
if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
579
SAM("ERROR: set_resolution() failed\n");
583
SAM("MISTAKE: bad format, cannot set resolution\n");
586
/*---------------------------------------------------------------------------*/
590
/*---------------------------------------------------------------------------*/
592
if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \
594
peasycap_format->v4l2_format.fmt.pix.height)) || \
596
peasycap_format->v4l2_format.fmt.pix.width) && \
598
peasycap_format->v4l2_format.fmt.pix.height))) {
599
if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
600
SAM("ERROR: set_resolution() failed\n");
603
} else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
605
peasycap_format->v4l2_format.fmt.pix.height)) || \
607
peasycap_format->v4l2_format.fmt.pix.width) && \
609
peasycap_format->v4l2_format.fmt.pix.height))) {
610
if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
611
SAM("ERROR: set_resolution() failed\n");
615
SAM("MISTAKE: bad format, cannot set resolution\n");
619
/*---------------------------------------------------------------------------*/
620
if (true == resubmit)
621
submit_video_urbs(peasycap);
622
return (int)(peasycap_best_format - &easycap_format[0]);
624
/*****************************************************************************/
625
int adjust_brightness(struct easycap *peasycap, int value)
630
if (NULL == peasycap) {
631
SAY("ERROR: peasycap is NULL\n");
634
if ((struct usb_device *)NULL == peasycap->pusb_device) {
635
SAM("ERROR: peasycap->pusb_device is NULL\n");
639
while (0xFFFFFFFF != easycap_control[i1].id) {
640
if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
641
if ((easycap_control[i1].minimum > value) || \
642
(easycap_control[i1].maximum < value))
643
value = easycap_control[i1].default_value;
645
if ((easycap_control[i1].minimum <= peasycap->brightness) && \
646
(easycap_control[i1].maximum >= \
647
peasycap->brightness)) {
648
if (peasycap->brightness == value) {
649
SAM("unchanged brightness at 0x%02X\n", \
654
peasycap->brightness = value;
655
for (k = 0; k < INPUT_MANY; k++) {
656
if (!peasycap->inputset[k].brightness_ok)
657
peasycap->inputset[k].brightness = \
658
peasycap->brightness;
660
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
661
peasycap->inputset[peasycap->input].brightness = \
662
peasycap->brightness;
663
peasycap->inputset[peasycap->input].brightness_ok = 1;
665
JOM(8, "%i=peasycap->input\n", peasycap->input);
666
mood = 0x00FF & (unsigned int)peasycap->brightness;
667
if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
668
SAM("adjusting brightness to 0x%02X\n", mood);
671
SAM("WARNING: failed to adjust brightness " \
672
"to 0x%02X\n", mood);
679
SAM("WARNING: failed to adjust brightness: control not found\n");
682
/*****************************************************************************/
683
int adjust_contrast(struct easycap *peasycap, int value)
688
if (NULL == peasycap) {
689
SAY("ERROR: peasycap is NULL\n");
692
if ((struct usb_device *)NULL == peasycap->pusb_device) {
693
SAM("ERROR: peasycap->pusb_device is NULL\n");
697
while (0xFFFFFFFF != easycap_control[i1].id) {
698
if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
699
if ((easycap_control[i1].minimum > value) || \
700
(easycap_control[i1].maximum < value))
701
value = easycap_control[i1].default_value;
705
if ((easycap_control[i1].minimum <= peasycap->contrast) && \
706
(easycap_control[i1].maximum >= \
707
peasycap->contrast)) {
708
if (peasycap->contrast == value) {
709
SAM("unchanged contrast at 0x%02X\n", value);
713
peasycap->contrast = value;
714
for (k = 0; k < INPUT_MANY; k++) {
715
if (!peasycap->inputset[k].contrast_ok) {
716
peasycap->inputset[k].contrast = \
720
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
721
peasycap->inputset[peasycap->input].contrast = \
723
peasycap->inputset[peasycap->input].contrast_ok = 1;
725
JOM(8, "%i=peasycap->input\n", peasycap->input);
726
mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
727
if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
728
SAM("adjusting contrast to 0x%02X\n", mood);
731
SAM("WARNING: failed to adjust contrast to " \
739
SAM("WARNING: failed to adjust contrast: control not found\n");
742
/*****************************************************************************/
743
int adjust_saturation(struct easycap *peasycap, int value)
748
if (NULL == peasycap) {
749
SAY("ERROR: peasycap is NULL\n");
752
if ((struct usb_device *)NULL == peasycap->pusb_device) {
753
SAM("ERROR: peasycap->pusb_device is NULL\n");
757
while (0xFFFFFFFF != easycap_control[i1].id) {
758
if (V4L2_CID_SATURATION == easycap_control[i1].id) {
759
if ((easycap_control[i1].minimum > value) || \
760
(easycap_control[i1].maximum < value))
761
value = easycap_control[i1].default_value;
764
if ((easycap_control[i1].minimum <= peasycap->saturation) && \
765
(easycap_control[i1].maximum >= \
766
peasycap->saturation)) {
767
if (peasycap->saturation == value) {
768
SAM("unchanged saturation at 0x%02X\n", \
773
peasycap->saturation = value;
774
for (k = 0; k < INPUT_MANY; k++) {
775
if (!peasycap->inputset[k].saturation_ok) {
776
peasycap->inputset[k].saturation = \
777
peasycap->saturation;
780
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
781
peasycap->inputset[peasycap->input].saturation = \
782
peasycap->saturation;
783
peasycap->inputset[peasycap->input].saturation_ok = 1;
785
JOM(8, "%i=peasycap->input\n", peasycap->input);
786
mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
787
if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
788
SAM("adjusting saturation to 0x%02X\n", mood);
791
SAM("WARNING: failed to adjust saturation to " \
799
SAM("WARNING: failed to adjust saturation: control not found\n");
802
/*****************************************************************************/
803
int adjust_hue(struct easycap *peasycap, int value)
808
if (NULL == peasycap) {
809
SAY("ERROR: peasycap is NULL\n");
812
if ((struct usb_device *)NULL == peasycap->pusb_device) {
813
SAM("ERROR: peasycap->pusb_device is NULL\n");
817
while (0xFFFFFFFF != easycap_control[i1].id) {
818
if (V4L2_CID_HUE == easycap_control[i1].id) {
819
if ((easycap_control[i1].minimum > value) || \
820
(easycap_control[i1].maximum < value))
821
value = easycap_control[i1].default_value;
823
if ((easycap_control[i1].minimum <= peasycap->hue) && \
824
(easycap_control[i1].maximum >= \
826
if (peasycap->hue == value) {
827
SAM("unchanged hue at 0x%02X\n", value);
831
peasycap->hue = value;
832
for (k = 0; k < INPUT_MANY; k++) {
833
if (!peasycap->inputset[k].hue_ok)
834
peasycap->inputset[k].hue = peasycap->hue;
836
if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
837
peasycap->inputset[peasycap->input].hue = \
839
peasycap->inputset[peasycap->input].hue_ok = 1;
841
JOM(8, "%i=peasycap->input\n", peasycap->input);
842
i2 = peasycap->hue - 128;
843
mood = 0x00FF & ((int) i2);
844
if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
845
SAM("adjusting hue to 0x%02X\n", mood);
848
SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
855
SAM("WARNING: failed to adjust hue: control not found\n");
858
/*****************************************************************************/
859
int adjust_volume(struct easycap *peasycap, int value)
864
if (NULL == peasycap) {
865
SAY("ERROR: peasycap is NULL\n");
868
if ((struct usb_device *)NULL == peasycap->pusb_device) {
869
SAM("ERROR: peasycap->pusb_device is NULL\n");
873
while (0xFFFFFFFF != easycap_control[i1].id) {
874
if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
875
if ((easycap_control[i1].minimum > value) || \
876
(easycap_control[i1].maximum < value))
877
value = easycap_control[i1].default_value;
878
if ((easycap_control[i1].minimum <= peasycap->volume) && \
879
(easycap_control[i1].maximum >= \
881
if (peasycap->volume == value) {
882
SAM("unchanged volume at 0x%02X\n", value);
886
peasycap->volume = value;
887
mood = (16 > peasycap->volume) ? 16 : \
888
((31 < peasycap->volume) ? 31 : \
889
(__s8) peasycap->volume);
890
if (!audio_gainset(peasycap->pusb_device, mood)) {
891
SAM("adjusting volume to 0x%02X\n", mood);
894
SAM("WARNING: failed to adjust volume to " \
902
SAM("WARNING: failed to adjust volume: control not found\n");
905
/*****************************************************************************/
906
/*---------------------------------------------------------------------------*/
908
* AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
909
* usb_set_interface(peasycap->pusb_device, \
910
* peasycap->audio_interface, \
911
* peasycap->audio_altsetting_off);
912
* HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
913
* -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT
914
* THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
916
/*---------------------------------------------------------------------------*/
917
int adjust_mute(struct easycap *peasycap, int value)
921
if (NULL == peasycap) {
922
SAY("ERROR: peasycap is NULL\n");
925
if ((struct usb_device *)NULL == peasycap->pusb_device) {
926
SAM("ERROR: peasycap->pusb_device is NULL\n");
930
while (0xFFFFFFFF != easycap_control[i1].id) {
931
if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
932
peasycap->mute = value;
933
switch (peasycap->mute) {
935
peasycap->audio_idle = 1;
936
peasycap->timeval0.tv_sec = 0;
937
SAM("adjusting mute: %i=peasycap->audio_idle\n", \
938
peasycap->audio_idle);
942
peasycap->audio_idle = 0;
943
SAM("adjusting mute: %i=peasycap->audio_idle\n", \
944
peasycap->audio_idle);
952
SAM("WARNING: failed to adjust mute: control not found\n");
955
/*****************************************************************************/
956
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
957
#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
958
(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
960
easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
961
return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg);
963
#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
964
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
965
/*---------------------------------------------------------------------------*/
967
easycap_ioctl(struct inode *inode, struct file *file,
968
unsigned int cmd, unsigned long arg)
970
struct easycap *peasycap;
971
struct usb_device *p;
975
SAY("ERROR: file is NULL\n");
978
peasycap = file->private_data;
979
if (NULL == peasycap) {
980
SAY("ERROR: peasycap is NULL\n");
983
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
984
SAY("ERROR: bad peasycap\n");
987
p = peasycap->pusb_device;
989
SAM("ERROR: peasycap->pusb_device is NULL\n");
992
kd = isdongle(peasycap);
993
if (0 <= kd && DONGLE_MANY > kd) {
994
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
995
SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd);
998
JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
999
/*---------------------------------------------------------------------------*/
1001
* MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
1002
* IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
1003
* IF NECESSARY, BAIL OUT.
1005
/*---------------------------------------------------------------------------*/
1006
if (kd != isdongle(peasycap))
1007
return -ERESTARTSYS;
1009
SAY("ERROR: file is NULL\n");
1010
mutex_unlock(&easycap_dongle[kd].mutex_video);
1011
return -ERESTARTSYS;
1013
peasycap = file->private_data;
1014
if (NULL == peasycap) {
1015
SAY("ERROR: peasycap is NULL\n");
1016
mutex_unlock(&easycap_dongle[kd].mutex_video);
1017
return -ERESTARTSYS;
1019
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1020
SAY("ERROR: bad peasycap\n");
1021
mutex_unlock(&easycap_dongle[kd].mutex_video);
1024
p = peasycap->pusb_device;
1025
if (NULL == peasycap->pusb_device) {
1026
SAM("ERROR: peasycap->pusb_device is NULL\n");
1027
mutex_unlock(&easycap_dongle[kd].mutex_video);
1028
return -ERESTARTSYS;
1031
/*---------------------------------------------------------------------------*/
1033
* IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1034
* ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
1036
/*---------------------------------------------------------------------------*/
1037
return -ERESTARTSYS;
1039
/*---------------------------------------------------------------------------*/
1041
case VIDIOC_QUERYCAP: {
1042
struct v4l2_capability v4l2_capability;
1043
char version[16], *p1, *p2;
1047
JOM(8, "VIDIOC_QUERYCAP\n");
1049
if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
1050
SAM("ERROR: bad driver version string\n");
1051
mutex_unlock(&easycap_dongle[kd].mutex_video);
1054
strcpy(&version[0], EASYCAP_DRIVER_VERSION);
1055
for (i = 0; i < 3; i++)
1057
p2 = &version[0]; i = 0;
1060
while (*p2 && ('.' != *p2))
1065
rc = (int) strict_strtol(p1, 10, &lng);
1067
SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \
1069
mutex_unlock(&easycap_dongle[kd].mutex_video);
1077
memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
1078
strlcpy(&v4l2_capability.driver[0], "easycap", \
1079
sizeof(v4l2_capability.driver));
1081
v4l2_capability.capabilities = \
1082
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
1083
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE;
1085
v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
1086
JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
1088
strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
1089
sizeof(v4l2_capability.card));
1091
if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\
1092
sizeof(v4l2_capability.bus_info)) < 0) {
1093
strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
1094
sizeof(v4l2_capability.bus_info));
1095
JOM(8, "%s=v4l2_capability.bus_info\n", \
1096
&v4l2_capability.bus_info[0]);
1098
if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
1099
sizeof(struct v4l2_capability))) {
1100
mutex_unlock(&easycap_dongle[kd].mutex_video);
1105
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1106
case VIDIOC_ENUMINPUT: {
1107
struct v4l2_input v4l2_input;
1110
JOM(8, "VIDIOC_ENUMINPUT\n");
1112
if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
1113
sizeof(struct v4l2_input))) {
1114
mutex_unlock(&easycap_dongle[kd].mutex_video);
1118
index = v4l2_input.index;
1119
memset(&v4l2_input, 0, sizeof(struct v4l2_input));
1123
v4l2_input.index = index;
1124
strcpy(&v4l2_input.name[0], "CVBS0");
1125
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1126
v4l2_input.audioset = 0x01;
1127
v4l2_input.tuner = 0;
1128
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1130
v4l2_input.status = 0;
1131
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1135
v4l2_input.index = index;
1136
strcpy(&v4l2_input.name[0], "CVBS1");
1137
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1138
v4l2_input.audioset = 0x01;
1139
v4l2_input.tuner = 0;
1140
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1142
v4l2_input.status = 0;
1143
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1147
v4l2_input.index = index;
1148
strcpy(&v4l2_input.name[0], "CVBS2");
1149
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1150
v4l2_input.audioset = 0x01;
1151
v4l2_input.tuner = 0;
1152
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1154
v4l2_input.status = 0;
1155
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1159
v4l2_input.index = index;
1160
strcpy(&v4l2_input.name[0], "CVBS3");
1161
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1162
v4l2_input.audioset = 0x01;
1163
v4l2_input.tuner = 0;
1164
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1166
v4l2_input.status = 0;
1167
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1171
v4l2_input.index = index;
1172
strcpy(&v4l2_input.name[0], "CVBS4");
1173
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1174
v4l2_input.audioset = 0x01;
1175
v4l2_input.tuner = 0;
1176
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1178
v4l2_input.status = 0;
1179
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1183
v4l2_input.index = index;
1184
strcpy(&v4l2_input.name[0], "S-VIDEO");
1185
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1186
v4l2_input.audioset = 0x01;
1187
v4l2_input.tuner = 0;
1188
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
1190
v4l2_input.status = 0;
1191
JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1195
JOM(8, "%i=index: exhausts inputs\n", index);
1196
mutex_unlock(&easycap_dongle[kd].mutex_video);
1201
if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
1202
sizeof(struct v4l2_input))) {
1203
mutex_unlock(&easycap_dongle[kd].mutex_video);
1208
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1209
case VIDIOC_G_INPUT: {
1212
JOM(8, "VIDIOC_G_INPUT\n");
1213
index = (__u32)peasycap->input;
1214
JOM(8, "user is told: %i\n", index);
1215
if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
1216
mutex_unlock(&easycap_dongle[kd].mutex_video);
1221
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1222
case VIDIOC_S_INPUT:
1227
JOM(8, "VIDIOC_S_INPUT\n");
1229
if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
1230
mutex_unlock(&easycap_dongle[kd].mutex_video);
1234
JOM(8, "user requests input %i\n", index);
1236
if ((int)index == peasycap->input) {
1237
SAM("requested input already in effect\n");
1241
if ((0 > index) || (INPUT_MANY <= index)) {
1242
JOM(8, "ERROR: bad requested input: %i\n", index);
1243
mutex_unlock(&easycap_dongle[kd].mutex_video);
1247
rc = newinput(peasycap, (int)index);
1249
JOM(8, "newinput(.,%i) OK\n", (int)index);
1251
SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
1252
mutex_unlock(&easycap_dongle[kd].mutex_video);
1257
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1258
case VIDIOC_ENUMAUDIO: {
1259
JOM(8, "VIDIOC_ENUMAUDIO\n");
1260
mutex_unlock(&easycap_dongle[kd].mutex_video);
1263
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1264
case VIDIOC_ENUMAUDOUT: {
1265
struct v4l2_audioout v4l2_audioout;
1267
JOM(8, "VIDIOC_ENUMAUDOUT\n");
1269
if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
1270
sizeof(struct v4l2_audioout))) {
1271
mutex_unlock(&easycap_dongle[kd].mutex_video);
1275
if (0 != v4l2_audioout.index) {
1276
mutex_unlock(&easycap_dongle[kd].mutex_video);
1279
memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1280
v4l2_audioout.index = 0;
1281
strcpy(&v4l2_audioout.name[0], "Soundtrack");
1283
if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
1284
sizeof(struct v4l2_audioout))) {
1285
mutex_unlock(&easycap_dongle[kd].mutex_video);
1290
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1291
case VIDIOC_QUERYCTRL: {
1293
struct v4l2_queryctrl v4l2_queryctrl;
1295
JOM(8, "VIDIOC_QUERYCTRL\n");
1297
if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
1298
sizeof(struct v4l2_queryctrl))) {
1299
mutex_unlock(&easycap_dongle[kd].mutex_video);
1304
while (0xFFFFFFFF != easycap_control[i1].id) {
1305
if (easycap_control[i1].id == v4l2_queryctrl.id) {
1306
JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \
1307
".name\n", &easycap_control[i1].name[0], i1);
1308
memcpy(&v4l2_queryctrl, &easycap_control[i1], \
1309
sizeof(struct v4l2_queryctrl));
1314
if (0xFFFFFFFF == easycap_control[i1].id) {
1315
JOM(8, "%i=index: exhausts controls\n", i1);
1316
mutex_unlock(&easycap_dongle[kd].mutex_video);
1319
if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
1320
sizeof(struct v4l2_queryctrl))) {
1321
mutex_unlock(&easycap_dongle[kd].mutex_video);
1326
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1327
case VIDIOC_QUERYMENU: {
1328
JOM(8, "VIDIOC_QUERYMENU unsupported\n");
1329
mutex_unlock(&easycap_dongle[kd].mutex_video);
1332
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1333
case VIDIOC_G_CTRL: {
1334
struct v4l2_control *pv4l2_control;
1336
JOM(8, "VIDIOC_G_CTRL\n");
1337
pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL);
1338
if (!pv4l2_control) {
1339
SAM("ERROR: out of memory\n");
1340
mutex_unlock(&easycap_dongle[kd].mutex_video);
1343
if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \
1344
sizeof(struct v4l2_control))) {
1345
kfree(pv4l2_control);
1346
mutex_unlock(&easycap_dongle[kd].mutex_video);
1350
switch (pv4l2_control->id) {
1351
case V4L2_CID_BRIGHTNESS: {
1352
pv4l2_control->value = peasycap->brightness;
1353
JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
1356
case V4L2_CID_CONTRAST: {
1357
pv4l2_control->value = peasycap->contrast;
1358
JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
1361
case V4L2_CID_SATURATION: {
1362
pv4l2_control->value = peasycap->saturation;
1363
JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
1366
case V4L2_CID_HUE: {
1367
pv4l2_control->value = peasycap->hue;
1368
JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
1371
case V4L2_CID_AUDIO_VOLUME: {
1372
pv4l2_control->value = peasycap->volume;
1373
JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
1376
case V4L2_CID_AUDIO_MUTE: {
1377
if (1 == peasycap->mute)
1378
pv4l2_control->value = true;
1380
pv4l2_control->value = false;
1381
JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
1385
SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1387
kfree(pv4l2_control);
1388
mutex_unlock(&easycap_dongle[kd].mutex_video);
1392
if (0 != copy_to_user((void __user *)arg, pv4l2_control, \
1393
sizeof(struct v4l2_control))) {
1394
kfree(pv4l2_control);
1395
mutex_unlock(&easycap_dongle[kd].mutex_video);
1398
kfree(pv4l2_control);
1401
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1402
#if defined(VIDIOC_S_CTRL_OLD)
1403
case VIDIOC_S_CTRL_OLD: {
1404
JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
1406
#endif /*VIDIOC_S_CTRL_OLD*/
1409
struct v4l2_control v4l2_control;
1411
JOM(8, "VIDIOC_S_CTRL\n");
1413
if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
1414
sizeof(struct v4l2_control))) {
1415
mutex_unlock(&easycap_dongle[kd].mutex_video);
1419
switch (v4l2_control.id) {
1420
case V4L2_CID_BRIGHTNESS: {
1421
JOM(8, "user requests brightness %i\n", v4l2_control.value);
1422
if (0 != adjust_brightness(peasycap, v4l2_control.value))
1426
case V4L2_CID_CONTRAST: {
1427
JOM(8, "user requests contrast %i\n", v4l2_control.value);
1428
if (0 != adjust_contrast(peasycap, v4l2_control.value))
1432
case V4L2_CID_SATURATION: {
1433
JOM(8, "user requests saturation %i\n", v4l2_control.value);
1434
if (0 != adjust_saturation(peasycap, v4l2_control.value))
1438
case V4L2_CID_HUE: {
1439
JOM(8, "user requests hue %i\n", v4l2_control.value);
1440
if (0 != adjust_hue(peasycap, v4l2_control.value))
1444
case V4L2_CID_AUDIO_VOLUME: {
1445
JOM(8, "user requests volume %i\n", v4l2_control.value);
1446
if (0 != adjust_volume(peasycap, v4l2_control.value))
1450
case V4L2_CID_AUDIO_MUTE: {
1453
JOM(8, "user requests mute %i\n", v4l2_control.value);
1454
if (true == v4l2_control.value)
1459
if (0 != adjust_mute(peasycap, mute))
1460
SAM("WARNING: failed to adjust mute to %i\n", mute);
1464
SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
1466
mutex_unlock(&easycap_dongle[kd].mutex_video);
1472
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1473
case VIDIOC_S_EXT_CTRLS: {
1474
JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1475
mutex_unlock(&easycap_dongle[kd].mutex_video);
1478
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1479
case VIDIOC_ENUM_FMT: {
1481
struct v4l2_fmtdesc v4l2_fmtdesc;
1483
JOM(8, "VIDIOC_ENUM_FMT\n");
1485
if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
1486
sizeof(struct v4l2_fmtdesc))) {
1487
mutex_unlock(&easycap_dongle[kd].mutex_video);
1491
index = v4l2_fmtdesc.index;
1492
memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1494
v4l2_fmtdesc.index = index;
1495
v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1499
v4l2_fmtdesc.flags = 0;
1500
strcpy(&v4l2_fmtdesc.description[0], "uyvy");
1501
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
1502
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1506
v4l2_fmtdesc.flags = 0;
1507
strcpy(&v4l2_fmtdesc.description[0], "yuy2");
1508
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1509
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1513
v4l2_fmtdesc.flags = 0;
1514
strcpy(&v4l2_fmtdesc.description[0], "rgb24");
1515
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
1516
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1520
v4l2_fmtdesc.flags = 0;
1521
strcpy(&v4l2_fmtdesc.description[0], "rgb32");
1522
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
1523
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1527
v4l2_fmtdesc.flags = 0;
1528
strcpy(&v4l2_fmtdesc.description[0], "bgr24");
1529
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
1530
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1534
v4l2_fmtdesc.flags = 0;
1535
strcpy(&v4l2_fmtdesc.description[0], "bgr32");
1536
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
1537
JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1541
JOM(8, "%i=index: exhausts formats\n", index);
1542
mutex_unlock(&easycap_dongle[kd].mutex_video);
1546
if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
1547
sizeof(struct v4l2_fmtdesc))) {
1548
mutex_unlock(&easycap_dongle[kd].mutex_video);
1553
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1555
* THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
1556
* THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1558
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1559
case VIDIOC_ENUM_FRAMESIZES: {
1561
struct v4l2_frmsizeenum v4l2_frmsizeenum;
1563
JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
1565
if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \
1566
sizeof(struct v4l2_frmsizeenum))) {
1567
mutex_unlock(&easycap_dongle[kd].mutex_video);
1571
index = v4l2_frmsizeenum.index;
1573
v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;
1575
if (true == peasycap->ntsc) {
1578
v4l2_frmsizeenum.discrete.width = 640;
1579
v4l2_frmsizeenum.discrete.height = 480;
1580
JOM(8, "%i=index: %ix%i\n", index, \
1581
(int)(v4l2_frmsizeenum.\
1583
(int)(v4l2_frmsizeenum.\
1588
v4l2_frmsizeenum.discrete.width = 320;
1589
v4l2_frmsizeenum.discrete.height = 240;
1590
JOM(8, "%i=index: %ix%i\n", index, \
1591
(int)(v4l2_frmsizeenum.\
1593
(int)(v4l2_frmsizeenum.\
1598
v4l2_frmsizeenum.discrete.width = 720;
1599
v4l2_frmsizeenum.discrete.height = 480;
1600
JOM(8, "%i=index: %ix%i\n", index, \
1601
(int)(v4l2_frmsizeenum.\
1603
(int)(v4l2_frmsizeenum.\
1608
v4l2_frmsizeenum.discrete.width = 360;
1609
v4l2_frmsizeenum.discrete.height = 240;
1610
JOM(8, "%i=index: %ix%i\n", index, \
1611
(int)(v4l2_frmsizeenum.\
1613
(int)(v4l2_frmsizeenum.\
1618
JOM(8, "%i=index: exhausts framesizes\n", index);
1619
mutex_unlock(&easycap_dongle[kd].mutex_video);
1626
v4l2_frmsizeenum.discrete.width = 640;
1627
v4l2_frmsizeenum.discrete.height = 480;
1628
JOM(8, "%i=index: %ix%i\n", index, \
1629
(int)(v4l2_frmsizeenum.\
1631
(int)(v4l2_frmsizeenum.\
1636
v4l2_frmsizeenum.discrete.width = 320;
1637
v4l2_frmsizeenum.discrete.height = 240;
1638
JOM(8, "%i=index: %ix%i\n", index, \
1639
(int)(v4l2_frmsizeenum.\
1641
(int)(v4l2_frmsizeenum.\
1646
v4l2_frmsizeenum.discrete.width = 704;
1647
v4l2_frmsizeenum.discrete.height = 576;
1648
JOM(8, "%i=index: %ix%i\n", index, \
1649
(int)(v4l2_frmsizeenum.\
1651
(int)(v4l2_frmsizeenum.\
1656
v4l2_frmsizeenum.discrete.width = 720;
1657
v4l2_frmsizeenum.discrete.height = 576;
1658
JOM(8, "%i=index: %ix%i\n", index, \
1659
(int)(v4l2_frmsizeenum.\
1661
(int)(v4l2_frmsizeenum.\
1666
v4l2_frmsizeenum.discrete.width = 360;
1667
v4l2_frmsizeenum.discrete.height = 288;
1668
JOM(8, "%i=index: %ix%i\n", index, \
1669
(int)(v4l2_frmsizeenum.\
1671
(int)(v4l2_frmsizeenum.\
1676
JOM(8, "%i=index: exhausts framesizes\n", index);
1677
mutex_unlock(&easycap_dongle[kd].mutex_video);
1682
if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \
1683
sizeof(struct v4l2_frmsizeenum))) {
1684
mutex_unlock(&easycap_dongle[kd].mutex_video);
1689
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1691
* THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
1692
* THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1694
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1695
case VIDIOC_ENUM_FRAMEINTERVALS: {
1698
struct v4l2_frmivalenum v4l2_frmivalenum;
1700
JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
1703
denominator = peasycap->fps;
1705
if (true == peasycap->ntsc)
1711
if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \
1712
sizeof(struct v4l2_frmivalenum))) {
1713
mutex_unlock(&easycap_dongle[kd].mutex_video);
1717
index = v4l2_frmivalenum.index;
1719
v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;
1723
v4l2_frmivalenum.discrete.numerator = 1;
1724
v4l2_frmivalenum.discrete.denominator = denominator;
1725
JOM(8, "%i=index: %i/%i\n", index, \
1726
(int)(v4l2_frmivalenum.discrete.numerator), \
1727
(int)(v4l2_frmivalenum.discrete.denominator));
1731
v4l2_frmivalenum.discrete.numerator = 1;
1732
v4l2_frmivalenum.discrete.denominator = denominator/5;
1733
JOM(8, "%i=index: %i/%i\n", index, \
1734
(int)(v4l2_frmivalenum.discrete.numerator), \
1735
(int)(v4l2_frmivalenum.discrete.denominator));
1739
JOM(8, "%i=index: exhausts frameintervals\n", index);
1740
mutex_unlock(&easycap_dongle[kd].mutex_video);
1744
if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \
1745
sizeof(struct v4l2_frmivalenum))) {
1746
mutex_unlock(&easycap_dongle[kd].mutex_video);
1751
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1752
case VIDIOC_G_FMT: {
1753
struct v4l2_format *pv4l2_format;
1754
struct v4l2_pix_format *pv4l2_pix_format;
1756
JOM(8, "VIDIOC_G_FMT\n");
1757
pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
1758
if (!pv4l2_format) {
1759
SAM("ERROR: out of memory\n");
1760
mutex_unlock(&easycap_dongle[kd].mutex_video);
1763
pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
1764
if (!pv4l2_pix_format) {
1765
SAM("ERROR: out of memory\n");
1766
kfree(pv4l2_format);
1767
mutex_unlock(&easycap_dongle[kd].mutex_video);
1770
if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \
1771
sizeof(struct v4l2_format))) {
1772
kfree(pv4l2_format);
1773
kfree(pv4l2_pix_format);
1774
mutex_unlock(&easycap_dongle[kd].mutex_video);
1778
if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1779
kfree(pv4l2_format);
1780
kfree(pv4l2_pix_format);
1781
mutex_unlock(&easycap_dongle[kd].mutex_video);
1785
memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1786
pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1787
memcpy(&pv4l2_format->fmt.pix, \
1788
&easycap_format[peasycap->format_offset]\
1789
.v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
1790
JOM(8, "user is told: %s\n", \
1791
&easycap_format[peasycap->format_offset].name[0]);
1793
if (0 != copy_to_user((void __user *)arg, pv4l2_format, \
1794
sizeof(struct v4l2_format))) {
1795
kfree(pv4l2_format);
1796
kfree(pv4l2_pix_format);
1797
mutex_unlock(&easycap_dongle[kd].mutex_video);
1800
kfree(pv4l2_format);
1801
kfree(pv4l2_pix_format);
1804
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1805
case VIDIOC_TRY_FMT:
1806
case VIDIOC_S_FMT: {
1807
struct v4l2_format v4l2_format;
1808
struct v4l2_pix_format v4l2_pix_format;
1812
if (VIDIOC_TRY_FMT == cmd) {
1813
JOM(8, "VIDIOC_TRY_FMT\n");
1816
JOM(8, "VIDIOC_S_FMT\n");
1820
if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
1821
sizeof(struct v4l2_format))) {
1822
mutex_unlock(&easycap_dongle[kd].mutex_video);
1826
best_format = adjust_format(peasycap, \
1827
v4l2_format.fmt.pix.width, \
1828
v4l2_format.fmt.pix.height, \
1829
v4l2_format.fmt.pix.pixelformat, \
1830
v4l2_format.fmt.pix.field, \
1832
if (0 > best_format) {
1833
if (-EBUSY == best_format) {
1834
mutex_unlock(&easycap_dongle[kd].mutex_video);
1837
JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
1838
mutex_unlock(&easycap_dongle[kd].mutex_video);
1841
/*...........................................................................*/
1842
memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1843
v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1845
memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
1846
.v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
1847
JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
1849
if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
1850
sizeof(struct v4l2_format))) {
1851
mutex_unlock(&easycap_dongle[kd].mutex_video);
1856
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1857
case VIDIOC_CROPCAP: {
1858
struct v4l2_cropcap v4l2_cropcap;
1860
JOM(8, "VIDIOC_CROPCAP\n");
1862
if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
1863
sizeof(struct v4l2_cropcap))) {
1864
mutex_unlock(&easycap_dongle[kd].mutex_video);
1868
if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1869
JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1871
memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
1872
v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1873
v4l2_cropcap.bounds.left = 0;
1874
v4l2_cropcap.bounds.top = 0;
1875
v4l2_cropcap.bounds.width = peasycap->width;
1876
v4l2_cropcap.bounds.height = peasycap->height;
1877
v4l2_cropcap.defrect.left = 0;
1878
v4l2_cropcap.defrect.top = 0;
1879
v4l2_cropcap.defrect.width = peasycap->width;
1880
v4l2_cropcap.defrect.height = peasycap->height;
1881
v4l2_cropcap.pixelaspect.numerator = 1;
1882
v4l2_cropcap.pixelaspect.denominator = 1;
1884
JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1886
if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
1887
sizeof(struct v4l2_cropcap))) {
1888
mutex_unlock(&easycap_dongle[kd].mutex_video);
1893
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1895
case VIDIOC_S_CROP: {
1896
JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
1897
mutex_unlock(&easycap_dongle[kd].mutex_video);
1900
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1901
case VIDIOC_QUERYSTD: {
1902
JOM(8, "VIDIOC_QUERYSTD: " \
1903
"EasyCAP is incapable of detecting standard\n");
1904
mutex_unlock(&easycap_dongle[kd].mutex_video);
1908
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1909
/*---------------------------------------------------------------------------*/
1911
* THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND
1912
* FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer.
1913
* NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
1915
/*---------------------------------------------------------------------------*/
1916
case VIDIOC_ENUMSTD: {
1917
int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1918
struct v4l2_standard v4l2_standard;
1920
struct easycap_standard const *peasycap_standard;
1922
JOM(8, "VIDIOC_ENUMSTD\n");
1924
if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
1925
sizeof(struct v4l2_standard))) {
1926
mutex_unlock(&easycap_dongle[kd].mutex_video);
1929
index = v4l2_standard.index;
1931
last3 = last2; last2 = last1; last1 = last0; last0 = index;
1932
if ((index == last3) && (index == last2) && \
1933
(index == last1) && (index == last0)) {
1935
last3 = last2; last2 = last1; last1 = last0; last0 = index;
1938
memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1940
peasycap_standard = &easycap_standard[0];
1941
while (0xFFFF != peasycap_standard->mask) {
1942
if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1944
peasycap_standard++;
1946
if (0xFFFF == peasycap_standard->mask) {
1947
JOM(8, "%i=index: exhausts standards\n", index);
1948
mutex_unlock(&easycap_dongle[kd].mutex_video);
1951
JOM(8, "%i=index: %s\n", index, \
1952
&(peasycap_standard->v4l2_standard.name[0]));
1953
memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
1954
sizeof(struct v4l2_standard));
1956
v4l2_standard.index = index;
1958
if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
1959
sizeof(struct v4l2_standard))) {
1960
mutex_unlock(&easycap_dongle[kd].mutex_video);
1965
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1966
case VIDIOC_G_STD: {
1968
struct easycap_standard const *peasycap_standard;
1970
JOM(8, "VIDIOC_G_STD\n");
1972
if (0 > peasycap->standard_offset) {
1973
JOM(8, "%i=peasycap->standard_offset\n", \
1974
peasycap->standard_offset);
1975
mutex_unlock(&easycap_dongle[kd].mutex_video);
1979
if (0 != copy_from_user(&std_id, (void __user *)arg, \
1980
sizeof(v4l2_std_id))) {
1981
mutex_unlock(&easycap_dongle[kd].mutex_video);
1985
peasycap_standard = &easycap_standard[peasycap->standard_offset];
1986
std_id = peasycap_standard->v4l2_standard.id;
1988
JOM(8, "user is told: %s\n", \
1989
&peasycap_standard->v4l2_standard.name[0]);
1991
if (0 != copy_to_user((void __user *)arg, &std_id, \
1992
sizeof(v4l2_std_id))) {
1993
mutex_unlock(&easycap_dongle[kd].mutex_video);
1998
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1999
case VIDIOC_S_STD: {
2003
JOM(8, "VIDIOC_S_STD\n");
2005
if (0 != copy_from_user(&std_id, (void __user *)arg, \
2006
sizeof(v4l2_std_id))) {
2007
mutex_unlock(&easycap_dongle[kd].mutex_video);
2011
JOM(8, "User requests standard: 0x%08X%08X\n", \
2012
(int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \
2013
(int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
2015
rc = adjust_standard(peasycap, std_id);
2017
JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
2018
mutex_unlock(&easycap_dongle[kd].mutex_video);
2023
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2024
case VIDIOC_REQBUFS: {
2026
struct v4l2_requestbuffers v4l2_requestbuffers;
2028
JOM(8, "VIDIOC_REQBUFS\n");
2030
if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
2031
sizeof(struct v4l2_requestbuffers))) {
2032
mutex_unlock(&easycap_dongle[kd].mutex_video);
2036
if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2037
mutex_unlock(&easycap_dongle[kd].mutex_video);
2040
if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
2041
mutex_unlock(&easycap_dongle[kd].mutex_video);
2044
nbuffers = v4l2_requestbuffers.count;
2045
JOM(8, " User requests %i buffers ...\n", nbuffers);
2048
if (nbuffers > FRAME_BUFFER_MANY)
2049
nbuffers = FRAME_BUFFER_MANY;
2050
if (v4l2_requestbuffers.count == nbuffers) {
2051
JOM(8, " ... agree to %i buffers\n", \
2054
JOM(8, " ... insist on %i buffers\n", \
2056
v4l2_requestbuffers.count = nbuffers;
2058
peasycap->frame_buffer_many = nbuffers;
2060
if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
2061
sizeof(struct v4l2_requestbuffers))) {
2062
mutex_unlock(&easycap_dongle[kd].mutex_video);
2067
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2068
case VIDIOC_QUERYBUF: {
2070
struct v4l2_buffer v4l2_buffer;
2072
JOM(8, "VIDIOC_QUERYBUF\n");
2074
if (peasycap->video_eof) {
2075
JOM(8, "returning -EIO because %i=video_eof\n", \
2076
peasycap->video_eof);
2077
mutex_unlock(&easycap_dongle[kd].mutex_video);
2081
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2082
sizeof(struct v4l2_buffer))) {
2083
mutex_unlock(&easycap_dongle[kd].mutex_video);
2087
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2088
mutex_unlock(&easycap_dongle[kd].mutex_video);
2091
index = v4l2_buffer.index;
2092
if (index < 0 || index >= peasycap->frame_buffer_many)
2094
memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
2095
v4l2_buffer.index = index;
2096
v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2097
v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2098
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
2099
peasycap->done[index] | \
2100
peasycap->queued[index];
2101
v4l2_buffer.field = V4L2_FIELD_NONE;
2102
v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2103
v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
2104
v4l2_buffer.length = FRAME_BUFFER_SIZE;
2106
JOM(16, " %10i=index\n", v4l2_buffer.index);
2107
JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2108
JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2109
JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2110
JOM(16, " %10i=field\n", v4l2_buffer.field);
2111
JOM(16, " %10li=timestamp.tv_usec\n", \
2112
(long)v4l2_buffer.timestamp.tv_usec);
2113
JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2114
JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2115
JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2116
JOM(16, " %10i=length\n", v4l2_buffer.length);
2118
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2119
sizeof(struct v4l2_buffer))) {
2120
mutex_unlock(&easycap_dongle[kd].mutex_video);
2125
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2127
struct v4l2_buffer v4l2_buffer;
2129
JOM(8, "VIDIOC_QBUF\n");
2131
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2132
sizeof(struct v4l2_buffer))) {
2133
mutex_unlock(&easycap_dongle[kd].mutex_video);
2137
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2138
mutex_unlock(&easycap_dongle[kd].mutex_video);
2141
if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
2142
mutex_unlock(&easycap_dongle[kd].mutex_video);
2145
if (v4l2_buffer.index < 0 || \
2146
(v4l2_buffer.index >= peasycap->frame_buffer_many)) {
2147
mutex_unlock(&easycap_dongle[kd].mutex_video);
2150
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
2152
peasycap->done[v4l2_buffer.index] = 0;
2153
peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
2155
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2156
sizeof(struct v4l2_buffer))) {
2157
mutex_unlock(&easycap_dongle[kd].mutex_video);
2161
JOM(8, "..... user queueing frame buffer %i\n", \
2162
(int)v4l2_buffer.index);
2164
peasycap->frame_lock = 0;
2168
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2171
#if defined(AUDIOTIME)
2172
struct signed_div_result sdr;
2173
long long int above, below, dnbydt, fudge, sll;
2174
unsigned long long int ull;
2175
struct timeval timeval8;
2176
struct timeval timeval1;
2177
#endif /*AUDIOTIME*/
2178
struct timeval timeval, timeval2;
2180
struct v4l2_buffer v4l2_buffer;
2184
JOM(8, "VIDIOC_DQBUF\n");
2186
if ((peasycap->video_idle) || (peasycap->video_eof)) {
2187
JOM(8, "returning -EIO because " \
2188
"%i=video_idle %i=video_eof\n", \
2189
peasycap->video_idle, peasycap->video_eof);
2190
mutex_unlock(&easycap_dongle[kd].mutex_video);
2194
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
2195
sizeof(struct v4l2_buffer))) {
2196
mutex_unlock(&easycap_dongle[kd].mutex_video);
2200
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2201
mutex_unlock(&easycap_dongle[kd].mutex_video);
2205
if (true == peasycap->offerfields) {
2206
/*-----------------------------------------------------------*/
2208
* IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
2211
/*-----------------------------------------------------------*/
2212
if (V4L2_FIELD_TOP == v4l2_buffer.field)
2213
JOM(8, "user wants V4L2_FIELD_TOP\n");
2214
else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
2215
JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
2216
else if (V4L2_FIELD_ANY == v4l2_buffer.field)
2217
JOM(8, "user wants V4L2_FIELD_ANY\n");
2219
JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \
2223
if (!peasycap->video_isoc_streaming) {
2224
JOM(16, "returning -EIO because video urbs not streaming\n");
2225
mutex_unlock(&easycap_dongle[kd].mutex_video);
2228
/*---------------------------------------------------------------------------*/
2230
* IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
2231
* THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS
2232
* CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
2234
/*---------------------------------------------------------------------------*/
2236
if (!peasycap->polled) {
2238
rcdq = easycap_dqbuf(peasycap, 0);
2240
JOM(8, "returning -EIO because " \
2241
"dqbuf() returned -EIO\n");
2242
mutex_unlock(&easycap_dongle[kd].mutex_video);
2245
} while (0 != rcdq);
2247
if (peasycap->video_eof) {
2248
mutex_unlock(&easycap_dongle[kd].mutex_video);
2252
if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
2253
SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
2254
peasycap->done[peasycap->frame_read]);
2256
peasycap->polled = 0;
2258
if (!(peasycap->isequence % 10)) {
2259
for (i = 0; i < 179; i++)
2260
peasycap->merit[i] = peasycap->merit[i+1];
2261
peasycap->merit[179] = merit_saa(peasycap->pusb_device);
2263
for (i = 0; i < 180; i++)
2264
j += peasycap->merit[i];
2266
SAM("easycap driver shutting down " \
2267
"on condition blue\n");
2268
peasycap->video_eof = 1; peasycap->audio_eof = 1;
2272
v4l2_buffer.index = peasycap->frame_read;
2273
v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2274
v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2275
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
2276
if (true == peasycap->offerfields)
2277
v4l2_buffer.field = V4L2_FIELD_BOTTOM;
2279
v4l2_buffer.field = V4L2_FIELD_NONE;
2280
do_gettimeofday(&timeval);
2283
#if defined(AUDIOTIME)
2284
if (!peasycap->timeval0.tv_sec) {
2289
peasycap->timeval0 = timeval8;
2291
dnbydt = peasycap->dnbydt;
2292
timeval1 = peasycap->timeval1;
2293
above = dnbydt * MICROSECONDS(timeval, timeval1);
2295
sdr = signed_div(above, below);
2297
above = sdr.quotient + timeval1.tv_usec - 350000;
2300
sdr = signed_div(above, below);
2301
timeval2.tv_usec = sdr.remainder;
2302
timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
2304
if (!(peasycap->isequence % 500)) {
2305
fudge = ((long long int)(1000000)) * \
2306
((long long int)(timeval.tv_sec - \
2307
timeval2.tv_sec)) + \
2308
(long long int)(timeval.tv_usec - \
2310
sdr = signed_div(fudge, 1000);
2312
ull = sdr.remainder;
2314
SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
2316
#endif /*AUDIOTIME*/
2318
v4l2_buffer.timestamp = timeval2;
2319
v4l2_buffer.sequence = peasycap->isequence++;
2320
v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2321
v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
2322
v4l2_buffer.length = FRAME_BUFFER_SIZE;
2324
JOM(16, " %10i=index\n", v4l2_buffer.index);
2325
JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2326
JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2327
JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2328
JOM(16, " %10i=field\n", v4l2_buffer.field);
2329
JOM(16, " %10li=timestamp.tv_sec\n", \
2330
(long)v4l2_buffer.timestamp.tv_sec);
2331
JOM(16, " %10li=timestamp.tv_usec\n", \
2332
(long)v4l2_buffer.timestamp.tv_usec);
2333
JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2334
JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2335
JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2336
JOM(16, " %10i=length\n", v4l2_buffer.length);
2338
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
2339
sizeof(struct v4l2_buffer))) {
2340
mutex_unlock(&easycap_dongle[kd].mutex_video);
2344
input = peasycap->frame_buffer[peasycap->frame_read][0].input;
2346
JOM(8, "user is offered frame buffer %i, input %i\n", \
2347
peasycap->frame_read, (0x07 & input));
2349
JOM(8, "user is offered frame buffer %i\n", \
2350
peasycap->frame_read);
2352
peasycap->frame_lock = 1;
2353
JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
2354
if (peasycap->frame_read == peasycap->frame_fill) {
2355
if (peasycap->frame_lock) {
2356
JOM(8, "WORRY: filling frame buffer " \
2357
"while offered to user\n");
2362
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2363
case VIDIOC_STREAMON: {
2366
JOM(8, "VIDIOC_STREAMON\n");
2368
peasycap->isequence = 0;
2369
for (i = 0; i < 180; i++)
2370
peasycap->merit[i] = 0;
2371
if ((struct usb_device *)NULL == peasycap->pusb_device) {
2372
SAM("ERROR: peasycap->pusb_device is NULL\n");
2373
mutex_unlock(&easycap_dongle[kd].mutex_video);
2376
submit_video_urbs(peasycap);
2377
peasycap->video_idle = 0;
2378
peasycap->audio_idle = 0;
2379
peasycap->video_eof = 0;
2380
peasycap->audio_eof = 0;
2383
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2384
case VIDIOC_STREAMOFF: {
2385
JOM(8, "VIDIOC_STREAMOFF\n");
2387
if ((struct usb_device *)NULL == peasycap->pusb_device) {
2388
SAM("ERROR: peasycap->pusb_device is NULL\n");
2389
mutex_unlock(&easycap_dongle[kd].mutex_video);
2393
peasycap->video_idle = 1;
2394
peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0;
2395
/*---------------------------------------------------------------------------*/
2397
* IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
2398
* THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2400
/*---------------------------------------------------------------------------*/
2401
JOM(8, "calling wake_up on wq_video and wq_audio\n");
2402
wake_up_interruptible(&(peasycap->wq_video));
2403
wake_up_interruptible(&(peasycap->wq_audio));
2404
/*---------------------------------------------------------------------------*/
2407
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2408
case VIDIOC_G_PARM: {
2409
struct v4l2_streamparm *pv4l2_streamparm;
2411
JOM(8, "VIDIOC_G_PARM\n");
2412
pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL);
2413
if (!pv4l2_streamparm) {
2414
SAM("ERROR: out of memory\n");
2415
mutex_unlock(&easycap_dongle[kd].mutex_video);
2418
if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \
2419
sizeof(struct v4l2_streamparm))) {
2420
kfree(pv4l2_streamparm);
2421
mutex_unlock(&easycap_dongle[kd].mutex_video);
2425
if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2426
kfree(pv4l2_streamparm);
2427
mutex_unlock(&easycap_dongle[kd].mutex_video);
2430
pv4l2_streamparm->parm.capture.capability = 0;
2431
pv4l2_streamparm->parm.capture.capturemode = 0;
2432
pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
2434
if (peasycap->fps) {
2435
pv4l2_streamparm->parm.capture.timeperframe.\
2436
denominator = peasycap->fps;
2438
if (true == peasycap->ntsc) {
2439
pv4l2_streamparm->parm.capture.timeperframe.\
2442
pv4l2_streamparm->parm.capture.timeperframe.\
2447
pv4l2_streamparm->parm.capture.readbuffers = \
2448
peasycap->frame_buffer_many;
2449
pv4l2_streamparm->parm.capture.extendedmode = 0;
2450
if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \
2451
sizeof(struct v4l2_streamparm))) {
2452
kfree(pv4l2_streamparm);
2453
mutex_unlock(&easycap_dongle[kd].mutex_video);
2456
kfree(pv4l2_streamparm);
2459
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2460
case VIDIOC_S_PARM: {
2461
JOM(8, "VIDIOC_S_PARM unsupported\n");
2462
mutex_unlock(&easycap_dongle[kd].mutex_video);
2465
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2466
case VIDIOC_G_AUDIO: {
2467
JOM(8, "VIDIOC_G_AUDIO unsupported\n");
2468
mutex_unlock(&easycap_dongle[kd].mutex_video);
2471
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2472
case VIDIOC_S_AUDIO: {
2473
JOM(8, "VIDIOC_S_AUDIO unsupported\n");
2474
mutex_unlock(&easycap_dongle[kd].mutex_video);
2477
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2478
case VIDIOC_S_TUNER: {
2479
JOM(8, "VIDIOC_S_TUNER unsupported\n");
2480
mutex_unlock(&easycap_dongle[kd].mutex_video);
2483
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2486
case VIDIOC_OVERLAY: {
2487
JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
2488
mutex_unlock(&easycap_dongle[kd].mutex_video);
2491
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2492
case VIDIOC_G_TUNER: {
2493
JOM(8, "VIDIOC_G_TUNER unsupported\n");
2494
mutex_unlock(&easycap_dongle[kd].mutex_video);
2497
case VIDIOC_G_FREQUENCY:
2498
case VIDIOC_S_FREQUENCY: {
2499
JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
2500
mutex_unlock(&easycap_dongle[kd].mutex_video);
2503
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2505
JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
2506
mutex_unlock(&easycap_dongle[kd].mutex_video);
2507
return -ENOIOCTLCMD;
2510
mutex_unlock(&easycap_dongle[kd].mutex_video);
2511
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
2514
/*****************************************************************************/
2515
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2516
#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
2517
(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
2519
easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
2520
return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg);
2522
#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
2523
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
2524
/*---------------------------------------------------------------------------*/
2526
easysnd_ioctl(struct inode *inode, struct file *file,
2527
unsigned int cmd, unsigned long arg)
2529
struct easycap *peasycap;
2530
struct usb_device *p;
2534
SAY("ERROR: file is NULL\n");
2535
return -ERESTARTSYS;
2537
peasycap = file->private_data;
2538
if (NULL == peasycap) {
2539
SAY("ERROR: peasycap is NULL.\n");
2542
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2543
SAY("ERROR: bad peasycap\n");
2546
p = peasycap->pusb_device;
2548
SAM("ERROR: peasycap->pusb_device is NULL\n");
2551
kd = isdongle(peasycap);
2552
if (0 <= kd && DONGLE_MANY > kd) {
2553
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
2554
SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd);
2555
return -ERESTARTSYS;
2557
JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
2558
/*---------------------------------------------------------------------------*/
2560
* MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
2561
* IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
2562
* IF NECESSARY, BAIL OUT.
2564
/*---------------------------------------------------------------------------*/
2565
if (kd != isdongle(peasycap))
2566
return -ERESTARTSYS;
2568
SAY("ERROR: file is NULL\n");
2569
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2570
return -ERESTARTSYS;
2572
peasycap = file->private_data;
2573
if (NULL == peasycap) {
2574
SAY("ERROR: peasycap is NULL\n");
2575
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2576
return -ERESTARTSYS;
2578
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2579
SAY("ERROR: bad peasycap\n");
2580
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2583
p = peasycap->pusb_device;
2584
if (NULL == peasycap->pusb_device) {
2585
SAM("ERROR: peasycap->pusb_device is NULL\n");
2586
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2587
return -ERESTARTSYS;
2590
/*---------------------------------------------------------------------------*/
2592
* IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
2593
* ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
2595
/*---------------------------------------------------------------------------*/
2596
return -ERESTARTSYS;
2598
/*---------------------------------------------------------------------------*/
2600
case SNDCTL_DSP_GETCAPS: {
2602
JOM(8, "SNDCTL_DSP_GETCAPS\n");
2604
#if defined(UPSAMPLE)
2605
if (true == peasycap->microphone)
2610
if (true == peasycap->microphone)
2616
if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
2617
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2622
case SNDCTL_DSP_GETFMTS: {
2624
JOM(8, "SNDCTL_DSP_GETFMTS\n");
2626
#if defined(UPSAMPLE)
2627
if (true == peasycap->microphone)
2628
incoming = AFMT_S16_LE;
2630
incoming = AFMT_S16_LE;
2632
if (true == peasycap->microphone)
2633
incoming = AFMT_S16_LE;
2635
incoming = AFMT_S16_LE;
2638
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2639
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2644
case SNDCTL_DSP_SETFMT: {
2645
int incoming, outgoing;
2646
JOM(8, "SNDCTL_DSP_SETFMT\n");
2647
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2648
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2651
JOM(8, "........... %i=incoming\n", incoming);
2653
#if defined(UPSAMPLE)
2654
if (true == peasycap->microphone)
2655
outgoing = AFMT_S16_LE;
2657
outgoing = AFMT_S16_LE;
2659
if (true == peasycap->microphone)
2660
outgoing = AFMT_S16_LE;
2662
outgoing = AFMT_S16_LE;
2665
if (incoming != outgoing) {
2666
JOM(8, "........... %i=outgoing\n", outgoing);
2667
JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
2668
JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8);
2669
if (0 != copy_to_user((void __user *)arg, &outgoing, \
2671
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2674
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2679
case SNDCTL_DSP_STEREO: {
2681
JOM(8, "SNDCTL_DSP_STEREO\n");
2682
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2683
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2686
JOM(8, "........... %i=incoming\n", incoming);
2688
#if defined(UPSAMPLE)
2689
if (true == peasycap->microphone)
2694
if (true == peasycap->microphone)
2700
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2701
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2706
case SNDCTL_DSP_SPEED: {
2708
JOM(8, "SNDCTL_DSP_SPEED\n");
2709
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2710
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2713
JOM(8, "........... %i=incoming\n", incoming);
2715
#if defined(UPSAMPLE)
2716
if (true == peasycap->microphone)
2721
if (true == peasycap->microphone)
2727
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2728
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2733
case SNDCTL_DSP_GETTRIGGER: {
2735
JOM(8, "SNDCTL_DSP_GETTRIGGER\n");
2736
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2737
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2740
JOM(8, "........... %i=incoming\n", incoming);
2742
incoming = PCM_ENABLE_INPUT;
2743
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2744
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2749
case SNDCTL_DSP_SETTRIGGER: {
2751
JOM(8, "SNDCTL_DSP_SETTRIGGER\n");
2752
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2753
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2756
JOM(8, "........... %i=incoming\n", incoming);
2757
JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
2758
"0x%x=PCM_ENABLE_OUTPUT\n", \
2759
PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
2766
case SNDCTL_DSP_GETBLKSIZE: {
2768
JOM(8, "SNDCTL_DSP_GETBLKSIZE\n");
2769
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
2770
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2773
JOM(8, "........... %i=incoming\n", incoming);
2774
incoming = peasycap->audio_bytes_per_fragment;
2775
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
2776
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2781
case SNDCTL_DSP_GETISPACE: {
2782
struct audio_buf_info audio_buf_info;
2784
JOM(8, "SNDCTL_DSP_GETISPACE\n");
2786
audio_buf_info.bytes = peasycap->audio_bytes_per_fragment;
2787
audio_buf_info.fragments = 1;
2788
audio_buf_info.fragsize = 0;
2789
audio_buf_info.fragstotal = 0;
2791
if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
2793
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2804
JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
2805
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2806
return -ENOIOCTLCMD;
2809
JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
2810
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2811
return -ENOIOCTLCMD;
2814
mutex_unlock(&easycap_dongle[kd].mutex_audio);
2817
/*****************************************************************************/