⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spca5xx.c

📁 应用于linux系统的usb接口的摄像头驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* reset iso context */    spca50x->compress = compress;    spca50x->curframe = 0;    spca50x->cursbuf = 0;    spca50x->frame[0].seq = -1;    spca50x->lastFrameRead = -1;    spca50x_set_packet_size(spca50x, spca50x->pipe_size);    PDEBUG(2, "setpacketsize %d", spca50x->pipe_size);    for (n = 0; n < SPCA50X_NUMSBUF; n++) {	urb = usb_alloc_urb(FRAMES_PER_DESC);	if (!urb) {	    err("init isoc: usb_alloc_urb ret. NULL");	    return -ENOMEM;	}	spca50x->sbuf[n].urb = urb;	urb->dev = spca50x->dev;	urb->context = spca50x;	if (spca50x->bridge == BRIDGE_PAC207) {	    urb->pipe =		usb_rcvisocpipe(spca50x->dev, PAC207_ENDPOINT_ADDRESS);	} else {	    urb->pipe =		usb_rcvisocpipe(spca50x->dev, SPCA50X_ENDPOINT_ADDRESS);	}	urb->transfer_flags = USB_ISO_ASAP;	urb->transfer_buffer = spca50x->sbuf[n].data;	urb->complete = spca50x_isoc_irq;	urb->number_of_packets = FRAMES_PER_DESC;	urb->transfer_buffer_length =	    spca50x->packet_size * FRAMES_PER_DESC;	for (fx = 0; fx < FRAMES_PER_DESC; fx++) {	    urb->iso_frame_desc[fx].offset = spca50x->packet_size * fx;	    urb->iso_frame_desc[fx].length = spca50x->packet_size;	}    }#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)    spca50x->sbuf[SPCA50X_NUMSBUF - 1].urb->next = spca50x->sbuf[0].urb;    for (n = 0; n < SPCA50X_NUMSBUF - 1; n++)	spca50x->sbuf[n].urb->next = spca50x->sbuf[n + 1].urb;#endif    spcaCameraStart(spca50x);    if (spca50x->bridge == BRIDGE_SONIX) {	intpipe = usb_rcvintpipe(spca50x->dev, 3);	usb_clear_halt(spca50x->dev, intpipe);    }    PDEBUG(5, "init isoc int %d altsetting %d", spca50x->iface,	   spca50x->alt);    for (n = 0; n < SPCA50X_NUMSBUF; n++) {	spca50x->sbuf[n].urb->dev = spca50x->dev;	err = usb_submit_urb(spca50x->sbuf[n].urb);		if (err) {	    err("init isoc: usb_submit_urb(%d) ret %d", n, err);	    return err;	}    }    for (n = 0; n < SPCA50X_NUMFRAMES; n++) {	spca50x->frame[n].grabstate = FRAME_UNUSED;	spca50x->frame[n].scanstate = STATE_SCANNING;    }    spca50x->streaming = 1;    return 0;}/*********************************************************************** spca50x_stop_isoc* Function stops the USB ISO pipe by stopping the chip ISO machine* and stopping USB transfer***********************************************************************/static void spca5xx_kill_isoc(struct usb_spca50x *spca50x){    int n;    if (!spca50x)	return;    PDEBUG(3, "*** killing capture ***");    spca50x->streaming = 0;    /* Unschedule all of the iso td's */    for (n = SPCA50X_NUMSBUF - 1; n >= 0; n--) {	if (spca50x->sbuf[n].urb) {	    usb_unlink_urb(spca50x->sbuf[n].urb);	    usb_free_urb(spca50x->sbuf[n].urb);	    spca50x->sbuf[n].urb = NULL;	}    }    PDEBUG(3, "*** Isoc killed ***");}static void spca50x_stop_isoc(struct usb_spca50x *spca50x){    if (!spca50x->streaming || !spca50x->dev)	return;    PDEBUG(3, "*** Stopping capture ***");    spcaCameraStop(spca50x);    spca5xx_kill_isoc(spca50x);    spca50x_set_packet_size(spca50x, 0);    if (spca50x->bridge == BRIDGE_CX11646)	cx11646_stop(spca50x);    PDEBUG(3, "*** Capture stopped ***");}/*********************************************************************** spca50x_find_mode_index* Function finds the mode index in the modes table***********************************************************************/static inline intspca50x_find_mode_index(int width, int height, __u16 ext_modes[][6]){    int i = 0;    int j = 0;    /* search through the mode list until we hit one which has     * a smaller or equal resolution, or we run out of modes.     */    for (i = 0; ext_modes[i][0] &&	 (ext_modes[i][0] >= width && ext_modes[i][1] >= height); i++) {	if (((ext_modes[i][2] & 0xF0) >> 4) == 0)	    j = (i & 0x0F) << 4;    }    /* search to found the first hardware available mode */    i--;			/* FIXME */    PDEBUG(2, "find Hardware mode %d soft mode %d", j >> 4, i);    /* check whether we found the requested mode, or ran out of     * modes in the list.     */    if (!ext_modes[i][0] ||	ext_modes[i][0] != width || ext_modes[i][1] != height) {	PDEBUG(3, "Failed to find mode %d x %d", width, height);	return -EINVAL;    }    i = (i & 0x0F) | j;    PDEBUG(2, "Pass Hardware mode %d soft mode %d", (i >> 4), (i & 0x0F));    /* return the index of the requested mode */    return i;}/*********************************************************************** spca50x_smallest_mode_index* Function finds the mode index in the modes table of the smallest* available mode.***********************************************************************/static int spca5xx_getDefaultMode(struct usb_spca50x *spca50x){    int i;    for (i = QCIF; i < TOTMODE; i++) {	if (spca50x->mode_cam[i].method == 0 && spca50x->mode_cam[i].width) {	    spca50x->width = spca50x->mode_cam[i].width;	    spca50x->height = spca50x->mode_cam[i].height;	    spca50x->method = 0;	    spca50x->pipe_size = spca50x->mode_cam[i].pipe;	    spca50x->mode = spca50x->mode_cam[i].mode;	    return 0;	}    }    return -EINVAL;}static inline intspca50x_smallest_mode_index(__u16 ext_modes[][6],			    int *cols, int *rows, int *pipe){    int i;    int width = INT_MAX;    int height = INT_MAX;    int intpipe = 1023;    int index = -EINVAL;    /* search through the mode list until we run out of modes */    /* and take the smallest hardware mode and pipe size */    for (i = 0; ext_modes[i][0]; i++) {	if (ext_modes[i][0] < width || ext_modes[i][1] < height) {	    if (!(ext_modes[i][2] & 0xF0)) {		width = ext_modes[i][0];		height = ext_modes[i][1];		intpipe = ext_modes[i][5];		index = i;	    }	}    }    /* return the index of the smallest mode */    if (index != -EINVAL) {	*pipe = intpipe;	if (cols != NULL)	    *cols = width;	if (rows != NULL)	    *rows = height;    }    return i;}/*********************************************************************** spca50x_set_mode* Function sets up the resolution directly. * Attention!!! index, the index in modes array is NOT checked. ***********************************************************************/static int spca5xx_getcapability(struct usb_spca50x *spca50x){    int maxw, maxh, minw, minh;    int i;    minw = minh = 255 * 255;    maxw = maxh = 0;    for (i = QCIF; i < TOTMODE; i++) {	if (spca50x->mode_cam[i].width) {	    if (maxw < spca50x->mode_cam[i].width		|| maxh < spca50x->mode_cam[i].height) {		maxw = spca50x->mode_cam[i].width;		maxh = spca50x->mode_cam[i].height;	    }	    if (minw > spca50x->mode_cam[i].width		|| minh > spca50x->mode_cam[i].height) {		minw = spca50x->mode_cam[i].width;		minh = spca50x->mode_cam[i].height;	    }	}    }    spca50x->maxwidth = maxw;    spca50x->maxheight = maxh;    spca50x->minwidth = minw;    spca50x->minheight = minh;    PDEBUG(0, "maxw %d maxh %d minw %d minh %d", maxw, maxh, minw, minh);    return 0;}static inline int v4l_to_spca5xx(int format){    switch (format) {    case VIDEO_PALETTE_RGB565:	return P_RGB16;    case VIDEO_PALETTE_RGB24:	return P_RGB24;    case VIDEO_PALETTE_RGB32:	return P_RGB32;    case VIDEO_PALETTE_YUV422P:	return P_YUV422;    case VIDEO_PALETTE_YUV420P:	return P_YUV420;    case VIDEO_PALETTE_RAW_JPEG:	return P_RAW;    case VIDEO_PALETTE_JPEG:	return P_JPEG;    default:	return -EINVAL;    }}static inline int spca5xx_setMode(struct usb_spca50x *spca50x, int width,				  int height, int format){    int i, j;    int formatIn;    int crop = 0, cropx1 = 0, cropx2 = 0, cropy1 = 0, cropy2 = 0, x =	0, y = 0;    /* Avoid changing to already selected mode */    /* convert V4l format to our internal format */    PDEBUG(2, "Set mode asked w %d h %d p %d", width, height, format);    if ((formatIn = v4l_to_spca5xx(format)) < 0)	return -EINVAL;    for (i = QCIF; i < TOTMODE; i++) {	if ((spca50x->mode_cam[i].width == width) &&	    (spca50x->mode_cam[i].height == height) &&	    (spca50x->mode_cam[i].t_palette & formatIn)) {	    spca50x->width = spca50x->mode_cam[i].width;	    spca50x->height = spca50x->mode_cam[i].height;	    spca50x->pipe_size = spca50x->mode_cam[i].pipe;	    spca50x->mode = spca50x->mode_cam[i].mode;	    spca50x->method = spca50x->mode_cam[i].method;	    spca50x->format = format;	//palette in use	    if (spca50x->method) {		if (spca50x->method == 1) {		    for (j = i; j < TOTMODE; j++) {			if (spca50x->mode_cam[j].method == 0			    && spca50x->mode_cam[j].width) {			    spca50x->hdrwidth = spca50x->mode_cam[j].width;			    spca50x->hdrheight =				spca50x->mode_cam[j].height;			    spca50x->mode = spca50x->mode_cam[j].mode;	// overwrite by the hardware mode			    break;			}		    }		// end match hardware mode		    if (!spca50x->hdrwidth && !spca50x->hdrheight)			return -EINVAL;		}	    }	    /* match found */	    break;	}    }				// end match mode    /* initialize the hdrwidth and hdrheight for the first init_source */    /* precompute the crop x y value for each frame */    if (!spca50x->method) {	/* nothing todo hardware found stream */	cropx1 = cropx2 = cropy1 = cropy2 = x = y = 0;	spca50x->hdrwidth = spca50x->width;	spca50x->hdrheight = spca50x->height;    }    if (spca50x->method & 0x01) {	/* cropping method */	if (spca50x->hdrwidth > spca50x->width) {	    crop = (spca50x->hdrwidth - spca50x->width);	    if (spca50x->cameratype == JPEG || spca50x->cameratype == JPGH		|| spca50x->cameratype == JPGS)		crop = crop >> 4;	    cropx1 = crop >> 1;	    cropx2 = cropx1 + (crop % 2);	} else {	    cropx1 = cropx2 = 0;	}	if (spca50x->hdrheight > spca50x->height) {	    crop = (spca50x->hdrheight - spca50x->height);	    if (spca50x->cameratype == JPEG)		crop = crop >> 4;	    if (spca50x->cameratype == JPGH || spca50x->cameratype == JPGS)		crop = crop >> 3;	    cropy1 = crop >> 1;	    cropy2 = cropy1 + (crop % 2);	} else {	    cropy1 = cropy2 = 0;	}    }    if (spca50x->method & 0x02) {	/* what can put here for div method */    }    if (spca50x->method & 0x04) {	/* and here for mult */    }    PDEBUG(2, "Found code %d method %d", spca50x->mode, spca50x->method);    PDEBUG(2, "Soft Win width height %d x %d", spca50x->width,	   spca50x->height);    PDEBUG(2, "Hard Win width height %d x %d", spca50x->hdrwidth,	   spca50x->hdrheight);    for (i = 0; i < SPCA50X_NUMFRAMES; i++) {	spca50x->frame[i].method = spca50x->method;	spca50x->frame[i].cameratype = spca50x->cameratype;	spca50x->frame[i].cropx1 = cropx1;	spca50x->frame[i].cropx2 = cropx2;	spca50x->frame[i].cropy1 = cropy1;	spca50x->frame[i].cropy2 = cropy2;	spca50x->frame[i].x = x;	spca50x->frame[i].y = y;	spca50x->frame[i].hdrwidth = spca50x->hdrwidth;	spca50x->frame[i].hdrheight = spca50x->hdrheight;	spca50x->frame[i].width = spca50x->width;	spca50x->frame[i].height = spca50x->height;	spca50x->frame[i].format = spca50x->format;	spca50x->frame[i].scanlength =	    spca50x->width * spca50x->height * 3 / 2;	// ?? assumes 4:2:0 data    }    return 0;}static inline intspca50x_set_mode(struct usb_spca50x *spca50x,		 int index, __u16 ext_modes[][6]){    struct usb_device *dev = spca50x->dev;    int i;    int mode = 0;    int method = 0;    int crop = 0, cropx1 = 0, cropx2 = 0, cropy1 = 0, cropy2 = 0, x =	0, y = 0;    if (spca50x->bridge == BRIDGE_ETOMS) {	spca50x->mode = (ext_modes[index][2] & 0x0f);    } else if (spca50x->bridge == BRIDGE_TV8532) {	mode = (ext_modes[index][2]) & 0x0F;	method = (ext_modes[index][2] & 0xF0) >> 4;	spca50x->mode = mode;    } else if (spca50x->bridge == BRIDGE_CX11646) {	mode = (ext_modes[index][2]) & 0x0F;	method = (ext_modes[index][2] & 0xF0) >> 4;	spca50x->mode = mode;    }    else if (spca50x->bridge == BRIDGE_SPCA506) {	spca506_Setsize(spca50x, ext_modes[index][2], ext_modes[index][3],			ext_modes[index][4]);    } else if (spca50x->bridge == BRIDGE_SPCA505) {	spca50x_reg_write(dev, SPCA50X_REG_COMPRESS, 0x0,			  ext_modes[index][2]);	spca50x_reg_write(dev, SPCA50X_REG_COMPRESS, 0x6,			  ext_modes[index][3]);	spca50x_reg_write(dev, SPCA50X_REG_COMPRESS, 0x7,			  ext_modes[index][4]);    } else if (spca50x->bridge == BRIDGE_SPCA501) {	mode = (ext_modes[index][2]) & 0x0F;	method = (ext_modes[index][2] & 0xF0) >> 4;	spca50x_reg_write(dev, SPCA50X_REG_USB, 0x6, ext_modes[index][3]);	spca50x_reg_write(dev, SPCA50X_REG_USB, 0x7, ext_modes[index][4]);    } else if (spca50x->bridge == BRIDGE_SPCA508) {	spca50x_reg_write(dev, 0, 0x8500, ext_modes[index][2]);	// mode

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -