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