0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/slab.h>
0010 #include "pvrusb2-context.h"
0011 #include "pvrusb2-hdw.h"
0012 #include "pvrusb2.h"
0013 #include "pvrusb2-debug.h"
0014 #include "pvrusb2-v4l2.h"
0015 #include "pvrusb2-ioread.h"
0016 #include <linux/videodev2.h>
0017 #include <linux/module.h>
0018 #include <media/v4l2-dev.h>
0019 #include <media/v4l2-device.h>
0020 #include <media/v4l2-fh.h>
0021 #include <media/v4l2-common.h>
0022 #include <media/v4l2-ioctl.h>
0023
0024 struct pvr2_v4l2_dev;
0025 struct pvr2_v4l2_fh;
0026 struct pvr2_v4l2;
0027
0028 struct pvr2_v4l2_dev {
0029 struct video_device devbase;
0030 struct pvr2_v4l2 *v4lp;
0031 struct pvr2_context_stream *stream;
0032
0033 enum pvr2_config config;
0034 int v4l_type;
0035 enum pvr2_v4l_type minor_type;
0036 };
0037
0038 struct pvr2_v4l2_fh {
0039 struct v4l2_fh fh;
0040 struct pvr2_channel channel;
0041 struct pvr2_v4l2_dev *pdi;
0042 struct pvr2_ioread *rhp;
0043 struct file *file;
0044 wait_queue_head_t wait_data;
0045 int fw_mode_flag;
0046
0047 unsigned char *input_map;
0048 unsigned int input_cnt;
0049 };
0050
0051 struct pvr2_v4l2 {
0052 struct pvr2_channel channel;
0053
0054
0055
0056
0057 struct pvr2_v4l2_dev *dev_video;
0058 struct pvr2_v4l2_dev *dev_radio;
0059 };
0060
0061 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
0062 module_param_array(video_nr, int, NULL, 0444);
0063 MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
0064 static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
0065 module_param_array(radio_nr, int, NULL, 0444);
0066 MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
0067 static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
0068 module_param_array(vbi_nr, int, NULL, 0444);
0069 MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
0070
0071 #define PVR_FORMAT_PIX 0
0072 #define PVR_FORMAT_VBI 1
0073
0074 static struct v4l2_format pvr_format [] = {
0075 [PVR_FORMAT_PIX] = {
0076 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
0077 .fmt = {
0078 .pix = {
0079 .width = 720,
0080 .height = 576,
0081 .pixelformat = V4L2_PIX_FMT_MPEG,
0082 .field = V4L2_FIELD_INTERLACED,
0083
0084 .sizeimage = 32 * 1024,
0085 }
0086 }
0087 },
0088 [PVR_FORMAT_VBI] = {
0089 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
0090 .fmt = {
0091 .vbi = {
0092 .sampling_rate = 27000000,
0093 .offset = 248,
0094 .samples_per_line = 1443,
0095 .sample_format = V4L2_PIX_FMT_GREY,
0096 .start = { 0, 0 },
0097 .count = { 0, 0 },
0098 .flags = 0,
0099 }
0100 }
0101 }
0102 };
0103
0104
0105
0106
0107
0108
0109 static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
0110 {
0111 struct pvr2_v4l2_fh *fh = file->private_data;
0112 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0113
0114 strscpy(cap->driver, "pvrusb2", sizeof(cap->driver));
0115 strscpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
0116 sizeof(cap->bus_info));
0117 strscpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
0118 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
0119 V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
0120 V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
0121 return 0;
0122 }
0123
0124 static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
0125 {
0126 struct pvr2_v4l2_fh *fh = file->private_data;
0127 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0128 int val = 0;
0129 int ret;
0130
0131 ret = pvr2_ctrl_get_value(
0132 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val);
0133 *std = val;
0134 return ret;
0135 }
0136
0137 static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id std)
0138 {
0139 struct pvr2_v4l2_fh *fh = file->private_data;
0140 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0141 int ret;
0142
0143 ret = pvr2_ctrl_set_value(
0144 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), std);
0145 pvr2_hdw_commit_ctl(hdw);
0146 return ret;
0147 }
0148
0149 static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
0150 {
0151 struct pvr2_v4l2_fh *fh = file->private_data;
0152 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0153 int val = 0;
0154 int ret;
0155
0156 ret = pvr2_ctrl_get_value(
0157 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val);
0158 *std = val;
0159 return ret;
0160 }
0161
0162 static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
0163 {
0164 struct pvr2_v4l2_fh *fh = file->private_data;
0165 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0166 struct pvr2_ctrl *cptr;
0167 struct v4l2_input tmp;
0168 unsigned int cnt;
0169 int val;
0170
0171 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
0172
0173 memset(&tmp, 0, sizeof(tmp));
0174 tmp.index = vi->index;
0175 if (vi->index >= fh->input_cnt)
0176 return -EINVAL;
0177 val = fh->input_map[vi->index];
0178 switch (val) {
0179 case PVR2_CVAL_INPUT_TV:
0180 case PVR2_CVAL_INPUT_DTV:
0181 case PVR2_CVAL_INPUT_RADIO:
0182 tmp.type = V4L2_INPUT_TYPE_TUNER;
0183 break;
0184 case PVR2_CVAL_INPUT_SVIDEO:
0185 case PVR2_CVAL_INPUT_COMPOSITE:
0186 tmp.type = V4L2_INPUT_TYPE_CAMERA;
0187 break;
0188 default:
0189 return -EINVAL;
0190 }
0191
0192 cnt = 0;
0193 pvr2_ctrl_get_valname(cptr, val,
0194 tmp.name, sizeof(tmp.name) - 1, &cnt);
0195 tmp.name[cnt] = 0;
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 *vi = tmp;
0207 return 0;
0208 }
0209
0210 static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
0211 {
0212 struct pvr2_v4l2_fh *fh = file->private_data;
0213 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0214 unsigned int idx;
0215 struct pvr2_ctrl *cptr;
0216 int val;
0217 int ret;
0218
0219 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
0220 val = 0;
0221 ret = pvr2_ctrl_get_value(cptr, &val);
0222 *i = 0;
0223 for (idx = 0; idx < fh->input_cnt; idx++) {
0224 if (fh->input_map[idx] == val) {
0225 *i = idx;
0226 break;
0227 }
0228 }
0229 return ret;
0230 }
0231
0232 static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
0233 {
0234 struct pvr2_v4l2_fh *fh = file->private_data;
0235 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0236 int ret;
0237
0238 if (inp >= fh->input_cnt)
0239 return -EINVAL;
0240 ret = pvr2_ctrl_set_value(
0241 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
0242 fh->input_map[inp]);
0243 pvr2_hdw_commit_ctl(hdw);
0244 return ret;
0245 }
0246
0247 static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
0248 {
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 if (vin->index > 0)
0265 return -EINVAL;
0266 strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name));
0267 vin->capability = V4L2_AUDCAP_STEREO;
0268 return 0;
0269 }
0270
0271 static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
0272 {
0273
0274 vin->index = 0;
0275 strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name));
0276 vin->capability = V4L2_AUDCAP_STEREO;
0277 return 0;
0278 }
0279
0280 static int pvr2_s_audio(struct file *file, void *priv, const struct v4l2_audio *vout)
0281 {
0282 if (vout->index)
0283 return -EINVAL;
0284 return 0;
0285 }
0286
0287 static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
0288 {
0289 struct pvr2_v4l2_fh *fh = file->private_data;
0290 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0291
0292 if (vt->index != 0)
0293 return -EINVAL;
0294
0295 pvr2_hdw_execute_tuner_poll(hdw);
0296 return pvr2_hdw_get_tuner_status(hdw, vt);
0297 }
0298
0299 static int pvr2_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
0300 {
0301 struct pvr2_v4l2_fh *fh = file->private_data;
0302 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0303 int ret;
0304
0305 if (vt->index != 0)
0306 return -EINVAL;
0307
0308 ret = pvr2_ctrl_set_value(
0309 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE),
0310 vt->audmode);
0311 pvr2_hdw_commit_ctl(hdw);
0312 return ret;
0313 }
0314
0315 static int pvr2_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
0316 {
0317 struct pvr2_v4l2_fh *fh = file->private_data;
0318 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0319 unsigned long fv;
0320 struct v4l2_tuner vt;
0321 int cur_input;
0322 struct pvr2_ctrl *ctrlp;
0323 int ret;
0324
0325 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
0326 if (ret != 0)
0327 return ret;
0328 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
0329 ret = pvr2_ctrl_get_value(ctrlp, &cur_input);
0330 if (ret != 0)
0331 return ret;
0332 if (vf->type == V4L2_TUNER_RADIO) {
0333 if (cur_input != PVR2_CVAL_INPUT_RADIO)
0334 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
0335 } else {
0336 if (cur_input == PVR2_CVAL_INPUT_RADIO)
0337 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
0338 }
0339 fv = vf->frequency;
0340 if (vt.capability & V4L2_TUNER_CAP_LOW)
0341 fv = (fv * 125) / 2;
0342 else
0343 fv = fv * 62500;
0344 ret = pvr2_ctrl_set_value(
0345 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
0346 pvr2_hdw_commit_ctl(hdw);
0347 return ret;
0348 }
0349
0350 static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
0351 {
0352 struct pvr2_v4l2_fh *fh = file->private_data;
0353 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0354 int val = 0;
0355 int cur_input;
0356 struct v4l2_tuner vt;
0357 int ret;
0358
0359 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
0360 if (ret != 0)
0361 return ret;
0362 ret = pvr2_ctrl_get_value(
0363 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
0364 &val);
0365 if (ret != 0)
0366 return ret;
0367 pvr2_ctrl_get_value(
0368 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
0369 &cur_input);
0370 if (cur_input == PVR2_CVAL_INPUT_RADIO)
0371 vf->type = V4L2_TUNER_RADIO;
0372 else
0373 vf->type = V4L2_TUNER_ANALOG_TV;
0374 if (vt.capability & V4L2_TUNER_CAP_LOW)
0375 val = (val * 2) / 125;
0376 else
0377 val /= 62500;
0378 vf->frequency = val;
0379 return 0;
0380 }
0381
0382 static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
0383 {
0384
0385 if (fd->index)
0386 return -EINVAL;
0387
0388 fd->pixelformat = V4L2_PIX_FMT_MPEG;
0389 return 0;
0390 }
0391
0392 static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
0393 {
0394 struct pvr2_v4l2_fh *fh = file->private_data;
0395 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0396 int val;
0397
0398 memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format));
0399 val = 0;
0400 pvr2_ctrl_get_value(
0401 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES),
0402 &val);
0403 vf->fmt.pix.width = val;
0404 val = 0;
0405 pvr2_ctrl_get_value(
0406 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES),
0407 &val);
0408 vf->fmt.pix.height = val;
0409 return 0;
0410 }
0411
0412 static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
0413 {
0414 struct pvr2_v4l2_fh *fh = file->private_data;
0415 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0416 int lmin, lmax, ldef;
0417 struct pvr2_ctrl *hcp, *vcp;
0418 int h = vf->fmt.pix.height;
0419 int w = vf->fmt.pix.width;
0420
0421 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
0422 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
0423
0424 lmin = pvr2_ctrl_get_min(hcp);
0425 lmax = pvr2_ctrl_get_max(hcp);
0426 pvr2_ctrl_get_def(hcp, &ldef);
0427 if (w == -1)
0428 w = ldef;
0429 else if (w < lmin)
0430 w = lmin;
0431 else if (w > lmax)
0432 w = lmax;
0433 lmin = pvr2_ctrl_get_min(vcp);
0434 lmax = pvr2_ctrl_get_max(vcp);
0435 pvr2_ctrl_get_def(vcp, &ldef);
0436 if (h == -1)
0437 h = ldef;
0438 else if (h < lmin)
0439 h = lmin;
0440 else if (h > lmax)
0441 h = lmax;
0442
0443 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
0444 sizeof(struct v4l2_format));
0445 vf->fmt.pix.width = w;
0446 vf->fmt.pix.height = h;
0447 return 0;
0448 }
0449
0450 static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
0451 {
0452 struct pvr2_v4l2_fh *fh = file->private_data;
0453 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0454 struct pvr2_ctrl *hcp, *vcp;
0455 int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
0456
0457 if (ret)
0458 return ret;
0459 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
0460 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
0461 pvr2_ctrl_set_value(hcp, vf->fmt.pix.width);
0462 pvr2_ctrl_set_value(vcp, vf->fmt.pix.height);
0463 pvr2_hdw_commit_ctl(hdw);
0464 return 0;
0465 }
0466
0467 static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
0468 {
0469 struct pvr2_v4l2_fh *fh = file->private_data;
0470 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0471 struct pvr2_v4l2_dev *pdi = fh->pdi;
0472 int ret;
0473
0474 if (!fh->pdi->stream) {
0475
0476
0477
0478 return -EPERM;
0479 }
0480 ret = pvr2_hdw_set_stream_type(hdw, pdi->config);
0481 if (ret < 0)
0482 return ret;
0483 return pvr2_hdw_set_streaming(hdw, !0);
0484 }
0485
0486 static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
0487 {
0488 struct pvr2_v4l2_fh *fh = file->private_data;
0489 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0490
0491 if (!fh->pdi->stream) {
0492
0493
0494
0495 return -EPERM;
0496 }
0497 return pvr2_hdw_set_streaming(hdw, 0);
0498 }
0499
0500 static int pvr2_queryctrl(struct file *file, void *priv,
0501 struct v4l2_queryctrl *vc)
0502 {
0503 struct pvr2_v4l2_fh *fh = file->private_data;
0504 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0505 struct pvr2_ctrl *cptr;
0506 int val;
0507
0508 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
0509 cptr = pvr2_hdw_get_ctrl_nextv4l(
0510 hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
0511 if (cptr)
0512 vc->id = pvr2_ctrl_get_v4lid(cptr);
0513 } else {
0514 cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id);
0515 }
0516 if (!cptr) {
0517 pvr2_trace(PVR2_TRACE_V4LIOCTL,
0518 "QUERYCTRL id=0x%x not implemented here",
0519 vc->id);
0520 return -EINVAL;
0521 }
0522
0523 pvr2_trace(PVR2_TRACE_V4LIOCTL,
0524 "QUERYCTRL id=0x%x mapping name=%s (%s)",
0525 vc->id, pvr2_ctrl_get_name(cptr),
0526 pvr2_ctrl_get_desc(cptr));
0527 strscpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
0528 vc->flags = pvr2_ctrl_get_v4lflags(cptr);
0529 pvr2_ctrl_get_def(cptr, &val);
0530 vc->default_value = val;
0531 switch (pvr2_ctrl_get_type(cptr)) {
0532 case pvr2_ctl_enum:
0533 vc->type = V4L2_CTRL_TYPE_MENU;
0534 vc->minimum = 0;
0535 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
0536 vc->step = 1;
0537 break;
0538 case pvr2_ctl_bool:
0539 vc->type = V4L2_CTRL_TYPE_BOOLEAN;
0540 vc->minimum = 0;
0541 vc->maximum = 1;
0542 vc->step = 1;
0543 break;
0544 case pvr2_ctl_int:
0545 vc->type = V4L2_CTRL_TYPE_INTEGER;
0546 vc->minimum = pvr2_ctrl_get_min(cptr);
0547 vc->maximum = pvr2_ctrl_get_max(cptr);
0548 vc->step = 1;
0549 break;
0550 default:
0551 pvr2_trace(PVR2_TRACE_V4LIOCTL,
0552 "QUERYCTRL id=0x%x name=%s not mappable",
0553 vc->id, pvr2_ctrl_get_name(cptr));
0554 return -EINVAL;
0555 }
0556 return 0;
0557 }
0558
0559 static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
0560 {
0561 struct pvr2_v4l2_fh *fh = file->private_data;
0562 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0563 unsigned int cnt = 0;
0564 int ret;
0565
0566 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id),
0567 vm->index,
0568 vm->name, sizeof(vm->name) - 1,
0569 &cnt);
0570 vm->name[cnt] = 0;
0571 return ret;
0572 }
0573
0574 static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
0575 {
0576 struct pvr2_v4l2_fh *fh = file->private_data;
0577 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0578 int val = 0;
0579 int ret;
0580
0581 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
0582 &val);
0583 vc->value = val;
0584 return ret;
0585 }
0586
0587 static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
0588 {
0589 struct pvr2_v4l2_fh *fh = file->private_data;
0590 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0591 int ret;
0592
0593 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
0594 vc->value);
0595 pvr2_hdw_commit_ctl(hdw);
0596 return ret;
0597 }
0598
0599 static int pvr2_g_ext_ctrls(struct file *file, void *priv,
0600 struct v4l2_ext_controls *ctls)
0601 {
0602 struct pvr2_v4l2_fh *fh = file->private_data;
0603 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0604 struct v4l2_ext_control *ctrl;
0605 struct pvr2_ctrl *cptr;
0606 unsigned int idx;
0607 int val;
0608 int ret;
0609
0610 ret = 0;
0611 for (idx = 0; idx < ctls->count; idx++) {
0612 ctrl = ctls->controls + idx;
0613 cptr = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
0614 if (cptr) {
0615 if (ctls->which == V4L2_CTRL_WHICH_DEF_VAL)
0616 pvr2_ctrl_get_def(cptr, &val);
0617 else
0618 ret = pvr2_ctrl_get_value(cptr, &val);
0619 } else
0620 ret = -EINVAL;
0621
0622 if (ret) {
0623 ctls->error_idx = idx;
0624 return ret;
0625 }
0626
0627
0628 ctrl->value64 = 0;
0629 ctrl->value = val;
0630 }
0631 return 0;
0632 }
0633
0634 static int pvr2_s_ext_ctrls(struct file *file, void *priv,
0635 struct v4l2_ext_controls *ctls)
0636 {
0637 struct pvr2_v4l2_fh *fh = file->private_data;
0638 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0639 struct v4l2_ext_control *ctrl;
0640 unsigned int idx;
0641 int ret;
0642
0643 ret = 0;
0644 for (idx = 0; idx < ctls->count; idx++) {
0645 ctrl = ctls->controls + idx;
0646 ret = pvr2_ctrl_set_value(
0647 pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id),
0648 ctrl->value);
0649 if (ret) {
0650 ctls->error_idx = idx;
0651 goto commit;
0652 }
0653 }
0654 commit:
0655 pvr2_hdw_commit_ctl(hdw);
0656 return ret;
0657 }
0658
0659 static int pvr2_try_ext_ctrls(struct file *file, void *priv,
0660 struct v4l2_ext_controls *ctls)
0661 {
0662 struct pvr2_v4l2_fh *fh = file->private_data;
0663 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0664 struct v4l2_ext_control *ctrl;
0665 struct pvr2_ctrl *pctl;
0666 unsigned int idx;
0667
0668
0669
0670 for (idx = 0; idx < ctls->count; idx++) {
0671 ctrl = ctls->controls + idx;
0672 pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
0673 if (!pctl) {
0674 ctls->error_idx = idx;
0675 return -EINVAL;
0676 }
0677 }
0678 return 0;
0679 }
0680
0681 static int pvr2_g_pixelaspect(struct file *file, void *priv,
0682 int type, struct v4l2_fract *f)
0683 {
0684 struct pvr2_v4l2_fh *fh = file->private_data;
0685 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0686 struct v4l2_cropcap cap = { .type = type };
0687 int ret;
0688
0689 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0690 return -EINVAL;
0691 ret = pvr2_hdw_get_cropcap(hdw, &cap);
0692 if (!ret)
0693 *f = cap.pixelaspect;
0694 return ret;
0695 }
0696
0697 static int pvr2_g_selection(struct file *file, void *priv,
0698 struct v4l2_selection *sel)
0699 {
0700 struct pvr2_v4l2_fh *fh = file->private_data;
0701 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0702 struct v4l2_cropcap cap;
0703 int val = 0;
0704 int ret;
0705
0706 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0707 return -EINVAL;
0708
0709 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0710
0711 switch (sel->target) {
0712 case V4L2_SEL_TGT_CROP:
0713 ret = pvr2_ctrl_get_value(
0714 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
0715 if (ret != 0)
0716 return -EINVAL;
0717 sel->r.left = val;
0718 ret = pvr2_ctrl_get_value(
0719 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
0720 if (ret != 0)
0721 return -EINVAL;
0722 sel->r.top = val;
0723 ret = pvr2_ctrl_get_value(
0724 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
0725 if (ret != 0)
0726 return -EINVAL;
0727 sel->r.width = val;
0728 ret = pvr2_ctrl_get_value(
0729 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
0730 if (ret != 0)
0731 return -EINVAL;
0732 sel->r.height = val;
0733 break;
0734 case V4L2_SEL_TGT_CROP_DEFAULT:
0735 ret = pvr2_hdw_get_cropcap(hdw, &cap);
0736 sel->r = cap.defrect;
0737 break;
0738 case V4L2_SEL_TGT_CROP_BOUNDS:
0739 ret = pvr2_hdw_get_cropcap(hdw, &cap);
0740 sel->r = cap.bounds;
0741 break;
0742 default:
0743 return -EINVAL;
0744 }
0745 return ret;
0746 }
0747
0748 static int pvr2_s_selection(struct file *file, void *priv,
0749 struct v4l2_selection *sel)
0750 {
0751 struct pvr2_v4l2_fh *fh = file->private_data;
0752 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0753 int ret;
0754
0755 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
0756 sel->target != V4L2_SEL_TGT_CROP)
0757 return -EINVAL;
0758 ret = pvr2_ctrl_set_value(
0759 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
0760 sel->r.left);
0761 if (ret != 0)
0762 goto commit;
0763 ret = pvr2_ctrl_set_value(
0764 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
0765 sel->r.top);
0766 if (ret != 0)
0767 goto commit;
0768 ret = pvr2_ctrl_set_value(
0769 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
0770 sel->r.width);
0771 if (ret != 0)
0772 goto commit;
0773 ret = pvr2_ctrl_set_value(
0774 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
0775 sel->r.height);
0776 commit:
0777 pvr2_hdw_commit_ctl(hdw);
0778 return ret;
0779 }
0780
0781 static int pvr2_log_status(struct file *file, void *priv)
0782 {
0783 struct pvr2_v4l2_fh *fh = file->private_data;
0784 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
0785
0786 pvr2_hdw_trigger_module_log(hdw);
0787 return 0;
0788 }
0789
0790 static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
0791 .vidioc_querycap = pvr2_querycap,
0792 .vidioc_s_audio = pvr2_s_audio,
0793 .vidioc_g_audio = pvr2_g_audio,
0794 .vidioc_enumaudio = pvr2_enumaudio,
0795 .vidioc_enum_input = pvr2_enum_input,
0796 .vidioc_g_pixelaspect = pvr2_g_pixelaspect,
0797 .vidioc_s_selection = pvr2_s_selection,
0798 .vidioc_g_selection = pvr2_g_selection,
0799 .vidioc_g_input = pvr2_g_input,
0800 .vidioc_s_input = pvr2_s_input,
0801 .vidioc_g_frequency = pvr2_g_frequency,
0802 .vidioc_s_frequency = pvr2_s_frequency,
0803 .vidioc_s_tuner = pvr2_s_tuner,
0804 .vidioc_g_tuner = pvr2_g_tuner,
0805 .vidioc_g_std = pvr2_g_std,
0806 .vidioc_s_std = pvr2_s_std,
0807 .vidioc_querystd = pvr2_querystd,
0808 .vidioc_log_status = pvr2_log_status,
0809 .vidioc_enum_fmt_vid_cap = pvr2_enum_fmt_vid_cap,
0810 .vidioc_g_fmt_vid_cap = pvr2_g_fmt_vid_cap,
0811 .vidioc_s_fmt_vid_cap = pvr2_s_fmt_vid_cap,
0812 .vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap,
0813 .vidioc_streamon = pvr2_streamon,
0814 .vidioc_streamoff = pvr2_streamoff,
0815 .vidioc_queryctrl = pvr2_queryctrl,
0816 .vidioc_querymenu = pvr2_querymenu,
0817 .vidioc_g_ctrl = pvr2_g_ctrl,
0818 .vidioc_s_ctrl = pvr2_s_ctrl,
0819 .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
0820 .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
0821 .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
0822 };
0823
0824 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
0825 {
0826 struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
0827 enum pvr2_config cfg = dip->config;
0828 char msg[80];
0829 unsigned int mcnt;
0830
0831
0832
0833
0834 mcnt = scnprintf(msg, sizeof(msg) - 1,
0835 "pvrusb2: unregistered device %s [%s]",
0836 video_device_node_name(&dip->devbase),
0837 pvr2_config_get_name(cfg));
0838 msg[mcnt] = 0;
0839
0840 pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
0841
0842
0843 dip->v4lp = NULL;
0844 dip->stream = NULL;
0845
0846
0847
0848 video_unregister_device(&dip->devbase);
0849
0850 pr_info("%s\n", msg);
0851
0852 }
0853
0854
0855 static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
0856 {
0857 if (!dip) return;
0858 if (!dip->devbase.v4l2_dev->dev) return;
0859 dip->devbase.v4l2_dev->dev = NULL;
0860 device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
0861 }
0862
0863
0864 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
0865 {
0866 if (vp->dev_video) {
0867 pvr2_v4l2_dev_destroy(vp->dev_video);
0868 vp->dev_video = NULL;
0869 }
0870 if (vp->dev_radio) {
0871 pvr2_v4l2_dev_destroy(vp->dev_radio);
0872 vp->dev_radio = NULL;
0873 }
0874
0875 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
0876 pvr2_channel_done(&vp->channel);
0877 kfree(vp);
0878 }
0879
0880
0881 static void pvr2_video_device_release(struct video_device *vdev)
0882 {
0883 struct pvr2_v4l2_dev *dev;
0884 dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
0885 kfree(dev);
0886 }
0887
0888
0889 static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
0890 {
0891 struct pvr2_v4l2 *vp;
0892 vp = container_of(chp,struct pvr2_v4l2,channel);
0893 if (!vp->channel.mc_head->disconnect_flag) return;
0894 pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
0895 pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
0896 if (!list_empty(&vp->dev_video->devbase.fh_list) ||
0897 (vp->dev_radio &&
0898 !list_empty(&vp->dev_radio->devbase.fh_list))) {
0899 pvr2_trace(PVR2_TRACE_STRUCT,
0900 "pvr2_v4l2 internal_check exit-empty id=%p", vp);
0901 return;
0902 }
0903 pvr2_v4l2_destroy_no_lock(vp);
0904 }
0905
0906
0907 static int pvr2_v4l2_release(struct file *file)
0908 {
0909 struct pvr2_v4l2_fh *fhp = file->private_data;
0910 struct pvr2_v4l2 *vp = fhp->pdi->v4lp;
0911 struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
0912
0913 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
0914
0915 if (fhp->rhp) {
0916 struct pvr2_stream *sp;
0917 pvr2_hdw_set_streaming(hdw,0);
0918 sp = pvr2_ioread_get_stream(fhp->rhp);
0919 if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
0920 pvr2_ioread_destroy(fhp->rhp);
0921 fhp->rhp = NULL;
0922 }
0923
0924 v4l2_fh_del(&fhp->fh);
0925 v4l2_fh_exit(&fhp->fh);
0926 file->private_data = NULL;
0927
0928 pvr2_channel_done(&fhp->channel);
0929 pvr2_trace(PVR2_TRACE_STRUCT,
0930 "Destroying pvr_v4l2_fh id=%p",fhp);
0931 if (fhp->input_map) {
0932 kfree(fhp->input_map);
0933 fhp->input_map = NULL;
0934 }
0935 kfree(fhp);
0936 if (vp->channel.mc_head->disconnect_flag &&
0937 list_empty(&vp->dev_video->devbase.fh_list) &&
0938 (!vp->dev_radio ||
0939 list_empty(&vp->dev_radio->devbase.fh_list))) {
0940 pvr2_v4l2_destroy_no_lock(vp);
0941 }
0942 return 0;
0943 }
0944
0945
0946 static int pvr2_v4l2_open(struct file *file)
0947 {
0948 struct pvr2_v4l2_dev *dip;
0949 struct pvr2_v4l2_fh *fhp;
0950 struct pvr2_v4l2 *vp;
0951 struct pvr2_hdw *hdw;
0952 unsigned int input_mask = 0;
0953 unsigned int input_cnt,idx;
0954 int ret = 0;
0955
0956 dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
0957
0958 vp = dip->v4lp;
0959 hdw = vp->channel.hdw;
0960
0961 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
0962
0963 if (!pvr2_hdw_dev_ok(hdw)) {
0964 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
0965 "pvr2_v4l2_open: hardware not ready");
0966 return -EIO;
0967 }
0968
0969 fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
0970 if (!fhp) {
0971 return -ENOMEM;
0972 }
0973
0974 v4l2_fh_init(&fhp->fh, &dip->devbase);
0975 init_waitqueue_head(&fhp->wait_data);
0976 fhp->pdi = dip;
0977
0978 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
0979 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
0980
0981 if (dip->v4l_type == VFL_TYPE_RADIO) {
0982
0983
0984 input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
0985 } else {
0986
0987
0988 input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
0989 (1 << PVR2_CVAL_INPUT_TV) |
0990 (1 << PVR2_CVAL_INPUT_COMPOSITE) |
0991 (1 << PVR2_CVAL_INPUT_SVIDEO));
0992 }
0993 ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
0994 if (ret) {
0995 pvr2_channel_done(&fhp->channel);
0996 pvr2_trace(PVR2_TRACE_STRUCT,
0997 "Destroying pvr_v4l2_fh id=%p (input mask error)",
0998 fhp);
0999 v4l2_fh_exit(&fhp->fh);
1000 kfree(fhp);
1001 return ret;
1002 }
1003
1004 input_mask &= pvr2_hdw_get_input_available(hdw);
1005 input_cnt = 0;
1006 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1007 if (input_mask & (1UL << idx)) input_cnt++;
1008 }
1009 fhp->input_cnt = input_cnt;
1010 fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
1011 if (!fhp->input_map) {
1012 pvr2_channel_done(&fhp->channel);
1013 pvr2_trace(PVR2_TRACE_STRUCT,
1014 "Destroying pvr_v4l2_fh id=%p (input map failure)",
1015 fhp);
1016 v4l2_fh_exit(&fhp->fh);
1017 kfree(fhp);
1018 return -ENOMEM;
1019 }
1020 input_cnt = 0;
1021 for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1022 if (!(input_mask & (1UL << idx))) continue;
1023 fhp->input_map[input_cnt++] = idx;
1024 }
1025
1026 fhp->file = file;
1027 file->private_data = fhp;
1028
1029 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1030 v4l2_fh_add(&fhp->fh);
1031
1032 return 0;
1033 }
1034
1035
1036 static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
1037 {
1038 wake_up(&fhp->wait_data);
1039 }
1040
1041 static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1042 {
1043 int ret;
1044 struct pvr2_stream *sp;
1045 struct pvr2_hdw *hdw;
1046 if (fh->rhp) return 0;
1047
1048 if (!fh->pdi->stream) {
1049
1050
1051 return -EPERM;
1052 }
1053
1054
1055
1056 if ((ret = pvr2_channel_claim_stream(&fh->channel,
1057 fh->pdi->stream)) != 0) {
1058
1059 return ret;
1060 }
1061
1062 fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
1063 if (!fh->rhp) {
1064 pvr2_channel_claim_stream(&fh->channel,NULL);
1065 return -ENOMEM;
1066 }
1067
1068 hdw = fh->channel.mc_head->hdw;
1069 sp = fh->pdi->stream->stream;
1070 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
1071 pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
1072 if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1073 return pvr2_ioread_set_enabled(fh->rhp,!0);
1074 }
1075
1076
1077 static ssize_t pvr2_v4l2_read(struct file *file,
1078 char __user *buff, size_t count, loff_t *ppos)
1079 {
1080 struct pvr2_v4l2_fh *fh = file->private_data;
1081 int ret;
1082
1083 if (fh->fw_mode_flag) {
1084 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
1085 char *tbuf;
1086 int c1,c2;
1087 int tcnt = 0;
1088 unsigned int offs = *ppos;
1089
1090 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1091 if (!tbuf) return -ENOMEM;
1092
1093 while (count) {
1094 c1 = count;
1095 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
1096 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
1097 if (c2 < 0) {
1098 tcnt = c2;
1099 break;
1100 }
1101 if (!c2) break;
1102 if (copy_to_user(buff,tbuf,c2)) {
1103 tcnt = -EFAULT;
1104 break;
1105 }
1106 offs += c2;
1107 tcnt += c2;
1108 buff += c2;
1109 count -= c2;
1110 *ppos += c2;
1111 }
1112 kfree(tbuf);
1113 return tcnt;
1114 }
1115
1116 if (!fh->rhp) {
1117 ret = pvr2_v4l2_iosetup(fh);
1118 if (ret) {
1119 return ret;
1120 }
1121 }
1122
1123 for (;;) {
1124 ret = pvr2_ioread_read(fh->rhp,buff,count);
1125 if (ret >= 0) break;
1126 if (ret != -EAGAIN) break;
1127 if (file->f_flags & O_NONBLOCK) break;
1128
1129 ret = wait_event_interruptible(
1130 fh->wait_data,
1131 pvr2_ioread_avail(fh->rhp) >= 0);
1132 if (ret < 0) break;
1133 }
1134
1135 return ret;
1136 }
1137
1138
1139 static __poll_t pvr2_v4l2_poll(struct file *file, poll_table *wait)
1140 {
1141 __poll_t mask = 0;
1142 struct pvr2_v4l2_fh *fh = file->private_data;
1143 int ret;
1144
1145 if (fh->fw_mode_flag) {
1146 mask |= EPOLLIN | EPOLLRDNORM;
1147 return mask;
1148 }
1149
1150 if (!fh->rhp) {
1151 ret = pvr2_v4l2_iosetup(fh);
1152 if (ret) return EPOLLERR;
1153 }
1154
1155 poll_wait(file,&fh->wait_data,wait);
1156
1157 if (pvr2_ioread_avail(fh->rhp) >= 0) {
1158 mask |= EPOLLIN | EPOLLRDNORM;
1159 }
1160
1161 return mask;
1162 }
1163
1164
1165 static const struct v4l2_file_operations vdev_fops = {
1166 .owner = THIS_MODULE,
1167 .open = pvr2_v4l2_open,
1168 .release = pvr2_v4l2_release,
1169 .read = pvr2_v4l2_read,
1170 .unlocked_ioctl = video_ioctl2,
1171 .poll = pvr2_v4l2_poll,
1172 };
1173
1174
1175 static const struct video_device vdev_template = {
1176 .fops = &vdev_fops,
1177 };
1178
1179
1180 static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1181 struct pvr2_v4l2 *vp,
1182 int v4l_type)
1183 {
1184 int mindevnum;
1185 int unit_number;
1186 struct pvr2_hdw *hdw;
1187 int *nr_ptr = NULL;
1188 u32 caps = V4L2_CAP_TUNER | V4L2_CAP_READWRITE;
1189
1190 dip->v4lp = vp;
1191
1192 hdw = vp->channel.mc_head->hdw;
1193 dip->v4l_type = v4l_type;
1194 switch (v4l_type) {
1195 case VFL_TYPE_VIDEO:
1196 dip->stream = &vp->channel.mc_head->video_stream;
1197 dip->config = pvr2_config_mpeg;
1198 dip->minor_type = pvr2_v4l_type_video;
1199 nr_ptr = video_nr;
1200 caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
1201 if (!dip->stream) {
1202 pr_err(KBUILD_MODNAME
1203 ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n");
1204 return;
1205 }
1206 break;
1207 case VFL_TYPE_VBI:
1208 dip->config = pvr2_config_vbi;
1209 dip->minor_type = pvr2_v4l_type_vbi;
1210 nr_ptr = vbi_nr;
1211 caps |= V4L2_CAP_VBI_CAPTURE;
1212 break;
1213 case VFL_TYPE_RADIO:
1214 dip->stream = &vp->channel.mc_head->video_stream;
1215 dip->config = pvr2_config_mpeg;
1216 dip->minor_type = pvr2_v4l_type_radio;
1217 nr_ptr = radio_nr;
1218 caps |= V4L2_CAP_RADIO;
1219 break;
1220 default:
1221
1222 pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev due to unrecognized config\n");
1223 return;
1224 }
1225
1226 dip->devbase = vdev_template;
1227 dip->devbase.release = pvr2_video_device_release;
1228 dip->devbase.ioctl_ops = &pvr2_ioctl_ops;
1229 dip->devbase.device_caps = caps;
1230 {
1231 int val;
1232 pvr2_ctrl_get_value(
1233 pvr2_hdw_get_ctrl_by_id(hdw,
1234 PVR2_CID_STDAVAIL), &val);
1235 dip->devbase.tvnorms = (v4l2_std_id)val;
1236 }
1237
1238 mindevnum = -1;
1239 unit_number = pvr2_hdw_get_unit_number(hdw);
1240 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1241 mindevnum = nr_ptr[unit_number];
1242 }
1243 pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
1244 if ((video_register_device(&dip->devbase,
1245 dip->v4l_type, mindevnum) < 0) &&
1246 (video_register_device(&dip->devbase,
1247 dip->v4l_type, -1) < 0)) {
1248 pr_err(KBUILD_MODNAME
1249 ": Failed to register pvrusb2 v4l device\n");
1250 }
1251
1252 pr_info("pvrusb2: registered device %s [%s]\n",
1253 video_device_node_name(&dip->devbase),
1254 pvr2_config_get_name(dip->config));
1255
1256 pvr2_hdw_v4l_store_minor_number(hdw,
1257 dip->minor_type,dip->devbase.minor);
1258 }
1259
1260
1261 struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1262 {
1263 struct pvr2_v4l2 *vp;
1264
1265 vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1266 if (!vp) return vp;
1267 pvr2_channel_init(&vp->channel,mnp);
1268 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1269
1270 vp->channel.check_func = pvr2_v4l2_internal_check;
1271
1272
1273 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1274 if (!vp->dev_video) goto fail;
1275 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_VIDEO);
1276 if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1277 (1 << PVR2_CVAL_INPUT_RADIO)) {
1278 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1279 if (!vp->dev_radio) goto fail;
1280 pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1281 }
1282
1283 return vp;
1284 fail:
1285 pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
1286 pvr2_v4l2_destroy_no_lock(vp);
1287 return NULL;
1288 }