📄 ov511 v1.28.c
字号:
if (rc < 0) err("reset: command failed"); return rc;}/* Temporarily stops OV511 from functioning. Must do this before changing * registers while the camera is streaming */static inline int ov511_stop(struct usb_device *dev){ PDEBUG(4, "stopping"); return (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x3d));}/* Restarts OV511 after ov511_stop() is called */static inline int ov511_restart(struct usb_device *dev){ PDEBUG(4, "restarting"); return (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x00));}static int ov511_set_packet_size(struct usb_ov511 *ov511, int size){ int alt, mult; if (ov511_stop(ov511->dev) < 0) return -EIO; mult = size >> 5; if (ov511->bridge == BRG_OV511) { if (size == 0) alt = OV511_ALT_SIZE_0; else if (size == 257) alt = OV511_ALT_SIZE_257; else if (size == 513) alt = OV511_ALT_SIZE_513; else if (size == 769) alt = OV511_ALT_SIZE_769; else if (size == 993) alt = OV511_ALT_SIZE_993; else { err("Set packet size: invalid size (%d)", size); return -EINVAL; } } else if (ov511->bridge == BRG_OV511PLUS) { if (size == 0) alt = OV511PLUS_ALT_SIZE_0; else if (size == 33) alt = OV511PLUS_ALT_SIZE_33; else if (size == 129) alt = OV511PLUS_ALT_SIZE_129; else if (size == 257) alt = OV511PLUS_ALT_SIZE_257; else if (size == 385) alt = OV511PLUS_ALT_SIZE_385; else if (size == 513) alt = OV511PLUS_ALT_SIZE_513; else if (size == 769) alt = OV511PLUS_ALT_SIZE_769; else if (size == 961) alt = OV511PLUS_ALT_SIZE_961; else { err("Set packet size: invalid size (%d)", size); return -EINVAL; } } else { err("Set packet size: Invalid bridge type"); return -EINVAL; } PDEBUG(3, "set packet size: %d, mult=%d, alt=%d", size, mult, alt); if (ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE, mult) < 0) return -ENOMEM; if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) { err("Set packet size: set interface error"); return -EBUSY; } // FIXME - Should we only reset the FIFO? if (ov511_reset(ov511->dev, OV511_RESET_NOREGS) < 0) return -ENOMEM; ov511->packet_size = size; if (ov511_restart(ov511->dev) < 0) return -EIO; return 0;}static inline intov7610_set_picture(struct usb_ov511 *ov511, struct video_picture *p){ int ret; struct usb_device *dev = ov511->dev; PDEBUG(4, "ov511_set_picture"); if (ov511_stop(dev) < 0) return -EIO; ov511->contrast = p->contrast; ov511->brightness = p->brightness; ov511->colour = p->colour; ov511->hue = p->hue; ov511->whiteness = p->whiteness; if ((ret = ov511_i2c_read(dev, OV7610_REG_COM_B)) < 0) return -EIO;#if 0 /* disable auto adjust mode */ if (ov511_i2c_write(dev, OV7610_REG_COM_B, ret & 0xfe) < 0) return -EIO;#endif if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE || ov511->sensor == SEN_OV6620) if (ov511_i2c_write(dev, OV7610_REG_SAT, p->colour >> 8) < 0) return -EIO; if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV6620) { if (ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0) return -EIO; if (ov511_i2c_write(dev, OV7610_REG_RED, 0xFF - (p->hue >> 8)) < 0) return -EIO; if (ov511_i2c_write(dev, OV7610_REG_BLUE, p->hue >> 8) < 0) return -EIO; if (ov511_i2c_write(dev, OV7610_REG_BRT, p->brightness >> 8) < 0) return -EIO; } else if ((ov511->sensor == SEN_OV7620) || (ov511->sensor == SEN_OV7620AE)) {#if 0 int cur_sat, new_sat, tmp; cur_sat = ov511_i2c_read(dev, OV7610_REG_BLUE); tmp = (p->hue >> 8) - cur_sat; new_sat = (tmp < 0) ? (-tmp) | 0x80 : tmp; PDEBUG(1, "cur=%d target=%d diff=%d", cur_sat, p->hue >> 8, tmp); if (ov511_i2c_write(dev, OV7610_REG_BLUE, new_sat) < 0) return -EIO; // DEBUG_CODE PDEBUG(1, "hue=%d", ov511_i2c_read(dev, OV7610_REG_BLUE)); #endif } if (ov511_restart(dev) < 0) return -EIO; return 0;}static inline intov7610_get_picture(struct usb_ov511 *ov511, struct video_picture *p){ int ret; struct usb_device *dev = ov511->dev; PDEBUG(4, "ov511_get_picture"); if (ov511_stop(dev) < 0) return -EIO; if ((ret = ov511_i2c_read(dev, OV7610_REG_SAT)) < 0) return -EIO; p->colour = ret << 8; if ((ret = ov511_i2c_read(dev, OV7610_REG_CNT)) < 0) return -EIO; p->contrast = ret << 8; if ((ret = ov511_i2c_read(dev, OV7610_REG_BRT)) < 0) return -EIO; p->brightness = ret << 8; /* This may not be the best way to do it */ if ((ret = ov511_i2c_read(dev, OV7610_REG_BLUE)) < 0) return -EIO; p->hue = ret << 8; p->whiteness = 105 << 8; /* Can we get these from frame[0]? -claudio? */ p->depth = ov511->frame[0].depth; p->palette = ov511->frame[0].format; if (ov511_restart(dev) < 0) return -EIO; return 0;}/* Returns number of bits per pixel (regardless of where they are located; planar or * not), or zero for unsupported format. */static int ov511_get_depth(int palette){ switch (palette) { case VIDEO_PALETTE_GREY: return 8; case VIDEO_PALETTE_RGB565: return 16; case VIDEO_PALETTE_RGB24: return 24; case VIDEO_PALETTE_YUV422: return 16; case VIDEO_PALETTE_YUYV: return 16; case VIDEO_PALETTE_YUV420: return 24; case VIDEO_PALETTE_YUV422P: return 24; /* Planar */ default: return 0; /* Invalid format */ }}/* LNCNT values fixed by Lawrence Glaister <lg@jfm.bc.ca> */static struct mode_list mlist[] = { /* W H C PXCNT LNCNT PXDIV LNDIV M420 COMA COML */ { 640, 480, 0, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e }, { 640, 480, 1, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e }, { 320, 240, 0, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 320, 240, 1, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 352, 288, 0, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 352, 288, 1, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 384, 288, 0, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 384, 288, 1, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 448, 336, 0, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 448, 336, 1, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 176, 144, 0, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 176, 144, 1, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 160, 120, 0, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 160, 120, 1, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e }, { 0, 0 }};static intov511_mode_init_regs(struct usb_ov511 *ov511, int width, int height, int mode, int sub_flag){ int i; struct usb_device *dev = ov511->dev; int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; int hwscale = 0, vwscale = 0; PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", width, height, mode, sub_flag); if (ov511_stop(ov511->dev) < 0) return -EIO; /* Dumppix only works with RGB24 */ if (dumppix && (mode != VIDEO_PALETTE_RGB24)) { err("dumppix only supported with RGB 24"); return -EINVAL; } if (mode == VIDEO_PALETTE_GREY) { ov511_reg_write(dev, 0x16, 0x00); if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE) { /* these aren't valid on the OV6620/OV7620 */ ov511_i2c_write(dev, 0x0e, 0x44); } ov511_i2c_write(dev, 0x13, autoadjust ? 0x21 : 0x20); /* For snapshot */ ov511_reg_write(dev, 0x1e, 0x00); ov511_reg_write(dev, 0x1f, 0x01); } else { ov511_reg_write(dev, 0x16, 0x01); if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE) { /* not valid on the OV6620/OV7620 */ ov511_i2c_write(dev, 0x0e, 0x04); } ov511_i2c_write(dev, 0x13, autoadjust ? 0x01 : 0x00); /* For snapshot */ ov511_reg_write(dev, 0x1e, 0x01); ov511_reg_write(dev, 0x1f, 0x03); } /* The different sensor ICs handle setting up of window differently */ switch (ov511->sensor) { case SEN_OV7610: case SEN_OV7620AE: hwsbase = 0x38; hwebase = 0x3a; vwsbase = vwebase = 0x05; break; case SEN_OV6620: hwsbase = 0x38; hwebase = 0x3a; vwsbase = 0x05; vwebase = 0x06; break; case SEN_OV7620: hwsbase = 0x2c; hwebase = 0x2d; vwsbase = vwebase = 0x05; break; default: err("Invalid sensor"); return -EINVAL; } /* Bit 5 of COM C register varies with sensor */ if (ov511->sensor == SEN_OV6620) { if (width > 176 && height > 144) { /* CIF */ ov511_i2c_write(dev, 0x14, 0x04); hwscale = 1; vwscale = 1; /* The datasheet says 0; it's wrong */ hwsize = 352; vwsize = 288; } else { /* QCIF */ ov511_i2c_write(dev, 0x14, 0x24); hwsize = 176; vwsize = 144; } } else { if (width > 320 && height > 240) { /* VGA */ ov511_i2c_write(dev, 0x14, 0x04); hwscale = 2; vwscale = 1; hwsize = 640; vwsize = 480; } else { /* QVGA */ ov511_i2c_write(dev, 0x14, 0x24); hwscale = 1; hwsize = 320; vwsize = 240; } } /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */ if (sub_flag) { ov511_i2c_write(dev, 0x17, hwsbase+(ov511->subx>>hwscale)); ov511_i2c_write(dev, 0x18, hwebase+((ov511->subx+ov511->subw)>>hwscale)); ov511_i2c_write(dev, 0x19, vwsbase+(ov511->suby>>vwscale)); ov511_i2c_write(dev, 0x1a, vwebase+((ov511->suby+ov511->subh)>>vwscale)); } else { ov511_i2c_write(dev, 0x17, hwsbase); ov511_i2c_write(dev, 0x18, hwebase + (hwsize>>hwscale)); ov511_i2c_write(dev, 0x19, vwsbase); ov511_i2c_write(dev, 0x1a, vwebase + (vwsize>>vwscale)); } for (i = 0; mlist[i].width; i++) { int lncnt, pxcnt, clock; if (width != mlist[i].width || height != mlist[i].height) continue; if (!mlist[i].color && mode != VIDEO_PALETTE_GREY) continue; /* Here I'm assuming that snapshot size == image size. * I hope that's always true. --claudio */ pxcnt = sub_flag ? (ov511->subw >> 3) - 1 : mlist[i].pxcnt; lncnt = sub_flag ? (ov511->subh >> 3) - 1 : mlist[i].lncnt; ov511_reg_write(dev, 0x12, pxcnt); ov511_reg_write(dev, 0x13, lncnt); ov511_reg_write(dev, 0x14, mlist[i].pxdv); ov511_reg_write(dev, 0x15, mlist[i].lndv); ov511_reg_write(dev, 0x18, mlist[i].m420); /* Snapshot additions */ ov511_reg_write(dev, 0x1a, pxcnt); ov511_reg_write(dev, 0x1b, lncnt); ov511_reg_write(dev, 0x1c, mlist[i].pxdv); ov511_reg_write(dev, 0x1d, mlist[i].lndv);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -