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