static int s3c_fimc_v4l2_reqbufs(struct file *filp, void *fh,
                                 struct v4l2_requestbuffers *b)
{
    struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
    struct s3c_fimc_out_frame *frame = &ctrl->out_frame;

    if (b->type != V4L2_BUF_TYPE_VIDEO_OVERLAY && \
            b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
        return -EINVAL;

    if (b->memory != V4L2_MEMORY_MMAP) {
        err("V4L2_MEMORY_MMAP is only supported\n");
        return -EINVAL;
    }

    /* control user input */
    if (b->count > 2)
        b->count = 4;
    else if (b->count < 1)
        b->count = 1;
    printk("%s  b-count %d\n",__func__,b->count);//hnmsky
    frame->nr_frames = b->count;

    if (frame->addr[0].virt_y != NULL)
        s3c_fimc_free_output_memory(frame);

    if (ctrl->out_type == PATH_OUT_DMA && frame->addr[0].virt_y == NULL) {
        if (s3c_fimc_alloc_output_memory(frame))
            err("cannot allocate memory\n");
    }

    return 0;
}
static int s3c_fimc_v4l2_streamoff(struct file *filp, void *fh,
                                   enum v4l2_buf_type i)
{
    struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
    struct s3c_fimc_out_frame *frame = &ctrl->out_frame;

    if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
        return -EINVAL;

    FSET_STOP(ctrl);
    FCLR_USAGE(ctrl);
    FCLR_IRQ(ctrl);

    s3c_fimc_stop_dma(ctrl);
    s3c_fimc_free_output_memory(frame);
    s3c_fimc_set_output_address(ctrl);

    frame->hq = 0;
    frame->jpeg.enabled = 0;
    frame->jpeg.thumb = 0;
    frame->jpeg.thumb_res = 0;
    frame->jpeg.main_size = 0;
    frame->jpeg.thumb_size = 0;

    return 0;
}
static int s3c_fimc_alloc_rgb_memory(struct s3c_fimc_out_frame *info)
{
	struct s3c_fimc_frame_addr *frame;
	int i, ret, nr_frames = info->nr_frames;

	for (i = 0; i < nr_frames; i++) {
		frame = &info->addr[i];

		frame->phys_rgb = s3c_fimc_get_dma_region(info->buf_size);
		if (frame->phys_rgb == 0) {
			ret = -ENOMEM;
			goto alloc_fail;
		}
		
		frame->virt_rgb = phys_to_virt(frame->phys_rgb);
	}

	for (i = nr_frames; i < S3C_FIMC_MAX_FRAMES; i++) {
		frame = &info->addr[i];
		frame->phys_rgb = info->addr[i - nr_frames].phys_rgb;
		frame->virt_rgb = info->addr[i - nr_frames].virt_rgb;		
	}

	return 0;

alloc_fail:
	s3c_fimc_free_output_memory(info);
	return ret;
}
static int s3c_fimc_alloc_yuv_memory(struct s3c_fimc_out_frame *info)
{
	struct s3c_fimc_frame_addr *frame;
	int i, ret, nr_frames = info->nr_frames;
	u32 size = info->width * info->height, cbcr_size;
	
	if (info->format == FORMAT_YCBCR420)
		cbcr_size = size / 4;
	else
		cbcr_size = size / 2;
	printk("%s: nr_frames %d  len  %d \n",__func__,nr_frames,s3c_fimc.dma_total);//hnmsky
	for (i = 0; i < nr_frames; i++) {
		frame = &info->addr[i];

		frame->phys_y = s3c_fimc_get_dma_region(info->buf_size);
		if (frame->phys_y == 0) {
			ret = -ENOMEM;
			goto alloc_fail;
		}

		frame->phys_cb = frame->phys_y + size;
		frame->phys_cr = frame->phys_cb + cbcr_size;

		frame->virt_y = phys_to_virt(frame->phys_y);
		frame->virt_cb = frame->virt_y + size;
		frame->virt_cr = frame->virt_cb + cbcr_size;
	}

	for (i = nr_frames; i < S3C_FIMC_MAX_FRAMES; i++) {
		frame = &info->addr[i];
		frame->phys_y = info->addr[i - nr_frames].phys_y;
		frame->phys_cb = info->addr[i - nr_frames].phys_cb;
		frame->phys_cr = info->addr[i - nr_frames].phys_cr;
		frame->virt_y = info->addr[i - nr_frames].virt_y;
		frame->virt_cb = info->addr[i - nr_frames].virt_cb;
		frame->virt_cr = info->addr[i - nr_frames].virt_cr;
	}

	return 0;

alloc_fail:
	s3c_fimc_free_output_memory(info);
	return ret;
}
static int s3c_fimc_alloc_yuv_memory(struct s3c_fimc_out_frame *info)
{
	struct s3c_fimc_frame_addr *frame;
	int i, ret, nr_frames = info->nr_frames;
	u32 size = info->width * info->height, cbcr_size;
	
	if (info->format == FORMAT_YCBCR420)
		cbcr_size = size / 4;
	else
		cbcr_size = size / 2;

	for (i = 0; i < nr_frames; i++) {
		frame = &info->addr[i];

		frame->virt_y = kmalloc(info->buf_size, GFP_DMA);
		if (frame->virt_y == NULL) {
			ret = -ENOMEM;
			goto alloc_fail;
		}

		frame->virt_cb = frame->virt_y + size;
		frame->virt_cr = frame->virt_cb + cbcr_size;

		frame->phys_y = virt_to_phys(frame->virt_y);
		frame->phys_cb = frame->phys_y + size;
		frame->phys_cr = frame->phys_cb + cbcr_size;
	}

	for (i = nr_frames; i < S3C_FIMC_MAX_FRAMES; i++) {
		frame = &info->addr[i];
		frame->phys_y = info->addr[i - nr_frames].phys_y;
		frame->phys_cb = info->addr[i - nr_frames].phys_cb;
		frame->phys_cr = info->addr[i - nr_frames].phys_cr;
		frame->virt_y = info->addr[i - nr_frames].virt_y;
		frame->virt_cb = info->addr[i - nr_frames].virt_cb;
		frame->virt_cr = info->addr[i - nr_frames].virt_cr;
	}

	return 0;

alloc_fail:
	s3c_fimc_free_output_memory(info);
	return ret;
}
Exemplo n.º 6
0
static int s3c_fimc_unregister_controller(struct platform_device *pdev)
{
	struct s3c_fimc_control *ctrl;
	struct s3c_platform_fimc *pdata;
	int id = pdev->id;

	ctrl = &s3c_fimc.ctrl[id];

	s3c_fimc_free_output_memory(&ctrl->out_frame);

	pdata = to_fimc_plat(ctrl->dev);

	if (!pdata->shared_io)
		iounmap(ctrl->regs);

	memset(ctrl, 0, sizeof(*ctrl));
	
	return 0;
}
static int s3c_fimc_v4l2_overlay(struct file *filp, void *fh, unsigned int i)
{
    struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;

    if (i) {
        if (ctrl->in_type != PATH_IN_DMA)
            s3c_fimc_init_camera(ctrl);

        FSET_PREVIEW(ctrl);
        s3c_fimc_start_dma(ctrl);
    } else {
        s3c_fimc_stop_dma(ctrl);

        if (ctrl->out_type != PATH_OUT_LCDFIFO) {
            s3c_fimc_free_output_memory(&ctrl->out_frame);
            s3c_fimc_set_output_address(ctrl);
        }
    }

    return 0;
}