Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285405
b: refs/heads/master
c: dafb9c7
h: refs/heads/master
i:
  285403: 1b5fb7d
v: v3
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Dec 30, 2011
1 parent 106395d commit 7ff3c57
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc1d327232759647ea56725eab1c6b16c92d52fa
refs/heads/master: dafb9c70abb7896a43288fbec2a9f2ed6e915d18
11 changes: 11 additions & 0 deletions trunk/drivers/media/video/s5p-fimc/fimc-capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ static int fimc_init_capture(struct fimc_dev *fimc)
fimc_hw_set_effect(ctx, false);
fimc_hw_set_output_path(ctx);
fimc_hw_set_out_dma(ctx);
if (fimc->variant->has_alpha)
fimc_hw_set_rgb_alpha(ctx);
clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
}
spin_unlock_irqrestore(&fimc->slock, flags);
Expand Down Expand Up @@ -154,6 +156,8 @@ int fimc_capture_config_update(struct fimc_ctx *ctx)
fimc_hw_set_rotation(ctx);
fimc_prepare_dma_offset(ctx, &ctx->d_frame);
fimc_hw_set_out_dma(ctx);
if (fimc->variant->has_alpha)
fimc_hw_set_rgb_alpha(ctx);
clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
}
spin_unlock(&ctx->slock);
Expand Down Expand Up @@ -812,6 +816,10 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
FIMC_SD_PAD_SOURCE);
if (!ff->fmt)
return -EINVAL;

/* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx);

/* Try to match format at the host and the sensor */
if (!fimc->vid_cap.user_subdev_api) {
mf->code = ff->fmt->mbus_code;
Expand Down Expand Up @@ -1235,6 +1243,9 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
*mf = fmt->format;
return 0;
}
/* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx);

fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));

ff = fmt->pad == FIMC_SD_PAD_SINK ?
Expand Down
129 changes: 103 additions & 26 deletions trunk/drivers/media/video/s5p-fimc/fimc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,29 @@ static struct fimc_fmt fimc_formats[] = {
.colplanes = 1,
.flags = FMT_FLAGS_M2M,
}, {
.name = "XRGB-8-8-8-8, 32 bpp",
.name = "ARGB8888, 32 bpp",
.fourcc = V4L2_PIX_FMT_RGB32,
.depth = { 32 },
.color = S5P_FIMC_RGB888,
.memplanes = 1,
.colplanes = 1,
.flags = FMT_FLAGS_M2M,
.flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
}, {
.name = "ARGB1555",
.fourcc = V4L2_PIX_FMT_RGB555,
.depth = { 16 },
.color = S5P_FIMC_RGB555,
.memplanes = 1,
.colplanes = 1,
.flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
}, {
.name = "ARGB4444",
.fourcc = V4L2_PIX_FMT_RGB444,
.depth = { 16 },
.color = S5P_FIMC_RGB444,
.memplanes = 1,
.colplanes = 1,
.flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
}, {
.name = "YUV 4:2:2 packed, YCbYCr",
.fourcc = V4L2_PIX_FMT_YUYV,
Expand Down Expand Up @@ -171,6 +187,14 @@ static struct fimc_fmt fimc_formats[] = {
},
};

static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
{
if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return FMT_FLAGS_M2M_IN;
else
return FMT_FLAGS_M2M_OUT;
}

int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
int dw, int dh, int rotation)
{
Expand Down Expand Up @@ -652,8 +676,11 @@ static void fimc_dma_run(void *priv)
if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS))
fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr, -1);

if (ctx->state & FIMC_PARAMS)
if (ctx->state & FIMC_PARAMS) {
fimc_hw_set_out_dma(ctx);
if (fimc->variant->has_alpha)
fimc_hw_set_rgb_alpha(ctx);
}

fimc_activate_capture(ctx);

Expand Down Expand Up @@ -750,72 +777,89 @@ static struct vb2_ops fimc_qops = {
#define ctrl_to_ctx(__ctrl) \
container_of((__ctrl)->handler, struct fimc_ctx, ctrl_handler)

static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
{
struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
struct fimc_dev *fimc = ctx->fimc_dev;
struct samsung_fimc_variant *variant = fimc->variant;
unsigned long flags;
unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
int ret = 0;

if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
return 0;

switch (ctrl->id) {
case V4L2_CID_HFLIP:
spin_lock_irqsave(&ctx->slock, flags);
ctx->hflip = ctrl->val;
break;

case V4L2_CID_VFLIP:
spin_lock_irqsave(&ctx->slock, flags);
ctx->vflip = ctrl->val;
break;

case V4L2_CID_ROTATE:
if (fimc_capture_pending(fimc) ||
fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
(ctx->state & flags) == flags) {
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ctx->s_frame.height, ctx->d_frame.width,
ctx->d_frame.height, ctrl->val);
}
if (ret) {
v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
return -EINVAL;
if (ret)
return -EINVAL;
}
if ((ctrl->val == 90 || ctrl->val == 270) &&
!variant->has_out_rot)
return -EINVAL;
spin_lock_irqsave(&ctx->slock, flags);

ctx->rotation = ctrl->val;
break;

default:
v4l2_err(fimc->v4l2_dev, "Invalid control: 0x%X\n", ctrl->id);
return -EINVAL;
case V4L2_CID_ALPHA_COMPONENT:
ctx->d_frame.alpha = ctrl->val;
break;
}
ctx->state |= FIMC_PARAMS;
set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
spin_unlock_irqrestore(&ctx->slock, flags);
return 0;
}

static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
unsigned long flags;
int ret;

spin_lock_irqsave(&ctx->slock, flags);
ret = __fimc_s_ctrl(ctx, ctrl);
spin_unlock_irqrestore(&ctx->slock, flags);

return ret;
}

static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
.s_ctrl = fimc_s_ctrl,
};

int fimc_ctrls_create(struct fimc_ctx *ctx)
{
struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);

if (ctx->ctrls_rdy)
return 0;
v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);

ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
V4L2_CID_HFLIP, 0, 1, 1, 0);
ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops,
V4L2_CID_ROTATE, 0, 270, 90, 0);
if (variant->has_alpha)
ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler,
&fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
0, max_alpha, 1, 0);
else
ctx->ctrl_alpha = NULL;

ctx->ctrls_rdy = ctx->ctrl_handler.error == 0;

return ctx->ctrl_handler.error;
Expand All @@ -826,18 +870,23 @@ void fimc_ctrls_delete(struct fimc_ctx *ctx)
if (ctx->ctrls_rdy) {
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
ctx->ctrls_rdy = false;
ctx->ctrl_alpha = NULL;
}
}

void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
{
unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;

if (!ctx->ctrls_rdy)
return;

mutex_lock(&ctx->ctrl_handler.lock);
v4l2_ctrl_activate(ctx->ctrl_rotate, active);
v4l2_ctrl_activate(ctx->ctrl_hflip, active);
v4l2_ctrl_activate(ctx->ctrl_vflip, active);
if (ctx->ctrl_alpha)
v4l2_ctrl_activate(ctx->ctrl_alpha, active && has_alpha);

if (active) {
ctx->rotation = ctx->ctrl_rotate->val;
Expand All @@ -851,6 +900,24 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
mutex_unlock(&ctx->ctrl_handler.lock);
}

/* Update maximum value of the alpha color control */
void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
{
struct fimc_dev *fimc = ctx->fimc_dev;
struct v4l2_ctrl *ctrl = ctx->ctrl_alpha;

if (ctrl == NULL || !fimc->variant->has_alpha)
return;

v4l2_ctrl_lock(ctrl);
ctrl->maximum = fimc_get_alpha_mask(ctx->d_frame.fmt);

if (ctrl->cur.val > ctrl->maximum)
ctrl->cur.val = ctrl->maximum;

v4l2_ctrl_unlock(ctrl);
}

/*
* V4L2 ioctl handlers
*/
Expand All @@ -874,7 +941,8 @@ static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
{
struct fimc_fmt *fmt;

fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_M2M, f->index);
fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
f->index);
if (!fmt)
return -EINVAL;

Expand Down Expand Up @@ -938,6 +1006,7 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
pix->colorspace = V4L2_COLORSPACE_JPEG;
pix->field = V4L2_FIELD_NONE;
pix->num_planes = fmt->memplanes;
pix->pixelformat = fmt->fourcc;
pix->height = height;
pix->width = width;

Expand Down Expand Up @@ -1017,7 +1086,8 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)

dbg("w: %d, h: %d", pix->width, pix->height);

fmt = fimc_find_format(&pix->pixelformat, NULL, FMT_FLAGS_M2M, 0);
fmt = fimc_find_format(&pix->pixelformat, NULL,
get_m2m_fmt_flags(f->type), 0);
if (WARN(fmt == NULL, "Pixel format lookup failed"))
return -EINVAL;

Expand Down Expand Up @@ -1087,10 +1157,13 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,

pix = &f->fmt.pix_mp;
frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
FMT_FLAGS_M2M, 0);
get_m2m_fmt_flags(f->type), 0);
if (!frame->fmt)
return -EINVAL;

/* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx);

for (i = 0; i < frame->fmt->colplanes; i++) {
frame->payload[i] =
(pix->width * pix->height * frame->fmt->depth[i]) / 8;
Expand Down Expand Up @@ -1374,6 +1447,12 @@ static int fimc_m2m_open(struct file *file)
if (!ctx)
return -ENOMEM;
v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
ctx->fimc_dev = fimc;

/* Default color format */
ctx->s_frame.fmt = &fimc_formats[0];
ctx->d_frame.fmt = &fimc_formats[0];

ret = fimc_ctrls_create(ctx);
if (ret)
goto error_fh;
Expand All @@ -1383,10 +1462,6 @@ static int fimc_m2m_open(struct file *file)
file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh);

ctx->fimc_dev = fimc;
/* Default color format */
ctx->s_frame.fmt = &fimc_formats[0];
ctx->d_frame.fmt = &fimc_formats[0];
/* Setup the device context for memory-to-memory mode */
ctx->state = FIMC_CTX_M2M;
ctx->flags = 0;
Expand Down Expand Up @@ -1893,6 +1968,7 @@ static struct samsung_fimc_variant fimc0_variant_exynos4 = {
.has_cam_if = 1,
.has_cistatus2 = 1,
.has_mainscaler_ext = 1,
.has_alpha = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 2,
Expand All @@ -1906,6 +1982,7 @@ static struct samsung_fimc_variant fimc3_variant_exynos4 = {
.has_cam_if = 1,
.has_cistatus2 = 1,
.has_mainscaler_ext = 1,
.has_alpha = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 16,
.hor_offs_align = 2,
Expand Down
Loading

0 comments on commit 7ff3c57

Please sign in to comment.