📄 qc-driver.c
字号:
#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 + -