~ubuntu-branches/ubuntu/trusty/v4l-utils/trusty

« back to all changes in this revision

Viewing changes to utils/v4l2-compliance/v4l2-test-input-output.cpp

  • Committer: Package Import Robot
  • Author(s): Gregor Jasny
  • Date: 2012-10-09 18:38:05 UTC
  • mfrom: (11.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20121009183805-v1m5kb2a1i97rw9y
* Imported Upstream version 0.8.9
  - libv4lconvert: Various Pixart JPEG fixes
  - libv4lconvert: Add more notebooks to the upside down device table
  - keytable: Add support for Sanyo IR and RC-5-SZ protocol
  - keytable: Add missing buttons in shipped keytables (LP: #1054122)
  - v4l2-compliance, v4l-ctl, qv4l2: Sync with development branch
* Drop 32bit cross compiled libraries

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
#define MAGIC 0x1eadbeef
35
35
 
 
36
static int checkEnumFreqBands(struct node *node, __u32 tuner, __u32 type, __u32 caps)
 
37
{
 
38
        unsigned i;
 
39
        __u32 caps_union = 0;
 
40
 
 
41
        for (i = 0; ; i++) {
 
42
                struct v4l2_frequency_band band;
 
43
                int ret;
 
44
 
 
45
                memset(band.reserved, 0, sizeof(band.reserved));
 
46
                band.tuner = tuner;
 
47
                band.type = type;
 
48
                band.index = i;
 
49
                ret = doioctl(node, VIDIOC_ENUM_FREQ_BANDS, &band);
 
50
                if (ret == EINVAL && i)
 
51
                        return 0;
 
52
                if (ret)
 
53
                        return fail("couldn't get freq band\n");
 
54
                caps_union |= band.capability;
 
55
                if ((caps & V4L2_TUNER_CAP_LOW) != (band.capability & V4L2_TUNER_CAP_LOW))
 
56
                        return fail("Inconsistent CAP_LOW usage\n");
 
57
                fail_on_test(band.rangehigh < band.rangelow);
 
58
                fail_on_test(band.index != i);
 
59
                fail_on_test(band.type != type);
 
60
                fail_on_test(band.tuner != tuner);
 
61
                fail_on_test((band.capability & V4L2_TUNER_CAP_FREQ_BANDS) == 0);
 
62
                check_0(band.reserved, sizeof(band.reserved));
 
63
        }
 
64
        fail_on_test(caps_union != caps);
 
65
        return 0;
 
66
}
 
67
 
36
68
static int checkTuner(struct node *node, const struct v4l2_tuner &tuner,
37
69
                unsigned t, v4l2_std_id std)
38
70
{
39
 
        bool valid_modes[5] = { true, false, false, true, false };
 
71
        bool valid_modes[5] = { true, false, false, false, false };
40
72
        bool tv = !node->is_radio;
41
 
        enum v4l2_tuner_type type = tv ? V4L2_TUNER_ANALOG_TV : V4L2_TUNER_RADIO;
 
73
        bool hwseek_caps = tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED |
 
74
                        V4L2_TUNER_CAP_HWSEEK_WRAP | V4L2_TUNER_CAP_HWSEEK_PROG_LIM);
 
75
        unsigned type = tv ? V4L2_TUNER_ANALOG_TV : V4L2_TUNER_RADIO;
42
76
        __u32 audmode;
43
77
 
44
78
        if (tuner.index != t)
58
92
                return fail("did not expect to see V4L2_TUNER_CAP_LOW set for a tv tuner\n");
59
93
        if (!tv && !(tuner.capability & V4L2_TUNER_CAP_LOW))
60
94
                return fail("V4L2_TUNER_CAP_LOW was not set for a radio tuner\n");
 
95
        fail_on_test(!(tuner.capability & V4L2_TUNER_CAP_FREQ_BANDS));
 
96
        fail_on_test(!(node->caps & V4L2_CAP_HW_FREQ_SEEK) && hwseek_caps);
 
97
        fail_on_test((node->caps & V4L2_CAP_HW_FREQ_SEEK) &&
 
98
                !(tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP)));
61
99
        if (tuner.rangelow >= tuner.rangehigh)
62
100
                return fail("rangelow >= rangehigh\n");
63
101
        if (tuner.rangelow == 0 || tuner.rangehigh == 0xffffffff)
74
112
        if (!(tuner.capability & V4L2_TUNER_CAP_RDS) &&
75
113
                        (tuner.rxsubchans & V4L2_TUNER_SUB_RDS))
76
114
                return fail("RDS subchan, but no RDS caps?\n");
 
115
        bool have_rds = tuner.capability & V4L2_TUNER_CAP_RDS;
 
116
        bool have_rds_method = tuner.capability &
 
117
                        (V4L2_TUNER_CAP_RDS_BLOCK_IO | V4L2_TUNER_CAP_RDS_CONTROLS);
 
118
        if (have_rds ^ have_rds_method)
 
119
                return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n");
 
120
        if ((tuner.capability & V4L2_TUNER_CAP_RDS) &&
 
121
                        !(node->caps & V4L2_CAP_READWRITE))
 
122
                return fail("V4L2_TUNER_CAP_RDS set, but not V4L2_CAP_READWRITE\n");
77
123
        if (std == V4L2_STD_NTSC_M && (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1))
78
124
                return fail("LANG1 subchan, but NTSC-M standard\n");
79
125
        if (tuner.audmode > V4L2_TUNER_MODE_LANG1_LANG2)
80
126
                return fail("invalid audio mode\n");
81
 
        // Ambiguous whether this is allowed or not
82
 
        //              if (!tv && tuner.audmode > V4L2_TUNER_MODE_STEREO)
83
 
        //                      return -16;
 
127
        if (!tv && tuner.audmode > V4L2_TUNER_MODE_STEREO)
 
128
                return fail("invalid audio mode for radio device\n");
84
129
        if (tuner.signal > 65535)
85
130
                return fail("signal too large\n");
86
131
        if (tuner.capability & V4L2_TUNER_CAP_STEREO)
87
132
                valid_modes[V4L2_TUNER_MODE_STEREO] = true;
 
133
        if (tuner.capability & V4L2_TUNER_CAP_LANG1)
 
134
                valid_modes[V4L2_TUNER_MODE_LANG1] = true;
88
135
        if (tuner.capability & V4L2_TUNER_CAP_LANG2) {
89
136
                valid_modes[V4L2_TUNER_MODE_LANG2] = true;
90
137
                valid_modes[V4L2_TUNER_MODE_LANG1_LANG2] = true;
100
147
                        fail("failure to get new tuner audmode\n");
101
148
                if (tun.audmode > V4L2_TUNER_MODE_LANG1_LANG2)
102
149
                        return fail("invalid new audmode\n");
103
 
                // Ambiguous whether this is allowed or not
104
 
                //      if (!tv && tun.audmode > V4L2_TUNER_MODE_STEREO)
105
 
                //              return -21;
106
 
                //      if (!valid_modes[tun.audmode])
107
 
                //              return fail("accepted invalid audmode %d\n", audmode);
 
150
                if (!valid_modes[tun.audmode])
 
151
                        return fail("accepted invalid audmode %d\n", audmode);
108
152
        }
109
 
        return 0;
 
153
        return checkEnumFreqBands(node, tuner.index, tuner.type, tuner.capability);
110
154
}
111
155
 
112
156
int testTuner(struct node *node)
125
169
                memset(tuner.reserved, 0, sizeof(tuner.reserved));
126
170
                tuner.index = t;
127
171
                ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
128
 
                if (ret == EINVAL && t == 0)
129
 
                        return -ENOSYS;
 
172
                if (ret == ENOTTY)
 
173
                        return ret;
130
174
                if (ret == EINVAL)
131
175
                        break;
132
176
                if (ret)
167
211
                ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
168
212
                if (ret)
169
213
                        return fail("could not get tuner %d\n", t);
170
 
                last_type = tuner.type;
 
214
                last_type = (enum v4l2_tuner_type)tuner.type;
171
215
                memset(&freq, 0, sizeof(freq));
172
216
                freq.tuner = t;
173
217
                ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
207
251
                        return fail("could not set rangehigh frequency\n");
208
252
                freq.frequency = tuner.rangelow - 1;
209
253
                ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
210
 
                if (ret != EINVAL)
211
 
                        return fail("set rangelow-1 frequency did not return EINVAL\n");
 
254
                if (ret)
 
255
                        return fail("could not set rangelow-1 frequency\n");
 
256
                ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
 
257
                if (ret || freq.frequency != tuner.rangelow)
 
258
                        return fail("frequency rangelow-1 wasn't mapped to rangelow\n");
212
259
                freq.frequency = tuner.rangehigh + 1;
213
260
                ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
214
 
                if (ret != EINVAL)
215
 
                        return fail("set rangehigh+1 frequency did not return EINVAL\n");
 
261
                if (ret)
 
262
                        return fail("could not set rangehigh+1 frequency\n");
 
263
                ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
 
264
                if (ret || freq.frequency != tuner.rangehigh)
 
265
                        return fail("frequency rangehigh+1 wasn't mapped to rangehigh\n");
216
266
        }
217
267
 
218
 
        /* There is an ambiguity in the API and G/S_FREQUENCY: you cannot specify
219
 
           correctly whether to the ioctl is for a tuner or a modulator. This should
220
 
           be corrected, but until then the tests below have to be skipped if there
221
 
           is a modulator of index t. */
222
 
        if (node->modulators > t)
 
268
        /* If this is a modulator device, then skip the remaining tests */
 
269
        if (node->caps & V4L2_CAP_MODULATOR)
223
270
                return 0;
224
271
 
225
272
        freq.tuner = t;
226
273
        ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
227
 
        if (ret != EINVAL)
 
274
        if (ret != EINVAL && ret != ENOTTY)
228
275
                return fail("could get frequency for invalid tuner %d\n", t);
229
276
        freq.tuner = t;
230
277
        freq.type = last_type;
231
278
        // TV: 400 Mhz Radio: 100 MHz
232
279
        freq.frequency = last_type == V4L2_TUNER_ANALOG_TV ? 6400 : 1600000;
233
280
        ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
234
 
        if (ret != EINVAL)
 
281
        if (ret != EINVAL && ret != ENOTTY)
235
282
                return fail("could set frequency for invalid tuner %d\n", t);
236
 
        return node->tuners ? 0 : -ENOSYS;
 
283
        return node->tuners ? 0 : ENOTTY;
 
284
}
 
285
 
 
286
int testTunerHwSeek(struct node *node)
 
287
{
 
288
        struct v4l2_hw_freq_seek seek;
 
289
        unsigned t;
 
290
        int ret;
 
291
 
 
292
        for (t = 0; t < node->tuners; t++) {
 
293
                struct v4l2_tuner tuner;
 
294
                
 
295
                tuner.index = t;
 
296
                ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
 
297
                if (ret)
 
298
                        return fail("could not get tuner %d\n", t);
 
299
 
 
300
                memset(&seek, 0, sizeof(seek));
 
301
                seek.tuner = t;
 
302
                seek.type = V4L2_TUNER_RADIO;
 
303
                ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
 
304
                if (!(node->caps & V4L2_CAP_HW_FREQ_SEEK) && ret != ENOTTY)
 
305
                        return fail("hw seek supported but capability not set\n");
 
306
                if (!node->is_radio && ret != ENOTTY)
 
307
                        return fail("hw seek supported on a non-radio node?!\n");
 
308
                if (!node->is_radio || !(node->caps & V4L2_CAP_HW_FREQ_SEEK))
 
309
                        return ENOTTY;
 
310
                seek.type = V4L2_TUNER_ANALOG_TV;
 
311
                ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
 
312
                if (ret != EINVAL)
 
313
                        return fail("hw seek accepted TV tuner\n");
 
314
                seek.type = V4L2_TUNER_RADIO;
 
315
                seek.seek_upward = 1;
 
316
                ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
 
317
                if (ret == EINVAL && (tuner.capability & V4L2_TUNER_CAP_HWSEEK_BOUNDED))
 
318
                        return fail("hw bounded seek failed\n");
 
319
                if (ret && ret != EINVAL && ret != ENODATA)
 
320
                        return fail("hw bounded seek failed with error %d\n", ret);
 
321
                seek.wrap_around = 1;
 
322
                ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
 
323
                if (ret == EINVAL && (tuner.capability & V4L2_TUNER_CAP_HWSEEK_WRAP))
 
324
                        return fail("hw wrapped seek failed\n");
 
325
                if (ret && ret != EINVAL && ret != ENODATA)
 
326
                        return fail("hw wrapped seek failed with error %d\n", ret);
 
327
                if (check_0(seek.reserved, sizeof(seek.reserved)))
 
328
                        return fail("non-zero reserved fields\n");
 
329
        }
 
330
        memset(&seek, 0, sizeof(seek));
 
331
        seek.tuner = node->tuners;
 
332
        seek.type = V4L2_TUNER_RADIO;
 
333
        ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
 
334
        if (ret != EINVAL && ret != ENOTTY)
 
335
                return fail("hw seek for invalid tuner didn't return EINVAL or ENOTTY\n");
 
336
        return ret == ENOTTY ? ret : 0;
237
337
}
238
338
 
239
339
static int checkInput(struct node *node, const struct v4l2_input &descr, unsigned i)
275
375
        int ret = doioctl(node, VIDIOC_G_INPUT, &cur_input);
276
376
        int i = 0;
277
377
 
278
 
        if (ret == EINVAL) {
 
378
        if (ret == ENOTTY) {
279
379
                descr.index = 0;
280
380
                ret = doioctl(node, VIDIOC_ENUMINPUT, &descr);
281
 
                if (ret != EINVAL)
 
381
                if (ret != ENOTTY)
282
382
                        return fail("G_INPUT not supported, but ENUMINPUT is\n");
283
383
                cur_input = 0;
284
384
                ret = doioctl(node, VIDIOC_S_INPUT, &cur_input);
285
 
                if (ret != EINVAL)
 
385
                if (ret != ENOTTY)
286
386
                        return fail("G_INPUT not supported, but S_INPUT is\n");
287
 
                return -ENOSYS;
 
387
                return ENOTTY;
288
388
        }
289
389
        if (ret)
290
390
                return fail("could not get current input\n");
350
450
                input.index = i;
351
451
 
352
452
                ret = doioctl(node, VIDIOC_ENUMAUDIO, &input);
353
 
                if (i == 0 && ret == EINVAL)
354
 
                        return -ENOSYS;
 
453
                if (ret == ENOTTY)
 
454
                        return ret;
355
455
                if (ret == EINVAL)
356
456
                        break;
357
457
                if (ret)
373
473
        int ret;
374
474
 
375
475
        ret = doioctl(node, VIDIOC_G_AUDIO, &input);
376
 
        if (audioset == 0 && ret != EINVAL)
377
 
                return fail("No audio inputs, but G_AUDIO did not return EINVAL\n");
 
476
        if (audioset == 0 && ret != ENOTTY && ret != EINVAL)
 
477
                return fail("No audio inputs, but G_AUDIO did not return ENOTTY or EINVAL\n");
378
478
        if (audioset) {
379
479
                if (ret)
380
480
                        return fail("Audio inputs, but G_AUDIO returned an error\n");
392
492
                input.index = i;
393
493
                input.mode = 0;
394
494
                ret = doioctl(node, VIDIOC_S_AUDIO, &input);
395
 
                if (!valid && ret != EINVAL)
 
495
                if (!valid && ret != EINVAL && ret != ENOTTY)
396
496
                        return fail("can set invalid audio input %d\n", i);
397
497
                if (valid && ret)
398
498
                        return fail("can't set valid audio input %d\n", i);
420
520
                if (checkInputAudioSet(node, vinput.audioset))
421
521
                        return fail("invalid audioset for input %d\n", i);
422
522
        }
423
 
        return node->audio_inputs ? 0 : -ENOSYS;
 
523
        return node->audio_inputs ? 0 : ENOTTY;
424
524
}
425
525
 
426
526
static int checkModulator(struct node *node, const struct v4l2_modulator &mod, unsigned m)
440
540
        if (mod.capability & (V4L2_TUNER_CAP_NORM |
441
541
                                        V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2))
442
542
                return fail("TV capabilities for radio modulator?\n");
 
543
        fail_on_test(!(mod.capability & V4L2_TUNER_CAP_FREQ_BANDS));
443
544
        if (mod.rangelow >= mod.rangehigh)
444
545
                return fail("rangelow >= rangehigh\n");
445
546
        if (mod.rangelow == 0 || mod.rangehigh == 0xffffffff)
456
557
        if (!(mod.capability & V4L2_TUNER_CAP_RDS) &&
457
558
                        (mod.txsubchans & V4L2_TUNER_SUB_RDS))
458
559
                return fail("RDS subchan, but no RDS caps?\n");
459
 
        return 0;
 
560
        bool have_rds = mod.capability & V4L2_TUNER_CAP_RDS;
 
561
        bool have_rds_method = mod.capability &
 
562
                        (V4L2_TUNER_CAP_RDS_BLOCK_IO | V4L2_TUNER_CAP_RDS_CONTROLS);
 
563
        if (have_rds ^ have_rds_method)
 
564
                return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n");
 
565
        if ((mod.capability & V4L2_TUNER_CAP_RDS) &&
 
566
                        !(node->caps & V4L2_CAP_READWRITE))
 
567
                return fail("V4L2_TUNER_CAP_RDS set, but not V4L2_CAP_READWRITE\n");
 
568
        return checkEnumFreqBands(node, mod.index, V4L2_TUNER_RADIO, mod.capability);
460
569
}
461
570
 
462
571
int testModulator(struct node *node)
471
580
                memset(mod.reserved, 0, sizeof(mod.reserved));
472
581
                mod.index = m;
473
582
                ret = doioctl(node, VIDIOC_G_MODULATOR, &mod);
474
 
                if (ret == EINVAL && m == 0)
475
 
                        return -ENOSYS;
 
583
                if (ret == ENOTTY)
 
584
                        return ret;
476
585
                if (ret == EINVAL)
477
586
                        break;
478
587
                if (ret)
542
651
                        return fail("could not set rangehigh frequency\n");
543
652
                freq.frequency = modulator.rangelow - 1;
544
653
                ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
545
 
                if (ret != EINVAL)
546
 
                        return fail("set rangelow-1 frequency did not return EINVAL\n");
 
654
                if (ret)
 
655
                        return fail("could not set rangelow-1 frequency\n");
 
656
                ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
 
657
                if (ret || freq.frequency != modulator.rangelow)
 
658
                        return fail("frequency rangelow-1 wasn't mapped to rangelow\n");
547
659
                freq.frequency = modulator.rangehigh + 1;
548
660
                ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
549
 
                if (ret != EINVAL)
550
 
                        return fail("set rangehigh+1 frequency did not return EINVAL\n");
 
661
                if (ret)
 
662
                        return fail("could not set rangehigh+1 frequency\n");
 
663
                ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
 
664
                if (ret || freq.frequency != modulator.rangehigh)
 
665
                        return fail("frequency rangehigh+1 wasn't mapped to rangehigh\n");
551
666
        }
552
667
 
553
 
        /* There is an ambiguity in the API and G/S_FREQUENCY: you cannot specify
554
 
           correctly whether to the ioctl is for a tuner or a modulator. This should
555
 
           be corrected, but until then the tests below have to be skipped if there
556
 
           is a tuner of index m. */
557
 
        if (node->tuners > m)
 
668
        /* If this is a tuner device, then skip the remaining tests */
 
669
        if (node->caps & V4L2_CAP_TUNER)
558
670
                return 0;
559
671
 
560
672
        freq.tuner = m;
561
673
        ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
562
 
        if (ret != EINVAL)
 
674
        if (ret != EINVAL && ret != ENOTTY)
563
675
                return fail("could get frequency for invalid modulator %d\n", m);
564
676
        freq.tuner = m;
565
677
        // Radio: 100 MHz
566
678
        freq.frequency = 1600000;
567
679
        ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
568
 
        if (ret != EINVAL)
 
680
        if (ret != EINVAL && ret != ENOTTY)
569
681
                return fail("could set frequency for invalid modulator %d\n", m);
570
 
        return node->modulators ? 0 : -ENOSYS;
 
682
        return node->modulators ? 0 : ENOTTY;
571
683
}
572
684
 
573
685
static int checkOutput(struct node *node, const struct v4l2_output &descr, unsigned o)
605
717
        int ret = doioctl(node, VIDIOC_G_OUTPUT, &cur_output);
606
718
        int o = 0;
607
719
 
608
 
        if (ret == EINVAL) {
 
720
        if (ret == ENOTTY) {
609
721
                descr.index = 0;
610
722
                ret = doioctl(node, VIDIOC_ENUMOUTPUT, &descr);
611
 
                if (ret != EINVAL)
 
723
                if (ret != ENOTTY)
612
724
                        return fail("G_OUTPUT not supported, but ENUMOUTPUT is\n");
613
725
                output = 0;
614
726
                ret = doioctl(node, VIDIOC_S_OUTPUT, &output);
615
 
                if (ret != EINVAL)
 
727
                if (ret != ENOTTY)
616
728
                        return fail("G_OUTPUT not supported, but S_OUTPUT is\n");
617
 
                return -ENOSYS;
618
729
        }
619
730
        if (ret)
620
731
                return ret;
674
785
                output.index = o;
675
786
 
676
787
                ret = doioctl(node, VIDIOC_ENUMAUDOUT, &output);
677
 
                if (o == 0 && ret == EINVAL)
678
 
                        return -ENOSYS;
 
788
                if (ret == ENOTTY)
 
789
                        return ENOTTY;
679
790
                if (ret == EINVAL)
680
791
                        break;
681
792
                if (ret)
698
809
        int ret;
699
810
 
700
811
        ret = doioctl(node, VIDIOC_G_AUDOUT, &output);
701
 
        if (audioset == 0 && ret != EINVAL)
702
 
                return fail("No audio outputs, but G_AUDOUT did not return EINVAL\n");
 
812
        if (audioset == 0 && ret != EINVAL && ret != ENOTTY)
 
813
                return fail("No audio outputs, but G_AUDOUT did not return EINVAL or ENOTTY\n");
703
814
        if (audioset) {
704
815
                if (ret)
705
816
                        return fail("Audio outputs, but G_AUDOUT returned an error\n");
717
828
                output.index = i;
718
829
                output.mode = 0;
719
830
                ret = doioctl(node, VIDIOC_S_AUDOUT, &output);
720
 
                if (!valid && ret != EINVAL)
 
831
                if (!valid && ret != EINVAL && ret != ENOTTY)
721
832
                        return fail("can set invalid audio output %d\n", i);
722
833
                if (valid && ret)
723
834
                        return fail("can't set valid audio output %d\n", i);
746
857
                        return fail("invalid audioset for output %d\n", o);
747
858
        }
748
859
 
749
 
        if (node->audio_outputs == 0 && node->audio_inputs && (caps & V4L2_CAP_AUDIO))
 
860
        if (node->audio_outputs == 0 && node->audio_inputs == 0 && (node->caps & V4L2_CAP_AUDIO))
750
861
                return fail("no audio inputs or outputs reported, but CAP_AUDIO set\n");
751
 
        return node->audio_outputs ? 0 : -ENOSYS;
 
862
        return node->audio_outputs ? 0 : ENOTTY;
752
863
}