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 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 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 */ 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 */ 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 */ 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 */ 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 *)¬if, 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, ¬if, ret); 266 267 complete(&csi->cmd_completion); 268 break; 269 default: 270 break; 271 } 272 } 273 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 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 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 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 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 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 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 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 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 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