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