blob: e93e2aa81f30b867e63bbfe289ae07f2a6a9010f [file] [log] [blame]
Mike Iselyd8554972006-06-26 20:58:46 -03001/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/kernel.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-common.h>
32
33struct pvr2_v4l2_dev;
34struct pvr2_v4l2_fh;
35struct pvr2_v4l2;
36
37/* V4L no longer provide the ability to set / get a private context pointer
38 (i.e. video_get_drvdata / video_set_drvdata), which means we have to
39 concoct our own context locating mechanism. Supposedly this is intended
40 to simplify driver implementation. It's not clear to me how that can
41 possibly be true. Our solution here is to maintain a lookup table of
42 our context instances, indexed by the minor device number of the V4L
43 device. See pvr2_v4l2_open() for some implications of this approach. */
44static struct pvr2_v4l2_dev *devices[256];
45static DEFINE_MUTEX(device_lock);
46
47struct pvr2_v4l2_dev {
48 struct pvr2_v4l2 *v4lp;
49 struct video_device *vdev;
50 struct pvr2_context_stream *stream;
51 int ctxt_idx;
52 enum pvr2_config config;
53};
54
55struct pvr2_v4l2_fh {
56 struct pvr2_channel channel;
57 struct pvr2_v4l2_dev *dev_info;
58 enum v4l2_priority prio;
59 struct pvr2_ioread *rhp;
60 struct file *file;
61 struct pvr2_v4l2 *vhead;
62 struct pvr2_v4l2_fh *vnext;
63 struct pvr2_v4l2_fh *vprev;
64 wait_queue_head_t wait_data;
65 int fw_mode_flag;
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 /* streams */
76 struct pvr2_v4l2_dev video_dev;
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 minor");
82
83struct v4l2_capability pvr_capability ={
84 .driver = "pvrusb2",
85 .card = "Hauppauge WinTV pvr-usb2",
86 .bus_info = "usb",
87 .version = KERNEL_VERSION(0,8,0),
88 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
89 V4L2_CAP_TUNER | V4L2_CAP_AUDIO |
90 V4L2_CAP_READWRITE),
91 .reserved = {0,0,0,0}
92};
93
94static struct v4l2_tuner pvr_v4l2_tuners[]= {
95 {
96 .index = 0,
97 .name = "TV Tuner",
98 .type = V4L2_TUNER_ANALOG_TV,
99 .capability = (V4L2_TUNER_CAP_NORM |
100 V4L2_TUNER_CAP_STEREO |
101 V4L2_TUNER_CAP_LANG1 |
102 V4L2_TUNER_CAP_LANG2),
103 .rangelow = 0,
104 .rangehigh = 0,
105 .rxsubchans = V4L2_TUNER_SUB_STEREO,
106 .audmode = V4L2_TUNER_MODE_STEREO,
107 .signal = 0,
108 .afc = 0,
109 .reserved = {0,0,0,0}
110 }
111};
112
113struct v4l2_fmtdesc pvr_fmtdesc [] = {
114 {
115 .index = 0,
116 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
117 .flags = V4L2_FMT_FLAG_COMPRESSED,
118 .description = "MPEG1/2",
119 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
120 // breaks when I do that.
121 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
122 .reserved = { 0, 0, 0, 0 }
123 }
124};
125
126#define PVR_FORMAT_PIX 0
127#define PVR_FORMAT_VBI 1
128
129struct v4l2_format pvr_format [] = {
130 [PVR_FORMAT_PIX] = {
131 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
132 .fmt = {
133 .pix = {
134 .width = 720,
135 .height = 576,
136 // This should really be V4L2_PIX_FMT_MPEG,
137 // but xawtv breaks when I do that.
138 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
139 .field = V4L2_FIELD_INTERLACED,
140 .bytesperline = 0, // doesn't make sense
141 // here
142 //FIXME : Don't know what to put here...
143 .sizeimage = (32*1024),
144 .colorspace = 0, // doesn't make sense here
145 .priv = 0
146 }
147 }
148 },
149 [PVR_FORMAT_VBI] = {
150 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
151 .fmt = {
152 .vbi = {
153 .sampling_rate = 27000000,
154 .offset = 248,
155 .samples_per_line = 1443,
156 .sample_format = V4L2_PIX_FMT_GREY,
157 .start = { 0, 0 },
158 .count = { 0, 0 },
159 .flags = 0,
160 .reserved = { 0, 0 }
161 }
162 }
163 }
164};
165
166/*
167 * pvr_ioctl()
168 *
169 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
170 *
171 */
172static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
173 unsigned int cmd, void *arg)
174{
175 struct pvr2_v4l2_fh *fh = file->private_data;
176 struct pvr2_v4l2 *vp = fh->vhead;
177 struct pvr2_v4l2_dev *dev_info = fh->dev_info;
178 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
179 int ret = -EINVAL;
180
181 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
182 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
183 }
184
185 if (!pvr2_hdw_dev_ok(hdw)) {
186 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
187 "ioctl failed - bad or no context");
188 return -EFAULT;
189 }
190
191 /* check priority */
192 switch (cmd) {
193 case VIDIOC_S_CTRL:
194 case VIDIOC_S_STD:
195 case VIDIOC_S_INPUT:
196 case VIDIOC_S_TUNER:
197 case VIDIOC_S_FREQUENCY:
198 ret = v4l2_prio_check(&vp->prio, &fh->prio);
199 if (ret)
200 return ret;
201 }
202
203 switch (cmd) {
204 case VIDIOC_QUERYCAP:
205 {
206 struct v4l2_capability *cap = arg;
207
208 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
209
210 ret = 0;
211 break;
212 }
213
214 case VIDIOC_G_PRIORITY:
215 {
216 enum v4l2_priority *p = arg;
217
218 *p = v4l2_prio_max(&vp->prio);
219 ret = 0;
220 break;
221 }
222
223 case VIDIOC_S_PRIORITY:
224 {
225 enum v4l2_priority *prio = arg;
226
227 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
228 break;
229 }
230
231 case VIDIOC_ENUMSTD:
232 {
233 struct v4l2_standard *vs = (struct v4l2_standard *)arg;
234 int idx = vs->index;
235 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
236 break;
237 }
238
239 case VIDIOC_G_STD:
240 {
241 int val = 0;
242 ret = pvr2_ctrl_get_value(
243 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
244 *(v4l2_std_id *)arg = val;
245 break;
246 }
247
248 case VIDIOC_S_STD:
249 {
250 ret = pvr2_ctrl_set_value(
251 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
252 *(v4l2_std_id *)arg);
253 break;
254 }
255
256 case VIDIOC_ENUMINPUT:
257 {
258 struct pvr2_ctrl *cptr;
259 struct v4l2_input *vi = (struct v4l2_input *)arg;
260 struct v4l2_input tmp;
261 unsigned int cnt;
262
263 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
264
265 memset(&tmp,0,sizeof(tmp));
266 tmp.index = vi->index;
267 ret = 0;
268 switch (vi->index) {
269 case PVR2_CVAL_INPUT_TV:
270 case PVR2_CVAL_INPUT_RADIO:
271 tmp.type = V4L2_INPUT_TYPE_TUNER;
272 break;
273 case PVR2_CVAL_INPUT_SVIDEO:
274 case PVR2_CVAL_INPUT_COMPOSITE:
275 tmp.type = V4L2_INPUT_TYPE_CAMERA;
276 break;
277 default:
278 ret = -EINVAL;
279 break;
280 }
281 if (ret < 0) break;
282
283 cnt = 0;
284 pvr2_ctrl_get_valname(cptr,vi->index,
285 tmp.name,sizeof(tmp.name)-1,&cnt);
286 tmp.name[cnt] = 0;
287
288 /* Don't bother with audioset, since this driver currently
289 always switches the audio whenever the video is
290 switched. */
291
292 /* Handling std is a tougher problem. It doesn't make
293 sense in cases where a device might be multi-standard.
294 We could just copy out the current value for the
295 standard, but it can change over time. For now just
296 leave it zero. */
297
298 memcpy(vi, &tmp, sizeof(tmp));
299
300 ret = 0;
301 break;
302 }
303
304 case VIDIOC_G_INPUT:
305 {
306 struct pvr2_ctrl *cptr;
307 struct v4l2_input *vi = (struct v4l2_input *)arg;
308 int val;
309 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
310 val = 0;
311 ret = pvr2_ctrl_get_value(cptr,&val);
312 vi->index = val;
313 break;
314 }
315
316 case VIDIOC_S_INPUT:
317 {
318 struct v4l2_input *vi = (struct v4l2_input *)arg;
319 ret = pvr2_ctrl_set_value(
320 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
321 vi->index);
322 break;
323 }
324
325 case VIDIOC_ENUMAUDIO:
326 {
327 ret = -EINVAL;
328 break;
329 }
330
331 case VIDIOC_G_AUDIO:
332 {
333 ret = -EINVAL;
334 break;
335 }
336
337 case VIDIOC_S_AUDIO:
338 {
339 ret = -EINVAL;
340 break;
341 }
342 case VIDIOC_G_TUNER:
343 {
344 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
345 unsigned int status_mask;
346 int val;
347 if (vt->index !=0) break;
348
349 status_mask = pvr2_hdw_get_signal_status(hdw);
350
351 memcpy(vt, &pvr_v4l2_tuners[vt->index],
352 sizeof(struct v4l2_tuner));
353
354 vt->signal = 0;
355 if (status_mask & PVR2_SIGNAL_OK) {
356 if (status_mask & PVR2_SIGNAL_STEREO) {
357 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
358 } else {
359 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
360 }
361 if (status_mask & PVR2_SIGNAL_SAP) {
362 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
363 V4L2_TUNER_SUB_LANG2);
364 }
365 vt->signal = 65535;
366 }
367
368 val = 0;
369 ret = pvr2_ctrl_get_value(
370 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
371 &val);
372 vt->audmode = val;
373 break;
374 }
375
376 case VIDIOC_S_TUNER:
377 {
378 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
379
380 if (vt->index != 0)
381 break;
382
383 ret = pvr2_ctrl_set_value(
384 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
385 vt->audmode);
386 }
387
388 case VIDIOC_S_FREQUENCY:
389 {
390 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
391 ret = pvr2_ctrl_set_value(
392 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
393 vf->frequency * 62500);
394 break;
395 }
396
397 case VIDIOC_G_FREQUENCY:
398 {
399 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
400 int val = 0;
401 ret = pvr2_ctrl_get_value(
402 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
403 &val);
404 val /= 62500;
405 vf->frequency = val;
406 break;
407 }
408
409 case VIDIOC_ENUM_FMT:
410 {
411 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
412
413 /* Only one format is supported : mpeg.*/
414 if (fd->index != 0)
415 break;
416
417 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
418 ret = 0;
419 break;
420 }
421
422 case VIDIOC_G_FMT:
423 {
424 struct v4l2_format *vf = (struct v4l2_format *)arg;
425 int val;
426 switch(vf->type) {
427 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
428 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
429 sizeof(struct v4l2_format));
430 val = 0;
431 pvr2_ctrl_get_value(
432 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
433 &val);
434 vf->fmt.pix.width = val;
435 val = 0;
436 pvr2_ctrl_get_value(
Mike Iselyd8554972006-06-26 20:58:46 -0300437 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
438 &val);
439 vf->fmt.pix.height = val;
440 ret = 0;
441 break;
442 case V4L2_BUF_TYPE_VBI_CAPTURE:
443 // ????? Still need to figure out to do VBI correctly
444 ret = -EINVAL;
445 break;
446 default:
447 ret = -EINVAL;
448 break;
449 }
450 break;
451 }
452
453 case VIDIOC_TRY_FMT:
454 case VIDIOC_S_FMT:
455 {
456 struct v4l2_format *vf = (struct v4l2_format *)arg;
457
458 ret = 0;
459 switch(vf->type) {
460 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
461 int h = vf->fmt.pix.height;
462 int w = vf->fmt.pix.width;
Mike Iselyd8554972006-06-26 20:58:46 -0300463
Mike Isely039c4302006-06-25 20:04:16 -0300464 if (h < 200) {
465 h = 200;
466 } else if (h > 625) {
467 h = 625;
Mike Iselyd8554972006-06-26 20:58:46 -0300468 }
Mike Isely039c4302006-06-25 20:04:16 -0300469 if (w < 320) {
470 w = 320;
471 } else if (w > 720) {
472 w = 720;
473 }
Mike Iselyd8554972006-06-26 20:58:46 -0300474
475 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
476 sizeof(struct v4l2_format));
Mike Isely039c4302006-06-25 20:04:16 -0300477 vf->fmt.pix.width = w;
478 vf->fmt.pix.height = h;
Mike Iselyd8554972006-06-26 20:58:46 -0300479
480 if (cmd == VIDIOC_S_FMT) {
481 pvr2_ctrl_set_value(
482 pvr2_hdw_get_ctrl_by_id(hdw,
483 PVR2_CID_HRES),
484 vf->fmt.pix.width);
485 pvr2_ctrl_set_value(
486 pvr2_hdw_get_ctrl_by_id(hdw,
487 PVR2_CID_VRES),
488 vf->fmt.pix.height);
Mike Iselyd8554972006-06-26 20:58:46 -0300489 }
490 } break;
491 case V4L2_BUF_TYPE_VBI_CAPTURE:
492 // ????? Still need to figure out to do VBI correctly
493 ret = -EINVAL;
494 break;
495 default:
496 ret = -EINVAL;
497 break;
498 }
499 break;
500 }
501
502 case VIDIOC_STREAMON:
503 {
504 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
505 if (ret < 0) return ret;
506 ret = pvr2_hdw_set_streaming(hdw,!0);
507 break;
508 }
509
510 case VIDIOC_STREAMOFF:
511 {
512 ret = pvr2_hdw_set_streaming(hdw,0);
513 break;
514 }
515
516 case VIDIOC_QUERYCTRL:
517 {
518 struct pvr2_ctrl *cptr;
519 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
520 ret = 0;
521 cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
522 if (!cptr) {
523 ret = -EINVAL;
524 break;
525 }
526
527 strlcpy(vc->name,pvr2_ctrl_get_name(cptr),sizeof(vc->name));
528 vc->default_value = pvr2_ctrl_get_def(cptr);
529 switch (pvr2_ctrl_get_type(cptr)) {
530 case pvr2_ctl_enum:
531 vc->type = V4L2_CTRL_TYPE_MENU;
532 vc->minimum = 0;
533 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
534 vc->step = 1;
535 break;
536 case pvr2_ctl_int:
537 vc->type = V4L2_CTRL_TYPE_INTEGER;
538 vc->minimum = pvr2_ctrl_get_min(cptr);
539 vc->maximum = pvr2_ctrl_get_max(cptr);
540 vc->step = 1;
541 break;
542 default:
543 ret = -EINVAL;
544 break;
545 }
546 break;
547 }
548
549 case VIDIOC_QUERYMENU:
550 {
551 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
552 unsigned int cnt = 0;
553 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
554 vm->index,
555 vm->name,sizeof(vm->name)-1,
556 &cnt);
557 vm->name[cnt] = 0;
558 break;
559 }
560
561 case VIDIOC_G_CTRL:
562 {
563 struct v4l2_control *vc = (struct v4l2_control *)arg;
564 int val = 0;
565 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
566 &val);
567 vc->value = val;
568 break;
569 }
570
571 case VIDIOC_S_CTRL:
572 {
573 struct v4l2_control *vc = (struct v4l2_control *)arg;
574 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
575 vc->value);
576 break;
577 }
578
579 case VIDIOC_LOG_STATUS:
580 {
581 int nr = pvr2_hdw_get_unit_number(hdw);
582
583 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
584 pvr2_hdw_trigger_module_log(hdw);
585 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
586 ret = 0;
587 break;
588 }
589
590 default :
591 ret = v4l_compat_translate_ioctl(inode,file,cmd,
592 arg,pvr2_v4l2_do_ioctl);
593 }
594
595 pvr2_hdw_commit_ctl(hdw);
596
597 if (ret < 0) {
598 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
599 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
600 "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
601 } else {
602 if (pvrusb2_debug & PVR2_TRACE_ERROR_LEGS) {
603 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
604 "pvr2_v4l2_do_ioctl failure, ret=%d"
605 " command was:",ret);
606 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
607 cmd);
608 }
609 }
610 } else {
611 pvr2_trace(PVR2_TRACE_V4LIOCTL,
612 "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
613 ret,ret);
614 }
615 return ret;
616}
617
618
619static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
620{
621 pvr2_trace(PVR2_TRACE_INIT,
622 "unregistering device video%d [%s]",
623 dip->vdev->minor,pvr2_config_get_name(dip->config));
624 if (dip->ctxt_idx >= 0) {
625 mutex_lock(&device_lock);
626 devices[dip->ctxt_idx] = NULL;
627 dip->ctxt_idx = -1;
628 mutex_unlock(&device_lock);
629 }
630 video_unregister_device(dip->vdev);
631}
632
633
634static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
635{
636 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
637 pvr2_v4l2_dev_destroy(&vp->video_dev);
638
639 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
640 pvr2_channel_done(&vp->channel);
641 kfree(vp);
642}
643
644
645void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
646{
647 struct pvr2_v4l2 *vp;
648 vp = container_of(chp,struct pvr2_v4l2,channel);
649 if (!vp->channel.mc_head->disconnect_flag) return;
650 if (vp->vfirst) return;
651 pvr2_v4l2_destroy_no_lock(vp);
652}
653
654
655int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
656 unsigned int cmd, unsigned long arg)
657{
658
659/* Temporary hack : use ivtv api until a v4l2 one is available. */
660#define IVTV_IOC_G_CODEC 0xFFEE7703
661#define IVTV_IOC_S_CODEC 0xFFEE7704
662 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
663 return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
664}
665
666
667int pvr2_v4l2_release(struct inode *inode, struct file *file)
668{
669 struct pvr2_v4l2_fh *fhp = file->private_data;
670 struct pvr2_v4l2 *vp = fhp->vhead;
671 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
672
673 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
674
675 if (fhp->rhp) {
676 struct pvr2_stream *sp;
677 struct pvr2_hdw *hdw;
678 hdw = fhp->channel.mc_head->hdw;
679 pvr2_hdw_set_streaming(hdw,0);
680 sp = pvr2_ioread_get_stream(fhp->rhp);
681 if (sp) pvr2_stream_set_callback(sp,0,0);
682 pvr2_ioread_destroy(fhp->rhp);
683 fhp->rhp = 0;
684 }
685 v4l2_prio_close(&vp->prio, &fhp->prio);
686 file->private_data = NULL;
687
688 pvr2_context_enter(mp); do {
689 if (fhp->vnext) {
690 fhp->vnext->vprev = fhp->vprev;
691 } else {
692 vp->vlast = fhp->vprev;
693 }
694 if (fhp->vprev) {
695 fhp->vprev->vnext = fhp->vnext;
696 } else {
697 vp->vfirst = fhp->vnext;
698 }
699 fhp->vnext = 0;
700 fhp->vprev = 0;
701 fhp->vhead = 0;
702 pvr2_channel_done(&fhp->channel);
703 pvr2_trace(PVR2_TRACE_STRUCT,
704 "Destroying pvr_v4l2_fh id=%p",fhp);
705 kfree(fhp);
706 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
707 pvr2_v4l2_destroy_no_lock(vp);
708 }
709 } while (0); pvr2_context_exit(mp);
710 return 0;
711}
712
713
714int pvr2_v4l2_open(struct inode *inode, struct file *file)
715{
716 struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */
717 struct pvr2_v4l2_fh *fhp;
718 struct pvr2_v4l2 *vp;
719 struct pvr2_hdw *hdw;
720
721 mutex_lock(&device_lock);
722 /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
723 atomic read of the device mapping array here, we still need the
724 mutex. The problem is that there is a tiny race possible when
725 we register the device. We can't update the device mapping
726 array until after the device has been registered, owing to the
727 fact that we can't know the minor device number until after the
728 registration succeeds. And if another thread tries to open the
729 device in the window of time after registration but before the
730 map is updated, then it will get back an erroneous null pointer
731 and the open will result in a spurious failure. The only way to
732 prevent that is to (a) be inside the mutex here before we access
733 the array, and (b) cover the entire registration process later
734 on with this same mutex. Thus if we get inside the mutex here,
735 then we can be assured that the registration process actually
736 completed correctly. This is an unhappy complication from the
737 use of global data in a driver that lives in a preemptible
738 environment. It sure would be nice if the video device itself
739 had a means for storing and retrieving a local context pointer.
740 Oh wait. It did. But now it's gone. Silly me. */
741 {
742 unsigned int midx = iminor(file->f_dentry->d_inode);
743 if (midx < sizeof(devices)/sizeof(devices[0])) {
744 dip = devices[midx];
745 }
746 }
747 mutex_unlock(&device_lock);
748
749 if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
750
751 vp = dip->v4lp;
752 hdw = vp->channel.hdw;
753
754 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
755
756 if (!pvr2_hdw_dev_ok(hdw)) {
757 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
758 "pvr2_v4l2_open: hardware not ready");
759 return -EIO;
760 }
761
762 fhp = kmalloc(sizeof(*fhp),GFP_KERNEL);
763 if (!fhp) {
764 return -ENOMEM;
765 }
766 memset(fhp,0,sizeof(*fhp));
767
768 init_waitqueue_head(&fhp->wait_data);
769 fhp->dev_info = dip;
770
771 pvr2_context_enter(vp->channel.mc_head); do {
772 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
773 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
774 fhp->vnext = 0;
775 fhp->vprev = vp->vlast;
776 if (vp->vlast) {
777 vp->vlast->vnext = fhp;
778 } else {
779 vp->vfirst = fhp;
780 }
781 vp->vlast = fhp;
782 fhp->vhead = vp;
783 } while (0); pvr2_context_exit(vp->channel.mc_head);
784
785 fhp->file = file;
786 file->private_data = fhp;
787 v4l2_prio_open(&vp->prio,&fhp->prio);
788
789 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
790
791 return 0;
792}
793
794
795static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
796{
797 wake_up(&fhp->wait_data);
798}
799
800static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
801{
802 int ret;
803 struct pvr2_stream *sp;
804 struct pvr2_hdw *hdw;
805 if (fh->rhp) return 0;
806
807 /* First read() attempt. Try to claim the stream and start
808 it... */
809 if ((ret = pvr2_channel_claim_stream(&fh->channel,
810 fh->dev_info->stream)) != 0) {
811 /* Someone else must already have it */
812 return ret;
813 }
814
815 fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
816 if (!fh->rhp) {
817 pvr2_channel_claim_stream(&fh->channel,0);
818 return -ENOMEM;
819 }
820
821 hdw = fh->channel.mc_head->hdw;
822 sp = fh->dev_info->stream->stream;
823 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
824 pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
825 pvr2_hdw_set_streaming(hdw,!0);
826 ret = pvr2_ioread_set_enabled(fh->rhp,!0);
827
828 return ret;
829}
830
831
832static ssize_t pvr2_v4l2_read(struct file *file,
833 char __user *buff, size_t count, loff_t *ppos)
834{
835 struct pvr2_v4l2_fh *fh = file->private_data;
836 int ret;
837
838 if (fh->fw_mode_flag) {
839 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
840 char *tbuf;
841 int c1,c2;
842 int tcnt = 0;
843 unsigned int offs = *ppos;
844
845 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
846 if (!tbuf) return -ENOMEM;
847
848 while (count) {
849 c1 = count;
850 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
851 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
852 if (c2 < 0) {
853 tcnt = c2;
854 break;
855 }
856 if (!c2) break;
857 if (copy_to_user(buff,tbuf,c2)) {
858 tcnt = -EFAULT;
859 break;
860 }
861 offs += c2;
862 tcnt += c2;
863 buff += c2;
864 count -= c2;
865 *ppos += c2;
866 }
867 kfree(tbuf);
868 return tcnt;
869 }
870
871 if (!fh->rhp) {
872 ret = pvr2_v4l2_iosetup(fh);
873 if (ret) {
874 return ret;
875 }
876 }
877
878 for (;;) {
879 ret = pvr2_ioread_read(fh->rhp,buff,count);
880 if (ret >= 0) break;
881 if (ret != -EAGAIN) break;
882 if (file->f_flags & O_NONBLOCK) break;
883 /* Doing blocking I/O. Wait here. */
884 ret = wait_event_interruptible(
885 fh->wait_data,
886 pvr2_ioread_avail(fh->rhp) >= 0);
887 if (ret < 0) break;
888 }
889
890 return ret;
891}
892
893
894static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
895{
896 unsigned int mask = 0;
897 struct pvr2_v4l2_fh *fh = file->private_data;
898 int ret;
899
900 if (fh->fw_mode_flag) {
901 mask |= POLLIN | POLLRDNORM;
902 return mask;
903 }
904
905 if (!fh->rhp) {
906 ret = pvr2_v4l2_iosetup(fh);
907 if (ret) return POLLERR;
908 }
909
910 poll_wait(file,&fh->wait_data,wait);
911
912 if (pvr2_ioread_avail(fh->rhp) >= 0) {
913 mask |= POLLIN | POLLRDNORM;
914 }
915
916 return mask;
917}
918
919
920static struct file_operations vdev_fops = {
921 .owner = THIS_MODULE,
922 .open = pvr2_v4l2_open,
923 .release = pvr2_v4l2_release,
924 .read = pvr2_v4l2_read,
925 .ioctl = pvr2_v4l2_ioctl,
926 .llseek = no_llseek,
927 .poll = pvr2_v4l2_poll,
928};
929
930
931#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */
932
933static struct video_device vdev_template = {
934 .owner = THIS_MODULE,
935 .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
936 .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
937 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
938 | V4L2_CAP_READWRITE),
939 .hardware = VID_HARDWARE_PVRUSB2,
940 .fops = &vdev_fops,
941};
942
943
944static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
945 struct pvr2_v4l2 *vp,
946 enum pvr2_config cfg)
947{
948 int mindevnum;
949 int unit_number;
950 int v4l_type;
951 dip->v4lp = vp;
952 dip->config = cfg;
953
954
955 switch (cfg) {
956 case pvr2_config_mpeg:
957 v4l_type = VFL_TYPE_GRABBER;
958 dip->stream = &vp->channel.mc_head->video_stream;
959 break;
960 case pvr2_config_vbi:
961 v4l_type = VFL_TYPE_VBI;
962 break;
963 case pvr2_config_radio:
964 v4l_type = VFL_TYPE_RADIO;
965 break;
966 default:
967 /* Bail out (this should be impossible) */
968 err("Failed to set up pvrusb2 v4l dev"
969 " due to unrecognized config");
970 return;
971 }
972
973 if (!dip->stream) {
974 err("Failed to set up pvrusb2 v4l dev"
975 " due to missing stream instance");
976 return;
977 }
978
979 dip->vdev = video_device_alloc();
980 if (!dip->vdev) {
981 err("Alloc of pvrusb2 v4l video device failed");
982 return;
983 }
984
985 memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
986 dip->vdev->release = video_device_release;
987 mutex_lock(&device_lock);
988
989 mindevnum = -1;
990 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
991 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
992 mindevnum = video_nr[unit_number];
993 }
994 if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
995 (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
996 err("Failed to register pvrusb2 v4l video device");
997 } else {
998 pvr2_trace(PVR2_TRACE_INIT,
999 "registered device video%d [%s]",
1000 dip->vdev->minor,pvr2_config_get_name(dip->config));
1001 }
1002
1003 if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
1004 (devices[dip->vdev->minor] == NULL)) {
1005 dip->ctxt_idx = dip->vdev->minor;
1006 devices[dip->ctxt_idx] = dip;
1007 }
1008 mutex_unlock(&device_lock);
1009
1010 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1011 dip->vdev->minor);
1012}
1013
1014
1015struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1016{
1017 struct pvr2_v4l2 *vp;
1018
1019 vp = kmalloc(sizeof(*vp),GFP_KERNEL);
1020 if (!vp) return vp;
1021 memset(vp,0,sizeof(*vp));
1022 vp->video_dev.ctxt_idx = -1;
1023 pvr2_channel_init(&vp->channel,mnp);
1024 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1025
1026 vp->channel.check_func = pvr2_v4l2_internal_check;
1027
1028 /* register streams */
1029 pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
1030
1031
1032 return vp;
1033}
1034
1035/*
1036 Stuff for Emacs to see, in order to encourage consistent editing style:
1037 *** Local Variables: ***
1038 *** mode: c ***
1039 *** fill-column: 75 ***
1040 *** tab-width: 8 ***
1041 *** c-basic-offset: 8 ***
1042 *** End: ***
1043 */