[PATCH v2 5/8] staging: media: starfive: Add ISP bayer video device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add bayer video device to capture bayer format data from ISP.

Signed-off-by: Changhuang Liang <changhuang.liang@xxxxxxxxxxxxxxxx>
---
 .../staging/media/starfive/camss/stf-camss.c  | 12 ++++++
 .../media/starfive/camss/stf-capture.c        | 41 +++++++++++++++++++
 .../media/starfive/camss/stf-isp-hw-ops.c     | 19 +++++++++
 .../staging/media/starfive/camss/stf-isp.h    |  1 +
 .../staging/media/starfive/camss/stf-video.h  |  1 +
 5 files changed, 74 insertions(+)

diff --git a/drivers/staging/media/starfive/camss/stf-camss.c b/drivers/staging/media/starfive/camss/stf-camss.c
index 62bf46a69a3e..b2f9892b7663 100644
--- a/drivers/staging/media/starfive/camss/stf-camss.c
+++ b/drivers/staging/media/starfive/camss/stf-camss.c
@@ -125,6 +125,7 @@ static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
 
 static int stfcamss_register_devs(struct stfcamss *stfcamss)
 {
+	struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
 	struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
 	struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
 	struct stf_output *output = &stfcamss->output;
@@ -172,8 +173,17 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)
 	if (ret)
 		goto err_rm_links1;
 
+	ret = media_create_pad_link(&isp_dev->subdev.entity, STF_ISP_PAD_SRC_BAYER,
+				    &cap_bayer->video.vdev.entity, 0, 0);
+	if (ret)
+		goto err_rm_links2;
+
+	cap_bayer->video.source_subdev = &isp_dev->subdev;
+
 	return ret;
 
+err_rm_links2:
+	media_entity_remove_links(&output->video.vdev.entity);
 err_rm_links1:
 	media_entity_remove_links(&cap_scd->video.vdev.entity);
 err_rm_links0:
@@ -191,6 +201,7 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)
 
 static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
 {
+	struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
 	struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
 	struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
 	struct stf_output *output = &stfcamss->output;
@@ -200,6 +211,7 @@ static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
 	media_entity_remove_links(&isp_dev->subdev.entity);
 	media_entity_remove_links(&cap_yuv->video.vdev.entity);
 	media_entity_remove_links(&cap_scd->video.vdev.entity);
+	media_entity_remove_links(&cap_bayer->video.vdev.entity);
 
 	stf_isp_unregister(&stfcamss->isp_dev);
 	stf_capture_unregister(stfcamss);
diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c
index 328b8c6e351d..21a59259d7a0 100644
--- a/drivers/staging/media/starfive/camss/stf-capture.c
+++ b/drivers/staging/media/starfive/camss/stf-capture.c
@@ -12,6 +12,7 @@
 static const char * const stf_cap_names[] = {
 	"capture_raw",
 	"capture_yuv",
+	"capture_bayer",
 	"capture_scd",
 };
 
@@ -56,6 +57,37 @@ static const struct stfcamss_format_info stf_isp_fmts[] = {
 	},
 };
 
+static const struct stfcamss_format_info stf_isp_bayer_fmts[] = {
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SRGGB12,
+		.planes = 1,
+		.vsub = { 1 },
+		.bpp = 12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGRBG12,
+		.planes = 1,
+		.vsub = { 1 },
+		.bpp = 12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGBRG12,
+		.planes = 1,
+		.vsub = { 1 },
+		.bpp = 12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SBGGR12,
+		.planes = 1,
+		.vsub = { 1 },
+		.bpp = 12,
+	},
+};
+
 /* 3A Statistics Collection Data */
 static const struct stfcamss_format_info stf_isp_scd_fmts[] = {
 	{
@@ -93,6 +125,8 @@ static void stf_init_addrs(struct stfcamss_video *video)
 		stf_set_raw_addr(video->stfcamss, addr0);
 	else if (cap->type == STF_CAPTURE_YUV)
 		stf_set_yuv_addr(video->stfcamss, addr0, addr1);
+	else if (cap->type == STF_CAPTURE_BAYER)
+		stf_set_bayer_addr(video->stfcamss, addr0);
 	else
 		stf_set_scd_addr(video->stfcamss, addr0, addr1, TYPE_AWB);
 }
@@ -251,6 +285,11 @@ static void stf_capture_init(struct stfcamss *stfcamss, struct stf_capture *cap)
 		cap->video.formats = stf_isp_fmts;
 		cap->video.nformats = ARRAY_SIZE(stf_isp_fmts);
 		cap->video.bpl_alignment = 1;
+	} else if (cap->type == STF_CAPTURE_BAYER) {
+		cap->video.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		cap->video.formats = stf_isp_bayer_fmts;
+		cap->video.nformats = ARRAY_SIZE(stf_isp_bayer_fmts);
+		cap->video.bpl_alignment = 16 * 8;
 	} else {
 		cap->video.type = V4L2_BUF_TYPE_META_CAPTURE;
 		cap->video.formats = stf_isp_scd_fmts;
@@ -377,6 +416,7 @@ static void stf_capture_unregister_one(struct stf_capture *cap)
 
 void stf_capture_unregister(struct stfcamss *stfcamss)
 {
+	struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
 	struct stf_capture *cap_raw = &stfcamss->captures[STF_CAPTURE_RAW];
 	struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
 	struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
@@ -384,6 +424,7 @@ void stf_capture_unregister(struct stfcamss *stfcamss)
 	stf_capture_unregister_one(cap_raw);
 	stf_capture_unregister_one(cap_yuv);
 	stf_capture_unregister_one(cap_scd);
+	stf_capture_unregister_one(cap_bayer);
 }
 
 int stf_capture_register(struct stfcamss *stfcamss,
diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
index 44ac472d9dc3..f170fab2bfb4 100644
--- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
+++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
@@ -515,6 +515,11 @@ void stf_set_scd_addr(struct stfcamss *stfcamss,
 	stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_4, yhist_addr);
 }
 
+void stf_set_bayer_addr(struct stfcamss *stfcamss, dma_addr_t bayer_addr)
+{
+	stf_isp_reg_write(stfcamss, ISP_REG_DUMP_CFG_0, bayer_addr);
+}
+
 static void stf_isp_fill_yhist(struct stfcamss *stfcamss, void *vaddr)
 {
 	struct jh7110_isp_sc_buffer *sc = (struct jh7110_isp_sc_buffer *)vaddr;
@@ -596,6 +601,7 @@ static void stf_isp_set_params(struct stfcamss *stfcamss, void *vaddr)
 irqreturn_t stf_line_irq_handler(int irq, void *priv)
 {
 	struct stfcamss *stfcamss = priv;
+	struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
 	struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
 	struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
 	struct stfcamss_buffer *change_buf;
@@ -623,6 +629,12 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv)
 							 change_buf->addr[1], type_scd);
 				}
 			}
+
+			if (value & CSI_DUMP_EN) {
+				change_buf = stf_change_buffer(&cap_bayer->buffers);
+				if (change_buf)
+					stf_set_bayer_addr(stfcamss, change_buf->addr[0]);
+			}
 		}
 
 		stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS,
@@ -640,6 +652,7 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv)
 irqreturn_t stf_isp_irq_handler(int irq, void *priv)
 {
 	struct stfcamss *stfcamss = priv;
+	struct stf_capture *cap_bayer = &stfcamss->captures[STF_CAPTURE_BAYER];
 	struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
 	struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
 	struct stf_output *output = &stfcamss->output;
@@ -668,6 +681,12 @@ irqreturn_t stf_isp_irq_handler(int irq, void *priv)
 			}
 		}
 
+		if (status & ISPC_CSI) {
+			ready_buf = stf_buf_done(&cap_bayer->buffers);
+			if (ready_buf)
+				vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+		}
+
 		stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
 				  (status & ~ISPC_INT_ALL_MASK) |
 				  ISPC_ISP | ISPC_CSI | ISPC_SC);
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index f63817b7a235..8505603bdbc5 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -592,6 +592,7 @@ int stf_isp_unregister(struct stf_isp_dev *isp_dev);
 
 void stf_set_yuv_addr(struct stfcamss *stfcamss,
 		      dma_addr_t y_addr, dma_addr_t uv_addr);
+void stf_set_bayer_addr(struct stfcamss *stfcamss, dma_addr_t bayer_addr);
 void stf_set_scd_addr(struct stfcamss *stfcamss,
 		      dma_addr_t yhist_addr, dma_addr_t scd_addr,
 		      enum stf_isp_type_scd type_scd);
diff --git a/drivers/staging/media/starfive/camss/stf-video.h b/drivers/staging/media/starfive/camss/stf-video.h
index 53a1cf4e59b7..ea7ec92c3ff5 100644
--- a/drivers/staging/media/starfive/camss/stf-video.h
+++ b/drivers/staging/media/starfive/camss/stf-video.h
@@ -37,6 +37,7 @@ enum stf_v_line_id {
 enum stf_capture_type {
 	STF_CAPTURE_RAW = 0,
 	STF_CAPTURE_YUV,
+	STF_CAPTURE_BAYER,
 	STF_CAPTURE_SCD,
 	STF_CAPTURE_NUM,
 };
-- 
2.25.1





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux