spca505.c
来自「trident tm5600的linux驱动」· C语言 代码 · 共 944 行 · 第 1/2 页
C
944 行
{0x03, 0x00, 0x00}, {0x03, 0x21, 0x00}, {0x03, 0x00, 0x04}, {0x03, 0x00, 0x03}, {0x03, 0x18, 0x03}, {0x03, 0x08, 0x01}, {0x03, 0x1c, 0x03}, {0x03, 0x5c, 0x03}, {0x03, 0x5c, 0x03}, {0x03, 0x18, 0x01},/* same as 505 */ {0x04, 0x10, 0x01}, {0x04, 0x00, 0x04}, {0x04, 0x00, 0x05}, {0x04, 0x20, 0x06}, {0x04, 0x20, 0x07}, {0x08, 0x0a, 0x00}, {0x05, 0x00, 0x10}, {0x05, 0x00, 0x11}, {0x05, 0x00, 0x12}, {0x05, 0x6f, 0x00}, {0x05, initial_brightness >> 6, 0x00}, {0x05, initial_brightness << 2, 0x01}, {0x05, 0x00, 0x02}, {0x05, 0x01, 0x03}, {0x05, 0x00, 0x04}, {0x05, 0x03, 0x05}, {0x05, 0xe0, 0x06}, {0x05, 0x20, 0x07}, {0x05, 0xa0, 0x08}, {0x05, 0x00, 0x12}, {0x05, 0x02, 0x0f}, {0x05, 128, 0x14}, /* max exposure off (0=on) */ {0x05, 0x01, 0xb0}, {0x05, 0x01, 0xbf}, {0x03, 0x02, 0x06}, {0x05, 0x10, 0x46}, {0x05, 0x08, 0x4a}, {0x06, 0x00, 0x01}, {0x06, 0x10, 0x02}, {0x06, 0x64, 0x07}, {0x06, 0x18, 0x08}, {0x06, 0xfc, 0x09}, {0x06, 0xfc, 0x0a}, {0x06, 0xfc, 0x0b}, {0x04, 0x00, 0x01}, {0x06, 0x18, 0x0c}, {0x06, 0xfc, 0x0d}, {0x06, 0xfc, 0x0e}, {0x06, 0xfc, 0x0f}, {0x06, 0x11, 0x10}, /* contrast */ {0x06, 0x00, 0x11}, {0x06, 0xfe, 0x12}, {0x06, 0x00, 0x13}, {0x06, 0x00, 0x14}, {0x06, 0x9d, 0x51}, {0x06, 0x40, 0x52}, {0x06, 0x7c, 0x53}, {0x06, 0x40, 0x54}, {0x06, 0x02, 0x57}, {0x06, 0x03, 0x58}, {0x06, 0x15, 0x59}, {0x06, 0x05, 0x5a}, {0x06, 0x03, 0x56}, {0x06, 0x02, 0x3f}, {0x06, 0x00, 0x40}, {0x06, 0x39, 0x41}, {0x06, 0x69, 0x42}, {0x06, 0x87, 0x43}, {0x06, 0x9e, 0x44}, {0x06, 0xb1, 0x45}, {0x06, 0xbf, 0x46}, {0x06, 0xcc, 0x47}, {0x06, 0xd5, 0x48}, {0x06, 0xdd, 0x49}, {0x06, 0xe3, 0x4a}, {0x06, 0xe8, 0x4b}, {0x06, 0xed, 0x4c}, {0x06, 0xf2, 0x4d}, {0x06, 0xf7, 0x4e}, {0x06, 0xfc, 0x4f}, {0x06, 0xff, 0x50}, {0x05, 0x01, 0xc0}, {0x05, 0x10, 0xcb}, {0x05, 0x40, 0xc1}, {0x05, 0x04, 0xc2}, {0x05, 0x00, 0xca}, {0x05, 0x40, 0xc1}, {0x05, 0x09, 0xc2}, {0x05, 0x00, 0xca}, {0x05, 0xc0, 0xc1}, {0x05, 0x09, 0xc2}, {0x05, 0x00, 0xca}, {0x05, 0x40, 0xc1}, {0x05, 0x59, 0xc2}, {0x05, 0x00, 0xca}, {0x04, 0x00, 0x01}, {0x05, 0x80, 0xc1}, {0x05, 0xec, 0xc2}, {0x05, 0x0, 0xca}, {0x06, 0x02, 0x57}, {0x06, 0x01, 0x58}, {0x06, 0x15, 0x59}, {0x06, 0x0a, 0x5a}, {0x06, 0x01, 0x57}, {0x06, 0x8a, 0x03}, {0x06, 0x0a, 0x6c}, {0x06, 0x30, 0x01}, {0x06, 0x20, 0x02}, {0x06, 0x00, 0x03}, {0x05, 0x8c, 0x25}, {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ {0x06, 0x84, 0x53}, /* making green (84) */ {0x06, 0x00, 0x57}, /* sharpness (1) */ {0x06, 0x18, 0x08}, {0x06, 0xfc, 0x09}, {0x06, 0xfc, 0x0a}, {0x06, 0xfc, 0x0b}, {0x06, 0x18, 0x0c}, /* maybe hue (18) */ {0x06, 0xfc, 0x0d}, {0x06, 0xfc, 0x0e}, {0x06, 0xfc, 0x0f}, {0x06, 0x18, 0x10}, /* maybe contrast (18) */ {0x05, 0x01, 0x02}, {0x04, 0x00, 0x08}, /* compression */ {0x04, 0x12, 0x09}, {0x04, 0x21, 0x0a}, {0x04, 0x10, 0x0b}, {0x04, 0x21, 0x0c}, {0x04, 0x1d, 0x00}, /* imagetype (1d) */ {0x04, 0x41, 0x01}, /* hardware snapcontrol */ {0x04, 0x00, 0x04}, {0x04, 0x00, 0x05}, {0x04, 0x10, 0x06}, {0x04, 0x10, 0x07}, {0x04, 0x40, 0x06}, {0x04, 0x40, 0x07}, {0x04, 0x00, 0x04}, {0x04, 0x00, 0x05}, {0x06, 0x1c, 0x17}, {0x06, 0xe2, 0x19}, {0x06, 0x1c, 0x1b}, {0x06, 0xe2, 0x1d}, {0x06, 0x5f, 0x1f}, {0x06, 0x32, 0x20}, {0x05, initial_brightness >> 6, 0x00}, {0x05, initial_brightness << 2, 0x01}, {0x05, 0x06, 0xc1}, {0x05, 0x58, 0xc2}, {0x05, 0x0, 0xca}, {0x05, 0x0, 0x11}, {}};static int reg_write(struct usb_device *dev, __u16 reg, __u16 index, __u16 value){ int ret; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), reg, USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", reg, index, value, ret); if (ret < 0) PDEBUG(D_ERR, "reg write: error %d", ret); return ret;}/* returns: negative is error, pos or zero is data */static int reg_read(struct gspca_dev *gspca_dev, __u16 reg, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */{ int ret; gspca_dev->usb_buf[1] = 0; ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), reg, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, (__u16) 0, /* value */ (__u16) index, gspca_dev->usb_buf, length, 500); /* timeout */ if (ret < 0) { PDEBUG(D_ERR, "reg_read err %d", ret); return -1; } return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];}static int write_vector(struct gspca_dev *gspca_dev, const __u16 data[][3]){ struct usb_device *dev = gspca_dev->dev; int ret, i = 0; while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); if (ret < 0) { PDEBUG(D_ERR, "Register write failed for 0x%x,0x%x,0x%x", data[i][0], data[i][1], data[i][2]); return ret; } i++; } return 0;}/* 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; cam->cam_mode = vga_mode; sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; else /* no 640x480 for IntelPCCameraPro */ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; if (sd->subtype == Nxultra) { if (write_vector(gspca_dev, spca505b_init_data)) return -EIO; } else { if (write_vector(gspca_dev, spca505_init_data)) return -EIO; } 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; int ret; PDEBUG(D_STREAM, "Initializing SPCA505"); if (sd->subtype == Nxultra) write_vector(gspca_dev, spca505b_open_data_ccd); else write_vector(gspca_dev, spca505_open_data_ccd); ret = reg_read(gspca_dev, 6, 0x16, 2); if (ret < 0) { PDEBUG(D_ERR|D_STREAM, "register read failed for after vector read err = %d", ret); return -EIO; } PDEBUG(D_STREAM, "After vector read returns : 0x%x should be 0x0101", ret & 0xffff); ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); if (ret < 0) { PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", ret); return -EIO; } reg_write(gspca_dev->dev, 5, 0xc2, 18); return 0;}static int sd_start(struct gspca_dev *gspca_dev){ struct usb_device *dev = gspca_dev->dev; int ret; /* necessary because without it we can see stream * only once after loading module */ /* stopping usb registers Tomasz change */ reg_write(dev, 0x02, 0x0, 0x0); switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: reg_write(dev, 0x04, 0x00, 0x00); reg_write(dev, 0x04, 0x06, 0x10); reg_write(dev, 0x04, 0x07, 0x10); break; case 1: reg_write(dev, 0x04, 0x00, 0x01); reg_write(dev, 0x04, 0x06, 0x1a); reg_write(dev, 0x04, 0x07, 0x1a); break; case 2: reg_write(dev, 0x04, 0x00, 0x02); reg_write(dev, 0x04, 0x06, 0x1c); reg_write(dev, 0x04, 0x07, 0x1d); break; case 4: reg_write(dev, 0x04, 0x00, 0x04); reg_write(dev, 0x04, 0x06, 0x34); reg_write(dev, 0x04, 0x07, 0x34); break; default:/* case 5: */ reg_write(dev, 0x04, 0x00, 0x05); reg_write(dev, 0x04, 0x06, 0x40); reg_write(dev, 0x04, 0x07, 0x40); break; }/* Enable ISO packet machine - should we do this here or in ISOC init ? */ ret = reg_write(dev, SPCA50X_REG_USB, SPCA50X_USB_CTRL, SPCA50X_CUSB_ENABLE);/* reg_write(dev, 0x5, 0x0, 0x0); *//* reg_write(dev, 0x5, 0x0, 0x1); *//* reg_write(dev, 0x5, 0x11, 0x2); */ return ret;}static void sd_stopN(struct gspca_dev *gspca_dev){ /* Disable ISO packet machine */ reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);}static void sd_stop0(struct gspca_dev *gspca_dev){ /* This maybe reset or power control */ reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);}static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */{ switch (data[0]) { case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); break; case 0xff: /* drop *//* gspca_dev->last_packet_type = DISCARD_PACKET; */ break; default: data += 1; len -= 1; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); break; }}static void setbrightness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; __u8 brightness = sd->brightness; reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);}static void getbrightness(struct gspca_dev *gspca_dev){ struct sd *sd = (struct sd *) gspca_dev; sd->brightness = 255 - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2) + (reg_read(gspca_dev, 5, 0x0, 1) << 6));}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;}/* sub-driver description */static const 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, .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan,};/* -- module initialisation -- */static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ {}};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 + -
显示快捷键?