omap24xxvout.c

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

C
2,498
字号
			omap24xxvout_default_crop (&vout->pix, 				&vout->fbuf, &cropcap->defrect);			cropcap->pixelaspect.numerator = 1;			cropcap->pixelaspect.denominator = 1;			return 0;		}		default:			return -EINVAL;		}	}	case VIDIOC_G_CROP:	{		struct v4l2_crop *crop = (struct v4l2_crop *) arg;		switch (crop->type) {			case V4L2_BUF_TYPE_VIDEO_OUTPUT:			{				crop->c = vout->crop;				return 0;			}			default:				return -EINVAL;		}	}	case VIDIOC_S_CROP:	{		struct v4l2_crop *crop = (struct v4l2_crop *) arg;		if (vout->streaming)			return -EBUSY;		omap2_disp_get_dss();		/* get the framebuffer parameters */		if(vout->rotation == 90 || vout->rotation == 270){			omap2_disp_get_panel_size (				omap2_disp_get_output_dev (vout->vid),					&(vout->fbuf.fmt.height),					&(vout->fbuf.fmt.width));		} else {			omap2_disp_get_panel_size (				omap2_disp_get_output_dev (vout->vid),					&(vout->fbuf.fmt.width), 					&(vout->fbuf.fmt.height));		}		omap2_disp_put_dss();		switch (crop->type) {			case V4L2_BUF_TYPE_VIDEO_OUTPUT:			{				err = omap24xxvout_new_crop (&vout->pix, 					&vout->crop, &vout->win, &vout->fbuf, 					&crop->c);				return err;			}			default:				return -EINVAL;		}	}	case VIDIOC_REQBUFS:	{		struct v4l2_requestbuffers *req = 			(struct v4l2_requestbuffers *) arg;		struct videobuf_queue *q = &fh->vbq;		unsigned int i, ret, num_buffers=0;		struct videobuf_dmabuf *dmabuf=NULL;		/* don't allow to buffer request for the linked layer */		if (vout->vid == vout_linked) {			return -EINVAL;		}		if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || 				(req->count < 0)) {			return -EINVAL;		}		/* if memory is not mmp or userptr		   return error */		if ((V4L2_MEMORY_MMAP != req->memory) && 				(V4L2_MEMORY_USERPTR != req->memory)) {			return -EINVAL;		}		/* Cannot be requested when streaming is on */		if (vout->streaming) {			return -EBUSY;		}		/* If buffers are already allocated free them */		if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {			if (vout->mmap_count) {				return -EBUSY;			}			num_buffers = (vout->vid == OMAP2_VIDEO1) ? 				video1_numbuffers : video2_numbuffers;			for(i = num_buffers;i < vout->buffer_allocated;i++) {				dmabuf = videobuf_to_dma(q->bufs[i]);				omap35xvout_free_buffer((u32)dmabuf->vmalloc,					dmabuf->bus_addr,					vout->buffer_size);				vout->buf_virt_addr[i] = 0;				vout->buf_phy_addr[i] = 0;			}			vout->buffer_allocated = num_buffers;			videobuf_mmap_free(q);		} else if(q->bufs[0] && (V4L2_MEMORY_USERPTR == 					q->bufs[0]->memory)) {			if(vout->buffer_allocated) {				videobuf_mmap_free(q);				for(i = 0 ; i < vout->buffer_allocated ; i ++){					if(q->bufs[i])						kfree(q->bufs[i]);					q->bufs[i] = NULL;				}				vout->buffer_allocated = 0;			}		}		fh->io_allowed = 1;		/*store the memory type in data structure*/		vout->memory = req->memory;		INIT_LIST_HEAD(&vout->dma_queue);		/* call videobuf_reqbufs api */		ret = videobuf_reqbufs(q, req);		if(ret < 0) {			break;		}		vout->buffer_allocated = req->count;		for(i = 0 ; i < req->count ; i ++) {			dmabuf = videobuf_to_dma(q->bufs[i]);			dmabuf->vmalloc = 				(void *)vout->buf_virt_addr[i];			dmabuf->bus_addr =				(dma_addr_t)vout->buf_phy_addr[i];			dmabuf->sglen = 1;		}		return 0;	}	case VIDIOC_QUERYBUF:		return videobuf_querybuf (&fh->vbq, arg);	case VIDIOC_QBUF:	{		struct v4l2_buffer *buffer = (struct v4l2_buffer *) arg;		struct videobuf_queue *q = &fh->vbq;		struct omap24xxvout_device *dest;		int output_dev = omap2_disp_get_output_dev(vout->vid);			int streaming_on = STREAMING_IS_ON(), ret=0, rotation=-1;		if(!fh->io_allowed) {			return -EINVAL;		}		timeout = HZ / 5;		timeout += jiffies; 		omap2_disp_get_tvlcd(&tvlcd_status);		if (!streaming_on)				omap2_disp_get_dss();		if (tvlcd_status.status == TVLCD_STOP) {			if (tvlcd_status.ltype == vout->vid) {				omap2_disp_disable_layer (vout->vid);				vout->streaming = NULL;			} else if (vout_linked != -1 && 					vout_linked != vout->vid){				omap2_disp_disable_layer (					(vout->vid == OMAP2_VIDEO1)					? OMAP2_VIDEO2 : OMAP2_VIDEO1);			}			while(omap2_disp_reg_sync_bit(output_dev ) && 					time_before(jiffies, timeout)) {				if ((!in_interrupt()) && (!irqs_disabled())) {					set_current_state(TASK_INTERRUPTIBLE);					schedule_timeout(1);				} else {					udelay(10);				}			}			if(vout->rotation == 90 || vout->rotation == 270){				omap2_disp_get_panel_size(					omap2_disp_get_output_dev (vout->vid),						&(vout->fbuf.fmt.height),						&(vout->fbuf.fmt.width));			} else {				omap2_disp_get_panel_size(					omap2_disp_get_output_dev (vout->vid),						&(vout->fbuf.fmt.width), 						&(vout->fbuf.fmt.height));			}			/* set default crop and win */			omap24xxvout_new_format (&vout->pix, &vout->fbuf, 					&vout->crop, &vout->win);			omap2_disp_set_output_dev(tvlcd_status.ltype, 					tvlcd_status.output_dev);			omap2_disp_set_tvlcd(TVLCD_CONTINUE);			if (!streaming_on)				omap2_disp_put_dss();			omap2_disp_get_tvlcd(&tvlcd_status);		}		if (tvlcd_status.status == TVLCD_CONTINUE) {			if (tvlcd_status.ltype == vout->vid) {				rotation = (vout->rotation > 0) ? 					vout->rotation:-1;				vout->streaming = fh;				omap2_disp_config_vlayer(vout->vid, 					&vout->pix, &vout->crop, &vout->win, 					rotation, vout->mirror);			} else if (vout_linked != -1 && vout_linked != 						vout->vid) {				dest = (vout_linked == OMAP2_VIDEO1) ? 					saved_v1out : saved_v2out;				rotation = (dest->rotation > 0) ? 					dest->rotation:-1;				omap2_disp_config_vlayer (dest->vid, 					&dest->pix, &dest-> crop, &dest->win, 					rotation, dest->mirror);			}			omap2_disp_set_tvlcd(0);		}		/* don't allow to queue buffer for the linked layer */		if (vout->vid == vout_linked) {			if (!streaming_on)				omap2_disp_put_dss();			return -EINVAL;		}		if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||				(buffer->index >= vout->buffer_allocated) ||			(q->bufs[buffer->index]->memory != buffer->memory)) {			if (!streaming_on)				omap2_disp_put_dss();			return -EINVAL;		}		if(V4L2_MEMORY_USERPTR == buffer->memory) {			if((buffer->length < vout->pix.sizeimage) ||					(0 == buffer->m.userptr)) {				if (!streaming_on)						omap2_disp_put_dss();				return -EINVAL;			}		}		if (vout->rotation > 0 && vout->vrfb_dma_tx.req_status == 				DMA_CHAN_NOT_ALLOTED) {			if (!streaming_on)				omap2_disp_put_dss();			return -EINVAL;		}		ret = videobuf_qbuf(q, buffer);		if (!streaming_on)			omap2_disp_put_dss();		return ret;	}	case VIDIOC_DQBUF:	{		struct videobuf_queue *q = &fh->vbq;		int ret = 0;		/* don't allow to dequeue buffer for the linked layer */		if (vout->vid == vout_linked)			return -EINVAL;		if(!vout->streaming || !fh->io_allowed)			return -EINVAL;		if (file->f_flags & O_NONBLOCK)			/* Call videobuf_dqbuf for non			   blocking mode */			ret = videobuf_dqbuf(q, (struct v4l2_buffer *)arg, 1);		else			/* Call videobuf_dqbuf for			   blocking mode */			ret = videobuf_dqbuf(q, (struct v4l2_buffer *)arg, 0);		break;	}	case VIDIOC_STREAMON:	{		struct videobuf_queue *q = &fh->vbq;		struct omap24xxvout_device *dest;		int ret=0, rotation=-1;		u32 addr=0;		if(!fh->io_allowed) {			return -EINVAL;		}		if(vout->streaming)			return -EBUSY;		ret = videobuf_streamon(q);		if(ret < 0) {			break;		}		if(list_empty(&vout->dma_queue)) {			ret = -EIO;			return ret;		}		/* Get the next frame from the buffer queue */		vout->nextFrm = vout->curFrm =			list_entry(vout->dma_queue.next,					struct videobuf_buffer, queue);		/* Remove buffer from the buffer queue */		list_del(&vout->curFrm->queue);		/* Mark state of the current frame to active */		vout->curFrm->state = VIDEOBUF_ACTIVE;		/* Initialize field_id and started member */		vout->field_id = 0;		/* set flag here. Next QBUF will start DMA */		vout->streaming = fh;		vout->first_int = 1;		omap2_disp_get_dss();		rotation = (vout->rotation > 0)?vout->rotation:-1;		omap2_disp_config_vlayer (vout->vid, &vout->pix, &vout->crop,				&vout->win, rotation, vout->mirror);		/* Configure also linked layer */		if (vout_linked != -1 && vout_linked != vout->vid){			rotation = (vout->rotation > 0)?vout->rotation:-1;			dest = (vout_linked == OMAP2_VIDEO1) ? saved_v1out : 				saved_v2out;			omap2_disp_config_vlayer (dest->vid, &dest->pix, 					&dest->crop, &dest->win, 					rotation, dest->mirror);		}		omap35xvout_calculate_offset(vout);		addr = (unsigned long)vout->queued_buf_addr[vout->curFrm->i] + 			vout->cropped_offset;		omap2_disp_set_addr(vout->vid, addr, addr, 				addr+vout->tv_field1_offset);		omap2_disp_start_video_layer(vout->vid);		return 0;	}	case VIDIOC_STREAMOFF:	{		struct videobuf_queue *q = &fh->vbq;		int ret = 0;		if(!fh->io_allowed) {			return -EINVAL;		}		if(!vout->streaming) {			return -EINVAL;		}				if (vout->streaming == fh){			omap2_disp_disable_layer (vout->vid);			vout->streaming = NULL;			/* stop the slave layer */			if (vout_linked != -1 && vout_linked != vout->vid){				omap2_disp_disable_layer (						(vout->vid == OMAP2_VIDEO1)						? OMAP2_VIDEO2 : OMAP2_VIDEO1);			}			omap2_disp_put_dss();			ret = videobuf_streamoff(q);			return 0;		}		return -EINVAL;	}	case VIDIOC_S_OMAP2_LINK:	{		int *link = arg;		spin_lock (&vout_link_lock);		if ((*link == 0) && (vout_linked == vout->vid))			vout_linked = -1;		omap2_disp_get_dss();		if ((*link == 1) && (vout_linked == -1 || 					vout_linked == vout->vid)){			vout_linked = vout->vid;			if (vout_linked == OMAP2_VIDEO2){				/* sync V2 to V1 for img and crop */				omap24xxvout_sync (saved_v2out, saved_v1out);			} else {				/* sync V1 to V2 */				omap24xxvout_sync (saved_v1out, saved_v2out);			}		}		omap2_disp_put_dss();		spin_unlock (&vout_link_lock);		return 0;	}	case VIDIOC_G_OMAP2_LINK:	{		int *link = arg;		spin_lock (&vout_link_lock);		if (vout_linked == vout->vid)			*link = 1;		else 			*link = 0;		spin_unlock (&vout_link_lock);		return 0;	}	case VIDIOC_S_OMAP2_MIRROR:	{		int *mirror = arg;		if ((*mirror == 0) && (vout->mirror == 1)) {			vout->mirror = 0;			return 0;		} else if ((*mirror == 1) && (vout->mirror == 0)) {			vout->mirror = 1;			return 0;		}		return -EINVAL;	}	case VIDIOC_G_OMAP2_MIRROR:	{		int *mirror = arg;		*mirror = vout->mirror;		return 0;	}	case VIDIOC_S_OMAP2_ROTATION:	{		int *rotation = arg;		if ((*rotation == 0) || (*rotation == 90) || 				(*rotation == 180) || (*rotation == 270) || 				(*rotation == -1)) {			vout->rotation = (*rotation == 90) ? 270 : 				(*rotation == 270) ? 90 : *rotation;			rotation_support = vout->rotation;			return 0;		} else {			return -EINVAL;		}	}	case VIDIOC_G_OMAP2_ROTATION:	{		int *rotation = arg;		*rotation = (vout->rotation == 90) ? 270 : 			(vout->rotation == 270) ? 90 : vout->rotation;		return 0;	}	case VIDIOC_S_OMAP2_COLORKEY:	{		struct omap24xxvout_colorkey *colorkey =			(struct omap24xxvout_colorkey *) arg;		if ((colorkey->output_dev != OMAP2_OUTPUT_LCD &&				colorkey->output_dev != OMAP2_OUTPUT_TV) ||				(colorkey->key_type != OMAP2_GFX_DESTINATION				&& colorkey->key_type != OMAP2_VIDEO_SOURCE))			return -EINVAL;		omap2_disp_get_dss();		omap2_disp_set_colorkey (colorkey->output_dev, 				colorkey->key_type, colorkey->key_val);		omap2_disp_put_dss();		return 0;	}	case VIDIOC_G_OMAP2_COLORKEY:	{		struct omap24xxvout_colorkey *colorkey =

⌨️ 快捷键说明

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