📄 ibmcam.c
字号:
usb_ibmcam_Packet_Format1(ibmcam, 0x30, 0x17); usb_ibmcam_Packet_Format1(ibmcam, 0x39, 0x08); for (i=0; i < ntries; i++) usb_ibmcam_Packet_Format1(ibmcam, 0x34, 0x00); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0101); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010a); switch (videosize) { case VIDEOSIZE_128x96: usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0103); usb_ibmcam_veio(ibmcam, 0, 0x60, 0x0105); usb_ibmcam_veio(ibmcam, 0, 0x0c, 0x010b); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x0b, 0x011d); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0129); break; case VIDEOSIZE_176x144: usb_ibmcam_veio(ibmcam, 0, 0xb0, 0x0103); usb_ibmcam_veio(ibmcam, 0, 0x8f, 0x0105); usb_ibmcam_veio(ibmcam, 0, 0x06, 0x010b); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x0d, 0x011d); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x03, 0x0129); break; case VIDEOSIZE_352x288: usb_ibmcam_veio(ibmcam, 0, 0xb0, 0x0103); usb_ibmcam_veio(ibmcam, 0, 0x90, 0x0105); usb_ibmcam_veio(ibmcam, 0, 0x02, 0x010b); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x05, 0x011d); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0129); break; } usb_ibmcam_veio(ibmcam, 0, 0xff, 0x012b); /* This is another brightness - don't know why */ for (i=0; i < ntries; i++) usb_ibmcam_Packet_Format1(ibmcam, 0x31, 0xc3); for (i=0; i < ntries; i++) usb_ibmcam_Packet_Format1(ibmcam, 0x32, 0xd2); for (i=0; i < ntries; i++) usb_ibmcam_Packet_Format1(ibmcam, 0x33, 0xe1); /* Default contrast */ for (i=0; i < ntries; i++) usb_ibmcam_Packet_Format1(ibmcam, contrast_14, 0x0a); /* Default sharpness */ for (i=0; i < 2; i++) usb_ibmcam_PacketFormat2(ibmcam, sharp_13, 0x1a); /* Level 4 FIXME */ /* Default lighting conditions */ usb_ibmcam_Packet_Format1(ibmcam, light_27, lighting); /* 0=Bright 2=Low */ /* Assorted init */ switch (videosize) { case VIDEOSIZE_128x96: usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1e); usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x36, 0x0102); usb_ibmcam_veio(ibmcam, 0, 0x1a, 0x0104); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x2b, 0x011c); usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a); /* Same everywhere */#if 0 usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0106); usb_ibmcam_veio(ibmcam, 0, 0x38, 0x0107);#else usb_ibmcam_veio(ibmcam, 0, 0x02, 0x0106); usb_ibmcam_veio(ibmcam, 0, 0x2a, 0x0107);#endif break; case VIDEOSIZE_176x144: usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1e); usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x04, 0x0102); usb_ibmcam_veio(ibmcam, 0, 0x02, 0x0104); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x2b, 0x011c); usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0106); usb_ibmcam_veio(ibmcam, 0, 0xca, 0x0107); break; case VIDEOSIZE_352x288: usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1f); usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x08, 0x0102); usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0104); usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x2f, 0x011c); usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a); /* Same everywhere */ usb_ibmcam_veio(ibmcam, 0, 0x03, 0x0106); usb_ibmcam_veio(ibmcam, 0, 0xf6, 0x0107); break; } return IBMCAM_IS_OPERATIONAL(ibmcam);}static int usb_ibmcam_model2_setup(struct usb_ibmcam *ibmcam){ usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100); /* LED on */ usb_ibmcam_veio(ibmcam, 1, 0x0000, 0x0116); usb_ibmcam_veio(ibmcam, 0, 0x0060, 0x0116); usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0112); usb_ibmcam_veio(ibmcam, 0, 0x00bc, 0x012c); usb_ibmcam_veio(ibmcam, 0, 0x0008, 0x012b); usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0108); usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0133); usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0102); switch (videosize) { case VIDEOSIZE_176x144: usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ usb_ibmcam_veio(ibmcam, 0, 0x00b9, 0x010a); /* Unique to this mode */ usb_ibmcam_veio(ibmcam, 0, 0x0038, 0x0119); /* Unique to this mode */ usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x0090, 0x0107); /* Unique to every mode*/ break; case VIDEOSIZE_320x240: usb_ibmcam_veio(ibmcam, 0, 0x0028, 0x0103); /* Unique to this mode */ usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x0098, 0x0107); /* Unique to every mode*/ break; case VIDEOSIZE_352x240: usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105); /* 320x240, 352x240 */ usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x00da, 0x0107); /* Unique to every mode*/ break; case VIDEOSIZE_352x288: usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103); /* All except 320x240 */ usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105); /* 176x144, 352x288 */ usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119); /* All except 176x144 */ usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106); /* Same */ usb_ibmcam_veio(ibmcam, 0, 0x00fe, 0x0107); /* Unique to every mode*/ break; } return IBMCAM_IS_OPERATIONAL(ibmcam);}/* * usb_ibmcam_model1_setup_after_video_if() * * This code adds finishing touches to the video data interface. * Here we configure the frame rate and turn on the LED. */static void usb_ibmcam_model1_setup_after_video_if(struct usb_ibmcam *ibmcam){ unsigned short internal_frame_rate; RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */ usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100); /* LED On */ usb_ibmcam_veio(ibmcam, 0, internal_frame_rate, 0x0111); usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114); usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c);}static void usb_ibmcam_model2_setup_after_video_if(struct usb_ibmcam *ibmcam){ unsigned short setup_model2_rg, setup_model2_rg2, setup_model2_sat, setup_model2_yb; usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100); /* LED on */ switch (videosize) { case VIDEOSIZE_176x144: usb_ibmcam_veio(ibmcam, 0, 0x0050, 0x0111); usb_ibmcam_veio(ibmcam, 0, 0x00d0, 0x0111); break; case VIDEOSIZE_320x240: case VIDEOSIZE_352x240: case VIDEOSIZE_352x288: usb_ibmcam_veio(ibmcam, 0, 0x0040, 0x0111); usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x0111); break; } usb_ibmcam_veio(ibmcam, 0, 0x009b, 0x010f); usb_ibmcam_veio(ibmcam, 0, 0x00bb, 0x010f); /* * Hardware settings, may affect CMOS sensor; not user controls! * ------------------------------------------------------------- * 0x0004: no effect * 0x0006: hardware effect * 0x0008: no effect * 0x000a: stops video stream, probably important h/w setting * 0x000c: changes color in hardware manner (not user setting) * 0x0012: changes number of colors (does not affect speed) * 0x002a: no effect * 0x002c: hardware setting (related to scan lines) * 0x002e: stops video stream, probably important h/w setting */ usb_ibmcam_model2_Packet1(ibmcam, 0x000a, 0x005c); usb_ibmcam_model2_Packet1(ibmcam, 0x0004, 0x0000); usb_ibmcam_model2_Packet1(ibmcam, 0x0006, 0x00fb); usb_ibmcam_model2_Packet1(ibmcam, 0x0008, 0x0000); usb_ibmcam_model2_Packet1(ibmcam, 0x000c, 0x0009); usb_ibmcam_model2_Packet1(ibmcam, 0x0012, 0x000a); usb_ibmcam_model2_Packet1(ibmcam, 0x002a, 0x0000); usb_ibmcam_model2_Packet1(ibmcam, 0x002c, 0x0000); usb_ibmcam_model2_Packet1(ibmcam, 0x002e, 0x0008); /* * Function 0x0030 pops up all over the place. Apparently * it is a hardware control register, with every bit assigned to * do something. */ usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0000); /* * Magic control of CMOS sensor. Only lower values like * 0-3 work, and picture shifts left or right. Don't change. */ switch (videosize) { case VIDEOSIZE_176x144: usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0002); usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */ usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */ break; case VIDEOSIZE_320x240: usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009); usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0005); /* Horizontal shift */ usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Another hardware setting */ break; case VIDEOSIZE_352x240: /* This mode doesn't work as Windows programs it; changed to work */ usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009); /* Windows sets this to 8 */ usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0003); /* Horizontal shift */ usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Windows sets this to 0x0045 */ break; case VIDEOSIZE_352x288: usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0003); usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */ usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */ break; } usb_ibmcam_model2_Packet1(ibmcam, mod2_brightness, 0x005a); /* * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest). * The camera model 2 allows frame rate in range [0..0x1F] where 0 is also the * slowest setting. However for all practical reasons high settings make no * sense because USB is not fast enough to support high FPS. Be aware that * the picture datastream will be severely disrupted if you ask for * frame rate faster than allowed for the video size - see below: * * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz): * ----------------------------------------------------------------- * 176x144: [6..31] * 320x240: [8..31] * 352x240: [10..31] * 352x288: [16..31] I have to raise lower threshold for stability... * * As usual, slower FPS provides better sensitivity. */ { short hw_fps=31, i_framerate; RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX); i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN; switch (videosize) { case VIDEOSIZE_176x144: hw_fps = 6 + i_framerate*4; break; case VIDEOSIZE_320x240: hw_fps = 8 + i_framerate*3; break; case VIDEOSIZE_352x240: hw_fps = 10 + i_framerate*2; break; case VIDEOSIZE_352x288: hw_fps = 28 + i_framerate/2; break; } if (debug > 0) printk(KERN_DEBUG "Framerate (hardware): %hd.\n", hw_fps); RESTRICT_TO_RANGE(hw_fps, 0, 31); usb_ibmcam_model2_Packet1(ibmcam, mod2_set_framerate, hw_fps); } /* * This setting does not visibly affect pictures; left it here * because it was present in Windows USB data stream. This function * does not allow arbitrary values and apparently is a bit mask, to * be activated only at appropriate time. Don't change it randomly! */ switch (videosize) { case VIDEOSIZE_176x144: usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x00c2); break; case VIDEOSIZE_320x240: usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0044); break; case VIDEOSIZE_352x240: usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0046); break; case VIDEOSIZE_352x288: usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0048); break; } usb_ibmcam_model2_Packet1(ibmcam, mod2_sensitivity, lighting); if (init_model2_rg >= 0) { RESTRICT_TO_RANGE(init_model2_rg, 0, 255); setup_model2_rg = init_model2_rg; } else setup_model2_rg = 0x0070; if (init_model2_rg2 >= 0) { RESTRICT_TO_RANGE(init_model2_rg2, 0, 255); setup_model2_rg2 = init_model2_rg2; } else setup_model2_rg2 = 0x002f; if (init_model2_sat >= 0) { RESTRICT_TO_RANGE(init_model2_sat, 0, 255); setup_model2_sat = init_model2_sat; } else setup_model2_sat = 0x0034; if (init_model2_yb >= 0) { RESTRICT_TO_RANGE(init_model2_yb, 0, 255); setup_model2_yb = init_model2_yb; } else setup_model2_yb = 0x00a0; usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg2, setup_model2_rg2); usb_ibmcam_model2_Packet1(ibmcam, mod2_saturation, setup_model2_sat); usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_yb, setup_model2_yb); usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg, setup_model2_rg); /* Hardware control command */ usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004); usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); /* Go camera, go! */ usb_clear_halt(ibmcam->dev, ibmcam->video_endp);}/* * usb_ibmcam_setup_video_stop() * * This code tells camera to stop streaming. The interface remains * configured and bandwidth - claimed. */static void usb_ibmcam_setup_video_stop(struct usb_ibmcam *ibmcam){ if (ibmcam->camera_model == IBMCAM_MODEL_1) { usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114); usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c); usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c); usb_ibmcam_send_FF_04_02(ibmcam); usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100); usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100); /* LED Off */ } else if (ibmcam->camera_model == IBMCAM_MODEL_2) { usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x010c); /* Stop the camera */ usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004); usb_ibmcam_veio(ibmcam, 0, 0x0080, 0x0100); /* LED Off */ usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111); usb_ibmcam_veio(ibmcam, 0, 0x00a0, 0x0111); usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0002); usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111); usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0112); }}/* * usb_ibmcam_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. * * History: * 1/2/00 Created. */static void usb_ibmcam_reinit_iso(struct usb_ibmcam *ibmcam, int do_stop){ if (ibmcam->camera_model == IBMCAM_MODEL_1) { if (do_stop) usb_ibmcam_setup_video_stop(ibmcam); usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0114); usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c); usb_clear_halt(ibmcam->dev, ibmcam->video_endp); usb_ibmcam_model1_setup_after_video_if(ibmcam); } else if (ibmcam->camera_model == IBMCAM_MODEL_2) { usb_ibmcam_model2_setup_after_video_if(ibmcam); }}/* * ibmcam_init_isoc() * * History: * 1/27/00 Used ibmcam->iface, ibmcam->ifaceAltActive instead of hardcoded values. * Simplified by using for loop, allowed any number of URBs. */static int ibmcam_init_isoc(struct usb_ibmcam *ibmcam){ struct usb_device *dev = ibmcam->dev; int i, err; if (!IBMCAM_IS_OPERATIONAL(ibmcam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -