Skip to content

Commit

Permalink
[media] s5p-fimc: mem2mem driver refactoring and cleanup
Browse files Browse the repository at this point in the history
Register access functions refactored for camera capture interface
control. Removed the workqueue since it was only useful for FIFO
output mode which is not supported at this time.
Fixed errors on module unload. Comments and whitespace cleanup.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Oct 21, 2010
1 parent 77e6208 commit 548aafc
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 178 deletions.
151 changes: 56 additions & 95 deletions drivers/media/video/s5p-fimc/fimc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static struct fimc_fmt fimc_formats[] = {
.buff_cnt = 1,
.planes_cnt = 2
}
};
};

static struct v4l2_queryctrl fimc_ctrls[] = {
{
Expand All @@ -127,16 +127,14 @@ static struct v4l2_queryctrl fimc_ctrls[] = {
.minimum = 0,
.maximum = 1,
.default_value = 0,
},
{
}, {
.id = V4L2_CID_VFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Vertical flip",
.minimum = 0,
.maximum = 1,
.default_value = 0,
},
{
}, {
.id = V4L2_CID_ROTATE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Rotation (CCW)",
Expand Down Expand Up @@ -181,28 +179,23 @@ static int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f)

static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
{
if (src >= tar * 64) {
u32 sh = 6;

if (src >= 64 * tar)
return -EINVAL;
} else if (src >= tar * 32) {
*ratio = 32;
*shift = 5;
} else if (src >= tar * 16) {
*ratio = 16;
*shift = 4;
} else if (src >= tar * 8) {
*ratio = 8;
*shift = 3;
} else if (src >= tar * 4) {
*ratio = 4;
*shift = 2;
} else if (src >= tar * 2) {
*ratio = 2;
*shift = 1;
} else {
*ratio = 1;
*shift = 0;

while (sh--) {
u32 tmp = 1 << sh;
if (src >= tar * tmp) {
*shift = sh, *ratio = tmp;
return 0;
}
}

*shift = 0, *ratio = 1;

dbg("s: %d, t: %d, shift: %d, ratio: %d",
src, tar, *shift, *ratio);
return 0;
}

Expand Down Expand Up @@ -265,8 +258,8 @@ static int fimc_set_scaler_info(struct fimc_ctx *ctx)
static irqreturn_t fimc_isr(int irq, void *priv)
{
struct fimc_vid_buffer *src_buf, *dst_buf;
struct fimc_dev *fimc = (struct fimc_dev *)priv;
struct fimc_ctx *ctx;
struct fimc_dev *fimc = priv;

BUG_ON(!fimc);
fimc_hw_clear_irq(fimc);
Expand All @@ -281,7 +274,7 @@ static irqreturn_t fimc_isr(int irq, void *priv)
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
if (src_buf && dst_buf) {
spin_lock(&fimc->irqlock);
src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
wake_up(&src_buf->vb.done);
wake_up(&dst_buf->vb.done);
spin_unlock(&fimc->irqlock);
Expand All @@ -295,20 +288,13 @@ static irqreturn_t fimc_isr(int irq, void *priv)
}

/* The color format (planes_cnt, buff_cnt) must be already configured. */
static int fimc_prepare_addr(struct fimc_ctx *ctx,
struct fimc_vid_buffer *buf, enum v4l2_buf_type type)
int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf,
struct fimc_frame *frame, struct fimc_addr *paddr)
{
struct fimc_frame *frame;
struct fimc_addr *paddr;
u32 pix_size;
int ret = 0;
u32 pix_size;

frame = ctx_m2m_get_frame(ctx, type);
if (IS_ERR(frame))
return PTR_ERR(frame);
paddr = &frame->paddr;

if (!buf)
if (buf == NULL || frame == NULL)
return -EINVAL;

pix_size = frame->width * frame->height;
Expand Down Expand Up @@ -344,8 +330,8 @@ static int fimc_prepare_addr(struct fimc_ctx *ctx,
}
}

dbg("PHYS_ADDR: type= %d, y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
type, paddr->y, paddr->cb, paddr->cr, ret);
dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
paddr->y, paddr->cb, paddr->cr, ret);

return ret;
}
Expand Down Expand Up @@ -466,16 +452,14 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)

if (flags & FIMC_SRC_ADDR) {
buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
ret = fimc_prepare_addr(ctx, buf,
V4L2_BUF_TYPE_VIDEO_OUTPUT);
ret = fimc_prepare_addr(ctx, buf, s_frame, &s_frame->paddr);
if (ret)
return ret;
}

if (flags & FIMC_DST_ADDR) {
buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
ret = fimc_prepare_addr(ctx, buf,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
ret = fimc_prepare_addr(ctx, buf, d_frame, &d_frame->paddr);
}

return ret;
Expand All @@ -499,23 +483,24 @@ static void fimc_dma_run(void *priv)
ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR);
ret = fimc_prepare_config(ctx, ctx->state);
if (ret) {
err("general configuration error");
err("Wrong parameters");
goto dma_unlock;
}

if (fimc->m2m.ctx != ctx)
/* Reconfigure hardware if the context has changed. */
if (fimc->m2m.ctx != ctx) {
ctx->state |= FIMC_PARAMS;
fimc->m2m.ctx = ctx;
}

fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr);

if (ctx->state & FIMC_PARAMS) {
fimc_hw_set_input_path(ctx);
fimc_hw_set_in_dma(ctx);
if (fimc_set_scaler_info(ctx)) {
err("scaler configuration error");
err("Scaler setup error");
goto dma_unlock;
}
fimc_hw_set_prescaler(ctx);
fimc_hw_set_scaler(ctx);
fimc_hw_set_target_format(ctx);
fimc_hw_set_rotation(ctx);
Expand All @@ -524,19 +509,15 @@ static void fimc_dma_run(void *priv)

fimc_hw_set_output_path(ctx);
if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS))
fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr);
fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr, -1);

if (ctx->state & FIMC_PARAMS)
fimc_hw_set_out_dma(ctx);

if (ctx->scaler.enabled)
fimc_hw_start_scaler(fimc);
fimc_hw_en_capture(ctx);

ctx->state = 0;
fimc_hw_start_in_dma(fimc);
fimc_activate_capture(ctx);

fimc->m2m.ctx = ctx;
fimc_hw_activate_input_dma(fimc, true);

dma_unlock:
spin_unlock_irqrestore(&ctx->slock, flags);
Expand All @@ -560,7 +541,7 @@ static int fimc_buf_setup(struct videobuf_queue *vq, unsigned int *count,
struct fimc_ctx *ctx = vq->priv_data;
struct fimc_frame *frame;

frame = ctx_m2m_get_frame(ctx, vq->type);
frame = ctx_get_frame(ctx, vq->type);
if (IS_ERR(frame))
return PTR_ERR(frame);

Expand All @@ -578,7 +559,7 @@ static int fimc_buf_prepare(struct videobuf_queue *vq,
struct fimc_frame *frame;
int ret;

frame = ctx_m2m_get_frame(ctx, vq->type);
frame = ctx_get_frame(ctx, vq->type);
if (IS_ERR(frame))
return PTR_ERR(frame);

Expand Down Expand Up @@ -663,7 +644,7 @@ static int fimc_m2m_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct fimc_ctx *ctx = priv;
struct fimc_frame *frame;

frame = ctx_m2m_get_frame(ctx, f->type);
frame = ctx_get_frame(ctx, f->type);
if (IS_ERR(frame))
return PTR_ERR(frame);

Expand Down Expand Up @@ -999,7 +980,7 @@ static int fimc_m2m_cropcap(struct file *file, void *fh,
struct fimc_frame *frame;
struct fimc_ctx *ctx = fh;

frame = ctx_m2m_get_frame(ctx, cr->type);
frame = ctx_get_frame(ctx, cr->type);
if (IS_ERR(frame))
return PTR_ERR(frame);

Expand All @@ -1019,7 +1000,7 @@ static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
struct fimc_frame *frame;
struct fimc_ctx *ctx = file->private_data;

frame = ctx_m2m_get_frame(ctx, cr->type);
frame = ctx_get_frame(ctx, cr->type);
if (IS_ERR(frame))
return PTR_ERR(frame);

Expand Down Expand Up @@ -1052,7 +1033,7 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
return -EINVAL;
}

f = ctx_m2m_get_frame(ctx, cr->type);
f = ctx_get_frame(ctx, cr->type);
if (IS_ERR(f))
return PTR_ERR(f);

Expand Down Expand Up @@ -1136,7 +1117,7 @@ static void queue_init(void *priv, struct videobuf_queue *vq,
struct fimc_dev *fimc = ctx->fimc_dev;

videobuf_queue_dma_contig_init(vq, &fimc_qops,
fimc->m2m.v4l2_dev.dev,
&fimc->pdev->dev,
&fimc->irqlock, type, V4L2_FIELD_NONE,
sizeof(struct fimc_vid_buffer), priv, NULL);
}
Expand All @@ -1159,13 +1140,12 @@ static int fimc_m2m_open(struct file *file)

file->private_data = ctx;
ctx->fimc_dev = fimc;
/* default format */
/* Default color format */
ctx->s_frame.fmt = &fimc_formats[0];
ctx->d_frame.fmt = &fimc_formats[0];
/* per user process device context initialization */
ctx->state = 0;
ctx->flags = 0;
ctx->effect.type = S5P_FIMC_EFFECT_ORIGINAL;
ctx->in_path = FIMC_DMA;
ctx->out_path = FIMC_DMA;
spin_lock_init(&ctx->slock);
Expand Down Expand Up @@ -1241,7 +1221,7 @@ static int fimc_register_m2m_device(struct fimc_dev *fimc)

ret = v4l2_device_register(&pdev->dev, v4l2_dev);
if (ret)
return ret;;
goto err_m2m_r1;

vfd = video_device_alloc();
if (!vfd) {
Expand Down Expand Up @@ -1293,7 +1273,7 @@ static void fimc_unregister_m2m_device(struct fimc_dev *fimc)
if (fimc) {
v4l2_m2m_release(fimc->m2m.m2m_dev);
video_unregister_device(fimc->m2m.vfd);
video_device_release(fimc->m2m.vfd);

v4l2_device_unregister(&fimc->m2m.v4l2_dev);
}
}
Expand Down Expand Up @@ -1399,25 +1379,15 @@ static int fimc_probe(struct platform_device *pdev)
goto err_clk;
}

fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev));
if (!fimc->work_queue) {
ret = -ENOMEM;
goto err_irq;
}

ret = fimc_register_m2m_device(fimc);
if (ret)
goto err_wq;

fimc_hw_en_lastirq(fimc, true);
goto err_irq;

dev_dbg(&pdev->dev, "%s(): fimc-%d registered successfully\n",
__func__, fimc->id);

return 0;

err_wq:
destroy_workqueue(fimc->work_queue);
err_irq:
free_irq(fimc->irq, fimc);
err_clk:
Expand All @@ -1429,7 +1399,7 @@ static int fimc_probe(struct platform_device *pdev)
kfree(fimc->regs_res);
err_info:
kfree(fimc);
dev_err(&pdev->dev, "failed to install\n");

return ret;
}

Expand All @@ -1438,10 +1408,7 @@ static int __devexit fimc_remove(struct platform_device *pdev)
struct fimc_dev *fimc =
(struct fimc_dev *)platform_get_drvdata(pdev);

v4l2_info(&fimc->m2m.v4l2_dev, "Removing %s\n", pdev->name);

free_irq(fimc->irq, fimc);

fimc_hw_reset(fimc);

fimc_unregister_m2m_device(fimc);
Expand All @@ -1450,6 +1417,8 @@ static int __devexit fimc_remove(struct platform_device *pdev)
release_resource(fimc->regs_res);
kfree(fimc->regs_res);
kfree(fimc);

dev_info(&pdev->dev, "%s driver unloaded\n", pdev->name);
return 0;
}

Expand Down Expand Up @@ -1484,7 +1453,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
.has_inp_rot = 1,
.has_out_rot = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 32,
.min_out_pixsize = 16,

.scaler_en_w = 4224,
.scaler_dis_w = 8192,
Expand All @@ -1497,7 +1466,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
.pix_hoff = 1,
.min_inp_pixsize = 16,
.min_out_pixsize = 32,
.min_out_pixsize = 16,

.scaler_en_w = 1920,
.scaler_dis_w = 8192,
Expand Down Expand Up @@ -1547,20 +1516,12 @@ static struct platform_driver fimc_driver = {
}
};

static char banner[] __initdata = KERN_INFO
"S5PC Camera Interface V4L2 Driver, (c) 2010 Samsung Electronics\n";

static int __init fimc_init(void)
{
u32 ret;
printk(banner);

ret = platform_driver_register(&fimc_driver);
if (ret) {
printk(KERN_ERR "FIMC platform driver register failed\n");
return -1;
}
return 0;
int ret = platform_driver_register(&fimc_driver);
if (ret)
err("platform_driver_register failed: %d\n", ret);
return ret;
}

static void __exit fimc_exit(void)
Expand Down
Loading

0 comments on commit 548aafc

Please sign in to comment.