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

📄 stv680.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (stv680->SupportedModes == 0) {		PDEBUG (0, "STV(e): There are NO supported STV680 modes!!");		i = -1;		goto error;	} else {		if (stv680->CIF)			PDEBUG (0, "STV(i): CIF is supported");		if (stv680->QVGA)			PDEBUG (0, "STV(i): QVGA is supported");	}	/* FW rev, ASIC rev, sensor ID  */	PDEBUG (1, "STV(i): Firmware rev is %i.%i", buffer[0], buffer[1]);	PDEBUG (1, "STV(i): ASIC rev is %i.%i", buffer[2], buffer[3]);	PDEBUG (1, "STV(i): Sensor ID is %i", (buffer[4]*16) + (buffer[5]>>4));	/*  set alternate interface 1 */	if ((i = stv_set_config (stv680, 1, 0, 1)) < 0)		goto error;	if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)		goto error;	if ((i = stv_sndctrl (0, stv680, 0x8d, 0, buffer, 0x08)) != 0x08)		goto error;	i = buffer[3];	PDEBUG (0, "STV(i): Camera has %i pictures.", i);	/*  get current mode */	if ((i = stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08)) != 0x08)		goto error;	stv680->origMode = buffer[0];	/* 01 = VGA, 03 = QVGA, 00 = CIF */	/* This will attemp CIF mode, if supported. If not, set to QVGA  */	memset (buffer, 0, 8);	if (stv680->CIF)		buffer[0] = 0x00;	else if (stv680->QVGA)		buffer[0] = 0x03;	if ((i = stv_sndctrl (3, stv680, 0x07, 0x0100, buffer, 0x08)) != 0x08) {		PDEBUG (0, "STV(i): Set_Camera_Mode failed");		i = -1;		goto error;	}	buffer[0] = 0xf0;	stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08);	if (((stv680->CIF == 1) && (buffer[0] != 0x00)) || ((stv680->QVGA == 1) && (buffer[0] != 0x03))) {		PDEBUG (0, "STV(e): Error setting camera video mode!");		i = -1;		goto error;	} else {		if (buffer[0] == 0) {			stv680->VideoMode = 0x0000;			PDEBUG (0, "STV(i): Video Mode set to CIF");		}		if (buffer[0] == 0x03) {			stv680->VideoMode = 0x0300;			PDEBUG (0, "STV(i): Video Mode set to QVGA");		}	}	if ((i = stv_sndctrl (0, stv680, 0x8f, 0, buffer, 0x10)) != 0x10)		goto error;	bufsize = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);	stv680->cwidth = (buffer[4] << 8) | (buffer[5]);	/* ->camera = 322, 356, 644  */	stv680->cheight = (buffer[6] << 8) | (buffer[7]);	/* ->camera = 242, 292, 484  */	stv680->origGain = buffer[12];	goto exit;error:	i = stv_sndctrl (0, stv680, 0x80, 0, buffer, 0x02);	/* Get Last Error */	PDEBUG (1, "STV(i): last error: %i,  command = 0x%x", buffer[0], buffer[1]);	kfree (buffer);	return -1;exit:	kfree (buffer);	/* video = 320x240, 352x288 */	if (stv680->CIF == 1) {		stv680->maxwidth = 352;		stv680->maxheight = 288;		stv680->vwidth = 352;		stv680->vheight = 288;	}	if (stv680->QVGA == 1) {		stv680->maxwidth = 320;		stv680->maxheight = 240;		stv680->vwidth = 320;		stv680->vheight = 240;	}	stv680->rawbufsize = bufsize;	/* must be ./. by 8 */	stv680->maxframesize = bufsize * 3;	/* RGB size */	PDEBUG (2, "STV(i): cwidth = %i, cheight = %i", stv680->cwidth, stv680->cheight);	PDEBUG (1, "STV(i): width = %i, height = %i, rawbufsize = %li", stv680->vwidth, stv680->vheight, stv680->rawbufsize);	/* some default values */	stv680->bulk_in_endpointAddr = 0x82;	stv680->dropped = 0;	stv680->error = 0;	stv680->framecount = 0;	stv680->readcount = 0;	stv680->streaming = 0;	/* bright, white, colour, hue, contrast are set by software, not in stv0680 */	stv680->brightness = 32767;	stv680->chgbright = 0;	stv680->whiteness = 0;	/* only for greyscale */	stv680->colour = 32767;	stv680->contrast = 32767;	stv680->hue = 32767;	stv680->palette = STV_VIDEO_PALETTE;	stv680->depth = 24;	/* rgb24 bits */	swapRGB = 0;	if ((swapRGB_on == 0) && (swapRGB == 0))		PDEBUG (1, "STV(i): swapRGB is (auto) OFF");	else if ((swapRGB_on == 1) && (swapRGB == 1))		PDEBUG (1, "STV(i): swapRGB is (auto) ON");	else if (swapRGB_on == 1)		PDEBUG (1, "STV(i): swapRGB is (forced) ON");	else if (swapRGB_on == -1)		PDEBUG (1, "STV(i): swapRGB is (forced) OFF");		if (stv_set_video_mode (stv680) < 0) {		PDEBUG (0, "STV(e): Could not set video mode in stv_init");		return -1;	}	return 0;}/***************** last of pencam  routines  *******************//******************************************************************** * /proc interface *******************************************************************/#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)static struct proc_dir_entry *stv680_proc_entry = NULL;extern struct proc_dir_entry *video_proc_entry;#define YES_NO(x) ((x) ? "yes" : "no")#define ON_OFF(x) ((x) ? "(auto) on" : "(auto) off")static int stv680_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data){	char *out = page;	int len;	struct usb_stv *stv680 = data;	/* Stay under PAGE_SIZE or else bla bla bla.... */	out += sprintf (out, "driver_version  : %s\n", DRIVER_VERSION);	out += sprintf (out, "model           : %s\n", stv680->camera_name);	out += sprintf (out, "in use          : %s\n", YES_NO (stv680->user));	out += sprintf (out, "streaming       : %s\n", YES_NO (stv680->streaming));	out += sprintf (out, "num_frames      : %d\n", STV680_NUMFRAMES);	out += sprintf (out, "Current size    : %ix%i\n", stv680->vwidth, stv680->vheight);	if (swapRGB_on == 0)		out += sprintf (out, "swapRGB         : %s\n", ON_OFF (swapRGB));	else if (swapRGB_on == 1)		out += sprintf (out, "swapRGB         : (forced) on\n");	else if (swapRGB_on == -1)		out += sprintf (out, "swapRGB         : (forced) off\n");	out += sprintf (out, "Palette         : %i", stv680->palette);	out += sprintf (out, "\n");	out += sprintf (out, "Frames total    : %d\n", stv680->readcount);	out += sprintf (out, "Frames read     : %d\n", stv680->framecount);	out += sprintf (out, "Packets dropped : %d\n", stv680->dropped);	out += sprintf (out, "Decoding Errors : %d\n", stv680->error);	len = out - page;	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0)			return 0;	} else		len = count;	*start = page + off;	return len;}static int create_proc_stv680_cam (struct usb_stv *stv680){	char name[9];	struct proc_dir_entry *ent;	if (!stv680_proc_entry || !stv680)		return -1;	sprintf (name, "video%d", stv680->vdev.minor);	ent = create_proc_entry (name, S_IFREG | S_IRUGO | S_IWUSR, stv680_proc_entry);	if (!ent)		return -1;	ent->data = stv680;	ent->read_proc = stv680_read_proc;	stv680->proc_entry = ent;	return 0;}static void destroy_proc_stv680_cam (struct usb_stv *stv680){	/* One to much, just to be sure :) */	char name[9];	if (!stv680 || !stv680->proc_entry)		return;	sprintf (name, "video%d", stv680->vdev.minor);	remove_proc_entry (name, stv680_proc_entry);	stv680->proc_entry = NULL;}static int proc_stv680_create (void){	if (video_proc_entry == NULL) {		PDEBUG (0, "STV(e): /proc/video/ doesn't exist!");		return -1;	}	stv680_proc_entry = create_proc_entry ("stv680", S_IFDIR, video_proc_entry);	if (stv680_proc_entry) {		stv680_proc_entry->owner = THIS_MODULE;	} else {		PDEBUG (0, "STV(e): Unable to initialize /proc/video/stv680");		return -1;	}	return 0;}static void proc_stv680_destroy (void){	if (stv680_proc_entry == NULL)		return;	remove_proc_entry ("stv", video_proc_entry);}#endif				/* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS *//******************************************************************** * Camera control *******************************************************************/static int stv680_get_pict (struct usb_stv *stv680, struct video_picture *p){	/* This sets values for v4l interface. max/min = 65535/0  */	p->brightness = stv680->brightness;	p->whiteness = stv680->whiteness;	/* greyscale */	p->colour = stv680->colour;	p->contrast = stv680->contrast;	p->hue = stv680->hue;	p->palette = stv680->palette;	p->depth = stv680->depth;	return 0;}static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p){	/* See above stv680_get_pict  */	if (p->palette != STV_VIDEO_PALETTE) {		PDEBUG (2, "STV(e): Palette set error in _set_pic");		return 1;	}	if (stv680->brightness != p->brightness) {		stv680->chgbright = 1;		stv680->brightness = p->brightness;	} 	stv680->whiteness = p->whiteness;	/* greyscale */	stv680->colour = p->colour;	stv680->contrast = p->contrast;	stv680->hue = p->hue;	stv680->palette = p->palette;	stv680->depth = p->depth;	return 0;}static void stv680_video_irq (struct urb *urb){	struct usb_stv *stv680 = urb->context;	int length = urb->actual_length;	if (length < stv680->rawbufsize)		PDEBUG (2, "STV(i): Lost data in transfer: exp %li, got %i", stv680->rawbufsize, length);	/* ohoh... */	if (!stv680->streaming)		return;	if (!stv680->udev) {		PDEBUG (0, "STV(e): device vapourished in video_irq");		return;	}	/* 0 sized packets happen if we are to fast, but sometimes the camera	   keeps sending them forever...	 */	if (length && !urb->status) {		stv680->nullpackets = 0;		switch (stv680->scratch[stv680->scratch_next].state) {		case BUFFER_READY:		case BUFFER_BUSY:			stv680->dropped++;			break;		case BUFFER_UNUSED:			memcpy (stv680->scratch[stv680->scratch_next].data,			        (unsigned char *) urb->transfer_buffer, length);			stv680->scratch[stv680->scratch_next].state = BUFFER_READY;			stv680->scratch[stv680->scratch_next].length = length;			if (waitqueue_active (&stv680->wq)) {				wake_up_interruptible (&stv680->wq);			}			stv680->scratch_overflow = 0;			stv680->scratch_next++;			if (stv680->scratch_next >= STV680_NUMSCRATCH)				stv680->scratch_next = 0;;			break;		}		/* switch  */	} else {		stv680->nullpackets++;		if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {			if (waitqueue_active (&stv680->wq)) {				wake_up_interruptible (&stv680->wq);			}		}	}			/*  if - else */	/* Resubmit urb for new data */	urb->status = 0;	urb->dev = stv680->udev;	if (usb_submit_urb (urb))		PDEBUG (0, "STV(e): urb burned down in video irq");	return;}				/*  _video_irq  */static int stv680_start_stream (struct usb_stv *stv680){	urb_t *urb;	int err = 0, i;	stv680->streaming = 1;	/* Do some memory allocation */	for (i = 0; i < STV680_NUMFRAMES; i++) {		stv680->frame[i].data = stv680->fbuf + i * stv680->maxframesize;		stv680->frame[i].curpix = 0;	}	/* packet size = 4096  */	for (i = 0; i < STV680_NUMSBUF; i++) {		stv680->sbuf[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);		if (stv680->sbuf[i].data == NULL) {			PDEBUG (0, "STV(e): Could not kmalloc raw data buffer %i", i);			return -1;		}	}	stv680->scratch_next = 0;	stv680->scratch_use = 0;	stv680->scratch_overflow = 0;	for (i = 0; i < STV680_NUMSCRATCH; i++) {		stv680->scratch[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);		if (stv680->scratch[i].data == NULL) {			PDEBUG (0, "STV(e): Could not kmalloc raw scratch buffer %i", i);			return -1;		}		stv680->scratch[i].state = BUFFER_UNUSED;	}	for (i = 0; i < STV680_NUMSBUF; i++) {		urb = usb_alloc_urb (0);		if (!urb)			return ENOMEM;		/* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */		usb_fill_bulk_urb (urb, stv680->udev,				   usb_rcvbulkpipe (stv680->udev, stv680->bulk_in_endpointAddr),				   stv680->sbuf[i].data, stv680->rawbufsize,				   stv680_video_irq, stv680);		urb->timeout = PENCAM_TIMEOUT * 2;		urb->transfer_flags |= USB_QUEUE_BULK;		stv680->urb[i] = urb;		err = usb_submit_urb (stv680->urb[i]);		if (err)			PDEBUG (0, "STV(e): urb burned down in start stream");	}			/* i STV680_NUMSBUF */	stv680->framecount = 0;	return 0;}static int stv680_stop_stream (struct usb_stv *stv680){	int i;	if (!stv680->streaming || !stv680->udev)		return 1;	stv680->streaming = 0;	for (i = 0; i < STV680_NUMSBUF; i++)		if (stv680->urb[i]) {			stv680->urb[i]->next = NULL;			usb_unlink_urb (stv680->urb[i]);			usb_free_urb (stv680->urb[i]);			stv680->urb[i] = NULL;			kfree (stv680->sbuf[i].data);		}

⌨️ 快捷键说明

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