spca500.c
来自「trident tm5600的linux驱动」· C语言 代码 · 共 1,126 行 · 第 1/2 页
C
1,126 行
PDEBUG(D_ERR, "reg_r_wait() failed"); return err; } /* all ok */ return 0;}/* Synchro the Bridge with sensor *//* Maybe that will work on all spca500 chip *//* because i only own a clicksmart310 try for that chip *//* using spca50x_set_packet_size() cause an Ooops here *//* usb_set_interface from kernel 2.6.x clear all the urb stuff *//* up-port the same feature as in 2.4.x kernel */static int spca500_synch310(struct gspca_dev *gspca_dev){ if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { PDEBUG(D_ERR, "Set packet size: set interface error"); goto error; } spca500_ping310(gspca_dev); reg_r(gspca_dev, 0x0d00, 1); /* need alt setting here */ PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); /* Windoze use pipe with altsetting 6 why 7 here */ if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->alt) < 0) { PDEBUG(D_ERR, "Set packet size: set interface error"); goto error; } return 0;error: return -EBUSY;}static void spca500_reinit(struct gspca_dev *gspca_dev){ int err; __u8 Data; /* some unknow command from Aiptek pocket dv and family300 */ reg_w(gspca_dev, 0x00, 0x0d01, 0x01); reg_w(gspca_dev, 0x00, 0x0d03, 0x00); reg_w(gspca_dev, 0x00, 0x0d02, 0x01); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); /* set qtable index */ reg_w(gspca_dev, 0x00, 0x8880, 2); /* family cam Quicksmart stuff */ reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); /*Start init sequence or stream */ reg_w(gspca_dev, 0, 0x8003, 0x00); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); msleep(2000); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) { reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data); }}/* this function is called at probe time */static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id){ struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; cam = &gspca_dev->cam; cam->epaddr = 0x01; sd->subtype = id->driver_info; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; } else { cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; } sd->qindex = 5; sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; return 0;}/* this function is called at probe and resume time */static int sd_init(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; /* initialisation of spca500 based cameras is deferred */ PDEBUG(D_STREAM, "SPCA500 init"); if (sd->subtype == LogitechClickSmart310) spca500_clksmart310_init(gspca_dev);/* else spca500_initialise(gspca_dev); */ PDEBUG(D_STREAM, "SPCA500 init done"); return 0;}static int sd_start(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; int err; __u8 Data; __u8 xmult, ymult; if (sd->subtype == LogitechClickSmart310) { xmult = 0x16; ymult = 0x12; } else { xmult = 0x28; ymult = 0x1e; } /* is there a sensor here ? */ reg_r(gspca_dev, 0x8a04, 1); PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x", gspca_dev->usb_buf[0]); PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x", gspca_dev->curr_mode, xmult, ymult); /* setup qtable */ switch (sd->subtype) { case LogitechClickSmart310: spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); msleep(500); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data); spca500_synch310(gspca_dev); write_vector(gspca_dev, spca500_visual_defaults); spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); PDEBUG(D_ERR, "failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data); break; case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ case IntelPocketPCCamera: /* FIXME: Temporary fix for * Intel Pocket PC Camera * - NWG (Sat 29th March 2003) */ /* do a full reset */ err = spca500_full_reset(gspca_dev); if (err < 0) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); if (err < 0) PDEBUG(D_ERR, "failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); reg_w(gspca_dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data);/* write_vector(gspca_dev, spca500_visual_defaults); */ break; case KodakEZ200: /* Kodak EZ200 */ /* do a full reset */ err = spca500_full_reset(gspca_dev); if (err < 0) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); reg_w(gspca_dev, 0x00, 0x8880, 0); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_kodak_ez200); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); reg_w(gspca_dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data);/* write_vector(gspca_dev, spca500_visual_defaults); */ break; case BenqDC1016: case DLinkDSC350: /* FamilyCam 300 */ case AiptekPocketDV: /* Aiptek PocketDV */ case Gsmartmini: /*Mustek Gsmart Mini */ case MustekGsmart300: /* Mustek Gsmart 300 */ case PalmPixDC85: case Optimedia: case ToptroIndus: case AgfaCl20: spca500_reinit(gspca_dev); reg_w(gspca_dev, 0x00, 0x0d01, 0x01); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); reg_w(gspca_dev, 0x00, 0x8880, 2); /* familycam Quicksmart pocketDV stuff */ reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); reg_r_wait(gspca_dev, 0, 0x8000, 0x44); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data); break; case LogitechTraveler: case LogitechClickSmart510: reg_w(gspca_dev, 0x02, 0x00, 0x00); /* enable drop packet */ reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); reg_w(gspca_dev, 0x00, 0x8880, 3); reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); reg_r_wait(gspca_dev, 0, 0x8000, 0x44); reg_r(gspca_dev, 0x816b, 1); Data = gspca_dev->usb_buf[0]; reg_w(gspca_dev, 0x00, 0x816b, Data); write_vector(gspca_dev, Clicksmart510_defaults); break; } return 0;}static void sd_stopN(struct gspca_dev *gspca_dev){ reg_w(gspca_dev, 0, 0x8003, 0x00); /* switch to video camera mode */ reg_w(gspca_dev, 0x00, 0x8000, 0x0004); reg_r(gspca_dev, 0x8000, 1); PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", gspca_dev->usb_buf[0]);}static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */{ struct sd *sd = (struct sd *) gspca_dev; int i; __u8 *s, *d; static __u8 ffd9[] = {0xff, 0xd9};/* frames are jpeg 4.1.1 without 0xff escape */ if (data[0] == 0xff) { if (data[1] != 0x01) { /* drop packet *//* gspca_dev->last_packet_type = DISCARD_PACKET; */ return; } frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, ffd9, 2); /* put the JPEG header in the new frame */ jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22); data += SPCA500_OFFSET_DATA; len -= SPCA500_OFFSET_DATA; } else { data += 1; len -= 1; } /* add 0x00 after 0xff */ for (i = len; --i >= 0; ) if (data[i] == 0xff) break; if (i < 0) { /* no 0xff */ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); return; } s = data; d = sd->packet; for (i = 0; i < len; i++) { *d++ = *s++; if (s[-1] == 0xff) *d++ = 0x00; } gspca_frame_add(gspca_dev, INTER_PACKET, frame, sd->packet, d - sd->packet);}static void setbrightness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; reg_w(gspca_dev, 0x00, 0x8167, (__u8) (sd->brightness - 128));}static void getbrightness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; int ret; ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1); if (ret >= 0) sd->brightness = ret + 128;}static void setcontrast(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);}static void getcontrast(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; int ret; ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1); if (ret >= 0) sd->contrast = ret;}static void setcolors(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; reg_w(gspca_dev, 0x00, 0x8169, sd->colors);}static void getcolors(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; int ret; ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1); if (ret >= 0) sd->colors = ret;}static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val){ struct sd *sd = (struct sd *) gspca_dev; sd->brightness = val; if (gspca_dev->streaming) setbrightness(gspca_dev); return 0;}static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val){ struct sd *sd = (struct sd *) gspca_dev; getbrightness(gspca_dev); *val = sd->brightness; return 0;}static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val){ struct sd *sd = (struct sd *) gspca_dev; sd->contrast = val; if (gspca_dev->streaming) setcontrast(gspca_dev); return 0;}static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val){ struct sd *sd = (struct sd *) gspca_dev; getcontrast(gspca_dev); *val = sd->contrast; return 0;}static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val){ struct sd *sd = (struct sd *) gspca_dev; sd->colors = val; if (gspca_dev->streaming) setcolors(gspca_dev); return 0;}static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val){ struct sd *sd = (struct sd *) gspca_dev; getcolors(gspca_dev); *val = sd->colors; return 0;}/* sub-driver description */static struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan,};/* -- module initialisation -- */static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310}, {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510}, {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016}, {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85}, {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300}, {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini}, {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20}, {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia}, {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350}, {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV}, {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus}, {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera}, {}};MODULE_DEVICE_TABLE(usb, device_table);/* -- device connect -- */static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id){ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), THIS_MODULE);}static struct usb_driver sd_driver = { .name = MODULE_NAME, .id_table = device_table, .probe = sd_probe, .disconnect = gspca_disconnect,#ifdef CONFIG_PM .suspend = gspca_suspend, .resume = gspca_resume,#endif};/* -- module insert / remove -- */static int __init sd_mod_init(void){ if (usb_register(&sd_driver) < 0) return -1; PDEBUG(D_PROBE, "registered"); return 0;}static void __exit sd_mod_exit(void){ usb_deregister(&sd_driver); PDEBUG(D_PROBE, "deregistered");}module_init(sd_mod_init);module_exit(sd_mod_exit);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?