xref: /freebsd/sys/dev/firewire/fwcam.h (revision f5dc2263ab1be8a35a7e27e82103f9ccd41ae584)
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