powerpc: use consistent types in mktree
[zen-stable.git] / drivers / media / video / pvrusb2 / pvrusb2-v4l2.c
blob2d8825e5b1bef5f3e319fa7dc8a1df4d3629a856
1 /*
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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>
35 struct pvr2_v4l2_dev;
36 struct pvr2_v4l2_fh;
37 struct pvr2_v4l2;
39 struct pvr2_v4l2_dev {
40 struct video_device devbase; /* MUST be first! */
41 struct pvr2_v4l2 *v4lp;
42 struct pvr2_context_stream *stream;
43 /* Information about this device: */
44 enum pvr2_config config; /* Expected stream format */
45 int v4l_type; /* V4L defined type for this device node */
46 enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
49 struct 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 /* Map contiguous ordinal value to input id */
61 unsigned char *input_map;
62 unsigned int input_cnt;
65 struct pvr2_v4l2 {
66 struct pvr2_channel channel;
67 struct pvr2_v4l2_fh *vfirst;
68 struct pvr2_v4l2_fh *vlast;
70 struct v4l2_prio_state prio;
72 /* streams - Note that these must be separately, individually,
73 * allocated pointers. This is because the v4l core is going to
74 * manage their deletion - separately, individually... */
75 struct pvr2_v4l2_dev *dev_video;
76 struct pvr2_v4l2_dev *dev_radio;
79 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
80 module_param_array(video_nr, int, NULL, 0444);
81 MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
82 static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
83 module_param_array(radio_nr, int, NULL, 0444);
84 MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
85 static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
86 module_param_array(vbi_nr, int, NULL, 0444);
87 MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
89 static 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}
100 static struct v4l2_fmtdesc pvr_fmtdesc [] = {
102 .index = 0,
103 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
104 .flags = V4L2_FMT_FLAG_COMPRESSED,
105 .description = "MPEG1/2",
106 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
107 // breaks when I do that.
108 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
109 .reserved = { 0, 0, 0, 0 }
113 #define PVR_FORMAT_PIX 0
114 #define PVR_FORMAT_VBI 1
116 static 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 // This should really be V4L2_PIX_FMT_MPEG,
124 // but xawtv breaks when I do that.
125 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
126 .field = V4L2_FIELD_INTERLACED,
127 .bytesperline = 0, // doesn't make sense
128 // here
129 //FIXME : Don't know what to put here...
130 .sizeimage = (32*1024),
131 .colorspace = 0, // doesn't make sense here
132 .priv = 0
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 }
154 static const char *get_v4l_name(int v4l_type)
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 "?";
166 * pvr_ioctl()
168 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
171 static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
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;
179 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
180 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
183 if (!pvr2_hdw_dev_ok(hdw)) {
184 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
185 "ioctl failed - bad or no context");
186 return -EFAULT;
189 /* check priority */
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;
201 switch (cmd) {
202 case VIDIOC_QUERYCAP:
204 struct v4l2_capability *cap = arg;
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));
211 ret = 0;
212 break;
215 case VIDIOC_G_PRIORITY:
217 enum v4l2_priority *p = arg;
219 *p = v4l2_prio_max(&vp->prio);
220 ret = 0;
221 break;
224 case VIDIOC_S_PRIORITY:
226 enum v4l2_priority *prio = arg;
228 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
229 break;
232 case VIDIOC_ENUMSTD:
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;
240 case VIDIOC_G_STD:
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;
249 case VIDIOC_S_STD:
251 ret = pvr2_ctrl_set_value(
252 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
253 *(v4l2_std_id *)arg);
254 break;
257 case VIDIOC_ENUMINPUT:
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;
265 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
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;
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;
289 if (ret < 0) break;
291 cnt = 0;
292 pvr2_ctrl_get_valname(cptr,val,
293 tmp.name,sizeof(tmp.name)-1,&cnt);
294 tmp.name[cnt] = 0;
296 /* Don't bother with audioset, since this driver currently
297 always switches the audio whenever the video is
298 switched. */
300 /* Handling std is a tougher problem. It doesn't make
301 sense in cases where a device might be multi-standard.
302 We could just copy out the current value for the
303 standard, but it can change over time. For now just
304 leave it zero. */
306 memcpy(vi, &tmp, sizeof(tmp));
308 ret = 0;
309 break;
312 case VIDIOC_G_INPUT:
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;
328 break;
331 case VIDIOC_S_INPUT:
333 struct v4l2_input *vi = (struct v4l2_input *)arg;
334 if (vi->index >= fh->input_cnt) {
335 ret = -ERANGE;
336 break;
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;
344 case VIDIOC_ENUMAUDIO:
346 /* pkt: FIXME: We are returning one "fake" input here
347 which could very well be called "whatever_we_like".
348 This is for apps that want to see an audio input
349 just to feel comfortable, as well as to test if
350 it can do stereo or sth. There is actually no guarantee
351 that the actual audio input cannot change behind the app's
352 back, but most applications should not mind that either.
354 Hopefully, mplayer people will work with us on this (this
355 whole mess is to support mplayer pvr://), or Hans will come
356 up with a more standard way to say "we have inputs but we
357 don 't want you to change them independent of video" which
358 will sort this mess.
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;
370 case VIDIOC_G_AUDIO:
372 /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
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;
382 case VIDIOC_S_AUDIO:
384 ret = -EINVAL;
385 break;
387 case VIDIOC_G_TUNER:
389 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
391 if (vt->index != 0) break; /* Only answer for the 1st tuner */
393 pvr2_hdw_execute_tuner_poll(hdw);
394 ret = pvr2_hdw_get_tuner_status(hdw,vt);
395 break;
398 case VIDIOC_S_TUNER:
400 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
402 if (vt->index != 0)
403 break;
405 ret = pvr2_ctrl_set_value(
406 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
407 vt->audmode);
408 break;
411 case VIDIOC_S_FREQUENCY:
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);
428 } else {
429 if (cur_input == PVR2_CVAL_INPUT_RADIO) {
430 pvr2_ctrl_set_value(ctrlp,
431 PVR2_CVAL_INPUT_TV);
434 fv = vf->frequency;
435 if (vt.capability & V4L2_TUNER_CAP_LOW) {
436 fv = (fv * 125) / 2;
437 } else {
438 fv = fv * 62500;
440 ret = pvr2_ctrl_set_value(
441 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
442 break;
445 case VIDIOC_G_FREQUENCY:
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;
465 if (vt.capability & V4L2_TUNER_CAP_LOW) {
466 val = (val * 2) / 125;
467 } else {
468 val /= 62500;
470 vf->frequency = val;
471 break;
474 case VIDIOC_ENUM_FMT:
476 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
478 /* Only one format is supported : mpeg.*/
479 if (fd->index != 0)
480 break;
482 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
483 ret = 0;
484 break;
487 case VIDIOC_G_FMT:
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 // ????? Still need to figure out to do VBI correctly
509 ret = -EINVAL;
510 break;
511 default:
512 ret = -EINVAL;
513 break;
515 break;
518 case VIDIOC_TRY_FMT:
519 case VIDIOC_S_FMT:
521 struct v4l2_format *vf = (struct v4l2_format *)arg;
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);
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;
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;
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;
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);
563 } break;
564 case V4L2_BUF_TYPE_VBI_CAPTURE:
565 // ????? Still need to figure out to do VBI correctly
566 ret = -EINVAL;
567 break;
568 default:
569 ret = -EINVAL;
570 break;
572 break;
575 case VIDIOC_STREAMON:
577 if (!fh->dev_info->stream) {
578 /* No stream defined for this node. This means
579 that we're not currently allowed to stream from
580 this node. */
581 ret = -EPERM;
582 break;
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;
590 case VIDIOC_STREAMOFF:
592 if (!fh->dev_info->stream) {
593 /* No stream defined for this node. This means
594 that we're not currently allowed to stream from
595 this node. */
596 ret = -EPERM;
597 break;
599 ret = pvr2_hdw_set_streaming(hdw,0);
600 break;
603 case VIDIOC_QUERYCTRL:
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);
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;
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;
658 break;
661 case VIDIOC_QUERYMENU:
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;
673 case VIDIOC_G_CTRL:
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;
683 case VIDIOC_S_CTRL:
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;
691 case VIDIOC_G_EXT_CTRLS:
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;
707 /* Ensure that if read as a 64 bit value, the user
708 will still get a hopefully sane value */
709 ctrl->value64 = 0;
710 ctrl->value = val;
712 break;
715 case VIDIOC_S_EXT_CTRLS:
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;
732 break;
735 case VIDIOC_TRY_EXT_CTRLS:
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 /* For the moment just validate that the requested control
743 actually exists. */
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;
754 break;
757 case VIDIOC_CROPCAP:
759 struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg;
760 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
761 ret = -EINVAL;
762 break;
764 ret = pvr2_hdw_get_cropcap(hdw, cap);
765 cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
766 break;
768 case VIDIOC_G_CROP:
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;
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;
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;
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;
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;
803 crop->c.height = val;
805 case VIDIOC_S_CROP:
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;
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;
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;
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;
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;
843 case VIDIOC_LOG_STATUS:
845 pvr2_hdw_trigger_module_log(hdw);
846 ret = 0;
847 break;
849 #ifdef CONFIG_VIDEO_ADV_DEBUG
850 case VIDIOC_DBG_S_REGISTER:
851 case VIDIOC_DBG_G_REGISTER:
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;
862 #endif
864 default :
865 ret = v4l_compat_translate_ioctl(file, cmd,
866 arg, pvr2_v4l2_do_ioctl);
869 pvr2_hdw_commit_ctl(hdw);
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);
884 } else {
885 pvr2_trace(PVR2_TRACE_V4LIOCTL,
886 "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
887 ret, ret);
889 return ret;
892 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
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;
899 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
901 /* Paranoia */
902 dip->v4lp = NULL;
903 dip->stream = NULL;
905 /* Actual deallocation happens later when all internal references
906 are gone. */
907 video_unregister_device(&dip->devbase);
909 printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
910 get_v4l_name(v4l_type), num,
911 pvr2_config_get_name(cfg));
916 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
918 if (vp->dev_video) {
919 pvr2_v4l2_dev_destroy(vp->dev_video);
920 vp->dev_video = NULL;
922 if (vp->dev_radio) {
923 pvr2_v4l2_dev_destroy(vp->dev_radio);
924 vp->dev_radio = NULL;
927 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
928 pvr2_channel_done(&vp->channel);
929 kfree(vp);
933 static void pvr2_video_device_release(struct video_device *vdev)
935 struct pvr2_v4l2_dev *dev;
936 dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
937 kfree(dev);
941 static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
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);
951 static long pvr2_v4l2_ioctl(struct file *file,
952 unsigned int cmd, unsigned long arg)
955 return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
959 static int pvr2_v4l2_release(struct file *file)
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;
965 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
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;
976 v4l2_prio_close(&vp->prio, &fhp->prio);
977 file->private_data = NULL;
979 if (fhp->vnext) {
980 fhp->vnext->vprev = fhp->vprev;
981 } else {
982 vp->vlast = fhp->vprev;
984 if (fhp->vprev) {
985 fhp->vprev->vnext = fhp->vnext;
986 } else {
987 vp->vfirst = fhp->vnext;
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;
999 kfree(fhp);
1000 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
1001 pvr2_v4l2_destroy_no_lock(vp);
1003 return 0;
1007 static int pvr2_v4l2_open(struct file *file)
1009 struct pvr2_v4l2_dev *dip; /* Our own context pointer */
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;
1017 dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
1019 vp = dip->v4lp;
1020 hdw = vp->channel.hdw;
1022 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
1024 if (!pvr2_hdw_dev_ok(hdw)) {
1025 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
1026 "pvr2_v4l2_open: hardware not ready");
1027 return -EIO;
1030 fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
1031 if (!fhp) {
1032 return -ENOMEM;
1035 init_waitqueue_head(&fhp->wait_data);
1036 fhp->dev_info = dip;
1038 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
1039 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
1041 if (dip->v4l_type == VFL_TYPE_RADIO) {
1042 /* Opening device as a radio, legal input selection subset
1043 is just the radio. */
1044 input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
1045 } else {
1046 /* Opening the main V4L device, legal input selection
1047 subset includes all analog inputs. */
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));
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);
1060 kfree(fhp);
1061 return ret;
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++;
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;
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;
1085 fhp->vnext = NULL;
1086 fhp->vprev = vp->vlast;
1087 if (vp->vlast) {
1088 vp->vlast->vnext = fhp;
1089 } else {
1090 vp->vfirst = fhp;
1092 vp->vlast = fhp;
1093 fhp->vhead = vp;
1095 fhp->file = file;
1096 file->private_data = fhp;
1097 v4l2_prio_open(&vp->prio,&fhp->prio);
1099 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1101 return 0;
1105 static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
1107 wake_up(&fhp->wait_data);
1110 static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1112 int ret;
1113 struct pvr2_stream *sp;
1114 struct pvr2_hdw *hdw;
1115 if (fh->rhp) return 0;
1117 if (!fh->dev_info->stream) {
1118 /* No stream defined for this node. This means that we're
1119 not currently allowed to stream from this node. */
1120 return -EPERM;
1123 /* First read() attempt. Try to claim the stream and start
1124 it... */
1125 if ((ret = pvr2_channel_claim_stream(&fh->channel,
1126 fh->dev_info->stream)) != 0) {
1127 /* Someone else must already have it */
1128 return ret;
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;
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);
1146 static ssize_t pvr2_v4l2_read(struct file *file,
1147 char __user *buff, size_t count, loff_t *ppos)
1149 struct pvr2_v4l2_fh *fh = file->private_data;
1150 int ret;
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;
1159 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1160 if (!tbuf) return -ENOMEM;
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;
1170 if (!c2) break;
1171 if (copy_to_user(buff,tbuf,c2)) {
1172 tcnt = -EFAULT;
1173 break;
1175 offs += c2;
1176 tcnt += c2;
1177 buff += c2;
1178 count -= c2;
1179 *ppos += c2;
1181 kfree(tbuf);
1182 return tcnt;
1185 if (!fh->rhp) {
1186 ret = pvr2_v4l2_iosetup(fh);
1187 if (ret) {
1188 return ret;
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 /* Doing blocking I/O. Wait here. */
1198 ret = wait_event_interruptible(
1199 fh->wait_data,
1200 pvr2_ioread_avail(fh->rhp) >= 0);
1201 if (ret < 0) break;
1204 return ret;
1208 static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
1210 unsigned int mask = 0;
1211 struct pvr2_v4l2_fh *fh = file->private_data;
1212 int ret;
1214 if (fh->fw_mode_flag) {
1215 mask |= POLLIN | POLLRDNORM;
1216 return mask;
1219 if (!fh->rhp) {
1220 ret = pvr2_v4l2_iosetup(fh);
1221 if (ret) return POLLERR;
1224 poll_wait(file,&fh->wait_data,wait);
1226 if (pvr2_ioread_avail(fh->rhp) >= 0) {
1227 mask |= POLLIN | POLLRDNORM;
1230 return mask;
1234 static 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,
1244 static struct video_device vdev_template = {
1245 .fops = &vdev_fops,
1249 static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1250 struct pvr2_v4l2 *vp,
1251 int v4l_type)
1253 int mindevnum;
1254 int unit_number;
1255 int *nr_ptr = NULL;
1256 dip->v4lp = vp;
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;
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 /* Bail out (this should be impossible) */
1286 pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
1287 " due to unrecognized config\n");
1288 return;
1291 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1292 dip->devbase.release = pvr2_video_device_release;
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];
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");
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));
1311 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1312 dip->minor_type,dip->devbase.minor);
1316 struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1318 struct pvr2_v4l2 *vp;
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);
1325 vp->channel.check_func = pvr2_v4l2_internal_check;
1327 /* register streams */
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);
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;
1346 Stuff for Emacs to see, in order to encourage consistent editing style:
1347 *** Local Variables: ***
1348 *** mode: c ***
1349 *** fill-column: 75 ***
1350 *** tab-width: 8 ***
1351 *** c-basic-offset: 8 ***
1352 *** End: ***