xref: /linux/drivers/media/i2c/cvs/core.c (revision cbae17630954cb89f2bdf5bbadfd3aa81ea67283)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2026 Intel Corporation
4  */
5 
6 #include <linux/acpi.h>
7 #include <linux/cleanup.h>
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/i2c.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/jiffies.h>
15 #include <linux/module.h>
16 #include <linux/pci.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/slab.h>
20 #include <linux/time64.h>
21 #include <linux/workqueue.h>
22 
23 #include <media/ipu-bridge.h>
24 #include <media/ipu6-pci-table.h>
25 
26 #include "icvs.h"
27 
28 /* Command timeouts determined experimentally */
29 #define CMD_TIMEOUT (5 * HZ)
30 #define FW_READY_DELAY_MS 100
31 
32 #define PCI_DEVICE_ID_INTEL_IPU7		0x645d	/* MTL / LNL */
33 #define PCI_DEVICE_ID_INTEL_IPU7P5		0xb05d	/* ARL / PTL */
34 
35 /*
36  * IPU7 PCI device IDs not covered by ipu6_pci_tbl in ipu6-pci-table.h.
37  * Once the IPU6 driver gains support for IPU7, this table can be dropped.
38  */
39 static const struct pci_device_id icvs_ipu7_tbl[] = {
40 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7) },
41 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7P5) },
42 	{ }
43 };
44 
45 static const struct acpi_gpio_params gpio_wake = { 0, 0, false };
46 static const struct acpi_gpio_params gpio_rst  = { 1, 0, false };
47 static const struct acpi_gpio_params gpio_req  = { 2, 0, false };
48 static const struct acpi_gpio_params gpio_resp = { 3, 0, false };
49 static const struct acpi_gpio_mapping icvs_acpi_gpios[] = {
50 	{ "wake-gpio", &gpio_wake, 1 },
51 	{ "rst-gpio",  &gpio_rst,  1 },
52 	{ "req-gpio",  &gpio_req,  1 },
53 	{ "resp-gpio", &gpio_resp, 1 },
54 	{ }
55 };
56 
57 static const struct acpi_gpio_params lgpio_req  = { 0, 0, false };
58 static const struct acpi_gpio_params lgpio_resp = { 1, 0, false };
59 static const struct acpi_gpio_mapping icvs_acpi_lgpios[] = {
60 	{ "req-gpio",  &lgpio_req,  1 },
61 	{ "resp-gpio", &lgpio_resp, 1 },
62 	{ }
63 };
64 
65 /* Device quirk table */
66 static const struct icvs_device_quirk cvs_quirk_table[] = {
67 	{ 0x2ac1, 0x20d0, ICVS_NO_MIPI_CONFIG |
68 			  ICVS_NO_CAPS |
69 			  ICVS_NO_FW_UPDATE
70 	},	/* Lattice NX33 */
71 	{ 0x06CB, 0x0701, ICVS_SKIP_FW_RESET |
72 			  ICVS_HOST_SENSOR_PWR_CTRL |
73 			  ICVS_HOST_PRIV_CTRL |
74 			  ICVS_FW_BUF_SIZE_256 |
75 			  ICVS_FW_HEADER_SIZE_256
76 	},	/* Synaptics SVP7xxx */
77 	{ }
78 };
79 
80 /**
81  * cvs_set_quirks - Match device VID/PID and set quirks
82  * @ctx: CVS device context
83  * @vid: Vendor ID
84  * @pid: Product ID
85  *
86  * Searches the quirk table for a matching VID/PID and populates ctx->quirks
87  * with the corresponding quirk flags.
88  * If no match is found, quirks is set to 0.
89  */
90 static void cvs_set_quirks(struct icvs *ctx, u16 vid, u16 pid)
91 {
92 	ctx->quirks = 0;
93 
94 	for (unsigned int i = 0; i < ARRAY_SIZE(cvs_quirk_table); i++) {
95 		if (cvs_quirk_table[i].vid == vid &&
96 		    cvs_quirk_table[i].pid == pid) {
97 			ctx->quirks = cvs_quirk_table[i].quirks;
98 			dev_info(cvs_dev(ctx),
99 				 "Quirks: 0x%lx (VID:0x%04x PID:0x%04x)\n",
100 				 ctx->quirks, vid, pid);
101 			return;
102 		}
103 	}
104 
105 	dev_info(cvs_dev(ctx),
106 		 "No quirks for device (VID:0x%04x PID:0x%04x)\n", vid, pid);
107 }
108 
109 /* I2C transport helpers */
110 
111 /**
112  * cvs_read_i2c - Issue a read-type command and fetch device response
113  * @ctx: CVS device context
114  * @cmd_id: Command identifier (big endian)
115  * @resp: Destination buffer for response payload
116  * @size: Size of payload to read into @resp (without prefix)
117  *
118  * Sends @cmd_id and reads back the response in a single I2C transaction.
119  * When the device prepends a 4-byte protocol prefix, the combined
120  * prefix+payload is read into a temporary buffer and only the payload is
121  * copied to @resp, avoiding any dependency on the layout of the caller's
122  * buffer.
123  *
124  * Return: 0 on success or negative errno.
125  */
126 static int cvs_read_i2c(struct icvs *ctx, __be16 cmd_id, void *resp,
127 			size_t size)
128 {
129 	size_t prefix_size = ctx->prefix ? sizeof(u32) : 0;
130 	size_t read_size = size + prefix_size;
131 	struct i2c_client *i2c = ctx->i2c_client;
132 	u8 *buf __free(kfree) = NULL;
133 	int cnt;
134 
135 	if (!resp || !size)
136 		return -EINVAL;
137 
138 	cnt = i2c_master_send(i2c, (const char *)&cmd_id, sizeof(cmd_id));
139 	if (cnt != sizeof(cmd_id))
140 		return cnt < 0 ? cnt : -EIO;
141 
142 	buf = kmalloc(read_size, GFP_KERNEL);
143 	if (!buf)
144 		return -ENOMEM;
145 
146 	cnt = i2c_master_recv(i2c, buf, read_size);
147 	if (cnt != read_size) {
148 		dev_dbg(cvs_dev(ctx), "recv cmd 0x%04x short read (%d/%zu)\n",
149 			be16_to_cpu(cmd_id), cnt, read_size);
150 		return cnt < 0 ? cnt : -EIO;
151 	}
152 
153 	memcpy(resp, buf + prefix_size, size);
154 
155 	return 0;
156 }
157 
158 /**
159  * cvs_write_i2c - Write a raw command buffer to the device over I2C
160  * @ctx: CVS device context
161  * @data: Buffer containing command + payload
162  * @size: Total bytes to write
163  *
164  * Return: 0 on success or negative errno.
165  */
166 static int cvs_write_i2c(struct icvs *ctx, const void *data, int size)
167 {
168 	struct i2c_client *i2c = ctx->i2c_client;
169 	int cnt;
170 
171 	if (size < 0 || !data)
172 		return -EINVAL;
173 
174 	cnt = i2c_master_send(i2c, data, size);
175 	if (cnt != size) {
176 		dev_dbg(cvs_dev(ctx), "send short (%d/%d)\n", cnt, size);
177 		return cnt < 0 ? cnt : -EIO;
178 	}
179 
180 	return 0;
181 }
182 
183 /**
184  * cvs_checksum - Simple additive checksum helper
185  * @data: 32-bit aligned data buffer
186  * @len: Length in bytes (multiple of 4)
187  *
188  * Return: 32-bit additive checksum of the dwords in @data.
189  */
190 static u32 cvs_checksum(const void *data, size_t len)
191 {
192 	const u32 *words = data;
193 	u32 csum = 0;
194 
195 	if (WARN_ON_ONCE(len % sizeof(u32)))
196 		return 0;
197 
198 	for (unsigned int i = 0; i < len / sizeof(u32); i++)
199 		csum += words[i];
200 
201 	return csum;
202 }
203 
204 /**
205  * cvs_schedule_and_wait - Schedule polling work then wait for completion
206  * @ctx: CVS device context
207  * @work_delay_ms: Delay in milliseconds before polling work executes
208  * @wait_jiffies: Timeout (jiffies) to wait for cmd completion
209  *
210  * Queues ctx->work to run after @work_delay_ms and then waits up to
211  * @wait_jiffies for ctx->cmd_completion.
212  *
213  * Return: 0 on success, -ETIMEDOUT on timeout, negative errno on error.
214  */
215 static int cvs_schedule_and_wait(struct icvs *ctx, unsigned int work_delay_ms,
216 				 unsigned long wait_jiffies)
217 {
218 	int ret;
219 
220 	schedule_delayed_work(&ctx->work, msecs_to_jiffies(work_delay_ms));
221 	ret = wait_for_completion_killable_timeout(&ctx->cmd_completion,
222 						   wait_jiffies);
223 	if (ret < 0)
224 		return ret;
225 	if (!ret)
226 		return -ETIMEDOUT;
227 
228 	return 0;
229 }
230 
231 /**
232  * cvs_wait_wake_or_sleep - Wait for wake IRQ or sleep fallback
233  * @ctx: CVS device context
234  * @timeout_jiffies: Timeout (jiffies) for wake event on full-cap devices
235  * @sleep_ms: Milliseconds to sleep on light-cap devices
236  *
237  * For full capability devices (ICVS_FULLCAP) waits interruptibly on
238  * ctx->hostwake_event until ctx->hostwake_event_arg becomes true or
239  * @timeout_jiffies elapses. The flag is cleared after the wait.
240  * For light capability devices performs a blocking msleep(@sleep_ms).
241  *
242  * Return codes normalized for caller switch handling:
243  *	<0		: error / interrupted
244  *	-ETIMEDOUT	: timeout (wake event not observed)
245  *	0		: success (wake observed OR light-cap sleep elapsed)
246  *
247  * Return: negative errno, -ETIMEDOUT on timeout, 0 on success.
248  */
249 static int cvs_wait_wake_or_sleep(struct icvs *ctx,
250 				  unsigned long timeout_jiffies,
251 				  unsigned int sleep_ms)
252 {
253 	int ret;
254 
255 	if (ctx->res == ICVS_FULLCAP) {
256 		ret = wait_event_interruptible_timeout(ctx->hostwake_event,
257 						       ctx->hostwake_event_arg,
258 						       timeout_jiffies);
259 		ctx->hostwake_event_arg = false;
260 		if (ret < 0)
261 			return ret;
262 		if (!ret)
263 			return -ETIMEDOUT;
264 		return 0;
265 	}
266 
267 	msleep(sleep_ms);
268 
269 	return 0; /* treat sleep path as success */
270 }
271 
272 /**
273  * cvs_config_mipi - Send a HOST_SET_MIPI_CONFIG command
274  * @ctx: CVS device context
275  * @c: Command container with conf field populated
276  * @len: Length of original command structure (unused except for symmetry)
277  *
278  * Packages @c->param.conf into a cvs_mipi_data_packet including size and
279  * checksum, then writes it to the device.
280  *
281  * Firmware note: the CVS firmware expects the MIPI configuration to be
282  * sent as a single transaction, including all relevant parameters and checksum.
283  *
284  * Return: 0 on success, NO_MIPI_CONFIG or negative errno from I2C write.
285  */
286 static int cvs_config_mipi(struct icvs *ctx, struct icvs_cmd *c, size_t len)
287 {
288 	struct icvs_mipi_data_packet pkt = {
289 		.cmd_id = c->cmd_id,
290 		.size = sizeof(c->param.conf),
291 		.crc = cvs_checksum(&c->param.conf, sizeof(c->param.conf)),
292 		.conf = c->param.conf,
293 	};
294 
295 	if (ctx->quirks & ICVS_NO_MIPI_CONFIG)
296 		return 0;
297 
298 	return cvs_write_i2c(ctx, &pkt, sizeof(pkt));
299 }
300 
301 /**
302  * cvs_get_device_state - Query current device state bitfield
303  * @ctx: CVS device context
304  * @state: Returned state value
305  *
306  * Issues GET_DEV_STATE and fills @state.
307  *
308  * Return: 0 on success or negative errno.
309  */
310 static int cvs_get_device_state(struct icvs *ctx, u8 *state)
311 {
312 	struct icvs_resp n = {
313 		.cmd_id = cpu_to_be16(ICVS_GET_DEV_STATE),
314 	};
315 	int ret;
316 
317 	ret = cvs_read_i2c(ctx, n.cmd_id, &n.resp.state, sizeof(n.resp.state));
318 	if (ret)
319 		return ret;
320 
321 	*state = n.resp.state;
322 
323 	return 0;
324 }
325 
326 /**
327  * cvs_get_device_caps - Read protocol capabilities
328  * @ctx: CVS device context
329  * @caps: Capability structure to populate
330  *
331  * Return: 0 on success or negative errno.
332  */
333 static int cvs_get_device_caps(struct icvs *ctx,
334 			       struct icvs_dev_capabilities *caps)
335 {
336 	struct icvs_resp n = {
337 		.cmd_id = cpu_to_be16(ICVS_GET_DEV_CAPABILITY),
338 	};
339 	int ret;
340 
341 	if (ctx->quirks & ICVS_NO_CAPS)
342 		return 0;
343 
344 	ret = cvs_read_i2c(ctx, n.cmd_id, &n.resp.cap, sizeof(n.resp.cap));
345 	if (ret)
346 		return ret;
347 
348 	*caps = n.resp.cap;
349 
350 	return 0;
351 }
352 
353 /**
354  * cvs_hw_init - Probe device for prefix support and apply quirks
355  * @ctx: CVS device context
356  *
357  * Sends GET_DEV_VID_PID and probes for a 32-bit prefix.
358  * If it matches ICVS_PREFIX_VAL, sets ctx->prefix for subsequent reads.
359  * Then reads VID/PID and applies matching quirks.
360  * GET_DEV_VID_PID is supported by all protocol versions.
361  *
362  * Return: 0 on success or negative errno.
363  */
364 static int cvs_hw_init(struct icvs *ctx)
365 {
366 	struct icvs_resp n = { };
367 	__be16 cmd = cpu_to_be16(ICVS_GET_DEV_VID_PID);
368 	u32 resp;
369 	int ret;
370 
371 	/*
372 	 * Clear prefix so cvs_read_i2c always reads exactly sizeof(u32) bytes
373 	 * here, regardless of any value left over from a previous call (e.g.
374 	 * on resume).
375 	 */
376 	ctx->prefix = false;
377 	ret = cvs_read_i2c(ctx, cmd, &resp, sizeof(resp));
378 	if (ret)
379 		return ret;
380 
381 	ctx->prefix = resp == ICVS_PREFIX_VAL;
382 
383 	/* Now read VID/PID to apply quirks */
384 	ret = cvs_read_i2c(ctx, cmd,
385 			   &n.resp.vid_pid, sizeof(n.resp.vid_pid));
386 	if (ret)
387 		return ret;
388 
389 	cvs_set_quirks(ctx, n.resp.vid_pid.v_id, n.resp.vid_pid.p_id);
390 
391 	return 0;
392 }
393 
394 /**
395  * cvs_irq_handler - Wake IRQ handler (full capability devices)
396  * @irq: IRQ number
397  * @dev_id: Device context pointer
398  *
399  * Sets a waitqueue flag and wakes up sleeping waiters.
400  *
401  * Return: IRQ_HANDLED always.
402  */
403 static irqreturn_t cvs_irq_handler(int irq, void *dev_id)
404 {
405 	struct icvs *ctx = dev_id;
406 
407 	ctx->hostwake_event_arg = true;
408 	wake_up_interruptible(&ctx->hostwake_event);
409 
410 	return IRQ_HANDLED;
411 }
412 
413 /**
414  * cvs_reset - Toggle reset GPIO for full capability devices
415  * @ctx: CVS device context
416  *
417  * Drives reset low briefly then high if device resources indicate full
418  * capability. Light devices have no reset line.
419  */
420 static void cvs_reset(struct icvs *ctx)
421 {
422 	if (ctx->quirks & ICVS_SKIP_FW_RESET)
423 		return;
424 
425 	if (ctx->res == ICVS_FULLCAP) {
426 		gpiod_set_value(ctx->rst, 0);
427 		fsleep(2000);
428 		gpiod_set_value(ctx->rst, 1);
429 	}
430 }
431 
432 /**
433  * cvs_recv - Delayed work handler polling for command completion
434  * @work: Embedded delayed_work member
435  *
436  * Re-reads device state; if device_busy remains set, re-schedules itself.
437  * Otherwise stores state into wq_resp and completes the command.
438  */
439 static void cvs_recv(struct work_struct *work)
440 {
441 	struct icvs *ctx = container_of(work, struct icvs, work.work);
442 	u8 state = 0;
443 	int ret;
444 
445 	ret = cvs_get_device_state(ctx, &state);
446 	if (ret < 0) {
447 		dev_dbg(cvs_dev(ctx), "state read failed: %d\n", ret);
448 		return;
449 	}
450 
451 	if (state & ICVS_DEV_STATE_BUSY) {
452 		dev_dbg(cvs_dev(ctx), "device busy, reschedule\n");
453 		schedule_delayed_work(&ctx->work,
454 				      msecs_to_jiffies(FW_READY_DELAY_MS));
455 		return;
456 	}
457 
458 	ctx->wq_resp.resp.state = state;
459 	complete(&ctx->cmd_completion);
460 }
461 
462 /**
463  * cvs_send - Common command submission path
464  * @ctx: CVS device context
465  * @cmd: Command buffer (icvs_cmd) with cmd_id and param populated
466  * @len: Buffer length
467  *
468  * Dispatches a set of supported commands:
469  * - ICVS_SET_DEV_HOST_ID,
470  * - ICVS_HOST_SENSOR_OWNER,
471  * - ICVS_HOST_SET_MIPI_CONFIG
472  * - ICVS_FW_LOADER_*
473  *
474  * For I2C based commands it sets big-endian cmd ids, writes to the device
475  * and waits (via delayed work) for completion or timeout.
476  * GPIO based ownership toggles are handled locally.
477  *
478  * Caller must hold ctx->lock when invoking this function and check for i2c
479  * bus availability.
480  *
481  * Return: 0 on success, negative errno, -EINVAL for unsupported command
482  * or status from device in ctx->wq_resp.
483  */
484 int cvs_send(struct icvs *ctx, struct icvs_cmd *cmd, size_t len)
485 {
486 	int ret, status = 0;
487 
488 	lockdep_assert_held(&ctx->lock);
489 
490 	dev_dbg(cvs_dev(ctx), "send cmd = 0x%04x", be16_to_cpu(cmd->cmd_id));
491 
492 	reinit_completion(&ctx->cmd_completion);
493 
494 	switch (be16_to_cpu(cmd->cmd_id)) {
495 	case ICVS_SET_DEV_HOST_ID:
496 		cmd->cmd_id = cpu_to_be16(ICVS_SET_DEV_HOST_ID);
497 		ret = cvs_write_i2c(ctx, cmd, len);
498 		if (ret < 0)
499 			break;
500 
501 		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
502 					    CMD_TIMEOUT);
503 		if (ret < 0)
504 			break;
505 
506 		status = ctx->wq_resp.resp.state &
507 			  ICVS_DEV_STATE_ERROR ? -EINVAL : 0;
508 		break;
509 	case ICVS_HOST_SENSOR_OWNER:
510 		gpiod_set_value_cansleep(ctx->req, cmd->param.param);
511 		fsleep(FW_READY_DELAY_MS * USEC_PER_MSEC);
512 		ret = gpiod_get_value_cansleep(ctx->resp);
513 		status = cmd->param.param == ret ? 0 : -EINVAL;
514 		ret = 0; /* success */
515 		break;
516 	case ICVS_HOST_SET_MIPI_CONFIG:
517 		cmd->cmd_id = cpu_to_be16(ICVS_HOST_SET_MIPI_CONFIG);
518 		ret = cvs_config_mipi(ctx, cmd, len);
519 		if (ret < 0)
520 			break;
521 
522 		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
523 					    CMD_TIMEOUT);
524 		status = (ctx->wq_resp.resp.state &
525 			  ICVS_DEV_STATE_ERROR) ? -EINVAL : 0;
526 		break;
527 	case ICVS_FW_LOADER_START:
528 		cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_START);
529 		ret = cvs_write_i2c(ctx, cmd, len);
530 		if (ret < 0)
531 			break;
532 
533 		ret = cvs_wait_wake_or_sleep(ctx, CMD_TIMEOUT,
534 					     FW_READY_DELAY_MS);
535 		if (ret)
536 			break;
537 
538 		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
539 					    CMD_TIMEOUT);
540 		status = (ctx->wq_resp.resp.state &
541 			  ICVS_DEV_STATE_DOWNLOAD) ? 0 : -EINVAL;
542 		break;
543 	case ICVS_FW_LOADER_DATA:
544 		/* Quirk for older protocols */
545 		if (ctx->caps.protocol_version_major >= 2 &&
546 		    ctx->caps.protocol_version_minor >= 2) {
547 			cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_DATA);
548 			ret = cvs_write_i2c(ctx, cmd, len);
549 		} else {
550 			ret = cvs_write_i2c(ctx, &cmd->param,
551 					    len - sizeof(cmd->cmd_id));
552 		}
553 
554 		if (ret < 0)
555 			return ret;
556 
557 		ret = cvs_wait_wake_or_sleep(ctx, FW_READY_DELAY_MS,
558 					     FW_READY_DELAY_MS);
559 		if (ret)
560 			break;
561 
562 		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
563 					    CMD_TIMEOUT);
564 		status = ctx->wq_resp.resp.state &
565 			  ICVS_DEV_STATE_ERROR ? -EINVAL : 0;
566 		break;
567 	case ICVS_FW_LOADER_END:
568 		cmd->cmd_id = cpu_to_be16(ICVS_FW_LOADER_END);
569 		ret = cvs_write_i2c(ctx, cmd, len);
570 		if (ret < 0)
571 			break;
572 
573 		ret = cvs_wait_wake_or_sleep(ctx, CMD_TIMEOUT,
574 					     FW_READY_DELAY_MS);
575 		if (ret)
576 			break;
577 
578 		ret = cvs_schedule_and_wait(ctx, FW_READY_DELAY_MS,
579 					    CMD_TIMEOUT);
580 		status = !(ctx->wq_resp.resp.state &
581 			   ICVS_DEV_STATE_DOWNLOAD) ? 0 : -EINVAL;
582 		break;
583 	default:
584 		ret = -EINVAL;
585 		break;
586 	}
587 
588 	if (ret < 0)
589 		return ret;
590 
591 	return ctx->wq_resp.status = status;
592 }
593 
594 /**
595  * cvs_set_link_owner - Switch CSI-2 link ownership between host and device
596  * @ctx: CVS device context
597  * @owner: Desired owner (ICVS_CSI_LINK_HOST or ICVS_CSI_LINK_CVS)
598  *
599  * Called from runtime PM callbacks to claim or release the CSI-2 link.
600  * Also callable directly for error recovery paths.
601  *
602  * Return: 0 on success or negative errno.
603  */
604 int cvs_set_link_owner(struct icvs *ctx, enum icvs_csi_link_owner owner)
605 {
606 	struct icvs_cmd cmd = {
607 		.cmd_id = cpu_to_be16(ICVS_HOST_SENSOR_OWNER),
608 		.param.param = owner,
609 	};
610 	size_t cmd_size = sizeof(cmd.cmd_id) + sizeof(cmd.param.param);
611 
612 	guard(mutex)(&ctx->lock);
613 	return cvs_send(ctx, &cmd, cmd_size);
614 }
615 
616 /**
617  * cvs_configure_dev_caps - Configure device capability ownership bits
618  * @ctx: CVS device context
619  *
620  * Tells the CVS device which of its features (privacy LED, RGB camera
621  * power-up, vision sensing) are controlled by the host, then sends
622  * SET_DEV_HOST_ID.
623  *
624  * Return: 0 on success or negative errno.
625  */
626 static int cvs_configure_dev_caps(struct icvs *ctx)
627 {
628 	struct icvs_cmd cmd = { .cmd_id = cpu_to_be16(ICVS_SET_DEV_HOST_ID) };
629 	size_t sz = sizeof(cmd.cmd_id) + sizeof(cmd.param.host_id);
630 
631 	if (ctx->quirks & ICVS_NO_CAPS)
632 		return 0;
633 
634 	if (ctx->quirks & ICVS_HOST_VISION_SENSING)
635 		cmd.param.host_id |= ICVS_HOST_ID_VISION_SENSING;
636 	if (ctx->quirks & ICVS_HOST_PRIV_CTRL)
637 		cmd.param.host_id |= ICVS_HOST_ID_PRIVACY_LED;
638 	if (ctx->quirks & ICVS_HOST_SENSOR_PWR_CTRL)
639 		cmd.param.host_id |= ICVS_HOST_ID_RGBCAMERA_PWRUP;
640 
641 	guard(mutex)(&ctx->lock);
642 	return cvs_send(ctx, &cmd, sz);
643 }
644 
645 /**
646  * cvs_core_probe - Shared probe path for I2C & platform instantiation
647  * @dev: Parent device
648  * @i2c: I2C client (NULL for platform devices)
649  *
650  * Discovers IPU, parses ACPI resources, sets up GPIOs/IRQs, initializes
651  * sub-device (CSI) and host identifier, and exposes sysfs firmware interface.
652  *
653  * Return: 0 on success or negative errno.
654  */
655 static int cvs_core_probe(struct device *dev, struct i2c_client *i2c)
656 {
657 	struct pci_dev *ipu = NULL;
658 	struct icvs *ctx;
659 	int ret;
660 
661 	/* Locate IPU device */
662 	for (unsigned int i = 0; !ipu && ipu6_pci_tbl[i].vendor; i++)
663 		ipu = pci_get_device(ipu6_pci_tbl[i].vendor,
664 				     ipu6_pci_tbl[i].device, NULL);
665 	for (unsigned int i = 0; !ipu && icvs_ipu7_tbl[i].vendor; i++)
666 		ipu = pci_get_device(icvs_ipu7_tbl[i].vendor,
667 				     icvs_ipu7_tbl[i].device, NULL);
668 	if (!ipu)
669 		return -ENODEV;
670 
671 	ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb);
672 	if (ret < 0)
673 		goto err_put_ipu;
674 
675 	if (!dev_fwnode(dev)) {
676 		ret = -ENXIO;
677 		goto err_put_ipu;
678 	}
679 
680 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
681 	if (!ctx) {
682 		ret = -ENOMEM;
683 		goto err_put_ipu;
684 	}
685 
686 	ctx->i2c_client = i2c;
687 
688 	ret = gpiod_count(dev, NULL);
689 	switch (ret) {
690 	case ICVS_GPIO_SYNC:
691 		ctx->res = ICVS_LIGHTCAP;
692 		break;
693 	case ICVS_GPIO_ASYNC:
694 		ctx->res = ICVS_FULLCAP;
695 		break;
696 	default:
697 		dev_err(dev, "unexpected GPIO count %d\n", ret);
698 		ret = -EINVAL;
699 		goto err_put_ipu;
700 	}
701 
702 	ret = devm_acpi_dev_add_driver_gpios(dev,
703 					     ctx->res == ICVS_FULLCAP ?
704 					     icvs_acpi_gpios :
705 					     icvs_acpi_lgpios);
706 	if (ret) {
707 		dev_err_probe(dev, ret, "failed to add ACPI GPIOs\n");
708 		goto err_put_ipu;
709 	}
710 
711 	ctx->req = devm_gpiod_get(dev, "req", GPIOD_OUT_HIGH);
712 	if (IS_ERR(ctx->req)) {
713 		ret = dev_err_probe(dev, PTR_ERR(ctx->req),
714 				    "failed to get req GPIO\n");
715 		goto err_put_ipu;
716 	}
717 
718 	ctx->resp = devm_gpiod_get(dev, "resp", GPIOD_IN);
719 	if (IS_ERR(ctx->resp)) {
720 		ret = dev_err_probe(dev, PTR_ERR(ctx->resp),
721 				    "failed to get resp GPIO\n");
722 		goto err_put_ipu;
723 	}
724 
725 	if (ctx->res == ICVS_FULLCAP) {
726 		struct gpio_desc *wake;
727 
728 		ctx->rst = devm_gpiod_get(dev, "rst", GPIOD_OUT_HIGH);
729 		if (IS_ERR(ctx->rst)) {
730 			ret = dev_err_probe(dev, PTR_ERR(ctx->rst),
731 					    "failed to get rst GPIO\n");
732 			goto err_put_ipu;
733 		}
734 
735 		wake = devm_gpiod_get(dev, "wake", GPIOD_IN);
736 		if (IS_ERR(wake)) {
737 			ret = dev_err_probe(dev, PTR_ERR(wake),
738 					    "failed to get wake GPIO\n");
739 			goto err_put_ipu;
740 		}
741 
742 		ctx->irq = gpiod_to_irq(wake);
743 		if (ctx->irq < 0) {
744 			ret = dev_err_probe(dev, ctx->irq,
745 					    "failed to get wake IRQ\n");
746 			goto err_put_ipu;
747 		}
748 
749 		ret = devm_request_threaded_irq(dev, ctx->irq, NULL,
750 						cvs_irq_handler,
751 						IRQF_ONESHOT | IRQF_NO_SUSPEND,
752 						"cvs_wake", ctx);
753 		if (ret) {
754 			dev_err_probe(dev, ret, "failed to request IRQ\n");
755 			goto err_put_ipu;
756 		}
757 	}
758 
759 	ret = devm_mutex_init(dev, &ctx->lock);
760 	if (ret)
761 		goto err_put_ipu;
762 
763 	init_completion(&ctx->cmd_completion);
764 	init_waitqueue_head(&ctx->hostwake_event);
765 	INIT_DELAYED_WORK(&ctx->work, cvs_recv);
766 
767 	if (i2c) {
768 		ret = cvs_hw_init(ctx);
769 		if (ret) {
770 			dev_err(dev, "HW init failed (%d)\n", ret);
771 			/*
772 			 * Fallback to GPIO-only mode.
773 			 * Some BIOS show the device on the I2C bus, however,
774 			 * the device is not accessible via I2C.
775 			 */
776 			ctx->i2c_client = NULL;
777 			goto fail_i2c;
778 		}
779 
780 		ret = cvs_get_device_caps(ctx, &ctx->caps);
781 		if (ret) {
782 			dev_err_probe(dev, ret, "get caps failed\n");
783 			goto err_put_ipu;
784 		}
785 
786 		ret = cvs_configure_dev_caps(ctx);
787 		if (ret) {
788 			dev_err_probe(dev, ret,
789 				      "configure dev caps failed\n");
790 			goto err_put_ipu;
791 		}
792 	}
793 
794 fail_i2c:
795 	ret = cvs_csi_init(ctx, dev, i2c);
796 	if (ret) {
797 		dev_err_probe(dev, ret, "CSI init failed\n");
798 		goto err_put_ipu;
799 	}
800 
801 	dev_set_drvdata(dev, ctx);
802 	pm_runtime_set_autosuspend_delay(dev, 1000);
803 	pm_runtime_use_autosuspend(dev);
804 	pm_runtime_enable(dev);
805 	pm_runtime_idle(dev);
806 
807 	/*
808 	 * Create a PM runtime device link with IPU as consumer and CVS as
809 	 * supplier. When the IPU runtime-resumes to start streaming, the PM
810 	 * framework automatically resumes CVS first, triggering
811 	 * cvs_runtime_resume() which hands CSI-2 link ownership to the host.
812 	 */
813 	ctx->ipu_link = device_link_add(&ipu->dev, dev,
814 					DL_FLAG_PM_RUNTIME |
815 					DL_FLAG_RPM_ACTIVE |
816 					DL_FLAG_STATELESS);
817 	if (!ctx->ipu_link) {
818 		dev_err(dev, "IPU device link failed\n");
819 		ret = -ENODEV;
820 		goto err_csi_remove;
821 	}
822 
823 	if (has_acpi_companion(dev))
824 		acpi_dev_clear_dependencies(ACPI_COMPANION(dev));
825 
826 	put_device(&ipu->dev);
827 
828 	return 0;
829 
830 err_csi_remove:
831 	if (ctx->ipu_link)
832 		device_link_del(ctx->ipu_link);
833 	cvs_csi_remove(ctx);
834 	pm_runtime_dont_use_autosuspend(dev);
835 	pm_runtime_disable(dev);
836 	pm_runtime_set_suspended(dev);
837 
838 err_put_ipu:
839 	put_device(&ipu->dev);
840 
841 	return ret;
842 }
843 
844 /**
845  * cvs_probe - I2C driver probe entry
846  * @i2c: I2C client
847  *
848  * Return: 0 on success or negative errno.
849  */
850 static int cvs_probe(struct i2c_client *i2c)
851 {
852 	return cvs_core_probe(&i2c->dev, i2c);
853 }
854 
855 /**
856  * cvs_core_remove - Shared remove logic
857  * @dev: Device
858  */
859 static void cvs_core_remove(struct device *dev)
860 {
861 	struct icvs *ctx = dev_get_drvdata(dev);
862 
863 	cancel_delayed_work_sync(&ctx->work);
864 	cvs_csi_remove(ctx);
865 
866 	if (ctx->ipu_link)
867 		device_link_del(ctx->ipu_link);
868 
869 	pm_runtime_put_noidle(dev);
870 	pm_runtime_disable(dev);
871 	pm_runtime_set_suspended(dev);
872 
873 	cvs_reset(ctx);
874 }
875 
876 /**
877  * cvs_remove - I2C driver remove
878  * @client: I2C client
879  */
880 static void cvs_remove(struct i2c_client *client)
881 {
882 	cvs_core_remove(&client->dev);
883 }
884 
885 /**
886  * cvs_suspend - System suspend callback
887  * @dev: Device
888  *
889  * Return: 0.
890  */
891 static int __maybe_unused cvs_suspend(struct device *dev)
892 {
893 	struct icvs *ctx = dev_get_drvdata(dev);
894 
895 	cancel_delayed_work_sync(&ctx->work);
896 
897 	return 0;
898 }
899 
900 /**
901  * cvs_resume - System resume callback
902  * @dev: Device
903  *
904  * Re-validates I2C link prefix and re-sends host id if transport available.
905  *
906  * Return: 0 on success or negative errno if I2C check fails.
907  */
908 static int __maybe_unused cvs_resume(struct device *dev)
909 {
910 	struct icvs *ctx = dev_get_drvdata(dev);
911 	int ret;
912 
913 	if (ctx->i2c_client) {
914 		ret = cvs_hw_init(ctx);
915 		if (ret)
916 			return ret;
917 		return cvs_configure_dev_caps(ctx);
918 	}
919 
920 	return 0;
921 }
922 
923 /**
924  * cvs_runtime_resume - Runtime PM resume: claim CSI-2 link ownership
925  * @dev: Device
926  *
927  * Triggered automatically when the IPU (consumer) runtime-resumes, because
928  * a DL_FLAG_PM_RUNTIME device link makes CVS the supplier. Transfers CSI-2
929  * link ownership to the host so the IPU can start receiving sensor frames.
930  *
931  * Return: 0 on success or negative errno.
932  */
933 static int __maybe_unused cvs_runtime_resume(struct device *dev)
934 {
935 	struct icvs *ctx = dev_get_drvdata(dev);
936 
937 	return cvs_set_link_owner(ctx, ICVS_CSI_LINK_HOST);
938 }
939 
940 /**
941  * cvs_runtime_suspend - Runtime PM suspend: release CSI-2 link ownership
942  * @dev: Device
943  *
944  * Called when the streaming reference is dropped by cvs_csi_disable_streams
945  * via pm_runtime_put_autosuspend. Returns CSI-2 link ownership to CVS firmware.
946  *
947  * Return: 0 on success or negative errno.
948  */
949 static int __maybe_unused cvs_runtime_suspend(struct device *dev)
950 {
951 	struct icvs *ctx = dev_get_drvdata(dev);
952 
953 	return cvs_set_link_owner(ctx, ICVS_CSI_LINK_CVS);
954 }
955 
956 static const struct dev_pm_ops __maybe_unused cvs_pm_ops = {
957 	SET_SYSTEM_SLEEP_PM_OPS(cvs_suspend, cvs_resume)
958 	SET_RUNTIME_PM_OPS(cvs_runtime_suspend, cvs_runtime_resume, NULL)
959 };
960 
961 static const struct acpi_device_id intel_cvs_acpi_match[] = {
962 	{ "INTC10DE" }, /* LNL */
963 	{ "INTC10E0" }, /* ARL */
964 	{ "INTC10E1" }, /* PTL */
965 	{ }
966 };
967 MODULE_DEVICE_TABLE(acpi, intel_cvs_acpi_match);
968 
969 static struct i2c_driver cvs_driver = {
970 	.driver = {
971 		.name = "intel_cvs",
972 		.acpi_match_table = intel_cvs_acpi_match,
973 		.pm = pm_ptr(&cvs_pm_ops),
974 	},
975 	.probe = cvs_probe,
976 	.remove = cvs_remove,
977 };
978 
979 static int cvs_platform_probe(struct platform_device *pdev)
980 {
981 	return cvs_core_probe(&pdev->dev, NULL);
982 }
983 
984 static void cvs_platform_remove(struct platform_device *pdev)
985 {
986 	cvs_core_remove(&pdev->dev);
987 }
988 
989 /*
990  * Platform driver structure.
991  *
992  * Some platforms may instantiate the CVS device as a platform device
993  * without I2C support. This driver binding allows such platforms to use the
994  * CVS core functionality (GPIOs, CSI sub-device) without I2C.
995  */
996 static struct platform_driver cvs_platform_driver = {
997 	.driver = {
998 		.name = "cvs_platform",
999 		.acpi_match_table = intel_cvs_acpi_match,
1000 		.pm = pm_ptr(&cvs_pm_ops),
1001 	},
1002 	.probe = cvs_platform_probe,
1003 	.remove = cvs_platform_remove,
1004 };
1005 
1006 /**
1007  * cvs_init - Module init registering I2C and platform drivers
1008  *
1009  * Return: 0 on success or negative errno.
1010  */
1011 static int __init cvs_init(void)
1012 {
1013 	int ret;
1014 
1015 	ret = i2c_add_driver(&cvs_driver);
1016 	if (ret)
1017 		return ret;
1018 
1019 	ret = platform_driver_register(&cvs_platform_driver);
1020 	if (ret) {
1021 		i2c_del_driver(&cvs_driver);
1022 		return ret;
1023 	}
1024 
1025 	return 0;
1026 }
1027 
1028 /**
1029  * cvs_exit - Module exit unregistering drivers
1030  */
1031 static void __exit cvs_exit(void)
1032 {
1033 	platform_driver_unregister(&cvs_platform_driver);
1034 	i2c_del_driver(&cvs_driver);
1035 }
1036 module_init(cvs_init);
1037 module_exit(cvs_exit);
1038 
1039 MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
1040 MODULE_AUTHOR("Miguel Vadillo <miguel.vadillo@intel.com>");
1041 MODULE_DESCRIPTION("Intel Vision Sensing Controller driver");
1042 MODULE_LICENSE("GPL");
1043