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