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