1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Code to build software firmware node graph for atomisp2 connected sensors 4 * from ACPI tables. 5 * 6 * Copyright (C) 2023 Hans de Goede <hdegoede@redhat.com> 7 * 8 * Based on drivers/media/pci/intel/ipu3/cio2-bridge.c written by: 9 * Dan Scally <djrscally@gmail.com> 10 */ 11 12 #include <linux/acpi.h> 13 #include <linux/clk.h> 14 #include <linux/device.h> 15 #include <linux/dmi.h> 16 #include <linux/property.h> 17 18 #include <media/ipu-bridge.h> 19 #include <media/v4l2-fwnode.h> 20 21 #include "atomisp_cmd.h" 22 #include "atomisp_csi2.h" 23 #include "atomisp_internal.h" 24 25 #define PMC_CLK_RATE_19_2MHZ 19200000 26 27 /* 28 * 79234640-9e10-4fea-a5c1-b5aa8b19756f 29 * This _DSM GUID returns information about the GPIO lines mapped to a sensor. 30 * Function number 1 returns a count of the GPIO lines that are mapped. 31 * Subsequent functions return 32 bit ints encoding information about the GPIO. 32 */ 33 static const guid_t intel_sensor_gpio_info_guid = 34 GUID_INIT(0x79234640, 0x9e10, 0x4fea, 35 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f); 36 37 #define INTEL_GPIO_DSM_TYPE_SHIFT 0 38 #define INTEL_GPIO_DSM_TYPE_MASK GENMASK(7, 0) 39 #define INTEL_GPIO_DSM_PIN_SHIFT 8 40 #define INTEL_GPIO_DSM_PIN_MASK GENMASK(15, 8) 41 #define INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT 24 42 #define INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK GENMASK(31, 24) 43 44 #define INTEL_GPIO_DSM_TYPE(x) \ 45 (((x) & INTEL_GPIO_DSM_TYPE_MASK) >> INTEL_GPIO_DSM_TYPE_SHIFT) 46 #define INTEL_GPIO_DSM_PIN(x) \ 47 (((x) & INTEL_GPIO_DSM_PIN_MASK) >> INTEL_GPIO_DSM_PIN_SHIFT) 48 #define INTEL_GPIO_DSM_SENSOR_ON_VAL(x) \ 49 (((x) & INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK) >> INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT) 50 51 /* 52 * 822ace8f-2814-4174-a56b-5f029fe079ee 53 * This _DSM GUID returns a string from the sensor device, which acts as a 54 * module identifier. 55 */ 56 static const guid_t intel_sensor_module_guid = 57 GUID_INIT(0x822ace8f, 0x2814, 0x4174, 58 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee); 59 60 /* 61 * dc2f6c4f-045b-4f1d-97b9-882a6860a4be 62 * This _DSM GUID returns a package with n*2 strings, with each set of 2 strings 63 * forming a key, value pair for settings like e.g. "CsiLanes" = "1". 64 */ 65 static const guid_t atomisp_dsm_guid = 66 GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d, 67 0x97, 0xb9, 0x88, 0x2a, 0x68, 0x60, 0xa4, 0xbe); 68 69 /* 70 * 75c9a639-5c8a-4a00-9f48-a9c3b5da789f 71 * This _DSM GUID returns a string giving the VCM type e.g. "AD5823". 72 */ 73 static const guid_t vcm_dsm_guid = 74 GUID_INIT(0x75c9a639, 0x5c8a, 0x4a00, 75 0x9f, 0x48, 0xa9, 0xc3, 0xb5, 0xda, 0x78, 0x9f); 76 77 struct atomisp_sensor_config { 78 int lanes; 79 bool vcm; 80 }; 81 82 #define ATOMISP_SENSOR_CONFIG(_HID, _LANES, _VCM) \ 83 { \ 84 .id = _HID, \ 85 .driver_data = (long)&((const struct atomisp_sensor_config) { \ 86 .lanes = _LANES, \ 87 .vcm = _VCM, \ 88 }) \ 89 } 90 91 /* 92 * gmin_cfg parsing code. This is a cleaned up version of the gmin_cfg parsing 93 * code from atomisp_gmin_platform.c. 94 * Once all sensors are moved to v4l2-async probing atomisp_gmin_platform.c can 95 * be removed and the duplication of this code goes away. 96 */ 97 struct gmin_cfg_var { 98 const char *acpi_dev_name; 99 const char *key; 100 const char *val; 101 }; 102 103 static struct gmin_cfg_var lenovo_ideapad_miix_310_vars[] = { 104 /* _DSM contains the wrong CsiPort! */ 105 { "OVTI2680:01", "CsiPort", "0" }, 106 {} 107 }; 108 109 static const struct dmi_system_id gmin_cfg_dmi_overrides[] = { 110 { 111 /* Lenovo Ideapad Miix 310 */ 112 .matches = { 113 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 114 DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10"), 115 }, 116 .driver_data = lenovo_ideapad_miix_310_vars, 117 }, 118 {} 119 }; 120 121 static char *gmin_cfg_get_dsm(struct acpi_device *adev, const char *key) 122 { 123 union acpi_object *obj, *key_el, *val_el; 124 char *val = NULL; 125 int i; 126 127 obj = acpi_evaluate_dsm_typed(adev->handle, &atomisp_dsm_guid, 0, 0, 128 NULL, ACPI_TYPE_PACKAGE); 129 if (!obj) 130 return NULL; 131 132 for (i = 0; i < obj->package.count - 1; i += 2) { 133 key_el = &obj->package.elements[i + 0]; 134 val_el = &obj->package.elements[i + 1]; 135 136 if (key_el->type != ACPI_TYPE_STRING || val_el->type != ACPI_TYPE_STRING) 137 break; 138 139 if (!strcmp(key_el->string.pointer, key)) { 140 val = kstrdup(val_el->string.pointer, GFP_KERNEL); 141 if (!val) 142 break; 143 144 acpi_handle_info(adev->handle, "%s: Using DSM entry %s=%s\n", 145 dev_name(&adev->dev), key, val); 146 break; 147 } 148 } 149 150 ACPI_FREE(obj); 151 return val; 152 } 153 154 static char *gmin_cfg_get_dmi_override(struct acpi_device *adev, const char *key) 155 { 156 const struct dmi_system_id *id; 157 struct gmin_cfg_var *gv; 158 159 id = dmi_first_match(gmin_cfg_dmi_overrides); 160 if (!id) 161 return NULL; 162 163 for (gv = id->driver_data; gv->acpi_dev_name; gv++) { 164 if (strcmp(gv->acpi_dev_name, acpi_dev_name(adev))) 165 continue; 166 167 if (strcmp(key, gv->key)) 168 continue; 169 170 acpi_handle_info(adev->handle, "%s: Using DMI entry %s=%s\n", 171 dev_name(&adev->dev), key, gv->val); 172 return kstrdup(gv->val, GFP_KERNEL); 173 } 174 175 return NULL; 176 } 177 178 static char *gmin_cfg_get(struct acpi_device *adev, const char *key) 179 { 180 char *val; 181 182 val = gmin_cfg_get_dmi_override(adev, key); 183 if (val) 184 return val; 185 186 return gmin_cfg_get_dsm(adev, key); 187 } 188 189 static int gmin_cfg_get_int(struct acpi_device *adev, const char *key, int default_val) 190 { 191 char *str_val; 192 long int_val; 193 int ret; 194 195 str_val = gmin_cfg_get(adev, key); 196 if (!str_val) 197 goto out_use_default; 198 199 ret = kstrtoul(str_val, 0, &int_val); 200 kfree(str_val); 201 if (ret) 202 goto out_use_default; 203 204 return int_val; 205 206 out_use_default: 207 acpi_handle_info(adev->handle, "%s: Using default %s=%d\n", 208 dev_name(&adev->dev), key, default_val); 209 return default_val; 210 } 211 212 static int atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(struct acpi_device *adev) 213 { 214 /* ACPI_PATH_SEGMENT_LENGTH is guaranteed to be big enough for name + 0 term. */ 215 char name[ACPI_PATH_SEGMENT_LENGTH]; 216 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 217 struct acpi_buffer b_name = { sizeof(name), name }; 218 union acpi_object *package, *element; 219 int i, ret = -ENOENT; 220 acpi_handle rhandle; 221 acpi_status status; 222 u8 clock_num; 223 224 status = acpi_evaluate_object_typed(adev->handle, "_PR0", NULL, &buffer, ACPI_TYPE_PACKAGE); 225 if (ACPI_FAILURE(status)) 226 return -ENOENT; 227 228 package = buffer.pointer; 229 for (i = 0; i < package->package.count; i++) { 230 element = &package->package.elements[i]; 231 232 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 233 continue; 234 235 rhandle = element->reference.handle; 236 if (!rhandle) 237 continue; 238 239 acpi_get_name(rhandle, ACPI_SINGLE_NAME, &b_name); 240 241 if (str_has_prefix(name, "CLK") && !kstrtou8(&name[3], 10, &clock_num) && 242 clock_num <= 4) { 243 ret = clock_num; 244 break; 245 } 246 } 247 248 ACPI_FREE(buffer.pointer); 249 250 if (ret < 0) 251 acpi_handle_warn(adev->handle, "%s: Could not find PMC clk in _PR0\n", 252 dev_name(&adev->dev)); 253 254 return ret; 255 } 256 257 static int atomisp_csi2_set_pmc_clk_freq(struct acpi_device *adev, int clock_num) 258 { 259 struct clk *clk; 260 char name[14]; 261 int ret; 262 263 if (clock_num < 0) 264 return 0; 265 266 snprintf(name, sizeof(name), "pmc_plt_clk_%d", clock_num); 267 268 clk = clk_get(NULL, name); 269 if (IS_ERR(clk)) { 270 ret = PTR_ERR(clk); 271 acpi_handle_err(adev->handle, "%s: Error getting clk %s: %d\n", 272 dev_name(&adev->dev), name, ret); 273 return ret; 274 } 275 276 /* 277 * The firmware might enable the clock at boot, to change 278 * the rate we must ensure the clock is disabled. 279 */ 280 ret = clk_prepare_enable(clk); 281 if (!ret) 282 clk_disable_unprepare(clk); 283 if (!ret) 284 ret = clk_set_rate(clk, PMC_CLK_RATE_19_2MHZ); 285 if (ret) 286 acpi_handle_err(adev->handle, "%s: Error setting clk-rate for %s: %d\n", 287 dev_name(&adev->dev), name, ret); 288 289 clk_put(clk); 290 return ret; 291 } 292 293 static int atomisp_csi2_get_port(struct acpi_device *adev, int clock_num) 294 { 295 int port; 296 297 /* 298 * Compare clock-number to the PMC-clock used for CsiPort 1 299 * in the CHT/BYT reference designs. 300 */ 301 if (IS_ISP2401) 302 port = clock_num == 4 ? 1 : 0; 303 else 304 port = clock_num == 0 ? 1 : 0; 305 306 /* Intel DSM or DMI quirk overrides _PR0 CLK derived default */ 307 return gmin_cfg_get_int(adev, "CsiPort", port); 308 } 309 310 /* Note this always returns 1 to continue looping so that res_count is accurate */ 311 static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_data) 312 { 313 struct atomisp_csi2_acpi_gpio_parsing_data *data = _data; 314 struct acpi_resource_gpio *agpio; 315 const char *name; 316 bool active_low; 317 unsigned int i; 318 u32 settings = 0; 319 u16 pin; 320 321 if (!acpi_gpio_get_io_resource(ares, &agpio)) 322 return 1; /* Not a GPIO, continue the loop */ 323 324 data->res_count++; 325 326 pin = agpio->pin_table[0]; 327 for (i = 0; i < data->settings_count; i++) { 328 if (INTEL_GPIO_DSM_PIN(data->settings[i]) == pin) { 329 settings = data->settings[i]; 330 break; 331 } 332 } 333 334 if (i == data->settings_count) { 335 acpi_handle_warn(data->adev->handle, 336 "%s: Could not find DSM GPIO settings for pin %u\n", 337 dev_name(&data->adev->dev), pin); 338 return 1; 339 } 340 341 switch (INTEL_GPIO_DSM_TYPE(settings)) { 342 case 0: 343 name = "reset-gpios"; 344 break; 345 case 1: 346 name = "powerdown-gpios"; 347 break; 348 default: 349 acpi_handle_warn(data->adev->handle, "%s: Unknown GPIO type 0x%02lx for pin %u\n", 350 dev_name(&data->adev->dev), 351 INTEL_GPIO_DSM_TYPE(settings), pin); 352 return 1; 353 } 354 355 /* 356 * Both reset and power-down need to be logical false when the sensor 357 * is on (sensor should not be in reset and not be powered-down). So 358 * when the sensor-on-value (which is the physical pin value) is high, 359 * then the signal is active-low. 360 */ 361 active_low = INTEL_GPIO_DSM_SENSOR_ON_VAL(settings); 362 363 i = data->map_count; 364 if (i == CSI2_MAX_ACPI_GPIOS) 365 return 1; 366 367 /* res_count is already incremented */ 368 data->map->params[i].crs_entry_index = data->res_count - 1; 369 data->map->params[i].active_low = active_low; 370 data->map->mapping[i].name = name; 371 data->map->mapping[i].data = &data->map->params[i]; 372 data->map->mapping[i].size = 1; 373 data->map_count++; 374 375 acpi_handle_info(data->adev->handle, "%s: %s crs %d %s pin %u active-%s\n", 376 dev_name(&data->adev->dev), name, 377 data->res_count - 1, agpio->resource_source.string_ptr, 378 pin, active_low ? "low" : "high"); 379 380 return 1; 381 } 382 383 /* 384 * Helper function to create an ACPI GPIO lookup table for sensor reset and 385 * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices, 386 * including setting the correct polarity for the GPIO. 387 * 388 * This uses the "79234640-9e10-4fea-a5c1-b5aa8b19756f" DSM method directly 389 * on the sensor device's ACPI node. This is different from later Intel 390 * hardware which has a separate INT3472 acpi_device with this info. 391 * 392 * This function must be called before creating the sw-noded describing 393 * the fwnode graph endpoint. And sensor drivers used on these devices 394 * must return -EPROBE_DEFER when there is no endpoint description yet. 395 * Together this guarantees that the GPIO lookups are in place before 396 * the sensor driver tries to get GPIOs with gpiod_get(). 397 * 398 * Note this code uses the same DSM GUID as the int3472_gpio_guid in 399 * the INT3472 discrete.c code and there is some overlap, but there are 400 * enough differences that it is difficult to share the code. 401 */ 402 static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev) 403 { 404 struct atomisp_csi2_acpi_gpio_parsing_data data = { }; 405 LIST_HEAD(resource_list); 406 union acpi_object *obj; 407 unsigned int i, j; 408 int ret; 409 410 obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid, 411 0x00, 1, NULL, ACPI_TYPE_STRING); 412 if (obj) { 413 acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n", 414 dev_name(&adev->dev), obj->string.pointer); 415 ACPI_FREE(obj); 416 } 417 418 /* 419 * First get the GPIO-settings count and then get count GPIO-settings 420 * values. Note the order of these may differ from the order in which 421 * the GPIOs are listed on the ACPI resources! So we first store them all 422 * and then enumerate the ACPI resources and match them up by pin number. 423 */ 424 obj = acpi_evaluate_dsm_typed(adev->handle, 425 &intel_sensor_gpio_info_guid, 0x00, 1, 426 NULL, ACPI_TYPE_INTEGER); 427 if (!obj) { 428 acpi_handle_err(adev->handle, "%s: No _DSM entry for GPIO pin count\n", 429 dev_name(&adev->dev)); 430 return -EIO; 431 } 432 433 data.settings_count = obj->integer.value; 434 ACPI_FREE(obj); 435 436 if (data.settings_count > CSI2_MAX_ACPI_GPIOS) { 437 acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n", 438 dev_name(&adev->dev), data.settings_count, 439 CSI2_MAX_ACPI_GPIOS); 440 return -EOVERFLOW; 441 } 442 443 for (i = 0; i < data.settings_count; i++) { 444 /* 445 * i + 2 because the index of this _DSM function is 1-based 446 * and the first function is just a count. 447 */ 448 obj = acpi_evaluate_dsm_typed(adev->handle, 449 &intel_sensor_gpio_info_guid, 450 0x00, i + 2, 451 NULL, ACPI_TYPE_INTEGER); 452 if (!obj) { 453 acpi_handle_err(adev->handle, "%s: No _DSM entry for pin %u\n", 454 dev_name(&adev->dev), i); 455 return -EIO; 456 } 457 458 data.settings[i] = obj->integer.value; 459 ACPI_FREE(obj); 460 } 461 462 /* Since we match up by pin-number the pin-numbers must be unique */ 463 for (i = 0; i < data.settings_count; i++) { 464 for (j = i + 1; j < data.settings_count; j++) { 465 if (INTEL_GPIO_DSM_PIN(data.settings[i]) != 466 INTEL_GPIO_DSM_PIN(data.settings[j])) 467 continue; 468 469 acpi_handle_err(adev->handle, "%s: Duplicate pin number %lu\n", 470 dev_name(&adev->dev), 471 INTEL_GPIO_DSM_PIN(data.settings[i])); 472 return -EIO; 473 } 474 } 475 476 data.map = kzalloc(sizeof(*data.map), GFP_KERNEL); 477 if (!data.map) 478 return -ENOMEM; 479 480 /* Now parse the ACPI resources and build the lookup table */ 481 data.adev = adev; 482 ret = acpi_dev_get_resources(adev, &resource_list, 483 atomisp_csi2_handle_acpi_gpio_res, &data); 484 if (ret < 0) 485 return ret; 486 487 acpi_dev_free_resource_list(&resource_list); 488 489 if (data.map_count != data.settings_count || 490 data.res_count != data.settings_count) 491 acpi_handle_warn(adev->handle, "%s: ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n", 492 dev_name(&adev->dev), data.settings_count, 493 data.res_count, data.map_count); 494 495 ret = acpi_dev_add_driver_gpios(adev, data.map->mapping); 496 if (ret) 497 acpi_handle_err(adev->handle, "%s: Error adding driver GPIOs: %d\n", 498 dev_name(&adev->dev), ret); 499 500 return ret; 501 } 502 503 static char *atomisp_csi2_get_vcm_type(struct acpi_device *adev) 504 { 505 union acpi_object *obj; 506 char *vcm_type; 507 508 obj = acpi_evaluate_dsm_typed(adev->handle, &vcm_dsm_guid, 0, 0, 509 NULL, ACPI_TYPE_STRING); 510 if (!obj) 511 return NULL; 512 513 vcm_type = kstrdup(obj->string.pointer, GFP_KERNEL); 514 ACPI_FREE(obj); 515 516 if (!vcm_type) 517 return NULL; 518 519 string_lower(vcm_type, vcm_type); 520 return vcm_type; 521 } 522 523 static const struct acpi_device_id atomisp_sensor_configs[] = { 524 ATOMISP_SENSOR_CONFIG("INT33BE", 2, true), /* OV5693 */ 525 {} 526 }; 527 528 static int atomisp_csi2_parse_sensor_fwnode(struct acpi_device *adev, 529 struct ipu_sensor *sensor) 530 { 531 const struct acpi_device_id *id; 532 int ret, clock_num; 533 bool vcm = false; 534 int lanes = 1; 535 536 id = acpi_match_acpi_device(atomisp_sensor_configs, adev); 537 if (id) { 538 struct atomisp_sensor_config *cfg = 539 (struct atomisp_sensor_config *)id->driver_data; 540 541 lanes = cfg->lanes; 542 vcm = cfg->vcm; 543 } 544 545 /* 546 * ACPI takes care of turning the PMC clock on and off, but on BYT 547 * the clock defaults to 25 MHz instead of the expected 19.2 MHz. 548 * Get the PMC-clock number from ACPI PR0 method and set it to 19.2 MHz. 549 * The PMC-clock number is also used to determine the default CSI port. 550 */ 551 clock_num = atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(adev); 552 553 ret = atomisp_csi2_set_pmc_clk_freq(adev, clock_num); 554 if (ret) 555 return ret; 556 557 sensor->link = atomisp_csi2_get_port(adev, clock_num); 558 if (sensor->link >= ATOMISP_CAMERA_NR_PORTS) { 559 acpi_handle_err(adev->handle, "%s: Invalid port: %u\n", 560 dev_name(&adev->dev), sensor->link); 561 return -EINVAL; 562 } 563 564 sensor->lanes = gmin_cfg_get_int(adev, "CsiLanes", lanes); 565 if (sensor->lanes > IPU_MAX_LANES) { 566 acpi_handle_err(adev->handle, "%s: Invalid lane-count: %d\n", 567 dev_name(&adev->dev), sensor->lanes); 568 return -EINVAL; 569 } 570 571 ret = atomisp_csi2_add_gpio_mappings(adev); 572 if (ret) 573 return ret; 574 575 sensor->mclkspeed = PMC_CLK_RATE_19_2MHZ; 576 sensor->rotation = 0; 577 sensor->orientation = (sensor->link == 1) ? 578 V4L2_FWNODE_ORIENTATION_BACK : V4L2_FWNODE_ORIENTATION_FRONT; 579 580 if (vcm) 581 sensor->vcm_type = atomisp_csi2_get_vcm_type(adev); 582 583 return 0; 584 } 585 586 int atomisp_csi2_bridge_init(struct atomisp_device *isp) 587 { 588 struct device *dev = isp->dev; 589 struct fwnode_handle *fwnode; 590 591 /* 592 * This function is intended to run only once and then leave 593 * the created nodes attached even after a rmmod, therefore: 594 * 1. The bridge memory is leaked deliberately on success 595 * 2. If a secondary fwnode is already set exit early. 596 */ 597 fwnode = dev_fwnode(dev); 598 if (fwnode && fwnode->secondary) 599 return 0; 600 601 return ipu_bridge_init(dev, atomisp_csi2_parse_sensor_fwnode); 602 } 603 604 /******* V4L2 sub-device asynchronous registration callbacks***********/ 605 606 struct sensor_async_subdev { 607 struct v4l2_async_connection asd; 608 int port; 609 }; 610 611 #define to_sensor_asd(a) container_of(a, struct sensor_async_subdev, asd) 612 #define notifier_to_atomisp(n) container_of(n, struct atomisp_device, notifier) 613 614 /* .bound() notifier callback when a match is found */ 615 static int atomisp_notifier_bound(struct v4l2_async_notifier *notifier, 616 struct v4l2_subdev *sd, 617 struct v4l2_async_connection *asd) 618 { 619 struct atomisp_device *isp = notifier_to_atomisp(notifier); 620 struct sensor_async_subdev *s_asd = to_sensor_asd(asd); 621 int ret; 622 623 if (s_asd->port >= ATOMISP_CAMERA_NR_PORTS) { 624 dev_err(isp->dev, "port %d not supported\n", s_asd->port); 625 return -EINVAL; 626 } 627 628 if (isp->sensor_subdevs[s_asd->port]) { 629 dev_err(isp->dev, "port %d already has a sensor attached\n", s_asd->port); 630 return -EBUSY; 631 } 632 633 ret = ipu_bridge_instantiate_vcm(sd->dev); 634 if (ret) 635 return ret; 636 637 isp->sensor_subdevs[s_asd->port] = sd; 638 return 0; 639 } 640 641 /* The .unbind callback */ 642 static void atomisp_notifier_unbind(struct v4l2_async_notifier *notifier, 643 struct v4l2_subdev *sd, 644 struct v4l2_async_connection *asd) 645 { 646 struct atomisp_device *isp = notifier_to_atomisp(notifier); 647 struct sensor_async_subdev *s_asd = to_sensor_asd(asd); 648 649 isp->sensor_subdevs[s_asd->port] = NULL; 650 } 651 652 /* .complete() is called after all subdevices have been located */ 653 static int atomisp_notifier_complete(struct v4l2_async_notifier *notifier) 654 { 655 struct atomisp_device *isp = notifier_to_atomisp(notifier); 656 657 return atomisp_register_device_nodes(isp); 658 } 659 660 static const struct v4l2_async_notifier_operations atomisp_async_ops = { 661 .bound = atomisp_notifier_bound, 662 .unbind = atomisp_notifier_unbind, 663 .complete = atomisp_notifier_complete, 664 }; 665 666 int atomisp_csi2_bridge_parse_firmware(struct atomisp_device *isp) 667 { 668 int i, mipi_port, ret; 669 670 v4l2_async_nf_init(&isp->notifier, &isp->v4l2_dev); 671 isp->notifier.ops = &atomisp_async_ops; 672 673 for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { 674 struct v4l2_fwnode_endpoint vep = { 675 .bus_type = V4L2_MBUS_CSI2_DPHY, 676 }; 677 struct sensor_async_subdev *s_asd; 678 struct fwnode_handle *ep; 679 680 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(isp->dev), i, 0, 681 FWNODE_GRAPH_ENDPOINT_NEXT); 682 if (!ep) 683 continue; 684 685 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 686 if (ret) 687 goto err_parse; 688 689 if (vep.base.port >= ATOMISP_CAMERA_NR_PORTS) { 690 dev_err(isp->dev, "port %d not supported\n", vep.base.port); 691 ret = -EINVAL; 692 goto err_parse; 693 } 694 695 mipi_port = atomisp_port_to_mipi_port(isp, vep.base.port); 696 isp->sensor_lanes[mipi_port] = vep.bus.mipi_csi2.num_data_lanes; 697 698 s_asd = v4l2_async_nf_add_fwnode_remote(&isp->notifier, ep, 699 struct sensor_async_subdev); 700 if (IS_ERR(s_asd)) { 701 ret = PTR_ERR(s_asd); 702 goto err_parse; 703 } 704 705 s_asd->port = vep.base.port; 706 707 fwnode_handle_put(ep); 708 continue; 709 710 err_parse: 711 fwnode_handle_put(ep); 712 return ret; 713 } 714 715 return 0; 716 } 717