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

📄 cpia2_usb.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6)		return -EINVAL;	if(alt == cam->params.camera_state.stream_mode)		return 0;	cpia2_usb_stream_pause(cam);	configure_transfer_mode(cam, alt);	cam->params.camera_state.stream_mode = alt;	/* Reset the camera to prevent image quality degradation */	cpia2_reset_camera(cam);	cpia2_usb_stream_resume(cam);	return ret;}/****************************************************************************** * * set_alternate * *****************************************************************************/int set_alternate(struct camera_data *cam, unsigned int alt){	int ret = 0;	if(alt == cam->cur_alt)		return 0;	if (cam->cur_alt != USBIF_CMDONLY) {		DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY);		ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY);		if (ret != 0)			return ret;	}	if (alt != USBIF_CMDONLY) {		DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt);		ret = usb_set_interface(cam->dev, cam->iface, alt);		if (ret != 0)			return ret;	}	cam->old_alt = cam->cur_alt;	cam->cur_alt = alt;	return ret;}/****************************************************************************** * * free_sbufs * * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL * are assumed to be allocated. Non-NULL .urb members are also assumed to be * submitted (and must therefore be killed before they are freed). *****************************************************************************/static void free_sbufs(struct camera_data *cam){	int i;	for (i = 0; i < NUM_SBUF; i++) {		if(cam->sbuf[i].urb) {			usb_kill_urb(cam->sbuf[i].urb);			usb_free_urb(cam->sbuf[i].urb);			cam->sbuf[i].urb = NULL;		}		if(cam->sbuf[i].data) {			kfree(cam->sbuf[i].data);			cam->sbuf[i].data = NULL;		}	}}/******** Convenience functions*******//**************************************************************************** * *  write_packet * ***************************************************************************/static int write_packet(struct usb_device *udev,			u8 request, u8 * registers, u16 start, size_t size){	if (!registers || size <= 0)		return -EINVAL;	return usb_control_msg(udev,			       usb_sndctrlpipe(udev, 0),			       request,			       USB_TYPE_VENDOR | USB_RECIP_DEVICE,			       start,	/* value */			       0,	/* index */			       registers,	/* buffer */			       size,			       HZ);}/**************************************************************************** * *  read_packet * ***************************************************************************/static int read_packet(struct usb_device *udev,		       u8 request, u8 * registers, u16 start, size_t size){	if (!registers || size <= 0)		return -EINVAL;	return usb_control_msg(udev,			       usb_rcvctrlpipe(udev, 0),			       request,			       USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,			       start,	/* value */			       0,	/* index */			       registers,	/* buffer */			       size,			       HZ);}/****************************************************************************** * *  cpia2_usb_transfer_cmd * *****************************************************************************/int cpia2_usb_transfer_cmd(struct camera_data *cam,			   void *registers,			   u8 request, u8 start, u8 count, u8 direction){	int err = 0;	struct usb_device *udev = cam->dev;	if (!udev) {		ERR("%s: Internal driver error: udev is NULL\n", __func__);		return -EINVAL;	}	if (!registers) {		ERR("%s: Internal driver error: register array is NULL\n", __func__);		return -EINVAL;	}	if (direction == TRANSFER_READ) {		err = read_packet(udev, request, (u8 *)registers, start, count);		if (err > 0)			err = 0;	} else if (direction == TRANSFER_WRITE) {		err =write_packet(udev, request, (u8 *)registers, start, count);		if (err < 0) {			LOG("Control message failed, err val = %d\n", err);			LOG("Message: request = 0x%0X, start = 0x%0X\n",			    request, start);			LOG("Message: count = %d, register[0] = 0x%0X\n",			    count, ((unsigned char *) registers)[0]);		} else			err=0;	} else {		LOG("Unexpected first byte of direction: %d\n",		       direction);		return -EINVAL;	}	if(err != 0)		LOG("Unexpected error: %d\n", err);	return err;}/****************************************************************************** * *  submit_urbs * *****************************************************************************/static int submit_urbs(struct camera_data *cam){	struct urb *urb;	int fx, err, i;	for(i=0; i<NUM_SBUF; ++i) {		if (cam->sbuf[i].data)			continue;		cam->sbuf[i].data =		    kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);		if (!cam->sbuf[i].data) {			return -ENOMEM;		}	}	/* We double buffer the Isoc lists, and also know the polling	 * interval is every frame (1 == (1 << (bInterval -1))).	 */	for(i=0; i<NUM_SBUF; ++i) {		if(cam->sbuf[i].urb) {			continue;		}		urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);		if (!urb) {			return -ENOMEM;		}		cam->sbuf[i].urb = urb;		urb->dev = cam->dev;		urb->context = cam;		urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/);		urb->transfer_flags = URB_ISO_ASAP;		urb->transfer_buffer = cam->sbuf[i].data;		urb->complete = cpia2_usb_complete;		urb->number_of_packets = FRAMES_PER_DESC;		urb->interval = 1;		urb->transfer_buffer_length =			FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;		for (fx = 0; fx < FRAMES_PER_DESC; fx++) {			urb->iso_frame_desc[fx].offset =				FRAME_SIZE_PER_DESC * fx;			urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;		}	}	/* Queue the ISO urbs, and resubmit in the completion handler */	for(i=0; i<NUM_SBUF; ++i) {		err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL);		if (err) {			ERR("usb_submit_urb[%d]() = %d\n", i, err);			return err;		}	}	return 0;}/****************************************************************************** * *  cpia2_usb_stream_start * *****************************************************************************/int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate){	int ret;	int old_alt;	if(cam->streaming)		return 0;	if (cam->flush) {		int i;		DBG("Flushing buffers\n");		for(i=0; i<cam->num_frames; ++i) {			cam->buffers[i].status = FRAME_EMPTY;			cam->buffers[i].length = 0;		}		cam->curbuff = &cam->buffers[0];		cam->workbuff = cam->curbuff->next;		cam->flush = false;	}	old_alt = cam->params.camera_state.stream_mode;	cam->params.camera_state.stream_mode = 0;	ret = cpia2_usb_change_streaming_alternate(cam, alternate);	if (ret < 0) {		int ret2;		ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret);		cam->params.camera_state.stream_mode = old_alt;		ret2 = set_alternate(cam, USBIF_CMDONLY);		if (ret2 < 0) {			ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already "			    "failed. Then tried to call "			    "set_alternate(USBIF_CMDONLY) = %d.\n",			    alternate, ret, ret2);		}	} else {		cam->frame_count = 0;		cam->streaming = 1;		ret = cpia2_usb_stream_resume(cam);	}	return ret;}/****************************************************************************** * *  cpia2_usb_stream_pause * *****************************************************************************/int cpia2_usb_stream_pause(struct camera_data *cam){	int ret = 0;	if(cam->streaming) {		ret = set_alternate(cam, USBIF_CMDONLY);		free_sbufs(cam);	}	return ret;}/****************************************************************************** * *  cpia2_usb_stream_resume * *****************************************************************************/int cpia2_usb_stream_resume(struct camera_data *cam){	int ret = 0;	if(cam->streaming) {		cam->first_image_seen = 0;		ret = set_alternate(cam, cam->params.camera_state.stream_mode);		if(ret == 0) {			ret = submit_urbs(cam);		}	}	return ret;}/****************************************************************************** * *  cpia2_usb_stream_stop * *****************************************************************************/int cpia2_usb_stream_stop(struct camera_data *cam){	int ret;	ret = cpia2_usb_stream_pause(cam);	cam->streaming = 0;	configure_transfer_mode(cam, 0);	return ret;}/****************************************************************************** * *  cpia2_usb_probe * *  Probe and initialize. *****************************************************************************/static int cpia2_usb_probe(struct usb_interface *intf,			   const struct usb_device_id *id){	struct usb_device *udev = interface_to_usbdev(intf);	struct usb_interface_descriptor *interface;	struct camera_data *cam;	int ret;	/* A multi-config CPiA2 camera? */	if (udev->descriptor.bNumConfigurations != 1)		return -ENODEV;	interface = &intf->cur_altsetting->desc;	/* If we get to this point, we found a CPiA2 camera */	LOG("CPiA2 USB camera found\n");	if((cam = cpia2_init_camera_struct()) == NULL)		return -ENOMEM;	cam->dev = udev;	cam->iface = interface->bInterfaceNumber;	ret = set_alternate(cam, USBIF_CMDONLY);	if (ret < 0) {		ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);		kfree(cam);		return ret;	}	if ((ret = cpia2_register_camera(cam)) < 0) {		ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);		kfree(cam);		return ret;	}	if((ret = cpia2_init_camera(cam)) < 0) {		ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);		cpia2_unregister_camera(cam);		kfree(cam);		return ret;	}	LOG("  CPiA Version: %d.%02d (%d.%d)\n",	       cam->params.version.firmware_revision_hi,	       cam->params.version.firmware_revision_lo,	       cam->params.version.asic_id,	       cam->params.version.asic_rev);	LOG("  CPiA PnP-ID: %04x:%04x:%04x\n",	       cam->params.pnp_id.vendor,	       cam->params.pnp_id.product,	       cam->params.pnp_id.device_revision);	LOG("  SensorID: %d.(version %d)\n",	       cam->params.version.sensor_flags,	       cam->params.version.sensor_rev);	usb_set_intfdata(intf, cam);	return 0;}/****************************************************************************** * *  cpia2_disconnect * *****************************************************************************/static void cpia2_usb_disconnect(struct usb_interface *intf){	struct camera_data *cam = usb_get_intfdata(intf);	usb_set_intfdata(intf, NULL);	cam->present = 0;	DBG("Stopping stream\n");	cpia2_usb_stream_stop(cam);	DBG("Unregistering camera\n");	cpia2_unregister_camera(cam);	if(cam->buffers) {		DBG("Wakeup waiting processes\n");		cam->curbuff->status = FRAME_READY;		cam->curbuff->length = 0;		if (waitqueue_active(&cam->wq_stream))			wake_up_interruptible(&cam->wq_stream);	}	DBG("Releasing interface\n");	usb_driver_release_interface(&cpia2_driver, intf);	if (cam->open_count == 0) {		DBG("Freeing camera structure\n");		kfree(cam);	}	LOG("CPiA2 camera disconnected.\n");}/****************************************************************************** * *  usb_cpia2_init * *****************************************************************************/int cpia2_usb_init(void){	return usb_register(&cpia2_driver);}/****************************************************************************** * *  usb_cpia_cleanup * *****************************************************************************/void cpia2_usb_cleanup(void){	schedule_timeout(2 * HZ);	usb_deregister(&cpia2_driver);}

⌨️ 快捷键说明

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