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