git: 84044a77a620 - main - fwcam: write video mode registers before enabling ISO streaming
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 Jul 2026 05:42:06 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=84044a77a620751d104f772345be66445ebe4fe0
commit 84044a77a620751d104f772345be66445ebe4fe0
Author: Abdelkader Boudih <freebsd@seuros.com>
AuthorDate: 2026-07-08 05:31:32 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2026-07-08 05:32:44 +0000
fwcam: write video mode registers before enabling ISO streaming
The IIDC spec (s3.1) requires the video mode to be programmed before ISO
enable. Without this, cameras that power up with invalid default
mode/rate combinations reject the ISO_EN write.
This can happen when the firmware of teh camera is outdated or
vendor never updated it.
Differential Revision: https://reviews.freebsd.org/D58092
---
sys/dev/firewire/fwcam.c | 40 +++++++++++++++++++++++++++++++++++++---
sys/dev/firewire/fwcam.h | 7 +++++++
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/sys/dev/firewire/fwcam.c b/sys/dev/firewire/fwcam.c
index 251451bc289e..226295154e6e 100644
--- a/sys/dev/firewire/fwcam.c
+++ b/sys/dev/firewire/fwcam.c
@@ -406,6 +406,40 @@ fwcam_iso_start(struct fwcam_softc *sc)
sc->frame_ready = 0;
sc->frame_dropped = 0;
+ /* IIDC spec s3.1: set video mode registers before ISO enable */
+ err = fwcam_write_quadlet(sc, IIDC_CUR_V_FORMAT,
+ (uint32_t)sc->cur_format << IIDC_CUR_V_SHIFT);
+ if (err) {
+ device_printf(sc->fd.dev,
+ "failed to set CUR_V_FORMAT: %d\n", err);
+ goto fail;
+ }
+ err = fwcam_write_quadlet(sc, IIDC_CUR_V_MODE,
+ (uint32_t)sc->cur_mode << IIDC_CUR_V_SHIFT);
+ if (err) {
+ device_printf(sc->fd.dev,
+ "failed to set CUR_V_MODE: %d\n", err);
+ goto fail;
+ }
+ err = fwcam_write_quadlet(sc, IIDC_CUR_V_FRM_RATE,
+ (uint32_t)sc->cur_framerate << IIDC_CUR_V_SHIFT);
+ if (err) {
+ device_printf(sc->fd.dev,
+ "failed to set CUR_V_FRM_RATE: %d\n", err);
+ goto fail;
+ }
+
+ /* Check Vmode_Error_Status - camera rejects ISO_EN on error */
+ err = fwcam_read_quadlet(sc, IIDC_VMODE_ERR_STATUS, &val);
+ if (err == 0 && (val & IIDC_VMODE_ERROR)) {
+ device_printf(sc->fd.dev,
+ "Vmode_Error_Status set: format=%d mode=%d rate=%d "
+ "speed=%d\n", sc->cur_format, sc->cur_mode,
+ sc->cur_framerate, sc->iso_speed);
+ err = EINVAL;
+ goto fail;
+ }
+
val = ((uint32_t)sc->iso_channel << IIDC_ISO_CH_SHIFT) |
((uint32_t)sc->iso_speed << IIDC_ISO_SPEED_SHIFT);
err = fwcam_write_quadlet(sc, IIDC_ISO_CHANNEL, val);
@@ -863,13 +897,13 @@ fwcam_cdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
FWCAM_UNLOCK(sc);
err = fwcam_write_quadlet(sc, IIDC_CUR_V_FORMAT,
- (uint32_t)mode->format << 29);
+ (uint32_t)mode->format << IIDC_CUR_V_SHIFT);
if (err == 0)
err = fwcam_write_quadlet(sc, IIDC_CUR_V_MODE,
- (uint32_t)mode->mode << 29);
+ (uint32_t)mode->mode << IIDC_CUR_V_SHIFT);
if (err == 0)
err = fwcam_write_quadlet(sc, IIDC_CUR_V_FRM_RATE,
- (uint32_t)mode->framerate << 29);
+ (uint32_t)mode->framerate << IIDC_CUR_V_SHIFT);
if (err == 0) {
sc->cur_format = mode->format;
diff --git a/sys/dev/firewire/fwcam.h b/sys/dev/firewire/fwcam.h
index ac72c8609f13..841683bbc37d 100644
--- a/sys/dev/firewire/fwcam.h
+++ b/sys/dev/firewire/fwcam.h
@@ -53,6 +53,13 @@
#define IIDC_ONE_SHOT 0x61C
#define IIDC_MEM_SAVE_CH 0x620
#define IIDC_CUR_MEM_CH 0x624
+#define IIDC_VMODE_ERR_STATUS 0x628
+
+/* Cur_V_Format / Cur_V_Mode / Cur_V_Frm_Rate register fields */
+#define IIDC_CUR_V_SHIFT 29 /* bits [0..2] */
+
+/* Vmode_Error_Status register */
+#define IIDC_VMODE_ERROR (1 << 31) /* bit [0]: mode error */
/* Section 1.7 - Status and control register for features */
#define IIDC_BRIGHTNESS 0x800