示例#1
0
static int vpif_update_std_info(struct channel_obj *ch)
{
	struct video_obj *vid_ch = &ch->video;
	struct vpif_params *vpifparams = &ch->vpifparams;
	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
	const struct vpif_channel_config_params *config;

	int i;

	for (i = 0; i < vpif_ch_params_count; i++) {
		config = &ch_params[i];
		if (config->hd_sd == 0) {
			vpif_dbg(2, debug, "SD format\n");
			if (config->stdid & vid_ch->stdid) {
				memcpy(std_info, config, sizeof(*config));
				break;
			}
		} else {
			vpif_dbg(2, debug, "HD format\n");
			if (config->dv_preset == vid_ch->dv_preset) {
				memcpy(std_info, config, sizeof(*config));
				break;
			}
		}
	}

	if (i == vpif_ch_params_count) {
		vpif_dbg(1, debug, "Format not found\n");
		return -EINVAL;
	}

	return 0;
}
示例#2
0
/**
 * vpif_s_std() - set STD handler
 * @file: file ptr
 * @priv: file handle
 * @std_id: ptr to std id
 */
static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret = 0;

	vpif_dbg(2, debug, "vpif_s_std\n");

	if (common->started) {
		vpif_err("streaming in progress\n");
		return -EBUSY;
	}

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (0 != ret)
		return ret;

	fh->initialized = 1;

	/* Call encoder subdevice function to set the standard */
	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	ch->video.stdid = *std_id;

	/* Get the information about the standard */
	if (vpif_update_std_info(ch)) {
		ret = -EINVAL;
		vpif_err("Error getting the standard info\n");
		goto s_std_exit;
	}

	/* Configure the default format information */
	vpif_config_format(ch);

	/* set standard in the sub device */
	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
				s_std, *std_id);
	if (ret < 0)
		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");

s_std_exit:
	mutex_unlock(&common->lock);
	return ret;
}
示例#3
0
/**
 * vpif_streamoff() - streamoff handler
 * @file: file ptr
 * @priv: file handle
 * @buftype: v4l2 buffer type
 */
static int vpif_streamoff(struct file *file, void *priv,
				enum v4l2_buf_type buftype)
{

	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret;

	vpif_dbg(2, debug, "vpif_streamoff\n");

	if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
		vpif_dbg(1, debug, "buffer type not supported\n");
		return -EINVAL;
	}

	/* If io is allowed for this file handle, return error */
	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
		vpif_dbg(1, debug, "io not allowed\n");
		return -EACCES;
	}

	/* If streaming is not started, return error */
	if (!common->started) {
		vpif_dbg(1, debug, "channel->started\n");
		return -EINVAL;
	}

	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	/* disable channel */
	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
		enable_channel0(0);
		channel0_intr_enable(0);
	} else {
		enable_channel1(0);
		channel1_intr_enable(0);
	}

	common->started = 0;

	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
				s_stream, 0);

	if (ret && (ret != -ENOIOCTLCMD))
		vpif_dbg(1, debug, "stream off failed in subdev\n");

	mutex_unlock(&common->lock);

	return videobuf_streamoff(&common->buffer_queue);
}
static int vpif_s_dv_preset(struct file *file, void *priv,
		struct v4l2_dv_preset *preset)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret = 0;

	if (common->started) {
		vpif_dbg(1, debug, "streaming in progress\n");
		return -EBUSY;
	}

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (ret)
		return ret;

	fh->initialized = 1;

	
	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	ch->video.dv_preset = preset->preset;
	ch->video.stdid = V4L2_STD_UNKNOWN;
	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));

	
	if (vpif_update_std_info(ch)) {
		vpif_dbg(1, debug, "Error getting the standard info\n");
		ret = -EINVAL;
	} else {
		
		vpif_config_format(ch);

		ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
				video, s_dv_preset, preset);
	}

	mutex_unlock(&common->lock);

	return ret;
}
示例#5
0
/**
 * buffer_prepare :  callback function for buffer prepare
 * @q : buffer queue ptr
 * @vb: ptr to video buffer
 * @field: field info
 *
 * This is the callback function for buffer prepare when videobuf_qbuf()
 * function is called. The buffer is prepared and user space virtual address
 * or user address is converted into  physical address
 */
static int vpif_buffer_prepare(struct videobuf_queue *q,
			       struct videobuf_buffer *vb,
			       enum v4l2_field field)
{
	/* Get the file handle object and channel object */
	struct vpif_fh *fh = q->priv_data;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common;
	unsigned long addr;


	vpif_dbg(2, debug, "vpif_buffer_prepare\n");

	common = &ch->common[VPIF_VIDEO_INDEX];

	/* If buffer is not initialized, initialize it */
	if (VIDEOBUF_NEEDS_INIT == vb->state) {
		vb->width = common->width;
		vb->height = common->height;
		vb->size = vb->width * vb->height;
		vb->field = field;
	}
	vb->state = VIDEOBUF_PREPARED;
	/**
	 * if user pointer memory mechanism is used, get the physical
	 * address of the buffer
	 */
	if (V4L2_MEMORY_USERPTR == common->memory) {
		if (0 == vb->baddr) {
			vpif_dbg(1, debug, "buffer address is 0\n");
			return -EINVAL;

		}
		vb->boff = vpif_uservirt_to_phys(vb->baddr);
		if (!IS_ALIGNED(vb->boff, 8))
			goto exit;
	}

	addr = vb->boff;
	if (q->streaming) {
		if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
		    !IS_ALIGNED((addr + common->ybtm_off), 8) ||
		    !IS_ALIGNED((addr + common->ctop_off), 8) ||
		    !IS_ALIGNED((addr + common->cbtm_off), 8))
			goto exit;
	}
	return 0;
exit:
	vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
	return -EINVAL;
}
static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret = 0;

	vpif_dbg(2, debug, "vpif_s_std\n");

	if (common->started) {
		vpif_err("streaming in progress\n");
		return -EBUSY;
	}

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (0 != ret)
		return ret;

	fh->initialized = 1;

	
	ch->video.stdid = *std_id;
	ch->video.dv_preset = V4L2_DV_INVALID;
	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));

	
	if (vpif_update_std_info(ch)) {
		vpif_err("Error getting the standard info\n");
		return -EINVAL;
	}

	
	vpif_config_format(ch);

	
	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
				s_std, *std_id);
	if (ret < 0)
		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
	return ret;
}
static int vpif_reqbufs(struct file *file, void *priv,
			struct v4l2_requestbuffers *reqbuf)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common;
	u8 index = 0;

	vpif_dbg(2, debug, "vpif_reqbufs\n");

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
	    || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
		return -EINVAL;

	index = VPIF_VIDEO_INDEX;

	common = &ch->common[index];

	if (0 != common->io_usrs)
		return -EBUSY;

	
	videobuf_queue_dma_contig_init(&common->buffer_queue,
					    &video_qops, NULL,
					    &common->irqlock,
					    reqbuf->type,
					    common->fmt.fmt.pix.field,
					    sizeof(struct videobuf_buffer), fh,
					    &common->lock);

	
	fh->io_allowed[index] = 1;
	
	common->io_usrs = 1;
	
	common->memory = reqbuf->memory;
	INIT_LIST_HEAD(&common->dma_queue);

	
	return videobuf_reqbufs(&common->buffer_queue, reqbuf);
}
示例#8
0
/**
 * vpif_update_std_info() - update standard related info
 * @ch: ptr to channel object
 *
 * For a given standard selected by application, update values
 * in the device data structures
 */
static int vpif_update_std_info(struct channel_obj *ch)
{
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct vpif_params *vpifparams = &ch->vpifparams;
	const struct vpif_channel_config_params *config;
	struct vpif_channel_config_params *std_info;
	struct video_obj *vid_ch = &ch->video;
	int index;

	vpif_dbg(2, debug, "vpif_update_std_info\n");

	std_info = &vpifparams->std_info;

	for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
		config = &ch_params[index];
		if (config->stdid & vid_ch->stdid) {
			memcpy(std_info, config, sizeof(*config));
			break;
		}
	}

	/* standard not found */
	if (index == ARRAY_SIZE(ch_params))
		return -EINVAL;

	common->fmt.fmt.pix.width = std_info->width;
	common->width = std_info->width;
	common->fmt.fmt.pix.height = std_info->height;
	common->height = std_info->height;
	common->fmt.fmt.pix.bytesperline = std_info->width;
	vpifparams->video_params.hpitch = std_info->width;
	vpifparams->video_params.storage_mode = std_info->frm_fmt;
	return 0;
}
示例#9
0
static int vpif_update_resolution(struct channel_obj *ch)
{
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct video_obj *vid_ch = &ch->video;
	struct vpif_params *vpifparams = &ch->vpifparams;
	struct vpif_channel_config_params *std_info = &vpifparams->std_info;

	if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
		return -EINVAL;

	if (vid_ch->stdid || vid_ch->dv_preset) {
		if (vpif_update_std_info(ch))
			return -EINVAL;
	}

	common->fmt.fmt.pix.width = std_info->width;
	common->fmt.fmt.pix.height = std_info->height;
	vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
			common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);

	/* Set height and width paramateres */
	common->height = std_info->height;
	common->width = std_info->width;

	return 0;
}
static int vpif_open(struct file *filep)
{
	struct vpif_capture_config *config = vpif_dev->platform_data;
	struct video_device *vdev = video_devdata(filep);
	struct common_obj *common;
	struct video_obj *vid_ch;
	struct channel_obj *ch;
	struct vpif_fh *fh;
	int i;

	vpif_dbg(2, debug, "vpif_open\n");

	ch = video_get_drvdata(vdev);

	vid_ch = &ch->video;
	common = &ch->common[VPIF_VIDEO_INDEX];

	if (NULL == ch->curr_subdev_info) {
		for (i = 0; i < config->subdev_count; i++) {
			if (vpif_obj.sd[i]) {
				
				ch->curr_subdev_info = &config->subdev_info[i];
				
				vid_ch->input_idx = 0;
				break;
			}
		}
		if (i == config->subdev_count) {
			vpif_err("No sub device registered\n");
			return -ENOENT;
		}
	}

	
	fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
	if (NULL == fh) {
		vpif_err("unable to allocate memory for file handle object\n");
		return -ENOMEM;
	}

	
	filep->private_data = fh;
	fh->channel = ch;
	fh->initialized = 0;
	
	if (!ch->initialized) {
		fh->initialized = 1;
		ch->initialized = 1;
		memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
	}
	
	ch->usrs++;
	
	fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
	
	fh->prio = V4L2_PRIORITY_UNSET;
	v4l2_prio_open(&ch->prio, &fh->prio);
	return 0;
}
static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *fmt)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct v4l2_pix_format *pixfmt;
	int ret = 0;

	vpif_dbg(2, debug, "VIDIOC_S_FMT\n");

	/* If streaming is started, return error */
	if (common->started) {
		vpif_dbg(1, debug, "Streaming is started\n");
		return -EBUSY;
	}

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (0 != ret)
		return ret;

	fh->initialized = 1;

	pixfmt = &fmt->fmt.pix;
	/* Check for valid field format */
	ret = vpif_check_format(ch, pixfmt, 0);

	if (ret)
		return ret;
	/* store the format in the channel object */
	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	common->fmt = *fmt;
	mutex_unlock(&common->lock);

	return 0;
}
static int vpif_s_fmt_vid_out(struct file *file, void *priv,
				struct v4l2_format *fmt)
{
	struct vpif_fh *fh = priv;
	struct v4l2_pix_format *pixfmt;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret = 0;

	if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
	    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}

		/* Check for the priority */
		ret = v4l2_prio_check(&ch->prio, fh->prio);
		if (0 != ret)
			return ret;
		fh->initialized = 1;
	}

	if (common->started) {
		vpif_dbg(1, debug, "Streaming in progress\n");
		return -EBUSY;
	}

	pixfmt = &fmt->fmt.pix;
	/* Check for valid field format */
	ret = vpif_check_format(ch, pixfmt);
	if (ret)
		return ret;

	/* store the pix format in the channel object */
	common->fmt.fmt.pix = *pixfmt;
	/* store the format in the channel object */
	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	common->fmt = *fmt;
	mutex_unlock(&common->lock);

	return 0;
}
示例#13
0
/*
 * vpif_mmap: It is used to map kernel space buffers into user spaces
 */
static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
{
	struct vpif_fh *fh = filep->private_data;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);

	vpif_dbg(2, debug, "vpif_mmap\n");

	return videobuf_mmap_mapper(&common->buffer_queue, vma);
}
示例#14
0
/**
 * vpif_g_std() - get STD handler
 * @file: file ptr
 * @priv: file handle
 * @std_id: ptr to std id
 */
static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;

	vpif_dbg(2, debug, "vpif_g_std\n");

	*std = ch->video.stdid;
	return 0;
}
示例#15
0
/**
 * vpif_querybuf() - query buffer handler
 * @file: file ptr
 * @priv: file handle
 * @buf: v4l2 buffer structure ptr
 */
static int vpif_querybuf(struct file *file, void *priv,
				struct v4l2_buffer *buf)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];

	vpif_dbg(2, debug, "vpif_querybuf\n");

	if (common->fmt.type != buf->type)
		return -EINVAL;

	if (common->memory != V4L2_MEMORY_MMAP) {
		vpif_dbg(1, debug, "Invalid memory\n");
		return -EINVAL;
	}

	return videobuf_querybuf(&common->buffer_queue, buf);
}
static int vpif_update_std_info(struct channel_obj *ch)
{
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct vpif_params *vpifparams = &ch->vpifparams;
	const struct vpif_channel_config_params *config;
	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
	struct video_obj *vid_ch = &ch->video;
	int index;

	vpif_dbg(2, debug, "vpif_update_std_info\n");

	for (index = 0; index < vpif_ch_params_count; index++) {
		config = &ch_params[index];
		if (config->hd_sd == 0) {
			vpif_dbg(2, debug, "SD format\n");
			if (config->stdid & vid_ch->stdid) {
				memcpy(std_info, config, sizeof(*config));
				break;
			}
		} else {
			vpif_dbg(2, debug, "HD format\n");
			if (config->dv_preset == vid_ch->dv_preset) {
				memcpy(std_info, config, sizeof(*config));
				break;
			}
		}
	}

	
	if (index == vpif_ch_params_count)
		return -EINVAL;

	common->fmt.fmt.pix.width = std_info->width;
	common->width = std_info->width;
	common->fmt.fmt.pix.height = std_info->height;
	common->height = std_info->height;
	common->fmt.fmt.pix.bytesperline = std_info->width;
	vpifparams->video_params.hpitch = std_info->width;
	vpifparams->video_params.storage_mode = std_info->frm_fmt;

	return 0;
}
示例#17
0
/**
 * vpif_dqbuf() - query buffer handler
 * @file: file ptr
 * @priv: file handle
 * @buf: v4l2 buffer structure ptr
 */
static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];

	vpif_dbg(2, debug, "vpif_dqbuf\n");

	return videobuf_dqbuf(&common->buffer_queue, buf,
					file->f_flags & O_NONBLOCK);
}
static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *fmt)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct v4l2_pix_format *pixfmt;
	int ret = 0;

	vpif_dbg(2, debug, "%s\n", __func__);

	
	if (common->started) {
		vpif_dbg(1, debug, "Streaming is started\n");
		return -EBUSY;
	}

	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
		if (!fh->initialized) {
			vpif_dbg(1, debug, "Channel Busy\n");
			return -EBUSY;
		}
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (0 != ret)
		return ret;

	fh->initialized = 1;

	pixfmt = &fmt->fmt.pix;
	
	ret = vpif_check_format(ch, pixfmt, 0);

	if (ret)
		return ret;
	
	common->fmt = *fmt;
	return 0;
}
static unsigned int vpif_poll(struct file *filep, poll_table * wait)
{
	struct vpif_fh *fh = filep->private_data;
	struct channel_obj *channel = fh->channel;
	struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);

	vpif_dbg(2, debug, "vpif_poll\n");

	if (common->started)
		return videobuf_poll_stream(filep, &common->buffer_queue, wait);
	return 0;
}
示例#20
0
/**
 * vpif_querystd() - querystd handler
 * @file: file ptr
 * @priv: file handle
 * @std_id: ptr to std id
 *
 * This function is called to detect standard at the selected input
 */
static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	int ret = 0;

	vpif_dbg(2, debug, "vpif_querystd\n");

	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	/* Call querystd function of decoder device */
	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
				querystd, std_id);
	if (ret < 0)
		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");

	mutex_unlock(&common->lock);
	return ret;
}
示例#21
0
/*
 * vpif_g_chip_ident() - Identify the chip
 * @file: file ptr
 * @priv: file handle
 * @chip: chip identity
 *
 * Returns zero or -EINVAL if read operations fails.
 */
static int vpif_g_chip_ident(struct file *file, void *priv,
		struct v4l2_dbg_chip_ident *chip)
{
	chip->ident = V4L2_IDENT_NONE;
	chip->revision = 0;
	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
		vpif_dbg(2, debug, "match_type is invalid.\n");
		return -EINVAL;
	}

	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
			g_chip_ident, chip);
}
示例#22
0
/**
 * vpif_release : function to clean up file close
 * @filep: file pointer
 *
 * This function deletes buffer queue, frees the buffers and the vpfe file
 * handle
 */
static int vpif_release(struct file *filep)
{
	struct vpif_fh *fh = filep->private_data;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common;

	vpif_dbg(2, debug, "vpif_release\n");

	common = &ch->common[VPIF_VIDEO_INDEX];

	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	/* if this instance is doing IO */
	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
		/* Reset io_usrs member of channel object */
		common->io_usrs = 0;
		/* Disable channel as per its device type and channel id */
		if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
			enable_channel0(0);
			channel0_intr_enable(0);
		}
		if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
		    (2 == common->started)) {
			enable_channel1(0);
			channel1_intr_enable(0);
		}
		common->started = 0;
		/* Free buffers allocated */
		videobuf_queue_cancel(&common->buffer_queue);
		videobuf_mmap_free(&common->buffer_queue);
	}

	/* Decrement channel usrs counter */
	ch->usrs--;

	/* unlock mutex on channel object */
	mutex_unlock(&common->lock);

	/* Close the priority */
	v4l2_prio_close(&ch->prio, fh->prio);

	if (fh->initialized)
		ch->initialized = 0;

	filep->private_data = NULL;
	kfree(fh);
	return 0;
}
示例#23
0
/**
 * vpif_config_addr() - function to configure buffer address in vpif
 * @ch - channel ptr
 * @muxmode - channel mux mode
 */
static void vpif_config_addr(struct channel_obj *ch, int muxmode)
{
	struct common_obj *common;

	vpif_dbg(2, debug, "vpif_config_addr\n");

	common = &(ch->common[VPIF_VIDEO_INDEX]);

	if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
		common->set_addr = ch1_set_videobuf_addr;
	else if (2 == muxmode)
		common->set_addr = ch0_set_videobuf_addr_yc_nmux;
	else
		common->set_addr = ch0_set_videobuf_addr;
}
示例#24
0
/**
 * vpif_map_sub_device_to_input() - Maps sub device to input
 * @ch - ptr to channel
 * @config - ptr to capture configuration
 * @input_index - Given input index from application
 * @sub_device_index - index into sd table
 *
 * lookup the sub device information for a given input index.
 * we report all the inputs to application. inputs table also
 * has sub device name for the each input
 */
static struct vpif_subdev_info *vpif_map_sub_device_to_input(
				struct channel_obj *ch,
				struct vpif_capture_config *vpif_cfg,
				int input_index,
				int *sub_device_index)
{
	struct vpif_capture_chan_config *chan_cfg;
	struct vpif_subdev_info *subdev_info = NULL;
	const char *subdev_name = NULL;
	int i;

	vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");

	chan_cfg = &vpif_cfg->chan_config[ch->channel_id];

	/**
	 * search through the inputs to find the sub device supporting
	 * the input
	 */
	for (i = 0; i < chan_cfg->input_count; i++) {
		/* For each sub device, loop through input */
		if (i == input_index) {
			subdev_name = chan_cfg->inputs[i].subdev_name;
			break;
		}
	}

	/* if reached maximum. return null */
	if (i == chan_cfg->input_count || (NULL == subdev_name))
		return subdev_info;

	/* loop through the sub device list to get the sub device info */
	for (i = 0; i < vpif_cfg->subdev_count; i++) {
		subdev_info = &vpif_cfg->subdev_info[i];
		if (!strcmp(subdev_info->name, subdev_name))
			break;
	}

	if (i == vpif_cfg->subdev_count)
		return subdev_info;

	/* check if the sub device is registered */
	if (NULL == vpif_obj.sd[i])
		return NULL;

	*sub_device_index = i;
	return subdev_info;
}
示例#25
0
/**
 * vpif_buffer_queue : Callback function to add buffer to DMA queue
 * @q: ptr to videobuf_queue
 * @vb: ptr to videobuf_buffer
 */
static void vpif_buffer_queue(struct videobuf_queue *q,
			      struct videobuf_buffer *vb)
{
	/* Get the file handle object and channel object */
	struct vpif_fh *fh = q->priv_data;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common;

	common = &ch->common[VPIF_VIDEO_INDEX];

	vpif_dbg(2, debug, "vpif_buffer_queue\n");

	/* add the buffer to the DMA queue */
	list_add_tail(&vb->queue, &common->dma_queue);
	/* Change state of the buffer */
	vb->state = VIDEOBUF_QUEUED;
}
示例#26
0
static int vpif_enum_output(struct file *file, void *fh,
				struct v4l2_output *output)
{

	struct vpif_display_config *config = vpif_dev->platform_data;

	if (output->index >= config->output_count) {
		vpif_dbg(1, debug, "Invalid output index\n");
		return -EINVAL;
	}

	strcpy(output->name, config->output[output->index]);
	output->type = V4L2_OUTPUT_TYPE_ANALOG;
	output->std = DM646X_V4L2_STD;

	return 0;
}
static void vpif_buffer_queue(struct videobuf_queue *q,
			      struct videobuf_buffer *vb)
{
	
	struct vpif_fh *fh = q->priv_data;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common;

	common = &ch->common[VPIF_VIDEO_INDEX];

	vpif_dbg(2, debug, "vpif_buffer_queue\n");

	
	list_add_tail(&vb->queue, &common->dma_queue);
	
	vb->state = VIDEOBUF_QUEUED;
}
static struct vpif_subdev_info *vpif_map_sub_device_to_input(
				struct channel_obj *ch,
				struct vpif_capture_config *vpif_cfg,
				int input_index,
				int *sub_device_index)
{
	struct vpif_capture_chan_config *chan_cfg;
	struct vpif_subdev_info *subdev_info = NULL;
	const char *subdev_name = NULL;
	int i;

	vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");

	chan_cfg = &vpif_cfg->chan_config[ch->channel_id];

	for (i = 0; i < chan_cfg->input_count; i++) {
		
		if (i == input_index) {
			subdev_name = chan_cfg->inputs[i].subdev_name;
			break;
		}
	}

	
	if (i == chan_cfg->input_count || (NULL == subdev_name))
		return subdev_info;

	
	for (i = 0; i < vpif_cfg->subdev_count; i++) {
		subdev_info = &vpif_cfg->subdev_info[i];
		if (!strcmp(subdev_info->name, subdev_name))
			break;
	}

	if (i == vpif_cfg->subdev_count)
		return subdev_info;

	
	if (NULL == vpif_obj.sd[i])
		return NULL;

	*sub_device_index = i;
	return subdev_info;
}
示例#29
0
/**
 * vpif_s_dv_presets() - S_DV_PRESETS handler
 * @file: file ptr
 * @priv: file handle
 * @preset: input preset
 */
static int vpif_s_dv_preset(struct file *file, void *priv,
		struct v4l2_dv_preset *preset)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct video_obj *vid_ch = &ch->video;
	int ret = 0;

	if (common->started) {
		vpif_dbg(1, debug, "streaming in progress\n");
		return -EBUSY;
	}

	ret = v4l2_prio_check(&ch->prio, fh->prio);
	if (ret != 0)
		return ret;

	fh->initialized = 1;

	/* Call encoder subdevice function to set the standard */
	if (mutex_lock_interruptible(&common->lock))
		return -ERESTARTSYS;

	ch->video.dv_preset = preset->preset;
	ch->video.stdid = V4L2_STD_UNKNOWN;
	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));

	/* Get the information about the standard */
	if (vpif_update_resolution(ch)) {
		ret = -EINVAL;
	} else {
		/* Configure the default format information */
		vpif_config_format(ch);

		ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
				video, s_dv_preset, preset);
	}

	mutex_unlock(&common->lock);

	return ret;
}
static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
{
	struct vpif_fh *fh = priv;
	struct channel_obj *ch = fh->channel;
	int ret = 0;

	vpif_dbg(2, debug, "vpif_querystd\n");

	
	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
				querystd, std_id);
	if (ret < 0)
		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");

	return ret;
}