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