1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/kernel.h>
23#include <linux/slab.h>
24#include "pvrusb2-context.h"
25#include "pvrusb2-hdw.h"
26#include "pvrusb2.h"
27#include "pvrusb2-debug.h"
28#include "pvrusb2-v4l2.h"
29#include "pvrusb2-ioread.h"
30#include <linux/videodev2.h>
31#include <linux/module.h>
32#include <media/v4l2-dev.h>
33#include <media/v4l2-device.h>
34#include <media/v4l2-fh.h>
35#include <media/v4l2-common.h>
36#include <media/v4l2-ioctl.h>
37
38struct pvr2_v4l2_dev;
39struct pvr2_v4l2_fh;
40struct pvr2_v4l2;
41
42struct pvr2_v4l2_dev {
43 struct video_device devbase;
44 struct pvr2_v4l2 *v4lp;
45 struct pvr2_context_stream *stream;
46
47 enum pvr2_config config;
48 int v4l_type;
49 enum pvr2_v4l_type minor_type;
50};
51
52struct pvr2_v4l2_fh {
53 struct v4l2_fh fh;
54 struct pvr2_channel channel;
55 struct pvr2_v4l2_dev *pdi;
56 struct pvr2_ioread *rhp;
57 struct file *file;
58 wait_queue_head_t wait_data;
59 int fw_mode_flag;
60
61 unsigned char *input_map;
62 unsigned int input_cnt;
63};
64
65struct pvr2_v4l2 {
66 struct pvr2_channel channel;
67
68
69
70
71 struct pvr2_v4l2_dev *dev_video;
72 struct pvr2_v4l2_dev *dev_radio;
73};
74
75static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
76module_param_array(video_nr, int, NULL, 0444);
77MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
78static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
79module_param_array(radio_nr, int, NULL, 0444);
80MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
81static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
82module_param_array(vbi_nr, int, NULL, 0444);
83MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
84
85static struct v4l2_fmtdesc pvr_fmtdesc [] = {
86 {
87 .index = 0,
88 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
89 .flags = V4L2_FMT_FLAG_COMPRESSED,
90 .description = "MPEG1/2",
91
92
93 .pixelformat = 0,
94 }
95};
96
97#define PVR_FORMAT_PIX 0
98#define PVR_FORMAT_VBI 1
99
100static struct v4l2_format pvr_format [] = {
101 [PVR_FORMAT_PIX] = {
102 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
103 .fmt = {
104 .pix = {
105 .width = 720,
106 .height = 576,
107
108
109 .pixelformat = 0,
110 .field = V4L2_FIELD_INTERLACED,
111 .bytesperline = 0,
112
113
114 .sizeimage = (32*1024),
115 .colorspace = 0,
116 .priv = 0
117 }
118 }
119 },
120 [PVR_FORMAT_VBI] = {
121 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
122 .fmt = {
123 .vbi = {
124 .sampling_rate = 27000000,
125 .offset = 248,
126 .samples_per_line = 1443,
127 .sample_format = V4L2_PIX_FMT_GREY,
128 .start = { 0, 0 },
129 .count = { 0, 0 },
130 .flags = 0,
131 }
132 }
133 }
134};
135
136
137
138
139
140
141static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
142{
143 struct pvr2_v4l2_fh *fh = file->private_data;
144 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
145
146 strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver));
147 strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
148 sizeof(cap->bus_info));
149 strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
150 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
151 V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
152 V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
153 switch (fh->pdi->devbase.vfl_type) {
154 case VFL_TYPE_GRABBER:
155 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
156 break;
157 case VFL_TYPE_RADIO:
158 cap->device_caps = V4L2_CAP_RADIO;
159 break;
160 }
161 cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE;
162 return 0;
163}
164
165static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
166{
167 struct pvr2_v4l2_fh *fh = file->private_data;
168 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
169 int val = 0;
170 int ret;
171
172 ret = pvr2_ctrl_get_value(
173 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val);
174 *std = val;
175 return ret;
176}
177
178static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id std)
179{
180 struct pvr2_v4l2_fh *fh = file->private_data;
181 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
182
183 return pvr2_ctrl_set_value(
184 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), std);
185}
186
187static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
188{
189 struct pvr2_v4l2_fh *fh = file->private_data;
190 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
191 int val = 0;
192 int ret;
193
194 ret = pvr2_ctrl_get_value(
195 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val);
196 *std = val;
197 return ret;
198}
199
200static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
201{
202 struct pvr2_v4l2_fh *fh = file->private_data;
203 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
204 struct pvr2_ctrl *cptr;
205 struct v4l2_input tmp;
206 unsigned int cnt;
207 int val;
208
209 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
210
211 memset(&tmp, 0, sizeof(tmp));
212 tmp.index = vi->index;
213 if (vi->index >= fh->input_cnt)
214 return -EINVAL;
215 val = fh->input_map[vi->index];
216 switch (val) {
217 case PVR2_CVAL_INPUT_TV:
218 case PVR2_CVAL_INPUT_DTV:
219 case PVR2_CVAL_INPUT_RADIO:
220 tmp.type = V4L2_INPUT_TYPE_TUNER;
221 break;
222 case PVR2_CVAL_INPUT_SVIDEO:
223 case PVR2_CVAL_INPUT_COMPOSITE:
224 tmp.type = V4L2_INPUT_TYPE_CAMERA;
225 break;
226 default:
227 return -EINVAL;
228 }
229
230 cnt = 0;
231 pvr2_ctrl_get_valname(cptr, val,
232 tmp.name, sizeof(tmp.name) - 1, &cnt);
233 tmp.name[cnt] = 0;
234
235
236
237
238
239
240
241
242
243
244 *vi = tmp;
245 return 0;
246}
247
248static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
249{
250 struct pvr2_v4l2_fh *fh = file->private_data;
251 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
252 unsigned int idx;
253 struct pvr2_ctrl *cptr;
254 int val;
255 int ret;
256
257 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
258 val = 0;
259 ret = pvr2_ctrl_get_value(cptr, &val);
260 *i = 0;
261 for (idx = 0; idx < fh->input_cnt; idx++) {
262 if (fh->input_map[idx] == val) {
263 *i = idx;
264 break;
265 }
266 }
267 return ret;
268}
269
270static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
271{
272 struct pvr2_v4l2_fh *fh = file->private_data;
273 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
274
275 if (inp >= fh->input_cnt)
276 return -EINVAL;
277 return pvr2_ctrl_set_value(
278 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
279 fh->input_map[inp]);
280}
281
282static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
283{
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299 if (vin->index > 0)
300 return -EINVAL;
301 strncpy(vin->name, "PVRUSB2 Audio", 14);
302 vin->capability = V4L2_AUDCAP_STEREO;
303 return 0;
304}
305
306static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
307{
308
309 vin->index = 0;
310 strncpy(vin->name, "PVRUSB2 Audio", 14);
311 vin->capability = V4L2_AUDCAP_STEREO;
312 return 0;
313}
314
315static int pvr2_s_audio(struct file *file, void *priv, const struct v4l2_audio *vout)
316{
317 if (vout->index)
318 return -EINVAL;
319 return 0;
320}
321
322static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
323{
324 struct pvr2_v4l2_fh *fh = file->private_data;
325 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
326
327 if (vt->index != 0)
328 return -EINVAL;
329
330 pvr2_hdw_execute_tuner_poll(hdw);
331 return pvr2_hdw_get_tuner_status(hdw, vt);
332}
333
334static int pvr2_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
335{
336 struct pvr2_v4l2_fh *fh = file->private_data;
337 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
338
339 if (vt->index != 0)
340 return -EINVAL;
341
342 return pvr2_ctrl_set_value(
343 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE),
344 vt->audmode);
345}
346
347static int pvr2_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
348{
349 struct pvr2_v4l2_fh *fh = file->private_data;
350 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
351 unsigned long fv;
352 struct v4l2_tuner vt;
353 int cur_input;
354 struct pvr2_ctrl *ctrlp;
355 int ret;
356
357 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
358 if (ret != 0)
359 return ret;
360 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
361 ret = pvr2_ctrl_get_value(ctrlp, &cur_input);
362 if (ret != 0)
363 return ret;
364 if (vf->type == V4L2_TUNER_RADIO) {
365 if (cur_input != PVR2_CVAL_INPUT_RADIO)
366 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
367 } else {
368 if (cur_input == PVR2_CVAL_INPUT_RADIO)
369 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
370 }
371 fv = vf->frequency;
372 if (vt.capability & V4L2_TUNER_CAP_LOW)
373 fv = (fv * 125) / 2;
374 else
375 fv = fv * 62500;
376 return pvr2_ctrl_set_value(
377 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
378}
379
380static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
381{
382 struct pvr2_v4l2_fh *fh = file->private_data;
383 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
384 int val = 0;
385 int cur_input;
386 struct v4l2_tuner vt;
387 int ret;
388
389 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
390 if (ret != 0)
391 return ret;
392 ret = pvr2_ctrl_get_value(
393 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
394 &val);
395 if (ret != 0)
396 return ret;
397 pvr2_ctrl_get_value(
398 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
399 &cur_input);
400 if (cur_input == PVR2_CVAL_INPUT_RADIO)
401 vf->type = V4L2_TUNER_RADIO;
402 else
403 vf->type = V4L2_TUNER_ANALOG_TV;
404 if (vt.capability & V4L2_TUNER_CAP_LOW)
405 val = (val * 2) / 125;
406 else
407 val /= 62500;
408 vf->frequency = val;
409 return 0;
410}
411
412static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
413{
414
415 if (fd->index != 0)
416 return -EINVAL;
417
418 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
419 return 0;
420}
421
422static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
423{
424 struct pvr2_v4l2_fh *fh = file->private_data;
425 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
426 int val;
427
428 memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format));
429 val = 0;
430 pvr2_ctrl_get_value(
431 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES),
432 &val);
433 vf->fmt.pix.width = val;
434 val = 0;
435 pvr2_ctrl_get_value(
436 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES),
437 &val);
438 vf->fmt.pix.height = val;
439 return 0;
440}
441
442static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
443{
444 struct pvr2_v4l2_fh *fh = file->private_data;
445 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
446 int lmin, lmax, ldef;
447 struct pvr2_ctrl *hcp, *vcp;
448 int h = vf->fmt.pix.height;
449 int w = vf->fmt.pix.width;
450
451 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
452 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
453
454 lmin = pvr2_ctrl_get_min(hcp);
455 lmax = pvr2_ctrl_get_max(hcp);
456 pvr2_ctrl_get_def(hcp, &ldef);
457 if (w == -1)
458 w = ldef;
459 else if (w < lmin)
460 w = lmin;
461 else if (w > lmax)
462 w = lmax;
463 lmin = pvr2_ctrl_get_min(vcp);
464 lmax = pvr2_ctrl_get_max(vcp);
465 pvr2_ctrl_get_def(vcp, &ldef);
466 if (h == -1)
467 h = ldef;
468 else if (h < lmin)
469 h = lmin;
470 else if (h > lmax)
471 h = lmax;
472
473 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
474 sizeof(struct v4l2_format));
475 vf->fmt.pix.width = w;
476 vf->fmt.pix.height = h;
477 return 0;
478}
479
480static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
481{
482 struct pvr2_v4l2_fh *fh = file->private_data;
483 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
484 struct pvr2_ctrl *hcp, *vcp;
485 int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
486
487 if (ret)
488 return ret;
489 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
490 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
491 pvr2_ctrl_set_value(hcp, vf->fmt.pix.width);
492 pvr2_ctrl_set_value(vcp, vf->fmt.pix.height);
493 return 0;
494}
495
496static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
497{
498 struct pvr2_v4l2_fh *fh = file->private_data;
499 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
500 struct pvr2_v4l2_dev *pdi = fh->pdi;
501 int ret;
502
503 if (!fh->pdi->stream) {
504
505
506
507 return -EPERM;
508 }
509 ret = pvr2_hdw_set_stream_type(hdw, pdi->config);
510 if (ret < 0)
511 return ret;
512 return pvr2_hdw_set_streaming(hdw, !0);
513}
514
515static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
516{
517 struct pvr2_v4l2_fh *fh = file->private_data;
518 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
519
520 if (!fh->pdi->stream) {
521
522
523
524 return -EPERM;
525 }
526 return pvr2_hdw_set_streaming(hdw, 0);
527}
528
529static int pvr2_queryctrl(struct file *file, void *priv,
530 struct v4l2_queryctrl *vc)
531{
532 struct pvr2_v4l2_fh *fh = file->private_data;
533 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
534 struct pvr2_ctrl *cptr;
535 int val;
536
537 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
538 cptr = pvr2_hdw_get_ctrl_nextv4l(
539 hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
540 if (cptr)
541 vc->id = pvr2_ctrl_get_v4lid(cptr);
542 } else {
543 cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id);
544 }
545 if (!cptr) {
546 pvr2_trace(PVR2_TRACE_V4LIOCTL,
547 "QUERYCTRL id=0x%x not implemented here",
548 vc->id);
549 return -EINVAL;
550 }
551
552 pvr2_trace(PVR2_TRACE_V4LIOCTL,
553 "QUERYCTRL id=0x%x mapping name=%s (%s)",
554 vc->id, pvr2_ctrl_get_name(cptr),
555 pvr2_ctrl_get_desc(cptr));
556 strlcpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
557 vc->flags = pvr2_ctrl_get_v4lflags(cptr);
558 pvr2_ctrl_get_def(cptr, &val);
559 vc->default_value = val;
560 switch (pvr2_ctrl_get_type(cptr)) {
561 case pvr2_ctl_enum:
562 vc->type = V4L2_CTRL_TYPE_MENU;
563 vc->minimum = 0;
564 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
565 vc->step = 1;
566 break;
567 case pvr2_ctl_bool:
568 vc->type = V4L2_CTRL_TYPE_BOOLEAN;
569 vc->minimum = 0;
570 vc->maximum = 1;
571 vc->step = 1;
572 break;
573 case pvr2_ctl_int:
574 vc->type = V4L2_CTRL_TYPE_INTEGER;
575 vc->minimum = pvr2_ctrl_get_min(cptr);
576 vc->maximum = pvr2_ctrl_get_max(cptr);
577 vc->step = 1;
578 break;
579 default:
580 pvr2_trace(PVR2_TRACE_V4LIOCTL,
581 "QUERYCTRL id=0x%x name=%s not mappable",
582 vc->id, pvr2_ctrl_get_name(cptr));
583 return -EINVAL;
584 }
585 return 0;
586}
587
588static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
589{
590 struct pvr2_v4l2_fh *fh = file->private_data;
591 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
592 unsigned int cnt = 0;
593 int ret;
594
595 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id),
596 vm->index,
597 vm->name, sizeof(vm->name) - 1,
598 &cnt);
599 vm->name[cnt] = 0;
600 return ret;
601}
602
603static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
604{
605 struct pvr2_v4l2_fh *fh = file->private_data;
606 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
607 int val = 0;
608 int ret;
609
610 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
611 &val);
612 vc->value = val;
613 return ret;
614}
615
616static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
617{
618 struct pvr2_v4l2_fh *fh = file->private_data;
619 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
620
621 return pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
622 vc->value);
623}
624
625static int pvr2_g_ext_ctrls(struct file *file, void *priv,
626 struct v4l2_ext_controls *ctls)
627{
628 struct pvr2_v4l2_fh *fh = file->private_data;
629 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
630 struct v4l2_ext_control *ctrl;
631 struct pvr2_ctrl *cptr;
632 unsigned int idx;
633 int val;
634 int ret;
635
636 ret = 0;
637 for (idx = 0; idx < ctls->count; idx++) {
638 ctrl = ctls->controls + idx;
639 cptr = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
640 if (cptr) {
641 if (ctls->which == V4L2_CTRL_WHICH_DEF_VAL)
642 pvr2_ctrl_get_def(cptr, &val);
643 else
644 ret = pvr2_ctrl_get_value(cptr, &val);
645 } else
646 ret = -EINVAL;
647
648 if (ret) {
649 ctls->error_idx = idx;
650 return ret;
651 }
652
653
654 ctrl->value64 = 0;
655 ctrl->value = val;
656 }
657 return 0;
658}
659
660static int pvr2_s_ext_ctrls(struct file *file, void *priv,
661 struct v4l2_ext_controls *ctls)
662{
663 struct pvr2_v4l2_fh *fh = file->private_data;
664 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
665 struct v4l2_ext_control *ctrl;
666 unsigned int idx;
667 int ret;
668
669
670 if (ctls->which == V4L2_CTRL_WHICH_DEF_VAL)
671 return -EINVAL;
672
673 ret = 0;
674 for (idx = 0; idx < ctls->count; idx++) {
675 ctrl = ctls->controls + idx;
676 ret = pvr2_ctrl_set_value(
677 pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id),
678 ctrl->value);
679 if (ret) {
680 ctls->error_idx = idx;
681 return ret;
682 }
683 }
684 return 0;
685}
686
687static int pvr2_try_ext_ctrls(struct file *file, void *priv,
688 struct v4l2_ext_controls *ctls)
689{
690 struct pvr2_v4l2_fh *fh = file->private_data;
691 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
692 struct v4l2_ext_control *ctrl;
693 struct pvr2_ctrl *pctl;
694 unsigned int idx;
695
696
697
698 for (idx = 0; idx < ctls->count; idx++) {
699 ctrl = ctls->controls + idx;
700 pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
701 if (!pctl) {
702 ctls->error_idx = idx;
703 return -EINVAL;
704 }
705 }
706 return 0;
707}
708
709static int pvr2_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap)
710{
711 struct pvr2_v4l2_fh *fh = file->private_data;
712 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
713 int ret;
714
715 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
716 return -EINVAL;
717 ret = pvr2_hdw_get_cropcap(hdw, cap);
718 cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
719 return ret;
720}
721
722static int pvr2_g_selection(struct file *file, void *priv,
723 struct v4l2_selection *sel)
724{
725 struct pvr2_v4l2_fh *fh = file->private_data;
726 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
727 struct v4l2_cropcap cap;
728 int val = 0;
729 int ret;
730
731 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
732 return -EINVAL;
733
734 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
735
736 switch (sel->target) {
737 case V4L2_SEL_TGT_CROP:
738 ret = pvr2_ctrl_get_value(
739 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
740 if (ret != 0)
741 return -EINVAL;
742 sel->r.left = val;
743 ret = pvr2_ctrl_get_value(
744 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
745 if (ret != 0)
746 return -EINVAL;
747 sel->r.top = val;
748 ret = pvr2_ctrl_get_value(
749 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
750 if (ret != 0)
751 return -EINVAL;
752 sel->r.width = val;
753 ret = pvr2_ctrl_get_value(
754 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
755 if (ret != 0)
756 return -EINVAL;
757 sel->r.height = val;
758 break;
759 case V4L2_SEL_TGT_CROP_DEFAULT:
760 ret = pvr2_hdw_get_cropcap(hdw, &cap);
761 sel->r = cap.defrect;
762 break;
763 case V4L2_SEL_TGT_CROP_BOUNDS:
764 ret = pvr2_hdw_get_cropcap(hdw, &cap);
765 sel->r = cap.bounds;
766 break;
767 default:
768 return -EINVAL;
769 }
770 return ret;
771}
772
773static int pvr2_s_selection(struct file *file, void *priv,
774 struct v4l2_selection *sel)
775{
776 struct pvr2_v4l2_fh *fh = file->private_data;
777 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
778 int ret;
779
780 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
781 sel->target != V4L2_SEL_TGT_CROP)
782 return -EINVAL;
783 ret = pvr2_ctrl_set_value(
784 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
785 sel->r.left);
786 if (ret != 0)
787 return -EINVAL;
788 ret = pvr2_ctrl_set_value(
789 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
790 sel->r.top);
791 if (ret != 0)
792 return -EINVAL;
793 ret = pvr2_ctrl_set_value(
794 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
795 sel->r.width);
796 if (ret != 0)
797 return -EINVAL;
798 ret = pvr2_ctrl_set_value(
799 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
800 sel->r.height);
801 if (ret != 0)
802 return -EINVAL;
803 return 0;
804}
805
806static int pvr2_log_status(struct file *file, void *priv)
807{
808 struct pvr2_v4l2_fh *fh = file->private_data;
809 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
810
811 pvr2_hdw_trigger_module_log(hdw);
812 return 0;
813}
814
815static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
816 .vidioc_querycap = pvr2_querycap,
817 .vidioc_s_audio = pvr2_s_audio,
818 .vidioc_g_audio = pvr2_g_audio,
819 .vidioc_enumaudio = pvr2_enumaudio,
820 .vidioc_enum_input = pvr2_enum_input,
821 .vidioc_cropcap = pvr2_cropcap,
822 .vidioc_s_selection = pvr2_s_selection,
823 .vidioc_g_selection = pvr2_g_selection,
824 .vidioc_g_input = pvr2_g_input,
825 .vidioc_s_input = pvr2_s_input,
826 .vidioc_g_frequency = pvr2_g_frequency,
827 .vidioc_s_frequency = pvr2_s_frequency,
828 .vidioc_s_tuner = pvr2_s_tuner,
829 .vidioc_g_tuner = pvr2_g_tuner,
830 .vidioc_g_std = pvr2_g_std,
831 .vidioc_s_std = pvr2_s_std,
832 .vidioc_querystd = pvr2_querystd,
833 .vidioc_log_status = pvr2_log_status,
834 .vidioc_enum_fmt_vid_cap = pvr2_enum_fmt_vid_cap,
835 .vidioc_g_fmt_vid_cap = pvr2_g_fmt_vid_cap,
836 .vidioc_s_fmt_vid_cap = pvr2_s_fmt_vid_cap,
837 .vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap,
838 .vidioc_streamon = pvr2_streamon,
839 .vidioc_streamoff = pvr2_streamoff,
840 .vidioc_queryctrl = pvr2_queryctrl,
841 .vidioc_querymenu = pvr2_querymenu,
842 .vidioc_g_ctrl = pvr2_g_ctrl,
843 .vidioc_s_ctrl = pvr2_s_ctrl,
844 .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
845 .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
846 .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
847};
848
849static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
850{
851 struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
852 enum pvr2_config cfg = dip->config;
853 char msg[80];
854 unsigned int mcnt;
855
856
857
858
859 mcnt = scnprintf(msg, sizeof(msg) - 1,
860 "pvrusb2: unregistered device %s [%s]",
861 video_device_node_name(&dip->devbase),
862 pvr2_config_get_name(cfg));
863 msg[mcnt] = 0;
864
865 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
866
867
868 dip->v4lp = NULL;
869 dip->stream = NULL;
870
871
872
873 video_unregister_device(&dip->devbase);
874
875 printk(KERN_INFO "%s\n", msg);
876
877}
878
879
880static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
881{
882 if (!dip) return;
883 if (!dip->devbase.v4l2_dev->dev) return;
884 dip->devbase.v4l2_dev->dev = NULL;
885 device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
886}
887
888
889static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
890{
891 if (vp->dev_video) {
892 pvr2_v4l2_dev_destroy(vp->dev_video);
893 vp->dev_video = NULL;
894 }
895 if (vp->dev_radio) {
896 pvr2_v4l2_dev_destroy(vp->dev_radio);
897 vp->dev_radio = NULL;
898 }
899
900 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
901 pvr2_channel_done(&vp->channel);
902 kfree(vp);
903}
904
905
906static void pvr2_video_device_release(struct video_device *vdev)
907{
908 struct pvr2_v4l2_dev *dev;
909 dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
910 kfree(dev);
911}
912
913
914static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
915{
916 struct pvr2_v4l2 *vp;
917 vp = container_of(chp,struct pvr2_v4l2,channel);
918 if (!vp->channel.mc_head->disconnect_flag) return;
919 pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
920 pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
921 if (!list_empty(&vp->dev_video->devbase.fh_list) ||
922 !list_empty(&vp->dev_radio->devbase.fh_list))
923 return;
924 pvr2_v4l2_destroy_no_lock(vp);
925}
926
927
928static long pvr2_v4l2_ioctl(struct file *file,
929 unsigned int cmd, unsigned long arg)
930{
931
932 struct pvr2_v4l2_fh *fh = file->private_data;
933 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
934 long ret = -EINVAL;
935
936 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL)
937 v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
938
939 if (!pvr2_hdw_dev_ok(hdw)) {
940 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
941 "ioctl failed - bad or no context");
942 return -EFAULT;
943 }
944
945 ret = video_ioctl2(file, cmd, arg);
946
947 pvr2_hdw_commit_ctl(hdw);
948
949 if (ret < 0) {
950 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
951 pvr2_trace(PVR2_TRACE_V4LIOCTL,
952 "pvr2_v4l2_do_ioctl failure, ret=%ld"
953 " command was:", ret);
954 v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
955 }
956 } else {
957 pvr2_trace(PVR2_TRACE_V4LIOCTL,
958 "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
959 ret, ret);
960 }
961 return ret;
962
963}
964
965
966static int pvr2_v4l2_release(struct file *file)
967{
968 struct pvr2_v4l2_fh *fhp = file->private_data;
969 struct pvr2_v4l2 *vp = fhp->pdi->v4lp;
970 struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
971
972 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
973
974 if (fhp->rhp) {
975 struct pvr2_stream *sp;
976 pvr2_hdw_set_streaming(hdw,0);
977 sp = pvr2_ioread_get_stream(fhp->rhp);
978 if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
979 pvr2_ioread_destroy(fhp->rhp);
980 fhp->rhp = NULL;
981 }
982
983 v4l2_fh_del(&fhp->fh);
984 v4l2_fh_exit(&fhp->fh);
985 file->private_data = NULL;
986
987 pvr2_channel_done(&fhp->channel);
988 pvr2_trace(PVR2_TRACE_STRUCT,
989 "Destroying pvr_v4l2_fh id=%p",fhp);
990 if (fhp->input_map) {
991 kfree(fhp->input_map);
992 fhp->input_map = NULL;
993 }
994 kfree(fhp);
995 if (vp->channel.mc_head->disconnect_flag &&
996 list_empty(&vp->dev_video->devbase.fh_list) &&
997 list_empty(&vp->dev_radio->devbase.fh_list)) {
998 pvr2_v4l2_destroy_no_lock(vp);
999 }
1000 return 0;
1001}
1002
1003
1004static int pvr2_v4l2_open(struct file *file)
1005{
1006 struct pvr2_v4l2_dev *dip;
1007 struct pvr2_v4l2_fh *fhp;
1008 struct pvr2_v4l2 *vp;
1009 struct pvr2_hdw *hdw;
1010 unsigned int input_mask = 0;
1011 unsigned int input_cnt,idx;
1012 int ret = 0;
1013
1014 dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
1015
1016 vp = dip->v4lp;
1017 hdw = vp->channel.hdw;
1018
1019 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
1020
1021 if (!pvr2_hdw_dev_ok(hdw)) {
1022 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
1023 "pvr2_v4l2_open: hardware not ready");
1024 return -EIO;
1025 }
1026
1027 fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
1028 if (!fhp) {
1029 return -ENOMEM;
1030 }
1031
1032 v4l2_fh_init(&fhp->fh, &dip->devbase);
1033 init_waitqueue_head(&fhp->wait_data);
1034 fhp->pdi = dip;
1035
1036 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
1037 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
1038
1039 if (dip->v4l_type == VFL_TYPE_RADIO) {
1040
1041
1042 input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
1043 } else {
1044
1045
1046 input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
1047 (1 << PVR2_CVAL_INPUT_TV) |
1048 (1 << PVR2_CVAL_INPUT_COMPOSITE) |
1049 (1 << PVR2_CVAL_INPUT_SVIDEO));
1050 }
1051 ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
1052 if (ret) {
1053 pvr2_channel_done(&fhp->channel);
1054 pvr2_trace(PVR2_TRACE_STRUCT,
1055 "Destroying pvr_v4l2_fh id=%p (input mask error)",
1056 fhp);
1057
1058 kfree(fhp);
1059 return ret;
1060 }
1061
1062 input_mask &= pvr2_hdw_get_input_available(hdw);
1063 input_cnt = 0;
1064 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1065 if (input_mask & (1 << idx)) input_cnt++;
1066 }
1067 fhp->input_cnt = input_cnt;
1068 fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
1069 if (!fhp->input_map) {
1070 pvr2_channel_done(&fhp->channel);
1071 pvr2_trace(PVR2_TRACE_STRUCT,
1072 "Destroying pvr_v4l2_fh id=%p (input map failure)",
1073 fhp);
1074 kfree(fhp);
1075 return -ENOMEM;
1076 }
1077 input_cnt = 0;
1078 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1079 if (!(input_mask & (1 << idx))) continue;
1080 fhp->input_map[input_cnt++] = idx;
1081 }
1082
1083 fhp->file = file;
1084 file->private_data = fhp;
1085
1086 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1087 v4l2_fh_add(&fhp->fh);
1088
1089 return 0;
1090}
1091
1092
1093static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
1094{
1095 wake_up(&fhp->wait_data);
1096}
1097
1098static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1099{
1100 int ret;
1101 struct pvr2_stream *sp;
1102 struct pvr2_hdw *hdw;
1103 if (fh->rhp) return 0;
1104
1105 if (!fh->pdi->stream) {
1106
1107
1108 return -EPERM;
1109 }
1110
1111
1112
1113 if ((ret = pvr2_channel_claim_stream(&fh->channel,
1114 fh->pdi->stream)) != 0) {
1115
1116 return ret;
1117 }
1118
1119 fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
1120 if (!fh->rhp) {
1121 pvr2_channel_claim_stream(&fh->channel,NULL);
1122 return -ENOMEM;
1123 }
1124
1125 hdw = fh->channel.mc_head->hdw;
1126 sp = fh->pdi->stream->stream;
1127 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
1128 pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
1129 if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1130 return pvr2_ioread_set_enabled(fh->rhp,!0);
1131}
1132
1133
1134static ssize_t pvr2_v4l2_read(struct file *file,
1135 char __user *buff, size_t count, loff_t *ppos)
1136{
1137 struct pvr2_v4l2_fh *fh = file->private_data;
1138 int ret;
1139
1140 if (fh->fw_mode_flag) {
1141 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
1142 char *tbuf;
1143 int c1,c2;
1144 int tcnt = 0;
1145 unsigned int offs = *ppos;
1146
1147 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1148 if (!tbuf) return -ENOMEM;
1149
1150 while (count) {
1151 c1 = count;
1152 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
1153 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
1154 if (c2 < 0) {
1155 tcnt = c2;
1156 break;
1157 }
1158 if (!c2) break;
1159 if (copy_to_user(buff,tbuf,c2)) {
1160 tcnt = -EFAULT;
1161 break;
1162 }
1163 offs += c2;
1164 tcnt += c2;
1165 buff += c2;
1166 count -= c2;
1167 *ppos += c2;
1168 }
1169 kfree(tbuf);
1170 return tcnt;
1171 }
1172
1173 if (!fh->rhp) {
1174 ret = pvr2_v4l2_iosetup(fh);
1175 if (ret) {
1176 return ret;
1177 }
1178 }
1179
1180 for (;;) {
1181 ret = pvr2_ioread_read(fh->rhp,buff,count);
1182 if (ret >= 0) break;
1183 if (ret != -EAGAIN) break;
1184 if (file->f_flags & O_NONBLOCK) break;
1185
1186 ret = wait_event_interruptible(
1187 fh->wait_data,
1188 pvr2_ioread_avail(fh->rhp) >= 0);
1189 if (ret < 0) break;
1190 }
1191
1192 return ret;
1193}
1194
1195
1196static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
1197{
1198 unsigned int mask = 0;
1199 struct pvr2_v4l2_fh *fh = file->private_data;
1200 int ret;
1201
1202 if (fh->fw_mode_flag) {
1203 mask |= POLLIN | POLLRDNORM;
1204 return mask;
1205 }
1206
1207 if (!fh->rhp) {
1208 ret = pvr2_v4l2_iosetup(fh);
1209 if (ret) return POLLERR;
1210 }
1211
1212 poll_wait(file,&fh->wait_data,wait);
1213
1214 if (pvr2_ioread_avail(fh->rhp) >= 0) {
1215 mask |= POLLIN | POLLRDNORM;
1216 }
1217
1218 return mask;
1219}
1220
1221
1222static const struct v4l2_file_operations vdev_fops = {
1223 .owner = THIS_MODULE,
1224 .open = pvr2_v4l2_open,
1225 .release = pvr2_v4l2_release,
1226 .read = pvr2_v4l2_read,
1227 .unlocked_ioctl = pvr2_v4l2_ioctl,
1228 .poll = pvr2_v4l2_poll,
1229};
1230
1231
1232static struct video_device vdev_template = {
1233 .fops = &vdev_fops,
1234};
1235
1236
1237static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1238 struct pvr2_v4l2 *vp,
1239 int v4l_type)
1240{
1241 int mindevnum;
1242 int unit_number;
1243 struct pvr2_hdw *hdw;
1244 int *nr_ptr = NULL;
1245 dip->v4lp = vp;
1246
1247 hdw = vp->channel.mc_head->hdw;
1248 dip->v4l_type = v4l_type;
1249 switch (v4l_type) {
1250 case VFL_TYPE_GRABBER:
1251 dip->stream = &vp->channel.mc_head->video_stream;
1252 dip->config = pvr2_config_mpeg;
1253 dip->minor_type = pvr2_v4l_type_video;
1254 nr_ptr = video_nr;
1255 if (!dip->stream) {
1256 pr_err(KBUILD_MODNAME
1257 ": Failed to set up pvrusb2 v4l video dev"
1258 " due to missing stream instance\n");
1259 return;
1260 }
1261 break;
1262 case VFL_TYPE_VBI:
1263 dip->config = pvr2_config_vbi;
1264 dip->minor_type = pvr2_v4l_type_vbi;
1265 nr_ptr = vbi_nr;
1266 break;
1267 case VFL_TYPE_RADIO:
1268 dip->stream = &vp->channel.mc_head->video_stream;
1269 dip->config = pvr2_config_mpeg;
1270 dip->minor_type = pvr2_v4l_type_radio;
1271 nr_ptr = radio_nr;
1272 break;
1273 default:
1274
1275 pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
1276 " due to unrecognized config\n");
1277 return;
1278 }
1279
1280 dip->devbase = vdev_template;
1281 dip->devbase.release = pvr2_video_device_release;
1282 dip->devbase.ioctl_ops = &pvr2_ioctl_ops;
1283 {
1284 int val;
1285 pvr2_ctrl_get_value(
1286 pvr2_hdw_get_ctrl_by_id(hdw,
1287 PVR2_CID_STDAVAIL), &val);
1288 dip->devbase.tvnorms = (v4l2_std_id)val;
1289 }
1290
1291 mindevnum = -1;
1292 unit_number = pvr2_hdw_get_unit_number(hdw);
1293 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1294 mindevnum = nr_ptr[unit_number];
1295 }
1296 pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
1297 if ((video_register_device(&dip->devbase,
1298 dip->v4l_type, mindevnum) < 0) &&
1299 (video_register_device(&dip->devbase,
1300 dip->v4l_type, -1) < 0)) {
1301 pr_err(KBUILD_MODNAME
1302 ": Failed to register pvrusb2 v4l device\n");
1303 }
1304
1305 printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
1306 video_device_node_name(&dip->devbase),
1307 pvr2_config_get_name(dip->config));
1308
1309 pvr2_hdw_v4l_store_minor_number(hdw,
1310 dip->minor_type,dip->devbase.minor);
1311}
1312
1313
1314struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1315{
1316 struct pvr2_v4l2 *vp;
1317
1318 vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1319 if (!vp) return vp;
1320 pvr2_channel_init(&vp->channel,mnp);
1321 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1322
1323 vp->channel.check_func = pvr2_v4l2_internal_check;
1324
1325
1326 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1327 if (!vp->dev_video) goto fail;
1328 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
1329 if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1330 (1 << PVR2_CVAL_INPUT_RADIO)) {
1331 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1332 if (!vp->dev_radio) goto fail;
1333 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1334 }
1335
1336 return vp;
1337 fail:
1338 pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
1339 pvr2_v4l2_destroy_no_lock(vp);
1340 return NULL;
1341}
1342