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