1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 Intel Corporation. All rights reserved.
4  * Intel Visual Sensing Controller CSI Linux driver
5  */
6 
7 /*
8  * To set ownership of CSI-2 link and to configure CSI-2 link, there
9  * are specific commands, which are sent via MEI protocol. The send
10  * command function uses "completion" as a synchronization mechanism.
11  * The response for command is received via a mei callback which wakes
12  * up the caller. There can be only one outstanding command at a time.
13  */
14 
15 #include <linux/completion.h>
16 #include <linux/delay.h>
17 #include <linux/kernel.h>
18 #include <linux/math64.h>
19 #include <linux/mei_cl_bus.h>
20 #include <linux/module.h>
21 #include <linux/mutex.h>
22 #include <linux/pci.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/slab.h>
25 #include <linux/units.h>
26 #include <linux/uuid.h>
27 #include <linux/workqueue.h>
28 
29 #include <media/ipu-bridge.h>
30 #include <media/ipu6-pci-table.h>
31 #include <media/v4l2-async.h>
32 #include <media/v4l2-ctrls.h>
33 #include <media/v4l2-fwnode.h>
34 #include <media/v4l2-subdev.h>
35 
36 #define MEI_CSI_ENTITY_NAME "Intel IVSC CSI"
37 
38 /* the 5s used here is based on experiment */
39 #define CSI_CMD_TIMEOUT (5 * HZ)
40 /* to setup CSI-2 link an extra delay needed and determined experimentally */
41 #define CSI_FW_READY_DELAY_MS 100
42 /* link frequency unit is 100kHz */
43 #define CSI_LINK_FREQ(x) ((u32)(div_u64(x, 100 * HZ_PER_KHZ)))
44 
45 /*
46  * identify the command id supported by firmware
47  * IPC, as well as the privacy notification id
48  * used when processing privacy event.
49  */
50 enum csi_cmd_id {
51 	/* used to set csi ownership */
52 	CSI_SET_OWNER = 0,
53 
54 	/* used to configure CSI-2 link */
55 	CSI_SET_CONF = 2,
56 
57 	/* privacy notification id used when privacy state changes */
58 	CSI_PRIVACY_NOTIF = 6,
59 };
60 
61 /* CSI-2 link ownership definition */
62 enum csi_link_owner {
63 	CSI_LINK_IVSC,
64 	CSI_LINK_HOST,
65 };
66 
67 /* privacy status definition */
68 enum ivsc_privacy_status {
69 	CSI_PRIVACY_OFF,
70 	CSI_PRIVACY_ON,
71 	CSI_PRIVACY_MAX,
72 };
73 
74 enum csi_pads {
75 	CSI_PAD_SINK,
76 	CSI_PAD_SOURCE,
77 	CSI_NUM_PADS
78 };
79 
80 /* configuration of the CSI-2 link between host and IVSC */
81 struct csi_link_cfg {
82 	/* number of data lanes used on the CSI-2 link */
83 	u32 nr_of_lanes;
84 
85 	/* frequency of the CSI-2 link */
86 	u32 link_freq;
87 
88 	/* for future use */
89 	u32 rsvd[2];
90 } __packed;
91 
92 /* CSI command structure */
93 struct csi_cmd {
94 	u32 cmd_id;
95 	union _cmd_param {
96 		u32 param;
97 		struct csi_link_cfg conf;
98 	} param;
99 } __packed;
100 
101 /* CSI notification structure */
102 struct csi_notif {
103 	u32 cmd_id;
104 	int status;
105 	union _resp_cont {
106 		u32 cont;
107 		struct csi_link_cfg conf;
108 	} cont;
109 } __packed;
110 
111 struct mei_csi {
112 	struct mei_cl_device *cldev;
113 
114 	/* command response */
115 	struct csi_notif cmd_response;
116 	/* used to wait for command response from firmware */
117 	struct completion cmd_completion;
118 	/* protect command download */
119 	struct mutex lock;
120 
121 	struct v4l2_subdev subdev;
122 	struct media_pad *remote;
123 	struct v4l2_async_notifier notifier;
124 	struct v4l2_ctrl_handler ctrl_handler;
125 	struct v4l2_ctrl *freq_ctrl;
126 	struct v4l2_ctrl *privacy_ctrl;
127 	/* lock for v4l2 controls */
128 	struct mutex ctrl_lock;
129 	/* start streaming or not */
130 	int streaming;
131 
132 	struct media_pad pads[CSI_NUM_PADS];
133 
134 	/* number of data lanes used on the CSI-2 link */
135 	u32 nr_of_lanes;
136 	/* frequency of the CSI-2 link */
137 	u64 link_freq;
138 };
139 
140 static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
141 	.width = 1,
142 	.height = 1,
143 	.code = MEDIA_BUS_FMT_Y8_1X8,
144 	.field = V4L2_FIELD_NONE,
145 };
146 
notifier_to_csi(struct v4l2_async_notifier * n)147 static inline struct mei_csi *notifier_to_csi(struct v4l2_async_notifier *n)
148 {
149 	return container_of(n, struct mei_csi, notifier);
150 }
151 
sd_to_csi(struct v4l2_subdev * sd)152 static inline struct mei_csi *sd_to_csi(struct v4l2_subdev *sd)
153 {
154 	return container_of(sd, struct mei_csi, subdev);
155 }
156 
157 /* send a command to firmware and mutex must be held by caller */
mei_csi_send(struct mei_csi * csi,u8 * buf,size_t len)158 static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len)
159 {
160 	struct csi_cmd *cmd = (struct csi_cmd *)buf;
161 	int ret;
162 
163 	reinit_completion(&csi->cmd_completion);
164 
165 	ret = mei_cldev_send(csi->cldev, buf, len);
166 	if (ret < 0)
167 		goto out;
168 
169 	ret = wait_for_completion_killable_timeout(&csi->cmd_completion,
170 						   CSI_CMD_TIMEOUT);
171 	if (ret < 0) {
172 		goto out;
173 	} else if (!ret) {
174 		ret = -ETIMEDOUT;
175 		goto out;
176 	}
177 
178 	/* command response status */
179 	ret = csi->cmd_response.status;
180 	if (ret == -1) {
181 		/* notify privacy on instead of reporting error */
182 		ret = 0;
183 		v4l2_ctrl_s_ctrl(csi->privacy_ctrl, 1);
184 	} else if (ret) {
185 		ret = -EINVAL;
186 		goto out;
187 	}
188 
189 	if (csi->cmd_response.cmd_id != cmd->cmd_id)
190 		ret = -EINVAL;
191 
192 out:
193 	return ret;
194 }
195 
196 /* set CSI-2 link ownership */
csi_set_link_owner(struct mei_csi * csi,enum csi_link_owner owner)197 static int csi_set_link_owner(struct mei_csi *csi, enum csi_link_owner owner)
198 {
199 	struct csi_cmd cmd = { 0 };
200 	size_t cmd_size;
201 	int ret;
202 
203 	cmd.cmd_id = CSI_SET_OWNER;
204 	cmd.param.param = owner;
205 	cmd_size = sizeof(cmd.cmd_id) + sizeof(cmd.param.param);
206 
207 	mutex_lock(&csi->lock);
208 
209 	ret = mei_csi_send(csi, (u8 *)&cmd, cmd_size);
210 
211 	mutex_unlock(&csi->lock);
212 
213 	return ret;
214 }
215 
216 /* configure CSI-2 link between host and IVSC */
csi_set_link_cfg(struct mei_csi * csi)217 static int csi_set_link_cfg(struct mei_csi *csi)
218 {
219 	struct csi_cmd cmd = { 0 };
220 	size_t cmd_size;
221 	int ret;
222 
223 	cmd.cmd_id = CSI_SET_CONF;
224 	cmd.param.conf.nr_of_lanes = csi->nr_of_lanes;
225 	cmd.param.conf.link_freq = CSI_LINK_FREQ(csi->link_freq);
226 	cmd_size = sizeof(cmd.cmd_id) + sizeof(cmd.param.conf);
227 
228 	mutex_lock(&csi->lock);
229 
230 	ret = mei_csi_send(csi, (u8 *)&cmd, cmd_size);
231 	/*
232 	 * wait configuration ready if download success. placing
233 	 * delay under mutex is to make sure current command flow
234 	 * completed before starting a possible new one.
235 	 */
236 	if (!ret)
237 		msleep(CSI_FW_READY_DELAY_MS);
238 
239 	mutex_unlock(&csi->lock);
240 
241 	return ret;
242 }
243 
244 /* callback for receive */
mei_csi_rx(struct mei_cl_device * cldev)245 static void mei_csi_rx(struct mei_cl_device *cldev)
246 {
247 	struct mei_csi *csi = mei_cldev_get_drvdata(cldev);
248 	struct csi_notif notif = { 0 };
249 	int ret;
250 
251 	ret = mei_cldev_recv(cldev, (u8 *)&notif, sizeof(notif));
252 	if (ret < 0) {
253 		dev_err(&cldev->dev, "recv error: %d\n", ret);
254 		return;
255 	}
256 
257 	switch (notif.cmd_id) {
258 	case CSI_PRIVACY_NOTIF:
259 		if (notif.cont.cont < CSI_PRIVACY_MAX)
260 			v4l2_ctrl_s_ctrl(csi->privacy_ctrl,
261 					 notif.cont.cont == CSI_PRIVACY_ON);
262 		break;
263 	case CSI_SET_OWNER:
264 	case CSI_SET_CONF:
265 		memcpy(&csi->cmd_response, &notif, ret);
266 
267 		complete(&csi->cmd_completion);
268 		break;
269 	default:
270 		break;
271 	}
272 }
273 
mei_csi_set_stream(struct v4l2_subdev * sd,int enable)274 static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
275 {
276 	struct mei_csi *csi = sd_to_csi(sd);
277 	struct v4l2_subdev *remote_sd =
278 		media_entity_to_v4l2_subdev(csi->remote->entity);
279 	s64 freq;
280 	int ret;
281 
282 	if (enable && csi->streaming == 0) {
283 		freq = v4l2_get_link_freq(csi->remote, 0, 0);
284 		if (freq < 0) {
285 			dev_err(&csi->cldev->dev,
286 				"error %lld, invalid link_freq\n", freq);
287 			ret = freq;
288 			goto err;
289 		}
290 		csi->link_freq = freq;
291 
292 		/* switch CSI-2 link to host */
293 		ret = csi_set_link_owner(csi, CSI_LINK_HOST);
294 		if (ret < 0)
295 			goto err;
296 
297 		/* configure CSI-2 link */
298 		ret = csi_set_link_cfg(csi);
299 		if (ret < 0)
300 			goto err_switch;
301 
302 		ret = v4l2_subdev_call(remote_sd, video, s_stream, 1);
303 		if (ret)
304 			goto err_switch;
305 	} else if (!enable && csi->streaming == 1) {
306 		v4l2_subdev_call(remote_sd, video, s_stream, 0);
307 
308 		/* switch CSI-2 link to IVSC */
309 		ret = csi_set_link_owner(csi, CSI_LINK_IVSC);
310 		if (ret < 0)
311 			dev_warn(&csi->cldev->dev,
312 				 "failed to switch CSI2 link: %d\n", ret);
313 	}
314 
315 	csi->streaming = enable;
316 
317 	return 0;
318 
319 err_switch:
320 	csi_set_link_owner(csi, CSI_LINK_IVSC);
321 
322 err:
323 	return ret;
324 }
325 
mei_csi_init_state(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state)326 static int mei_csi_init_state(struct v4l2_subdev *sd,
327 			      struct v4l2_subdev_state *sd_state)
328 {
329 	struct v4l2_mbus_framefmt *mbusformat;
330 	unsigned int i;
331 
332 	for (i = 0; i < sd->entity.num_pads; i++) {
333 		mbusformat = v4l2_subdev_state_get_format(sd_state, i);
334 		*mbusformat = mei_csi_format_mbus_default;
335 	}
336 
337 	return 0;
338 }
339 
mei_csi_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * format)340 static int mei_csi_set_fmt(struct v4l2_subdev *sd,
341 			   struct v4l2_subdev_state *sd_state,
342 			   struct v4l2_subdev_format *format)
343 {
344 	struct v4l2_mbus_framefmt *source_fmt;
345 	struct v4l2_mbus_framefmt *sink_fmt;
346 
347 	sink_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SINK);
348 	source_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SOURCE);
349 
350 	if (format->pad) {
351 		*source_fmt = *sink_fmt;
352 
353 		return 0;
354 	}
355 
356 	v4l_bound_align_image(&format->format.width, 1, 65536, 0,
357 			      &format->format.height, 1, 65536, 0, 0);
358 
359 	switch (format->format.code) {
360 	case MEDIA_BUS_FMT_RGB444_1X12:
361 	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE:
362 	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE:
363 	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
364 	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
365 	case MEDIA_BUS_FMT_RGB565_1X16:
366 	case MEDIA_BUS_FMT_BGR565_2X8_BE:
367 	case MEDIA_BUS_FMT_BGR565_2X8_LE:
368 	case MEDIA_BUS_FMT_RGB565_2X8_BE:
369 	case MEDIA_BUS_FMT_RGB565_2X8_LE:
370 	case MEDIA_BUS_FMT_RGB666_1X18:
371 	case MEDIA_BUS_FMT_RBG888_1X24:
372 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
373 	case MEDIA_BUS_FMT_BGR888_1X24:
374 	case MEDIA_BUS_FMT_GBR888_1X24:
375 	case MEDIA_BUS_FMT_RGB888_1X24:
376 	case MEDIA_BUS_FMT_RGB888_2X12_BE:
377 	case MEDIA_BUS_FMT_RGB888_2X12_LE:
378 	case MEDIA_BUS_FMT_ARGB8888_1X32:
379 	case MEDIA_BUS_FMT_RGB888_1X32_PADHI:
380 	case MEDIA_BUS_FMT_RGB101010_1X30:
381 	case MEDIA_BUS_FMT_RGB121212_1X36:
382 	case MEDIA_BUS_FMT_RGB161616_1X48:
383 	case MEDIA_BUS_FMT_Y8_1X8:
384 	case MEDIA_BUS_FMT_UV8_1X8:
385 	case MEDIA_BUS_FMT_UYVY8_1_5X8:
386 	case MEDIA_BUS_FMT_VYUY8_1_5X8:
387 	case MEDIA_BUS_FMT_YUYV8_1_5X8:
388 	case MEDIA_BUS_FMT_YVYU8_1_5X8:
389 	case MEDIA_BUS_FMT_UYVY8_2X8:
390 	case MEDIA_BUS_FMT_VYUY8_2X8:
391 	case MEDIA_BUS_FMT_YUYV8_2X8:
392 	case MEDIA_BUS_FMT_YVYU8_2X8:
393 	case MEDIA_BUS_FMT_Y10_1X10:
394 	case MEDIA_BUS_FMT_UYVY10_2X10:
395 	case MEDIA_BUS_FMT_VYUY10_2X10:
396 	case MEDIA_BUS_FMT_YUYV10_2X10:
397 	case MEDIA_BUS_FMT_YVYU10_2X10:
398 	case MEDIA_BUS_FMT_Y12_1X12:
399 	case MEDIA_BUS_FMT_UYVY12_2X12:
400 	case MEDIA_BUS_FMT_VYUY12_2X12:
401 	case MEDIA_BUS_FMT_YUYV12_2X12:
402 	case MEDIA_BUS_FMT_YVYU12_2X12:
403 	case MEDIA_BUS_FMT_UYVY8_1X16:
404 	case MEDIA_BUS_FMT_VYUY8_1X16:
405 	case MEDIA_BUS_FMT_YUYV8_1X16:
406 	case MEDIA_BUS_FMT_YVYU8_1X16:
407 	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
408 	case MEDIA_BUS_FMT_UYVY10_1X20:
409 	case MEDIA_BUS_FMT_VYUY10_1X20:
410 	case MEDIA_BUS_FMT_YUYV10_1X20:
411 	case MEDIA_BUS_FMT_YVYU10_1X20:
412 	case MEDIA_BUS_FMT_VUY8_1X24:
413 	case MEDIA_BUS_FMT_YUV8_1X24:
414 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
415 	case MEDIA_BUS_FMT_UYVY12_1X24:
416 	case MEDIA_BUS_FMT_VYUY12_1X24:
417 	case MEDIA_BUS_FMT_YUYV12_1X24:
418 	case MEDIA_BUS_FMT_YVYU12_1X24:
419 	case MEDIA_BUS_FMT_YUV10_1X30:
420 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
421 	case MEDIA_BUS_FMT_AYUV8_1X32:
422 	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
423 	case MEDIA_BUS_FMT_YUV12_1X36:
424 	case MEDIA_BUS_FMT_YUV16_1X48:
425 	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
426 	case MEDIA_BUS_FMT_JPEG_1X8:
427 	case MEDIA_BUS_FMT_AHSV8888_1X32:
428 	case MEDIA_BUS_FMT_SBGGR8_1X8:
429 	case MEDIA_BUS_FMT_SGBRG8_1X8:
430 	case MEDIA_BUS_FMT_SGRBG8_1X8:
431 	case MEDIA_BUS_FMT_SRGGB8_1X8:
432 	case MEDIA_BUS_FMT_SBGGR10_1X10:
433 	case MEDIA_BUS_FMT_SGBRG10_1X10:
434 	case MEDIA_BUS_FMT_SGRBG10_1X10:
435 	case MEDIA_BUS_FMT_SRGGB10_1X10:
436 	case MEDIA_BUS_FMT_SBGGR12_1X12:
437 	case MEDIA_BUS_FMT_SGBRG12_1X12:
438 	case MEDIA_BUS_FMT_SGRBG12_1X12:
439 	case MEDIA_BUS_FMT_SRGGB12_1X12:
440 	case MEDIA_BUS_FMT_SBGGR14_1X14:
441 	case MEDIA_BUS_FMT_SGBRG14_1X14:
442 	case MEDIA_BUS_FMT_SGRBG14_1X14:
443 	case MEDIA_BUS_FMT_SRGGB14_1X14:
444 	case MEDIA_BUS_FMT_SBGGR16_1X16:
445 	case MEDIA_BUS_FMT_SGBRG16_1X16:
446 	case MEDIA_BUS_FMT_SGRBG16_1X16:
447 	case MEDIA_BUS_FMT_SRGGB16_1X16:
448 		break;
449 	default:
450 		format->format.code = MEDIA_BUS_FMT_Y8_1X8;
451 		break;
452 	}
453 
454 	if (format->format.field == V4L2_FIELD_ANY)
455 		format->format.field = V4L2_FIELD_NONE;
456 
457 	*sink_fmt = format->format;
458 	*source_fmt = *sink_fmt;
459 
460 	return 0;
461 }
462 
mei_csi_get_mbus_config(struct v4l2_subdev * sd,unsigned int pad,struct v4l2_mbus_config * mbus_config)463 static int mei_csi_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
464 				   struct v4l2_mbus_config *mbus_config)
465 {
466 	struct mei_csi *csi = sd_to_csi(sd);
467 	unsigned int i;
468 	s64 freq;
469 
470 	mbus_config->type = V4L2_MBUS_CSI2_DPHY;
471 	for (i = 0; i < V4L2_MBUS_CSI2_MAX_DATA_LANES; i++)
472 		mbus_config->bus.mipi_csi2.data_lanes[i] = i + 1;
473 	mbus_config->bus.mipi_csi2.num_data_lanes = csi->nr_of_lanes;
474 
475 	freq = v4l2_get_link_freq(csi->remote, 0, 0);
476 	if (freq < 0) {
477 		dev_err(&csi->cldev->dev,
478 			"error %lld, invalid link_freq\n", freq);
479 		return -EINVAL;
480 	}
481 
482 	csi->link_freq = freq;
483 	mbus_config->link_freq = freq;
484 
485 	return 0;
486 }
487 
488 static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
489 	.s_stream = mei_csi_set_stream,
490 };
491 
492 static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
493 	.get_fmt = v4l2_subdev_get_fmt,
494 	.set_fmt = mei_csi_set_fmt,
495 	.get_mbus_config = mei_csi_get_mbus_config,
496 };
497 
498 static const struct v4l2_subdev_ops mei_csi_subdev_ops = {
499 	.video = &mei_csi_video_ops,
500 	.pad = &mei_csi_pad_ops,
501 };
502 
503 static const struct v4l2_subdev_internal_ops mei_csi_internal_ops = {
504 	.init_state = mei_csi_init_state,
505 };
506 
507 static const struct media_entity_operations mei_csi_entity_ops = {
508 	.link_validate = v4l2_subdev_link_validate,
509 };
510 
mei_csi_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_connection * asd)511 static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
512 				struct v4l2_subdev *subdev,
513 				struct v4l2_async_connection *asd)
514 {
515 	struct mei_csi *csi = notifier_to_csi(notifier);
516 	int pad;
517 
518 	pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
519 					  MEDIA_PAD_FL_SOURCE);
520 	if (pad < 0)
521 		return pad;
522 
523 	csi->remote = &subdev->entity.pads[pad];
524 
525 	return media_create_pad_link(&subdev->entity, pad,
526 				     &csi->subdev.entity, CSI_PAD_SINK,
527 				     MEDIA_LNK_FL_ENABLED |
528 				     MEDIA_LNK_FL_IMMUTABLE);
529 }
530 
mei_csi_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_connection * asd)531 static void mei_csi_notify_unbind(struct v4l2_async_notifier *notifier,
532 				  struct v4l2_subdev *subdev,
533 				  struct v4l2_async_connection *asd)
534 {
535 	struct mei_csi *csi = notifier_to_csi(notifier);
536 
537 	csi->remote = NULL;
538 }
539 
540 static const struct v4l2_async_notifier_operations mei_csi_notify_ops = {
541 	.bound = mei_csi_notify_bound,
542 	.unbind = mei_csi_notify_unbind,
543 };
544 
mei_csi_init_controls(struct mei_csi * csi)545 static int mei_csi_init_controls(struct mei_csi *csi)
546 {
547 	int ret;
548 
549 	mutex_init(&csi->ctrl_lock);
550 
551 	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 1);
552 	if (ret)
553 		return ret;
554 
555 	csi->ctrl_handler.lock = &csi->ctrl_lock;
556 
557 	csi->privacy_ctrl = v4l2_ctrl_new_std(&csi->ctrl_handler, NULL,
558 					      V4L2_CID_PRIVACY, 0, 1, 1, 0);
559 	if (csi->privacy_ctrl)
560 		csi->privacy_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
561 
562 	if (csi->ctrl_handler.error)
563 		return csi->ctrl_handler.error;
564 
565 	csi->subdev.ctrl_handler = &csi->ctrl_handler;
566 
567 	return 0;
568 }
569 
mei_csi_parse_firmware(struct mei_csi * csi)570 static int mei_csi_parse_firmware(struct mei_csi *csi)
571 {
572 	struct v4l2_fwnode_endpoint v4l2_ep = {
573 		.bus_type = V4L2_MBUS_CSI2_DPHY,
574 	};
575 	struct device *dev = &csi->cldev->dev;
576 	struct v4l2_async_connection *asd;
577 	struct fwnode_handle *sink_ep, *source_ep;
578 	int ret;
579 
580 	sink_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
581 	if (!sink_ep) {
582 		dev_err(dev, "can't obtain sink endpoint\n");
583 		return -EINVAL;
584 	}
585 
586 	v4l2_async_subdev_nf_init(&csi->notifier, &csi->subdev);
587 	csi->notifier.ops = &mei_csi_notify_ops;
588 
589 	ret = v4l2_fwnode_endpoint_parse(sink_ep, &v4l2_ep);
590 	if (ret) {
591 		dev_err(dev, "could not parse v4l2 sink endpoint\n");
592 		goto out_nf_cleanup;
593 	}
594 
595 	csi->nr_of_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
596 
597 	source_ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 1, 0, 0);
598 	if (!source_ep) {
599 		ret = -ENOTCONN;
600 		dev_err(dev, "can't obtain source endpoint\n");
601 		goto out_nf_cleanup;
602 	}
603 
604 	ret = v4l2_fwnode_endpoint_parse(source_ep, &v4l2_ep);
605 	fwnode_handle_put(source_ep);
606 	if (ret) {
607 		dev_err(dev, "could not parse v4l2 source endpoint\n");
608 		goto out_nf_cleanup;
609 	}
610 
611 	if (csi->nr_of_lanes != v4l2_ep.bus.mipi_csi2.num_data_lanes) {
612 		ret = -EINVAL;
613 		dev_err(dev,
614 			"the number of lanes does not match (%u vs. %u)\n",
615 			csi->nr_of_lanes, v4l2_ep.bus.mipi_csi2.num_data_lanes);
616 		goto out_nf_cleanup;
617 	}
618 
619 	asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, sink_ep,
620 					      struct v4l2_async_connection);
621 	if (IS_ERR(asd)) {
622 		ret = PTR_ERR(asd);
623 		goto out_nf_cleanup;
624 	}
625 
626 	ret = v4l2_async_nf_register(&csi->notifier);
627 	if (ret)
628 		goto out_nf_cleanup;
629 
630 	fwnode_handle_put(sink_ep);
631 
632 	return 0;
633 
634 out_nf_cleanup:
635 	v4l2_async_nf_cleanup(&csi->notifier);
636 	fwnode_handle_put(sink_ep);
637 
638 	return ret;
639 }
640 
mei_csi_probe(struct mei_cl_device * cldev,const struct mei_cl_device_id * id)641 static int mei_csi_probe(struct mei_cl_device *cldev,
642 			 const struct mei_cl_device_id *id)
643 {
644 	struct device *dev = &cldev->dev;
645 	struct pci_dev *ipu;
646 	struct mei_csi *csi;
647 	unsigned int i;
648 	int ret;
649 
650 	for (i = 0, ipu = NULL; !ipu && ipu6_pci_tbl[i].vendor; i++)
651 		ipu = pci_get_device(ipu6_pci_tbl[i].vendor,
652 				     ipu6_pci_tbl[i].device, NULL);
653 
654 	if (!ipu)
655 		return -ENODEV;
656 
657 	ret = ipu_bridge_init(&ipu->dev, ipu_bridge_parse_ssdb);
658 	put_device(&ipu->dev);
659 	if (ret < 0)
660 		return ret;
661 	if (!dev_fwnode(dev)) {
662 		dev_err(dev, "mei-csi probed without device fwnode!\n");
663 		return -ENXIO;
664 	}
665 
666 	csi = devm_kzalloc(dev, sizeof(struct mei_csi), GFP_KERNEL);
667 	if (!csi)
668 		return -ENOMEM;
669 
670 	csi->cldev = cldev;
671 	mutex_init(&csi->lock);
672 	init_completion(&csi->cmd_completion);
673 
674 	mei_cldev_set_drvdata(cldev, csi);
675 
676 	ret = mei_cldev_enable(cldev);
677 	if (ret < 0) {
678 		dev_err(dev, "mei_cldev_enable failed: %d\n", ret);
679 		goto destroy_mutex;
680 	}
681 
682 	ret = mei_cldev_register_rx_cb(cldev, mei_csi_rx);
683 	if (ret) {
684 		dev_err(dev, "event cb registration failed: %d\n", ret);
685 		goto err_disable;
686 	}
687 
688 	ret = mei_csi_parse_firmware(csi);
689 	if (ret)
690 		goto err_disable;
691 
692 	csi->subdev.dev = &cldev->dev;
693 	csi->subdev.state_lock = &csi->lock;
694 	v4l2_subdev_init(&csi->subdev, &mei_csi_subdev_ops);
695 	csi->subdev.internal_ops = &mei_csi_internal_ops;
696 	v4l2_set_subdevdata(&csi->subdev, csi);
697 	csi->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE |
698 			    V4L2_SUBDEV_FL_HAS_EVENTS;
699 	csi->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
700 	csi->subdev.entity.ops = &mei_csi_entity_ops;
701 
702 	snprintf(csi->subdev.name, sizeof(csi->subdev.name),
703 		 MEI_CSI_ENTITY_NAME);
704 
705 	ret = mei_csi_init_controls(csi);
706 	if (ret)
707 		goto err_ctrl_handler;
708 
709 	csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
710 	csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
711 	ret = media_entity_pads_init(&csi->subdev.entity, CSI_NUM_PADS,
712 				     csi->pads);
713 	if (ret)
714 		goto err_ctrl_handler;
715 
716 	ret = v4l2_subdev_init_finalize(&csi->subdev);
717 	if (ret < 0)
718 		goto err_entity;
719 
720 	ret = v4l2_async_register_subdev(&csi->subdev);
721 	if (ret < 0)
722 		goto err_subdev;
723 
724 	pm_runtime_enable(&cldev->dev);
725 
726 	return 0;
727 
728 err_subdev:
729 	v4l2_subdev_cleanup(&csi->subdev);
730 
731 err_entity:
732 	media_entity_cleanup(&csi->subdev.entity);
733 
734 err_ctrl_handler:
735 	v4l2_ctrl_handler_free(&csi->ctrl_handler);
736 	mutex_destroy(&csi->ctrl_lock);
737 	v4l2_async_nf_unregister(&csi->notifier);
738 	v4l2_async_nf_cleanup(&csi->notifier);
739 
740 err_disable:
741 	mei_cldev_disable(cldev);
742 
743 destroy_mutex:
744 	mutex_destroy(&csi->lock);
745 
746 	return ret;
747 }
748 
mei_csi_remove(struct mei_cl_device * cldev)749 static void mei_csi_remove(struct mei_cl_device *cldev)
750 {
751 	struct mei_csi *csi = mei_cldev_get_drvdata(cldev);
752 
753 	v4l2_async_nf_unregister(&csi->notifier);
754 	v4l2_async_nf_cleanup(&csi->notifier);
755 	v4l2_ctrl_handler_free(&csi->ctrl_handler);
756 	mutex_destroy(&csi->ctrl_lock);
757 	v4l2_async_unregister_subdev(&csi->subdev);
758 	v4l2_subdev_cleanup(&csi->subdev);
759 	media_entity_cleanup(&csi->subdev.entity);
760 
761 	pm_runtime_disable(&cldev->dev);
762 
763 	mutex_destroy(&csi->lock);
764 }
765 
766 #define MEI_CSI_UUID UUID_LE(0x92335FCF, 0x3203, 0x4472, \
767 			     0xAF, 0x93, 0x7b, 0x44, 0x53, 0xAC, 0x29, 0xDA)
768 
769 static const struct mei_cl_device_id mei_csi_tbl[] = {
770 	{ .uuid = MEI_CSI_UUID, .version = MEI_CL_VERSION_ANY },
771 	{ /* sentinel */ }
772 };
773 MODULE_DEVICE_TABLE(mei, mei_csi_tbl);
774 
775 static struct mei_cl_driver mei_csi_driver = {
776 	.id_table = mei_csi_tbl,
777 	.name = KBUILD_MODNAME,
778 
779 	.probe = mei_csi_probe,
780 	.remove = mei_csi_remove,
781 };
782 
783 module_mei_cl_driver(mei_csi_driver);
784 
785 MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
786 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
787 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
788 MODULE_DESCRIPTION("Device driver for IVSC CSI");
789 MODULE_LICENSE("GPL");
790