diff --git a/drivers/media/platform/rockchip/isp1/capture.c b/drivers/media/platform/rockchip/isp1/capture.c index 6c71dc5e466c..852d55b2bebc 100644 --- a/drivers/media/platform/rockchip/isp1/capture.c +++ b/drivers/media/platform/rockchip/isp1/capture.c @@ -1501,11 +1501,28 @@ static int rkisp1_fop_release(struct file *file) return ret; } +void rkisp1_set_stream_def_fmt(struct rkisp1_device *dev, u32 id, + u32 width, u32 height, u32 pixelformat) +{ + struct rkisp1_stream *stream = &dev->stream[id]; + struct v4l2_pix_format_mplane pixm; + + memset(&pixm, 0, sizeof(pixm)); + pixm.pixelformat = pixelformat; + pixm.width = width; + pixm.height = height; + rkisp1_set_fmt(stream, &pixm, false); + + stream->dcrop.left = 0; + stream->dcrop.top = 0; + stream->dcrop.width = width; + stream->dcrop.height = height; +} + /************************* v4l2_file_operations***************************/ void rkisp1_stream_init(struct rkisp1_device *dev, u32 id) { struct rkisp1_stream *stream = &dev->stream[id]; - struct v4l2_pix_format_mplane pixm; memset(stream, 0, sizeof(*stream)); stream->id = id; @@ -1523,17 +1540,10 @@ void rkisp1_stream_init(struct rkisp1_device *dev, u32 id) } stream->streaming = false; - - memset(&pixm, 0, sizeof(pixm)); - pixm.pixelformat = V4L2_PIX_FMT_YUYV; - pixm.width = RKISP1_DEFAULT_WIDTH; - pixm.height = RKISP1_DEFAULT_HEIGHT; - rkisp1_set_fmt(stream, &pixm, false); - - stream->dcrop.left = 0; - stream->dcrop.top = 0; - stream->dcrop.width = RKISP1_DEFAULT_WIDTH; - stream->dcrop.height = RKISP1_DEFAULT_HEIGHT; + rkisp1_set_stream_def_fmt(dev, id, + RKISP1_DEFAULT_WIDTH, + RKISP1_DEFAULT_HEIGHT, + V4L2_PIX_FMT_YUYV); stream->burst = CIF_MI_CTRL_BURST_LEN_LUM_16 | diff --git a/drivers/media/platform/rockchip/isp1/capture.h b/drivers/media/platform/rockchip/isp1/capture.h index 8387e3f1173a..ef1eb7a1d490 100644 --- a/drivers/media/platform/rockchip/isp1/capture.h +++ b/drivers/media/platform/rockchip/isp1/capture.h @@ -188,5 +188,7 @@ void rkisp1_unregister_stream_vdevs(struct rkisp1_device *dev); int rkisp1_register_stream_vdevs(struct rkisp1_device *dev); void rkisp1_mi_isr(u32 mis_val, struct rkisp1_device *dev); void rkisp1_stream_init(struct rkisp1_device *dev, u32 id); +void rkisp1_set_stream_def_fmt(struct rkisp1_device *dev, u32 id, + u32 width, u32 height, u32 pixelformat); #endif /* _RKISP1_PATH_VIDEO_H */ diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c index 794f42b2a273..79d8a5b1ca2d 100644 --- a/drivers/media/platform/rockchip/isp1/dev.c +++ b/drivers/media/platform/rockchip/isp1/dev.c @@ -344,6 +344,68 @@ static int rkisp1_create_links(struct rkisp1_device *dev) sink, 0, flags); } +static int _set_pipeline_default_fmt(struct rkisp1_device *dev) +{ + int ret; + struct v4l2_subdev *isp; + struct v4l2_subdev *sensor; + struct v4l2_subdev_format fmt; + struct v4l2_subdev_selection sel; + struct v4l2_subdev_pad_config cfg; + u32 width, height; + + if (dev->num_sensors) { + sensor = dev->sensors[0].sd; + isp = &dev->isp_sdev.sd; + + /* get fmt from sensor */ + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(sensor, pad, get_fmt, &cfg, &fmt); + if (ret) { + dev_err(dev->dev, + "failed to get fmt for %s\n", + sensor->name); + + return -ENXIO; + } + + sel.r.left = 0; + sel.r.top = 0; + width = fmt.format.width; + height = fmt.format.height; + sel.r.width = fmt.format.width; + sel.r.height = fmt.format.height; + sel.target = V4L2_SEL_TGT_CROP; + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + memset(&cfg, 0, sizeof(cfg)); + + /* change fmt&size for RKISP1_ISP_PAD_SINK */ + fmt.pad = RKISP1_ISP_PAD_SINK; + sel.pad = RKISP1_ISP_PAD_SINK; + v4l2_subdev_call(isp, pad, set_fmt, &cfg, &fmt); + v4l2_subdev_call(isp, pad, set_selection, &cfg, &sel); + + /* change fmt&size for RKISP1_ISP_PAD_SOURCE_PATH */ + if ((fmt.format.code & RKISP1_MEDIA_BUS_FMT_MASK) == + RKISP1_MEDIA_BUS_FMT_BAYER) + fmt.format.code = MEDIA_BUS_FMT_YUYV8_2X8; + + fmt.pad = RKISP1_ISP_PAD_SOURCE_PATH; + sel.pad = RKISP1_ISP_PAD_SOURCE_PATH; + v4l2_subdev_call(isp, pad, set_fmt, &cfg, &fmt); + v4l2_subdev_call(isp, pad, set_selection, &cfg, &sel); + + /* change fmt&size of MP/SP */ + rkisp1_set_stream_def_fmt(dev, RKISP1_STREAM_MP, + width, height, V4L2_PIX_FMT_YUYV); + rkisp1_set_stream_def_fmt(dev, RKISP1_STREAM_SP, + width, height, V4L2_PIX_FMT_YUYV); + } + + return 0; +} + static int subdev_notifier_complete(struct v4l2_async_notifier *notifier) { struct rkisp1_device *dev; @@ -359,6 +421,10 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier) if (ret < 0) goto unlock; + ret = _set_pipeline_default_fmt(dev); + if (ret < 0) + goto unlock; + v4l2_info(&dev->v4l2_dev, "Async subdev notifier completed\n"); unlock: diff --git a/drivers/media/platform/rockchip/isp1/dev.h b/drivers/media/platform/rockchip/isp1/dev.h index 70630f2fe0cf..c3043ea5ff1e 100644 --- a/drivers/media/platform/rockchip/isp1/dev.h +++ b/drivers/media/platform/rockchip/isp1/dev.h @@ -56,6 +56,9 @@ #define RKISP1_MAX_SENSOR 2 #define RKISP1_MAX_PIPELINE 4 +#define RKISP1_MEDIA_BUS_FMT_MASK 0xF000 +#define RKISP1_MEDIA_BUS_FMT_BAYER 0x3000 + enum rkisp1_isp_ver { ISP_V10 = 0, ISP_V11,