⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vino.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Driver for the VINO (Video In No Out) system found in SGI Indys. * * This file is subject to the terms and conditions of the GNU General Public * License version 2 as published by the Free Software Foundation. * * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi> * * Based on the previous version of the driver for 2.4 kernels by: * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> *//* * TODO: * - remove "mark pages reserved-hacks" from memory allocation code *   and implement nopage() * - check decimation, calculating and reporting image size when *   using decimation * - implement read(), user mode buffers and overlay (?) */#include <linux/init.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/dma-mapping.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/interrupt.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/moduleparam.h>#include <linux/time.h>#include <linux/version.h>#ifdef CONFIG_KMOD#include <linux/kmod.h>#endif#include <linux/i2c.h>#include <linux/i2c-algo-sgi.h>#include <linux/videodev.h>#include <linux/videodev2.h>#include <linux/video_decoder.h>#include "compat.h"#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)#include <linux/mutex.h>#endif#include <asm/paccess.h>#include <asm/io.h>#include <asm/sgi/ip22.h>#include <asm/sgi/mc.h>#include "vino.h"#include "saa7191.h"#include "indycam.h"/* Uncomment the following line to get lots and lots of (mostly useless) * debug info. * Note that the debug output also slows down the driver significantly */// #define VINO_DEBUG// #define VINO_DEBUG_INT#define VINO_MODULE_VERSION "0.0.5"#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");MODULE_VERSION(VINO_MODULE_VERSION);MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");MODULE_LICENSE("GPL");#ifdef VINO_DEBUG#define dprintk(x...) printk("VINO: " x);#else#define dprintk(x...)#endif#define VINO_NO_CHANNEL			0#define VINO_CHANNEL_A			1#define VINO_CHANNEL_B			2#define VINO_PAL_WIDTH			768#define VINO_PAL_HEIGHT			576#define VINO_NTSC_WIDTH			640#define VINO_NTSC_HEIGHT		480#define VINO_MIN_WIDTH			32#define VINO_MIN_HEIGHT			32#define VINO_CLIPPING_START_ODD_D1	1#define VINO_CLIPPING_START_ODD_PAL	15#define VINO_CLIPPING_START_ODD_NTSC	12#define VINO_CLIPPING_START_EVEN_D1	2#define VINO_CLIPPING_START_EVEN_PAL	15#define VINO_CLIPPING_START_EVEN_NTSC	12#define VINO_INPUT_CHANNEL_COUNT	3/* the number is the index for vino_inputs */#define VINO_INPUT_NONE			-1#define VINO_INPUT_COMPOSITE		0#define VINO_INPUT_SVIDEO		1#define VINO_INPUT_D1			2#define VINO_PAGE_RATIO			(PAGE_SIZE / VINO_PAGE_SIZE)#define VINO_FIFO_THRESHOLD_DEFAULT	16#define VINO_FRAMEBUFFER_SIZE		((VINO_PAL_WIDTH \					  * VINO_PAL_HEIGHT * 4 \					  + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))#define VINO_FRAMEBUFFER_COUNT_MAX	8#define VINO_FRAMEBUFFER_UNUSED		0#define VINO_FRAMEBUFFER_IN_USE		1#define VINO_FRAMEBUFFER_READY		2#define VINO_QUEUE_ERROR		-1#define VINO_QUEUE_MAGIC		0x20050125#define VINO_MEMORY_NONE		0#define VINO_MEMORY_MMAP		1#define VINO_MEMORY_USERPTR		2#define VINO_DUMMY_DESC_COUNT		4#define VINO_DESC_FETCH_DELAY		5	/* microseconds */#define VINO_MAX_FRAME_SKIP_COUNT	128/* the number is the index for vino_data_formats */#define VINO_DATA_FMT_NONE		-1#define VINO_DATA_FMT_GREY		0#define VINO_DATA_FMT_RGB332		1#define VINO_DATA_FMT_RGB32		2#define VINO_DATA_FMT_YUV		3#define VINO_DATA_FMT_COUNT		4/* the number is the index for vino_data_norms */#define VINO_DATA_NORM_NONE		-1#define VINO_DATA_NORM_NTSC		0#define VINO_DATA_NORM_PAL		1#define VINO_DATA_NORM_SECAM		2#define VINO_DATA_NORM_D1		3/* The following are special entries that can be used to * autodetect the norm. */#define VINO_DATA_NORM_AUTO		0xfe#define VINO_DATA_NORM_AUTO_EXT		0xff#define VINO_DATA_NORM_COUNT		4/* Internal data structure definitions */struct vino_input {	char *name;	v4l2_std_id std;};struct vino_clipping {	unsigned int left, right, top, bottom;};struct vino_data_format {	/* the description */	char *description;	/* bytes per pixel */	unsigned int bpp;	/* V4L2 fourcc code */	__u32 pixelformat;	/* V4L2 colorspace (duh!) */	enum v4l2_colorspace colorspace;};struct vino_data_norm {	char *description;	unsigned int width, height;	struct vino_clipping odd;	struct vino_clipping even;	v4l2_std_id std;	unsigned int fps_min, fps_max;	__u32 framelines;};struct vino_descriptor_table {	/* the number of PAGE_SIZE sized pages in the buffer */	unsigned int page_count;	/* virtual (kmalloc'd) pointers to the actual data	 * (in PAGE_SIZE chunks, used with mmap streaming) */	unsigned long *virtual;	/* cpu address for the VINO descriptor table	 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */	unsigned long *dma_cpu;	/* dma address for the VINO descriptor table	 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */	dma_addr_t dma;};struct vino_framebuffer {	/* identifier nubmer */	unsigned int id;	/* the length of the whole buffer */	unsigned int size;	/* the length of actual data in buffer */	unsigned int data_size;	/* the data format */	unsigned int data_format;	/* the state of buffer data */	unsigned int state;	/* is the buffer mapped in user space? */	unsigned int map_count;	/* memory offset for mmap() */	unsigned int offset;	/* frame counter */	unsigned int frame_counter;	/* timestamp (written when image capture finishes) */	struct timeval timestamp;	struct vino_descriptor_table desc_table;	spinlock_t state_lock;};struct vino_framebuffer_fifo {	unsigned int length;	unsigned int used;	unsigned int head;	unsigned int tail;	unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];};struct vino_framebuffer_queue {	unsigned int magic;	/* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */	unsigned int type;	unsigned int length;	/* data field of in and out contain index numbers for buffer */	struct vino_framebuffer_fifo in;	struct vino_framebuffer_fifo out;	struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];	spinlock_t queue_lock;	struct mutex queue_mutex;	wait_queue_head_t frame_wait_queue;};struct vino_interrupt_data {	struct timeval timestamp;	unsigned int frame_counter;	unsigned int skip_count;	unsigned int skip;};struct vino_channel_settings {	unsigned int channel;	int input;	unsigned int data_format;	unsigned int data_norm;	struct vino_clipping clipping;	unsigned int decimation;	unsigned int line_size;	unsigned int alpha;	unsigned int fps;	unsigned int framert_reg;	unsigned int fifo_threshold;	struct vino_framebuffer_queue fb_queue;	/* number of the current field */	unsigned int field;	/* read in progress */	int reading;	/* streaming is active */	int streaming;	/* the driver is currently processing the queue */	int capturing;	struct mutex channel_mutex;	spinlock_t capture_lock;	unsigned int users;	struct vino_interrupt_data int_data;	/* V4L support */	struct video_device *v4l_device;};struct vino_client {	/* the channel which owns this client:	 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */	unsigned int owner;	struct i2c_client *driver;};struct vino_settings {	struct vino_channel_settings a;	struct vino_channel_settings b;	struct vino_client decoder;	struct vino_client camera;	/* a lock for vino register access */	spinlock_t vino_lock;	/* a lock for channel input changes */	spinlock_t input_lock;	unsigned long dummy_page;	struct vino_descriptor_table dummy_desc_table;};/* Module parameters *//* * Using vino_pixel_conversion the ABGR32-format pixels supplied * by the VINO chip can be converted to more common formats * like RGBA32 (or probably RGB24 in the future). This way we * can give out data that can be specified correctly with * the V4L2-definitions. * * The pixel format is specified as RGBA32 when no conversion * is used. * * Note that this only affects the 32-bit bit depth. * * Use non-zero value to enable conversion. */static int vino_pixel_conversion = 0;module_param_named(pixelconv, vino_pixel_conversion, int, 0);MODULE_PARM_DESC(pixelconv,		 "enable pixel conversion (non-zero value enables)");/* Internal data structures */static struct sgi_vino *vino;static struct vino_settings *vino_drvdata;static const char *vino_driver_name = "vino";static const char *vino_driver_description = "SGI VINO";static const char *vino_bus_name = "GIO64 bus";static const char *vino_v4l_device_name_a = "SGI VINO Channel A";static const char *vino_v4l_device_name_b = "SGI VINO Channel B";static void vino_capture_tasklet(unsigned long channel);DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);static const struct vino_input vino_inputs[] = {	{		.name		= "Composite",		.std		= V4L2_STD_NTSC | V4L2_STD_PAL		| V4L2_STD_SECAM,	},{		.name		= "S-Video",		.std		= V4L2_STD_NTSC | V4L2_STD_PAL		| V4L2_STD_SECAM,	},{		.name		= "D1/IndyCam",		.std		= V4L2_STD_NTSC,	}};static const struct vino_data_format vino_data_formats[] = {	{		.description	= "8-bit greyscale",		.bpp		= 1,		.pixelformat	= V4L2_PIX_FMT_GREY,		.colorspace	= V4L2_COLORSPACE_SMPTE170M,	},{		.description	= "8-bit dithered RGB 3-3-2",		.bpp		= 1,		.pixelformat	= V4L2_PIX_FMT_RGB332,		.colorspace	= V4L2_COLORSPACE_SRGB,	},{		.description	= "32-bit RGB",		.bpp		= 4,		.pixelformat	= V4L2_PIX_FMT_RGB32,		.colorspace	= V4L2_COLORSPACE_SRGB,	},{		.description	= "YUV 4:2:2",		.bpp		= 2,		.pixelformat	= V4L2_PIX_FMT_YUYV, // XXX: swapped?		.colorspace	= V4L2_COLORSPACE_SMPTE170M,	}};static const struct vino_data_norm vino_data_norms[] = {	{		.description	= "NTSC",		.std		= V4L2_STD_NTSC,		.fps_min	= 6,		.fps_max	= 30,		.framelines	= 525,		.width		= VINO_NTSC_WIDTH,		.height		= VINO_NTSC_HEIGHT,		.odd		= {			.top	= VINO_CLIPPING_START_ODD_NTSC,			.left	= 0,			.bottom	= VINO_CLIPPING_START_ODD_NTSC			+ VINO_NTSC_HEIGHT / 2 - 1,			.right	= VINO_NTSC_WIDTH,		},		.even		= {			.top	= VINO_CLIPPING_START_EVEN_NTSC,			.left	= 0,			.bottom	= VINO_CLIPPING_START_EVEN_NTSC			+ VINO_NTSC_HEIGHT / 2 - 1,			.right	= VINO_NTSC_WIDTH,		},	},{		.description	= "PAL",		.std		= V4L2_STD_PAL,		.fps_min	= 5,		.fps_max	= 25,		.framelines	= 625,		.width		= VINO_PAL_WIDTH,		.height		= VINO_PAL_HEIGHT,		.odd		= {			.top	= VINO_CLIPPING_START_ODD_PAL,			.left	= 0,			.bottom	= VINO_CLIPPING_START_ODD_PAL			+ VINO_PAL_HEIGHT / 2 - 1,			.right	= VINO_PAL_WIDTH,		},		.even		= {			.top	= VINO_CLIPPING_START_EVEN_PAL,			.left	= 0,			.bottom	= VINO_CLIPPING_START_EVEN_PAL			+ VINO_PAL_HEIGHT / 2 - 1,			.right	= VINO_PAL_WIDTH,		},	},{		.description	= "SECAM",		.std		= V4L2_STD_SECAM,		.fps_min	= 5,		.fps_max	= 25,		.framelines	= 625,		.width		= VINO_PAL_WIDTH,		.height		= VINO_PAL_HEIGHT,		.odd		= {			.top	= VINO_CLIPPING_START_ODD_PAL,			.left	= 0,			.bottom	= VINO_CLIPPING_START_ODD_PAL			+ VINO_PAL_HEIGHT / 2 - 1,			.right	= VINO_PAL_WIDTH,		},		.even		= {			.top	= VINO_CLIPPING_START_EVEN_PAL,			.left	= 0,			.bottom	= VINO_CLIPPING_START_EVEN_PAL			+ VINO_PAL_HEIGHT / 2 - 1,			.right	= VINO_PAL_WIDTH,		},	},{		.description	= "NTSC/D1",		.std		= V4L2_STD_NTSC,		.fps_min	= 6,		.fps_max	= 30,		.framelines	= 525,		.width		= VINO_NTSC_WIDTH,		.height		= VINO_NTSC_HEIGHT,		.odd		= {			.top	= VINO_CLIPPING_START_ODD_D1,			.left	= 0,			.bottom	= VINO_CLIPPING_START_ODD_D1			+ VINO_NTSC_HEIGHT / 2 - 1,			.right	= VINO_NTSC_WIDTH,		},		.even		= {			.top	= VINO_CLIPPING_START_EVEN_D1,			.left	= 0,			.bottom	= VINO_CLIPPING_START_EVEN_D1			+ VINO_NTSC_HEIGHT / 2 - 1,			.right	= VINO_NTSC_WIDTH,		},	}};#define VINO_INDYCAM_V4L2_CONTROL_COUNT		9struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {	{		.id = V4L2_CID_AUTOGAIN,		.type = V4L2_CTRL_TYPE_BOOLEAN,		.name = "Automatic Gain Control",		.minimum = 0,		.maximum = 1,		.step = 1,		.default_value = INDYCAM_AGC_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_AGC, 0 },	},{		.id = V4L2_CID_AUTO_WHITE_BALANCE,		.type = V4L2_CTRL_TYPE_BOOLEAN,		.name = "Automatic White Balance",		.minimum = 0,		.maximum = 1,		.step = 1,		.default_value = INDYCAM_AWB_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_AWB, 0 },	},{		.id = V4L2_CID_GAIN,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Gain",		.minimum = INDYCAM_GAIN_MIN,		.maximum = INDYCAM_GAIN_MAX,		.step = 1,		.default_value = INDYCAM_GAIN_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_GAIN, 0 },	},{		.id = V4L2_CID_PRIVATE_BASE,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Red Saturation",		.minimum = INDYCAM_RED_SATURATION_MIN,		.maximum = INDYCAM_RED_SATURATION_MAX,		.step = 1,		.default_value = INDYCAM_RED_SATURATION_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },	},{		.id = V4L2_CID_PRIVATE_BASE + 1,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Blue Saturation",		.minimum = INDYCAM_BLUE_SATURATION_MIN,		.maximum = INDYCAM_BLUE_SATURATION_MAX,		.step = 1,		.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },	},{		.id = V4L2_CID_RED_BALANCE,		.type = V4L2_CTRL_TYPE_INTEGER,		.name = "Red Balance",		.minimum = INDYCAM_RED_BALANCE_MIN,		.maximum = INDYCAM_RED_BALANCE_MAX,		.step = 1,		.default_value = INDYCAM_RED_BALANCE_DEFAULT,		.flags = 0,		.reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },	},{		.id = V4L2_CID_BLUE_BALANCE,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -