File Index
Files and directories
Sign in
FILE

go7007-v4l2.c

File preview with syntax highlighting.

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