brintos

brintos / linux-shallow public Read only

0
0
Text · 47.9 KiB · 6a790ac Raw
1745 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * vivid-vid-cap.c - video capture support functions.4 *5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.6 */7 8#include <linux/errno.h>9#include <linux/kernel.h>10#include <linux/sched.h>11#include <linux/vmalloc.h>12#include <linux/videodev2.h>13#include <linux/v4l2-dv-timings.h>14#include <media/v4l2-common.h>15#include <media/v4l2-event.h>16#include <media/v4l2-dv-timings.h>17#include <media/v4l2-rect.h>18 19#include "vivid-core.h"20#include "vivid-vid-common.h"21#include "vivid-kthread-cap.h"22#include "vivid-vid-cap.h"23 24/* Sizes must be in increasing order */25static const struct v4l2_frmsize_discrete webcam_sizes[] = {26	{  320, 180 },27	{  640, 360 },28	{  640, 480 },29	{ 1280, 720 },30	{ 1920, 1080 },31	{ 3840, 2160 },32};33 34/*35 * Intervals must be in increasing order and there must be twice as many36 * elements in this array as there are in webcam_sizes.37 */38static const struct v4l2_fract webcam_intervals[] = {39	{  1, 1 },40	{  1, 2 },41	{  1, 4 },42	{  1, 5 },43	{  1, 10 },44	{  2, 25 },45	{  1, 15 }, /* 7 - maximum for 2160p */46	{  1, 25 },47	{  1, 30 }, /* 9 - maximum for 1080p */48	{  1, 40 },49	{  1, 50 },50	{  1, 60 }, /* 12 - maximum for 720p */51	{  1, 120 },52};53 54/* Limit maximum FPS rates for high resolutions */55#define IVAL_COUNT_720P 12 /* 720p and up is limited to 60 fps */56#define IVAL_COUNT_1080P 9 /* 1080p and up is limited to 30 fps */57#define IVAL_COUNT_2160P 7 /* 2160p and up is limited to 15 fps */58 59static inline unsigned int webcam_ival_count(const struct vivid_dev *dev,60					     unsigned int frmsize_idx)61{62	if (webcam_sizes[frmsize_idx].height >= 2160)63		return IVAL_COUNT_2160P;64 65	if (webcam_sizes[frmsize_idx].height >= 1080)66		return IVAL_COUNT_1080P;67 68	if (webcam_sizes[frmsize_idx].height >= 720)69		return IVAL_COUNT_720P;70 71	/* For low resolutions, allow all FPS rates */72	return ARRAY_SIZE(webcam_intervals);73}74 75static int vid_cap_queue_setup(struct vb2_queue *vq,76		       unsigned *nbuffers, unsigned *nplanes,77		       unsigned sizes[], struct device *alloc_devs[])78{79	struct vivid_dev *dev = vb2_get_drv_priv(vq);80	unsigned buffers = tpg_g_buffers(&dev->tpg);81	unsigned h = dev->fmt_cap_rect.height;82	unsigned p;83 84	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {85		/*86		 * You cannot use read() with FIELD_ALTERNATE since the field87		 * information (TOP/BOTTOM) cannot be passed back to the user.88		 */89		if (vb2_fileio_is_active(vq))90			return -EINVAL;91	}92 93	if (dev->queue_setup_error) {94		/*95		 * Error injection: test what happens if queue_setup() returns96		 * an error.97		 */98		dev->queue_setup_error = false;99		return -EINVAL;100	}101	if (*nplanes) {102		/*103		 * Check if the number of requested planes match104		 * the number of buffers in the current format. You can't mix that.105		 */106		if (*nplanes != buffers)107			return -EINVAL;108		for (p = 0; p < buffers; p++) {109			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h /110					dev->fmt_cap->vdownsampling[p] +111					dev->fmt_cap->data_offset[p])112				return -EINVAL;113		}114	} else {115		for (p = 0; p < buffers; p++)116			sizes[p] = (tpg_g_line_width(&dev->tpg, p) * h) /117					dev->fmt_cap->vdownsampling[p] +118					dev->fmt_cap->data_offset[p];119	}120 121	*nplanes = buffers;122 123	dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);124	for (p = 0; p < buffers; p++)125		dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);126 127	return 0;128}129 130static int vid_cap_buf_prepare(struct vb2_buffer *vb)131{132	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);133	unsigned long size;134	unsigned buffers = tpg_g_buffers(&dev->tpg);135	unsigned p;136 137	dprintk(dev, 1, "%s\n", __func__);138 139	if (WARN_ON(NULL == dev->fmt_cap))140		return -EINVAL;141 142	if (dev->buf_prepare_error) {143		/*144		 * Error injection: test what happens if buf_prepare() returns145		 * an error.146		 */147		dev->buf_prepare_error = false;148		return -EINVAL;149	}150	for (p = 0; p < buffers; p++) {151		size = (tpg_g_line_width(&dev->tpg, p) *152			dev->fmt_cap_rect.height) /153			dev->fmt_cap->vdownsampling[p] +154			dev->fmt_cap->data_offset[p];155 156		if (vb2_plane_size(vb, p) < size) {157			dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n",158					__func__, p, vb2_plane_size(vb, p), size);159			return -EINVAL;160		}161 162		vb2_set_plane_payload(vb, p, size);163		vb->planes[p].data_offset = dev->fmt_cap->data_offset[p];164	}165 166	return 0;167}168 169static void vid_cap_buf_finish(struct vb2_buffer *vb)170{171	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);172	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);173	struct v4l2_timecode *tc = &vbuf->timecode;174	unsigned fps = 25;175	unsigned seq = vbuf->sequence;176 177	if (!vivid_is_sdtv_cap(dev))178		return;179 180	/*181	 * Set the timecode. Rarely used, so it is interesting to182	 * test this.183	 */184	vbuf->flags |= V4L2_BUF_FLAG_TIMECODE;185	if (dev->std_cap[dev->input] & V4L2_STD_525_60)186		fps = 30;187	tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS;188	tc->flags = 0;189	tc->frames = seq % fps;190	tc->seconds = (seq / fps) % 60;191	tc->minutes = (seq / (60 * fps)) % 60;192	tc->hours = (seq / (60 * 60 * fps)) % 24;193}194 195static void vid_cap_buf_queue(struct vb2_buffer *vb)196{197	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);198	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);199	struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);200 201	dprintk(dev, 1, "%s\n", __func__);202 203	spin_lock(&dev->slock);204	list_add_tail(&buf->list, &dev->vid_cap_active);205	spin_unlock(&dev->slock);206}207 208static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)209{210	struct vivid_dev *dev = vb2_get_drv_priv(vq);211	unsigned i;212	int err;213 214	dev->vid_cap_seq_count = 0;215	dprintk(dev, 1, "%s\n", __func__);216	for (i = 0; i < MAX_VID_CAP_BUFFERS; i++)217		dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100;218	if (dev->start_streaming_error) {219		dev->start_streaming_error = false;220		err = -EINVAL;221	} else {222		err = vivid_start_generating_vid_cap(dev, &dev->vid_cap_streaming);223	}224	if (err) {225		struct vivid_buffer *buf, *tmp;226 227		list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) {228			list_del(&buf->list);229			vb2_buffer_done(&buf->vb.vb2_buf,230					VB2_BUF_STATE_QUEUED);231		}232	}233	return err;234}235 236/* abort streaming and wait for last buffer */237static void vid_cap_stop_streaming(struct vb2_queue *vq)238{239	struct vivid_dev *dev = vb2_get_drv_priv(vq);240 241	dprintk(dev, 1, "%s\n", __func__);242	vivid_stop_generating_vid_cap(dev, &dev->vid_cap_streaming);243}244 245static void vid_cap_buf_request_complete(struct vb2_buffer *vb)246{247	struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);248 249	v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_cap);250}251 252const struct vb2_ops vivid_vid_cap_qops = {253	.queue_setup		= vid_cap_queue_setup,254	.buf_prepare		= vid_cap_buf_prepare,255	.buf_finish		= vid_cap_buf_finish,256	.buf_queue		= vid_cap_buf_queue,257	.start_streaming	= vid_cap_start_streaming,258	.stop_streaming		= vid_cap_stop_streaming,259	.buf_request_complete	= vid_cap_buf_request_complete,260	.wait_prepare		= vb2_ops_wait_prepare,261	.wait_finish		= vb2_ops_wait_finish,262};263 264/*265 * Determine the 'picture' quality based on the current TV frequency: either266 * COLOR for a good 'signal', GRAY (grayscale picture) for a slightly off267 * signal or NOISE for no signal.268 */269void vivid_update_quality(struct vivid_dev *dev)270{271	unsigned freq_modulus;272 273	if (dev->input_is_connected_to_output[dev->input]) {274		/*275		 * The 'noise' will only be replaced by the actual video276		 * if the output video matches the input video settings.277		 */278		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);279		return;280	}281	if (vivid_is_hdmi_cap(dev) &&282	    VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])) {283		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);284		return;285	}286	if (vivid_is_sdtv_cap(dev) &&287	    VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {288		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);289		return;290	}291	if (!vivid_is_tv_cap(dev)) {292		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);293		return;294	}295 296	/*297	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.298	 * From +/- 0.25 MHz around the channel there is color, and from299	 * +/- 1 MHz there is grayscale (chroma is lost).300	 * Everywhere else it is just noise.301	 */302	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);303	if (freq_modulus > 2 * 16) {304		tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE,305			next_pseudo_random32(dev->tv_freq ^ 0x55) & 0x3f);306		return;307	}308	if (freq_modulus < 12 /*0.75 * 16*/ || freq_modulus > 20 /*1.25 * 16*/)309		tpg_s_quality(&dev->tpg, TPG_QUAL_GRAY, 0);310	else311		tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0);312}313 314/*315 * Get the current picture quality and the associated afc value.316 */317static enum tpg_quality vivid_get_quality(struct vivid_dev *dev, s32 *afc)318{319	unsigned freq_modulus;320 321	if (afc)322		*afc = 0;323	if (tpg_g_quality(&dev->tpg) == TPG_QUAL_COLOR ||324	    tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE)325		return tpg_g_quality(&dev->tpg);326 327	/*328	 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.329	 * From +/- 0.25 MHz around the channel there is color, and from330	 * +/- 1 MHz there is grayscale (chroma is lost).331	 * Everywhere else it is just gray.332	 */333	freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16);334	if (afc)335		*afc = freq_modulus - 1 * 16;336	return TPG_QUAL_GRAY;337}338 339enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev)340{341	if (vivid_is_sdtv_cap(dev))342		return dev->std_aspect_ratio[dev->input];343 344	if (vivid_is_hdmi_cap(dev))345		return dev->dv_timings_aspect_ratio[dev->input];346 347	return TPG_VIDEO_ASPECT_IMAGE;348}349 350static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)351{352	if (vivid_is_sdtv_cap(dev))353		return (dev->std_cap[dev->input] & V4L2_STD_525_60) ?354			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;355 356	if (vivid_is_hdmi_cap(dev) &&357	    dev->src_rect.width == 720 && dev->src_rect.height <= 576)358		return dev->src_rect.height == 480 ?359			TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;360 361	return TPG_PIXEL_ASPECT_SQUARE;362}363 364/*365 * Called whenever the format has to be reset which can occur when366 * changing inputs, standard, timings, etc.367 */368void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)369{370	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;371	u32 dims[V4L2_CTRL_MAX_DIMS] = {};372	unsigned size;373	u64 pixelclock;374 375	switch (dev->input_type[dev->input]) {376	case WEBCAM:377	default:378		dev->src_rect.width = webcam_sizes[dev->webcam_size_idx].width;379		dev->src_rect.height = webcam_sizes[dev->webcam_size_idx].height;380		dev->timeperframe_vid_cap = webcam_intervals[dev->webcam_ival_idx];381		dev->field_cap = V4L2_FIELD_NONE;382		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);383		break;384	case TV:385	case SVID:386		dev->field_cap = dev->tv_field_cap;387		dev->src_rect.width = 720;388		if (dev->std_cap[dev->input] & V4L2_STD_525_60) {389			dev->src_rect.height = 480;390			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1001, 30000 };391			dev->service_set_cap = V4L2_SLICED_CAPTION_525;392		} else {393			dev->src_rect.height = 576;394			dev->timeperframe_vid_cap = (struct v4l2_fract) { 1000, 25000 };395			dev->service_set_cap = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;396		}397		tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO);398		break;399	case HDMI:400		dev->src_rect.width = bt->width;401		dev->src_rect.height = bt->height;402		size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);403		if (dev->reduced_fps && can_reduce_fps(bt)) {404			pixelclock = div_u64(bt->pixelclock * 1000, 1001);405			bt->flags |= V4L2_DV_FL_REDUCED_FPS;406		} else {407			pixelclock = bt->pixelclock;408			bt->flags &= ~V4L2_DV_FL_REDUCED_FPS;409		}410		dev->timeperframe_vid_cap = (struct v4l2_fract) {411			size / 100, (u32)pixelclock / 100412		};413		if (bt->interlaced)414			dev->field_cap = V4L2_FIELD_ALTERNATE;415		else416			dev->field_cap = V4L2_FIELD_NONE;417 418		/*419		 * We can be called from within s_ctrl, in that case we can't420		 * set/get controls. Luckily we don't need to in that case.421		 */422		if (keep_controls || !dev->colorspace)423			break;424		if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {425			if (bt->width == 720 && bt->height <= 576)426				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);427			else428				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);429			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 1);430		} else {431			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);432			v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 0);433		}434		tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap));435		break;436	}437	vivid_update_quality(dev);438	tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);439	dev->crop_cap = dev->src_rect;440	dev->crop_bounds_cap = dev->src_rect;441	dev->compose_cap = dev->crop_cap;442	if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))443		dev->compose_cap.height /= 2;444	dev->fmt_cap_rect = dev->compose_cap;445	tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));446	tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));447	tpg_update_mv_step(&dev->tpg);448 449	/*450	 * We can be called from within s_ctrl, in that case we can't451	 * modify controls. Luckily we don't need to in that case.452	 */453	if (keep_controls)454		return;455 456	dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);457	dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);458	v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);459}460 461/* Map the field to something that is valid for the current input */462static enum v4l2_field vivid_field_cap(struct vivid_dev *dev, enum v4l2_field field)463{464	if (vivid_is_sdtv_cap(dev)) {465		switch (field) {466		case V4L2_FIELD_INTERLACED_TB:467		case V4L2_FIELD_INTERLACED_BT:468		case V4L2_FIELD_SEQ_TB:469		case V4L2_FIELD_SEQ_BT:470		case V4L2_FIELD_TOP:471		case V4L2_FIELD_BOTTOM:472		case V4L2_FIELD_ALTERNATE:473			return field;474		case V4L2_FIELD_INTERLACED:475		default:476			return V4L2_FIELD_INTERLACED;477		}478	}479	if (vivid_is_hdmi_cap(dev))480		return dev->dv_timings_cap[dev->input].bt.interlaced ?481			V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE;482	return V4L2_FIELD_NONE;483}484 485static unsigned vivid_colorspace_cap(struct vivid_dev *dev)486{487	if (!vivid_input_is_connected_to(dev))488		return tpg_g_colorspace(&dev->tpg);489	return dev->colorspace_out;490}491 492static unsigned vivid_xfer_func_cap(struct vivid_dev *dev)493{494	if (!vivid_input_is_connected_to(dev))495		return tpg_g_xfer_func(&dev->tpg);496	return dev->xfer_func_out;497}498 499static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev)500{501	if (!vivid_input_is_connected_to(dev))502		return tpg_g_ycbcr_enc(&dev->tpg);503	return dev->ycbcr_enc_out;504}505 506static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev)507{508	if (!vivid_input_is_connected_to(dev))509		return tpg_g_hsv_enc(&dev->tpg);510	return dev->hsv_enc_out;511}512 513static unsigned vivid_quantization_cap(struct vivid_dev *dev)514{515	if (!vivid_input_is_connected_to(dev))516		return tpg_g_quantization(&dev->tpg);517	return dev->quantization_out;518}519 520int vivid_g_fmt_vid_cap(struct file *file, void *priv,521					struct v4l2_format *f)522{523	struct vivid_dev *dev = video_drvdata(file);524	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;525	unsigned p;526 527	mp->width        = dev->fmt_cap_rect.width;528	mp->height       = dev->fmt_cap_rect.height;529	mp->field        = dev->field_cap;530	mp->pixelformat  = dev->fmt_cap->fourcc;531	mp->colorspace   = vivid_colorspace_cap(dev);532	mp->xfer_func    = vivid_xfer_func_cap(dev);533	if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV)534		mp->hsv_enc    = vivid_hsv_enc_cap(dev);535	else536		mp->ycbcr_enc    = vivid_ycbcr_enc_cap(dev);537	mp->quantization = vivid_quantization_cap(dev);538	mp->num_planes = dev->fmt_cap->buffers;539	for (p = 0; p < mp->num_planes; p++) {540		mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);541		mp->plane_fmt[p].sizeimage =542			(tpg_g_line_width(&dev->tpg, p) * mp->height) /543			dev->fmt_cap->vdownsampling[p] +544			dev->fmt_cap->data_offset[p];545	}546	return 0;547}548 549int vivid_try_fmt_vid_cap(struct file *file, void *priv,550			struct v4l2_format *f)551{552	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;553	struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;554	struct vivid_dev *dev = video_drvdata(file);555	const struct vivid_fmt *fmt;556	unsigned bytesperline, max_bpl;557	unsigned factor = 1;558	unsigned w, h;559	unsigned p;560	bool user_set_csc = !!(mp->flags & V4L2_PIX_FMT_FLAG_SET_CSC);561 562	fmt = vivid_get_format(dev, mp->pixelformat);563	if (!fmt) {564		dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",565			mp->pixelformat);566		mp->pixelformat = V4L2_PIX_FMT_YUYV;567		fmt = vivid_get_format(dev, mp->pixelformat);568	}569 570	mp->field = vivid_field_cap(dev, mp->field);571	if (vivid_is_webcam(dev)) {572		const struct v4l2_frmsize_discrete *sz =573			v4l2_find_nearest_size(webcam_sizes,574					       ARRAY_SIZE(webcam_sizes), width,575					       height, mp->width, mp->height);576 577		w = sz->width;578		h = sz->height;579	} else if (vivid_is_sdtv_cap(dev)) {580		w = 720;581		h = (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 480 : 576;582	} else {583		w = dev->src_rect.width;584		h = dev->src_rect.height;585	}586	if (V4L2_FIELD_HAS_T_OR_B(mp->field))587		factor = 2;588	if (vivid_is_webcam(dev) ||589	    (!dev->has_scaler_cap && !dev->has_crop_cap && !dev->has_compose_cap)) {590		mp->width = w;591		mp->height = h / factor;592	} else {593		struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };594 595		v4l2_rect_set_min_size(&r, &vivid_min_rect);596		v4l2_rect_set_max_size(&r, &vivid_max_rect);597		if (dev->has_scaler_cap && !dev->has_compose_cap) {598			struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };599 600			v4l2_rect_set_max_size(&r, &max_r);601		} else if (!dev->has_scaler_cap && dev->has_crop_cap && !dev->has_compose_cap) {602			v4l2_rect_set_max_size(&r, &dev->src_rect);603		} else if (!dev->has_scaler_cap && !dev->has_crop_cap) {604			v4l2_rect_set_min_size(&r, &dev->src_rect);605		}606		mp->width = r.width;607		mp->height = r.height / factor;608	}609 610	/* This driver supports custom bytesperline values */611 612	mp->num_planes = fmt->buffers;613	for (p = 0; p < fmt->buffers; p++) {614		/* Calculate the minimum supported bytesperline value */615		bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;616		/* Calculate the maximum supported bytesperline value */617		max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;618 619		if (pfmt[p].bytesperline > max_bpl)620			pfmt[p].bytesperline = max_bpl;621		if (pfmt[p].bytesperline < bytesperline)622			pfmt[p].bytesperline = bytesperline;623 624		pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /625				fmt->vdownsampling[p] + fmt->data_offset[p];626 627		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));628	}629	for (p = fmt->buffers; p < fmt->planes; p++)630		pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *631			(fmt->bit_depth[p] / fmt->vdownsampling[p])) /632			(fmt->bit_depth[0] / fmt->vdownsampling[0]);633 634	if (!user_set_csc || !v4l2_is_colorspace_valid(mp->colorspace))635		mp->colorspace = vivid_colorspace_cap(dev);636 637	if (!user_set_csc || !v4l2_is_xfer_func_valid(mp->xfer_func))638		mp->xfer_func = vivid_xfer_func_cap(dev);639 640	if (fmt->color_enc == TGP_COLOR_ENC_HSV) {641		if (!user_set_csc || !v4l2_is_hsv_enc_valid(mp->hsv_enc))642			mp->hsv_enc = vivid_hsv_enc_cap(dev);643	} else if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) {644		if (!user_set_csc || !v4l2_is_ycbcr_enc_valid(mp->ycbcr_enc))645			mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);646	} else {647		mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);648	}649 650	if (fmt->color_enc == TGP_COLOR_ENC_YCBCR ||651	    fmt->color_enc == TGP_COLOR_ENC_RGB) {652		if (!user_set_csc || !v4l2_is_quant_valid(mp->quantization))653			mp->quantization = vivid_quantization_cap(dev);654	} else {655		mp->quantization = vivid_quantization_cap(dev);656	}657 658	memset(mp->reserved, 0, sizeof(mp->reserved));659	return 0;660}661 662int vivid_s_fmt_vid_cap(struct file *file, void *priv,663					struct v4l2_format *f)664{665	struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;666	struct vivid_dev *dev = video_drvdata(file);667	struct v4l2_rect *crop = &dev->crop_cap;668	struct v4l2_rect *compose = &dev->compose_cap;669	struct vb2_queue *q = &dev->vb_vid_cap_q;670	int ret = vivid_try_fmt_vid_cap(file, priv, f);671	unsigned factor = 1;672	unsigned p;673	unsigned i;674 675	if (ret < 0)676		return ret;677 678	if (vb2_is_busy(q)) {679		dprintk(dev, 1, "%s device busy\n", __func__);680		return -EBUSY;681	}682 683	dev->fmt_cap = vivid_get_format(dev, mp->pixelformat);684	if (V4L2_FIELD_HAS_T_OR_B(mp->field))685		factor = 2;686 687	/* Note: the webcam input doesn't support scaling, cropping or composing */688 689	if (!vivid_is_webcam(dev) &&690	    (dev->has_scaler_cap || dev->has_crop_cap || dev->has_compose_cap)) {691		struct v4l2_rect r = { 0, 0, mp->width, mp->height };692 693		if (dev->has_scaler_cap) {694			if (dev->has_compose_cap)695				v4l2_rect_map_inside(compose, &r);696			else697				*compose = r;698			if (dev->has_crop_cap && !dev->has_compose_cap) {699				struct v4l2_rect min_r = {700					0, 0,701					r.width / MAX_ZOOM,702					factor * r.height / MAX_ZOOM703				};704				struct v4l2_rect max_r = {705					0, 0,706					r.width * MAX_ZOOM,707					factor * r.height * MAX_ZOOM708				};709 710				v4l2_rect_set_min_size(crop, &min_r);711				v4l2_rect_set_max_size(crop, &max_r);712				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);713			} else if (dev->has_crop_cap) {714				struct v4l2_rect min_r = {715					0, 0,716					compose->width / MAX_ZOOM,717					factor * compose->height / MAX_ZOOM718				};719				struct v4l2_rect max_r = {720					0, 0,721					compose->width * MAX_ZOOM,722					factor * compose->height * MAX_ZOOM723				};724 725				v4l2_rect_set_min_size(crop, &min_r);726				v4l2_rect_set_max_size(crop, &max_r);727				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);728			}729		} else if (dev->has_crop_cap && !dev->has_compose_cap) {730			r.height *= factor;731			v4l2_rect_set_size_to(crop, &r);732			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);733			r = *crop;734			r.height /= factor;735			v4l2_rect_set_size_to(compose, &r);736		} else if (!dev->has_crop_cap) {737			v4l2_rect_map_inside(compose, &r);738		} else {739			r.height *= factor;740			v4l2_rect_set_max_size(crop, &r);741			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);742			compose->top *= factor;743			compose->height *= factor;744			v4l2_rect_set_size_to(compose, crop);745			v4l2_rect_map_inside(compose, &r);746			compose->top /= factor;747			compose->height /= factor;748		}749	} else if (vivid_is_webcam(dev)) {750		unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx);751 752		/* Guaranteed to be a match */753		for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)754			if (webcam_sizes[i].width == mp->width &&755					webcam_sizes[i].height == mp->height)756				break;757		dev->webcam_size_idx = i;758		if (dev->webcam_ival_idx >= ival_sz)759			dev->webcam_ival_idx = ival_sz - 1;760		vivid_update_format_cap(dev, false);761	} else {762		struct v4l2_rect r = { 0, 0, mp->width, mp->height };763 764		v4l2_rect_set_size_to(compose, &r);765		r.height *= factor;766		v4l2_rect_set_size_to(crop, &r);767	}768 769	dev->fmt_cap_rect.width = mp->width;770	dev->fmt_cap_rect.height = mp->height;771	tpg_s_buf_height(&dev->tpg, mp->height);772	tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);773	for (p = 0; p < tpg_g_buffers(&dev->tpg); p++)774		tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline);775	dev->field_cap = mp->field;776	if (dev->field_cap == V4L2_FIELD_ALTERNATE)777		tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true);778	else779		tpg_s_field(&dev->tpg, dev->field_cap, false);780	tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap);781	if (vivid_is_sdtv_cap(dev))782		dev->tv_field_cap = mp->field;783	tpg_update_mv_step(&dev->tpg);784	dev->tpg.colorspace = mp->colorspace;785	dev->tpg.xfer_func = mp->xfer_func;786	if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_YCBCR)787		dev->tpg.ycbcr_enc = mp->ycbcr_enc;788	else789		dev->tpg.hsv_enc = mp->hsv_enc;790	dev->tpg.quantization = mp->quantization;791 792	return 0;793}794 795int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,796					struct v4l2_format *f)797{798	struct vivid_dev *dev = video_drvdata(file);799 800	if (!dev->multiplanar)801		return -ENOTTY;802	return vivid_g_fmt_vid_cap(file, priv, f);803}804 805int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,806			struct v4l2_format *f)807{808	struct vivid_dev *dev = video_drvdata(file);809 810	if (!dev->multiplanar)811		return -ENOTTY;812	return vivid_try_fmt_vid_cap(file, priv, f);813}814 815int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,816			struct v4l2_format *f)817{818	struct vivid_dev *dev = video_drvdata(file);819 820	if (!dev->multiplanar)821		return -ENOTTY;822	return vivid_s_fmt_vid_cap(file, priv, f);823}824 825int vidioc_g_fmt_vid_cap(struct file *file, void *priv,826					struct v4l2_format *f)827{828	struct vivid_dev *dev = video_drvdata(file);829 830	if (dev->multiplanar)831		return -ENOTTY;832	return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap);833}834 835int vidioc_try_fmt_vid_cap(struct file *file, void *priv,836			struct v4l2_format *f)837{838	struct vivid_dev *dev = video_drvdata(file);839 840	if (dev->multiplanar)841		return -ENOTTY;842	return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap);843}844 845int vidioc_s_fmt_vid_cap(struct file *file, void *priv,846			struct v4l2_format *f)847{848	struct vivid_dev *dev = video_drvdata(file);849 850	if (dev->multiplanar)851		return -ENOTTY;852	return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap);853}854 855int vivid_vid_cap_g_selection(struct file *file, void *priv,856			      struct v4l2_selection *sel)857{858	struct vivid_dev *dev = video_drvdata(file);859 860	if (!dev->has_crop_cap && !dev->has_compose_cap)861		return -ENOTTY;862	if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)863		return -EINVAL;864	if (vivid_is_webcam(dev))865		return -ENODATA;866 867	sel->r.left = sel->r.top = 0;868	switch (sel->target) {869	case V4L2_SEL_TGT_CROP:870		if (!dev->has_crop_cap)871			return -EINVAL;872		sel->r = dev->crop_cap;873		break;874	case V4L2_SEL_TGT_CROP_DEFAULT:875	case V4L2_SEL_TGT_CROP_BOUNDS:876		if (!dev->has_crop_cap)877			return -EINVAL;878		sel->r = dev->src_rect;879		break;880	case V4L2_SEL_TGT_COMPOSE_BOUNDS:881		if (!dev->has_compose_cap)882			return -EINVAL;883		sel->r = vivid_max_rect;884		break;885	case V4L2_SEL_TGT_COMPOSE:886		if (!dev->has_compose_cap)887			return -EINVAL;888		sel->r = dev->compose_cap;889		break;890	case V4L2_SEL_TGT_COMPOSE_DEFAULT:891		if (!dev->has_compose_cap)892			return -EINVAL;893		sel->r = dev->fmt_cap_rect;894		break;895	default:896		return -EINVAL;897	}898	return 0;899}900 901int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s)902{903	struct vivid_dev *dev = video_drvdata(file);904	struct v4l2_rect *crop = &dev->crop_cap;905	struct v4l2_rect *compose = &dev->compose_cap;906	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;907	int ret;908 909	if (!dev->has_crop_cap && !dev->has_compose_cap)910		return -ENOTTY;911	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)912		return -EINVAL;913	if (vivid_is_webcam(dev))914		return -ENODATA;915 916	switch (s->target) {917	case V4L2_SEL_TGT_CROP:918		if (!dev->has_crop_cap)919			return -EINVAL;920		ret = vivid_vid_adjust_sel(s->flags, &s->r);921		if (ret)922			return ret;923		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);924		v4l2_rect_set_max_size(&s->r, &dev->src_rect);925		v4l2_rect_map_inside(&s->r, &dev->crop_bounds_cap);926		s->r.top /= factor;927		s->r.height /= factor;928		if (dev->has_scaler_cap) {929			struct v4l2_rect fmt = dev->fmt_cap_rect;930			struct v4l2_rect max_rect = {931				0, 0,932				s->r.width * MAX_ZOOM,933				s->r.height * MAX_ZOOM934			};935			struct v4l2_rect min_rect = {936				0, 0,937				s->r.width / MAX_ZOOM,938				s->r.height / MAX_ZOOM939			};940 941			v4l2_rect_set_min_size(&fmt, &min_rect);942			if (!dev->has_compose_cap)943				v4l2_rect_set_max_size(&fmt, &max_rect);944			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&945			    vb2_is_busy(&dev->vb_vid_cap_q))946				return -EBUSY;947			if (dev->has_compose_cap) {948				v4l2_rect_set_min_size(compose, &min_rect);949				v4l2_rect_set_max_size(compose, &max_rect);950				v4l2_rect_map_inside(compose, &fmt);951			}952			dev->fmt_cap_rect = fmt;953			tpg_s_buf_height(&dev->tpg, fmt.height);954		} else if (dev->has_compose_cap) {955			struct v4l2_rect fmt = dev->fmt_cap_rect;956 957			v4l2_rect_set_min_size(&fmt, &s->r);958			if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) &&959			    vb2_is_busy(&dev->vb_vid_cap_q))960				return -EBUSY;961			dev->fmt_cap_rect = fmt;962			tpg_s_buf_height(&dev->tpg, fmt.height);963			v4l2_rect_set_size_to(compose, &s->r);964			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);965		} else {966			if (!v4l2_rect_same_size(&s->r, &dev->fmt_cap_rect) &&967			    vb2_is_busy(&dev->vb_vid_cap_q))968				return -EBUSY;969			v4l2_rect_set_size_to(&dev->fmt_cap_rect, &s->r);970			v4l2_rect_set_size_to(compose, &s->r);971			v4l2_rect_map_inside(compose, &dev->fmt_cap_rect);972			tpg_s_buf_height(&dev->tpg, dev->fmt_cap_rect.height);973		}974		s->r.top *= factor;975		s->r.height *= factor;976		*crop = s->r;977		break;978	case V4L2_SEL_TGT_COMPOSE:979		if (!dev->has_compose_cap)980			return -EINVAL;981		ret = vivid_vid_adjust_sel(s->flags, &s->r);982		if (ret)983			return ret;984		v4l2_rect_set_min_size(&s->r, &vivid_min_rect);985		v4l2_rect_set_max_size(&s->r, &dev->fmt_cap_rect);986		if (dev->has_scaler_cap) {987			struct v4l2_rect max_rect = {988				0, 0,989				dev->src_rect.width * MAX_ZOOM,990				(dev->src_rect.height / factor) * MAX_ZOOM991			};992 993			v4l2_rect_set_max_size(&s->r, &max_rect);994			if (dev->has_crop_cap) {995				struct v4l2_rect min_rect = {996					0, 0,997					s->r.width / MAX_ZOOM,998					(s->r.height * factor) / MAX_ZOOM999				};1000				struct v4l2_rect max_rect = {1001					0, 0,1002					s->r.width * MAX_ZOOM,1003					(s->r.height * factor) * MAX_ZOOM1004				};1005 1006				v4l2_rect_set_min_size(crop, &min_rect);1007				v4l2_rect_set_max_size(crop, &max_rect);1008				v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);1009			}1010		} else if (dev->has_crop_cap) {1011			s->r.top *= factor;1012			s->r.height *= factor;1013			v4l2_rect_set_max_size(&s->r, &dev->src_rect);1014			v4l2_rect_set_size_to(crop, &s->r);1015			v4l2_rect_map_inside(crop, &dev->crop_bounds_cap);1016			s->r.top /= factor;1017			s->r.height /= factor;1018		} else {1019			v4l2_rect_set_size_to(&s->r, &dev->src_rect);1020			s->r.height /= factor;1021		}1022		v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);1023		*compose = s->r;1024		break;1025	default:1026		return -EINVAL;1027	}1028 1029	tpg_s_crop_compose(&dev->tpg, crop, compose);1030	return 0;1031}1032 1033int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv,1034				int type, struct v4l2_fract *f)1035{1036	struct vivid_dev *dev = video_drvdata(file);1037 1038	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)1039		return -EINVAL;1040 1041	switch (vivid_get_pixel_aspect(dev)) {1042	case TPG_PIXEL_ASPECT_NTSC:1043		f->numerator = 11;1044		f->denominator = 10;1045		break;1046	case TPG_PIXEL_ASPECT_PAL:1047		f->numerator = 54;1048		f->denominator = 59;1049		break;1050	default:1051		break;1052	}1053	return 0;1054}1055 1056static const struct v4l2_audio vivid_audio_inputs[] = {1057	{ 0, "TV", V4L2_AUDCAP_STEREO },1058	{ 1, "Line-In", V4L2_AUDCAP_STEREO },1059};1060 1061int vidioc_enum_input(struct file *file, void *priv,1062				struct v4l2_input *inp)1063{1064	struct vivid_dev *dev = video_drvdata(file);1065 1066	if (inp->index >= dev->num_inputs)1067		return -EINVAL;1068 1069	inp->type = V4L2_INPUT_TYPE_CAMERA;1070	switch (dev->input_type[inp->index]) {1071	case WEBCAM:1072		snprintf(inp->name, sizeof(inp->name), "Webcam %03u-%u",1073			 dev->inst, dev->input_name_counter[inp->index]);1074		inp->capabilities = 0;1075		break;1076	case TV:1077		snprintf(inp->name, sizeof(inp->name), "TV %03u-%u",1078			 dev->inst, dev->input_name_counter[inp->index]);1079		inp->type = V4L2_INPUT_TYPE_TUNER;1080		inp->std = V4L2_STD_ALL;1081		if (dev->has_audio_inputs)1082			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;1083		inp->capabilities = V4L2_IN_CAP_STD;1084		break;1085	case SVID:1086		snprintf(inp->name, sizeof(inp->name), "S-Video %03u-%u",1087			 dev->inst, dev->input_name_counter[inp->index]);1088		inp->std = V4L2_STD_ALL;1089		if (dev->has_audio_inputs)1090			inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1;1091		inp->capabilities = V4L2_IN_CAP_STD;1092		break;1093	case HDMI:1094		snprintf(inp->name, sizeof(inp->name), "HDMI %03u-%u",1095			 dev->inst, dev->input_name_counter[inp->index]);1096		inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;1097		if (dev->edid_blocks == 0 ||1098		    dev->dv_timings_signal_mode[dev->input] == NO_SIGNAL)1099			inp->status |= V4L2_IN_ST_NO_SIGNAL;1100		else if (dev->dv_timings_signal_mode[dev->input] == NO_LOCK ||1101			 dev->dv_timings_signal_mode[dev->input] == OUT_OF_RANGE)1102			inp->status |= V4L2_IN_ST_NO_H_LOCK;1103		break;1104	}1105	if (dev->sensor_hflip)1106		inp->status |= V4L2_IN_ST_HFLIP;1107	if (dev->sensor_vflip)1108		inp->status |= V4L2_IN_ST_VFLIP;1109	if (dev->input == inp->index && vivid_is_sdtv_cap(dev)) {1110		if (dev->std_signal_mode[dev->input] == NO_SIGNAL) {1111			inp->status |= V4L2_IN_ST_NO_SIGNAL;1112		} else if (dev->std_signal_mode[dev->input] == NO_LOCK) {1113			inp->status |= V4L2_IN_ST_NO_H_LOCK;1114		} else if (vivid_is_tv_cap(dev)) {1115			switch (tpg_g_quality(&dev->tpg)) {1116			case TPG_QUAL_GRAY:1117				inp->status |= V4L2_IN_ST_COLOR_KILL;1118				break;1119			case TPG_QUAL_NOISE:1120				inp->status |= V4L2_IN_ST_NO_H_LOCK;1121				break;1122			default:1123				break;1124			}1125		}1126	}1127	return 0;1128}1129 1130int vidioc_g_input(struct file *file, void *priv, unsigned *i)1131{1132	struct vivid_dev *dev = video_drvdata(file);1133 1134	*i = dev->input;1135	return 0;1136}1137 1138int vidioc_s_input(struct file *file, void *priv, unsigned i)1139{1140	struct vivid_dev *dev = video_drvdata(file);1141	struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;1142	unsigned brightness;1143 1144	if (i >= dev->num_inputs)1145		return -EINVAL;1146 1147	if (i == dev->input)1148		return 0;1149 1150	if (vb2_is_busy(&dev->vb_vid_cap_q) ||1151	    vb2_is_busy(&dev->vb_vbi_cap_q) ||1152	    vb2_is_busy(&dev->vb_meta_cap_q))1153		return -EBUSY;1154 1155	dev->input = i;1156	dev->vid_cap_dev.tvnorms = 0;1157	if (dev->input_type[i] == TV || dev->input_type[i] == SVID) {1158		dev->tv_audio_input = (dev->input_type[i] == TV) ? 0 : 1;1159		dev->vid_cap_dev.tvnorms = V4L2_STD_ALL;1160	}1161	dev->vbi_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;1162	dev->meta_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;1163	vivid_update_format_cap(dev, false);1164 1165	if (dev->colorspace) {1166		switch (dev->input_type[i]) {1167		case WEBCAM:1168			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);1169			break;1170		case TV:1171		case SVID:1172			v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);1173			break;1174		case HDMI:1175			if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {1176				if (dev->src_rect.width == 720 && dev->src_rect.height <= 576)1177					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);1178				else1179					v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709);1180			} else {1181				v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB);1182			}1183			break;1184		}1185	}1186 1187	/*1188	 * Modify the brightness range depending on the input.1189	 * This makes it easy to use vivid to test if applications can1190	 * handle control range modifications and is also how this is1191	 * typically used in practice as different inputs may be hooked1192	 * up to different receivers with different control ranges.1193	 */1194	brightness = 128 * i + dev->input_brightness[i];1195	v4l2_ctrl_modify_range(dev->brightness,1196			128 * i, 255 + 128 * i, 1, 128 + 128 * i);1197	v4l2_ctrl_s_ctrl(dev->brightness, brightness);1198 1199	/* Restore per-input states. */1200	v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode,1201			   vivid_is_hdmi_cap(dev));1202	v4l2_ctrl_activate(dev->ctrl_dv_timings, vivid_is_hdmi_cap(dev) &&1203			   dev->dv_timings_signal_mode[dev->input] ==1204			   SELECTED_DV_TIMINGS);1205	v4l2_ctrl_activate(dev->ctrl_std_signal_mode, vivid_is_sdtv_cap(dev));1206	v4l2_ctrl_activate(dev->ctrl_standard, vivid_is_sdtv_cap(dev) &&1207			   dev->std_signal_mode[dev->input]);1208 1209	if (vivid_is_hdmi_cap(dev)) {1210		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings_signal_mode,1211				 dev->dv_timings_signal_mode[dev->input]);1212		v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings,1213				 dev->query_dv_timings[dev->input]);1214	} else if (vivid_is_sdtv_cap(dev)) {1215		v4l2_ctrl_s_ctrl(dev->ctrl_std_signal_mode,1216				 dev->std_signal_mode[dev->input]);1217		v4l2_ctrl_s_ctrl(dev->ctrl_standard,1218				 dev->std_signal_mode[dev->input]);1219	}1220 1221	return 0;1222}1223 1224int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)1225{1226	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))1227		return -EINVAL;1228	*vin = vivid_audio_inputs[vin->index];1229	return 0;1230}1231 1232int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)1233{1234	struct vivid_dev *dev = video_drvdata(file);1235 1236	if (!vivid_is_sdtv_cap(dev))1237		return -EINVAL;1238	*vin = vivid_audio_inputs[dev->tv_audio_input];1239	return 0;1240}1241 1242int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin)1243{1244	struct vivid_dev *dev = video_drvdata(file);1245 1246	if (!vivid_is_sdtv_cap(dev))1247		return -EINVAL;1248	if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))1249		return -EINVAL;1250	dev->tv_audio_input = vin->index;1251	return 0;1252}1253 1254int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)1255{1256	struct vivid_dev *dev = video_drvdata(file);1257 1258	if (vf->tuner != 0)1259		return -EINVAL;1260	vf->frequency = dev->tv_freq;1261	return 0;1262}1263 1264int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)1265{1266	struct vivid_dev *dev = video_drvdata(file);1267 1268	if (vf->tuner != 0)1269		return -EINVAL;1270	dev->tv_freq = clamp_t(unsigned, vf->frequency, MIN_TV_FREQ, MAX_TV_FREQ);1271	if (vivid_is_tv_cap(dev))1272		vivid_update_quality(dev);1273	return 0;1274}1275 1276int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)1277{1278	struct vivid_dev *dev = video_drvdata(file);1279 1280	if (vt->index != 0)1281		return -EINVAL;1282	if (vt->audmode > V4L2_TUNER_MODE_LANG1_LANG2)1283		return -EINVAL;1284	dev->tv_audmode = vt->audmode;1285	return 0;1286}1287 1288int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)1289{1290	struct vivid_dev *dev = video_drvdata(file);1291	enum tpg_quality qual;1292 1293	if (vt->index != 0)1294		return -EINVAL;1295 1296	vt->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |1297			 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;1298	vt->audmode = dev->tv_audmode;1299	vt->rangelow = MIN_TV_FREQ;1300	vt->rangehigh = MAX_TV_FREQ;1301	qual = vivid_get_quality(dev, &vt->afc);1302	if (qual == TPG_QUAL_COLOR)1303		vt->signal = 0xffff;1304	else if (qual == TPG_QUAL_GRAY)1305		vt->signal = 0x8000;1306	else1307		vt->signal = 0;1308	if (qual == TPG_QUAL_NOISE) {1309		vt->rxsubchans = 0;1310	} else if (qual == TPG_QUAL_GRAY) {1311		vt->rxsubchans = V4L2_TUNER_SUB_MONO;1312	} else {1313		unsigned int channel_nr = dev->tv_freq / (6 * 16);1314		unsigned int options =1315			(dev->std_cap[dev->input] & V4L2_STD_NTSC_M) ? 4 : 3;1316 1317		switch (channel_nr % options) {1318		case 0:1319			vt->rxsubchans = V4L2_TUNER_SUB_MONO;1320			break;1321		case 1:1322			vt->rxsubchans = V4L2_TUNER_SUB_STEREO;1323			break;1324		case 2:1325			if (dev->std_cap[dev->input] & V4L2_STD_NTSC_M)1326				vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP;1327			else1328				vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;1329			break;1330		case 3:1331			vt->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_SAP;1332			break;1333		}1334	}1335	strscpy(vt->name, "TV Tuner", sizeof(vt->name));1336	return 0;1337}1338 1339/* Must remain in sync with the vivid_ctrl_standard_strings array */1340const v4l2_std_id vivid_standard[] = {1341	V4L2_STD_NTSC_M,1342	V4L2_STD_NTSC_M_JP,1343	V4L2_STD_NTSC_M_KR,1344	V4L2_STD_NTSC_443,1345	V4L2_STD_PAL_BG | V4L2_STD_PAL_H,1346	V4L2_STD_PAL_I,1347	V4L2_STD_PAL_DK,1348	V4L2_STD_PAL_M,1349	V4L2_STD_PAL_N,1350	V4L2_STD_PAL_Nc,1351	V4L2_STD_PAL_60,1352	V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,1353	V4L2_STD_SECAM_DK,1354	V4L2_STD_SECAM_L,1355	V4L2_STD_SECAM_LC,1356	V4L2_STD_UNKNOWN1357};1358 1359/* Must remain in sync with the vivid_standard array */1360const char * const vivid_ctrl_standard_strings[] = {1361	"NTSC-M",1362	"NTSC-M-JP",1363	"NTSC-M-KR",1364	"NTSC-443",1365	"PAL-BGH",1366	"PAL-I",1367	"PAL-DK",1368	"PAL-M",1369	"PAL-N",1370	"PAL-Nc",1371	"PAL-60",1372	"SECAM-BGH",1373	"SECAM-DK",1374	"SECAM-L",1375	"SECAM-Lc",1376	NULL,1377};1378 1379int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id)1380{1381	struct vivid_dev *dev = video_drvdata(file);1382	unsigned int last = dev->query_std_last[dev->input];1383 1384	if (!vivid_is_sdtv_cap(dev))1385		return -ENODATA;1386	if (dev->std_signal_mode[dev->input] == NO_SIGNAL ||1387	    dev->std_signal_mode[dev->input] == NO_LOCK) {1388		*id = V4L2_STD_UNKNOWN;1389		return 0;1390	}1391	if (vivid_is_tv_cap(dev) && tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE) {1392		*id = V4L2_STD_UNKNOWN;1393	} else if (dev->std_signal_mode[dev->input] == CURRENT_STD) {1394		*id = dev->std_cap[dev->input];1395	} else if (dev->std_signal_mode[dev->input] == SELECTED_STD) {1396		*id = dev->query_std[dev->input];1397	} else {1398		*id = vivid_standard[last];1399		dev->query_std_last[dev->input] =1400			(last + 1) % ARRAY_SIZE(vivid_standard);1401	}1402 1403	return 0;1404}1405 1406int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id)1407{1408	struct vivid_dev *dev = video_drvdata(file);1409 1410	if (!vivid_is_sdtv_cap(dev))1411		return -ENODATA;1412	if (dev->std_cap[dev->input] == id)1413		return 0;1414	if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q))1415		return -EBUSY;1416	dev->std_cap[dev->input] = id;1417	vivid_update_format_cap(dev, false);1418	return 0;1419}1420 1421static void find_aspect_ratio(u32 width, u32 height,1422			       u32 *num, u32 *denom)1423{1424	if (!(height % 3) && ((height * 4 / 3) == width)) {1425		*num = 4;1426		*denom = 3;1427	} else if (!(height % 9) && ((height * 16 / 9) == width)) {1428		*num = 16;1429		*denom = 9;1430	} else if (!(height % 10) && ((height * 16 / 10) == width)) {1431		*num = 16;1432		*denom = 10;1433	} else if (!(height % 4) && ((height * 5 / 4) == width)) {1434		*num = 5;1435		*denom = 4;1436	} else if (!(height % 9) && ((height * 15 / 9) == width)) {1437		*num = 15;1438		*denom = 9;1439	} else { /* default to 16:9 */1440		*num = 16;1441		*denom = 9;1442	}1443}1444 1445static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)1446{1447	struct v4l2_bt_timings *bt = &timings->bt;1448	u32 total_h_pixel;1449	u32 total_v_lines;1450	u32 h_freq;1451 1452	if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap,1453				NULL, NULL))1454		return false;1455 1456	total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt);1457	total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt);1458 1459	h_freq = (u32)bt->pixelclock / total_h_pixel;1460 1461	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {1462		if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width,1463				    bt->polarities, bt->interlaced, timings))1464			return true;1465	}1466 1467	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {1468		struct v4l2_fract aspect_ratio;1469 1470		find_aspect_ratio(bt->width, bt->height,1471				  &aspect_ratio.numerator,1472				  &aspect_ratio.denominator);1473		if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,1474				    bt->polarities, bt->interlaced,1475				    aspect_ratio, timings))1476			return true;1477	}1478	return false;1479}1480 1481int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,1482				    struct v4l2_dv_timings *timings)1483{1484	struct vivid_dev *dev = video_drvdata(file);1485 1486	if (!vivid_is_hdmi_cap(dev))1487		return -ENODATA;1488	if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,1489				      0, NULL, NULL) &&1490	    !valid_cvt_gtf_timings(timings))1491		return -EINVAL;1492 1493	if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap[dev->input],1494				  0, false))1495		return 0;1496	if (vb2_is_busy(&dev->vb_vid_cap_q))1497		return -EBUSY;1498 1499	dev->dv_timings_cap[dev->input] = *timings;1500	vivid_update_format_cap(dev, false);1501	return 0;1502}1503 1504int vidioc_query_dv_timings(struct file *file, void *_fh,1505				    struct v4l2_dv_timings *timings)1506{1507	struct vivid_dev *dev = video_drvdata(file);1508	unsigned int input = dev->input;1509	unsigned int last = dev->query_dv_timings_last[input];1510 1511	if (!vivid_is_hdmi_cap(dev))1512		return -ENODATA;1513	if (dev->dv_timings_signal_mode[input] == NO_SIGNAL ||1514	    dev->edid_blocks == 0)1515		return -ENOLINK;1516	if (dev->dv_timings_signal_mode[input] == NO_LOCK)1517		return -ENOLCK;1518	if (dev->dv_timings_signal_mode[input] == OUT_OF_RANGE) {1519		timings->bt.pixelclock = vivid_dv_timings_cap.bt.max_pixelclock * 2;1520		return -ERANGE;1521	}1522	if (dev->dv_timings_signal_mode[input] == CURRENT_DV_TIMINGS) {1523		*timings = dev->dv_timings_cap[input];1524	} else if (dev->dv_timings_signal_mode[input] ==1525		   SELECTED_DV_TIMINGS) {1526		*timings =1527			v4l2_dv_timings_presets[dev->query_dv_timings[input]];1528	} else {1529		*timings =1530			v4l2_dv_timings_presets[last];1531		dev->query_dv_timings_last[input] =1532			(last + 1) % dev->query_dv_timings_size;1533	}1534	return 0;1535}1536 1537void vivid_update_outputs(struct vivid_dev *dev)1538{1539	u32 edid_present = 0;1540 1541	if (!dev || !dev->num_outputs)1542		return;1543	for (unsigned int i = 0, j = 0; i < dev->num_outputs; i++) {1544		if (dev->output_type[i] != HDMI)1545			continue;1546 1547		struct vivid_dev *dev_rx = dev->output_to_input_instance[i];1548 1549		if (dev_rx && dev_rx->edid_blocks)1550			edid_present |= 1 << j;1551		j++;1552	}1553	v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, edid_present);1554	v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, edid_present);1555	v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, edid_present);1556}1557 1558void vivid_update_connected_outputs(struct vivid_dev *dev)1559{1560	u16 phys_addr = cec_get_edid_phys_addr(dev->edid, dev->edid_blocks * 128, NULL);1561 1562	for (unsigned int i = 0, j = 0; i < dev->num_inputs; i++) {1563		unsigned int menu_idx =1564			dev->input_is_connected_to_output[i];1565 1566		if (dev->input_type[i] != HDMI)1567			continue;1568		j++;1569		if (menu_idx < FIXED_MENU_ITEMS)1570			continue;1571 1572		struct vivid_dev *dev_tx = vivid_ctrl_hdmi_to_output_instance[menu_idx];1573		unsigned int output = vivid_ctrl_hdmi_to_output_index[menu_idx];1574 1575		if (!dev_tx)1576			continue;1577 1578		unsigned int hdmi_output = dev_tx->output_to_iface_index[output];1579 1580		vivid_update_outputs(dev_tx);1581		if (dev->edid_blocks) {1582			cec_s_phys_addr(dev_tx->cec_tx_adap[hdmi_output],1583					v4l2_phys_addr_for_input(phys_addr, j),1584					false);1585		} else {1586			cec_phys_addr_invalidate(dev_tx->cec_tx_adap[hdmi_output]);1587		}1588	}1589}1590 1591int vidioc_s_edid(struct file *file, void *_fh,1592			 struct v4l2_edid *edid)1593{1594	struct vivid_dev *dev = video_drvdata(file);1595	u16 phys_addr;1596	int ret;1597 1598	memset(edid->reserved, 0, sizeof(edid->reserved));1599	if (edid->pad >= dev->num_inputs)1600		return -EINVAL;1601	if (dev->input_type[edid->pad] != HDMI || edid->start_block)1602		return -EINVAL;1603	if (edid->blocks == 0) {1604		if (vb2_is_busy(&dev->vb_vid_cap_q))1605			return -EBUSY;1606		dev->edid_blocks = 0;1607		vivid_update_connected_outputs(dev);1608		return 0;1609	}1610	if (edid->blocks > dev->edid_max_blocks) {1611		edid->blocks = dev->edid_max_blocks;1612		return -E2BIG;1613	}1614	phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);1615	ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL);1616	if (ret)1617		return ret;1618 1619	if (vb2_is_busy(&dev->vb_vid_cap_q))1620		return -EBUSY;1621 1622	dev->edid_blocks = edid->blocks;1623	memcpy(dev->edid, edid->edid, edid->blocks * 128);1624 1625	vivid_update_connected_outputs(dev);1626	return 0;1627}1628 1629int vidioc_enum_framesizes(struct file *file, void *fh,1630					 struct v4l2_frmsizeenum *fsize)1631{1632	struct vivid_dev *dev = video_drvdata(file);1633 1634	if (!vivid_is_webcam(dev) && !dev->has_scaler_cap)1635		return -EINVAL;1636	if (vivid_get_format(dev, fsize->pixel_format) == NULL)1637		return -EINVAL;1638	if (vivid_is_webcam(dev)) {1639		if (fsize->index >= ARRAY_SIZE(webcam_sizes))1640			return -EINVAL;1641		fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;1642		fsize->discrete = webcam_sizes[fsize->index];1643		return 0;1644	}1645	if (fsize->index)1646		return -EINVAL;1647	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;1648	fsize->stepwise.min_width = MIN_WIDTH;1649	fsize->stepwise.max_width = MAX_WIDTH * MAX_ZOOM;1650	fsize->stepwise.step_width = 2;1651	fsize->stepwise.min_height = MIN_HEIGHT;1652	fsize->stepwise.max_height = MAX_HEIGHT * MAX_ZOOM;1653	fsize->stepwise.step_height = 2;1654	return 0;1655}1656 1657/* timeperframe is arbitrary and continuous */1658int vidioc_enum_frameintervals(struct file *file, void *priv,1659					     struct v4l2_frmivalenum *fival)1660{1661	struct vivid_dev *dev = video_drvdata(file);1662	const struct vivid_fmt *fmt;1663	int i;1664 1665	fmt = vivid_get_format(dev, fival->pixel_format);1666	if (!fmt)1667		return -EINVAL;1668 1669	if (!vivid_is_webcam(dev)) {1670		if (fival->index)1671			return -EINVAL;1672		if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM)1673			return -EINVAL;1674		if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM)1675			return -EINVAL;1676		fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;1677		fival->discrete = dev->timeperframe_vid_cap;1678		return 0;1679	}1680 1681	for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++)1682		if (fival->width == webcam_sizes[i].width &&1683		    fival->height == webcam_sizes[i].height)1684			break;1685	if (i == ARRAY_SIZE(webcam_sizes))1686		return -EINVAL;1687	if (fival->index >= webcam_ival_count(dev, i))1688		return -EINVAL;1689	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;1690	fival->discrete = webcam_intervals[fival->index];1691	return 0;1692}1693 1694int vivid_vid_cap_g_parm(struct file *file, void *priv,1695			  struct v4l2_streamparm *parm)1696{1697	struct vivid_dev *dev = video_drvdata(file);1698 1699	if (parm->type != (dev->multiplanar ?1700			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :1701			   V4L2_BUF_TYPE_VIDEO_CAPTURE))1702		return -EINVAL;1703 1704	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;1705	parm->parm.capture.timeperframe = dev->timeperframe_vid_cap;1706	parm->parm.capture.readbuffers  = 1;1707	return 0;1708}1709 1710int vivid_vid_cap_s_parm(struct file *file, void *priv,1711			  struct v4l2_streamparm *parm)1712{1713	struct vivid_dev *dev = video_drvdata(file);1714	unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx);1715	struct v4l2_fract tpf;1716	unsigned i;1717 1718	if (parm->type != (dev->multiplanar ?1719			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :1720			   V4L2_BUF_TYPE_VIDEO_CAPTURE))1721		return -EINVAL;1722	if (!vivid_is_webcam(dev))1723		return vivid_vid_cap_g_parm(file, priv, parm);1724 1725	tpf = parm->parm.capture.timeperframe;1726 1727	if (tpf.denominator == 0)1728		tpf = webcam_intervals[ival_sz - 1];1729	for (i = 0; i < ival_sz; i++)1730		if (V4L2_FRACT_COMPARE(tpf, >=, webcam_intervals[i]))1731			break;1732	if (i == ival_sz)1733		i = ival_sz - 1;1734	dev->webcam_ival_idx = i;1735	tpf = webcam_intervals[dev->webcam_ival_idx];1736 1737	/* resync the thread's timings */1738	dev->cap_seq_resync = true;1739	dev->timeperframe_vid_cap = tpf;1740	parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;1741	parm->parm.capture.timeperframe = tpf;1742	parm->parm.capture.readbuffers  = 1;1743	return 0;1744}1745