34
34
#define MAGIC 0x1eadbeef
36
static int checkEnumFreqBands(struct node *node, __u32 tuner, __u32 type, __u32 caps)
42
struct v4l2_frequency_band band;
45
memset(band.reserved, 0, sizeof(band.reserved));
49
ret = doioctl(node, VIDIOC_ENUM_FREQ_BANDS, &band);
50
if (ret == EINVAL && i)
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));
64
fail_on_test(caps_union != caps);
36
68
static int checkTuner(struct node *node, const struct v4l2_tuner &tuner,
37
69
unsigned t, v4l2_std_id std)
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;
44
78
if (tuner.index != t)
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)
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;
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);
211
return fail("set rangelow-1 frequency did not return EINVAL\n");
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);
215
return fail("set rangehigh+1 frequency did not return EINVAL\n");
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");
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)
226
273
ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
274
if (ret != EINVAL && ret != ENOTTY)
228
275
return fail("could get frequency for invalid tuner %d\n", 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);
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;
286
int testTunerHwSeek(struct node *node)
288
struct v4l2_hw_freq_seek seek;
292
for (t = 0; t < node->tuners; t++) {
293
struct v4l2_tuner tuner;
296
ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
298
return fail("could not get tuner %d\n", t);
300
memset(&seek, 0, sizeof(seek));
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))
310
seek.type = V4L2_TUNER_ANALOG_TV;
311
ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek);
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");
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;
239
339
static int checkInput(struct node *node, const struct v4l2_input &descr, unsigned i)
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");
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);
462
571
int testModulator(struct node *node)
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);
546
return fail("set rangelow-1 frequency did not return EINVAL\n");
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);
550
return fail("set rangehigh+1 frequency did not return EINVAL\n");
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");
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)
561
673
ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
674
if (ret != EINVAL && ret != ENOTTY)
563
675
return fail("could get frequency for invalid modulator %d\n", m);
565
677
// Radio: 100 MHz
566
678
freq.frequency = 1600000;
567
679
ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
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;
573
685
static int checkOutput(struct node *node, const struct v4l2_output &descr, unsigned o)