1 /* 2 * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #ifndef _DEV_FIREWIRE_FWCAM_H_ 8 #define _DEV_FIREWIRE_FWCAM_H_ 9 10 /* 11 * IIDC 1394-based Digital Camera Specification v1.30 12 * Register offsets relative to command_regs_base 13 */ 14 15 /* Section 1.1 - Camera initialize register */ 16 #define IIDC_INITIALIZE 0x000 17 18 /* Section 1.2 - Inquiry registers for video format/mode/frame rate */ 19 #define IIDC_V_FORMAT_INQ 0x100 20 #define IIDC_V_MODE_INQ(f) (0x180 + (f) * 4) 21 #define IIDC_V_RATE_INQ(f, m) (0x200 + (f) * 0x20 + (m) * 4) 22 23 /* Section 1.3 - Inquiry register for basic function */ 24 #define IIDC_BASIC_FUNC_INQ 0x400 25 26 /* Section 1.4 - Inquiry registers for feature presence */ 27 #define IIDC_FEATURE_HI_INQ 0x404 28 #define IIDC_FEATURE_LO_INQ 0x408 29 30 /* Section 1.5 - Inquiry registers for feature elements (per feature) */ 31 #define IIDC_BRIGHTNESS_INQ 0x500 32 #define IIDC_AUTO_EXPOSURE_INQ 0x504 33 #define IIDC_SHARPNESS_INQ 0x508 34 #define IIDC_WHITE_BAL_INQ 0x50C 35 #define IIDC_HUE_INQ 0x510 36 #define IIDC_SATURATION_INQ 0x514 37 #define IIDC_GAMMA_INQ 0x518 38 #define IIDC_SHUTTER_INQ 0x51C 39 #define IIDC_GAIN_INQ 0x520 40 #define IIDC_IRIS_INQ 0x524 41 #define IIDC_FOCUS_INQ 0x528 42 #define IIDC_TEMPERATURE_INQ 0x52C 43 #define IIDC_TRIGGER_INQ 0x530 44 45 /* Section 1.6 - Status and control registers for camera */ 46 #define IIDC_CUR_V_FRM_RATE 0x600 47 #define IIDC_CUR_V_MODE 0x604 48 #define IIDC_CUR_V_FORMAT 0x608 49 #define IIDC_ISO_CHANNEL 0x60C 50 #define IIDC_CAMERA_POWER 0x610 51 #define IIDC_ISO_EN 0x614 52 #define IIDC_MEMORY_SAVE 0x618 53 #define IIDC_ONE_SHOT 0x61C 54 #define IIDC_MEM_SAVE_CH 0x620 55 #define IIDC_CUR_MEM_CH 0x624 56 #define IIDC_VMODE_ERR_STATUS 0x628 57 58 /* Cur_V_Format / Cur_V_Mode / Cur_V_Frm_Rate register fields */ 59 #define IIDC_CUR_V_SHIFT 29 /* bits [0..2] */ 60 61 /* Vmode_Error_Status register */ 62 #define IIDC_VMODE_ERROR (1 << 31) /* bit [0]: mode error */ 63 64 /* Section 1.7 - Status and control register for features */ 65 #define IIDC_BRIGHTNESS 0x800 66 #define IIDC_AUTO_EXPOSURE 0x804 67 #define IIDC_SHARPNESS 0x808 68 #define IIDC_WHITE_BALANCE 0x80C 69 #define IIDC_HUE 0x810 70 #define IIDC_SATURATION 0x814 71 #define IIDC_GAMMA 0x818 72 #define IIDC_SHUTTER 0x81C 73 #define IIDC_GAIN 0x820 74 #define IIDC_IRIS 0x824 75 #define IIDC_FOCUS 0x828 76 #define IIDC_TEMPERATURE 0x82C 77 #define IIDC_TRIGGER_MODE 0x830 78 #define IIDC_ZOOM 0x880 79 #define IIDC_PAN 0x884 80 #define IIDC_TILT 0x888 81 82 /* Video format indices (CUR_V_FORMAT register) */ 83 #define IIDC_FMT_VGA 0 /* Format_0: VGA non-compressed */ 84 #define IIDC_FMT_SVGA1 1 /* Format_1: Super VGA (1) */ 85 #define IIDC_FMT_SVGA2 2 /* Format_2: Super VGA (2) */ 86 #define IIDC_FMT_STILL 6 /* Format_6: Still image */ 87 #define IIDC_FMT_PARTIAL 7 /* Format_7: Partial/scalable */ 88 89 /* V_FORMAT_INQ bits */ 90 #define IIDC_FORMAT_VGA (1 << 31) /* Format_0: VGA */ 91 #define IIDC_FORMAT_SVGA1 (1 << 30) /* Format_1: Super VGA (1) */ 92 #define IIDC_FORMAT_SVGA2 (1 << 29) /* Format_2: Super VGA (2) */ 93 #define IIDC_FORMAT_STILL (1 << 25) /* Format_6: Still image */ 94 #define IIDC_FORMAT_PARTIAL (1 << 24) /* Format_7: Partial image */ 95 96 /* ISO_CHANNEL register fields */ 97 #define IIDC_ISO_CH_MASK 0xf0000000 /* bits [0..3] */ 98 #define IIDC_ISO_CH_SHIFT 28 99 #define IIDC_ISO_SPEED_MASK 0x03000000 /* bits [6..7] */ 100 #define IIDC_ISO_SPEED_SHIFT 24 101 102 /* CAMERA_POWER register */ 103 #define IIDC_POWER_ON (1 << 31) /* bit [0] */ 104 105 /* ISO_EN register */ 106 #define IIDC_ISO_EN_ON (1 << 31) /* bit [0] */ 107 108 /* BASIC_FUNC_INQ bits */ 109 #define IIDC_ADV_FEATURE_INQ (1 << 31) /* bit [0] */ 110 #define IIDC_CAM_POWER_CTRL (1 << 15) /* bit [16] */ 111 #define IIDC_ONE_SHOT_INQ (1 << 12) /* bit [19] */ 112 #define IIDC_MULTI_SHOT_INQ (1 << 11) /* bit [20] */ 113 114 /* FEATURE_HI_INQ bits (feature presence, section 1.4) */ 115 #define IIDC_HAS_BRIGHTNESS (1 << 31) 116 #define IIDC_HAS_AUTO_EXPOSURE (1 << 30) 117 #define IIDC_HAS_SHARPNESS (1 << 29) 118 #define IIDC_HAS_WHITE_BALANCE (1 << 28) 119 #define IIDC_HAS_HUE (1 << 27) 120 #define IIDC_HAS_SATURATION (1 << 26) 121 #define IIDC_HAS_GAMMA (1 << 25) 122 #define IIDC_HAS_SHUTTER (1 << 24) 123 #define IIDC_HAS_GAIN (1 << 23) 124 #define IIDC_HAS_IRIS (1 << 22) 125 #define IIDC_HAS_FOCUS (1 << 21) 126 #define IIDC_HAS_TEMPERATURE (1 << 20) 127 #define IIDC_HAS_TRIGGER (1 << 19) 128 129 /* Config ROM: IIDC unit-dependent directory command_regs_base key */ 130 #define IIDC_CROM_CMD_BASE (CSRTYPE_C | 0x00) /* 0x40 */ 131 132 /* 133 * Frame size limits for Format_0 (VGA non-compressed): 134 * Mode_1: 320x240 YUV422 = 153,600 bytes 135 * Mode_2: 640x480 YUV411 = 460,800 bytes 136 * Mode_3: 640x480 YUV422 = 614,400 bytes 137 */ 138 /* 139 * ioctl interface 140 */ 141 struct fwcam_mode { 142 uint8_t format; /* IIDC video format (0-7) */ 143 uint8_t mode; /* IIDC video mode (0-7) */ 144 uint8_t framerate; /* IIDC frame rate (0-7) */ 145 uint8_t _pad; 146 uint32_t frame_size; /* computed frame size in bytes (read-only) */ 147 }; 148 149 struct fwcam_feature { 150 uint32_t id; /* FWCAM_FEAT_* */ 151 uint32_t flags; /* FWCAM_FEATF_* (from INQ, read-only) */ 152 uint32_t min; /* minimum value (from INQ, read-only) */ 153 uint32_t max; /* maximum value (from INQ, read-only) */ 154 uint32_t value; /* current value / value to set */ 155 uint32_t value2; /* second value (white balance V) */ 156 }; 157 158 /* Feature IDs (index into IIDC feature register space) */ 159 #define FWCAM_FEAT_BRIGHTNESS 0 160 #define FWCAM_FEAT_AUTO_EXPOSURE 1 161 #define FWCAM_FEAT_SHARPNESS 2 162 #define FWCAM_FEAT_WHITE_BALANCE 3 163 #define FWCAM_FEAT_HUE 4 164 #define FWCAM_FEAT_SATURATION 5 165 #define FWCAM_FEAT_GAMMA 6 166 #define FWCAM_FEAT_SHUTTER 7 167 #define FWCAM_FEAT_GAIN 8 168 #define FWCAM_FEAT_IRIS 9 169 #define FWCAM_FEAT_FOCUS 10 170 #define FWCAM_FEAT_TEMPERATURE 11 171 #define FWCAM_FEAT_TRIGGER 12 172 #define FWCAM_FEAT_ZOOM 13 173 #define FWCAM_FEAT_PAN 14 174 #define FWCAM_FEAT_TILT 15 175 #define FWCAM_FEAT_MAX 16 176 177 /* Feature flags (from INQ register bits) */ 178 #define FWCAM_FEATF_PRESENT (1 << 0) /* feature is present */ 179 #define FWCAM_FEATF_ONOFF (1 << 1) /* supports on/off */ 180 #define FWCAM_FEATF_AUTO (1 << 2) /* supports auto mode */ 181 #define FWCAM_FEATF_MANUAL (1 << 3) /* supports manual mode */ 182 183 struct fwcam_info { 184 uint32_t formats; /* V_FORMAT_INQ bitmask */ 185 uint32_t basic_func; /* BASIC_FUNC_INQ */ 186 uint32_t features_hi; /* FEATURE_HI_INQ */ 187 uint32_t features_lo; /* FEATURE_LO_INQ */ 188 uint8_t cur_format; 189 uint8_t cur_mode; 190 uint8_t cur_framerate; 191 uint8_t state; /* FWCAM_STATE_* */ 192 uint32_t frame_size; 193 uint32_t frame_dropped; 194 uint8_t iso_channel; /* active ISO receive channel */ 195 uint8_t _pad[3]; 196 }; 197 198 #define FWCAM_GMODE _IOR('C', 1, struct fwcam_mode) 199 #define FWCAM_SMODE _IOWR('C', 2, struct fwcam_mode) 200 #define FWCAM_GFEAT _IOWR('C', 3, struct fwcam_feature) 201 #define FWCAM_SFEAT _IOW('C', 4, struct fwcam_feature) 202 #define FWCAM_GINFO _IOR('C', 5, struct fwcam_info) 203 204 /* fwcam state values (visible to userland via fwcam_info.state) */ 205 #define FWCAM_STATE_IDLE 0 206 #define FWCAM_STATE_PROBING 1 207 #define FWCAM_STATE_PROBED 2 208 #define FWCAM_STATE_STREAMING 3 209 #define FWCAM_STATE_DETACHING 4 210 211 /* IIDC format/mode/rate/feature/state name tables for userland and driver */ 212 #define FWCAM_FMT_NMAX 8 213 #define FWCAM_RATE_NMAX 8 214 215 static const char * const fwcam_fmt_names[FWCAM_FMT_NMAX] = { 216 "VGA (Format_0)", 217 "Super VGA 1 (Format_1)", 218 "Super VGA 2 (Format_2)", 219 "Reserved", 220 "Reserved", 221 "Reserved", 222 "Still Image (Format_6)", 223 "Partial Image (Format_7)", 224 }; 225 226 static const char * const fwcam_rate_names[FWCAM_RATE_NMAX] = { 227 "1.875 fps", "3.75 fps", "7.5 fps", "15 fps", 228 "30 fps", "60 fps", "120 fps", "240 fps", 229 }; 230 231 static const char * const fwcam_feat_names[FWCAM_FEAT_MAX] = { 232 [FWCAM_FEAT_BRIGHTNESS] = "brightness", 233 [FWCAM_FEAT_AUTO_EXPOSURE] = "auto_exposure", 234 [FWCAM_FEAT_SHARPNESS] = "sharpness", 235 [FWCAM_FEAT_WHITE_BALANCE] = "white_balance", 236 [FWCAM_FEAT_HUE] = "hue", 237 [FWCAM_FEAT_SATURATION] = "saturation", 238 [FWCAM_FEAT_GAMMA] = "gamma", 239 [FWCAM_FEAT_SHUTTER] = "shutter", 240 [FWCAM_FEAT_GAIN] = "gain", 241 [FWCAM_FEAT_IRIS] = "iris", 242 [FWCAM_FEAT_FOCUS] = "focus", 243 [FWCAM_FEAT_TEMPERATURE] = "temperature", 244 [FWCAM_FEAT_TRIGGER] = "trigger", 245 [FWCAM_FEAT_ZOOM] = "zoom", 246 [FWCAM_FEAT_PAN] = "pan", 247 [FWCAM_FEAT_TILT] = "tilt", 248 }; 249 250 static const char * const fwcam_state_names[] = { 251 [FWCAM_STATE_IDLE] = "idle", 252 [FWCAM_STATE_PROBING] = "probing", 253 [FWCAM_STATE_PROBED] = "probed", 254 [FWCAM_STATE_STREAMING] = "streaming", 255 [FWCAM_STATE_DETACHING] = "detaching", 256 }; 257 258 /* Format_0 (VGA non-compressed) mode geometry */ 259 struct fwcam_fmt0_mode { 260 int w, h; 261 const char *pixfmt; 262 }; 263 264 #define FWCAM_FMT0_NMODES 7 265 266 static const struct fwcam_fmt0_mode fwcam_fmt0_modes[FWCAM_FMT0_NMODES] = { 267 { 160, 120, "YUV444" }, /* mode 0 */ 268 { 320, 240, "YUV422" }, /* mode 1 */ 269 { 640, 480, "YUV411" }, /* mode 2 */ 270 { 640, 480, "YUV422" }, /* mode 3 */ 271 { 640, 480, "RGB8" }, /* mode 4 */ 272 { 640, 480, "Mono8" }, /* mode 5 */ 273 { 640, 480, "Mono16" }, /* mode 6 */ 274 }; 275 276 /* 277 * Internal constants 278 */ 279 #define FWCAM_MAX_FRAME_SIZE (640 * 480 * 3) /* 921,600 (RGB24) */ 280 #define FWCAM_ISO_NCHUNK 256 /* receive DMA chunks */ 281 #define FWCAM_ISO_PKTSIZE 2048 /* max iso packet size (MCLBYTES) */ 282 283 #ifdef _KERNEL 284 285 struct video_device; 286 287 struct fwcam_softc { 288 struct firewire_dev_comm fd; /* must be first */ 289 struct mtx mtx; 290 291 /* video(4) framework handle */ 292 struct video_device *sc_vd; 293 uint32_t sc_sequence; 294 295 /* Remote camera node */ 296 struct fw_device *fwdev; 297 298 /* IIDC command register addressing */ 299 uint16_t cmd_hi; /* always 0xffff */ 300 uint32_t cmd_lo; /* 0xf0000000 | (base << 2) */ 301 302 /* Capabilities from INQ registers */ 303 uint32_t formats; /* V_FORMAT_INQ */ 304 uint32_t basic_func; /* BASIC_FUNC_INQ */ 305 uint32_t features_hi; /* FEATURE_HI_INQ */ 306 uint32_t features_lo; /* FEATURE_LO_INQ */ 307 uint32_t modes[8]; /* V_MODE_INQ per format */ 308 uint32_t rates[8][8]; /* V_RATE_INQ per format/mode */ 309 310 /* Current settings */ 311 uint8_t cur_format; 312 uint8_t cur_mode; 313 uint8_t cur_framerate; 314 uint8_t iso_channel; 315 uint8_t iso_speed; 316 317 /* Deferred probe task */ 318 struct task probe_task; 319 320 /* Isochronous receive */ 321 int dma_ch; /* IR DMA channel, -1 if none */ 322 int iso_active; /* iso_input running */ 323 324 /* Frame assembly */ 325 uint8_t *frame_buf; /* frame being assembled */ 326 uint32_t frame_size; /* expected frame size (bytes) */ 327 uint32_t frame_offset; /* write position in frame_buf */ 328 int frame_dropped; /* dropped frame count */ 329 330 /* State: one of FWCAM_STATE_* */ 331 int state; 332 }; 333 334 #define FWCAM_LOCK(sc) mtx_lock(&(sc)->mtx) 335 #define FWCAM_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 336 337 #endif /* _KERNEL */ 338 339 #endif /* _DEV_FIREWIRE_FWCAM_H_ */ 340