Пример #1
0
static
struct s3c_fimc_control *s3c_fimc_register_controller(struct platform_device *pdev)
{
	struct s3c_platform_fimc *pdata;
	struct s3c_fimc_control *ctrl;
	struct resource *res;
	int i = S3C_FIMC_MAX_CTRLS - 1;
	int id = pdev->id;

	pdata = to_fimc_plat(&pdev->dev);

	//printk("[CAM]s3c_fimc_register_controller.id=%d\n",id);

	ctrl = &s3c_fimc.ctrl[id];
	ctrl->id = id;
	ctrl->dev = &pdev->dev;
	ctrl->vd = &s3c_fimc_video_device[id];
	ctrl->rot90 = 0;
	ctrl->vd->minor = id;
	ctrl->out_frame.nr_frames = pdata->nr_frames;
	ctrl->out_frame.skip_frames = 0;
	ctrl->scaler.line_length = pdata->line_length;

	sprintf(ctrl->name, "%s%d", S3C_FIMC_NAME, id);
	strcpy(ctrl->vd->name, ctrl->name);

	ctrl->open_lcdfifo = s3cfb_enable_local;
	ctrl->close_lcdfifo = s3cfb_enable_dma;

	atomic_set(&ctrl->in_use, 0);
	mutex_init(&ctrl->lock);
	init_waitqueue_head(&ctrl->waitq);

	/* get resource for io memory */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		err("failed to get io memory region\n");
		return NULL;
	}

	if (!pdata->shared_io) {
		/* request mem region */
		res = request_mem_region(res->start, res->end - res->start + 1, pdev->name);
		if (!res) {
			err("failed to request io memory region\n");
			return NULL;
		}

		/* ioremap for register block */
		ctrl->regs = ioremap(res->start, res->end - res->start + 1);
	} else {
		while (i >= 0 && ctrl->regs == NULL) {
			ctrl->regs = s3c_fimc.ctrl[i].regs;
			i--;
		}
	}

	if (!ctrl->regs) {
		err("failed to remap io region\n");
		return NULL;
	}

	/* irq */
	ctrl->irq = platform_get_irq(pdev, 0);
	if (request_irq(ctrl->irq, s3c_fimc_irq, IRQF_DISABLED, ctrl->name, ctrl))
		err("request_irq failed\n");

	s3c_fimc_reset(ctrl);
	s3c_fimc_set_active_camera(ctrl, 0);//note: only one camera type

	return ctrl;
}
static int s3c_fimc_v4l2_s_ctrl(struct file *filp, void *fh,
                                struct v4l2_control *c)
{
    struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
    struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
    struct s3c_fimc_window_offset *offset = &ctrl->in_cam->offset;

    switch (c->id) {
    case V4L2_CID_EFFECT_ORIGINAL:
        frame->effect.type = EFFECT_ORIGINAL;
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_EFFECT_NEGATIVE:
        frame->effect.type = EFFECT_NEGATIVE;
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_EFFECT_EMBOSSING:
        frame->effect.type = EFFECT_EMBOSSING;
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_EFFECT_ARTFREEZE:
        frame->effect.type = EFFECT_ARTFREEZE;
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_EFFECT_SILHOUETTE:
        frame->effect.type = EFFECT_SILHOUETTE;
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_EFFECT_ARBITRARY:
        frame->effect.type = EFFECT_ARBITRARY;
        frame->effect.pat_cb = PAT_CB(c->value);
        frame->effect.pat_cr = PAT_CR(c->value);
        s3c_fimc_change_effect(ctrl);
        break;

    case V4L2_CID_ROTATE_ORIGINAL:
        frame->flip = FLIP_ORIGINAL;
        ctrl->rot90 = 0;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_HFLIP:
        frame->flip = FLIP_X_AXIS;
        ctrl->rot90 = 0;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_VFLIP:
        frame->flip = FLIP_Y_AXIS;
        ctrl->rot90 = 0;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ROTATE_180:
        frame->flip = FLIP_XY_AXIS;
        ctrl->rot90 = 0;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ROTATE_90:
        frame->flip = FLIP_ORIGINAL;
        ctrl->rot90 = 1;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ROTATE_270:
        frame->flip = FLIP_XY_AXIS;
        ctrl->rot90 = 1;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ROTATE_90_HFLIP:
        frame->flip = FLIP_X_AXIS;
        ctrl->rot90 = 1;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ROTATE_90_VFLIP:
        frame->flip = FLIP_Y_AXIS;
        ctrl->rot90 = 1;
        s3c_fimc_change_rotate(ctrl);
        break;

    case V4L2_CID_ZOOM_IN:
        if (s3c_fimc_check_zoom(ctrl, c->id) == 0) {
            offset->h1 += S3C_FIMC_ZOOM_PIXELS;
            offset->h2 += S3C_FIMC_ZOOM_PIXELS;
            offset->v1 += S3C_FIMC_ZOOM_PIXELS;
            offset->v2 += S3C_FIMC_ZOOM_PIXELS;
            s3c_fimc_restart_dma(ctrl);
        }

        break;

    case V4L2_CID_ZOOM_OUT:
        if (s3c_fimc_check_zoom(ctrl, c->id) == 0) {
            offset->h1 -= S3C_FIMC_ZOOM_PIXELS;
            offset->h2 -= S3C_FIMC_ZOOM_PIXELS;
            offset->v1 -= S3C_FIMC_ZOOM_PIXELS;
            offset->v2 -= S3C_FIMC_ZOOM_PIXELS;
            s3c_fimc_restart_dma(ctrl);
        }

        break;

    case V4L2_CID_AUTO_WHITE_BALANCE:
        s3c_fimc_i2c_command(ctrl, I2C_CAM_WB, c->value);
        break;

    case V4L2_CID_ACTIVE_CAMERA:
        s3c_fimc_set_active_camera(ctrl, c->value);
        s3c_fimc_i2c_command(ctrl, I2C_CAM_WB, WB_AUTO);
        break;

    case V4L2_CID_TEST_PATTERN:
        s3c_fimc_set_active_camera(ctrl, S3C_FIMC_TPID);
        s3c_fimc_set_test_pattern(ctrl, c->value);
        break;

    case V4L2_CID_NR_FRAMES:
        s3c_fimc_set_nr_frames(ctrl, c->value);
        break;

    case V4L2_CID_INPUT_ADDR:
        s3c_fimc_alloc_input_memory(&ctrl->in_frame, \
                                    (dma_addr_t) c->value);
        s3c_fimc_set_input_address(ctrl);
        break;

    case V4L2_CID_INPUT_ADDR_Y:
    case V4L2_CID_INPUT_ADDR_RGB:
        s3c_fimc_alloc_y_memory(&ctrl->in_frame, \
                                (dma_addr_t) c->value);
        s3c_fimc_set_input_address(ctrl);
        break;

    case V4L2_CID_INPUT_ADDR_CB:	/* fall through */
    case V4L2_CID_INPUT_ADDR_CBCR:
        s3c_fimc_alloc_cb_memory(&ctrl->in_frame, \
                                 (dma_addr_t) c->value);
        s3c_fimc_set_input_address(ctrl);
        break;

    case V4L2_CID_INPUT_ADDR_CR:
        s3c_fimc_alloc_cr_memory(&ctrl->in_frame, \
                                 (dma_addr_t) c->value);
        s3c_fimc_set_input_address(ctrl);
        break;

    case V4L2_CID_RESET:
        ctrl->rot90 = 0;
        ctrl->in_frame.flip = FLIP_ORIGINAL;
        ctrl->out_frame.flip = FLIP_ORIGINAL;
        ctrl->out_frame.effect.type = EFFECT_ORIGINAL;
        ctrl->scaler.bypass = 0;
        s3c_fimc_reset(ctrl);
        break;

    case V4L2_CID_JPEG_INPUT:	/* fall through */
    case V4L2_CID_SCALER_BYPASS:
        ctrl->scaler.bypass = 1;
        break;

    case V4L2_CID_THUMBNAIL_SIZE:
        frame->jpeg.thumb_res = c->value;
        break;

    case V4L2_CID_JPEG_QUALITY:
        frame->jpeg.quality = c->value - 1;
        break;

    default:
        err("invalid control id: %d\n", c->id);
        return -EINVAL;
    }

    return 0;
}