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