go7007-v4l2.c (30670B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2005-2006 Micronas USA Inc. 4 */ 5 6#include <linux/module.h> 7#include <linux/delay.h> 8#include <linux/sched.h> 9#include <linux/spinlock.h> 10#include <linux/slab.h> 11#include <linux/fs.h> 12#include <linux/unistd.h> 13#include <linux/time.h> 14#include <linux/vmalloc.h> 15#include <linux/pagemap.h> 16#include <linux/i2c.h> 17#include <linux/mutex.h> 18#include <linux/uaccess.h> 19#include <linux/videodev2.h> 20#include <media/v4l2-common.h> 21#include <media/v4l2-ioctl.h> 22#include <media/v4l2-subdev.h> 23#include <media/v4l2-event.h> 24#include <media/videobuf2-vmalloc.h> 25#include <media/i2c/saa7115.h> 26 27#include "go7007-priv.h" 28 29#define call_all(dev, o, f, args...) \ 30 v4l2_device_call_until_err(dev, 0, o, f, ##args) 31 32static bool valid_pixelformat(u32 pixelformat) 33{ 34 switch (pixelformat) { 35 case V4L2_PIX_FMT_MJPEG: 36 case V4L2_PIX_FMT_MPEG1: 37 case V4L2_PIX_FMT_MPEG2: 38 case V4L2_PIX_FMT_MPEG4: 39 return true; 40 default: 41 return false; 42 } 43} 44 45static u32 get_frame_type_flag(struct go7007_buffer *vb, int format) 46{ 47 u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0); 48 49 switch (format) { 50 case V4L2_PIX_FMT_MJPEG: 51 return V4L2_BUF_FLAG_KEYFRAME; 52 case V4L2_PIX_FMT_MPEG4: 53 switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) { 54 case 0: 55 return V4L2_BUF_FLAG_KEYFRAME; 56 case 1: 57 return V4L2_BUF_FLAG_PFRAME; 58 case 2: 59 return V4L2_BUF_FLAG_BFRAME; 60 default: 61 return 0; 62 } 63 case V4L2_PIX_FMT_MPEG1: 64 case V4L2_PIX_FMT_MPEG2: 65 switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) { 66 case 1: 67 return V4L2_BUF_FLAG_KEYFRAME; 68 case 2: 69 return V4L2_BUF_FLAG_PFRAME; 70 case 3: 71 return V4L2_BUF_FLAG_BFRAME; 72 default: 73 return 0; 74 } 75 } 76 77 return 0; 78} 79 80static void get_resolution(struct go7007 *go, int *width, int *height) 81{ 82 switch (go->standard) { 83 case GO7007_STD_NTSC: 84 *width = 720; 85 *height = 480; 86 break; 87 case GO7007_STD_PAL: 88 *width = 720; 89 *height = 576; 90 break; 91 case GO7007_STD_OTHER: 92 default: 93 *width = go->board_info->sensor_width; 94 *height = go->board_info->sensor_height; 95 break; 96 } 97} 98 99static void set_formatting(struct go7007 *go) 100{ 101 if (go->format == V4L2_PIX_FMT_MJPEG) { 102 go->pali = 0; 103 go->aspect_ratio = GO7007_RATIO_1_1; 104 go->gop_size = 0; 105 go->ipb = 0; 106 go->closed_gop = 0; 107 go->repeat_seqhead = 0; 108 go->seq_header_enable = 0; 109 go->gop_header_enable = 0; 110 go->dvd_mode = 0; 111 return; 112 } 113 114 switch (go->format) { 115 case V4L2_PIX_FMT_MPEG1: 116 go->pali = 0; 117 break; 118 default: 119 case V4L2_PIX_FMT_MPEG2: 120 go->pali = 0x48; 121 break; 122 case V4L2_PIX_FMT_MPEG4: 123 /* For future reference: this is the list of MPEG4 124 * profiles that are available, although they are 125 * untested: 126 * 127 * Profile pali 128 * -------------- ---- 129 * PROFILE_S_L0 0x08 130 * PROFILE_S_L1 0x01 131 * PROFILE_S_L2 0x02 132 * PROFILE_S_L3 0x03 133 * PROFILE_ARTS_L1 0x91 134 * PROFILE_ARTS_L2 0x92 135 * PROFILE_ARTS_L3 0x93 136 * PROFILE_ARTS_L4 0x94 137 * PROFILE_AS_L0 0xf0 138 * PROFILE_AS_L1 0xf1 139 * PROFILE_AS_L2 0xf2 140 * PROFILE_AS_L3 0xf3 141 * PROFILE_AS_L4 0xf4 142 * PROFILE_AS_L5 0xf5 143 */ 144 go->pali = 0xf5; 145 break; 146 } 147 go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size); 148 go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure); 149 go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0; 150 go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate); 151 go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader); 152 go->gop_header_enable = 1; 153 go->dvd_mode = 0; 154 if (go->format == V4L2_PIX_FMT_MPEG2) 155 go->dvd_mode = 156 go->bitrate == 9800000 && 157 go->gop_size == 15 && 158 go->ipb == 0 && 159 go->repeat_seqhead == 1 && 160 go->closed_gop; 161 162 switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) { 163 default: 164 case V4L2_MPEG_VIDEO_ASPECT_1x1: 165 go->aspect_ratio = GO7007_RATIO_1_1; 166 break; 167 case V4L2_MPEG_VIDEO_ASPECT_4x3: 168 go->aspect_ratio = GO7007_RATIO_4_3; 169 break; 170 case V4L2_MPEG_VIDEO_ASPECT_16x9: 171 go->aspect_ratio = GO7007_RATIO_16_9; 172 break; 173 } 174} 175 176static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) 177{ 178 int sensor_height = 0, sensor_width = 0; 179 int width, height; 180 181 if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat)) 182 return -EINVAL; 183 184 get_resolution(go, &sensor_width, &sensor_height); 185 186 if (fmt == NULL) { 187 width = sensor_width; 188 height = sensor_height; 189 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { 190 if (fmt->fmt.pix.width > sensor_width) 191 width = sensor_width; 192 else if (fmt->fmt.pix.width < 144) 193 width = 144; 194 else 195 width = fmt->fmt.pix.width & ~0x0f; 196 197 if (fmt->fmt.pix.height > sensor_height) 198 height = sensor_height; 199 else if (fmt->fmt.pix.height < 96) 200 height = 96; 201 else 202 height = fmt->fmt.pix.height & ~0x0f; 203 } else { 204 width = fmt->fmt.pix.width; 205 206 if (width <= sensor_width / 4) { 207 width = sensor_width / 4; 208 height = sensor_height / 4; 209 } else if (width <= sensor_width / 2) { 210 width = sensor_width / 2; 211 height = sensor_height / 2; 212 } else { 213 width = sensor_width; 214 height = sensor_height; 215 } 216 width &= ~0xf; 217 height &= ~0xf; 218 } 219 220 if (fmt != NULL) { 221 u32 pixelformat = fmt->fmt.pix.pixelformat; 222 223 memset(fmt, 0, sizeof(*fmt)); 224 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 225 fmt->fmt.pix.width = width; 226 fmt->fmt.pix.height = height; 227 fmt->fmt.pix.pixelformat = pixelformat; 228 fmt->fmt.pix.field = V4L2_FIELD_NONE; 229 fmt->fmt.pix.bytesperline = 0; 230 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; 231 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 232 } 233 234 if (try) 235 return 0; 236 237 if (fmt) 238 go->format = fmt->fmt.pix.pixelformat; 239 go->width = width; 240 go->height = height; 241 go->encoder_h_offset = go->board_info->sensor_h_offset; 242 go->encoder_v_offset = go->board_info->sensor_v_offset; 243 244 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { 245 struct v4l2_subdev_format format = { 246 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 247 }; 248 249 format.format.code = MEDIA_BUS_FMT_FIXED; 250 format.format.width = fmt ? fmt->fmt.pix.width : width; 251 format.format.height = height; 252 go->encoder_h_halve = 0; 253 go->encoder_v_halve = 0; 254 go->encoder_subsample = 0; 255 call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format); 256 } else { 257 if (width <= sensor_width / 4) { 258 go->encoder_h_halve = 1; 259 go->encoder_v_halve = 1; 260 go->encoder_subsample = 1; 261 } else if (width <= sensor_width / 2) { 262 go->encoder_h_halve = 1; 263 go->encoder_v_halve = 1; 264 go->encoder_subsample = 0; 265 } else { 266 go->encoder_h_halve = 0; 267 go->encoder_v_halve = 0; 268 go->encoder_subsample = 0; 269 } 270 } 271 return 0; 272} 273 274static int vidioc_querycap(struct file *file, void *priv, 275 struct v4l2_capability *cap) 276{ 277 struct go7007 *go = video_drvdata(file); 278 279 strscpy(cap->driver, "go7007", sizeof(cap->driver)); 280 strscpy(cap->card, go->name, sizeof(cap->card)); 281 strscpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info)); 282 return 0; 283} 284 285static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 286 struct v4l2_fmtdesc *fmt) 287{ 288 switch (fmt->index) { 289 case 0: 290 fmt->pixelformat = V4L2_PIX_FMT_MJPEG; 291 break; 292 case 1: 293 fmt->pixelformat = V4L2_PIX_FMT_MPEG1; 294 break; 295 case 2: 296 fmt->pixelformat = V4L2_PIX_FMT_MPEG2; 297 break; 298 case 3: 299 fmt->pixelformat = V4L2_PIX_FMT_MPEG4; 300 break; 301 default: 302 return -EINVAL; 303 } 304 return 0; 305} 306 307static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 308 struct v4l2_format *fmt) 309{ 310 struct go7007 *go = video_drvdata(file); 311 312 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 313 fmt->fmt.pix.width = go->width; 314 fmt->fmt.pix.height = go->height; 315 fmt->fmt.pix.pixelformat = go->format; 316 fmt->fmt.pix.field = V4L2_FIELD_NONE; 317 fmt->fmt.pix.bytesperline = 0; 318 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; 319 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 320 321 return 0; 322} 323 324static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 325 struct v4l2_format *fmt) 326{ 327 struct go7007 *go = video_drvdata(file); 328 329 return set_capture_size(go, fmt, 1); 330} 331 332static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 333 struct v4l2_format *fmt) 334{ 335 struct go7007 *go = video_drvdata(file); 336 337 if (vb2_is_busy(&go->vidq)) 338 return -EBUSY; 339 340 return set_capture_size(go, fmt, 0); 341} 342 343static int go7007_queue_setup(struct vb2_queue *q, 344 unsigned int *num_buffers, unsigned int *num_planes, 345 unsigned int sizes[], struct device *alloc_devs[]) 346{ 347 sizes[0] = GO7007_BUF_SIZE; 348 *num_planes = 1; 349 350 if (*num_buffers < 2) 351 *num_buffers = 2; 352 353 return 0; 354} 355 356static void go7007_buf_queue(struct vb2_buffer *vb) 357{ 358 struct vb2_queue *vq = vb->vb2_queue; 359 struct go7007 *go = vb2_get_drv_priv(vq); 360 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 361 struct go7007_buffer *go7007_vb = 362 container_of(vbuf, struct go7007_buffer, vb); 363 unsigned long flags; 364 365 spin_lock_irqsave(&go->spinlock, flags); 366 list_add_tail(&go7007_vb->list, &go->vidq_active); 367 spin_unlock_irqrestore(&go->spinlock, flags); 368} 369 370static int go7007_buf_prepare(struct vb2_buffer *vb) 371{ 372 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 373 struct go7007_buffer *go7007_vb = 374 container_of(vbuf, struct go7007_buffer, vb); 375 376 go7007_vb->modet_active = 0; 377 go7007_vb->frame_offset = 0; 378 vb->planes[0].bytesused = 0; 379 return 0; 380} 381 382static void go7007_buf_finish(struct vb2_buffer *vb) 383{ 384 struct vb2_queue *vq = vb->vb2_queue; 385 struct go7007 *go = vb2_get_drv_priv(vq); 386 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 387 struct go7007_buffer *go7007_vb = 388 container_of(vbuf, struct go7007_buffer, vb); 389 u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format); 390 391 vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME | 392 V4L2_BUF_FLAG_PFRAME); 393 vbuf->flags |= frame_type_flag; 394 vbuf->field = V4L2_FIELD_NONE; 395} 396 397static int go7007_start_streaming(struct vb2_queue *q, unsigned int count) 398{ 399 struct go7007 *go = vb2_get_drv_priv(q); 400 int ret; 401 402 set_formatting(go); 403 mutex_lock(&go->hw_lock); 404 go->next_seq = 0; 405 go->active_buf = NULL; 406 go->modet_event_status = 0; 407 q->streaming = 1; 408 if (go7007_start_encoder(go) < 0) 409 ret = -EIO; 410 else 411 ret = 0; 412 mutex_unlock(&go->hw_lock); 413 if (ret) { 414 q->streaming = 0; 415 return ret; 416 } 417 call_all(&go->v4l2_dev, video, s_stream, 1); 418 v4l2_ctrl_grab(go->mpeg_video_gop_size, true); 419 v4l2_ctrl_grab(go->mpeg_video_gop_closure, true); 420 v4l2_ctrl_grab(go->mpeg_video_bitrate, true); 421 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true); 422 /* Turn on Capture LED */ 423 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) 424 go7007_write_addr(go, 0x3c82, 0x0005); 425 return ret; 426} 427 428static void go7007_stop_streaming(struct vb2_queue *q) 429{ 430 struct go7007 *go = vb2_get_drv_priv(q); 431 unsigned long flags; 432 433 q->streaming = 0; 434 go7007_stream_stop(go); 435 mutex_lock(&go->hw_lock); 436 go7007_reset_encoder(go); 437 mutex_unlock(&go->hw_lock); 438 call_all(&go->v4l2_dev, video, s_stream, 0); 439 440 spin_lock_irqsave(&go->spinlock, flags); 441 INIT_LIST_HEAD(&go->vidq_active); 442 spin_unlock_irqrestore(&go->spinlock, flags); 443 v4l2_ctrl_grab(go->mpeg_video_gop_size, false); 444 v4l2_ctrl_grab(go->mpeg_video_gop_closure, false); 445 v4l2_ctrl_grab(go->mpeg_video_bitrate, false); 446 v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false); 447 /* Turn on Capture LED */ 448 if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) 449 go7007_write_addr(go, 0x3c82, 0x000d); 450} 451 452static const struct vb2_ops go7007_video_qops = { 453 .queue_setup = go7007_queue_setup, 454 .buf_queue = go7007_buf_queue, 455 .buf_prepare = go7007_buf_prepare, 456 .buf_finish = go7007_buf_finish, 457 .start_streaming = go7007_start_streaming, 458 .stop_streaming = go7007_stop_streaming, 459 .wait_prepare = vb2_ops_wait_prepare, 460 .wait_finish = vb2_ops_wait_finish, 461}; 462 463static int vidioc_g_parm(struct file *filp, void *priv, 464 struct v4l2_streamparm *parm) 465{ 466 struct go7007 *go = video_drvdata(filp); 467 struct v4l2_fract timeperframe = { 468 .numerator = 1001 * go->fps_scale, 469 .denominator = go->sensor_framerate, 470 }; 471 472 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 473 return -EINVAL; 474 475 parm->parm.capture.readbuffers = 2; 476 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 477 parm->parm.capture.timeperframe = timeperframe; 478 479 return 0; 480} 481 482static int vidioc_s_parm(struct file *filp, void *priv, 483 struct v4l2_streamparm *parm) 484{ 485 struct go7007 *go = video_drvdata(filp); 486 unsigned int n, d; 487 488 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 489 return -EINVAL; 490 491 n = go->sensor_framerate * 492 parm->parm.capture.timeperframe.numerator; 493 d = 1001 * parm->parm.capture.timeperframe.denominator; 494 if (n != 0 && d != 0 && n > d) 495 go->fps_scale = (n + d/2) / d; 496 else 497 go->fps_scale = 1; 498 499 return vidioc_g_parm(filp, priv, parm); 500} 501 502/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and 503 its resolution, when the device is not connected to TV. 504 This is were an API abuse, probably used by the lack of specific IOCTL's to 505 enumerate it, by the time the driver was written. 506 507 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS 508 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose. 509 510 The two functions below implement the newer ioctls 511*/ 512static int vidioc_enum_framesizes(struct file *filp, void *priv, 513 struct v4l2_frmsizeenum *fsize) 514{ 515 struct go7007 *go = video_drvdata(filp); 516 int width, height; 517 518 if (fsize->index > 2) 519 return -EINVAL; 520 521 if (!valid_pixelformat(fsize->pixel_format)) 522 return -EINVAL; 523 524 get_resolution(go, &width, &height); 525 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 526 fsize->discrete.width = (width >> fsize->index) & ~0xf; 527 fsize->discrete.height = (height >> fsize->index) & ~0xf; 528 return 0; 529} 530 531static int vidioc_enum_frameintervals(struct file *filp, void *priv, 532 struct v4l2_frmivalenum *fival) 533{ 534 struct go7007 *go = video_drvdata(filp); 535 int width, height; 536 int i; 537 538 if (fival->index > 4) 539 return -EINVAL; 540 541 if (!valid_pixelformat(fival->pixel_format)) 542 return -EINVAL; 543 544 if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) { 545 get_resolution(go, &width, &height); 546 for (i = 0; i <= 2; i++) 547 if (fival->width == ((width >> i) & ~0xf) && 548 fival->height == ((height >> i) & ~0xf)) 549 break; 550 if (i > 2) 551 return -EINVAL; 552 } 553 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 554 fival->discrete.numerator = 1001 * (fival->index + 1); 555 fival->discrete.denominator = go->sensor_framerate; 556 return 0; 557} 558 559static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std) 560{ 561 struct go7007 *go = video_drvdata(file); 562 563 *std = go->std; 564 return 0; 565} 566 567static int go7007_s_std(struct go7007 *go) 568{ 569 if (go->std & V4L2_STD_625_50) { 570 go->standard = GO7007_STD_PAL; 571 go->sensor_framerate = 25025; 572 } else { 573 go->standard = GO7007_STD_NTSC; 574 go->sensor_framerate = 30000; 575 } 576 577 call_all(&go->v4l2_dev, video, s_std, go->std); 578 set_capture_size(go, NULL, 0); 579 return 0; 580} 581 582static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std) 583{ 584 struct go7007 *go = video_drvdata(file); 585 586 if (vb2_is_busy(&go->vidq)) 587 return -EBUSY; 588 589 go->std = std; 590 591 return go7007_s_std(go); 592} 593 594static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std) 595{ 596 struct go7007 *go = video_drvdata(file); 597 598 return call_all(&go->v4l2_dev, video, querystd, std); 599} 600 601static int vidioc_enum_input(struct file *file, void *priv, 602 struct v4l2_input *inp) 603{ 604 struct go7007 *go = video_drvdata(file); 605 606 if (inp->index >= go->board_info->num_inputs) 607 return -EINVAL; 608 609 strscpy(inp->name, go->board_info->inputs[inp->index].name, 610 sizeof(inp->name)); 611 612 /* If this board has a tuner, it will be the first input */ 613 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 614 inp->index == 0) 615 inp->type = V4L2_INPUT_TYPE_TUNER; 616 else 617 inp->type = V4L2_INPUT_TYPE_CAMERA; 618 619 if (go->board_info->num_aud_inputs) 620 inp->audioset = (1 << go->board_info->num_aud_inputs) - 1; 621 else 622 inp->audioset = 0; 623 inp->tuner = 0; 624 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 625 inp->std = video_devdata(file)->tvnorms; 626 else 627 inp->std = 0; 628 629 return 0; 630} 631 632 633static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) 634{ 635 struct go7007 *go = video_drvdata(file); 636 637 *input = go->input; 638 639 return 0; 640} 641 642static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) 643{ 644 struct go7007 *go = video_drvdata(file); 645 646 if (a->index >= go->board_info->num_aud_inputs) 647 return -EINVAL; 648 strscpy(a->name, go->board_info->aud_inputs[a->index].name, 649 sizeof(a->name)); 650 a->capability = V4L2_AUDCAP_STEREO; 651 return 0; 652} 653 654static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 655{ 656 struct go7007 *go = video_drvdata(file); 657 658 a->index = go->aud_input; 659 strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name, 660 sizeof(a->name)); 661 a->capability = V4L2_AUDCAP_STEREO; 662 return 0; 663} 664 665static int vidioc_s_audio(struct file *file, void *fh, 666 const struct v4l2_audio *a) 667{ 668 struct go7007 *go = video_drvdata(file); 669 670 if (a->index >= go->board_info->num_aud_inputs) 671 return -EINVAL; 672 go->aud_input = a->index; 673 v4l2_subdev_call(go->sd_audio, audio, s_routing, 674 go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0); 675 return 0; 676} 677 678static void go7007_s_input(struct go7007 *go) 679{ 680 unsigned int input = go->input; 681 682 v4l2_subdev_call(go->sd_video, video, s_routing, 683 go->board_info->inputs[input].video_input, 0, 684 go->board_info->video_config); 685 if (go->board_info->num_aud_inputs) { 686 int aud_input = go->board_info->inputs[input].audio_index; 687 688 v4l2_subdev_call(go->sd_audio, audio, s_routing, 689 go->board_info->aud_inputs[aud_input].audio_input, 0, 0); 690 go->aud_input = aud_input; 691 } 692} 693 694static int vidioc_s_input(struct file *file, void *priv, unsigned int input) 695{ 696 struct go7007 *go = video_drvdata(file); 697 698 if (input >= go->board_info->num_inputs) 699 return -EINVAL; 700 if (vb2_is_busy(&go->vidq)) 701 return -EBUSY; 702 703 go->input = input; 704 go7007_s_input(go); 705 706 return 0; 707} 708 709static int vidioc_g_tuner(struct file *file, void *priv, 710 struct v4l2_tuner *t) 711{ 712 struct go7007 *go = video_drvdata(file); 713 714 if (t->index != 0) 715 return -EINVAL; 716 717 strscpy(t->name, "Tuner", sizeof(t->name)); 718 return call_all(&go->v4l2_dev, tuner, g_tuner, t); 719} 720 721static int vidioc_s_tuner(struct file *file, void *priv, 722 const struct v4l2_tuner *t) 723{ 724 struct go7007 *go = video_drvdata(file); 725 726 if (t->index != 0) 727 return -EINVAL; 728 729 return call_all(&go->v4l2_dev, tuner, s_tuner, t); 730} 731 732static int vidioc_g_frequency(struct file *file, void *priv, 733 struct v4l2_frequency *f) 734{ 735 struct go7007 *go = video_drvdata(file); 736 737 if (f->tuner) 738 return -EINVAL; 739 740 return call_all(&go->v4l2_dev, tuner, g_frequency, f); 741} 742 743static int vidioc_s_frequency(struct file *file, void *priv, 744 const struct v4l2_frequency *f) 745{ 746 struct go7007 *go = video_drvdata(file); 747 748 if (f->tuner) 749 return -EINVAL; 750 751 return call_all(&go->v4l2_dev, tuner, s_frequency, f); 752} 753 754static int vidioc_log_status(struct file *file, void *priv) 755{ 756 struct go7007 *go = video_drvdata(file); 757 758 v4l2_ctrl_log_status(file, priv); 759 return call_all(&go->v4l2_dev, core, log_status); 760} 761 762static int vidioc_subscribe_event(struct v4l2_fh *fh, 763 const struct v4l2_event_subscription *sub) 764{ 765 766 switch (sub->type) { 767 case V4L2_EVENT_MOTION_DET: 768 /* Allow for up to 30 events (1 second for NTSC) to be 769 * stored. */ 770 return v4l2_event_subscribe(fh, sub, 30, NULL); 771 default: 772 return v4l2_ctrl_subscribe_event(fh, sub); 773 } 774} 775 776 777static int go7007_s_ctrl(struct v4l2_ctrl *ctrl) 778{ 779 struct go7007 *go = 780 container_of(ctrl->handler, struct go7007, hdl); 781 unsigned y; 782 u8 *mt; 783 784 switch (ctrl->id) { 785 case V4L2_CID_PIXEL_THRESHOLD0: 786 go->modet[0].pixel_threshold = ctrl->val; 787 break; 788 case V4L2_CID_MOTION_THRESHOLD0: 789 go->modet[0].motion_threshold = ctrl->val; 790 break; 791 case V4L2_CID_MB_THRESHOLD0: 792 go->modet[0].mb_threshold = ctrl->val; 793 break; 794 case V4L2_CID_PIXEL_THRESHOLD1: 795 go->modet[1].pixel_threshold = ctrl->val; 796 break; 797 case V4L2_CID_MOTION_THRESHOLD1: 798 go->modet[1].motion_threshold = ctrl->val; 799 break; 800 case V4L2_CID_MB_THRESHOLD1: 801 go->modet[1].mb_threshold = ctrl->val; 802 break; 803 case V4L2_CID_PIXEL_THRESHOLD2: 804 go->modet[2].pixel_threshold = ctrl->val; 805 break; 806 case V4L2_CID_MOTION_THRESHOLD2: 807 go->modet[2].motion_threshold = ctrl->val; 808 break; 809 case V4L2_CID_MB_THRESHOLD2: 810 go->modet[2].mb_threshold = ctrl->val; 811 break; 812 case V4L2_CID_PIXEL_THRESHOLD3: 813 go->modet[3].pixel_threshold = ctrl->val; 814 break; 815 case V4L2_CID_MOTION_THRESHOLD3: 816 go->modet[3].motion_threshold = ctrl->val; 817 break; 818 case V4L2_CID_MB_THRESHOLD3: 819 go->modet[3].mb_threshold = ctrl->val; 820 break; 821 case V4L2_CID_DETECT_MD_REGION_GRID: 822 mt = go->modet_map; 823 for (y = 0; y < go->height / 16; y++, mt += go->width / 16) 824 memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16); 825 break; 826 default: 827 return -EINVAL; 828 } 829 return 0; 830} 831 832static const struct v4l2_file_operations go7007_fops = { 833 .owner = THIS_MODULE, 834 .open = v4l2_fh_open, 835 .release = vb2_fop_release, 836 .unlocked_ioctl = video_ioctl2, 837 .read = vb2_fop_read, 838 .mmap = vb2_fop_mmap, 839 .poll = vb2_fop_poll, 840}; 841 842static const struct v4l2_ioctl_ops video_ioctl_ops = { 843 .vidioc_querycap = vidioc_querycap, 844 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 845 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 846 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 847 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 848 .vidioc_reqbufs = vb2_ioctl_reqbufs, 849 .vidioc_querybuf = vb2_ioctl_querybuf, 850 .vidioc_qbuf = vb2_ioctl_qbuf, 851 .vidioc_dqbuf = vb2_ioctl_dqbuf, 852 .vidioc_g_std = vidioc_g_std, 853 .vidioc_s_std = vidioc_s_std, 854 .vidioc_querystd = vidioc_querystd, 855 .vidioc_enum_input = vidioc_enum_input, 856 .vidioc_g_input = vidioc_g_input, 857 .vidioc_s_input = vidioc_s_input, 858 .vidioc_enumaudio = vidioc_enumaudio, 859 .vidioc_g_audio = vidioc_g_audio, 860 .vidioc_s_audio = vidioc_s_audio, 861 .vidioc_streamon = vb2_ioctl_streamon, 862 .vidioc_streamoff = vb2_ioctl_streamoff, 863 .vidioc_g_tuner = vidioc_g_tuner, 864 .vidioc_s_tuner = vidioc_s_tuner, 865 .vidioc_g_frequency = vidioc_g_frequency, 866 .vidioc_s_frequency = vidioc_s_frequency, 867 .vidioc_g_parm = vidioc_g_parm, 868 .vidioc_s_parm = vidioc_s_parm, 869 .vidioc_enum_framesizes = vidioc_enum_framesizes, 870 .vidioc_enum_frameintervals = vidioc_enum_frameintervals, 871 .vidioc_log_status = vidioc_log_status, 872 .vidioc_subscribe_event = vidioc_subscribe_event, 873 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 874}; 875 876static const struct video_device go7007_template = { 877 .name = "go7007", 878 .fops = &go7007_fops, 879 .release = video_device_release_empty, 880 .ioctl_ops = &video_ioctl_ops, 881 .tvnorms = V4L2_STD_ALL, 882}; 883 884static const struct v4l2_ctrl_ops go7007_ctrl_ops = { 885 .s_ctrl = go7007_s_ctrl, 886}; 887 888static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = { 889 .ops = &go7007_ctrl_ops, 890 .id = V4L2_CID_PIXEL_THRESHOLD0, 891 .name = "Pixel Threshold Region 0", 892 .type = V4L2_CTRL_TYPE_INTEGER, 893 .def = 20, 894 .max = 32767, 895 .step = 1, 896}; 897 898static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = { 899 .ops = &go7007_ctrl_ops, 900 .id = V4L2_CID_MOTION_THRESHOLD0, 901 .name = "Motion Threshold Region 0", 902 .type = V4L2_CTRL_TYPE_INTEGER, 903 .def = 80, 904 .max = 32767, 905 .step = 1, 906}; 907 908static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = { 909 .ops = &go7007_ctrl_ops, 910 .id = V4L2_CID_MB_THRESHOLD0, 911 .name = "MB Threshold Region 0", 912 .type = V4L2_CTRL_TYPE_INTEGER, 913 .def = 200, 914 .max = 32767, 915 .step = 1, 916}; 917 918static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = { 919 .ops = &go7007_ctrl_ops, 920 .id = V4L2_CID_PIXEL_THRESHOLD1, 921 .name = "Pixel Threshold Region 1", 922 .type = V4L2_CTRL_TYPE_INTEGER, 923 .def = 20, 924 .max = 32767, 925 .step = 1, 926}; 927 928static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = { 929 .ops = &go7007_ctrl_ops, 930 .id = V4L2_CID_MOTION_THRESHOLD1, 931 .name = "Motion Threshold Region 1", 932 .type = V4L2_CTRL_TYPE_INTEGER, 933 .def = 80, 934 .max = 32767, 935 .step = 1, 936}; 937 938static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = { 939 .ops = &go7007_ctrl_ops, 940 .id = V4L2_CID_MB_THRESHOLD1, 941 .name = "MB Threshold Region 1", 942 .type = V4L2_CTRL_TYPE_INTEGER, 943 .def = 200, 944 .max = 32767, 945 .step = 1, 946}; 947 948static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = { 949 .ops = &go7007_ctrl_ops, 950 .id = V4L2_CID_PIXEL_THRESHOLD2, 951 .name = "Pixel Threshold Region 2", 952 .type = V4L2_CTRL_TYPE_INTEGER, 953 .def = 20, 954 .max = 32767, 955 .step = 1, 956}; 957 958static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = { 959 .ops = &go7007_ctrl_ops, 960 .id = V4L2_CID_MOTION_THRESHOLD2, 961 .name = "Motion Threshold Region 2", 962 .type = V4L2_CTRL_TYPE_INTEGER, 963 .def = 80, 964 .max = 32767, 965 .step = 1, 966}; 967 968static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = { 969 .ops = &go7007_ctrl_ops, 970 .id = V4L2_CID_MB_THRESHOLD2, 971 .name = "MB Threshold Region 2", 972 .type = V4L2_CTRL_TYPE_INTEGER, 973 .def = 200, 974 .max = 32767, 975 .step = 1, 976}; 977 978static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = { 979 .ops = &go7007_ctrl_ops, 980 .id = V4L2_CID_PIXEL_THRESHOLD3, 981 .name = "Pixel Threshold Region 3", 982 .type = V4L2_CTRL_TYPE_INTEGER, 983 .def = 20, 984 .max = 32767, 985 .step = 1, 986}; 987 988static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = { 989 .ops = &go7007_ctrl_ops, 990 .id = V4L2_CID_MOTION_THRESHOLD3, 991 .name = "Motion Threshold Region 3", 992 .type = V4L2_CTRL_TYPE_INTEGER, 993 .def = 80, 994 .max = 32767, 995 .step = 1, 996}; 997 998static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = { 999 .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 1008static 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 1016int 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 1074int 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 /* Setup correct crystal frequency on this board */ 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 1150void go7007_v4l2_remove(struct go7007 *go) 1151{ 1152 v4l2_ctrl_handler_free(&go->hdl); 1153}