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