omap24xxvout.c

来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,498 行 · 第 1/5 页

C
2,498
字号
			(struct omap24xxvout_colorkey *) arg;		if (colorkey->output_dev != OMAP2_OUTPUT_LCD				&& colorkey->output_dev != OMAP2_OUTPUT_TV)			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_get_colorkey (colorkey->output_dev, 				&colorkey->key_type,				&colorkey->key_val);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_S_OMAP2_BGCOLOR:	{		struct omap24xxvout_bgcolor *bgcolor =			(struct omap24xxvout_bgcolor *) arg;		if (bgcolor->output_dev != OMAP2_OUTPUT_LCD				&& bgcolor->output_dev != OMAP2_OUTPUT_TV)			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_set_bg_color (bgcolor->output_dev, bgcolor->color);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_G_OMAP2_BGCOLOR:	{		struct omap24xxvout_bgcolor *bgcolor =			(struct omap24xxvout_bgcolor *) arg;		if (bgcolor->output_dev != OMAP2_OUTPUT_LCD				&& bgcolor->output_dev != OMAP2_OUTPUT_TV)			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_get_bg_color (bgcolor->output_dev, &bgcolor->color);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_OMAP2_COLORKEY_ENABLE:	{		int *output_dev = arg;		if (*output_dev != OMAP2_OUTPUT_LCD && *output_dev != 				OMAP2_OUTPUT_TV)			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_enable_colorkey (*output_dev);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_OMAP2_COLORKEY_DISABLE:	{		int *output_dev = arg;		if (*output_dev != OMAP2_OUTPUT_LCD && *output_dev != 				OMAP2_OUTPUT_TV)			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_disable_colorkey (*output_dev);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_S_OMAP2_COLORCONV:	{		int v; 		struct omap24xxvout_colconv *ccmtx =			(struct omap24xxvout_colconv *) arg;		if(vout->vid == OMAP2_VIDEO1) v =0;		else v =1;		current_colorconv_values[v][0][0]=ccmtx->RY;		current_colorconv_values[v][0][1]=ccmtx->RCr;		current_colorconv_values[v][0][2]=ccmtx->RCb;		current_colorconv_values[v][1][0]=ccmtx->GY;		current_colorconv_values[v][1][1]=ccmtx->GCr;		current_colorconv_values[v][1][2]=ccmtx->GCb;		current_colorconv_values[v][2][0]=ccmtx->BY;		current_colorconv_values[v][2][1]=ccmtx->BCr;		current_colorconv_values[v][2][2]=ccmtx->BCb;		omap2_disp_get_dss();		omap2_disp_set_colorconv(vout->vid, &vout->pix);			omap2_disp_put_dss();		return 0;	}	case VIDIOC_G_OMAP2_COLORCONV:	{		int v; 		struct omap24xxvout_colconv *ccmtx =			(struct omap24xxvout_colconv *) arg;		if(vout->vid == OMAP2_VIDEO1) v =0;		else v =1;		ccmtx->RY = current_colorconv_values[v][0][0];		ccmtx->RCr= current_colorconv_values[v][0][1];		ccmtx->RCb= current_colorconv_values[v][0][2];		ccmtx->GY = current_colorconv_values[v][1][0];		ccmtx->GCr= current_colorconv_values[v][1][1];		ccmtx->GCb= current_colorconv_values[v][1][2];		ccmtx->BY = current_colorconv_values[v][2][0];		ccmtx->BCr= current_colorconv_values[v][2][1];		ccmtx->BCb= current_colorconv_values[v][2][2];		return 0;	}	case VIDIOC_S_OMAP2_DEFCOLORCONV:	{		omap2_disp_get_dss();		omap2_disp_set_default_colorconv(vout->vid, &vout->pix);			omap2_disp_put_dss();		return 0;	}	default:		/* unrecognized ioctl */		return -ENOIOCTLCMD;	} /* End of switch(cmd) */	return 0;}/* *  file operations */static void omap24xxvout_vm_open (struct vm_area_struct *vma){	struct omap24xxvout_device *vout = vma->vm_private_data;	DPRINTK ("vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);	vout->mmap_count++;}static void omap24xxvout_vm_close (struct vm_area_struct *vma){	struct omap24xxvout_device *vout = vma->vm_private_data;	DPRINTK ("vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);	vout->mmap_count--;}static struct vm_operations_struct omap24xxvout_vm_ops = {	.open = omap24xxvout_vm_open,	.close = omap24xxvout_vm_close,};static int omap24xxvout_mmap (struct file *file, struct vm_area_struct *vma){	struct omap24xxvout_fh *fh = file->private_data;	struct omap24xxvout_device *vout = fh->vout;	struct videobuf_queue *q = &fh->vbq;	unsigned long size = (vma->vm_end - vma->vm_start);	unsigned long start = vma->vm_start;	int i;	void *pos; 	struct videobuf_dmabuf *dmabuf=NULL;	DPRINTK ("pgoff=0x%x, start=0x%x, end=0x%x\n", vma->vm_pgoff, 			vma->vm_start,  vma->vm_end);	/* look for the buffer to map */	for (i = 0; i < VIDEO_MAX_FRAME; i++) {		if (NULL == q->bufs[i])	continue;		if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)			continue;		if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))			break;	}	if (VIDEO_MAX_FRAME == i) {		DPRINTK ("offset invalid [offset=0x%lx]\n",				(vma->vm_pgoff << PAGE_SHIFT));		return -EINVAL;	}	q->bufs[i]->baddr = vma->vm_start;	vma->vm_flags |= VM_RESERVED;	vma->vm_page_prot = pgprot_writecombine (vma->vm_page_prot);	vma->vm_ops = &omap24xxvout_vm_ops;	vma->vm_private_data = (void *) vout;	dmabuf = videobuf_to_dma(q->bufs[i]);	pos = dmabuf->vmalloc;	while (size > 0) {      /* size is page-aligned */		if (vm_insert_page(vma, start, vmalloc_to_page(pos) )) {			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		size -= PAGE_SIZE;	}	vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */	/* under investigation. 	   clearing this bit allows video-buf to accept buffers alloacted here but has troube when unmap */	vout->mmap_count++;	return 0;}static int omap24xxvout_ioctl (struct inode *inode, struct file *file, 		unsigned int cmd, unsigned long arg){	struct omap24xxvout_fh *fh = file->private_data;	struct omap24xxvout_device *vout = fh->vout;	omap24xxvout_suspend_lockout (vout, file);	return video_usercopy (inode, file, cmd, arg, omap24xxvout_do_ioctl);}static void omap24xxvout_free_allbuffers(struct omap24xxvout_device *vout){	int num_buffers = 0, i;	num_buffers = (vout->vid == OMAP2_VIDEO1) ? 		video1_numbuffers : video2_numbuffers;	for(i = num_buffers ; i < vout->buffer_allocated ; i ++) {		if(vout->buf_virt_addr[i]) {			omap35xvout_free_buffer(vout->buf_virt_addr[i],					vout->buf_phy_addr[i],					vout->buffer_size);		}		vout->buf_virt_addr[i] = 0;		vout->buf_phy_addr[i] = 0;	}	for(i = 0 ; i < 4 ; i ++) {		if(vout->smsshado_virt_addr[i]) {			omap35xvout_free_buffer(vout->smsshado_virt_addr[i],					vout->smsshado_phy_addr[i],					vout->smsshado_size);			vout->smsshado_virt_addr[i]=0;			vout->smsshado_phy_addr[i]=0;		}	}	vout->buffer_allocated = num_buffers;}static int omap24xxvout_release (struct inode *inode, struct file *file){	struct omap24xxvout_fh *fh = file->private_data;	struct omap24xxvout_device *vout;	struct videobuf_queue *q;	DPRINTK ("entering\n");	if (fh == 0)		return 0;	if ((vout = fh->vout) == 0)		return 0;	q = &fh->vbq;	omap2_disp_get_dss();	omap24xxvout_suspend_lockout (vout, file);	/* 	 * Check if the hidden buffer transfer is happening with DMA	 * if yes then stop it	 */	if (vout->rotation > 0) {		if (vout->vrfb_dma_tx.tx_status == 0) {			/* 			 * DMA will be stopped once here and again after 			 * wakeup to avoid race conditions due to time 			 * taken to wakeup the sleeping process			 */			omap_stop_dma (vout->vrfb_dma_tx.dma_ch);			wake_up_interruptible(&vout->vrfb_dma_tx.wait);			}	}	if(fh->io_allowed) {		videobuf_streamoff(q);		videobuf_queue_cancel(q);		/* Free all buffers */		omap24xxvout_free_allbuffers(vout);		videobuf_mmap_free(q);	}	omap2_disp_disable_layer (vout->vid);	if ((vout_linked != -1) && (vout->vid != vout_linked))		omap2_disp_disable_layer ((vout->vid == OMAP2_VIDEO1) ? 				OMAP2_VIDEO2 : OMAP2_VIDEO1);	if (vout->streaming == fh) vout->streaming = NULL;	if (vout->mmap_count != 0){		vout->mmap_count = 0;		printk("mmap count is not zero!\n");	}	omap2_disp_release_layer (vout->vid);	omap2_disp_put_dss ();	vout->opened -= 1;	file->private_data = NULL;	if (vout->buffer_allocated)		videobuf_mmap_free(q);	kfree (fh);	/* need to remove the link when the either slave or master is gone */	spin_lock (&vout_link_lock);	if (vout_linked != -1) {		vout_linked = -1;	}	spin_unlock (&vout_link_lock);	return 0;}static int omap24xxvout_open (struct inode *inode, struct file *file){	int minor = MINOR (file->f_dentry->d_inode->i_rdev);	struct omap24xxvout_device *vout = NULL;	struct omap24xxvout_fh *fh;	struct videobuf_queue *q;	/*int i;*/	DPRINTK ("entering\n");	if (saved_v1out && saved_v1out->vfd && (saved_v1out->vfd->minor == 				minor)) {		vout = saved_v1out;	}	if (vout == NULL) {		if (saved_v2out && saved_v2out->vfd				&& (saved_v2out->vfd->minor == minor)) {			vout = saved_v2out;		}	}	if (vout == NULL)		return -ENODEV;	/* for now, we only support single open */	if (vout->opened)		return -EBUSY;	vout->opened += 1;	if (!omap2_disp_request_layer (vout->vid)) {		vout->opened -= 1;		return -ENODEV;	}	omap2_disp_get_dss ();	omap24xxvout_suspend_lockout (vout, file);	/* allocate per-filehandle data */	fh = kmalloc (sizeof (*fh), GFP_KERNEL);	if (NULL == fh) {		omap2_disp_release_layer (vout->vid);		omap2_disp_put_dss ();		vout->opened -= 1;		return -ENOMEM;	}	memset(fh, 0, sizeof(*fh));	file->private_data = fh;	fh->vout = vout;	fh->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;	q = &fh->vbq;	video_vbq_ops.buf_setup = omap35x_buffer_setup;	video_vbq_ops.buf_prepare = omap35x_buffer_prepare;	video_vbq_ops.buf_release = omap35x_buffer_release;	video_vbq_ops.buf_queue = omap35x_buffer_queue;	spin_lock_init(&vout->vbq_lock);	videobuf_queue_pci_init (q, &video_vbq_ops, NULL, &vout->vbq_lock,			fh->type, V4L2_FIELD_NONE, sizeof 			(struct videobuf_buffer), fh);	omap2_disp_put_dss();	return 0;}static struct file_operations omap24xxvout_fops = {	.owner = THIS_MODULE,	.llseek = no_llseek,	.ioctl = omap24xxvout_ioctl,	.mmap = omap24xxvout_mmap,	.open = omap24xxvout_open,	.release = omap24xxvout_release,};static int omap24xxvout_suspend (struct platform_device *dev, 		pm_message_t state){	struct omap24xxvout_device *vout = platform_get_drvdata (dev);	/* lock-out applications during suspend */	if(vout->suspended == 1) 		return 0;	if (vout->opened) {		/* stall vid DMA */		if (vout->streaming) {			omap2_disp_disable_layer (vout->vid);			/*			 * Check if the hidden buffer transfer is happening 			 * with DMA if yes then stop it			 */			if (vout->rotation > 0) {				if (vout->vrfb_dma_tx.tx_status == 0) {					/*					 * DMA will be stopped once here 					 * and again after wakeup to					 * avoid race conditions due to time 					 * taken to wakeup the sleeping 					 * process */					omap_stop_dma (						vout->vrfb_dma_tx.dma_ch);					wake_up_interruptible (						&vout->vrfb_dma_tx.wait);				}			}		}		vout->suspended = 1;		omap2_disp_put_dss ();	}	return 0;}static int omap24xxvout_resume (struct platform_device *dev){	struct omap24xxvout_device *vout = platform_get_drvdata (dev);	if(vout->suspended == 0)		return 0;	if (vout->opened) {		omap2_disp_get_dss ();		/* resume vid DMA */		if (vout->streaming)			omap2_disp_enable_layer (vout->vid);		/* wake up applications waiting on suspend queue */		vout->suspended = 0;		wake_up (&vout->suspend_wq);	}	return 0;}static intomap24xxvout_probe (struct platform_device *dev){	return 0;}static void omap35x_platform_release(struct device				  *device){	/* This is called when the reference count goes to zero */}static struct platform_device omap24xxv1out_dev = {	.name = V1OUT_NAME,	.id = 11,	//.devid = OMAP24xx_V1OUT_DEVID,	// .busid = OMAP_BUS_L3,	.dev = {		.release = omap35x_platform_release,

⌨️ 快捷键说明

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