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