[PATCH v2 54/66] media: sun6i-csi: Add support for MIPI CSI-2 to the bridge code
Paul Kocialkowski
paul.kocialkowski at bootlin.com
Sat Feb 5 10:54:17 PST 2022
Introduce MIPI CSI-2 support to the bridge with a new port, source
and hardware configuration helper.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski at bootlin.com>
---
.../platform/sunxi/sun6i-csi/sun6i_csi.h | 1 +
.../sunxi/sun6i-csi/sun6i_csi_bridge.c | 35 +++++++++++++++++--
.../sunxi/sun6i-csi/sun6i_csi_bridge.h | 1 +
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
index d7082e951b06..3c08b2712215 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
@@ -21,6 +21,7 @@
enum sun6i_csi_port {
SUN6I_CSI_PORT_PARALLEL = 0,
+ SUN6I_CSI_PORT_MIPI_CSI2 = 1,
};
struct sun6i_csi_buffer {
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
index f5303842d169..b631220dd682 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
@@ -226,7 +226,7 @@ static void sun6i_csi_bridge_disable(struct sun6i_csi_device *csi_dev)
}
static void
-sun6i_csi_bridge_configure_interface(struct sun6i_csi_device *csi_dev)
+sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev)
{
struct device *dev = csi_dev->dev;
struct regmap *regmap = csi_dev->regmap;
@@ -316,6 +316,25 @@ sun6i_csi_bridge_configure_interface(struct sun6i_csi_device *csi_dev)
regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value);
}
+static void
+sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev)
+{
+ struct regmap *regmap = csi_dev->regmap;
+ u32 value = SUN6I_CSI_IF_CFG_IF_MIPI;
+ u32 field;
+
+ sun6i_csi_bridge_format(csi_dev, NULL, &field);
+
+ if (field == V4L2_FIELD_INTERLACED ||
+ field == V4L2_FIELD_INTERLACED_TB ||
+ field == V4L2_FIELD_INTERLACED_BT)
+ value |= SUN6I_CSI_IF_CFG_SRC_TYPE_INTERLACED;
+ else
+ value |= SUN6I_CSI_IF_CFG_SRC_TYPE_PROGRESSIVE;
+
+ regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value);
+}
+
static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev)
{
struct regmap *regmap = csi_dev->regmap;
@@ -369,7 +388,11 @@ static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev)
static void sun6i_csi_bridge_configure(struct sun6i_csi_device *csi_dev)
{
- sun6i_csi_bridge_configure_interface(csi_dev);
+ if (csi_dev->bridge.source == &csi_dev->bridge.source_parallel)
+ sun6i_csi_bridge_configure_parallel(csi_dev);
+ else if (csi_dev->bridge.source == &csi_dev->bridge.source_mipi_csi2)
+ sun6i_csi_bridge_configure_mipi_csi2(csi_dev);
+
sun6i_csi_bridge_configure_format(csi_dev);
}
@@ -552,6 +575,8 @@ static int sun6i_csi_bridge_link_validate(struct media_link *link)
if (source_subdev == bridge->source_parallel.subdev)
bridge->source = &bridge->source_parallel;
+ else if (source_subdev == bridge->source_mipi_csi2.subdev)
+ bridge->source = &bridge->source_mipi_csi2;
else
return -EINVAL;
@@ -638,6 +663,10 @@ sun6i_csi_bridge_notifier_bound(struct v4l2_async_notifier *notifier,
source = &bridge->source_parallel;
enabled = true;
break;
+ case SUN6I_CSI_PORT_MIPI_CSI2:
+ source = &bridge->source_mipi_csi2;
+ enabled = !bridge->source_parallel.expected;
+ break;
default:
break;
}
@@ -784,6 +813,8 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_parallel,
SUN6I_CSI_PORT_PARALLEL,
parallel_mbus_types);
+ sun6i_csi_bridge_source_setup(csi_dev, &bridge->source_mipi_csi2,
+ SUN6I_CSI_PORT_MIPI_CSI2, NULL);
ret = v4l2_async_nf_register(v4l2_dev, notifier);
if (ret) {
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
index 079227c02482..e59c40611872 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
@@ -40,6 +40,7 @@ struct sun6i_csi_bridge {
struct v4l2_mbus_framefmt mbus_format;
struct sun6i_csi_bridge_source source_parallel;
+ struct sun6i_csi_bridge_source source_mipi_csi2;
struct sun6i_csi_bridge_source *source;
};
--
2.34.1
More information about the linux-arm-kernel
mailing list