$NetBSD: patch-ab,v 1.4 2006/02/08 17:18:53 joerg Exp $ --- vid.c.orig 2000-05-08 04:59:03.000000000 +0000 +++ vid.c @@ -35,7 +35,11 @@ #include #include +#if defined(__DragonFly__) +#include +#else #include +#endif #include @@ -48,6 +52,8 @@ ov511_reg_read(int fd, int reg) { struct usb_ctl_request ur; unsigned char data[1024]; +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) + ur.request.bmRequestType = UT_READ_VENDOR_INTERFACE; ur.request.bRequest = 2; @@ -57,6 +63,17 @@ ov511_reg_read(int fd, int reg) { ur.data = data; ur.flags = 0; ur.actlen = 0; +#else + ur.ucr_request.bmRequestType = UT_READ_VENDOR_INTERFACE; + ur.ucr_request.bRequest = 2; + + USETW(ur.ucr_request.wValue, 0); /* unused */ + USETW(ur.ucr_request.wIndex, reg); /* index */ + USETW(ur.ucr_request.wLength, 1); /* payload len in bytes */ + ur.ucr_data = data; + ur.ucr_flags = 0; + ur.ucr_actlen = 0; +#endif if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; @@ -72,6 +89,8 @@ ov511_reg_write(int fd, int reg, int val data[0] = val; +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) + ur.request.bmRequestType = UT_WRITE_VENDOR_INTERFACE; ur.request.bRequest = 2; @@ -81,7 +100,17 @@ ov511_reg_write(int fd, int reg, int val ur.data = data; ur.flags = 0; ur.actlen = 0; - +#else + ur.ucr_request.bmRequestType = UT_WRITE_VENDOR_INTERFACE; + ur.ucr_request.bRequest = 2; + + USETW(ur.ucr_request.wValue, 0); /* unused */ + USETW(ur.ucr_request.wIndex, reg); /* index */ + USETW(ur.ucr_request.wLength, 1); /* payload len in bytes */ + ur.ucr_data = data; + ur.ucr_flags = 0; + ur.ucr_actlen = 0; +#endif if(ioctl(fd, USB_DO_REQUEST, &ur) < 0) { return -1; } @@ -217,12 +246,15 @@ main(int argc, char *argv[]) { struct vidstate vs; /* current read state */ int small = 0; /* use 320x240 */ int frmnm = 0; /* cyclic frame number key */ + int isplus; /* bridge is OV511+ if true, else OV511 */ + int is20; /* sensor is OV7620 if true, else OV7610 */ + int bufsize; /* size of packet buffer */ /* pnm_init(&argc, argv); */ /* required for PNM programs? */ while(++argv, --argc) { if(strcmp(*argv, "--version") == 0) { - fprintf(stderr, "OV511 capture program version " VERSION + fprintf(stderr, "OV511/OV511+ capture program version " VERSION "\nCopyright 2000 Peter S. Housel" "\nThis program is free software; " "you may redistribute it under the terms of" @@ -235,14 +267,14 @@ main(int argc, char *argv[]) { exit(0); } else if(strcmp(*argv, "--help") == 0) { fprintf(stderr, "usage: vid [options]\n" - "Capture an image frame from an OV511-based USB video camera\n" + "Capture an image frame from an OV511/OV511+-based USB video camera\n" "and write image data to standard output in PNM format\n\n" "--version print program version information\n" "--usage summarize command line options\n" "--help print this description\n" "--small capture as 320x240 image (default is 640x480)\n" "-d device, --device-name=device\n" - " specify OV511 ugen device\n"); + " specify OV511/OV511+ ugen device\n"); exit(0); } else if(strcmp(*argv, "--small") == 0) { small = 1; @@ -287,18 +319,33 @@ main(int argc, char *argv[]) { exit(1); } - if(udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) { - fprintf(stderr, "device %s is not an OmniVision OV511\n", devname); +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) + + if(udi.vendorNo != 0x05A9 || udi.productNo != 0x0511 && udi.productNo != 0xa511) { +#else + if(udi.udi_vendorNo != 0x05A9 || udi.udi_productNo != 0x0511 && udi.udi_productNo != 0xa511) { +#endif + + fprintf(stderr, "device %s is not an OmniVision OV511/OV511+\n", devname); exit(1); } } else { int i = 0; for(i = 0; i < 15; ++i) { +#ifdef __NetBSD__ + sprintf(dev, "/dev/ugen%d.00", i); +#else sprintf(dev, "/dev/ugen%d", i); +#endif if((fd = open(dev, O_RDWR)) < 0) continue; +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) + if(ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0 + || udi.vendorNo != 0x05A9 || udi.productNo != 0x0511 && udi.productNo != 0xa511) { +#else if(ioctl(fd, USB_GET_DEVICEINFO, &udi) < 0 - || udi.vendorNo != 0x05A9 || udi.productNo != 0x0511) { + || udi.udi_vendorNo != 0x05A9 || udi.udi_productNo != 0x0511 && udi.udi_productNo != 0xa511) { +#endif close(fd); fd = -1; continue; @@ -308,12 +355,18 @@ main(int argc, char *argv[]) { } if(fd < 0) { - fprintf(stderr, "vid: couldn't locate an OV511 device\n"); + fprintf(stderr, "vid: couldn't locate an OV511/OV511+ device\n"); exit(1); } devname = dev; } +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) + isplus = udi.productNo == 0xa511; +#else + isplus = udi.udi_productNo == 0xa511; +#endif + bufsize = (isplus ? 961 : 993); /* reset the OV511 */ if(ov511_reg_write(fd, OV511_REG_RST, 0x7f) < 0) @@ -398,23 +451,56 @@ main(int argc, char *argv[]) { if(ov511_reg_write(fd, OV511_REG_CE_EN, 0x0) < 0) exit(1); - ov511_i2c_write(fd, OV7610_REG_RWB, 0x5); - ov511_i2c_write(fd, OV7610_REG_EC, 0xFF); - ov511_i2c_write(fd, OV7610_REG_COMB, 0x01); - ov511_i2c_write(fd, OV7610_REG_FD, 0x06); - ov511_i2c_write(fd, OV7610_REG_COME, 0x1c); - ov511_i2c_write(fd, OV7610_REG_COMF, 0x90); - ov511_i2c_write(fd, OV7610_REG_ECW, 0x2e); - ov511_i2c_write(fd, OV7610_REG_ECB, 0x7C); - ov511_i2c_write(fd, OV7610_REG_COMH, 0x24); - ov511_i2c_write(fd, OV7610_REG_EHSH, 0x04); - ov511_i2c_write(fd, OV7610_REG_EHSL, 0xAC); - ov511_i2c_write(fd, OV7610_REG_EXBK, 0xFE); - ov511_i2c_write(fd, OV7610_REG_COMJ, 0x93); - ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48); - ov511_i2c_write(fd, OV7610_REG_COMK, 0x81); + /* This returns 0 if we have an OV7620 sensor */ + if((is20 = ov511_i2c_read(fd, OV7610_REG_COMI)) < 0) + exit(1); + is20 = !is20; + + /* set up the OV7610/OV7620 */ + if(is20) { + ov511_i2c_write(fd, OV7610_REG_EC, 0xff); + ov511_i2c_write(fd, OV7610_REG_FD, 0x06); + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24); + ov511_i2c_write(fd, OV7610_REG_EHSL, 0xac); + ov511_i2c_write(fd, OV7610_REG_COMA, 0x00); + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24); + ov511_i2c_write(fd, OV7610_REG_RWB, 0x85); + ov511_i2c_write(fd, OV7610_REG_COMD, 0x01); + ov511_i2c_write(fd, 0x23, 0x00); + ov511_i2c_write(fd, OV7610_REG_ECW, 0x10); + ov511_i2c_write(fd, OV7610_REG_ECB, 0x8a); + ov511_i2c_write(fd, OV7610_REG_COMG, 0xe2); + ov511_i2c_write(fd, OV7610_REG_EHSH, 0x00); + ov511_i2c_write(fd, OV7610_REG_EXBK, 0xfe); + ov511_i2c_write(fd, 0x30, 0x71); + ov511_i2c_write(fd, 0x31, 0x60); + ov511_i2c_write(fd, 0x32, 0x26); + ov511_i2c_write(fd, OV7610_REG_YGAM, 0x20); + ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48); + ov511_i2c_write(fd, OV7610_REG_COMA, 0x24); + ov511_i2c_write(fd, OV7610_REG_SYN_CLK, 0x01); + ov511_i2c_write(fd, OV7610_REG_BBS, 0x24); + ov511_i2c_write(fd, OV7610_REG_RBS, 0x24); + } else { + ov511_i2c_write(fd, OV7610_REG_GC, 0x00); + ov511_i2c_write(fd, OV7610_REG_RWB, 0x05); + ov511_i2c_write(fd, OV7610_REG_EC, 0xFF); + ov511_i2c_write(fd, OV7610_REG_COMB, 0x01); + ov511_i2c_write(fd, OV7610_REG_FD, 0x06); + ov511_i2c_write(fd, OV7610_REG_COME, 0x1c); + ov511_i2c_write(fd, OV7610_REG_COMF, 0x90); + ov511_i2c_write(fd, OV7610_REG_ECW, 0x2e); + ov511_i2c_write(fd, OV7610_REG_ECB, 0x7C); + ov511_i2c_write(fd, OV7610_REG_COMH, 0x24); + ov511_i2c_write(fd, OV7610_REG_EHSH, 0x04); + ov511_i2c_write(fd, OV7610_REG_EHSL, 0xAC); + ov511_i2c_write(fd, OV7610_REG_EXBK, 0xFE); + ov511_i2c_write(fd, OV7610_REG_COMJ, 0x93); + ov511_i2c_write(fd, OV7610_REG_BADJ, 0x48); + ov511_i2c_write(fd, OV7610_REG_COMK, 0x81); - ov511_i2c_write(fd, OV7610_REG_GAM, 0x04); + ov511_i2c_write(fd, OV7610_REG_GAM, 0x04); + } if(small) { vs.width = 320; @@ -442,14 +528,19 @@ main(int argc, char *argv[]) { ov511_reg_write(fd, OV511_REG_LNDV, 0x00); /* set FIFO format (993-byte packets) */ - if(ov511_reg_write(fd, OV511_REG_PKSZ, 0x1F) < 0) + if(ov511_reg_write(fd, OV511_REG_PKSZ, bufsize/32) < 0) exit(1); if(ov511_reg_write(fd, OV511_REG_PKFMT, 0x03) < 0) exit(1); /* select the 993-byte alternative */ +#if !defined(USB_STACK_VERSION) ||(USB_STACK_VERSION < 2) alt.interface_index = 0; - alt.alt_no = 1; + alt.alt_no = (isplus ? 7 : 1); +#else + alt.uai_interface_index = 0; + alt.uai_alt_no = (isplus ? 7 : 1); +#endif if(ioctl(fd, USB_SET_ALTINTERFACE, &alt) < 0) { perror("USB_SET_ALTINTERFACE"); exit(1); @@ -468,43 +559,50 @@ main(int argc, char *argv[]) { vs.xels = pnm_allocarray(vs.width, vs.height); /* open the isochronous endpoint (endpoint 1) */ - sprintf(isocdev, "%s.1", devname); +#ifdef __NetBSD__ + sprintf(isocdev, "%s.01", strtok(devname,".")); +#else + sprintf(isocdev, "%s.01", devname); +#endif if((isoc = open(isocdev, O_RDONLY)) < 0) { perror(isocdev); exit(1); } /* read, looking for start and end frames */ - while(vs.state != DONE && (len = read(isoc, &buf, 993)) >= 0) { + while(vs.state != DONE && (len = read(isoc, &buf, bufsize)) >= 0) { if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 - && (buf[8] & 0x80) == 0 && buf[992] == 0 && vs.state == SKIPPING) { - vs.state = READING; - vs.iY = vs.jY = vs.iUV = vs.jUV = 0; - vs.residue = 0; - procdata(&vs, buf + 9, 993 - 10); + && (buf[8] & 0x80) == 0 && buf[bufsize-1] == 0 && vs.state == SKIPPING) { + vs.state = READING; + vs.iY = vs.jY = vs.iUV = vs.jUV = 0; + vs.residue = 0; + procdata(&vs, buf + 9, bufsize - 10); } else if(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 - && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 - && (buf[8] & 0x80) == 0x80 && buf[992] == 0 + && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0 + && (buf[8] & 0x80) == 0x80 && buf[bufsize-1] == 0 && vs.state == READING) { vs.state = DONE; } else if(vs.state == READING) { - procdata(&vs, buf, 993 - 1); + procdata(&vs, buf, bufsize - 1); /* abort the capture and start over if packets come in out-of-order */ - if(buf[992] != frmnm && buf[992] != 1) { + if(buf[bufsize-1] != frmnm && buf[bufsize-1] != 1) { vs.state = SKIPPING; } - frmnm = buf[992] + 1; + frmnm = buf[bufsize-1] + 1; if(frmnm == 256) frmnm = 1; - } else if(buf[992] != 0) { - frmnm = buf[992] + 1; + } else if(buf[bufsize-1] != 0) { + frmnm = buf[bufsize-1] + 1; if(frmnm == 256) frmnm = 1; } } + /* reset and close the OV511 */ + ov511_reg_write(fd, OV511_REG_RST, 0x7f); + close(isoc); close(fd);