0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/delay.h>
0008 #include <linux/sched.h>
0009 #include <linux/spinlock.h>
0010 #include <linux/slab.h>
0011 #include <linux/fs.h>
0012 #include <linux/unistd.h>
0013 #include <linux/time.h>
0014 #include <linux/vmalloc.h>
0015 #include <linux/pagemap.h>
0016 #include <linux/i2c.h>
0017 #include <linux/mutex.h>
0018 #include <linux/uaccess.h>
0019 #include <linux/videodev2.h>
0020 #include <media/v4l2-common.h>
0021 #include <media/v4l2-ioctl.h>
0022 #include <media/v4l2-subdev.h>
0023 #include <media/v4l2-event.h>
0024 #include <media/videobuf2-vmalloc.h>
0025 #include <media/i2c/saa7115.h>
0026
0027 #include "go7007-priv.h"
0028
0029 #define call_all(dev, o, f, args...) \
0030 v4l2_device_call_until_err(dev, 0, o, f, ##args)
0031
0032 static bool valid_pixelformat(u32 pixelformat)
0033 {
0034 switch (pixelformat) {
0035 case V4L2_PIX_FMT_MJPEG:
0036 case V4L2_PIX_FMT_MPEG1:
0037 case V4L2_PIX_FMT_MPEG2:
0038 case V4L2_PIX_FMT_MPEG4:
0039 return true;
0040 default:
0041 return false;
0042 }
0043 }
0044
0045 static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
0046 {
0047 u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
0048
0049 switch (format) {
0050 case V4L2_PIX_FMT_MJPEG:
0051 return V4L2_BUF_FLAG_KEYFRAME;
0052 case V4L2_PIX_FMT_MPEG4:
0053 switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
0054 case 0:
0055 return V4L2_BUF_FLAG_KEYFRAME;
0056 case 1:
0057 return V4L2_BUF_FLAG_PFRAME;
0058 case 2:
0059 return V4L2_BUF_FLAG_BFRAME;
0060 default:
0061 return 0;
0062 }
0063 case V4L2_PIX_FMT_MPEG1:
0064 case V4L2_PIX_FMT_MPEG2:
0065 switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
0066 case 1:
0067 return V4L2_BUF_FLAG_KEYFRAME;
0068 case 2:
0069 return V4L2_BUF_FLAG_PFRAME;
0070 case 3:
0071 return V4L2_BUF_FLAG_BFRAME;
0072 default:
0073 return 0;
0074 }
0075 }
0076
0077 return 0;
0078 }
0079
0080 static void get_resolution(struct go7007 *go, int *width, int *height)
0081 {
0082 switch (go->standard) {
0083 case GO7007_STD_NTSC:
0084 *width = 720;
0085 *height = 480;
0086 break;
0087 case GO7007_STD_PAL:
0088 *width = 720;
0089 *height = 576;
0090 break;
0091 case GO7007_STD_OTHER:
0092 default:
0093 *width = go->board_info->sensor_width;
0094 *height = go->board_info->sensor_height;
0095 break;
0096 }
0097 }
0098
0099 static void set_formatting(struct go7007 *go)
0100 {
0101 if (go->format == V4L2_PIX_FMT_MJPEG) {
0102 go->pali = 0;
0103 go->aspect_ratio = GO7007_RATIO_1_1;
0104 go->gop_size = 0;
0105 go->ipb = 0;
0106 go->closed_gop = 0;
0107 go->repeat_seqhead = 0;
0108 go->seq_header_enable = 0;
0109 go->gop_header_enable = 0;
0110 go->dvd_mode = 0;
0111 return;
0112 }
0113
0114 switch (go->format) {
0115 case V4L2_PIX_FMT_MPEG1:
0116 go->pali = 0;
0117 break;
0118 default:
0119 case V4L2_PIX_FMT_MPEG2:
0120 go->pali = 0x48;
0121 break;
0122 case V4L2_PIX_FMT_MPEG4:
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 go->pali = 0xf5;
0145 break;
0146 }
0147 go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
0148 go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
0149 go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
0150 go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
0151 go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
0152 go->gop_header_enable = 1;
0153 go->dvd_mode = 0;
0154 if (go->format == V4L2_PIX_FMT_MPEG2)
0155 go->dvd_mode =
0156 go->bitrate == 9800000 &&
0157 go->gop_size == 15 &&
0158 go->ipb == 0 &&
0159 go->repeat_seqhead == 1 &&
0160 go->closed_gop;
0161
0162 switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
0163 default:
0164 case V4L2_MPEG_VIDEO_ASPECT_1x1:
0165 go->aspect_ratio = GO7007_RATIO_1_1;
0166 break;
0167 case V4L2_MPEG_VIDEO_ASPECT_4x3:
0168 go->aspect_ratio = GO7007_RATIO_4_3;
0169 break;
0170 case V4L2_MPEG_VIDEO_ASPECT_16x9:
0171 go->aspect_ratio = GO7007_RATIO_16_9;
0172 break;
0173 }
0174 }
0175
0176 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
0177 {
0178 int sensor_height = 0, sensor_width = 0;
0179 int width, height;
0180
0181 if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
0182 return -EINVAL;
0183
0184 get_resolution(go, &sensor_width, &sensor_height);
0185
0186 if (fmt == NULL) {
0187 width = sensor_width;
0188 height = sensor_height;
0189 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
0190 if (fmt->fmt.pix.width > sensor_width)
0191 width = sensor_width;
0192 else if (fmt->fmt.pix.width < 144)
0193 width = 144;
0194 else
0195 width = fmt->fmt.pix.width & ~0x0f;
0196
0197 if (fmt->fmt.pix.height > sensor_height)
0198 height = sensor_height;
0199 else if (fmt->fmt.pix.height < 96)
0200 height = 96;
0201 else
0202 height = fmt->fmt.pix.height & ~0x0f;
0203 } else {
0204 width = fmt->fmt.pix.width;
0205
0206 if (width <= sensor_width / 4) {
0207 width = sensor_width / 4;
0208 height = sensor_height / 4;
0209 } else if (width <= sensor_width / 2) {
0210 width = sensor_width / 2;
0211 height = sensor_height / 2;
0212 } else {
0213 width = sensor_width;
0214 height = sensor_height;
0215 }
0216 width &= ~0xf;
0217 height &= ~0xf;
0218 }
0219
0220 if (fmt != NULL) {
0221 u32 pixelformat = fmt->fmt.pix.pixelformat;
0222
0223 memset(fmt, 0, sizeof(*fmt));
0224 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0225 fmt->fmt.pix.width = width;
0226 fmt->fmt.pix.height = height;
0227 fmt->fmt.pix.pixelformat = pixelformat;
0228 fmt->fmt.pix.field = V4L2_FIELD_NONE;
0229 fmt->fmt.pix.bytesperline = 0;
0230 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
0231 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
0232 }
0233
0234 if (try)
0235 return 0;
0236
0237 if (fmt)
0238 go->format = fmt->fmt.pix.pixelformat;
0239 go->width = width;
0240 go->height = height;
0241 go->encoder_h_offset = go->board_info->sensor_h_offset;
0242 go->encoder_v_offset = go->board_info->sensor_v_offset;
0243
0244 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
0245 struct v4l2_subdev_format format = {
0246 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0247 };
0248
0249 format.format.code = MEDIA_BUS_FMT_FIXED;
0250 format.format.width = fmt ? fmt->fmt.pix.width : width;
0251 format.format.height = height;
0252 go->encoder_h_halve = 0;
0253 go->encoder_v_halve = 0;
0254 go->encoder_subsample = 0;
0255 call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format);
0256 } else {
0257 if (width <= sensor_width / 4) {
0258 go->encoder_h_halve = 1;
0259 go->encoder_v_halve = 1;
0260 go->encoder_subsample = 1;
0261 } else if (width <= sensor_width / 2) {
0262 go->encoder_h_halve = 1;
0263 go->encoder_v_halve = 1;
0264 go->encoder_subsample = 0;
0265 } else {
0266 go->encoder_h_halve = 0;
0267 go->encoder_v_halve = 0;
0268 go->encoder_subsample = 0;
0269 }
0270 }
0271 return 0;
0272 }
0273
0274 static int vidioc_querycap(struct file *file, void *priv,
0275 struct v4l2_capability *cap)
0276 {
0277 struct go7007 *go = video_drvdata(file);
0278
0279 strscpy(cap->driver, "go7007", sizeof(cap->driver));
0280 strscpy(cap->card, go->name, sizeof(cap->card));
0281 strscpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
0282 return 0;
0283 }
0284
0285 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
0286 struct v4l2_fmtdesc *fmt)
0287 {
0288 switch (fmt->index) {
0289 case 0:
0290 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
0291 break;
0292 case 1:
0293 fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
0294 break;
0295 case 2:
0296 fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
0297 break;
0298 case 3:
0299 fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
0300 break;
0301 default:
0302 return -EINVAL;
0303 }
0304 return 0;
0305 }
0306
0307 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
0308 struct v4l2_format *fmt)
0309 {
0310 struct go7007 *go = video_drvdata(file);
0311
0312 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0313 fmt->fmt.pix.width = go->width;
0314 fmt->fmt.pix.height = go->height;
0315 fmt->fmt.pix.pixelformat = go->format;
0316 fmt->fmt.pix.field = V4L2_FIELD_NONE;
0317 fmt->fmt.pix.bytesperline = 0;
0318 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
0319 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
0320
0321 return 0;
0322 }
0323
0324 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
0325 struct v4l2_format *fmt)
0326 {
0327 struct go7007 *go = video_drvdata(file);
0328
0329 return set_capture_size(go, fmt, 1);
0330 }
0331
0332 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
0333 struct v4l2_format *fmt)
0334 {
0335 struct go7007 *go = video_drvdata(file);
0336
0337 if (vb2_is_busy(&go->vidq))
0338 return -EBUSY;
0339
0340 return set_capture_size(go, fmt, 0);
0341 }
0342
0343 static int go7007_queue_setup(struct vb2_queue *q,
0344 unsigned int *num_buffers, unsigned int *num_planes,
0345 unsigned int sizes[], struct device *alloc_devs[])
0346 {
0347 sizes[0] = GO7007_BUF_SIZE;
0348 *num_planes = 1;
0349
0350 if (*num_buffers < 2)
0351 *num_buffers = 2;
0352
0353 return 0;
0354 }
0355
0356 static void go7007_buf_queue(struct vb2_buffer *vb)
0357 {
0358 struct vb2_queue *vq = vb->vb2_queue;
0359 struct go7007 *go = vb2_get_drv_priv(vq);
0360 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0361 struct go7007_buffer *go7007_vb =
0362 container_of(vbuf, struct go7007_buffer, vb);
0363 unsigned long flags;
0364
0365 spin_lock_irqsave(&go->spinlock, flags);
0366 list_add_tail(&go7007_vb->list, &go->vidq_active);
0367 spin_unlock_irqrestore(&go->spinlock, flags);
0368 }
0369
0370 static int go7007_buf_prepare(struct vb2_buffer *vb)
0371 {
0372 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0373 struct go7007_buffer *go7007_vb =
0374 container_of(vbuf, struct go7007_buffer, vb);
0375
0376 go7007_vb->modet_active = 0;
0377 go7007_vb->frame_offset = 0;
0378 vb->planes[0].bytesused = 0;
0379 return 0;
0380 }
0381
0382 static void go7007_buf_finish(struct vb2_buffer *vb)
0383 {
0384 struct vb2_queue *vq = vb->vb2_queue;
0385 struct go7007 *go = vb2_get_drv_priv(vq);
0386 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0387 struct go7007_buffer *go7007_vb =
0388 container_of(vbuf, struct go7007_buffer, vb);
0389 u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
0390
0391 vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
0392 V4L2_BUF_FLAG_PFRAME);
0393 vbuf->flags |= frame_type_flag;
0394 vbuf->field = V4L2_FIELD_NONE;
0395 }
0396
0397 static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
0398 {
0399 struct go7007 *go = vb2_get_drv_priv(q);
0400 int ret;
0401
0402 set_formatting(go);
0403 mutex_lock(&go->hw_lock);
0404 go->next_seq = 0;
0405 go->active_buf = NULL;
0406 go->modet_event_status = 0;
0407 q->streaming = 1;
0408 if (go7007_start_encoder(go) < 0)
0409 ret = -EIO;
0410 else
0411 ret = 0;
0412 mutex_unlock(&go->hw_lock);
0413 if (ret) {
0414 q->streaming = 0;
0415 return ret;
0416 }
0417 call_all(&go->v4l2_dev, video, s_stream, 1);
0418 v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
0419 v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
0420 v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
0421 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
0422
0423 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
0424 go7007_write_addr(go, 0x3c82, 0x0005);
0425 return ret;
0426 }
0427
0428 static void go7007_stop_streaming(struct vb2_queue *q)
0429 {
0430 struct go7007 *go = vb2_get_drv_priv(q);
0431 unsigned long flags;
0432
0433 q->streaming = 0;
0434 go7007_stream_stop(go);
0435 mutex_lock(&go->hw_lock);
0436 go7007_reset_encoder(go);
0437 mutex_unlock(&go->hw_lock);
0438 call_all(&go->v4l2_dev, video, s_stream, 0);
0439
0440 spin_lock_irqsave(&go->spinlock, flags);
0441 INIT_LIST_HEAD(&go->vidq_active);
0442 spin_unlock_irqrestore(&go->spinlock, flags);
0443 v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
0444 v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
0445 v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
0446 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
0447
0448 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
0449 go7007_write_addr(go, 0x3c82, 0x000d);
0450 }
0451
0452 static const struct vb2_ops go7007_video_qops = {
0453 .queue_setup = go7007_queue_setup,
0454 .buf_queue = go7007_buf_queue,
0455 .buf_prepare = go7007_buf_prepare,
0456 .buf_finish = go7007_buf_finish,
0457 .start_streaming = go7007_start_streaming,
0458 .stop_streaming = go7007_stop_streaming,
0459 .wait_prepare = vb2_ops_wait_prepare,
0460 .wait_finish = vb2_ops_wait_finish,
0461 };
0462
0463 static int vidioc_g_parm(struct file *filp, void *priv,
0464 struct v4l2_streamparm *parm)
0465 {
0466 struct go7007 *go = video_drvdata(filp);
0467 struct v4l2_fract timeperframe = {
0468 .numerator = 1001 * go->fps_scale,
0469 .denominator = go->sensor_framerate,
0470 };
0471
0472 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0473 return -EINVAL;
0474
0475 parm->parm.capture.readbuffers = 2;
0476 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
0477 parm->parm.capture.timeperframe = timeperframe;
0478
0479 return 0;
0480 }
0481
0482 static int vidioc_s_parm(struct file *filp, void *priv,
0483 struct v4l2_streamparm *parm)
0484 {
0485 struct go7007 *go = video_drvdata(filp);
0486 unsigned int n, d;
0487
0488 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0489 return -EINVAL;
0490
0491 n = go->sensor_framerate *
0492 parm->parm.capture.timeperframe.numerator;
0493 d = 1001 * parm->parm.capture.timeperframe.denominator;
0494 if (n != 0 && d != 0 && n > d)
0495 go->fps_scale = (n + d/2) / d;
0496 else
0497 go->fps_scale = 1;
0498
0499 return vidioc_g_parm(filp, priv, parm);
0500 }
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 static int vidioc_enum_framesizes(struct file *filp, void *priv,
0513 struct v4l2_frmsizeenum *fsize)
0514 {
0515 struct go7007 *go = video_drvdata(filp);
0516 int width, height;
0517
0518 if (fsize->index > 2)
0519 return -EINVAL;
0520
0521 if (!valid_pixelformat(fsize->pixel_format))
0522 return -EINVAL;
0523
0524 get_resolution(go, &width, &height);
0525 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
0526 fsize->discrete.width = (width >> fsize->index) & ~0xf;
0527 fsize->discrete.height = (height >> fsize->index) & ~0xf;
0528 return 0;
0529 }
0530
0531 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
0532 struct v4l2_frmivalenum *fival)
0533 {
0534 struct go7007 *go = video_drvdata(filp);
0535 int width, height;
0536 int i;
0537
0538 if (fival->index > 4)
0539 return -EINVAL;
0540
0541 if (!valid_pixelformat(fival->pixel_format))
0542 return -EINVAL;
0543
0544 if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
0545 get_resolution(go, &width, &height);
0546 for (i = 0; i <= 2; i++)
0547 if (fival->width == ((width >> i) & ~0xf) &&
0548 fival->height == ((height >> i) & ~0xf))
0549 break;
0550 if (i > 2)
0551 return -EINVAL;
0552 }
0553 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
0554 fival->discrete.numerator = 1001 * (fival->index + 1);
0555 fival->discrete.denominator = go->sensor_framerate;
0556 return 0;
0557 }
0558
0559 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
0560 {
0561 struct go7007 *go = video_drvdata(file);
0562
0563 *std = go->std;
0564 return 0;
0565 }
0566
0567 static int go7007_s_std(struct go7007 *go)
0568 {
0569 if (go->std & V4L2_STD_625_50) {
0570 go->standard = GO7007_STD_PAL;
0571 go->sensor_framerate = 25025;
0572 } else {
0573 go->standard = GO7007_STD_NTSC;
0574 go->sensor_framerate = 30000;
0575 }
0576
0577 call_all(&go->v4l2_dev, video, s_std, go->std);
0578 set_capture_size(go, NULL, 0);
0579 return 0;
0580 }
0581
0582 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
0583 {
0584 struct go7007 *go = video_drvdata(file);
0585
0586 if (vb2_is_busy(&go->vidq))
0587 return -EBUSY;
0588
0589 go->std = std;
0590
0591 return go7007_s_std(go);
0592 }
0593
0594 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
0595 {
0596 struct go7007 *go = video_drvdata(file);
0597
0598 return call_all(&go->v4l2_dev, video, querystd, std);
0599 }
0600
0601 static int vidioc_enum_input(struct file *file, void *priv,
0602 struct v4l2_input *inp)
0603 {
0604 struct go7007 *go = video_drvdata(file);
0605
0606 if (inp->index >= go->board_info->num_inputs)
0607 return -EINVAL;
0608
0609 strscpy(inp->name, go->board_info->inputs[inp->index].name,
0610 sizeof(inp->name));
0611
0612
0613 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
0614 inp->index == 0)
0615 inp->type = V4L2_INPUT_TYPE_TUNER;
0616 else
0617 inp->type = V4L2_INPUT_TYPE_CAMERA;
0618
0619 if (go->board_info->num_aud_inputs)
0620 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
0621 else
0622 inp->audioset = 0;
0623 inp->tuner = 0;
0624 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
0625 inp->std = video_devdata(file)->tvnorms;
0626 else
0627 inp->std = 0;
0628
0629 return 0;
0630 }
0631
0632
0633 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
0634 {
0635 struct go7007 *go = video_drvdata(file);
0636
0637 *input = go->input;
0638
0639 return 0;
0640 }
0641
0642 static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
0643 {
0644 struct go7007 *go = video_drvdata(file);
0645
0646 if (a->index >= go->board_info->num_aud_inputs)
0647 return -EINVAL;
0648 strscpy(a->name, go->board_info->aud_inputs[a->index].name,
0649 sizeof(a->name));
0650 a->capability = V4L2_AUDCAP_STEREO;
0651 return 0;
0652 }
0653
0654 static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
0655 {
0656 struct go7007 *go = video_drvdata(file);
0657
0658 a->index = go->aud_input;
0659 strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
0660 sizeof(a->name));
0661 a->capability = V4L2_AUDCAP_STEREO;
0662 return 0;
0663 }
0664
0665 static int vidioc_s_audio(struct file *file, void *fh,
0666 const struct v4l2_audio *a)
0667 {
0668 struct go7007 *go = video_drvdata(file);
0669
0670 if (a->index >= go->board_info->num_aud_inputs)
0671 return -EINVAL;
0672 go->aud_input = a->index;
0673 v4l2_subdev_call(go->sd_audio, audio, s_routing,
0674 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
0675 return 0;
0676 }
0677
0678 static void go7007_s_input(struct go7007 *go)
0679 {
0680 unsigned int input = go->input;
0681
0682 v4l2_subdev_call(go->sd_video, video, s_routing,
0683 go->board_info->inputs[input].video_input, 0,
0684 go->board_info->video_config);
0685 if (go->board_info->num_aud_inputs) {
0686 int aud_input = go->board_info->inputs[input].audio_index;
0687
0688 v4l2_subdev_call(go->sd_audio, audio, s_routing,
0689 go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
0690 go->aud_input = aud_input;
0691 }
0692 }
0693
0694 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
0695 {
0696 struct go7007 *go = video_drvdata(file);
0697
0698 if (input >= go->board_info->num_inputs)
0699 return -EINVAL;
0700 if (vb2_is_busy(&go->vidq))
0701 return -EBUSY;
0702
0703 go->input = input;
0704 go7007_s_input(go);
0705
0706 return 0;
0707 }
0708
0709 static int vidioc_g_tuner(struct file *file, void *priv,
0710 struct v4l2_tuner *t)
0711 {
0712 struct go7007 *go = video_drvdata(file);
0713
0714 if (t->index != 0)
0715 return -EINVAL;
0716
0717 strscpy(t->name, "Tuner", sizeof(t->name));
0718 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
0719 }
0720
0721 static int vidioc_s_tuner(struct file *file, void *priv,
0722 const struct v4l2_tuner *t)
0723 {
0724 struct go7007 *go = video_drvdata(file);
0725
0726 if (t->index != 0)
0727 return -EINVAL;
0728
0729 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
0730 }
0731
0732 static int vidioc_g_frequency(struct file *file, void *priv,
0733 struct v4l2_frequency *f)
0734 {
0735 struct go7007 *go = video_drvdata(file);
0736
0737 if (f->tuner)
0738 return -EINVAL;
0739
0740 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
0741 }
0742
0743 static int vidioc_s_frequency(struct file *file, void *priv,
0744 const struct v4l2_frequency *f)
0745 {
0746 struct go7007 *go = video_drvdata(file);
0747
0748 if (f->tuner)
0749 return -EINVAL;
0750
0751 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
0752 }
0753
0754 static int vidioc_log_status(struct file *file, void *priv)
0755 {
0756 struct go7007 *go = video_drvdata(file);
0757
0758 v4l2_ctrl_log_status(file, priv);
0759 return call_all(&go->v4l2_dev, core, log_status);
0760 }
0761
0762 static int vidioc_subscribe_event(struct v4l2_fh *fh,
0763 const struct v4l2_event_subscription *sub)
0764 {
0765
0766 switch (sub->type) {
0767 case V4L2_EVENT_MOTION_DET:
0768
0769
0770 return v4l2_event_subscribe(fh, sub, 30, NULL);
0771 default:
0772 return v4l2_ctrl_subscribe_event(fh, sub);
0773 }
0774 }
0775
0776
0777 static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
0778 {
0779 struct go7007 *go =
0780 container_of(ctrl->handler, struct go7007, hdl);
0781 unsigned y;
0782 u8 *mt;
0783
0784 switch (ctrl->id) {
0785 case V4L2_CID_PIXEL_THRESHOLD0:
0786 go->modet[0].pixel_threshold = ctrl->val;
0787 break;
0788 case V4L2_CID_MOTION_THRESHOLD0:
0789 go->modet[0].motion_threshold = ctrl->val;
0790 break;
0791 case V4L2_CID_MB_THRESHOLD0:
0792 go->modet[0].mb_threshold = ctrl->val;
0793 break;
0794 case V4L2_CID_PIXEL_THRESHOLD1:
0795 go->modet[1].pixel_threshold = ctrl->val;
0796 break;
0797 case V4L2_CID_MOTION_THRESHOLD1:
0798 go->modet[1].motion_threshold = ctrl->val;
0799 break;
0800 case V4L2_CID_MB_THRESHOLD1:
0801 go->modet[1].mb_threshold = ctrl->val;
0802 break;
0803 case V4L2_CID_PIXEL_THRESHOLD2:
0804 go->modet[2].pixel_threshold = ctrl->val;
0805 break;
0806 case V4L2_CID_MOTION_THRESHOLD2:
0807 go->modet[2].motion_threshold = ctrl->val;
0808 break;
0809 case V4L2_CID_MB_THRESHOLD2:
0810 go->modet[2].mb_threshold = ctrl->val;
0811 break;
0812 case V4L2_CID_PIXEL_THRESHOLD3:
0813 go->modet[3].pixel_threshold = ctrl->val;
0814 break;
0815 case V4L2_CID_MOTION_THRESHOLD3:
0816 go->modet[3].motion_threshold = ctrl->val;
0817 break;
0818 case V4L2_CID_MB_THRESHOLD3:
0819 go->modet[3].mb_threshold = ctrl->val;
0820 break;
0821 case V4L2_CID_DETECT_MD_REGION_GRID:
0822 mt = go->modet_map;
0823 for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
0824 memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
0825 break;
0826 default:
0827 return -EINVAL;
0828 }
0829 return 0;
0830 }
0831
0832 static const struct v4l2_file_operations go7007_fops = {
0833 .owner = THIS_MODULE,
0834 .open = v4l2_fh_open,
0835 .release = vb2_fop_release,
0836 .unlocked_ioctl = video_ioctl2,
0837 .read = vb2_fop_read,
0838 .mmap = vb2_fop_mmap,
0839 .poll = vb2_fop_poll,
0840 };
0841
0842 static const struct v4l2_ioctl_ops video_ioctl_ops = {
0843 .vidioc_querycap = vidioc_querycap,
0844 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
0845 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
0846 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
0847 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
0848 .vidioc_reqbufs = vb2_ioctl_reqbufs,
0849 .vidioc_querybuf = vb2_ioctl_querybuf,
0850 .vidioc_qbuf = vb2_ioctl_qbuf,
0851 .vidioc_dqbuf = vb2_ioctl_dqbuf,
0852 .vidioc_g_std = vidioc_g_std,
0853 .vidioc_s_std = vidioc_s_std,
0854 .vidioc_querystd = vidioc_querystd,
0855 .vidioc_enum_input = vidioc_enum_input,
0856 .vidioc_g_input = vidioc_g_input,
0857 .vidioc_s_input = vidioc_s_input,
0858 .vidioc_enumaudio = vidioc_enumaudio,
0859 .vidioc_g_audio = vidioc_g_audio,
0860 .vidioc_s_audio = vidioc_s_audio,
0861 .vidioc_streamon = vb2_ioctl_streamon,
0862 .vidioc_streamoff = vb2_ioctl_streamoff,
0863 .vidioc_g_tuner = vidioc_g_tuner,
0864 .vidioc_s_tuner = vidioc_s_tuner,
0865 .vidioc_g_frequency = vidioc_g_frequency,
0866 .vidioc_s_frequency = vidioc_s_frequency,
0867 .vidioc_g_parm = vidioc_g_parm,
0868 .vidioc_s_parm = vidioc_s_parm,
0869 .vidioc_enum_framesizes = vidioc_enum_framesizes,
0870 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
0871 .vidioc_log_status = vidioc_log_status,
0872 .vidioc_subscribe_event = vidioc_subscribe_event,
0873 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
0874 };
0875
0876 static const struct video_device go7007_template = {
0877 .name = "go7007",
0878 .fops = &go7007_fops,
0879 .release = video_device_release_empty,
0880 .ioctl_ops = &video_ioctl_ops,
0881 .tvnorms = V4L2_STD_ALL,
0882 };
0883
0884 static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
0885 .s_ctrl = go7007_s_ctrl,
0886 };
0887
0888 static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
0889 .ops = &go7007_ctrl_ops,
0890 .id = V4L2_CID_PIXEL_THRESHOLD0,
0891 .name = "Pixel Threshold Region 0",
0892 .type = V4L2_CTRL_TYPE_INTEGER,
0893 .def = 20,
0894 .max = 32767,
0895 .step = 1,
0896 };
0897
0898 static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
0899 .ops = &go7007_ctrl_ops,
0900 .id = V4L2_CID_MOTION_THRESHOLD0,
0901 .name = "Motion Threshold Region 0",
0902 .type = V4L2_CTRL_TYPE_INTEGER,
0903 .def = 80,
0904 .max = 32767,
0905 .step = 1,
0906 };
0907
0908 static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
0909 .ops = &go7007_ctrl_ops,
0910 .id = V4L2_CID_MB_THRESHOLD0,
0911 .name = "MB Threshold Region 0",
0912 .type = V4L2_CTRL_TYPE_INTEGER,
0913 .def = 200,
0914 .max = 32767,
0915 .step = 1,
0916 };
0917
0918 static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
0919 .ops = &go7007_ctrl_ops,
0920 .id = V4L2_CID_PIXEL_THRESHOLD1,
0921 .name = "Pixel Threshold Region 1",
0922 .type = V4L2_CTRL_TYPE_INTEGER,
0923 .def = 20,
0924 .max = 32767,
0925 .step = 1,
0926 };
0927
0928 static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
0929 .ops = &go7007_ctrl_ops,
0930 .id = V4L2_CID_MOTION_THRESHOLD1,
0931 .name = "Motion Threshold Region 1",
0932 .type = V4L2_CTRL_TYPE_INTEGER,
0933 .def = 80,
0934 .max = 32767,
0935 .step = 1,
0936 };
0937
0938 static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
0939 .ops = &go7007_ctrl_ops,
0940 .id = V4L2_CID_MB_THRESHOLD1,
0941 .name = "MB Threshold Region 1",
0942 .type = V4L2_CTRL_TYPE_INTEGER,
0943 .def = 200,
0944 .max = 32767,
0945 .step = 1,
0946 };
0947
0948 static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
0949 .ops = &go7007_ctrl_ops,
0950 .id = V4L2_CID_PIXEL_THRESHOLD2,
0951 .name = "Pixel Threshold Region 2",
0952 .type = V4L2_CTRL_TYPE_INTEGER,
0953 .def = 20,
0954 .max = 32767,
0955 .step = 1,
0956 };
0957
0958 static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
0959 .ops = &go7007_ctrl_ops,
0960 .id = V4L2_CID_MOTION_THRESHOLD2,
0961 .name = "Motion Threshold Region 2",
0962 .type = V4L2_CTRL_TYPE_INTEGER,
0963 .def = 80,
0964 .max = 32767,
0965 .step = 1,
0966 };
0967
0968 static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
0969 .ops = &go7007_ctrl_ops,
0970 .id = V4L2_CID_MB_THRESHOLD2,
0971 .name = "MB Threshold Region 2",
0972 .type = V4L2_CTRL_TYPE_INTEGER,
0973 .def = 200,
0974 .max = 32767,
0975 .step = 1,
0976 };
0977
0978 static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
0979 .ops = &go7007_ctrl_ops,
0980 .id = V4L2_CID_PIXEL_THRESHOLD3,
0981 .name = "Pixel Threshold Region 3",
0982 .type = V4L2_CTRL_TYPE_INTEGER,
0983 .def = 20,
0984 .max = 32767,
0985 .step = 1,
0986 };
0987
0988 static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
0989 .ops = &go7007_ctrl_ops,
0990 .id = V4L2_CID_MOTION_THRESHOLD3,
0991 .name = "Motion Threshold Region 3",
0992 .type = V4L2_CTRL_TYPE_INTEGER,
0993 .def = 80,
0994 .max = 32767,
0995 .step = 1,
0996 };
0997
0998 static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
0999 .ops = &go7007_ctrl_ops,
1000 .id = V4L2_CID_MB_THRESHOLD3,
1001 .name = "MB Threshold Region 3",
1002 .type = V4L2_CTRL_TYPE_INTEGER,
1003 .def = 200,
1004 .max = 32767,
1005 .step = 1,
1006 };
1007
1008 static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
1009 .ops = &go7007_ctrl_ops,
1010 .id = V4L2_CID_DETECT_MD_REGION_GRID,
1011 .dims = { 576 / 16, 720 / 16 },
1012 .max = 3,
1013 .step = 1,
1014 };
1015
1016 int go7007_v4l2_ctrl_init(struct go7007 *go)
1017 {
1018 struct v4l2_ctrl_handler *hdl = &go->hdl;
1019 struct v4l2_ctrl *ctrl;
1020
1021 v4l2_ctrl_handler_init(hdl, 22);
1022 go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
1023 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
1024 go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
1025 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
1026 go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
1027 V4L2_CID_MPEG_VIDEO_BITRATE,
1028 64000, 10000000, 1, 9800000);
1029 go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
1030 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
1031 go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
1032 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
1033
1034 go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
1035 V4L2_CID_MPEG_VIDEO_ASPECT,
1036 V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
1037 V4L2_MPEG_VIDEO_ASPECT_1x1);
1038 ctrl = v4l2_ctrl_new_std(hdl, NULL,
1039 V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1040 V4L2_JPEG_ACTIVE_MARKER_DQT |
1041 V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1042 V4L2_JPEG_ACTIVE_MARKER_DQT |
1043 V4L2_JPEG_ACTIVE_MARKER_DHT);
1044 if (ctrl)
1045 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1046 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
1047 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
1048 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
1049 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
1050 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
1051 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
1052 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
1053 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
1054 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
1055 v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
1056 v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
1057 v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
1058 v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
1059 go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
1060 V4L2_CID_DETECT_MD_MODE,
1061 V4L2_DETECT_MD_MODE_REGION_GRID,
1062 1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
1063 V4L2_DETECT_MD_MODE_DISABLED);
1064 if (hdl->error) {
1065 int rv = hdl->error;
1066
1067 v4l2_err(&go->v4l2_dev, "Could not register controls\n");
1068 return rv;
1069 }
1070 go->v4l2_dev.ctrl_handler = hdl;
1071 return 0;
1072 }
1073
1074 int go7007_v4l2_init(struct go7007 *go)
1075 {
1076 struct video_device *vdev = &go->vdev;
1077 int rv;
1078
1079 mutex_init(&go->serialize_lock);
1080 mutex_init(&go->queue_lock);
1081
1082 INIT_LIST_HEAD(&go->vidq_active);
1083 go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1084 go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1085 go->vidq.ops = &go7007_video_qops;
1086 go->vidq.mem_ops = &vb2_vmalloc_memops;
1087 go->vidq.drv_priv = go;
1088 go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
1089 go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1090 go->vidq.lock = &go->queue_lock;
1091 rv = vb2_queue_init(&go->vidq);
1092 if (rv)
1093 return rv;
1094 *vdev = go7007_template;
1095 vdev->lock = &go->serialize_lock;
1096 vdev->queue = &go->vidq;
1097 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1098 V4L2_CAP_STREAMING;
1099 if (go->board_info->num_aud_inputs)
1100 vdev->device_caps |= V4L2_CAP_AUDIO;
1101 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
1102 vdev->device_caps |= V4L2_CAP_TUNER;
1103 video_set_drvdata(vdev, go);
1104 vdev->v4l2_dev = &go->v4l2_dev;
1105 if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd))
1106 v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1107 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1108 v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1109 v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1110 v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1111 v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1112 } else {
1113 struct v4l2_frequency f = {
1114 .type = V4L2_TUNER_ANALOG_TV,
1115 .frequency = 980,
1116 };
1117
1118 call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1119 }
1120 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1121 v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1122 v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1123 vdev->tvnorms = 0;
1124 }
1125 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1126 v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1127 if (go->board_info->num_aud_inputs == 0) {
1128 v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1129 v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1130 v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1131 }
1132
1133 if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1134 v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1135 SAA7115_FREQ_24_576_MHZ,
1136 SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1137 SAA7115_FREQ_FL_DOUBLE_ASCLK);
1138 go7007_s_input(go);
1139 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1140 go7007_s_std(go);
1141 rv = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1142 if (rv < 0)
1143 return rv;
1144 dev_info(go->dev, "registered device %s [v4l2]\n",
1145 video_device_node_name(vdev));
1146
1147 return 0;
1148 }
1149
1150 void go7007_v4l2_remove(struct go7007 *go)
1151 {
1152 v4l2_ctrl_handler_free(&go->hdl);
1153 }