summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c')
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c282
1 files changed, 120 insertions, 162 deletions
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index 07fbb77ce2..5fbc47bda6 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -54,40 +54,6 @@
*/
/* ----------------------------------------------------------------------------
- * Helpers
- */
-
-static struct v4l2_mbus_framefmt *
-rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, u32 which)
-{
- struct v4l2_subdev_state state = {
- .pads = isp->pad_cfg
- };
-
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(&isp->sd, sd_state, pad);
- else
- return v4l2_subdev_get_try_format(&isp->sd, &state, pad);
-}
-
-static struct v4l2_rect *
-rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, u32 which)
-{
- struct v4l2_subdev_state state = {
- .pads = isp->pad_cfg
- };
-
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(&isp->sd, sd_state, pad);
- else
- return v4l2_subdev_get_try_crop(&isp->sd, &state, pad);
-}
-
-/* ----------------------------------------------------------------------------
* Camera Interface registers configurations
*/
@@ -96,12 +62,12 @@ rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
* This should only be called when configuring CIF
* or at the frame end interrupt
*/
-static void rkisp1_config_ism(struct rkisp1_isp *isp)
+static void rkisp1_config_ism(struct rkisp1_isp *isp,
+ struct v4l2_subdev_state *sd_state)
{
const struct v4l2_rect *src_crop =
- rkisp1_isp_get_pad_crop(isp, NULL,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
+ v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
struct rkisp1_device *rkisp1 = isp->rkisp1;
u32 val;
@@ -125,21 +91,26 @@ static void rkisp1_config_ism(struct rkisp1_isp *isp)
* configure ISP blocks with input format, size......
*/
static int rkisp1_config_isp(struct rkisp1_isp *isp,
+ struct v4l2_subdev_state *sd_state,
enum v4l2_mbus_type mbus_type, u32 mbus_flags)
{
struct rkisp1_device *rkisp1 = isp->rkisp1;
u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, acq_prop = 0;
- const struct rkisp1_mbus_info *sink_fmt = isp->sink_fmt;
- const struct rkisp1_mbus_info *src_fmt = isp->src_fmt;
+ const struct rkisp1_mbus_info *sink_fmt;
+ const struct rkisp1_mbus_info *src_fmt;
+ const struct v4l2_mbus_framefmt *src_frm;
const struct v4l2_mbus_framefmt *sink_frm;
const struct v4l2_rect *sink_crop;
- sink_frm = rkisp1_isp_get_pad_fmt(isp, NULL,
- RKISP1_ISP_PAD_SINK_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- sink_crop = rkisp1_isp_get_pad_crop(isp, NULL,
- RKISP1_ISP_PAD_SINK_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
+ sink_frm = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ sink_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ src_frm = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+
+ sink_fmt = rkisp1_mbus_info_get_by_code(sink_frm->code);
+ src_fmt = rkisp1_mbus_info_get_by_code(src_frm->code);
if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
acq_mult = 1;
@@ -230,14 +201,15 @@ static int rkisp1_config_isp(struct rkisp1_isp *isp,
} else {
struct v4l2_mbus_framefmt *src_frm;
- src_frm = rkisp1_isp_get_pad_fmt(isp, NULL,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
+ src_frm = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
rkisp1_params_pre_configure(&rkisp1->params, sink_fmt->bayer_pat,
src_frm->quantization,
src_frm->ycbcr_enc);
}
+ isp->sink_fmt = sink_fmt;
+
return 0;
}
@@ -258,16 +230,17 @@ static void rkisp1_config_path(struct rkisp1_isp *isp,
/* Hardware configure Entry */
static int rkisp1_config_cif(struct rkisp1_isp *isp,
+ struct v4l2_subdev_state *sd_state,
enum v4l2_mbus_type mbus_type, u32 mbus_flags)
{
int ret;
- ret = rkisp1_config_isp(isp, mbus_type, mbus_flags);
+ ret = rkisp1_config_isp(isp, sd_state, mbus_type, mbus_flags);
if (ret)
return ret;
rkisp1_config_path(isp, mbus_type);
- rkisp1_config_ism(isp);
+ rkisp1_config_ism(isp, sd_state);
return 0;
}
@@ -281,11 +254,25 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp)
* ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
* Stop ISP(isp) ->wait for ISP isp off
*/
- /* stop and clear MI and ISP interrupts */
- rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0);
- rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0);
+ /* Mask MI and ISP interrupts */
+ rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0);
rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0);
+
+ /* Flush posted writes */
+ rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC);
+
+ /*
+ * Wait until the IRQ handler has ended. The IRQ handler may get called
+ * even after this, but it will return immediately as the MI and ISP
+ * interrupts have been masked.
+ */
+ synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]);
+ if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI])
+ synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]);
+
+ /* Clear MI and ISP interrupt status */
+ rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0);
rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0);
/* stop ISP */
@@ -328,9 +315,12 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
}
}
-static void rkisp1_isp_start(struct rkisp1_isp *isp)
+static void rkisp1_isp_start(struct rkisp1_isp *isp,
+ struct v4l2_subdev_state *sd_state)
{
struct rkisp1_device *rkisp1 = isp->rkisp1;
+ const struct v4l2_mbus_framefmt *src_fmt;
+ const struct rkisp1_mbus_info *src_info;
u32 val;
rkisp1_config_clk(isp);
@@ -342,7 +332,11 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp)
RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;
rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);
- if (isp->src_fmt->pixel_enc != V4L2_PIXEL_ENC_BAYER)
+ src_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
+
+ if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
rkisp1_params_post_configure(&rkisp1->params);
}
@@ -436,7 +430,7 @@ static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
struct v4l2_rect *sink_crop, *src_crop;
/* Video. */
- sink_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+ sink_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
RKISP1_ISP_PAD_SINK_VIDEO);
sink_fmt->width = RKISP1_DEFAULT_WIDTH;
sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
@@ -447,14 +441,14 @@ static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
- sink_crop = v4l2_subdev_get_try_crop(sd, sd_state,
+ sink_crop = v4l2_subdev_get_pad_crop(sd, sd_state,
RKISP1_ISP_PAD_SINK_VIDEO);
sink_crop->width = RKISP1_DEFAULT_WIDTH;
sink_crop->height = RKISP1_DEFAULT_HEIGHT;
sink_crop->left = 0;
sink_crop->top = 0;
- src_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+ src_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
RKISP1_ISP_PAD_SOURCE_VIDEO);
*src_fmt = *sink_fmt;
src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
@@ -463,14 +457,14 @@ static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
src_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
- src_crop = v4l2_subdev_get_try_crop(sd, sd_state,
+ src_crop = v4l2_subdev_get_pad_crop(sd, sd_state,
RKISP1_ISP_PAD_SOURCE_VIDEO);
*src_crop = *sink_crop;
/* Parameters and statistics. */
- sink_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+ sink_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
RKISP1_ISP_PAD_SINK_PARAMS);
- src_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+ src_fmt = v4l2_subdev_get_pad_format(sd, sd_state,
RKISP1_ISP_PAD_SOURCE_STATS);
sink_fmt->width = 0;
sink_fmt->height = 0;
@@ -483,8 +477,7 @@ static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
struct v4l2_subdev_state *sd_state,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
+ struct v4l2_mbus_framefmt *format)
{
const struct rkisp1_mbus_info *sink_info;
const struct rkisp1_mbus_info *src_info;
@@ -493,12 +486,12 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
const struct v4l2_rect *src_crop;
bool set_csc;
- sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO, which);
- src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- src_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ sink_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ src_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ src_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
/*
* Media bus code. The ISP can operate in pass-through mode (Bayer in,
@@ -581,26 +574,20 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
*/
if (set_csc)
format->flags |= V4L2_MBUS_FRAMEFMT_SET_CSC;
-
- /* Store the source format info when setting the active format. */
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- isp->src_fmt = src_info;
}
static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
struct v4l2_subdev_state *sd_state,
- struct v4l2_rect *r, unsigned int which)
+ struct v4l2_rect *r)
{
struct v4l2_mbus_framefmt *src_fmt;
const struct v4l2_rect *sink_crop;
struct v4l2_rect *src_crop;
- src_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- which);
- sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
+ src_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ sink_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
src_crop->left = ALIGN(r->left, 2);
src_crop->width = ALIGN(r->width, 2);
@@ -611,24 +598,22 @@ static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
*r = *src_crop;
/* Propagate to out format */
- src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- rkisp1_isp_set_src_fmt(isp, sd_state, src_fmt, which);
+ src_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ rkisp1_isp_set_src_fmt(isp, sd_state, src_fmt);
}
static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
struct v4l2_subdev_state *sd_state,
- struct v4l2_rect *r, unsigned int which)
+ struct v4l2_rect *r)
{
struct v4l2_rect *sink_crop, *src_crop;
const struct v4l2_mbus_framefmt *sink_fmt;
- sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
- sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
+ sink_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ sink_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
sink_crop->left = ALIGN(r->left, 2);
sink_crop->width = ALIGN(r->width, 2);
@@ -639,32 +624,28 @@ static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
*r = *sink_crop;
/* Propagate to out crop */
- src_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- rkisp1_isp_set_src_crop(isp, sd_state, src_crop, which);
+ src_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ rkisp1_isp_set_src_crop(isp, sd_state, src_crop);
}
static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
struct v4l2_subdev_state *sd_state,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
+ struct v4l2_mbus_framefmt *format)
{
const struct rkisp1_mbus_info *mbus_info;
struct v4l2_mbus_framefmt *sink_fmt;
struct v4l2_rect *sink_crop;
bool is_yuv;
- sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
+ sink_fmt = v4l2_subdev_get_pad_format(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
sink_fmt->code = format->code;
mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {
sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
}
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- isp->sink_fmt = mbus_info;
sink_fmt->width = clamp_t(u32, format->width,
RKISP1_ISP_MIN_WIDTH,
@@ -706,23 +687,9 @@ static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
*format = *sink_fmt;
/* Propagate to in crop */
- sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
- rkisp1_isp_set_sink_crop(isp, sd_state, sink_crop, which);
-}
-
-static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct rkisp1_isp *isp = to_rkisp1_isp(sd);
-
- mutex_lock(&isp->ops_lock);
- fmt->format = *rkisp1_isp_get_pad_fmt(isp, sd_state, fmt->pad,
- fmt->which);
- mutex_unlock(&isp->ops_lock);
- return 0;
+ sink_crop = v4l2_subdev_get_pad_crop(&isp->sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ rkisp1_isp_set_sink_crop(isp, sd_state, sink_crop);
}
static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
@@ -731,18 +698,13 @@ static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
{
struct rkisp1_isp *isp = to_rkisp1_isp(sd);
- mutex_lock(&isp->ops_lock);
if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)
- rkisp1_isp_set_sink_fmt(isp, sd_state, &fmt->format,
- fmt->which);
+ rkisp1_isp_set_sink_fmt(isp, sd_state, &fmt->format);
else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
- rkisp1_isp_set_src_fmt(isp, sd_state, &fmt->format,
- fmt->which);
+ rkisp1_isp_set_src_fmt(isp, sd_state, &fmt->format);
else
- fmt->format = *rkisp1_isp_get_pad_fmt(isp, sd_state, fmt->pad,
- fmt->which);
+ fmt->format = *v4l2_subdev_get_pad_format(sd, sd_state, fmt->pad);
- mutex_unlock(&isp->ops_lock);
return 0;
}
@@ -750,39 +712,37 @@ static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_selection *sel)
{
- struct rkisp1_isp *isp = to_rkisp1_isp(sd);
int ret = 0;
if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&
sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)
return -EINVAL;
- mutex_lock(&isp->ops_lock);
switch (sel->target) {
case V4L2_SEL_TGT_CROP_BOUNDS:
if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
struct v4l2_mbus_framefmt *fmt;
- fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, sel->pad,
- sel->which);
+ fmt = v4l2_subdev_get_pad_format(sd, sd_state, sel->pad);
sel->r.height = fmt->height;
sel->r.width = fmt->width;
sel->r.left = 0;
sel->r.top = 0;
} else {
- sel->r = *rkisp1_isp_get_pad_crop(isp, sd_state,
- RKISP1_ISP_PAD_SINK_VIDEO,
- sel->which);
+ sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state,
+ RKISP1_ISP_PAD_SINK_VIDEO);
}
break;
+
case V4L2_SEL_TGT_CROP:
- sel->r = *rkisp1_isp_get_pad_crop(isp, sd_state, sel->pad,
- sel->which);
+ sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state, sel->pad);
break;
+
default:
ret = -EINVAL;
+ break;
}
- mutex_unlock(&isp->ops_lock);
+
return ret;
}
@@ -798,15 +758,14 @@ static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,
dev_dbg(isp->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
- mutex_lock(&isp->ops_lock);
+
if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)
- rkisp1_isp_set_sink_crop(isp, sd_state, &sel->r, sel->which);
+ rkisp1_isp_set_sink_crop(isp, sd_state, &sel->r);
else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
- rkisp1_isp_set_src_crop(isp, sd_state, &sel->r, sel->which);
+ rkisp1_isp_set_src_crop(isp, sd_state, &sel->r);
else
ret = -EINVAL;
- mutex_unlock(&isp->ops_lock);
return ret;
}
@@ -824,7 +783,7 @@ static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {
.get_selection = rkisp1_isp_get_selection,
.set_selection = rkisp1_isp_set_selection,
.init_cfg = rkisp1_isp_init_config,
- .get_fmt = rkisp1_isp_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = rkisp1_isp_set_fmt,
.link_validate = v4l2_subdev_link_validate_default,
};
@@ -837,6 +796,7 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
{
struct rkisp1_isp *isp = to_rkisp1_isp(sd);
struct rkisp1_device *rkisp1 = isp->rkisp1;
+ struct v4l2_subdev_state *sd_state;
struct media_pad *source_pad;
struct media_pad *sink_pad;
enum v4l2_mbus_type mbus_type;
@@ -881,21 +841,23 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
}
isp->frame_sequence = -1;
- mutex_lock(&isp->ops_lock);
- ret = rkisp1_config_cif(isp, mbus_type, mbus_flags);
+
+ sd_state = v4l2_subdev_lock_and_get_active_state(sd);
+
+ ret = rkisp1_config_cif(isp, sd_state, mbus_type, mbus_flags);
if (ret)
- goto mutex_unlock;
+ goto out_unlock;
- rkisp1_isp_start(isp);
+ rkisp1_isp_start(isp, sd_state);
ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);
if (ret) {
rkisp1_isp_stop(isp);
- goto mutex_unlock;
+ goto out_unlock;
}
-mutex_unlock:
- mutex_unlock(&isp->ops_lock);
+out_unlock:
+ v4l2_subdev_unlock_state(sd_state);
return ret;
}
@@ -933,9 +895,6 @@ static const struct v4l2_subdev_ops rkisp1_isp_ops = {
int rkisp1_isp_register(struct rkisp1_device *rkisp1)
{
- struct v4l2_subdev_state state = {
- .pads = rkisp1->isp.pad_cfg
- };
struct rkisp1_isp *isp = &rkisp1->isp;
struct media_pad *pads = isp->pads;
struct v4l2_subdev *sd = &isp->sd;
@@ -956,27 +915,26 @@ int rkisp1_isp_register(struct rkisp1_device *rkisp1)
pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
- isp->sink_fmt = rkisp1_mbus_info_get_by_code(RKISP1_DEF_SINK_PAD_FMT);
- isp->src_fmt = rkisp1_mbus_info_get_by_code(RKISP1_DEF_SRC_PAD_FMT);
-
- mutex_init(&isp->ops_lock);
ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);
if (ret)
- goto error;
+ goto err_entity_cleanup;
+
+ ret = v4l2_subdev_init_finalize(sd);
+ if (ret)
+ goto err_subdev_cleanup;
ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);
if (ret) {
dev_err(rkisp1->dev, "Failed to register isp subdev\n");
- goto error;
+ goto err_subdev_cleanup;
}
- rkisp1_isp_init_config(sd, &state);
-
return 0;
-error:
+err_subdev_cleanup:
+ v4l2_subdev_cleanup(sd);
+err_entity_cleanup:
media_entity_cleanup(&sd->entity);
- mutex_destroy(&isp->ops_lock);
isp->sd.v4l2_dev = NULL;
return ret;
}
@@ -989,8 +947,8 @@ void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
return;
v4l2_device_unregister_subdev(&isp->sd);
+ v4l2_subdev_cleanup(&isp->sd);
media_entity_cleanup(&isp->sd.entity);
- mutex_destroy(&isp->ops_lock);
}
/* ----------------------------------------------------------------------------