brintos

brintos / linux-shallow public Read only

0
0
Text · 25.8 KiB · 702f1c8 Raw
971 lines · c
1/*2 * Copyright (c) 2013,2016 Lubomir Rintel3 * All rights reserved.4 *5 * Redistribution and use in source and binary forms, with or without6 * modification, are permitted provided that the following conditions7 * are met:8 * 1. Redistributions of source code must retain the above copyright9 *    notice, this list of conditions, and the following disclaimer,10 *    without modification.11 * 2. The name of the author may not be used to endorse or promote products12 *    derived from this software without specific prior written permission.13 *14 * Alternatively, this software may be distributed under the terms of the15 * GNU General Public License ("GPL").16 *17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.28 */29/*30 * Fushicai USBTV007 Audio-Video Grabber Driver31 *32 * Product web site:33 * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html34 *35 * Following LWN articles were very useful in construction of this driver:36 * Video4Linux2 API series: http://lwn.net/Articles/203924/37 * videobuf2 API explanation: http://lwn.net/Articles/447435/38 * Thanks go to Jonathan Corbet for providing this quality documentation.39 * He is awesome.40 *41 * No physical hardware was harmed running Windows during the42 * reverse-engineering activity43 */44 45#include <media/v4l2-ioctl.h>46#include <media/videobuf2-v4l2.h>47 48#include "usbtv.h"49 50static const struct usbtv_norm_params norm_params[] = {51	{52		.norm = V4L2_STD_525_60,53		.cap_width = 720,54		.cap_height = 480,55	},56	{57		.norm = V4L2_STD_625_50,58		.cap_width = 720,59		.cap_height = 576,60	}61};62 63static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm)64{65	int i, ret = 0;66	const struct usbtv_norm_params *params = NULL;67 68	for (i = 0; i < ARRAY_SIZE(norm_params); i++) {69		if (norm_params[i].norm & norm) {70			params = &norm_params[i];71			break;72		}73	}74 75	if (params) {76		usbtv->width = params->cap_width;77		usbtv->height = params->cap_height;78		usbtv->n_chunks = usbtv->width * usbtv->height79						/ 4 / USBTV_CHUNK;80		usbtv->norm = norm;81	} else82		ret = -EINVAL;83 84	return ret;85}86 87static int usbtv_select_input(struct usbtv *usbtv, int input)88{89	int ret;90 91	static const u16 composite[][2] = {92		{ USBTV_BASE + 0x0105, 0x0060 },93		{ USBTV_BASE + 0x011f, 0x00f2 },94		{ USBTV_BASE + 0x0127, 0x0060 },95		{ USBTV_BASE + 0x00ae, 0x0010 },96		{ USBTV_BASE + 0x0239, 0x0060 },97	};98 99	static const u16 svideo[][2] = {100		{ USBTV_BASE + 0x0105, 0x0010 },101		{ USBTV_BASE + 0x011f, 0x00ff },102		{ USBTV_BASE + 0x0127, 0x0060 },103		{ USBTV_BASE + 0x00ae, 0x0030 },104		{ USBTV_BASE + 0x0239, 0x0060 },105	};106 107	switch (input) {108	case USBTV_COMPOSITE_INPUT:109		ret = usbtv_set_regs(usbtv, composite, ARRAY_SIZE(composite));110		break;111	case USBTV_SVIDEO_INPUT:112		ret = usbtv_set_regs(usbtv, svideo, ARRAY_SIZE(svideo));113		break;114	default:115		ret = -EINVAL;116	}117 118	if (!ret)119		usbtv->input = input;120 121	return ret;122}123 124static uint16_t usbtv_norm_to_16f_reg(v4l2_std_id norm)125{126	/* NTSC M/M-JP/M-KR */127	if (norm & V4L2_STD_NTSC)128		return 0x00b8;129	/* PAL BG/DK/H/I */130	if (norm & V4L2_STD_PAL)131		return 0x00ee;132	/* SECAM B/D/G/H/K/K1/L/Lc */133	if (norm & V4L2_STD_SECAM)134		return 0x00ff;135	if (norm & V4L2_STD_NTSC_443)136		return 0x00a8;137	if (norm & (V4L2_STD_PAL_M | V4L2_STD_PAL_60))138		return 0x00bc;139	if (norm & V4L2_STD_PAL_Nc)140		return 0x00fe;141	/* Fallback to automatic detection for other standards */142	return 0x0000;143}144 145static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm)146{147	int ret;148	/* These are the series of register values used to configure the149	 * decoder for a specific standard.150	 * The first 21 register writes are copied from the151	 * Settings\DecoderDefaults registry keys present in the Windows driver152	 * .INF file, and control various image tuning parameters (color153	 * correction, sharpness, ...).154	 */155	static const u16 pal[][2] = {156		/* "AVPAL" tuning sequence from .INF file */157		{ USBTV_BASE + 0x0003, 0x0004 },158		{ USBTV_BASE + 0x001a, 0x0068 },159		{ USBTV_BASE + 0x0100, 0x00d3 },160		{ USBTV_BASE + 0x010e, 0x0072 },161		{ USBTV_BASE + 0x010f, 0x00a2 },162		{ USBTV_BASE + 0x0112, 0x00b0 },163		{ USBTV_BASE + 0x0115, 0x0015 },164		{ USBTV_BASE + 0x0117, 0x0001 },165		{ USBTV_BASE + 0x0118, 0x002c },166		{ USBTV_BASE + 0x012d, 0x0010 },167		{ USBTV_BASE + 0x012f, 0x0020 },168		{ USBTV_BASE + 0x0220, 0x002e },169		{ USBTV_BASE + 0x0225, 0x0008 },170		{ USBTV_BASE + 0x024e, 0x0002 },171		{ USBTV_BASE + 0x024f, 0x0002 },172		{ USBTV_BASE + 0x0254, 0x0059 },173		{ USBTV_BASE + 0x025a, 0x0016 },174		{ USBTV_BASE + 0x025b, 0x0035 },175		{ USBTV_BASE + 0x0263, 0x0017 },176		{ USBTV_BASE + 0x0266, 0x0016 },177		{ USBTV_BASE + 0x0267, 0x0036 },178		/* End image tuning */179		{ USBTV_BASE + 0x024e, 0x0002 },180		{ USBTV_BASE + 0x024f, 0x0002 },181	};182 183	static const u16 ntsc[][2] = {184		/* "AVNTSC" tuning sequence from .INF file */185		{ USBTV_BASE + 0x0003, 0x0004 },186		{ USBTV_BASE + 0x001a, 0x0079 },187		{ USBTV_BASE + 0x0100, 0x00d3 },188		{ USBTV_BASE + 0x010e, 0x0068 },189		{ USBTV_BASE + 0x010f, 0x009c },190		{ USBTV_BASE + 0x0112, 0x00f0 },191		{ USBTV_BASE + 0x0115, 0x0015 },192		{ USBTV_BASE + 0x0117, 0x0000 },193		{ USBTV_BASE + 0x0118, 0x00fc },194		{ USBTV_BASE + 0x012d, 0x0004 },195		{ USBTV_BASE + 0x012f, 0x0008 },196		{ USBTV_BASE + 0x0220, 0x002e },197		{ USBTV_BASE + 0x0225, 0x0008 },198		{ USBTV_BASE + 0x024e, 0x0002 },199		{ USBTV_BASE + 0x024f, 0x0001 },200		{ USBTV_BASE + 0x0254, 0x005f },201		{ USBTV_BASE + 0x025a, 0x0012 },202		{ USBTV_BASE + 0x025b, 0x0001 },203		{ USBTV_BASE + 0x0263, 0x001c },204		{ USBTV_BASE + 0x0266, 0x0011 },205		{ USBTV_BASE + 0x0267, 0x0005 },206		/* End image tuning */207		{ USBTV_BASE + 0x024e, 0x0002 },208		{ USBTV_BASE + 0x024f, 0x0002 },209	};210 211	static const u16 secam[][2] = {212		/* "AVSECAM" tuning sequence from .INF file */213		{ USBTV_BASE + 0x0003, 0x0004 },214		{ USBTV_BASE + 0x001a, 0x0073 },215		{ USBTV_BASE + 0x0100, 0x00dc },216		{ USBTV_BASE + 0x010e, 0x0072 },217		{ USBTV_BASE + 0x010f, 0x00a2 },218		{ USBTV_BASE + 0x0112, 0x0090 },219		{ USBTV_BASE + 0x0115, 0x0035 },220		{ USBTV_BASE + 0x0117, 0x0001 },221		{ USBTV_BASE + 0x0118, 0x0030 },222		{ USBTV_BASE + 0x012d, 0x0004 },223		{ USBTV_BASE + 0x012f, 0x0008 },224		{ USBTV_BASE + 0x0220, 0x002d },225		{ USBTV_BASE + 0x0225, 0x0028 },226		{ USBTV_BASE + 0x024e, 0x0008 },227		{ USBTV_BASE + 0x024f, 0x0002 },228		{ USBTV_BASE + 0x0254, 0x0069 },229		{ USBTV_BASE + 0x025a, 0x0016 },230		{ USBTV_BASE + 0x025b, 0x0035 },231		{ USBTV_BASE + 0x0263, 0x0021 },232		{ USBTV_BASE + 0x0266, 0x0016 },233		{ USBTV_BASE + 0x0267, 0x0036 },234		/* End image tuning */235		{ USBTV_BASE + 0x024e, 0x0002 },236		{ USBTV_BASE + 0x024f, 0x0002 },237	};238 239	ret = usbtv_configure_for_norm(usbtv, norm);240 241	if (!ret) {242		/* Masks for norms using a NTSC or PAL color encoding. */243		static const v4l2_std_id ntsc_mask =244			V4L2_STD_NTSC | V4L2_STD_NTSC_443;245		static const v4l2_std_id pal_mask =246			V4L2_STD_PAL | V4L2_STD_PAL_60 | V4L2_STD_PAL_M |247			V4L2_STD_PAL_Nc;248 249		if (norm & ntsc_mask)250			ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc));251		else if (norm & pal_mask)252			ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal));253		else if (norm & V4L2_STD_SECAM)254			ret = usbtv_set_regs(usbtv, secam, ARRAY_SIZE(secam));255		else256			ret = -EINVAL;257	}258 259	if (!ret) {260		/* Configure the decoder for the color standard */261		const u16 cfg[][2] = {262			{ USBTV_BASE + 0x016f, usbtv_norm_to_16f_reg(norm) }263		};264		ret = usbtv_set_regs(usbtv, cfg, ARRAY_SIZE(cfg));265	}266 267	return ret;268}269 270static int usbtv_setup_capture(struct usbtv *usbtv)271{272	int ret;273	static const u16 setup[][2] = {274		/* These seem to enable the device. */275		{ USBTV_BASE + 0x0008, 0x0001 },276		{ USBTV_BASE + 0x01d0, 0x00ff },277		{ USBTV_BASE + 0x01d9, 0x0002 },278 279		/* These seem to influence color parameters, such as280		 * brightness, etc. */281		{ USBTV_BASE + 0x0239, 0x0040 },282		{ USBTV_BASE + 0x0240, 0x0000 },283		{ USBTV_BASE + 0x0241, 0x0000 },284		{ USBTV_BASE + 0x0242, 0x0002 },285		{ USBTV_BASE + 0x0243, 0x0080 },286		{ USBTV_BASE + 0x0244, 0x0012 },287		{ USBTV_BASE + 0x0245, 0x0090 },288		{ USBTV_BASE + 0x0246, 0x0000 },289 290		{ USBTV_BASE + 0x0278, 0x002d },291		{ USBTV_BASE + 0x0279, 0x000a },292		{ USBTV_BASE + 0x027a, 0x0032 },293		{ 0xf890, 0x000c },294		{ 0xf894, 0x0086 },295 296		{ USBTV_BASE + 0x00ac, 0x00c0 },297		{ USBTV_BASE + 0x00ad, 0x0000 },298		{ USBTV_BASE + 0x00a2, 0x0012 },299		{ USBTV_BASE + 0x00a3, 0x00e0 },300		{ USBTV_BASE + 0x00a4, 0x0028 },301		{ USBTV_BASE + 0x00a5, 0x0082 },302		{ USBTV_BASE + 0x00a7, 0x0080 },303		{ USBTV_BASE + 0x0000, 0x0014 },304		{ USBTV_BASE + 0x0006, 0x0003 },305		{ USBTV_BASE + 0x0090, 0x0099 },306		{ USBTV_BASE + 0x0091, 0x0090 },307		{ USBTV_BASE + 0x0094, 0x0068 },308		{ USBTV_BASE + 0x0095, 0x0070 },309		{ USBTV_BASE + 0x009c, 0x0030 },310		{ USBTV_BASE + 0x009d, 0x00c0 },311		{ USBTV_BASE + 0x009e, 0x00e0 },312		{ USBTV_BASE + 0x0019, 0x0006 },313		{ USBTV_BASE + 0x008c, 0x00ba },314		{ USBTV_BASE + 0x0101, 0x00ff },315		{ USBTV_BASE + 0x010c, 0x00b3 },316		{ USBTV_BASE + 0x01b2, 0x0080 },317		{ USBTV_BASE + 0x01b4, 0x00a0 },318		{ USBTV_BASE + 0x014c, 0x00ff },319		{ USBTV_BASE + 0x014d, 0x00ca },320		{ USBTV_BASE + 0x0113, 0x0053 },321		{ USBTV_BASE + 0x0119, 0x008a },322		{ USBTV_BASE + 0x013c, 0x0003 },323		{ USBTV_BASE + 0x0150, 0x009c },324		{ USBTV_BASE + 0x0151, 0x0071 },325		{ USBTV_BASE + 0x0152, 0x00c6 },326		{ USBTV_BASE + 0x0153, 0x0084 },327		{ USBTV_BASE + 0x0154, 0x00bc },328		{ USBTV_BASE + 0x0155, 0x00a0 },329		{ USBTV_BASE + 0x0156, 0x00a0 },330		{ USBTV_BASE + 0x0157, 0x009c },331		{ USBTV_BASE + 0x0158, 0x001f },332		{ USBTV_BASE + 0x0159, 0x0006 },333		{ USBTV_BASE + 0x015d, 0x0000 },334	};335 336	ret = usbtv_set_regs(usbtv, setup, ARRAY_SIZE(setup));337	if (ret)338		return ret;339 340	ret = usbtv_select_norm(usbtv, usbtv->norm);341	if (ret)342		return ret;343 344	ret = usbtv_select_input(usbtv, usbtv->input);345	if (ret)346		return ret;347 348	ret = v4l2_ctrl_handler_setup(&usbtv->ctrl);349	if (ret)350		return ret;351 352	return 0;353}354 355/* Copy data from chunk into a frame buffer, deinterlacing the data356 * into every second line. Unfortunately, they don't align nicely into357 * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.358 * Therefore, we break down the chunk into two halves before copying,359 * so that we can interleave a line if needed.360 *361 * Each "chunk" is 240 words; a word in this context equals 4 bytes.362 * Image format is YUYV/YUV 4:2:2, consisting of Y Cr Y Cb, defining two363 * pixels, the Cr and Cb shared between the two pixels, but each having364 * separate Y values. Thus, the 240 words equal 480 pixels. It therefore,365 * takes 1.5 chunks to make a 720 pixel-wide line for the frame.366 * The image is interlaced, so there is a "scan" of odd lines, followed367 * by "scan" of even numbered lines.368 *369 * Following code is writing the chunks in correct sequence, skipping370 * the rows based on "odd" value.371 * line 1: chunk[0][  0..479] chunk[0][480..959] chunk[1][  0..479]372 * line 3: chunk[1][480..959] chunk[2][  0..479] chunk[2][480..959]373 * ...etc.374 */375static void usbtv_chunk_to_vbuf(u32 *frame, __be32 *src, int chunk_no, int odd)376{377	int half;378 379	for (half = 0; half < 2; half++) {380		int part_no = chunk_no * 2 + half;381		int line = part_no / 3;382		int part_index = (line * 2 + !odd) * 3 + (part_no % 3);383 384		u32 *dst = &frame[part_index * USBTV_CHUNK/2];385 386		memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src));387		src += USBTV_CHUNK/2;388	}389}390 391/* Called for each 256-byte image chunk.392 * First word identifies the chunk, followed by 240 words of image393 * data and padding. */394static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)395{396	int frame_id, odd, chunk_no;397	u32 *frame;398	struct usbtv_buf *buf;399	unsigned long flags;400 401	/* Ignore corrupted lines. */402	if (!USBTV_MAGIC_OK(chunk))403		return;404	frame_id = USBTV_FRAME_ID(chunk);405	odd = USBTV_ODD(chunk);406	chunk_no = USBTV_CHUNK_NO(chunk);407	if (chunk_no >= usbtv->n_chunks)408		return;409 410	/* Beginning of a frame. */411	if (chunk_no == 0) {412		usbtv->frame_id = frame_id;413		usbtv->chunks_done = 0;414	}415 416	if (usbtv->frame_id != frame_id)417		return;418 419	spin_lock_irqsave(&usbtv->buflock, flags);420	if (list_empty(&usbtv->bufs)) {421		/* No free buffers. Userspace likely too slow. */422		spin_unlock_irqrestore(&usbtv->buflock, flags);423		return;424	}425 426	/* First available buffer. */427	buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);428	frame = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);429 430	/* Copy the chunk data. */431	usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);432	usbtv->chunks_done++;433 434	/* Last chunk in a field */435	if (chunk_no == usbtv->n_chunks-1) {436		/* Last chunk in a frame, signalling an end */437		if (odd && !usbtv->last_odd) {438			int size = vb2_plane_size(&buf->vb.vb2_buf, 0);439			enum vb2_buffer_state state = usbtv->chunks_done ==440				usbtv->n_chunks ?441				VB2_BUF_STATE_DONE :442				VB2_BUF_STATE_ERROR;443 444			buf->vb.field = V4L2_FIELD_INTERLACED;445			buf->vb.sequence = usbtv->sequence++;446			buf->vb.vb2_buf.timestamp = ktime_get_ns();447			vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);448			vb2_buffer_done(&buf->vb.vb2_buf, state);449			list_del(&buf->list);450		}451		usbtv->last_odd = odd;452	}453 454	spin_unlock_irqrestore(&usbtv->buflock, flags);455}456 457/* Got image data. Each packet contains a number of 256-word chunks we458 * compose the image from. */459static void usbtv_iso_cb(struct urb *ip)460{461	int ret;462	int i;463	struct usbtv *usbtv = (struct usbtv *)ip->context;464 465	switch (ip->status) {466	/* All fine. */467	case 0:468		break;469	/* Device disconnected or capture stopped? */470	case -ENODEV:471	case -ENOENT:472	case -ECONNRESET:473	case -ESHUTDOWN:474		return;475	/* Unknown error. Retry. */476	default:477		dev_warn(usbtv->dev, "Bad response for ISO request.\n");478		goto resubmit;479	}480 481	for (i = 0; i < ip->number_of_packets; i++) {482		int size = ip->iso_frame_desc[i].actual_length;483		unsigned char *data = ip->transfer_buffer +484				ip->iso_frame_desc[i].offset;485		int offset;486 487		for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)488			usbtv_image_chunk(usbtv,489				(__be32 *)&data[USBTV_CHUNK_SIZE * offset]);490	}491 492resubmit:493	ret = usb_submit_urb(ip, GFP_ATOMIC);494	if (ret < 0)495		dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");496}497 498static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)499{500	struct urb *ip;501	int size = usbtv->iso_size;502	int i;503 504	ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);505	if (ip == NULL)506		return NULL;507 508	ip->dev = usbtv->udev;509	ip->context = usbtv;510	ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);511	ip->interval = 1;512	ip->transfer_flags = URB_ISO_ASAP;513	ip->transfer_buffer = kcalloc(USBTV_ISOC_PACKETS, size,514						GFP_KERNEL);515	if (!ip->transfer_buffer) {516		usb_free_urb(ip);517		return NULL;518	}519	ip->complete = usbtv_iso_cb;520	ip->number_of_packets = USBTV_ISOC_PACKETS;521	ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;522	for (i = 0; i < USBTV_ISOC_PACKETS; i++) {523		ip->iso_frame_desc[i].offset = size * i;524		ip->iso_frame_desc[i].length = size;525	}526 527	return ip;528}529 530static void usbtv_stop(struct usbtv *usbtv)531{532	int i;533	unsigned long flags;534 535	/* Cancel running transfers. */536	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {537		struct urb *ip = usbtv->isoc_urbs[i];538 539		if (ip == NULL)540			continue;541		usb_kill_urb(ip);542		kfree(ip->transfer_buffer);543		usb_free_urb(ip);544		usbtv->isoc_urbs[i] = NULL;545	}546 547	/* Return buffers to userspace. */548	spin_lock_irqsave(&usbtv->buflock, flags);549	while (!list_empty(&usbtv->bufs)) {550		struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,551						struct usbtv_buf, list);552		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);553		list_del(&buf->list);554	}555	spin_unlock_irqrestore(&usbtv->buflock, flags);556}557 558static int usbtv_start(struct usbtv *usbtv)559{560	int i;561	int ret;562 563	usbtv_audio_suspend(usbtv);564 565	ret = usb_set_interface(usbtv->udev, 0, 0);566	if (ret < 0)567		return ret;568 569	ret = usbtv_setup_capture(usbtv);570	if (ret < 0)571		return ret;572 573	ret = usb_set_interface(usbtv->udev, 0, 1);574	if (ret < 0)575		return ret;576 577	usbtv_audio_resume(usbtv);578 579	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {580		struct urb *ip;581 582		ip = usbtv_setup_iso_transfer(usbtv);583		if (ip == NULL) {584			ret = -ENOMEM;585			goto start_fail;586		}587		usbtv->isoc_urbs[i] = ip;588 589		ret = usb_submit_urb(ip, GFP_KERNEL);590		if (ret < 0)591			goto start_fail;592	}593 594	return 0;595 596start_fail:597	usbtv_stop(usbtv);598	return ret;599}600 601static int usbtv_querycap(struct file *file, void *priv,602				struct v4l2_capability *cap)603{604	struct usbtv *dev = video_drvdata(file);605 606	strscpy(cap->driver, "usbtv", sizeof(cap->driver));607	strscpy(cap->card, "usbtv", sizeof(cap->card));608	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));609	return 0;610}611 612static int usbtv_enum_input(struct file *file, void *priv,613					struct v4l2_input *i)614{615	struct usbtv *dev = video_drvdata(file);616 617	switch (i->index) {618	case USBTV_COMPOSITE_INPUT:619		strscpy(i->name, "Composite", sizeof(i->name));620		break;621	case USBTV_SVIDEO_INPUT:622		strscpy(i->name, "S-Video", sizeof(i->name));623		break;624	default:625		return -EINVAL;626	}627 628	i->type = V4L2_INPUT_TYPE_CAMERA;629	i->std = dev->vdev.tvnorms;630	return 0;631}632 633static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,634					struct v4l2_fmtdesc *f)635{636	if (f->index > 0)637		return -EINVAL;638 639	f->pixelformat = V4L2_PIX_FMT_YUYV;640	return 0;641}642 643static int usbtv_fmt_vid_cap(struct file *file, void *priv,644					struct v4l2_format *f)645{646	struct usbtv *usbtv = video_drvdata(file);647 648	f->fmt.pix.width = usbtv->width;649	f->fmt.pix.height = usbtv->height;650	f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;651	f->fmt.pix.field = V4L2_FIELD_INTERLACED;652	f->fmt.pix.bytesperline = usbtv->width * 2;653	f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);654	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;655 656	return 0;657}658 659static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)660{661	struct usbtv *usbtv = video_drvdata(file);662	*norm = usbtv->norm;663	return 0;664}665 666static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)667{668	int ret = -EINVAL;669	struct usbtv *usbtv = video_drvdata(file);670 671	if (norm & USBTV_TV_STD)672		ret = usbtv_select_norm(usbtv, norm);673 674	return ret;675}676 677static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)678{679	struct usbtv *usbtv = video_drvdata(file);680	*i = usbtv->input;681	return 0;682}683 684static int usbtv_s_input(struct file *file, void *priv, unsigned int i)685{686	struct usbtv *usbtv = video_drvdata(file);687 688	return usbtv_select_input(usbtv, i);689}690 691static const struct v4l2_ioctl_ops usbtv_ioctl_ops = {692	.vidioc_querycap = usbtv_querycap,693	.vidioc_enum_input = usbtv_enum_input,694	.vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,695	.vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,696	.vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,697	.vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,698	.vidioc_g_std = usbtv_g_std,699	.vidioc_s_std = usbtv_s_std,700	.vidioc_g_input = usbtv_g_input,701	.vidioc_s_input = usbtv_s_input,702 703	.vidioc_reqbufs = vb2_ioctl_reqbufs,704	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,705	.vidioc_querybuf = vb2_ioctl_querybuf,706	.vidioc_create_bufs = vb2_ioctl_create_bufs,707	.vidioc_qbuf = vb2_ioctl_qbuf,708	.vidioc_dqbuf = vb2_ioctl_dqbuf,709	.vidioc_streamon = vb2_ioctl_streamon,710	.vidioc_streamoff = vb2_ioctl_streamoff,711};712 713static const struct v4l2_file_operations usbtv_fops = {714	.owner = THIS_MODULE,715	.unlocked_ioctl = video_ioctl2,716	.mmap = vb2_fop_mmap,717	.open = v4l2_fh_open,718	.release = vb2_fop_release,719	.read = vb2_fop_read,720	.poll = vb2_fop_poll,721};722 723static int usbtv_queue_setup(struct vb2_queue *vq,724	unsigned int *nbuffers,725	unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[])726{727	struct usbtv *usbtv = vb2_get_drv_priv(vq);728	unsigned size = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);729	unsigned int q_num_bufs = vb2_get_num_buffers(vq);730 731	if (q_num_bufs + *nbuffers < 2)732		*nbuffers = 2 - q_num_bufs;733	if (*nplanes)734		return sizes[0] < size ? -EINVAL : 0;735	*nplanes = 1;736	sizes[0] = size;737 738	return 0;739}740 741static void usbtv_buf_queue(struct vb2_buffer *vb)742{743	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);744	struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);745	struct usbtv_buf *buf = container_of(vbuf, struct usbtv_buf, vb);746	unsigned long flags;747 748	if (usbtv->udev == NULL) {749		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);750		return;751	}752 753	spin_lock_irqsave(&usbtv->buflock, flags);754	list_add_tail(&buf->list, &usbtv->bufs);755	spin_unlock_irqrestore(&usbtv->buflock, flags);756}757 758static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)759{760	struct usbtv *usbtv = vb2_get_drv_priv(vq);761 762	if (usbtv->udev == NULL)763		return -ENODEV;764 765	usbtv->last_odd = 1;766	usbtv->sequence = 0;767	return usbtv_start(usbtv);768}769 770static void usbtv_stop_streaming(struct vb2_queue *vq)771{772	struct usbtv *usbtv = vb2_get_drv_priv(vq);773 774	if (usbtv->udev)775		usbtv_stop(usbtv);776}777 778static const struct vb2_ops usbtv_vb2_ops = {779	.queue_setup = usbtv_queue_setup,780	.buf_queue = usbtv_buf_queue,781	.start_streaming = usbtv_start_streaming,782	.stop_streaming = usbtv_stop_streaming,783	.wait_prepare = vb2_ops_wait_prepare,784	.wait_finish = vb2_ops_wait_finish,785};786 787static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl)788{789	struct usbtv *usbtv = container_of(ctrl->handler, struct usbtv,790								ctrl);791	u8 *data;792	u16 index, size;793	int ret;794 795	data = kmalloc(3, GFP_KERNEL);796	if (!data)797		return -ENOMEM;798 799	/*800	 * Read in the current brightness/contrast registers. We need them801	 * both, because the values are for some reason interleaved.802	 */803	if (ctrl->id == V4L2_CID_BRIGHTNESS || ctrl->id == V4L2_CID_CONTRAST) {804		ret = usb_control_msg(usbtv->udev,805			usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,806			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,807			0, USBTV_BASE + 0x0244, (void *)data, 3,808			USB_CTRL_GET_TIMEOUT);809		if (ret < 0)810			goto error;811	}812 813	switch (ctrl->id) {814	case V4L2_CID_BRIGHTNESS:815		index = USBTV_BASE + 0x0244;816		size = 3;817		data[0] &= 0xf0;818		data[0] |= (ctrl->val >> 8) & 0xf;819		data[2] = ctrl->val & 0xff;820		break;821	case V4L2_CID_CONTRAST:822		index = USBTV_BASE + 0x0244;823		size = 3;824		data[0] &= 0x0f;825		data[0] |= (ctrl->val >> 4) & 0xf0;826		data[1] = ctrl->val & 0xff;827		break;828	case V4L2_CID_SATURATION:829		index = USBTV_BASE + 0x0242;830		data[0] = ctrl->val >> 8;831		data[1] = ctrl->val & 0xff;832		size = 2;833		break;834	case V4L2_CID_HUE:835		index = USBTV_BASE + 0x0240;836		size = 2;837		if (ctrl->val > 0) {838			data[0] = 0x92 + (ctrl->val >> 8);839			data[1] = ctrl->val & 0xff;840		} else {841			data[0] = 0x82 + (-ctrl->val >> 8);842			data[1] = -ctrl->val & 0xff;843		}844		break;845	case V4L2_CID_SHARPNESS:846		index = USBTV_BASE + 0x0239;847		data[0] = 0;848		data[1] = ctrl->val;849		size = 2;850		break;851	default:852		kfree(data);853		return -EINVAL;854	}855 856	ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0),857			USBTV_CONTROL_REG,858			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,859			0, index, (void *)data, size, USB_CTRL_SET_TIMEOUT);860 861error:862	if (ret < 0)863		dev_warn(usbtv->dev, "Failed to submit a control request.\n");864 865	kfree(data);866	return ret;867}868 869static const struct v4l2_ctrl_ops usbtv_ctrl_ops = {870	.s_ctrl = usbtv_s_ctrl,871};872 873static void usbtv_release(struct v4l2_device *v4l2_dev)874{875	struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);876 877	v4l2_device_unregister(&usbtv->v4l2_dev);878	v4l2_ctrl_handler_free(&usbtv->ctrl);879	kfree(usbtv);880}881 882int usbtv_video_init(struct usbtv *usbtv)883{884	int ret;885 886	(void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60);887 888	spin_lock_init(&usbtv->buflock);889	mutex_init(&usbtv->v4l2_lock);890	mutex_init(&usbtv->vb2q_lock);891	INIT_LIST_HEAD(&usbtv->bufs);892 893	/* videobuf2 structure */894	usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;895	usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;896	usbtv->vb2q.drv_priv = usbtv;897	usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);898	usbtv->vb2q.ops = &usbtv_vb2_ops;899	usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;900	usbtv->vb2q.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;901	usbtv->vb2q.lock = &usbtv->vb2q_lock;902	ret = vb2_queue_init(&usbtv->vb2q);903	if (ret < 0) {904		dev_warn(usbtv->dev, "Could not initialize videobuf2 queue\n");905		return ret;906	}907 908	/* controls */909	v4l2_ctrl_handler_init(&usbtv->ctrl, 4);910	v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,911			V4L2_CID_CONTRAST, 0, 0x3ff, 1, 0x1d0);912	v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,913			V4L2_CID_BRIGHTNESS, 0, 0x3ff, 1, 0x1c0);914	v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,915			V4L2_CID_SATURATION, 0, 0x3ff, 1, 0x200);916	v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,917			V4L2_CID_HUE, -0xdff, 0xdff, 1, 0x000);918	v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,919			V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x60);920	ret = usbtv->ctrl.error;921	if (ret < 0) {922		dev_warn(usbtv->dev, "Could not initialize controls\n");923		goto ctrl_fail;924	}925 926	/* v4l2 structure */927	usbtv->v4l2_dev.ctrl_handler = &usbtv->ctrl;928	usbtv->v4l2_dev.release = usbtv_release;929	ret = v4l2_device_register(usbtv->dev, &usbtv->v4l2_dev);930	if (ret < 0) {931		dev_warn(usbtv->dev, "Could not register v4l2 device\n");932		goto v4l2_fail;933	}934 935	/* Video structure */936	strscpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));937	usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev;938	usbtv->vdev.release = video_device_release_empty;939	usbtv->vdev.fops = &usbtv_fops;940	usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;941	usbtv->vdev.tvnorms = USBTV_TV_STD;942	usbtv->vdev.queue = &usbtv->vb2q;943	usbtv->vdev.lock = &usbtv->v4l2_lock;944	usbtv->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |945				  V4L2_CAP_STREAMING;946	video_set_drvdata(&usbtv->vdev, usbtv);947	ret = video_register_device(&usbtv->vdev, VFL_TYPE_VIDEO, -1);948	if (ret < 0) {949		dev_warn(usbtv->dev, "Could not register video device\n");950		goto vdev_fail;951	}952 953	return 0;954 955vdev_fail:956	v4l2_device_unregister(&usbtv->v4l2_dev);957v4l2_fail:958ctrl_fail:959	v4l2_ctrl_handler_free(&usbtv->ctrl);960 961	return ret;962}963 964void usbtv_video_free(struct usbtv *usbtv)965{966	vb2_video_unregister_device(&usbtv->vdev);967	v4l2_device_disconnect(&usbtv->v4l2_dev);968 969	v4l2_device_put(&usbtv->v4l2_dev);970}971