xref: /linux/drivers/media/i2c/cvs/icvs.h (revision 23d66dbab84e8518943563df2ced14aaab28b77a)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2026 Intel Corporation
4  */
5 
6 #ifndef _ICVS_H
7 #define _ICVS_H
8 
9 #include <linux/bits.h>
10 #include <linux/completion.h>
11 #include <linux/mutex.h>
12 #include <linux/workqueue.h>
13 #include <linux/types.h>
14 #include <linux/wait.h>
15 
16 #include <media/media-entity.h>
17 #include <media/v4l2-ctrls.h>
18 #include <media/v4l2-subdev.h>
19 
20 /*
21  * PCI device IDs for all IPU generations that co-exist with the CVS bridge.
22  * IPU7 (0x645d) is shared by MTL and LNL; IPU7P5 (0xb05d) is shared by
23  * ARL and PTL. These are not yet in the shared ipu6-pci-table so they are
24  * listed here alongside the IPU6 family for probe-time IPU discovery.
25  */
26 struct gpio_desc;
27 struct i2c_client;
28 
29 /*
30  * GPIO resource counts (ACPI enumerated).
31  *
32  * 4-GPIO configuration has a wake IRQ and supports asynchronous messaging.
33  * 2-GPIO configuration has no IRQ, so communication is synchronous only.
34  */
35 #define ICVS_GPIO_ASYNC	4
36 #define ICVS_GPIO_SYNC	2
37 
38 /* Firmware response prefix (optional, for protocol revision 2.x or newer) */
39 #define ICVS_PREFIX_VAL	0xCAFEB0BA
40 
41 /*
42  * CSI bridge sub-device definitions
43  */
44 /**
45  * enum icvs_csi_cmd_id - Low-level CSI bridge command identifiers
46  *
47  * These numeric IDs are part of the legacy CSI-side protocol not mapped
48  * directly to the higher level firmware opcodes in enum icvs_command. Only
49  * a minimal subset is presently issued/handled by the driver. Others are
50  * reserved for future expansion of the CSI bridge feature set.
51  *
52  * @ICVS_CSI_SET_OWNER:     Set CSI sensor ownership between host and CVS
53  * @ICVS_CSI_SET_CONF:      Apply CSI link configuration parameters
54  * @ICVS_CSI_PRIVACY_NOTIF: Notify host of a privacy state transition
55  */
56 enum icvs_csi_cmd_id {
57 	ICVS_CSI_SET_OWNER = 0,
58 	ICVS_CSI_SET_CONF = 2,
59 	ICVS_CSI_PRIVACY_NOTIF = 6,
60 };
61 
62 /**
63  * enum icvs_csi_link_owner - CSI-2 link / sensor ownership
64  *
65  * Ownership reflects which endpoint currently controls the attached image
66  * sensor over the CSI-2 link. Transitions may gate streaming or reconfigure
67  * link parameters. The host requests ownership changes via protocol opcodes
68  * and may need to assert GPIO signals on platforms without full capability.
69  *
70  * @ICVS_CSI_LINK_HOST: Host (Linux) owns the sensor and may start streaming
71  * @ICVS_CSI_LINK_CVS:  CVS firmware owns the sensor (host must not stream)
72  */
73 enum icvs_csi_link_owner {
74 	ICVS_CSI_LINK_HOST,
75 	ICVS_CSI_LINK_CVS,
76 };
77 
78 /**
79  * enum icvs_csi_privacy_status - Reported privacy state
80  *
81  * Reflects user privacy (e.g. camera LED assertion and stream gating). The
82  * MAX value is a sentinel used for bounds checking and is not a real state.
83  *
84  * @ICVS_CSI_PRIVACY_OFF: Privacy not asserted (LED off, streaming permitted)
85  * @ICVS_CSI_PRIVACY_ON:  Privacy asserted (LED on and/or stream gated)
86  * @ICVS_CSI_PRIVACY_MAX: Sentinel; not a valid operational value
87  */
88 enum icvs_csi_privacy_status {
89 	ICVS_CSI_PRIVACY_OFF,
90 	ICVS_CSI_PRIVACY_ON,
91 	ICVS_CSI_PRIVACY_MAX
92 };
93 
94 /**
95  * enum icvs_csi_pads - Media pads exposed by the CVS sub-device
96  *
97  * The bridge presents a single sink (from the remote sensor) and a single
98  * source (toward the rest of the media graph / consumers). NUM_PADS is used
99  * for sizing arrays and iteration; it is not a real pad index.
100  *
101  * @ICVS_CSI_PAD_SINK:   Sink pad receiving frames from remote sensor
102  * @ICVS_CSI_PAD_SOURCE: Source pad emitting frames to downstream entities
103  * @ICVS_CSI_NUM_PADS:   Count sentinel (array size / iteration bound)
104  */
105 enum icvs_csi_pads {
106 	ICVS_CSI_PAD_SINK,
107 	ICVS_CSI_PAD_SOURCE,
108 	ICVS_CSI_NUM_PADS
109 };
110 
111 /*
112  * Core driver structures and functions used by both I2C and platform modes
113  */
114 
115 /**
116  * DOC: CVS device quirk flags
117  *
118  * These bit flag macros describe per-device behavioral adjustments applied
119  * after VID/PID matching (see cvs_i2c_check() and cvs_apply_quirks()). They
120  * allow the driver to selectively alter logic paths for firmware / hardware
121  * variants without introducing hard-coded conditionals at each call site.
122  *
123  * @ICVS_NO_MIPI_CONFIG: Device firmware performs its own MIPI link setup;
124  *                       skip sending HOST_SET_MIPI_CONFIG.
125  * @ICVS_SKIP_FW_RESET:  Skip issuing a post firmware-update reset sequence.
126  * @ICVS_NO_CAPS:        Device firmware does not support GET_DEV_CAPABILITY;
127  *                       skip capability query and treat caps as unsupported.
128  * @ICVS_FW_BUF_SIZE_256: Firmware expects chunk transfer buffer size of 256
129  *                        bytes (override defaults if they differ).
130  * @ICVS_FW_HEADER_SIZE_256: Firmware header size fixed at 256 bytes offset
131  *                           for start of payload data.
132  * @ICVS_HOST_SENSOR_PWR_CTRL: Host must control sensor power sequencing.
133  * @ICVS_HOST_PRIV_CTRL: Host owns privacy LED gating.
134  * @ICVS_HOST_VISION_SENSING: Host enables vision sensing capability bit
135  * @ICVS_NO_FW_UPDATE:   Device does not support firmware update.
136  */
137 #define ICVS_NO_MIPI_CONFIG		BIT(0)
138 #define ICVS_SKIP_FW_RESET		BIT(1)
139 #define ICVS_NO_CAPS			BIT(2)
140 #define ICVS_FW_BUF_SIZE_256		BIT(3)
141 #define ICVS_FW_HEADER_SIZE_256		BIT(4)
142 #define ICVS_HOST_SENSOR_PWR_CTRL	BIT(5)
143 #define ICVS_HOST_PRIV_CTRL		BIT(6)
144 #define ICVS_HOST_VISION_SENSING	BIT(7)
145 #define ICVS_NO_FW_UPDATE		BIT(8)
146 
147 /**
148  * struct icvs_device_quirk - Device-specific quirk entry
149  * @vid: Vendor ID
150  * @pid: Product ID
151  * @quirks: Quirk flags for this device
152  */
153 struct icvs_device_quirk {
154 	u16 vid;
155 	u16 pid;
156 	unsigned long quirks;
157 };
158 
159 /**
160  * struct icvs_dt_config - Data type configuration for a virtual channel
161  * @pixel_width: Pixel width in pixels
162  * @pixel_height: Pixel height in pixels
163  * @data_type: MIPI CSI-2 data type (RAW10, RAW12, etc.)
164  * @reserved: Reserved for future use
165  */
166 struct icvs_dt_config {
167 	u16	pixel_width;
168 	u16	pixel_height;
169 	u8	data_type;
170 	u8	reserved[3];
171 };
172 
173 /**
174  * struct icvs_vc_config - Virtual channel configuration
175  * @vc: Virtual channel index (0-31)
176  * @dt_count: Number of data types configured
177  * @dt_configs: Array of data type configurations (up to 4)
178  * @reserved: Reserved for future use
179  */
180 struct icvs_vc_config {
181 	u8	vc;
182 	u8	dt_count;
183 	struct icvs_dt_config dt_configs[4];
184 	u8	reserved[6];
185 };
186 
187 /**
188  * struct icvs_link_cfg - Host to CVS CSI link configuration
189  * @fps: Frames per second
190  * @nr_of_lanes: Number of CSI-2 data lanes used
191  * @phy_mode: 0 = DPHY, 1 = CPHY
192  * @vc_count: Number of virtual channels enabled
193  * @vc_configs: Per-VC configuration
194  * @link_freq: Link frequency in Hz
195  * @reserved: Reserved for future use
196  */
197 struct icvs_link_cfg {
198 	u8	fps;
199 	u8	nr_of_lanes;
200 	u8	phy_mode;
201 	u8	vc_count;
202 	struct icvs_vc_config vc_configs[4];
203 	u32	link_freq;
204 	u8	reserved[8];
205 };
206 
207 /**
208  * struct icvs_fw_version - Firmware version tuple
209  * @major: Major version
210  * @minor: Minor version
211  * @hotfix: Hotfix/patch level
212  * @build: Build number
213  */
214 struct icvs_fw_version {
215 	u32	major;
216 	u32	minor;
217 	u32	hotfix;
218 	u32	build;
219 };
220 
221 /**
222  * struct icvs_vid_pid - Device vendor/product IDs
223  * @v_id: Vendor ID
224  * @p_id: Product ID
225  */
226 struct icvs_vid_pid {
227 	u16	v_id;
228 	u16	p_id;
229 };
230 
231 /**
232  * struct icvs_mipi_data_packet - Encapsulated MIPI link configuration packet
233  * @cmd_id: Command identifier
234  * @size: Payload size (bytes)
235  * @crc: Checksum over payload
236  * @conf: CSI link configuration
237  * @reserved: Reserved for future use
238  */
239 struct icvs_mipi_data_packet {
240 	__be16	cmd_id;
241 	u32	size;
242 	u32	crc;
243 	struct icvs_link_cfg conf;
244 	u8	reserved[70];
245 } __packed;
246 
247 /**
248  * struct icvs_mipi_read_packet - Read-back MIPI configuration
249  * @size: Payload size
250  * @crc: Payload checksum
251  * @conf: CSI link configuration
252  */
253 struct icvs_mipi_read_packet {
254 	u32	size;
255 	u32	crc;
256 	struct icvs_link_cfg conf;
257 };
258 
259 /* Host identifier bitfield masks */
260 #define ICVS_HOST_ID_RGBCAMERA_PWRUP	BIT(31)
261 #define ICVS_HOST_ID_PRIVACY_LED	BIT(30)
262 #define ICVS_HOST_ID_DEVICE_POWER	GENMASK(29, 28)
263 #define ICVS_HOST_ID_VISION_SENSING	BIT(27)
264 
265 /* Device state bitfield masks (u8) */
266 #define ICVS_DEV_STATE_PRIVACY		BIT(0)
267 #define ICVS_DEV_STATE_ON		BIT(1)
268 #define ICVS_DEV_STATE_SENSOR_OWNER	BIT(2)
269 #define ICVS_DEV_STATE_DOWNLOAD		BIT(4)
270 #define ICVS_DEV_STATE_ERROR		BIT(6)
271 #define ICVS_DEV_STATE_BUSY		BIT(7)
272 
273 /* Device capability bitfield masks (u16) */
274 #define ICVS_CAP_HOST_MIPI_REQUIRED	BIT(15)
275 #define ICVS_CAP_FW_ANTIROLLBACK	BIT(14)
276 #define ICVS_CAP_PRIVACY2VISIONDRIVER	BIT(13)
277 #define ICVS_CAP_FWUPDATE_RESET_HOST	BIT(12)
278 #define ICVS_CAP_NO_CAMERA_FWUPDATE	BIT(11)
279 #define ICVS_CAP_POWER_DOMAIN_SUPPORT	BIT(10)
280 #define ICVS_CAP_FW_FLASHED_IN_PLACE	BIT(9)
281 #define ICVS_CAP_IO_CONTEXT_HOT		BIT(8)
282 
283 /**
284  * struct icvs_dev_capabilities - Protocol capabilities reported by device
285  * @protocol_version_major: Major protocol version
286  * @protocol_version_minor: Minor protocol version
287  * @capability: Capability bitfield - use ICVS_CAP_* masks
288  * @max_packet_time: Max packet processing time (ms)
289  * @max_post_dl_time: Max post-download time (s)
290  */
291 struct icvs_dev_capabilities {
292 	u8 protocol_version_major;
293 	u8 protocol_version_minor;
294 	u16 capability;
295 	u16 max_packet_time;
296 	u16 max_post_dl_time;
297 };
298 
299 /**
300  * struct icvs_cmd - Generic command container
301  * @cmd_id: Command identifier
302  * @param: Parameter union providing multiple variants
303  * @param.param: Raw parameter
304  * @param.host_id: Host identifier (ICVS_SET_DEV_HOST_ID) - use
305  *		   ICVS_HOST_ID_* masks
306  * @param.conf: CSI link configuration (ICVS_HOST_SET_MIPI_CONFIG)
307  */
308 struct icvs_cmd {
309 	__be16 cmd_id;
310 	union {
311 		u32 param;
312 		u32 host_id;
313 		struct icvs_link_cfg conf;
314 	} param;
315 } __packed;
316 
317 /**
318  * struct icvs_resp - Firmware response container
319  * @status: Internal status code
320  * @cmd_id: Original command identifier
321  * @resp: Response union containing variant payload
322  * @resp.state: Device state response (u8, use ICVS_DEV_STATE_* masks)
323  * @resp.cap: Capability response
324  * @resp.conf: Link configuration response
325  * @resp.mipi_read: Raw link config read-back
326  * @resp.vid_pid: Vendor/product identifiers
327  * @resp.fw_version: Firmware version tuple
328  */
329 struct icvs_resp {
330 	u32 status;
331 	__be16 cmd_id;
332 	union {
333 		u8 state;
334 		struct icvs_dev_capabilities cap;
335 		struct icvs_link_cfg conf;
336 		struct icvs_mipi_read_packet mipi_read;
337 		struct icvs_vid_pid vid_pid;
338 		struct icvs_fw_version fw_version;
339 	} resp;
340 };
341 
342 /**
343  * enum icvs_resources - Device capability / resource category
344  *
345  * Categorizes hardware resource availability which influences protocol
346  * features (e.g. reset control, wake IRQ, GPIO mediated ownership). Light
347  * capability devices expose a reduced set of control GPIOs; full capability
348  * devices provide all optional signals and features. NOTSUP represents an
349  * unsupported or uninitialized state.
350  *
351  * @ICVS_NOTSUP:   Capability not supported / not yet determined
352  * @ICVS_LIGHTCAP: Light capability (limited GPIO / no dedicated wake IRQ)
353  * @ICVS_FULLCAP:  Full capability (reset GPIO, wake IRQ, extended protocol)
354  */
355 enum icvs_resources {
356 	ICVS_NOTSUP,
357 	ICVS_LIGHTCAP,
358 	ICVS_FULLCAP,
359 };
360 
361 /**
362  * enum icvs_command - Protocol command opcodes (firmware space 0x0800+)
363  * @ICVS_GET_DEV_STATE:        Query current device state bitfield
364  * @ICVS_GET_DEV_FW_VERSION:   Retrieve firmware version tuple
365  * @ICVS_GET_DEV_VID_PID:      Read vendor / product identifiers
366  * @ICVS_GET_DEV_ERR_CODE:     Fetch last error code (if any)
367  * @ICVS_GET_DEV_CAPABILITY:   Read protocol capability structure
368  * @ICVS_SET_DEV_HOST_ID:      Set host identity / ownership bits
369  * @ICVS_GET_DEV_HOST_ID:      Read back host identity
370  * @ICVS_FW_LOADER_START:      Begin firmware download sequence
371  * @ICVS_FW_LOADER_DATA:       Stream a chunk of firmware payload
372  * @ICVS_FW_LOADER_END:        End firmware download / trigger flash
373  * @ICVS_HOST_GET_MIPI_CONFIG: Request current MIPI CSI link configuration
374  * @ICVS_HOST_SET_MIPI_CONFIG: Apply new MIPI CSI link configuration
375  * @ICVS_HOST_SENSOR_OWNER:    Toggle CSI sensor ownership (GPIO assist)
376  */
377 enum icvs_command {
378 	ICVS_GET_DEV_STATE		= 0x0800,
379 	ICVS_GET_DEV_FW_VERSION		= 0x0801,
380 	ICVS_GET_DEV_VID_PID		= 0x0802,
381 	ICVS_GET_DEV_ERR_CODE		= 0x0803,
382 	ICVS_GET_DEV_CAPABILITY		= 0x0804,
383 	ICVS_SET_DEV_HOST_ID		= 0x0805,
384 	ICVS_GET_DEV_HOST_ID		= 0x0806,
385 	ICVS_FW_LOADER_START		= 0x0820,
386 	ICVS_FW_LOADER_DATA		= 0x0821,
387 	ICVS_FW_LOADER_END		= 0x0822,
388 	ICVS_HOST_GET_MIPI_CONFIG	= 0x082F,
389 	ICVS_HOST_SET_MIPI_CONFIG	= 0x0830,
390 	ICVS_HOST_SENSOR_OWNER		= 0x0831,
391 };
392 
393 /**
394  * enum icvs_state - Device state bitfield flags
395  *
396  * These flags correspond to bits in the device state byte returned via
397  * GET_DEV_STATE and decoded in union icvs_dev_state. Multiple bits may be
398  * asserted simultaneously. Reserved bits are omitted.
399  *
400  * @ICVS_DEVICE_OFF_STATE: Raw zero value; device is powered off or
401  *			   not yet ready
402  * @ICVS_DEVICE_PRIVACY_ON: Privacy mode active (LED asserted and/or
403  *			    stream gated)
404  * @ICVS_DEVICE_ON_STATE: Device powered and responsive to protocol commands
405  * @ICVS_DEVICE_SENSOR_OWNER: CVS currently owns the attached CSI sensor
406  * @ICVS_DEVICE_DWNLD_STATE: Firmware download / flash operation in progress
407  * @ICVS_DEVICE_ERROR_STATE: Device has reported an error (query
408  *			     ICVS_GET_DEV_ERR_CODE)
409  * @ICVS_DEVICE_BUSY_STATE: Device is busy processing a prior command
410  */
411 enum icvs_state {
412 	ICVS_DEVICE_OFF_STATE		= 0x00,
413 	ICVS_DEVICE_PRIVACY_ON		= BIT(0),
414 	ICVS_DEVICE_ON_STATE		= BIT(1),
415 	ICVS_DEVICE_SENSOR_OWNER	= BIT(2),
416 	ICVS_DEVICE_DWNLD_STATE		= BIT(4),
417 	ICVS_DEVICE_ERROR_STATE		= BIT(6),
418 	ICVS_DEVICE_BUSY_STATE		= BIT(7),
419 };
420 
421 /**
422  * struct icvs - Core CVS device context
423  * @i2c_client: I2C client (NULL in platform-only mode)
424  * @work: Delayed work for polling device state / completion
425  * @wq_resp: Last response container populated by workqueue
426  * @cmd_completion: Completion for command waiters
427  * @lock: Mutex protecting command submission & shared state
428  * @subdev: V4L2 sub-device representing the CSI bridge entity
429  * @remote: Remote media pad connected to upstream camera sensor
430  * @notifier: Async notifier for remote sensor discovery
431  * @ctrl_handler: V4L2 control handler
432  * @freq_ctrl: (future) frequency control pointer
433  * @pads: Local media pads (sink/source)
434  * @nr_of_lanes: Active CSI-2 lane count
435  * @link_freq: Current link frequency (Hz)
436  * @ipu_link: PM runtime device link (IPU consumer, CVS supplier)
437  * @res: Resource capability (light/full)
438  * @caps: Reported device protocol capabilities
439  * @prefix: Firmware response prefix present
440  * @quirks: Device-specific quirk flags
441  * @rst: Reset GPIO (full capability only)
442  * @req: Request GPIO (ownership signaling)
443  * @resp: Response GPIO (ownership signaling)
444  * @irq: Wake IRQ (full capability)
445  * @hostwake_event: Waitqueue for wake events
446  * @hostwake_event_arg: Wake event flag
447  */
448 struct icvs {
449 	struct i2c_client *i2c_client;
450 	struct delayed_work work;
451 	struct icvs_resp wq_resp;
452 	struct completion cmd_completion;
453 	struct mutex lock; /* Protects command execution and device state */
454 	struct v4l2_subdev subdev;
455 	struct media_pad *remote;
456 	struct v4l2_async_notifier notifier;
457 	struct v4l2_ctrl_handler ctrl_handler;
458 	struct v4l2_ctrl *freq_ctrl;
459 	struct media_pad pads[ICVS_CSI_NUM_PADS];
460 	u32 nr_of_lanes;
461 	u64 link_freq;
462 	struct device_link *ipu_link;
463 	enum icvs_resources res;
464 	struct icvs_dev_capabilities caps;
465 	bool prefix;
466 	unsigned long quirks;
467 	struct gpio_desc *rst;
468 	struct gpio_desc *req;
469 	struct gpio_desc *resp;
470 	int irq;
471 	wait_queue_head_t hostwake_event;
472 	bool hostwake_event_arg;
473 };
474 
475 /**
476  * cvs_dev - Helper returning the struct device for a CVS context
477  * @ctx: CVS context
478  *
479  * Avoids repeating transport conditional logic at each call site when
480  * acquiring the device pointer for logging or PM operations.
481  *
482  * Return: Device pointer (never NULL if @ctx is valid).
483  */
484 static inline struct device *cvs_dev(struct icvs *ctx)
485 {
486 	return ctx->i2c_client ? &ctx->i2c_client->dev : ctx->subdev.dev;
487 }
488 
489 /* Cross-unit interfaces */
490 int cvs_send(struct icvs *ctx, struct icvs_cmd *cmd, size_t len);
491 int cvs_set_link_owner(struct icvs *ctx, enum icvs_csi_link_owner owner);
492 int cvs_csi_init(struct icvs *ctx, struct device *dev, struct i2c_client *i2c);
493 void cvs_csi_remove(struct icvs *ctx);
494 
495 #endif /* _ICVS_H */
496