📄 ultracam.c
字号:
/* * USB NB Camera driver * * HISTORY: * 25-Dec-2002 Dmitri Removed lighting, sharpness parameters, methods. */#include <linux/kernel.h>#include <linux/sched.h>#include <linux/module.h>#include <linux/init.h>#include "usbvideo.h"#define ULTRACAM_VENDOR_ID 0x0461#define ULTRACAM_PRODUCT_ID 0x0813#define MAX_CAMERAS 4 /* How many devices we allow to connect *//* * This structure lives in uvd_t->user field. */typedef struct { int initialized; /* Had we already sent init sequence? */ int camera_model; /* What type of IBM camera we got? */ int has_hdr;} ultracam_t;#define ULTRACAM_T(uvd) ((ultracam_t *)((uvd)->user_data))static struct usbvideo *cams = NULL;static int debug = 0;static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */static const int min_canvasWidth = 8;static const int min_canvasHeight = 4;#define FRAMERATE_MIN 0#define FRAMERATE_MAX 6static int framerate = -1;/* * Here we define several initialization variables. They may * be used to automatically set color, hue, brightness and * contrast to desired values. This is particularly useful in * case of webcams (which have no controls and no on-screen * output) and also when a client V4L software is used that * does not have some of those controls. In any case it's * good to have startup values as options. * * These values are all in [0..255] range. This simplifies * operation. Note that actual values of V4L variables may * be scaled up (as much as << 8). User can see that only * on overlay output, however, or through a V4L client. */static int init_brightness = 128;static int init_contrast = 192;static int init_color = 128;static int init_hue = 128;static int hue_correction = 128;module_param(debug, int, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");module_param(flags, int, 0);MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, " "1=B/W, " "2=show hints, " "3=show stats, " "4=test pattern, " "5=separate frames, " "6=clean frames");module_param(framerate, int, 0);MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");module_param(init_brightness, int, 0);MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");module_param(init_contrast, int, 0);MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");module_param(init_color, int, 0);MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");module_param(init_hue, int, 0);MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");module_param(hue_correction, int, 0);MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");/* * ultracam_ProcessIsocData() * * Generic routine to parse the ring queue data. It employs either * ultracam_find_header() or ultracam_parse_lines() to do most * of work. * * 02-Nov-2000 First (mostly dummy) version. * 06-Nov-2000 Rewrote to dump all data into frame. */static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame){ int n; assert(uvd != NULL); assert(frame != NULL); /* Try to move data from queue into frame buffer */ n = RingQueue_GetLength(&uvd->dp); if (n > 0) { int m; /* See how much spare we have left */ m = uvd->max_frame_size - frame->seqRead_Length; if (n > m) n = m; /* Now move that much data into frame buffer */ RingQueue_Dequeue( &uvd->dp, frame->data + frame->seqRead_Length, m); frame->seqRead_Length += m; } /* See if we filled the frame */ if (frame->seqRead_Length >= uvd->max_frame_size) { frame->frameState = FrameState_Done; uvd->curframe = -1; uvd->stats.frame_num++; }}/* * ultracam_veio() * * History: * 1/27/00 Added check for dev == NULL; this happens if camera is unplugged. */static int ultracam_veio( struct uvd *uvd, unsigned char req, unsigned short value, unsigned short index, int is_out){ static const char proc[] = "ultracam_veio"; unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */; int i; if (!CAMERA_IS_OPERATIONAL(uvd)) return 0; if (!is_out) { i = usb_control_msg( uvd->dev, usb_rcvctrlpipe(uvd->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, cp, sizeof(cp), 1000);#if 1 info("USB => %02x%02x%02x%02x%02x%02x%02x%02x " "(req=$%02x val=$%04x ind=$%04x)", cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7], req, value, index);#endif } else { i = usb_control_msg( uvd->dev, usb_sndctrlpipe(uvd->dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 1000); } if (i < 0) { err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.", proc, i); uvd->last_error = i; } return i;}/* * ultracam_calculate_fps() */static int ultracam_calculate_fps(struct uvd *uvd){ return 3 + framerate*4 + framerate/2;}/* * ultracam_adjust_contrast() */static void ultracam_adjust_contrast(struct uvd *uvd){}/* * ultracam_set_brightness() * * This procedure changes brightness of the picture. */static void ultracam_set_brightness(struct uvd *uvd){}static void ultracam_set_hue(struct uvd *uvd){}/* * ultracam_adjust_picture() * * This procedure gets called from V4L interface to update picture settings. * Here we change brightness and contrast. */static void ultracam_adjust_picture(struct uvd *uvd){ ultracam_adjust_contrast(uvd); ultracam_set_brightness(uvd); ultracam_set_hue(uvd);}/* * ultracam_video_stop() * * This code tells camera to stop streaming. The interface remains * configured and bandwidth - claimed. */static void ultracam_video_stop(struct uvd *uvd){}/* * ultracam_reinit_iso() * * This procedure sends couple of commands to the camera and then * resets the video pipe. This sequence was observed to reinit the * camera or, at least, to initiate ISO data stream. */static void ultracam_reinit_iso(struct uvd *uvd, int do_stop){}static void ultracam_video_start(struct uvd *uvd){ ultracam_reinit_iso(uvd, 0);}static int ultracam_resetPipe(struct uvd *uvd){ usb_clear_halt(uvd->dev, uvd->video_endp); return 0;}static int ultracam_alternateSetting(struct uvd *uvd, int setting){ static const char proc[] = "ultracam_alternateSetting"; int i; i = usb_set_interface(uvd->dev, uvd->iface, setting); if (i < 0) { err("%s: usb_set_interface error", proc); uvd->last_error = i; return -EBUSY; } return 0;}/* * Return negative code on failure, 0 on success. */static int ultracam_setup_on_open(struct uvd *uvd){ int setup_ok = 0; /* Success by default */ /* Send init sequence only once, it's large! */ if (!ULTRACAM_T(uvd)->initialized) { ultracam_alternateSetting(uvd, 0x04); ultracam_alternateSetting(uvd, 0x00); ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1); ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1); ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1); ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1); ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1); ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1); ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1); ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1); ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1); ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1); ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1); ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1); ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1); ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1); ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1); ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1); ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1); ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1); ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1); ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1); ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1); ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1); ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1); ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1); ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1); ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1); ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1); ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1); ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1); ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1); ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1); ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1); ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1); ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1); ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1); ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1); ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1); ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1); ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1); ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1); ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1); ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1); ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1); ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1); ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1); ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1); ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1); ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1); ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1); ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1); ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1); ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -