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

📄 qc-driver.c

📁 Webcam Linux driver for Quickcam
💻 C
📖 第 1 页 / 共 5 页
字号:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)			urb->dev    = qc->dev;#endif			//PDEBUG("urb->dev = %p", urb->dev);			urb->status = 0;			r = usb_submit_urb(urb, GFP_ATOMIC);			CHECK_ERROR(r<0, endpolling, "error submit_urb again = %d", r);#endif			return;		}	}	IDEBUG_TEST(*id);	if(urb->actual_length > 0) {	  int val = ((unsigned char *)urb->transfer_buffer)[0];	  if(val & 0x80) {	    if(!(val & 0x08)) {	      qc->button_status = 1;	      qc->button_pressed++;	      qc->button_pressed_cum++;	    } else if(val == 0x88) {	      qc->button_status = 0;	      qc->button_released++;	      qc->button_released_cum++;	      qc->button_count = 0;	    }#ifdef USE_INPUT	    input_report_key(qc->input_ptr, BTN_0, qc->button_status);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	    input_sync(qc->input_ptr);#endif#endif	  }	}	urb->actual_length = 0;  // reset length	urb->transfer_buffer_length = 1;	if(id->abort_polling) {	  PDEBUG("end due to abort_polling");	  goto endpolling;	}	id->polling = 1;#if 0	if(urb->dev != qc->dev) {	  PDEBUG("urb->dev != qc->dev %p %p", urb->dev, qc->dev);	  urb->dev = qc->dev;	}#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)	urb->dev    = qc->dev;#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	/* always submit in 2.6.x kernels */#else	/* urb->status == -ECONNABORTED when we get timeout from urb	 * (shouldn't be used, but anyway...)	 * doesn't seem to need submit if status==0 in 2.4.x kernels...	 */	if(!urb->status) {	  return;	}#endif	urb->status = 0;	r = usb_submit_urb(urb, GFP_ATOMIC);	CHECK_ERROR(r<0, endpolling, "Failed submit()=%i", r);	return;endpolling:	urb->status = 0;end2:	if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_int_handler: Stop polling");	id->polling = 0;	wake_up(&id->wq);	return;}#endifstatic int qc_int_init(struct quickcam *qc){	struct qc_int_data *id = &qc->int_data;	struct urb *urb;	int ret = 0;	int_init_jiffy = jiffies;	qc->bEndpointAddress = 0x82;  // hardcode the endpoint address	if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_int_init(quickcam=%p)",qc);	TEST_BUGR(qc==NULL);	id->errorcount = 0;	id->polling = 1;	id->abort_polling = 0;	init_waitqueue_head(&id->wq);	#if 1	if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_int_init: set_interface(%p, %d, 1)", qc->dev, qc->iface);	ret = usb_set_interface(qc->dev, qc->iface, 1);	CHECK_ERROR(ret<0, fail0, "qc_int_init: set_interface failed");#endif	#ifdef DISABLE_INT_URBS	return ret;#else	/* Allocate transfer buffer */	id->buffer = kmalloc(INT_PACKET_SIZE, GFP_KERNEL);	CHECK_ERROR(!id->buffer, fail1, "Out of memory allocating id->buffer");	id->rawbufsize = INT_PACKET_SIZE;	memset(id->buffer, 0, id->rawbufsize);	/* Allocate URB, fill it and submit it */	urb = id->urb = usb_alloc_urb(0, GFP_KERNEL);	CHECK_ERROR(!urb, fail2, "Out of memory allocating urbs");#if 1	usb_fill_int_urb(urb, qc->dev,			 usb_rcvintpipe(qc->dev, qc->bEndpointAddress),			 id->buffer,			 id->rawbufsize,			 qc_int_handler,			 qc,			 16);#else	spin_lock_init(&urb->lock);	urb->dev                    = qc->dev;	urb->context                = qc;	urb->pipe                   = usb_rcvintpipe(qc->dev, qc->bEndpointAddress);	urb->complete               = qc_int_handler;	urb->transfer_buffer        = id->buffer;	urb->transfer_buffer_length = id->rawbufsize;	urb->interval               = 16;	/* See Table 9-10 of the USB 1.1 specification */	urb->start_frame	    = -1;#endif	urb->transfer_flags         = 0;	#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)	/* There are no real idea to use the timeout. It should be cleared	 * from alloc_urb and we don't have any problem with SUSE's 2.6.8-0	 * kernel either */	//urb->timeout  = HZ;                   /* 1 s */#endif	if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("dev=%p iface=%d", qc->dev, qc->iface);	IDEBUG_INIT(*id);	/* Submit URB */	urb->status = 0;	//PDEBUG("urb->dev=%p urb=%p", urb->dev, urb);	ret = usb_submit_urb(id->urb, GFP_KERNEL);	CHECK_ERROR(ret<0, fail4, "qc_int_init: submit urb failed %d", ret);	//ret = usb_set_interface(qc->dev, qc->iface, 1);	CHECK_ERROR(ret<0, fail5, "qc_int_init: set_interface failed");	return ret;fail5:	usb_kill_urb(id->urb);fail4:	usb_free_urb(id->urb);	POISON(id->urb);fail2:	kfree(id->buffer);	POISON(id->buffer);fail1:	usb_set_interface(qc->dev, qc->iface, 0);#endiffail0:	id->polling = 0;	if (qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGINIT) PDEBUG("qc_int_init: failed");	return ret;}static void qc_int_exit(struct quickcam *qc){	struct qc_int_data *id = &qc->int_data;		if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_int_exit(qc=%p)",qc);	TEST_BUG(qc==NULL);	if(qc->dev == NULL) {	  /* This will happen if we have a postponed exit */	  //PDEBUG("qc_int_exit: qc->dev == null (postponed exit?)");	  return;	}#ifdef DISABLE_INT_URBS	return;#else	qc_int_abort(qc);	/* Since qc_int_exit() could be called even if id->urb already	   was de-allocated, I do this test here...	 */        if(NOT_POISONED_PTR(id->urb)) {	  //PDEBUG("free INT urb %p", id->urb);	  usb_free_urb(id->urb);	  POISON(id->urb);	  	  kfree(id->buffer);	  POISON(id->buffer);	}	IDEBUG_EXIT(*id);#endif}/* }}} *//* {{{ [fold] **** qc_proc:   /proc interface *********************************** */#if HAVE_PROCFSstatic struct proc_dir_entry *qc_proc_video_entry = NULL;	/* Initialization should not be necessary, but just in case... */static struct proc_dir_entry *qc_proc_quickcam_entry = NULL;	/* Initialization should not be necessary, but just in case... *//* {{{ [fold] qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) */static inline const char *qc_proc_yesno(Bool b){	return b ? "Yes" : "No";}static int qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data){	struct quickcam *qc = data;	char *out = page;	int len;	if (qc_lock(qc) < 0) return 0;	out += sprintf(out, "\tGeneral driver status\n");	out += sprintf(out, "Driver version   : %s\n", VERSION);	out += sprintf(out, "Kernel version   : %s\n", UTS_RELEASE);	if (qc->dev!=NULL) {	out += sprintf(out, "Device Id        : %04X:%04X\n", (int)GET_VENDORID(qc), (int)GET_PRODUCTID(qc));	out += sprintf(out, "USB bus number   : %i\n", qc->dev->bus->busnum);	}	out += sprintf(out, "Users            : %i\n", qc->users);	out += sprintf(out, "Connected        : %s\n", qc_proc_yesno(qc->connected));	out += sprintf(out, "\n\tPicture settings set by user\n");	out += sprintf(out, "Brightness       : %d\n", (int)qc->vpic.brightness);	out += sprintf(out, "Hue              : %d\n", (int)qc->vpic.hue);	out += sprintf(out, "Color            : %d\n", (int)qc->vpic.colour);	out += sprintf(out, "Contrast         : %d\n", (int)qc->vpic.contrast);	out += sprintf(out, "Whiteness        : %d\n", (int)qc->vpic.whiteness);	if (qc->users > 0) {	out += sprintf(out, "Depth            : %d\n", (int)qc->vpic.depth);	out += sprintf(out, "Palette          : %s\n", qc_fmt_getname(qc->vpic.palette));	}	if (qc->users > 0) {	out += sprintf(out, "\n\tOutput window\n");	out += sprintf(out, "Width            : %d\n", (int)qc->vwin.width);	out += sprintf(out, "Height           : %d\n", (int)qc->vwin.height);	}	out += sprintf(out, "\n\tSensor\n");	out += sprintf(out, "Type             : %s\n", qc->sensor_data.sensor->name);	out += sprintf(out, "Manufacturer     : %s\n", qc->sensor_data.sensor->manufacturer);	if (qc->users > 0) {	out += sprintf(out, "Maximum width    : %d\n", qc->sensor_data.maxwidth);	out += sprintf(out, "Maximum height   : %d\n", qc->sensor_data.maxheight);	out += sprintf(out, "Current width    : %d\n", qc->sensor_data.width);	out += sprintf(out, "Current height   : %d\n", qc->sensor_data.height);	}	out += sprintf(out, "\n\tINT command stream\n");	out += sprintf(out, "Polling          : %s\n", qc_proc_yesno(qc->int_data.polling));	out += sprintf(out, "Error count      : %d\n", qc->int_data.errorcount);	out += sprintf(out, "Button pressed   : %s\n", qc_proc_yesno(qc->button_status));#ifdef USE_INPUT	out += sprintf(out, "Button physname  : %s\n", qc->input_physname);	out += sprintf(out, "Button input path: %s\n", qc->input_event_path);#endif	if (qc->users > 0) {	out += sprintf(out, "\n\tIsochronous data stream\n");	out += sprintf(out, "Stream enabled   : %s\n", qc_proc_yesno(qc->isoc_data.streaming));	out += sprintf(out, "Transfer errors  : %d\n", qc->isoc_data.errorcount);	out += sprintf(out, "\n\tFrame buffering\n");	out += sprintf(out, "Frames on queue  : %d\n", (FRAME_BUFFERS + qc->frame_data.head - qc->frame_data.tail) % FRAME_BUFFERS);	out += sprintf(out, "Capturing        : %s\n", qc_proc_yesno(qc->stream_data.capturing));	out += sprintf(out, "Waiting processes: %d\n", qc->frame_data.waiting);	}	out += sprintf(out, "\n\tAutomatic exposure control\n");	out += sprintf(out, "Picture intensity: %d\n", qc->adapt_data.oldmidvalue);	out += sprintf(out, "Exposure setting : %d\n", qc->adapt_data.exposure);	out += sprintf(out, "Gain setting     : %d\n", qc->adapt_data.gain);	out += sprintf(out, "Delta value      : %d\n", qc->adapt_data.olddelta);	out += sprintf(out, "Current rgb-gain : %d,%d,%d\n", qc->sensor_data.rgain,		       qc->sensor_data.ggain,qc->sensor_data.bgain);	{	  int ex = (qc->sensor_data.exposure >> 12) & 0x0f;	  if(ex >= 14) ex = 14;	  out += sprintf(out, "Current exposure : %d\n", ex);	}	out += sprintf(out, "Current shutter  : %d (%d%%)\n",		       qc->sensor_data.shutter,		       100*(qc->sensor_data.shutter) / 0xFFFF);	out += sprintf(out, "Control algorithm: ");	switch (qc->adapt_data.controlalg) {		case EXPCONTROL_SATURATED: out += sprintf(out, "Saturated\n"); break;		case EXPCONTROL_NEWTON:    out += sprintf(out, "Newton\n"); break;		case EXPCONTROL_FLOAT:     out += sprintf(out, "Float\n"); break;		default: out += sprintf(out, "?\n"); break;	}	out += sprintf(out, "\n\tDefault settings\n");	out += sprintf(out, "Debug            : 0x%02X\n", qcdebug);	out += sprintf(out, "Keep settings    : %s\n", qc_proc_yesno(qc->settings.keepsettings));	out += sprintf(out, "Settle max frames: %i\n", qc->settings.settle);	out += sprintf(out, "Subsampling      : %s\n", qc_proc_yesno(qc->settings.subsample));	out += sprintf(out, "Compress         : %s\n", qc_proc_yesno(qc->settings.compress));	out += sprintf(out, "Frame skipping   : %i\n", qc->settings.frameskip);	out += sprintf(out, "Image quality    : %i\n", qc->settings.quality);	out += sprintf(out, "Adaptive         : %s\n", qc_proc_yesno(qc->settings.adaptive));	out += sprintf(out, "Shutter Adapt    : %s\n", qc_proc_yesno(qc->settings.shutteradapt));	out += sprintf(out, "Equalize         : %s\n", qc_proc_yesno(qc->settings.equalize));	out += sprintf(out, "User lookup-table: %s\n", qc_proc_yesno(qc->settings.userlut));	out += sprintf(out, "Retryerrors      : %s\n", qc_proc_yesno(qc->settings.retryerrors));	out += sprintf(out, "Compatible 16x   : %s\n", qc_proc_yesno(qc->settings.compat_16x));	out += sprintf(out, "Compatible DblBuf: %s\n", qc_proc_yesno(qc->settings.compat_dblbuf));	out += sprintf(out, "Compatible ToRgb : %s\n", qc_proc_yesno(qc->settings.compat_torgb));	up(&quickcam_list_lock);	len = out - page;	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0) return 0;	} else		len = count;	*start = page + off;	return len;}static int qc_proc_button_read(char *page, char **start, off_t off, int count, int *eof, void *data){	struct quickcam *qc = data;	char *out = page;	int len;	if (qc_lock(qc) < 0) return 0;	out += sprintf(out, "\tButton status\n");	out += sprintf(out, "Polling         : %s\n", qc_proc_yesno(qc->int_data.polling));	out += sprintf(out, "Error count     : %d\n", qc->int_data.errorcount);	out += sprintf(out, "Button pressed  : %s\n", qc_proc_yesno(qc->button_status));	out += sprintf(out, "Button down     : %d\n", qc->button_pressed);	out += sprintf(out, "Button up       : %d\n", qc->button_released);	out += sprintf(out, "Cummulative down: %d\n", qc->button_pressed_cum);	out += sprintf(out, "Cummulative up  : %d\n", qc->button_released_cum);	qc->button_pressed = 0;	qc->button_released = 0;

⌨️ 快捷键说明

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