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

📄 w9968cf.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                 " for every device."                 "\n");MODULE_PARM_DESC(contrast,                  "\n<n[,...]> Set picture contrast (0-65535)."                 "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)                 " for every device."                 "\n");MODULE_PARM_DESC(whiteness,                  "\n<n[,...]> Set picture whiteness (0-65535)."                 "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)                 " for every device."                 "\n");#ifdef W9968CF_DEBUGMODULE_PARM_DESC(debug,                 "\n<n> Debugging information level, from 0 to 6:"                 "\n0 = none (use carefully)"                 "\n1 = critical errors"                 "\n2 = significant informations"                 "\n3 = configuration or general messages"                 "\n4 = warnings"                 "\n5 = called functions"                 "\n6 = function internals"                 "\nLevel 5 and 6 are useful for testing only, when only "                 "one device is used."                 "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."                 "\n");MODULE_PARM_DESC(specific_debug,                 "\n<0|1> Enable or disable specific debugging messages:"                 "\n0 = print messages concerning every level"                 " <= 'debug' level."                 "\n1 = print messages concerning the level"                 " indicated by 'debug'."                 "\nDefault value is "                 __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."                 "\n");#endif /* W9968CF_DEBUG *//**************************************************************************** * Some prototypes                                                          * ****************************************************************************//* Video4linux interface */static struct file_operations w9968cf_fops;static int w9968cf_open(struct inode*, struct file*);static int w9968cf_release(struct inode*, struct file*);static int w9968cf_mmap(struct file*, struct vm_area_struct*);static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,                             void __user *);/* USB-specific */static int w9968cf_start_transfer(struct w9968cf_device*);static int w9968cf_stop_transfer(struct w9968cf_device*);static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);static int w9968cf_read_reg(struct w9968cf_device*, u16 index);static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);static int w9968cf_write_sb(struct w9968cf_device*, u16 value);static int w9968cf_read_sb(struct w9968cf_device*);static int w9968cf_upload_quantizationtables(struct w9968cf_device*);static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);/* Low-level I2C (SMBus) I/O */static int w9968cf_smbus_start(struct w9968cf_device*);static int w9968cf_smbus_stop(struct w9968cf_device*);static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);static int w9968cf_smbus_write_ack(struct w9968cf_device*);static int w9968cf_smbus_read_ack(struct w9968cf_device*);static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,                                      u16 address, u8* value);static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,                                            u8 subaddress, u8* value);static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,                                       u16 address, u8 subaddress);static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,                                                u16 address, u8 subaddress,                                                u8 value);/* I2C interface to kernel */static int w9968cf_i2c_init(struct w9968cf_device*);static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,                                   unsigned short flags, char read_write,                                   u8 command, int size, union i2c_smbus_data*);static u32 w9968cf_i2c_func(struct i2c_adapter*);static int w9968cf_i2c_attach_inform(struct i2c_client*);static int w9968cf_i2c_detach_inform(struct i2c_client*);static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,                               unsigned long arg);/* Memory management */static inline unsigned long kvirt_to_pa(unsigned long adr);static void* rvmalloc(unsigned long size);static void rvfree(void *mem, unsigned long size);static void w9968cf_deallocate_memory(struct w9968cf_device*);static int  w9968cf_allocate_memory(struct w9968cf_device*);/* High-level image sensor control functions */static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);static int w9968cf_sensor_cmd(struct w9968cf_device*,                              unsigned int cmd, void *arg);static int w9968cf_sensor_init(struct w9968cf_device*);static int w9968cf_sensor_update_settings(struct w9968cf_device*);static int w9968cf_sensor_get_picture(struct w9968cf_device*);static int w9968cf_sensor_update_picture(struct w9968cf_device*,                                          struct video_picture pict);/* Other helper functions */static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,                                     enum w9968cf_model_id,                                      const unsigned short dev_nr);static void w9968cf_adjust_configuration(struct w9968cf_device*);static int w9968cf_turn_on_led(struct w9968cf_device*);static int w9968cf_init_chip(struct w9968cf_device*);static inline u16 w9968cf_valid_palette(u16 palette);static inline u16 w9968cf_valid_depth(u16 palette);static inline u8 w9968cf_need_decompression(u16 palette);static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);static int w9968cf_set_window(struct w9968cf_device*, struct video_window);static int w9968cf_postprocess_frame(struct w9968cf_device*,                                      struct w9968cf_frame_t*);static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h);static void w9968cf_init_framelist(struct w9968cf_device*);static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);static void w9968cf_release_resources(struct w9968cf_device*);/* Intermodule communication */static int w9968cf_vppmod_detect(struct w9968cf_device*);static void w9968cf_vppmod_release(struct w9968cf_device*);/**************************************************************************** * Symbolic names                                                           * ****************************************************************************//* Used to represent a list of values and their respective symbolic names */struct w9968cf_symbolic_list {	const int num;	const char *name;};/*--------------------------------------------------------------------------   Returns the name of the matching element in the symbolic_list array. The  end of the list must be marked with an element that has a NULL name.  --------------------------------------------------------------------------*/static inline const char * symbolic(struct w9968cf_symbolic_list list[], const int num){	int i;	for (i = 0; list[i].name != NULL; i++)		if (list[i].num == num)			return (list[i].name);	return "Unknown";}static struct w9968cf_symbolic_list camlist[] = {	{ W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },	{ W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },	/* Other cameras (having the same descriptors as Generic W996[87]CF) */	{ W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },	{ W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },	{ W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },	{ W9968CF_MOD_LL, "Lebon LDC-035A" },	{ W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },	{ W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },	{ W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },	{ W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },	{ W9968CF_MOD_PDP480, "Pretec DigiPen-480" },	{  -1, NULL }};static struct w9968cf_symbolic_list senlist[] = {	{ CC_OV76BE,   "OV76BE" },	{ CC_OV7610,   "OV7610" },	{ CC_OV7620,   "OV7620" },	{ CC_OV7620AE, "OV7620AE" },	{ CC_OV6620,   "OV6620" },	{ CC_OV6630,   "OV6630" },	{ CC_OV6630AE, "OV6630AE" },	{ CC_OV6630AF, "OV6630AF" },	{ -1, NULL }};/* Video4Linux1 palettes */static struct w9968cf_symbolic_list v4l1_plist[] = {	{ VIDEO_PALETTE_GREY,    "GREY" },	{ VIDEO_PALETTE_HI240,   "HI240" },	{ VIDEO_PALETTE_RGB565,  "RGB565" },	{ VIDEO_PALETTE_RGB24,   "RGB24" },	{ VIDEO_PALETTE_RGB32,   "RGB32" },	{ VIDEO_PALETTE_RGB555,  "RGB555" },	{ VIDEO_PALETTE_YUV422,  "YUV422" },	{ VIDEO_PALETTE_YUYV,    "YUYV" },	{ VIDEO_PALETTE_UYVY,    "UYVY" },	{ VIDEO_PALETTE_YUV420,  "YUV420" },	{ VIDEO_PALETTE_YUV411,  "YUV411" },	{ VIDEO_PALETTE_RAW,     "RAW" },	{ VIDEO_PALETTE_YUV422P, "YUV422P" },	{ VIDEO_PALETTE_YUV411P, "YUV411P" },	{ VIDEO_PALETTE_YUV420P, "YUV420P" },	{ VIDEO_PALETTE_YUV410P, "YUV410P" },	{ -1, NULL }};/* Decoder error codes: */static struct w9968cf_symbolic_list decoder_errlist[] = {	{ W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },	{ W9968CF_DEC_ERR_BUF_OVERFLOW,   "Buffer overflow" },	{ W9968CF_DEC_ERR_NO_SOI,         "SOI marker not found" },     	{ W9968CF_DEC_ERR_NO_SOF0,        "SOF0 marker not found" },	{ W9968CF_DEC_ERR_NO_SOS,         "SOS marker not found" },	{ W9968CF_DEC_ERR_NO_EOI,         "EOI marker not found" },	{ -1, NULL }};/* URB error codes: */static struct w9968cf_symbolic_list urb_errlist[] = {	{ -ENOMEM,    "No memory for allocation of internal structures" },	{ -ENOSPC,    "The host controller's bandwidth is already consumed" },	{ -ENOENT,    "URB was canceled by unlink_urb" },	{ -EXDEV,     "ISO transfer only partially completed" },	{ -EAGAIN,    "Too match scheduled for the future" },	{ -ENXIO,     "URB already queued" },	{ -EFBIG,     "Too much ISO frames requested" },	{ -ENOSR,     "Buffer error (overrun)" },	{ -EPIPE,     "Specified endpoint is stalled (device not responding)"},	{ -EOVERFLOW, "Babble (bad cable?)" },	{ -EPROTO,    "Bit-stuff error (bad cable?)" },	{ -EILSEQ,    "CRC/Timeout" },	{ -ETIMEDOUT, "NAK (device does not respond)" },	{ -1, NULL }};/**************************************************************************** * Memory management functions                                              * ****************************************************************************//* Here we want the physical address of the memory.   This is used when initializing the contents of the area. */static inline unsigned long kvirt_to_pa(unsigned long adr){	unsigned long kva, ret;	kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));	kva |= adr & (PAGE_SIZE-1); /* restore the offset */	ret = __pa(kva);	return ret;}static void* rvmalloc(unsigned long size){	void* mem;	unsigned long adr;	size = PAGE_ALIGN(size);	mem = vmalloc_32(size);	if (!mem)		return NULL;	memset(mem, 0, size); /* Clear the ram out, no junk to the user */	adr = (unsigned long) mem;	while (size > 0) {		SetPageReserved(vmalloc_to_page((void *)adr));		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	return mem;}static void rvfree(void* mem, unsigned long size){	unsigned long adr;	if (!mem)		return;	adr = (unsigned long) mem;	while ((long) size > 0) {		ClearPageReserved(vmalloc_to_page((void *)adr));		adr += PAGE_SIZE;		size -= PAGE_SIZE;	}	vfree(mem);}/*--------------------------------------------------------------------------  Deallocate previously allocated memory.  --------------------------------------------------------------------------*/static void w9968cf_deallocate_memory(struct w9968cf_device* cam){	u8 i;	/* Free the isochronous transfer buffers */	for (i = 0; i < W9968CF_URBS; i++) {		kfree(cam->transfer_buffer[i]);		cam->transfer_buffer[i] = NULL;	}	/* Free temporary frame buffer */	if (cam->frame_tmp.buffer) {		rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);		cam->frame_tmp.buffer = NULL;	}	/* Free helper buffer */	if (cam->frame_vpp.buffer) {		rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);		cam->frame_vpp.buffer = NULL;	}	/* Free video frame buffers */	if (cam->frame[0].buffer) {		rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);		cam->frame[0].buffer = NULL;	}	cam->nbuffers = 0;	DBG(5, "Memory successfully deallocated")}/*--------------------------------------------------------------------------  Allocate memory buffers for USB transfers and video frames.  This function is called by open() only.  Return 0 on success, a negative number otherwise.  --------------------------------------------------------------------------*/static int w9968cf_allocate_memory(struct w9968cf_device* cam){	const u16 p_size = wMaxPacketSize[cam->altsetting-1];	void* buff = NULL;	unsigned long hw_bufsize, vpp_bufsize;	u8 i, bpp;	/* NOTE: Deallocation is done elsewhere in case of error */	/* Calculate the max amount of raw data per frame from the device */	hw_bufsize = cam->maxwidth*cam->maxheight*2;	/* Calculate the max buf. size needed for post-processing routines */	bpp = (w9968cf_vpp) ? 4 : 2;	if (cam->upscaling)		vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,		                  cam->maxwidth*cam->maxheight*bpp);	else		vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;	/* Allocate memory for the isochronous transfer buffers */	for (i = 0; i < W9968CF_URBS; i++) {

⌨️ 快捷键说明

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