diff --git a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi index 360fb05fe80ed8..1d45fba0b3928b 100644 --- a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi @@ -97,6 +97,19 @@ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4; drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4; drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4; + + cam1_sync = <&csi1>, "sync-gpios:0=", <&gpio>, + <&csi1>, "sync-gpios:4", + <&csi1>, "sync-gpios:8=0", ; + cam1_sync_inverted = <&csi1>, "sync-gpios:0=", <&gpio>, + <&csi1>, "sync-gpios:4", + <&csi1>, "sync-gpios:8=0", ; + cam0_sync = <&csi0>, "sync-gpios:0=", <&gpio>, + <&csi0>, "sync-gpios:4", + <&csi0>, "sync-gpios:8=0", ; + cam0_sync_inverted = <&csi0>, "sync-gpios:0=", <&gpio>, + <&csi0>, "sync-gpios:4", + <&csi0>, "sync-gpios:8=0", ; }; }; diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 7f5fb70ec0ca09..65f7a8ea2f26bd 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -170,6 +170,18 @@ Params: Default of GPIO expander 5 on CM4, but override switches to normal GPIO. + cam0_sync Enable a GPIO to reflect frame sync from CSI0, + going high on frame start, and low on frame end. + + cam0_sync_inverted Enable a GPIO to reflect frame sync from CSI0 + going low on frame start, and high on frame end. + + cam1_sync Enable a GPIO to reflect frame sync from CSI1, + going high on frame start, and low on frame end. + + cam1_sync_inverted Enable a GPIO to reflect frame sync from CSI1 + going low on frame start, and high on frame end. + cooling_fan Enables the Pi 5 cooling fan (enabled automatically by the firmware) diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c index 65f66327c04f4a..a6ad0c0fbef64a 100644 --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -543,6 +544,8 @@ struct unicam_device { struct v4l2_device v4l2_dev; struct media_device mdev; + struct gpio_desc *sync_gpio; + /* parent device */ struct platform_device *pdev; /* subdevice async Notifier */ @@ -943,6 +946,8 @@ static irqreturn_t unicam_isr(int irq, void *dev) if (fe) { bool inc_seq = unicam->frame_started; + if (unicam->sync_gpio) + gpiod_set_value(unicam->sync_gpio, 0); /* * Ensure we have swapped buffers already as we can't * stop the peripheral. If no buffer is available, use a @@ -1003,6 +1008,10 @@ static irqreturn_t unicam_isr(int irq, void *dev) * aka frame start. */ ts = ktime_get_ns(); + + if (unicam->sync_gpio) + gpiod_set_value(unicam->sync_gpio, 1); + for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { if (!unicam->node[i].streaming) continue; @@ -3407,6 +3416,9 @@ static int unicam_probe(struct platform_device *pdev) goto err_unicam_put; } + unicam->sync_gpio = devm_gpiod_get_optional(&pdev->dev, "sync", + GPIOD_OUT_LOW); + ret = platform_get_irq(pdev, 0); if (ret <= 0) { dev_err(&pdev->dev, "No IRQ resource\n");