static int s3c_fimc_open(struct inode *inode, struct file *filp) { struct s3c_fimc_control *ctrl; int id, ret; id = MINOR(inode->i_rdev); //printk("[CAM]s3c_fimc_open.id=%d\n",id); ctrl = &s3c_fimc.ctrl[id]; //printk("ctrl->in_cam=%x",ctrl->in_cam); //printk("[CAM]ctrl->in_cam->width=%d\n",ctrl->in_cam->width); mutex_lock(&ctrl->lock); if (atomic_read(&ctrl->in_use)) { ret = -EBUSY; goto resource_busy; } else { atomic_inc(&ctrl->in_use); s3c_fimc_reset(ctrl); filp->private_data = ctrl; } mutex_unlock(&ctrl->lock); return 0; resource_busy: mutex_unlock(&ctrl->lock); return ret; }
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; }