1/* 2 * Copyright (C) 2005-2006 Micronas USA Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License (Version 2) as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 */ 17 18#include <linux/module.h> 19#include <linux/init.h> 20#include <linux/version.h> 21#include <linux/delay.h> 22#include <linux/sched.h> 23#include <linux/spinlock.h> 24#include <linux/slab.h> 25#include <linux/fs.h> 26#include <linux/unistd.h> 27#include <linux/time.h> 28#include <linux/vmalloc.h> 29#include <linux/pagemap.h> 30#include <linux/videodev2.h> 31#include <media/v4l2-common.h> 32#include <media/v4l2-ioctl.h> 33#include <media/v4l2-subdev.h> 34#include <linux/i2c.h> 35#include <linux/mutex.h> 36#include <linux/uaccess.h> 37#include <asm/system.h> 38 39#include "go7007.h" 40#include "go7007-priv.h" 41#include "wis-i2c.h" 42 43/* Temporary defines until accepted in v4l-dvb */ 44#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 45#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */ 46#endif 47#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4 48#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 49#endif 50 51#define call_all(dev, o, f, args...) \ 52 v4l2_device_call_until_err(dev, 0, o, f, ##args) 53 54static void deactivate_buffer(struct go7007_buffer *gobuf) 55{ 56 int i; 57 58 if (gobuf->state != BUF_STATE_IDLE) { 59 list_del(&gobuf->stream); 60 gobuf->state = BUF_STATE_IDLE; 61 } 62 if (gobuf->page_count > 0) { 63 for (i = 0; i < gobuf->page_count; ++i) 64 page_cache_release(gobuf->pages[i]); 65 gobuf->page_count = 0; 66 } 67} 68 69static void abort_queued(struct go7007 *go) 70{ 71 struct go7007_buffer *gobuf, *next; 72 73 list_for_each_entry_safe(gobuf, next, &go->stream, stream) { 74 deactivate_buffer(gobuf); 75 } 76} 77 78static int go7007_streamoff(struct go7007 *go) 79{ 80 int retval = -EINVAL; 81 unsigned long flags; 82 83 mutex_lock(&go->hw_lock); 84 if (go->streaming) { 85 go->streaming = 0; 86 go7007_stream_stop(go); 87 spin_lock_irqsave(&go->spinlock, flags); 88 abort_queued(go); 89 spin_unlock_irqrestore(&go->spinlock, flags); 90 go7007_reset_encoder(go); 91 retval = 0; 92 } 93 mutex_unlock(&go->hw_lock); 94 return 0; 95} 96 97static int go7007_open(struct file *file) 98{ 99 struct go7007 *go = video_get_drvdata(video_devdata(file)); 100 struct go7007_file *gofh; 101 102 if (go->status != STATUS_ONLINE) 103 return -EBUSY; 104 gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL); 105 if (gofh == NULL) 106 return -ENOMEM; 107 ++go->ref_count; 108 gofh->go = go; 109 mutex_init(&gofh->lock); 110 gofh->buf_count = 0; 111 file->private_data = gofh; 112 return 0; 113} 114 115static int go7007_release(struct file *file) 116{ 117 struct go7007_file *gofh = file->private_data; 118 struct go7007 *go = gofh->go; 119 120 if (gofh->buf_count > 0) { 121 go7007_streamoff(go); 122 go->in_use = 0; 123 kfree(gofh->bufs); 124 gofh->buf_count = 0; 125 } 126 kfree(gofh); 127 if (--go->ref_count == 0) 128 kfree(go); 129 file->private_data = NULL; 130 return 0; 131} 132 133static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format) 134{ 135 u8 *f = page_address(gobuf->pages[0]); 136 137 switch (format) { 138 case GO7007_FORMAT_MJPEG: 139 return V4L2_BUF_FLAG_KEYFRAME; 140 case GO7007_FORMAT_MPEG4: 141 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) { 142 case 0: 143 return V4L2_BUF_FLAG_KEYFRAME; 144 case 1: 145 return V4L2_BUF_FLAG_PFRAME; 146 case 2: 147 return V4L2_BUF_FLAG_BFRAME; 148 default: 149 return 0; 150 } 151 case GO7007_FORMAT_MPEG1: 152 case GO7007_FORMAT_MPEG2: 153 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) { 154 case 1: 155 return V4L2_BUF_FLAG_KEYFRAME; 156 case 2: 157 return V4L2_BUF_FLAG_PFRAME; 158 case 3: 159 return V4L2_BUF_FLAG_BFRAME; 160 default: 161 return 0; 162 } 163 } 164 165 return 0; 166} 167 168static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) 169{ 170 int sensor_height = 0, sensor_width = 0; 171 int width, height, i; 172 173 if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && 174 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG && 175 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4) 176 return -EINVAL; 177 178 switch (go->standard) { 179 case GO7007_STD_NTSC: 180 sensor_width = 720; 181 sensor_height = 480; 182 break; 183 case GO7007_STD_PAL: 184 sensor_width = 720; 185 sensor_height = 576; 186 break; 187 case GO7007_STD_OTHER: 188 sensor_width = go->board_info->sensor_width; 189 sensor_height = go->board_info->sensor_height; 190 break; 191 } 192 193 if (fmt == NULL) { 194 width = sensor_width; 195 height = sensor_height; 196 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { 197 if (fmt->fmt.pix.width > sensor_width) 198 width = sensor_width; 199 else if (fmt->fmt.pix.width < 144) 200 width = 144; 201 else 202 width = fmt->fmt.pix.width & ~0x0f; 203 204 if (fmt->fmt.pix.height > sensor_height) 205 height = sensor_height; 206 else if (fmt->fmt.pix.height < 96) 207 height = 96; 208 else 209 height = fmt->fmt.pix.height & ~0x0f; 210 } else { 211 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height; 212 int sensor_size = sensor_width * sensor_height; 213 214 if (64 * requested_size < 9 * sensor_size) { 215 width = sensor_width / 4; 216 height = sensor_height / 4; 217 } else if (64 * requested_size < 36 * sensor_size) { 218 width = sensor_width / 2; 219 height = sensor_height / 2; 220 } else { 221 width = sensor_width; 222 height = sensor_height; 223 } 224 width &= ~0xf; 225 height &= ~0xf; 226 } 227 228 if (fmt != NULL) { 229 u32 pixelformat = fmt->fmt.pix.pixelformat; 230 231 memset(fmt, 0, sizeof(*fmt)); 232 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 233 fmt->fmt.pix.width = width; 234 fmt->fmt.pix.height = height; 235 fmt->fmt.pix.pixelformat = pixelformat; 236 fmt->fmt.pix.field = V4L2_FIELD_NONE; 237 fmt->fmt.pix.bytesperline = 0; 238 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; 239 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */ 240 } 241 242 if (try) 243 return 0; 244 245 go->width = width; 246 go->height = height; 247 go->encoder_h_offset = go->board_info->sensor_h_offset; 248 go->encoder_v_offset = go->board_info->sensor_v_offset; 249 for (i = 0; i < 4; ++i) 250 go->modet[i].enable = 0; 251 for (i = 0; i < 1624; ++i) 252 go->modet_map[i] = 0; 253 254 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { 255 struct v4l2_mbus_framefmt mbus_fmt; 256 257 mbus_fmt.code = V4L2_MBUS_FMT_FIXED; 258 if (fmt != NULL) 259 mbus_fmt.width = fmt->fmt.pix.width; 260 else 261 mbus_fmt.width = width; 262 263 if (height > sensor_height / 2) { 264 mbus_fmt.height = height / 2; 265 go->encoder_v_halve = 0; 266 } else { 267 mbus_fmt.height = height; 268 go->encoder_v_halve = 1; 269 } 270 call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt); 271 } else { 272 if (width <= sensor_width / 4) { 273 go->encoder_h_halve = 1; 274 go->encoder_v_halve = 1; 275 go->encoder_subsample = 1; 276 } else if (width <= sensor_width / 2) { 277 go->encoder_h_halve = 1; 278 go->encoder_v_halve = 1; 279 go->encoder_subsample = 0; 280 } else { 281 go->encoder_h_halve = 0; 282 go->encoder_v_halve = 0; 283 go->encoder_subsample = 0; 284 } 285 } 286 287 if (fmt == NULL) 288 return 0; 289 290 switch (fmt->fmt.pix.pixelformat) { 291 case V4L2_PIX_FMT_MPEG: 292 if (go->format == GO7007_FORMAT_MPEG1 || 293 go->format == GO7007_FORMAT_MPEG2 || 294 go->format == GO7007_FORMAT_MPEG4) 295 break; 296 go->format = GO7007_FORMAT_MPEG1; 297 go->pali = 0; 298 go->aspect_ratio = GO7007_RATIO_1_1; 299 go->gop_size = go->sensor_framerate / 1000; 300 go->ipb = 0; 301 go->closed_gop = 1; 302 go->repeat_seqhead = 1; 303 go->seq_header_enable = 1; 304 go->gop_header_enable = 1; 305 go->dvd_mode = 0; 306 break; 307 /* Backwards compatibility only! */ 308 case V4L2_PIX_FMT_MPEG4: 309 if (go->format == GO7007_FORMAT_MPEG4) 310 break; 311 go->format = GO7007_FORMAT_MPEG4; 312 go->pali = 0xf5; 313 go->aspect_ratio = GO7007_RATIO_1_1; 314 go->gop_size = go->sensor_framerate / 1000; 315 go->ipb = 0; 316 go->closed_gop = 1; 317 go->repeat_seqhead = 1; 318 go->seq_header_enable = 1; 319 go->gop_header_enable = 1; 320 go->dvd_mode = 0; 321 break; 322 case V4L2_PIX_FMT_MJPEG: 323 go->format = GO7007_FORMAT_MJPEG; 324 go->pali = 0; 325 go->aspect_ratio = GO7007_RATIO_1_1; 326 go->gop_size = 0; 327 go->ipb = 0; 328 go->closed_gop = 0; 329 go->repeat_seqhead = 0; 330 go->seq_header_enable = 0; 331 go->gop_header_enable = 0; 332 go->dvd_mode = 0; 333 break; 334 } 335 return 0; 336} 337 338#if 0 339static int clip_to_modet_map(struct go7007 *go, int region, 340 struct v4l2_clip *clip_list) 341{ 342 struct v4l2_clip clip, *clip_ptr; 343 int x, y, mbnum; 344 345 /* Check if coordinates are OK and if any macroblocks are already 346 * used by other regions (besides 0) */ 347 clip_ptr = clip_list; 348 while (clip_ptr) { 349 if (copy_from_user(&clip, clip_ptr, sizeof(clip))) 350 return -EFAULT; 351 if (clip.c.left < 0 || (clip.c.left & 0xF) || 352 clip.c.width <= 0 || (clip.c.width & 0xF)) 353 return -EINVAL; 354 if (clip.c.left + clip.c.width > go->width) 355 return -EINVAL; 356 if (clip.c.top < 0 || (clip.c.top & 0xF) || 357 clip.c.height <= 0 || (clip.c.height & 0xF)) 358 return -EINVAL; 359 if (clip.c.top + clip.c.height > go->height) 360 return -EINVAL; 361 for (y = 0; y < clip.c.height; y += 16) 362 for (x = 0; x < clip.c.width; x += 16) { 363 mbnum = (go->width >> 4) * 364 ((clip.c.top + y) >> 4) + 365 ((clip.c.left + x) >> 4); 366 if (go->modet_map[mbnum] != 0 && 367 go->modet_map[mbnum] != region) 368 return -EBUSY; 369 } 370 clip_ptr = clip.next; 371 } 372 373 /* Clear old region macroblocks */ 374 for (mbnum = 0; mbnum < 1624; ++mbnum) 375 if (go->modet_map[mbnum] == region) 376 go->modet_map[mbnum] = 0; 377 378 /* Claim macroblocks in this list */ 379 clip_ptr = clip_list; 380 while (clip_ptr) { 381 if (copy_from_user(&clip, clip_ptr, sizeof(clip))) 382 return -EFAULT; 383 for (y = 0; y < clip.c.height; y += 16) 384 for (x = 0; x < clip.c.width; x += 16) { 385 mbnum = (go->width >> 4) * 386 ((clip.c.top + y) >> 4) + 387 ((clip.c.left + x) >> 4); 388 go->modet_map[mbnum] = region; 389 } 390 clip_ptr = clip.next; 391 } 392 return 0; 393} 394#endif 395 396static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl) 397{ 398 static const u32 mpeg_ctrls[] = { 399 V4L2_CID_MPEG_CLASS, 400 V4L2_CID_MPEG_STREAM_TYPE, 401 V4L2_CID_MPEG_VIDEO_ENCODING, 402 V4L2_CID_MPEG_VIDEO_ASPECT, 403 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 404 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 405 V4L2_CID_MPEG_VIDEO_BITRATE, 406 0 407 }; 408 static const u32 *ctrl_classes[] = { 409 mpeg_ctrls, 410 NULL 411 }; 412 413 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id); 414 415 switch (ctrl->id) { 416 case V4L2_CID_MPEG_CLASS: 417 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0); 418 case V4L2_CID_MPEG_STREAM_TYPE: 419 return v4l2_ctrl_query_fill(ctrl, 420 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, 421 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1, 422 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM); 423 case V4L2_CID_MPEG_VIDEO_ENCODING: 424 return v4l2_ctrl_query_fill(ctrl, 425 V4L2_MPEG_VIDEO_ENCODING_MPEG_1, 426 V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1, 427 V4L2_MPEG_VIDEO_ENCODING_MPEG_2); 428 case V4L2_CID_MPEG_VIDEO_ASPECT: 429 return v4l2_ctrl_query_fill(ctrl, 430 V4L2_MPEG_VIDEO_ASPECT_1x1, 431 V4L2_MPEG_VIDEO_ASPECT_16x9, 1, 432 V4L2_MPEG_VIDEO_ASPECT_1x1); 433 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 434 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15); 435 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 436 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0); 437 case V4L2_CID_MPEG_VIDEO_BITRATE: 438 return v4l2_ctrl_query_fill(ctrl, 439 64000, 440 10000000, 1, 441 1500000); 442 default: 443 return -EINVAL; 444 } 445 return 0; 446} 447 448static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go) 449{ 450 /* pretty sure we can't change any of these while streaming */ 451 if (go->streaming) 452 return -EBUSY; 453 454 switch (ctrl->id) { 455 case V4L2_CID_MPEG_STREAM_TYPE: 456 switch (ctrl->value) { 457 case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD: 458 go->format = GO7007_FORMAT_MPEG2; 459 go->bitrate = 9800000; 460 go->gop_size = 15; 461 go->pali = 0x48; 462 go->closed_gop = 1; 463 go->repeat_seqhead = 0; 464 go->seq_header_enable = 1; 465 go->gop_header_enable = 1; 466 go->dvd_mode = 1; 467 break; 468 case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM: 469 /* todo: */ 470 break; 471 default: 472 return -EINVAL; 473 } 474 break; 475 case V4L2_CID_MPEG_VIDEO_ENCODING: 476 switch (ctrl->value) { 477 case V4L2_MPEG_VIDEO_ENCODING_MPEG_1: 478 go->format = GO7007_FORMAT_MPEG1; 479 go->pali = 0; 480 break; 481 case V4L2_MPEG_VIDEO_ENCODING_MPEG_2: 482 go->format = GO7007_FORMAT_MPEG2; 483 /*if (mpeg->pali >> 24 == 2) 484 go->pali = mpeg->pali & 0xff; 485 else*/ 486 go->pali = 0x48; 487 break; 488 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4: 489 go->format = GO7007_FORMAT_MPEG4; 490 /*if (mpeg->pali >> 24 == 4) 491 go->pali = mpeg->pali & 0xff; 492 else*/ 493 go->pali = 0xf5; 494 break; 495 default: 496 return -EINVAL; 497 } 498 go->gop_header_enable = 499 /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER 500 ? 0 :*/ 1; 501 /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER) 502 go->repeat_seqhead = 1; 503 else*/ 504 go->repeat_seqhead = 0; 505 go->dvd_mode = 0; 506 break; 507 case V4L2_CID_MPEG_VIDEO_ASPECT: 508 if (go->format == GO7007_FORMAT_MJPEG) 509 return -EINVAL; 510 switch (ctrl->value) { 511 case V4L2_MPEG_VIDEO_ASPECT_1x1: 512 go->aspect_ratio = GO7007_RATIO_1_1; 513 break; 514 case V4L2_MPEG_VIDEO_ASPECT_4x3: 515 go->aspect_ratio = GO7007_RATIO_4_3; 516 break; 517 case V4L2_MPEG_VIDEO_ASPECT_16x9: 518 go->aspect_ratio = GO7007_RATIO_16_9; 519 break; 520 case V4L2_MPEG_VIDEO_ASPECT_221x100: 521 default: 522 return -EINVAL; 523 } 524 break; 525 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 526 if (ctrl->value < 0 || ctrl->value > 34) 527 return -EINVAL; 528 go->gop_size = ctrl->value; 529 break; 530 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 531 if (ctrl->value != 0 && ctrl->value != 1) 532 return -EINVAL; 533 go->closed_gop = ctrl->value; 534 break; 535 case V4L2_CID_MPEG_VIDEO_BITRATE: 536 /* Upper bound is kind of arbitrary here */ 537 if (ctrl->value < 64000 || ctrl->value > 10000000) 538 return -EINVAL; 539 go->bitrate = ctrl->value; 540 break; 541 default: 542 return -EINVAL; 543 } 544 return 0; 545} 546 547static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go) 548{ 549 switch (ctrl->id) { 550 case V4L2_CID_MPEG_STREAM_TYPE: 551 if (go->dvd_mode) 552 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; 553 else 554 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM; 555 break; 556 case V4L2_CID_MPEG_VIDEO_ENCODING: 557 switch (go->format) { 558 case GO7007_FORMAT_MPEG1: 559 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 560 break; 561 case GO7007_FORMAT_MPEG2: 562 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; 563 break; 564 case GO7007_FORMAT_MPEG4: 565 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4; 566 break; 567 default: 568 return -EINVAL; 569 } 570 break; 571 case V4L2_CID_MPEG_VIDEO_ASPECT: 572 switch (go->aspect_ratio) { 573 case GO7007_RATIO_1_1: 574 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1; 575 break; 576 case GO7007_RATIO_4_3: 577 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3; 578 break; 579 case GO7007_RATIO_16_9: 580 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9; 581 break; 582 default: 583 return -EINVAL; 584 } 585 break; 586 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 587 ctrl->value = go->gop_size; 588 break; 589 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 590 ctrl->value = go->closed_gop; 591 break; 592 case V4L2_CID_MPEG_VIDEO_BITRATE: 593 ctrl->value = go->bitrate; 594 break; 595 default: 596 return -EINVAL; 597 } 598 return 0; 599} 600 601static int vidioc_querycap(struct file *file, void *priv, 602 struct v4l2_capability *cap) 603{ 604 struct go7007 *go = ((struct go7007_file *) priv)->go; 605 606 strlcpy(cap->driver, "go7007", sizeof(cap->driver)); 607 strlcpy(cap->card, go->name, sizeof(cap->card)); 608#if 0 609 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); 610#endif 611 612 cap->version = KERNEL_VERSION(0, 9, 8); 613 614 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 615 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */ 616 617 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER) 618 cap->capabilities |= V4L2_CAP_TUNER; 619 620 return 0; 621} 622 623static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 624 struct v4l2_fmtdesc *fmt) 625{ 626 char *desc = NULL; 627 628 switch (fmt->index) { 629 case 0: 630 fmt->pixelformat = V4L2_PIX_FMT_MJPEG; 631 desc = "Motion-JPEG"; 632 break; 633 case 1: 634 fmt->pixelformat = V4L2_PIX_FMT_MPEG; 635 desc = "MPEG1/MPEG2/MPEG4"; 636 break; 637 default: 638 return -EINVAL; 639 } 640 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 641 fmt->flags = V4L2_FMT_FLAG_COMPRESSED; 642 643 strncpy(fmt->description, desc, sizeof(fmt->description)); 644 645 return 0; 646} 647 648static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 649 struct v4l2_format *fmt) 650{ 651 struct go7007 *go = ((struct go7007_file *) priv)->go; 652 653 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 654 fmt->fmt.pix.width = go->width; 655 fmt->fmt.pix.height = go->height; 656 fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ? 657 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG; 658 fmt->fmt.pix.field = V4L2_FIELD_NONE; 659 fmt->fmt.pix.bytesperline = 0; 660 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; 661 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 662 663 return 0; 664} 665 666static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 667 struct v4l2_format *fmt) 668{ 669 struct go7007 *go = ((struct go7007_file *) priv)->go; 670 671 return set_capture_size(go, fmt, 1); 672} 673 674static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 675 struct v4l2_format *fmt) 676{ 677 struct go7007 *go = ((struct go7007_file *) priv)->go; 678 679 if (go->streaming) 680 return -EBUSY; 681 682 return set_capture_size(go, fmt, 0); 683} 684 685static int vidioc_reqbufs(struct file *file, void *priv, 686 struct v4l2_requestbuffers *req) 687{ 688 struct go7007_file *gofh = priv; 689 struct go7007 *go = gofh->go; 690 int retval = -EBUSY; 691 unsigned int count, i; 692 693 if (go->streaming) 694 return retval; 695 696 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 697 req->memory != V4L2_MEMORY_MMAP) 698 return -EINVAL; 699 700 mutex_lock(&gofh->lock); 701 for (i = 0; i < gofh->buf_count; ++i) 702 if (gofh->bufs[i].mapped > 0) 703 goto unlock_and_return; 704 705 mutex_lock(&go->hw_lock); 706 if (go->in_use > 0 && gofh->buf_count == 0) { 707 mutex_unlock(&go->hw_lock); 708 goto unlock_and_return; 709 } 710 711 if (gofh->buf_count > 0) 712 kfree(gofh->bufs); 713 714 retval = -ENOMEM; 715 count = req->count; 716 if (count > 0) { 717 if (count < 2) 718 count = 2; 719 if (count > 32) 720 count = 32; 721 722 gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer), 723 GFP_KERNEL); 724 725 if (!gofh->bufs) { 726 mutex_unlock(&go->hw_lock); 727 goto unlock_and_return; 728 } 729 730 for (i = 0; i < count; ++i) { 731 gofh->bufs[i].go = go; 732 gofh->bufs[i].index = i; 733 gofh->bufs[i].state = BUF_STATE_IDLE; 734 gofh->bufs[i].mapped = 0; 735 } 736 737 go->in_use = 1; 738 } else { 739 go->in_use = 0; 740 } 741 742 gofh->buf_count = count; 743 mutex_unlock(&go->hw_lock); 744 mutex_unlock(&gofh->lock); 745 746 memset(req, 0, sizeof(*req)); 747 748 req->count = count; 749 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 750 req->memory = V4L2_MEMORY_MMAP; 751 752 return 0; 753 754unlock_and_return: 755 mutex_unlock(&gofh->lock); 756 return retval; 757} 758 759static int vidioc_querybuf(struct file *file, void *priv, 760 struct v4l2_buffer *buf) 761{ 762 struct go7007_file *gofh = priv; 763 int retval = -EINVAL; 764 unsigned int index; 765 766 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 767 return retval; 768 769 index = buf->index; 770 771 mutex_lock(&gofh->lock); 772 if (index >= gofh->buf_count) 773 goto unlock_and_return; 774 775 memset(buf, 0, sizeof(*buf)); 776 buf->index = index; 777 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 778 779 switch (gofh->bufs[index].state) { 780 case BUF_STATE_QUEUED: 781 buf->flags = V4L2_BUF_FLAG_QUEUED; 782 break; 783 case BUF_STATE_DONE: 784 buf->flags = V4L2_BUF_FLAG_DONE; 785 break; 786 default: 787 buf->flags = 0; 788 } 789 790 if (gofh->bufs[index].mapped) 791 buf->flags |= V4L2_BUF_FLAG_MAPPED; 792 buf->memory = V4L2_MEMORY_MMAP; 793 buf->m.offset = index * GO7007_BUF_SIZE; 794 buf->length = GO7007_BUF_SIZE; 795 mutex_unlock(&gofh->lock); 796 797 return 0; 798 799unlock_and_return: 800 mutex_unlock(&gofh->lock); 801 return retval; 802} 803 804static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 805{ 806 struct go7007_file *gofh = priv; 807 struct go7007 *go = gofh->go; 808 struct go7007_buffer *gobuf; 809 unsigned long flags; 810 int retval = -EINVAL; 811 int ret; 812 813 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 814 buf->memory != V4L2_MEMORY_MMAP) 815 return retval; 816 817 mutex_lock(&gofh->lock); 818 if (buf->index < 0 || buf->index >= gofh->buf_count) 819 goto unlock_and_return; 820 821 gobuf = &gofh->bufs[buf->index]; 822 if (!gobuf->mapped) 823 goto unlock_and_return; 824 825 retval = -EBUSY; 826 if (gobuf->state != BUF_STATE_IDLE) 827 goto unlock_and_return; 828 829 /* offset will be 0 until we really support USERPTR streaming */ 830 gobuf->offset = gobuf->user_addr & ~PAGE_MASK; 831 gobuf->bytesused = 0; 832 gobuf->frame_offset = 0; 833 gobuf->modet_active = 0; 834 if (gobuf->offset > 0) 835 gobuf->page_count = GO7007_BUF_PAGES + 1; 836 else 837 gobuf->page_count = GO7007_BUF_PAGES; 838 839 retval = -ENOMEM; 840 down_read(¤t->mm->mmap_sem); 841 ret = get_user_pages(current, current->mm, 842 gobuf->user_addr & PAGE_MASK, gobuf->page_count, 843 1, 1, gobuf->pages, NULL); 844 up_read(¤t->mm->mmap_sem); 845 846 if (ret != gobuf->page_count) { 847 int i; 848 for (i = 0; i < ret; ++i) 849 page_cache_release(gobuf->pages[i]); 850 gobuf->page_count = 0; 851 goto unlock_and_return; 852 } 853 854 gobuf->state = BUF_STATE_QUEUED; 855 spin_lock_irqsave(&go->spinlock, flags); 856 list_add_tail(&gobuf->stream, &go->stream); 857 spin_unlock_irqrestore(&go->spinlock, flags); 858 mutex_unlock(&gofh->lock); 859 860 return 0; 861 862unlock_and_return: 863 mutex_unlock(&gofh->lock); 864 return retval; 865} 866 867 868static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 869{ 870 struct go7007_file *gofh = priv; 871 struct go7007 *go = gofh->go; 872 struct go7007_buffer *gobuf; 873 int retval = -EINVAL; 874 unsigned long flags; 875 u32 frame_type_flag; 876 DEFINE_WAIT(wait); 877 878 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 879 return retval; 880 if (buf->memory != V4L2_MEMORY_MMAP) 881 return retval; 882 883 mutex_lock(&gofh->lock); 884 if (list_empty(&go->stream)) 885 goto unlock_and_return; 886 gobuf = list_entry(go->stream.next, 887 struct go7007_buffer, stream); 888 889 retval = -EAGAIN; 890 if (gobuf->state != BUF_STATE_DONE && 891 !(file->f_flags & O_NONBLOCK)) { 892 for (;;) { 893 prepare_to_wait(&go->frame_waitq, &wait, 894 TASK_INTERRUPTIBLE); 895 if (gobuf->state == BUF_STATE_DONE) 896 break; 897 if (signal_pending(current)) { 898 retval = -ERESTARTSYS; 899 break; 900 } 901 schedule(); 902 } 903 finish_wait(&go->frame_waitq, &wait); 904 } 905 if (gobuf->state != BUF_STATE_DONE) 906 goto unlock_and_return; 907 908 spin_lock_irqsave(&go->spinlock, flags); 909 deactivate_buffer(gobuf); 910 spin_unlock_irqrestore(&go->spinlock, flags); 911 frame_type_flag = get_frame_type_flag(gobuf, go->format); 912 gobuf->state = BUF_STATE_IDLE; 913 914 memset(buf, 0, sizeof(*buf)); 915 buf->index = gobuf->index; 916 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 917 buf->bytesused = gobuf->bytesused; 918 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag; 919 buf->field = V4L2_FIELD_NONE; 920 buf->timestamp = gobuf->timestamp; 921 buf->sequence = gobuf->seq; 922 buf->memory = V4L2_MEMORY_MMAP; 923 buf->m.offset = gobuf->index * GO7007_BUF_SIZE; 924 buf->length = GO7007_BUF_SIZE; 925 buf->reserved = gobuf->modet_active; 926 927 mutex_unlock(&gofh->lock); 928 return 0; 929 930unlock_and_return: 931 mutex_unlock(&gofh->lock); 932 return retval; 933} 934 935static int vidioc_streamon(struct file *file, void *priv, 936 enum v4l2_buf_type type) 937{ 938 struct go7007_file *gofh = priv; 939 struct go7007 *go = gofh->go; 940 int retval = 0; 941 942 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 943 return -EINVAL; 944 945 mutex_lock(&gofh->lock); 946 mutex_lock(&go->hw_lock); 947 948 if (!go->streaming) { 949 go->streaming = 1; 950 go->next_seq = 0; 951 go->active_buf = NULL; 952 if (go7007_start_encoder(go) < 0) 953 retval = -EIO; 954 else 955 retval = 0; 956 } 957 mutex_unlock(&go->hw_lock); 958 mutex_unlock(&gofh->lock); 959 960 return retval; 961} 962 963static int vidioc_streamoff(struct file *file, void *priv, 964 enum v4l2_buf_type type) 965{ 966 struct go7007_file *gofh = priv; 967 struct go7007 *go = gofh->go; 968 969 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 970 return -EINVAL; 971 mutex_lock(&gofh->lock); 972 go7007_streamoff(go); 973 mutex_unlock(&gofh->lock); 974 975 return 0; 976} 977 978static int vidioc_queryctrl(struct file *file, void *priv, 979 struct v4l2_queryctrl *query) 980{ 981 struct go7007 *go = ((struct go7007_file *) priv)->go; 982 int id = query->id; 983 984 if (0 == call_all(&go->v4l2_dev, core, queryctrl, query)) 985 return 0; 986 987 query->id = id; 988 return mpeg_query_ctrl(query); 989} 990 991static int vidioc_g_ctrl(struct file *file, void *priv, 992 struct v4l2_control *ctrl) 993{ 994 struct go7007 *go = ((struct go7007_file *) priv)->go; 995 996 if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl)) 997 return 0; 998 999 return mpeg_g_ctrl(ctrl, go); 1000} 1001 1002static int vidioc_s_ctrl(struct file *file, void *priv, 1003 struct v4l2_control *ctrl) 1004{ 1005 struct go7007 *go = ((struct go7007_file *) priv)->go; 1006 1007 if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl)) 1008 return 0; 1009 1010 return mpeg_s_ctrl(ctrl, go); 1011} 1012 1013static int vidioc_g_parm(struct file *filp, void *priv, 1014 struct v4l2_streamparm *parm) 1015{ 1016 struct go7007 *go = ((struct go7007_file *) priv)->go; 1017 struct v4l2_fract timeperframe = { 1018 .numerator = 1001 * go->fps_scale, 1019 .denominator = go->sensor_framerate, 1020 }; 1021 1022 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1023 return -EINVAL; 1024 1025 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; 1026 parm->parm.capture.timeperframe = timeperframe; 1027 1028 return 0; 1029} 1030 1031static int vidioc_s_parm(struct file *filp, void *priv, 1032 struct v4l2_streamparm *parm) 1033{ 1034 struct go7007 *go = ((struct go7007_file *) priv)->go; 1035 unsigned int n, d; 1036 1037 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1038 return -EINVAL; 1039 if (parm->parm.capture.capturemode != 0) 1040 return -EINVAL; 1041 1042 n = go->sensor_framerate * 1043 parm->parm.capture.timeperframe.numerator; 1044 d = 1001 * parm->parm.capture.timeperframe.denominator; 1045 if (n != 0 && d != 0 && n > d) 1046 go->fps_scale = (n + d/2) / d; 1047 else 1048 go->fps_scale = 1; 1049 1050 return 0; 1051} 1052 1053/* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and 1054 its resolution, when the device is not connected to TV. 1055 This were an API abuse, probably used by the lack of specific IOCTL's to 1056 enumberate it, by the time the driver were written. 1057 1058 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS 1059 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose. 1060 1061 The two functions bellow implements the newer ioctls 1062*/ 1063static int vidioc_enum_framesizes(struct file *filp, void *priv, 1064 struct v4l2_frmsizeenum *fsize) 1065{ 1066 struct go7007 *go = ((struct go7007_file *) priv)->go; 1067 1068 /* Return -EINVAL, if it is a TV board */ 1069 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1070 (go->board_info->sensor_flags & GO7007_SENSOR_TV)) 1071 return -EINVAL; 1072 1073 if (fsize->index > 0) 1074 return -EINVAL; 1075 1076 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 1077 fsize->discrete.width = go->board_info->sensor_width; 1078 fsize->discrete.height = go->board_info->sensor_height; 1079 1080 return 0; 1081} 1082 1083static int vidioc_enum_frameintervals(struct file *filp, void *priv, 1084 struct v4l2_frmivalenum *fival) 1085{ 1086 struct go7007 *go = ((struct go7007_file *) priv)->go; 1087 1088 /* Return -EINVAL, if it is a TV board */ 1089 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1090 (go->board_info->sensor_flags & GO7007_SENSOR_TV)) 1091 return -EINVAL; 1092 1093 if (fival->index > 0) 1094 return -EINVAL; 1095 1096 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 1097 fival->discrete.numerator = 1001; 1098 fival->discrete.denominator = go->board_info->sensor_framerate; 1099 1100 return 0; 1101} 1102 1103static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std) 1104{ 1105 struct go7007 *go = ((struct go7007_file *) priv)->go; 1106 1107 switch (go->standard) { 1108 case GO7007_STD_NTSC: 1109 *std = V4L2_STD_NTSC; 1110 break; 1111 case GO7007_STD_PAL: 1112 *std = V4L2_STD_PAL; 1113 break; 1114 default: 1115 return -EINVAL; 1116 } 1117 1118 return 0; 1119} 1120 1121static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) 1122{ 1123 struct go7007 *go = ((struct go7007_file *) priv)->go; 1124 1125 if (go->streaming) 1126 return -EBUSY; 1127 1128 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0) 1129 return -EINVAL; 1130 1131 if (*std == 0) 1132 return -EINVAL; 1133 1134 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1135 go->input == go->board_info->num_inputs - 1) { 1136 if (!go->i2c_adapter_online) 1137 return -EIO; 1138 if (call_all(&go->v4l2_dev, core, s_std, *std) < 0) 1139 return -EINVAL; 1140 } 1141 1142 if (*std & V4L2_STD_NTSC) { 1143 go->standard = GO7007_STD_NTSC; 1144 go->sensor_framerate = 30000; 1145 } else if (*std & V4L2_STD_PAL) { 1146 go->standard = GO7007_STD_PAL; 1147 go->sensor_framerate = 25025; 1148 } else if (*std & V4L2_STD_SECAM) { 1149 go->standard = GO7007_STD_PAL; 1150 go->sensor_framerate = 25025; 1151 } else 1152 return -EINVAL; 1153 1154 call_all(&go->v4l2_dev, core, s_std, *std); 1155 set_capture_size(go, NULL, 0); 1156 1157 return 0; 1158} 1159 1160static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std) 1161{ 1162 struct go7007 *go = ((struct go7007_file *) priv)->go; 1163 1164 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1165 go->input == go->board_info->num_inputs - 1) { 1166 if (!go->i2c_adapter_online) 1167 return -EIO; 1168 return call_all(&go->v4l2_dev, video, querystd, std); 1169 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1170 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 1171 else 1172 *std = 0; 1173 1174 return 0; 1175} 1176 1177static int vidioc_enum_input(struct file *file, void *priv, 1178 struct v4l2_input *inp) 1179{ 1180 struct go7007 *go = ((struct go7007_file *) priv)->go; 1181 1182 if (inp->index >= go->board_info->num_inputs) 1183 return -EINVAL; 1184 1185 strncpy(inp->name, go->board_info->inputs[inp->index].name, 1186 sizeof(inp->name)); 1187 1188 /* If this board has a tuner, it will be the last input */ 1189 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1190 inp->index == go->board_info->num_inputs - 1) 1191 inp->type = V4L2_INPUT_TYPE_TUNER; 1192 else 1193 inp->type = V4L2_INPUT_TYPE_CAMERA; 1194 1195 inp->audioset = 0; 1196 inp->tuner = 0; 1197 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1198 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | 1199 V4L2_STD_SECAM; 1200 else 1201 inp->std = 0; 1202 1203 return 0; 1204} 1205 1206 1207static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) 1208{ 1209 struct go7007 *go = ((struct go7007_file *) priv)->go; 1210 1211 *input = go->input; 1212 1213 return 0; 1214} 1215 1216static int vidioc_s_input(struct file *file, void *priv, unsigned int input) 1217{ 1218 struct go7007 *go = ((struct go7007_file *) priv)->go; 1219 1220 if (input >= go->board_info->num_inputs) 1221 return -EINVAL; 1222 if (go->streaming) 1223 return -EBUSY; 1224 1225 go->input = input; 1226 1227 return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0); 1228} 1229 1230static int vidioc_g_tuner(struct file *file, void *priv, 1231 struct v4l2_tuner *t) 1232{ 1233 struct go7007 *go = ((struct go7007_file *) priv)->go; 1234 1235 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1236 return -EINVAL; 1237 if (t->index != 0) 1238 return -EINVAL; 1239 if (!go->i2c_adapter_online) 1240 return -EIO; 1241 1242 return call_all(&go->v4l2_dev, tuner, g_tuner, t); 1243} 1244 1245static int vidioc_s_tuner(struct file *file, void *priv, 1246 struct v4l2_tuner *t) 1247{ 1248 struct go7007 *go = ((struct go7007_file *) priv)->go; 1249 1250 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1251 return -EINVAL; 1252 if (t->index != 0) 1253 return -EINVAL; 1254 if (!go->i2c_adapter_online) 1255 return -EIO; 1256 1257 switch (go->board_id) { 1258 case GO7007_BOARDID_PX_TV402U_NA: 1259 case GO7007_BOARDID_PX_TV402U_JP: 1260 /* No selectable options currently */ 1261 if (t->audmode != V4L2_TUNER_MODE_STEREO) 1262 return -EINVAL; 1263 break; 1264 } 1265 1266 return call_all(&go->v4l2_dev, tuner, s_tuner, t); 1267} 1268 1269static int vidioc_g_frequency(struct file *file, void *priv, 1270 struct v4l2_frequency *f) 1271{ 1272 struct go7007 *go = ((struct go7007_file *) priv)->go; 1273 1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1275 return -EINVAL; 1276 if (!go->i2c_adapter_online) 1277 return -EIO; 1278 1279 f->type = V4L2_TUNER_ANALOG_TV; 1280 1281 return call_all(&go->v4l2_dev, tuner, g_frequency, f); 1282} 1283 1284static int vidioc_s_frequency(struct file *file, void *priv, 1285 struct v4l2_frequency *f) 1286{ 1287 struct go7007 *go = ((struct go7007_file *) priv)->go; 1288 1289 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1290 return -EINVAL; 1291 if (!go->i2c_adapter_online) 1292 return -EIO; 1293 1294 return call_all(&go->v4l2_dev, tuner, s_frequency, f); 1295} 1296 1297static int vidioc_cropcap(struct file *file, void *priv, 1298 struct v4l2_cropcap *cropcap) 1299{ 1300 struct go7007 *go = ((struct go7007_file *) priv)->go; 1301 1302 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1303 return -EINVAL; 1304 1305 /* These specify the raw input of the sensor */ 1306 switch (go->standard) { 1307 case GO7007_STD_NTSC: 1308 cropcap->bounds.top = 0; 1309 cropcap->bounds.left = 0; 1310 cropcap->bounds.width = 720; 1311 cropcap->bounds.height = 480; 1312 cropcap->defrect.top = 0; 1313 cropcap->defrect.left = 0; 1314 cropcap->defrect.width = 720; 1315 cropcap->defrect.height = 480; 1316 break; 1317 case GO7007_STD_PAL: 1318 cropcap->bounds.top = 0; 1319 cropcap->bounds.left = 0; 1320 cropcap->bounds.width = 720; 1321 cropcap->bounds.height = 576; 1322 cropcap->defrect.top = 0; 1323 cropcap->defrect.left = 0; 1324 cropcap->defrect.width = 720; 1325 cropcap->defrect.height = 576; 1326 break; 1327 case GO7007_STD_OTHER: 1328 cropcap->bounds.top = 0; 1329 cropcap->bounds.left = 0; 1330 cropcap->bounds.width = go->board_info->sensor_width; 1331 cropcap->bounds.height = go->board_info->sensor_height; 1332 cropcap->defrect.top = 0; 1333 cropcap->defrect.left = 0; 1334 cropcap->defrect.width = go->board_info->sensor_width; 1335 cropcap->defrect.height = go->board_info->sensor_height; 1336 break; 1337 } 1338 1339 return 0; 1340} 1341 1342static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1343{ 1344 struct go7007 *go = ((struct go7007_file *) priv)->go; 1345 1346 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1347 return -EINVAL; 1348 1349 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1350 1351 /* These specify the raw input of the sensor */ 1352 switch (go->standard) { 1353 case GO7007_STD_NTSC: 1354 crop->c.top = 0; 1355 crop->c.left = 0; 1356 crop->c.width = 720; 1357 crop->c.height = 480; 1358 break; 1359 case GO7007_STD_PAL: 1360 crop->c.top = 0; 1361 crop->c.left = 0; 1362 crop->c.width = 720; 1363 crop->c.height = 576; 1364 break; 1365 case GO7007_STD_OTHER: 1366 crop->c.top = 0; 1367 crop->c.left = 0; 1368 crop->c.width = go->board_info->sensor_width; 1369 crop->c.height = go->board_info->sensor_height; 1370 break; 1371 } 1372 1373 return 0; 1374} 1375 1376/* FIXME: vidioc_s_crop is not really implemented!!! 1377 */ 1378static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1379{ 1380 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1381 return -EINVAL; 1382 1383 return 0; 1384} 1385 1386static int vidioc_g_jpegcomp(struct file *file, void *priv, 1387 struct v4l2_jpegcompression *params) 1388{ 1389 memset(params, 0, sizeof(*params)); 1390 params->quality = 50; /* ?? */ 1391 params->jpeg_markers = V4L2_JPEG_MARKER_DHT | 1392 V4L2_JPEG_MARKER_DQT; 1393 1394 return 0; 1395} 1396 1397static int vidioc_s_jpegcomp(struct file *file, void *priv, 1398 struct v4l2_jpegcompression *params) 1399{ 1400 if (params->quality != 50 || 1401 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT | 1402 V4L2_JPEG_MARKER_DQT)) 1403 return -EINVAL; 1404 1405 return 0; 1406} 1407 1408/* FIXME: 1409 Those ioctls are private, and not needed, since several standard 1410 extended controls already provide streaming control. 1411 So, those ioctls should be converted into vidioc_g_ext_ctrls() 1412 and vidioc_s_ext_ctrls() 1413 */ 1414 1415#if 0 1416 /* Temporary ioctls for controlling compression characteristics */ 1417 case GO7007IOC_S_BITRATE: 1418 { 1419 int *bitrate = arg; 1420 1421 if (go->streaming) 1422 return -EINVAL; 1423 /* Upper bound is kind of arbitrary here */ 1424 if (*bitrate < 64000 || *bitrate > 10000000) 1425 return -EINVAL; 1426 go->bitrate = *bitrate; 1427 return 0; 1428 } 1429 case GO7007IOC_G_BITRATE: 1430 { 1431 int *bitrate = arg; 1432 1433 *bitrate = go->bitrate; 1434 return 0; 1435 } 1436 case GO7007IOC_S_COMP_PARAMS: 1437 { 1438 struct go7007_comp_params *comp = arg; 1439 1440 if (go->format == GO7007_FORMAT_MJPEG) 1441 return -EINVAL; 1442 if (comp->gop_size > 0) 1443 go->gop_size = comp->gop_size; 1444 else 1445 go->gop_size = go->sensor_framerate / 1000; 1446 if (go->gop_size != 15) 1447 go->dvd_mode = 0; 1448 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */ 1449 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) { 1450 switch (comp->aspect_ratio) { 1451 case GO7007_ASPECT_RATIO_4_3_NTSC: 1452 case GO7007_ASPECT_RATIO_4_3_PAL: 1453 go->aspect_ratio = GO7007_RATIO_4_3; 1454 break; 1455 case GO7007_ASPECT_RATIO_16_9_NTSC: 1456 case GO7007_ASPECT_RATIO_16_9_PAL: 1457 go->aspect_ratio = GO7007_RATIO_16_9; 1458 break; 1459 default: 1460 go->aspect_ratio = GO7007_RATIO_1_1; 1461 break; 1462 } 1463 } 1464 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) { 1465 go->dvd_mode = 0; 1466 go->seq_header_enable = 0; 1467 } else { 1468 go->seq_header_enable = 1; 1469 } 1470 /* fall-through */ 1471 } 1472 case GO7007IOC_G_COMP_PARAMS: 1473 { 1474 struct go7007_comp_params *comp = arg; 1475 1476 if (go->format == GO7007_FORMAT_MJPEG) 1477 return -EINVAL; 1478 memset(comp, 0, sizeof(*comp)); 1479 comp->gop_size = go->gop_size; 1480 comp->max_b_frames = go->ipb ? 2 : 0; 1481 switch (go->aspect_ratio) { 1482 case GO7007_RATIO_4_3: 1483 if (go->standard == GO7007_STD_NTSC) 1484 comp->aspect_ratio = 1485 GO7007_ASPECT_RATIO_4_3_NTSC; 1486 else 1487 comp->aspect_ratio = 1488 GO7007_ASPECT_RATIO_4_3_PAL; 1489 break; 1490 case GO7007_RATIO_16_9: 1491 if (go->standard == GO7007_STD_NTSC) 1492 comp->aspect_ratio = 1493 GO7007_ASPECT_RATIO_16_9_NTSC; 1494 else 1495 comp->aspect_ratio = 1496 GO7007_ASPECT_RATIO_16_9_PAL; 1497 break; 1498 default: 1499 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1; 1500 break; 1501 } 1502 if (go->closed_gop) 1503 comp->flags |= GO7007_COMP_CLOSED_GOP; 1504 if (!go->seq_header_enable) 1505 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER; 1506 return 0; 1507 } 1508 case GO7007IOC_S_MPEG_PARAMS: 1509 { 1510 struct go7007_mpeg_params *mpeg = arg; 1511 1512 if (go->format != GO7007_FORMAT_MPEG1 && 1513 go->format != GO7007_FORMAT_MPEG2 && 1514 go->format != GO7007_FORMAT_MPEG4) 1515 return -EINVAL; 1516 1517 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) { 1518 go->format = GO7007_FORMAT_MPEG2; 1519 go->bitrate = 9800000; 1520 go->gop_size = 15; 1521 go->pali = 0x48; 1522 go->closed_gop = 1; 1523 go->repeat_seqhead = 0; 1524 go->seq_header_enable = 1; 1525 go->gop_header_enable = 1; 1526 go->dvd_mode = 1; 1527 } else { 1528 switch (mpeg->mpeg_video_standard) { 1529 case GO7007_MPEG_VIDEO_MPEG1: 1530 go->format = GO7007_FORMAT_MPEG1; 1531 go->pali = 0; 1532 break; 1533 case GO7007_MPEG_VIDEO_MPEG2: 1534 go->format = GO7007_FORMAT_MPEG2; 1535 if (mpeg->pali >> 24 == 2) 1536 go->pali = mpeg->pali & 0xff; 1537 else 1538 go->pali = 0x48; 1539 break; 1540 case GO7007_MPEG_VIDEO_MPEG4: 1541 go->format = GO7007_FORMAT_MPEG4; 1542 if (mpeg->pali >> 24 == 4) 1543 go->pali = mpeg->pali & 0xff; 1544 else 1545 go->pali = 0xf5; 1546 break; 1547 default: 1548 return -EINVAL; 1549 } 1550 go->gop_header_enable = 1551 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER 1552 ? 0 : 1; 1553 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER) 1554 go->repeat_seqhead = 1; 1555 else 1556 go->repeat_seqhead = 0; 1557 go->dvd_mode = 0; 1558 } 1559 /* fall-through */ 1560 } 1561 case GO7007IOC_G_MPEG_PARAMS: 1562 { 1563 struct go7007_mpeg_params *mpeg = arg; 1564 1565 memset(mpeg, 0, sizeof(*mpeg)); 1566 switch (go->format) { 1567 case GO7007_FORMAT_MPEG1: 1568 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1; 1569 mpeg->pali = 0; 1570 break; 1571 case GO7007_FORMAT_MPEG2: 1572 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2; 1573 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali); 1574 break; 1575 case GO7007_FORMAT_MPEG4: 1576 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4; 1577 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali); 1578 break; 1579 default: 1580 return -EINVAL; 1581 } 1582 if (!go->gop_header_enable) 1583 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER; 1584 if (go->repeat_seqhead) 1585 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER; 1586 if (go->dvd_mode) 1587 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE; 1588 return 0; 1589 } 1590 case GO7007IOC_S_MD_PARAMS: 1591 { 1592 struct go7007_md_params *mdp = arg; 1593 1594 if (mdp->region > 3) 1595 return -EINVAL; 1596 if (mdp->trigger > 0) { 1597 go->modet[mdp->region].pixel_threshold = 1598 mdp->pixel_threshold >> 1; 1599 go->modet[mdp->region].motion_threshold = 1600 mdp->motion_threshold >> 1; 1601 go->modet[mdp->region].mb_threshold = 1602 mdp->trigger >> 1; 1603 go->modet[mdp->region].enable = 1; 1604 } else 1605 go->modet[mdp->region].enable = 0; 1606 /* fall-through */ 1607 } 1608 case GO7007IOC_G_MD_PARAMS: 1609 { 1610 struct go7007_md_params *mdp = arg; 1611 int region = mdp->region; 1612 1613 if (mdp->region > 3) 1614 return -EINVAL; 1615 memset(mdp, 0, sizeof(struct go7007_md_params)); 1616 mdp->region = region; 1617 if (!go->modet[region].enable) 1618 return 0; 1619 mdp->pixel_threshold = 1620 (go->modet[region].pixel_threshold << 1) + 1; 1621 mdp->motion_threshold = 1622 (go->modet[region].motion_threshold << 1) + 1; 1623 mdp->trigger = 1624 (go->modet[region].mb_threshold << 1) + 1; 1625 return 0; 1626 } 1627 case GO7007IOC_S_MD_REGION: 1628 { 1629 struct go7007_md_region *region = arg; 1630 1631 if (region->region < 1 || region->region > 3) 1632 return -EINVAL; 1633 return clip_to_modet_map(go, region->region, region->clips); 1634 } 1635#endif 1636 1637static ssize_t go7007_read(struct file *file, char __user *data, 1638 size_t count, loff_t *ppos) 1639{ 1640 return -EINVAL; 1641} 1642 1643static void go7007_vm_open(struct vm_area_struct *vma) 1644{ 1645 struct go7007_buffer *gobuf = vma->vm_private_data; 1646 1647 ++gobuf->mapped; 1648} 1649 1650static void go7007_vm_close(struct vm_area_struct *vma) 1651{ 1652 struct go7007_buffer *gobuf = vma->vm_private_data; 1653 unsigned long flags; 1654 1655 if (--gobuf->mapped == 0) { 1656 spin_lock_irqsave(&gobuf->go->spinlock, flags); 1657 deactivate_buffer(gobuf); 1658 spin_unlock_irqrestore(&gobuf->go->spinlock, flags); 1659 } 1660} 1661 1662/* Copied from videobuf-dma-sg.c */ 1663static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 1664{ 1665 struct page *page; 1666 1667 page = alloc_page(GFP_USER | __GFP_DMA32); 1668 if (!page) 1669 return VM_FAULT_OOM; 1670 clear_user_highpage(page, (unsigned long)vmf->virtual_address); 1671 vmf->page = page; 1672 return 0; 1673} 1674 1675static struct vm_operations_struct go7007_vm_ops = { 1676 .open = go7007_vm_open, 1677 .close = go7007_vm_close, 1678 .fault = go7007_vm_fault, 1679}; 1680 1681static int go7007_mmap(struct file *file, struct vm_area_struct *vma) 1682{ 1683 struct go7007_file *gofh = file->private_data; 1684 unsigned int index; 1685 1686 if (gofh->go->status != STATUS_ONLINE) 1687 return -EIO; 1688 if (!(vma->vm_flags & VM_SHARED)) 1689 return -EINVAL; /* only support VM_SHARED mapping */ 1690 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE) 1691 return -EINVAL; /* must map exactly one full buffer */ 1692 mutex_lock(&gofh->lock); 1693 index = vma->vm_pgoff / GO7007_BUF_PAGES; 1694 if (index >= gofh->buf_count) { 1695 mutex_unlock(&gofh->lock); 1696 return -EINVAL; /* trying to map beyond requested buffers */ 1697 } 1698 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) { 1699 mutex_unlock(&gofh->lock); 1700 return -EINVAL; /* offset is not aligned on buffer boundary */ 1701 } 1702 if (gofh->bufs[index].mapped > 0) { 1703 mutex_unlock(&gofh->lock); 1704 return -EBUSY; 1705 } 1706 gofh->bufs[index].mapped = 1; 1707 gofh->bufs[index].user_addr = vma->vm_start; 1708 vma->vm_ops = &go7007_vm_ops; 1709 vma->vm_flags |= VM_DONTEXPAND; 1710 vma->vm_flags &= ~VM_IO; 1711 vma->vm_private_data = &gofh->bufs[index]; 1712 mutex_unlock(&gofh->lock); 1713 return 0; 1714} 1715 1716static unsigned int go7007_poll(struct file *file, poll_table *wait) 1717{ 1718 struct go7007_file *gofh = file->private_data; 1719 struct go7007_buffer *gobuf; 1720 1721 if (list_empty(&gofh->go->stream)) 1722 return POLLERR; 1723 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream); 1724 poll_wait(file, &gofh->go->frame_waitq, wait); 1725 if (gobuf->state == BUF_STATE_DONE) 1726 return POLLIN | POLLRDNORM; 1727 return 0; 1728} 1729 1730static void go7007_vfl_release(struct video_device *vfd) 1731{ 1732 struct go7007 *go = video_get_drvdata(vfd); 1733 1734 video_device_release(vfd); 1735 if (--go->ref_count == 0) 1736 kfree(go); 1737} 1738 1739static struct v4l2_file_operations go7007_fops = { 1740 .owner = THIS_MODULE, 1741 .open = go7007_open, 1742 .release = go7007_release, 1743 .ioctl = video_ioctl2, 1744 .read = go7007_read, 1745 .mmap = go7007_mmap, 1746 .poll = go7007_poll, 1747}; 1748 1749static const struct v4l2_ioctl_ops video_ioctl_ops = { 1750 .vidioc_querycap = vidioc_querycap, 1751 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1752 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1753 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1754 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1755 .vidioc_reqbufs = vidioc_reqbufs, 1756 .vidioc_querybuf = vidioc_querybuf, 1757 .vidioc_qbuf = vidioc_qbuf, 1758 .vidioc_dqbuf = vidioc_dqbuf, 1759 .vidioc_g_std = vidioc_g_std, 1760 .vidioc_s_std = vidioc_s_std, 1761 .vidioc_querystd = vidioc_querystd, 1762 .vidioc_enum_input = vidioc_enum_input, 1763 .vidioc_g_input = vidioc_g_input, 1764 .vidioc_s_input = vidioc_s_input, 1765 .vidioc_queryctrl = vidioc_queryctrl, 1766 .vidioc_g_ctrl = vidioc_g_ctrl, 1767 .vidioc_s_ctrl = vidioc_s_ctrl, 1768 .vidioc_streamon = vidioc_streamon, 1769 .vidioc_streamoff = vidioc_streamoff, 1770 .vidioc_g_tuner = vidioc_g_tuner, 1771 .vidioc_s_tuner = vidioc_s_tuner, 1772 .vidioc_g_frequency = vidioc_g_frequency, 1773 .vidioc_s_frequency = vidioc_s_frequency, 1774 .vidioc_g_parm = vidioc_g_parm, 1775 .vidioc_s_parm = vidioc_s_parm, 1776 .vidioc_enum_framesizes = vidioc_enum_framesizes, 1777 .vidioc_enum_frameintervals = vidioc_enum_frameintervals, 1778 .vidioc_cropcap = vidioc_cropcap, 1779 .vidioc_g_crop = vidioc_g_crop, 1780 .vidioc_s_crop = vidioc_s_crop, 1781 .vidioc_g_jpegcomp = vidioc_g_jpegcomp, 1782 .vidioc_s_jpegcomp = vidioc_s_jpegcomp, 1783}; 1784 1785static struct video_device go7007_template = { 1786 .name = "go7007", 1787 .fops = &go7007_fops, 1788 .release = go7007_vfl_release, 1789 .ioctl_ops = &video_ioctl_ops, 1790 .tvnorms = V4L2_STD_ALL, 1791 .current_norm = V4L2_STD_NTSC, 1792}; 1793 1794int go7007_v4l2_init(struct go7007 *go) 1795{ 1796 int rv; 1797 1798 go->video_dev = video_device_alloc(); 1799 if (go->video_dev == NULL) 1800 return -ENOMEM; 1801 *go->video_dev = go7007_template; 1802 go->video_dev->parent = go->dev; 1803 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1); 1804 if (rv < 0) { 1805 video_device_release(go->video_dev); 1806 go->video_dev = NULL; 1807 return rv; 1808 } 1809 rv = v4l2_device_register(go->dev, &go->v4l2_dev); 1810 if (rv < 0) { 1811 video_device_release(go->video_dev); 1812 go->video_dev = NULL; 1813 return rv; 1814 } 1815 video_set_drvdata(go->video_dev, go); 1816 ++go->ref_count; 1817 printk(KERN_INFO "%s: registered device %s [v4l2]\n", 1818 go->video_dev->name, video_device_node_name(go->video_dev)); 1819 1820 return 0; 1821} 1822 1823void go7007_v4l2_remove(struct go7007 *go) 1824{ 1825 unsigned long flags; 1826 1827 mutex_lock(&go->hw_lock); 1828 if (go->streaming) { 1829 go->streaming = 0; 1830 go7007_stream_stop(go); 1831 spin_lock_irqsave(&go->spinlock, flags); 1832 abort_queued(go); 1833 spin_unlock_irqrestore(&go->spinlock, flags); 1834 } 1835 mutex_unlock(&go->hw_lock); 1836 if (go->video_dev) 1837 video_unregister_device(go->video_dev); 1838 v4l2_device_unregister(&go->v4l2_dev); 1839} 1840