| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Analog Devices ADV7511 HDMI transmitter driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2012 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 8 | +#include <linux/clk.h> |
|---|
| 9 | 9 | #include <linux/device.h> |
|---|
| 10 | 10 | #include <linux/gpio/consumer.h> |
|---|
| 11 | 11 | #include <linux/module.h> |
|---|
| 12 | 12 | #include <linux/of_device.h> |
|---|
| 13 | 13 | #include <linux/slab.h> |
|---|
| 14 | | -#include <linux/clk.h> |
|---|
| 15 | 14 | |
|---|
| 16 | | -#include <drm/drmP.h> |
|---|
| 15 | +#include <media/cec.h> |
|---|
| 16 | + |
|---|
| 17 | 17 | #include <drm/drm_atomic.h> |
|---|
| 18 | 18 | #include <drm/drm_atomic_helper.h> |
|---|
| 19 | 19 | #include <drm/drm_edid.h> |
|---|
| 20 | | - |
|---|
| 21 | | -#include <media/cec.h> |
|---|
| 20 | +#include <drm/drm_print.h> |
|---|
| 21 | +#include <drm/drm_probe_helper.h> |
|---|
| 22 | 22 | |
|---|
| 23 | 23 | #include "adv7511.h" |
|---|
| 24 | 24 | |
|---|
| .. | .. |
|---|
| 351 | 351 | * from standby or are enabled. When the HPD goes low the adv7511 is |
|---|
| 352 | 352 | * reset and the outputs are disabled which might cause the monitor to |
|---|
| 353 | 353 | * go to standby again. To avoid this we ignore the HPD pin for the |
|---|
| 354 | | - * first few seconds after enabling the output. |
|---|
| 354 | + * first few seconds after enabling the output. On the other hand |
|---|
| 355 | + * adv7535 require to enable HPD Override bit for proper HPD. |
|---|
| 355 | 356 | */ |
|---|
| 356 | | - regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 357 | | - ADV7511_REG_POWER2_HPD_SRC_MASK, |
|---|
| 358 | | - ADV7511_REG_POWER2_HPD_SRC_NONE); |
|---|
| 357 | + if (adv7511->type == ADV7535) |
|---|
| 358 | + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 359 | + ADV7535_REG_POWER2_HPD_OVERRIDE, |
|---|
| 360 | + ADV7535_REG_POWER2_HPD_OVERRIDE); |
|---|
| 361 | + else |
|---|
| 362 | + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 363 | + ADV7511_REG_POWER2_HPD_SRC_MASK, |
|---|
| 364 | + ADV7511_REG_POWER2_HPD_SRC_NONE); |
|---|
| 365 | + |
|---|
| 366 | + /* HACK: If we don't delay here edid probing doesn't work properly */ |
|---|
| 367 | + msleep(200); |
|---|
| 359 | 368 | } |
|---|
| 360 | 369 | |
|---|
| 361 | 370 | static void adv7511_power_on(struct adv7511 *adv7511) |
|---|
| .. | .. |
|---|
| 367 | 376 | */ |
|---|
| 368 | 377 | regcache_sync(adv7511->regmap); |
|---|
| 369 | 378 | |
|---|
| 370 | | - if (adv7511->type == ADV7533) |
|---|
| 379 | + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) |
|---|
| 371 | 380 | adv7533_dsi_power_on(adv7511); |
|---|
| 372 | 381 | adv7511->powered = true; |
|---|
| 373 | 382 | } |
|---|
| .. | .. |
|---|
| 375 | 384 | static void __adv7511_power_off(struct adv7511 *adv7511) |
|---|
| 376 | 385 | { |
|---|
| 377 | 386 | /* TODO: setup additional power down modes */ |
|---|
| 387 | + if (adv7511->type == ADV7535) |
|---|
| 388 | + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 389 | + ADV7535_REG_POWER2_HPD_OVERRIDE, 0); |
|---|
| 390 | + |
|---|
| 378 | 391 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, |
|---|
| 379 | 392 | ADV7511_POWER_POWER_DOWN, |
|---|
| 380 | 393 | ADV7511_POWER_POWER_DOWN); |
|---|
| .. | .. |
|---|
| 387 | 400 | static void adv7511_power_off(struct adv7511 *adv7511) |
|---|
| 388 | 401 | { |
|---|
| 389 | 402 | __adv7511_power_off(adv7511); |
|---|
| 390 | | - if (adv7511->type == ADV7533) |
|---|
| 403 | + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) |
|---|
| 391 | 404 | adv7533_dsi_power_off(adv7511); |
|---|
| 392 | 405 | adv7511->powered = false; |
|---|
| 393 | 406 | } |
|---|
| .. | .. |
|---|
| 443 | 456 | |
|---|
| 444 | 457 | if (adv7511->connector.status != status) { |
|---|
| 445 | 458 | adv7511->connector.status = status; |
|---|
| 446 | | - if (status == connector_status_disconnected) |
|---|
| 447 | | - cec_phys_addr_invalidate(adv7511->cec_adap); |
|---|
| 448 | | - drm_kms_helper_hotplug_event(adv7511->connector.dev); |
|---|
| 459 | + |
|---|
| 460 | + if (adv7511->connector.dev) { |
|---|
| 461 | + if (status == connector_status_disconnected) |
|---|
| 462 | + cec_phys_addr_invalidate(adv7511->cec_adap); |
|---|
| 463 | + drm_kms_helper_hotplug_event(adv7511->connector.dev); |
|---|
| 464 | + } else { |
|---|
| 465 | + drm_bridge_hpd_notify(&adv7511->bridge, status); |
|---|
| 466 | + } |
|---|
| 449 | 467 | } |
|---|
| 450 | 468 | } |
|---|
| 451 | 469 | |
|---|
| .. | .. |
|---|
| 589 | 607 | * ADV75xx helpers |
|---|
| 590 | 608 | */ |
|---|
| 591 | 609 | |
|---|
| 592 | | -static int adv7511_get_modes(struct adv7511 *adv7511, |
|---|
| 593 | | - struct drm_connector *connector) |
|---|
| 610 | +static struct edid *adv7511_get_edid(struct adv7511 *adv7511, |
|---|
| 611 | + struct drm_connector *connector) |
|---|
| 594 | 612 | { |
|---|
| 595 | 613 | struct edid *edid; |
|---|
| 596 | | - unsigned int count; |
|---|
| 597 | 614 | |
|---|
| 598 | 615 | /* Reading the EDID only works if the device is powered */ |
|---|
| 599 | 616 | if (!adv7511->powered) { |
|---|
| .. | .. |
|---|
| 612 | 629 | if (!adv7511->powered) |
|---|
| 613 | 630 | __adv7511_power_off(adv7511); |
|---|
| 614 | 631 | |
|---|
| 615 | | - |
|---|
| 616 | | - drm_connector_update_edid_property(connector, edid); |
|---|
| 617 | | - count = drm_add_edid_modes(connector, edid); |
|---|
| 618 | | - |
|---|
| 619 | 632 | adv7511_set_config_csc(adv7511, connector, adv7511->rgb, |
|---|
| 620 | 633 | drm_detect_hdmi_monitor(edid)); |
|---|
| 621 | 634 | |
|---|
| 622 | 635 | cec_s_phys_addr_from_edid(adv7511->cec_adap, edid); |
|---|
| 636 | + |
|---|
| 637 | + return edid; |
|---|
| 638 | +} |
|---|
| 639 | + |
|---|
| 640 | +static int adv7511_get_modes(struct adv7511 *adv7511, |
|---|
| 641 | + struct drm_connector *connector) |
|---|
| 642 | +{ |
|---|
| 643 | + struct edid *edid; |
|---|
| 644 | + unsigned int count; |
|---|
| 645 | + |
|---|
| 646 | + edid = adv7511_get_edid(adv7511, connector); |
|---|
| 647 | + |
|---|
| 648 | + drm_connector_update_edid_property(connector, edid); |
|---|
| 649 | + count = drm_add_edid_modes(connector, edid); |
|---|
| 623 | 650 | |
|---|
| 624 | 651 | kfree(edid); |
|---|
| 625 | 652 | |
|---|
| .. | .. |
|---|
| 652 | 679 | if (status == connector_status_connected && hpd && adv7511->powered) { |
|---|
| 653 | 680 | regcache_mark_dirty(adv7511->regmap); |
|---|
| 654 | 681 | adv7511_power_on(adv7511); |
|---|
| 655 | | - adv7511_get_modes(adv7511, connector); |
|---|
| 682 | + if (connector) |
|---|
| 683 | + adv7511_get_modes(adv7511, connector); |
|---|
| 656 | 684 | if (adv7511->status == connector_status_connected) |
|---|
| 657 | 685 | status = connector_status_disconnected; |
|---|
| 658 | 686 | } else { |
|---|
| 659 | 687 | /* Renable HPD sensing */ |
|---|
| 660 | | - regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 661 | | - ADV7511_REG_POWER2_HPD_SRC_MASK, |
|---|
| 662 | | - ADV7511_REG_POWER2_HPD_SRC_BOTH); |
|---|
| 688 | + if (adv7511->type == ADV7535) |
|---|
| 689 | + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 690 | + ADV7535_REG_POWER2_HPD_OVERRIDE, |
|---|
| 691 | + ADV7535_REG_POWER2_HPD_OVERRIDE); |
|---|
| 692 | + else |
|---|
| 693 | + regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
|---|
| 694 | + ADV7511_REG_POWER2_HPD_SRC_MASK, |
|---|
| 695 | + ADV7511_REG_POWER2_HPD_SRC_BOTH); |
|---|
| 663 | 696 | } |
|---|
| 664 | 697 | |
|---|
| 665 | 698 | adv7511->status = status; |
|---|
| .. | .. |
|---|
| 676 | 709 | } |
|---|
| 677 | 710 | |
|---|
| 678 | 711 | static void adv7511_mode_set(struct adv7511 *adv7511, |
|---|
| 679 | | - struct drm_display_mode *mode, |
|---|
| 680 | | - struct drm_display_mode *adj_mode) |
|---|
| 712 | + const struct drm_display_mode *mode, |
|---|
| 713 | + const struct drm_display_mode *adj_mode) |
|---|
| 681 | 714 | { |
|---|
| 682 | 715 | unsigned int low_refresh_rate; |
|---|
| 683 | 716 | unsigned int hsync_polarity = 0; |
|---|
| .. | .. |
|---|
| 761 | 794 | regmap_update_bits(adv7511->regmap, 0x17, |
|---|
| 762 | 795 | 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); |
|---|
| 763 | 796 | |
|---|
| 764 | | - if (adv7511->type == ADV7533) |
|---|
| 797 | + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) |
|---|
| 765 | 798 | adv7533_mode_set(adv7511, adj_mode); |
|---|
| 766 | 799 | |
|---|
| 767 | 800 | drm_mode_copy(&adv7511->curr_mode, adj_mode); |
|---|
| .. | .. |
|---|
| 774 | 807 | adv7511->f_tmds = mode->clock; |
|---|
| 775 | 808 | } |
|---|
| 776 | 809 | |
|---|
| 777 | | -/* Connector funcs */ |
|---|
| 810 | +/* ----------------------------------------------------------------------------- |
|---|
| 811 | + * DRM Connector Operations |
|---|
| 812 | + */ |
|---|
| 813 | + |
|---|
| 778 | 814 | static struct adv7511 *connector_to_adv7511(struct drm_connector *connector) |
|---|
| 779 | 815 | { |
|---|
| 780 | 816 | return container_of(connector, struct adv7511, connector); |
|---|
| .. | .. |
|---|
| 818 | 854 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
|---|
| 819 | 855 | }; |
|---|
| 820 | 856 | |
|---|
| 821 | | -/* Bridge funcs */ |
|---|
| 857 | +static int adv7511_connector_init(struct adv7511 *adv) |
|---|
| 858 | +{ |
|---|
| 859 | + struct drm_bridge *bridge = &adv->bridge; |
|---|
| 860 | + int ret; |
|---|
| 861 | + |
|---|
| 862 | + if (!bridge->encoder) { |
|---|
| 863 | + DRM_ERROR("Parent encoder object not found"); |
|---|
| 864 | + return -ENODEV; |
|---|
| 865 | + } |
|---|
| 866 | + |
|---|
| 867 | + if (adv->i2c_main->irq) |
|---|
| 868 | + adv->connector.polled = DRM_CONNECTOR_POLL_HPD; |
|---|
| 869 | + else |
|---|
| 870 | + adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT | |
|---|
| 871 | + DRM_CONNECTOR_POLL_DISCONNECT; |
|---|
| 872 | + |
|---|
| 873 | + ret = drm_connector_init(bridge->dev, &adv->connector, |
|---|
| 874 | + &adv7511_connector_funcs, |
|---|
| 875 | + DRM_MODE_CONNECTOR_HDMIA); |
|---|
| 876 | + if (ret < 0) { |
|---|
| 877 | + DRM_ERROR("Failed to initialize connector with drm\n"); |
|---|
| 878 | + return ret; |
|---|
| 879 | + } |
|---|
| 880 | + drm_connector_helper_add(&adv->connector, |
|---|
| 881 | + &adv7511_connector_helper_funcs); |
|---|
| 882 | + drm_connector_attach_encoder(&adv->connector, bridge->encoder); |
|---|
| 883 | + |
|---|
| 884 | + return 0; |
|---|
| 885 | +} |
|---|
| 886 | + |
|---|
| 887 | +/* ----------------------------------------------------------------------------- |
|---|
| 888 | + * DRM Bridge Operations |
|---|
| 889 | + */ |
|---|
| 890 | + |
|---|
| 822 | 891 | static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge) |
|---|
| 823 | 892 | { |
|---|
| 824 | 893 | return container_of(bridge, struct adv7511, bridge); |
|---|
| .. | .. |
|---|
| 839 | 908 | } |
|---|
| 840 | 909 | |
|---|
| 841 | 910 | static void adv7511_bridge_mode_set(struct drm_bridge *bridge, |
|---|
| 842 | | - struct drm_display_mode *mode, |
|---|
| 843 | | - struct drm_display_mode *adj_mode) |
|---|
| 911 | + const struct drm_display_mode *mode, |
|---|
| 912 | + const struct drm_display_mode *adj_mode) |
|---|
| 844 | 913 | { |
|---|
| 845 | 914 | struct adv7511 *adv = bridge_to_adv7511(bridge); |
|---|
| 846 | 915 | |
|---|
| 847 | 916 | adv7511_mode_set(adv, mode, adj_mode); |
|---|
| 848 | 917 | } |
|---|
| 849 | 918 | |
|---|
| 850 | | -static int adv7511_bridge_attach(struct drm_bridge *bridge) |
|---|
| 919 | +static int adv7511_bridge_attach(struct drm_bridge *bridge, |
|---|
| 920 | + enum drm_bridge_attach_flags flags) |
|---|
| 851 | 921 | { |
|---|
| 852 | 922 | struct adv7511 *adv = bridge_to_adv7511(bridge); |
|---|
| 853 | | - int ret; |
|---|
| 923 | + int ret = 0; |
|---|
| 854 | 924 | |
|---|
| 855 | | - if (!bridge->encoder) { |
|---|
| 856 | | - DRM_ERROR("Parent encoder object not found"); |
|---|
| 857 | | - return -ENODEV; |
|---|
| 925 | + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { |
|---|
| 926 | + ret = adv7511_connector_init(adv); |
|---|
| 927 | + if (ret < 0) |
|---|
| 928 | + return ret; |
|---|
| 858 | 929 | } |
|---|
| 859 | 930 | |
|---|
| 860 | | - if (adv->i2c_main->irq) |
|---|
| 861 | | - adv->connector.polled = DRM_CONNECTOR_POLL_HPD; |
|---|
| 862 | | - else |
|---|
| 863 | | - adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT | |
|---|
| 864 | | - DRM_CONNECTOR_POLL_DISCONNECT; |
|---|
| 865 | | - |
|---|
| 866 | | - ret = drm_connector_init(bridge->dev, &adv->connector, |
|---|
| 867 | | - &adv7511_connector_funcs, |
|---|
| 868 | | - DRM_MODE_CONNECTOR_HDMIA); |
|---|
| 869 | | - if (ret) { |
|---|
| 870 | | - DRM_ERROR("Failed to initialize connector with drm\n"); |
|---|
| 871 | | - return ret; |
|---|
| 872 | | - } |
|---|
| 873 | | - drm_connector_helper_add(&adv->connector, |
|---|
| 874 | | - &adv7511_connector_helper_funcs); |
|---|
| 875 | | - drm_connector_attach_encoder(&adv->connector, bridge->encoder); |
|---|
| 876 | | - |
|---|
| 877 | | - if (adv->type == ADV7533) |
|---|
| 931 | + if (adv->type == ADV7533 || adv->type == ADV7535) |
|---|
| 878 | 932 | ret = adv7533_attach_dsi(adv); |
|---|
| 879 | 933 | |
|---|
| 880 | 934 | if (adv->i2c_main->irq) |
|---|
| .. | .. |
|---|
| 884 | 938 | return ret; |
|---|
| 885 | 939 | } |
|---|
| 886 | 940 | |
|---|
| 941 | +static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge) |
|---|
| 942 | +{ |
|---|
| 943 | + struct adv7511 *adv = bridge_to_adv7511(bridge); |
|---|
| 944 | + |
|---|
| 945 | + return adv7511_detect(adv, NULL); |
|---|
| 946 | +} |
|---|
| 947 | + |
|---|
| 948 | +static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge, |
|---|
| 949 | + struct drm_connector *connector) |
|---|
| 950 | +{ |
|---|
| 951 | + struct adv7511 *adv = bridge_to_adv7511(bridge); |
|---|
| 952 | + |
|---|
| 953 | + return adv7511_get_edid(adv, connector); |
|---|
| 954 | +} |
|---|
| 955 | + |
|---|
| 956 | +static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge, |
|---|
| 957 | + enum drm_connector_status status) |
|---|
| 958 | +{ |
|---|
| 959 | + struct adv7511 *adv = bridge_to_adv7511(bridge); |
|---|
| 960 | + |
|---|
| 961 | + if (status == connector_status_disconnected) |
|---|
| 962 | + cec_phys_addr_invalidate(adv->cec_adap); |
|---|
| 963 | +} |
|---|
| 964 | + |
|---|
| 887 | 965 | static const struct drm_bridge_funcs adv7511_bridge_funcs = { |
|---|
| 888 | 966 | .enable = adv7511_bridge_enable, |
|---|
| 889 | 967 | .disable = adv7511_bridge_disable, |
|---|
| 890 | 968 | .mode_set = adv7511_bridge_mode_set, |
|---|
| 891 | 969 | .attach = adv7511_bridge_attach, |
|---|
| 970 | + .detect = adv7511_bridge_detect, |
|---|
| 971 | + .get_edid = adv7511_bridge_get_edid, |
|---|
| 972 | + .hpd_notify = adv7511_bridge_hpd_notify, |
|---|
| 892 | 973 | }; |
|---|
| 893 | 974 | |
|---|
| 894 | 975 | /* ----------------------------------------------------------------------------- |
|---|
| .. | .. |
|---|
| 952 | 1033 | struct i2c_client *i2c = to_i2c_client(dev); |
|---|
| 953 | 1034 | struct adv7511 *adv7511 = i2c_get_clientdata(i2c); |
|---|
| 954 | 1035 | |
|---|
| 955 | | - if (adv7511->type == ADV7533) |
|---|
| 1036 | + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) |
|---|
| 956 | 1037 | reg -= ADV7533_REG_CEC_OFFSET; |
|---|
| 957 | 1038 | |
|---|
| 958 | 1039 | switch (reg) { |
|---|
| .. | .. |
|---|
| 981 | 1062 | { |
|---|
| 982 | 1063 | int ret; |
|---|
| 983 | 1064 | |
|---|
| 984 | | - adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec", |
|---|
| 1065 | + adv->i2c_cec = i2c_new_ancillary_device(adv->i2c_main, "cec", |
|---|
| 985 | 1066 | ADV7511_CEC_I2C_ADDR_DEFAULT); |
|---|
| 986 | | - if (!adv->i2c_cec) |
|---|
| 987 | | - return -EINVAL; |
|---|
| 1067 | + if (IS_ERR(adv->i2c_cec)) |
|---|
| 1068 | + return PTR_ERR(adv->i2c_cec); |
|---|
| 1069 | + |
|---|
| 1070 | + regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR, |
|---|
| 1071 | + adv->i2c_cec->addr << 1); |
|---|
| 1072 | + |
|---|
| 988 | 1073 | i2c_set_clientdata(adv->i2c_cec, adv); |
|---|
| 989 | 1074 | |
|---|
| 990 | 1075 | adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, |
|---|
| .. | .. |
|---|
| 994 | 1079 | goto err; |
|---|
| 995 | 1080 | } |
|---|
| 996 | 1081 | |
|---|
| 997 | | - if (adv->type == ADV7533) { |
|---|
| 1082 | + if (adv->type == ADV7533 || adv->type == ADV7535) { |
|---|
| 998 | 1083 | ret = adv7533_patch_cec_registers(adv); |
|---|
| 999 | 1084 | if (ret) |
|---|
| 1000 | 1085 | goto err; |
|---|
| .. | .. |
|---|
| 1165 | 1250 | |
|---|
| 1166 | 1251 | adv7511_packet_disable(adv7511, 0xffff); |
|---|
| 1167 | 1252 | |
|---|
| 1168 | | - adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid", |
|---|
| 1253 | + adv7511->i2c_edid = i2c_new_ancillary_device(i2c, "edid", |
|---|
| 1169 | 1254 | ADV7511_EDID_I2C_ADDR_DEFAULT); |
|---|
| 1170 | | - if (!adv7511->i2c_edid) { |
|---|
| 1171 | | - ret = -EINVAL; |
|---|
| 1255 | + if (IS_ERR(adv7511->i2c_edid)) { |
|---|
| 1256 | + ret = PTR_ERR(adv7511->i2c_edid); |
|---|
| 1172 | 1257 | goto uninit_regulators; |
|---|
| 1173 | 1258 | } |
|---|
| 1174 | 1259 | |
|---|
| 1175 | 1260 | regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, |
|---|
| 1176 | 1261 | adv7511->i2c_edid->addr << 1); |
|---|
| 1177 | 1262 | |
|---|
| 1178 | | - adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet", |
|---|
| 1263 | + adv7511->i2c_packet = i2c_new_ancillary_device(i2c, "packet", |
|---|
| 1179 | 1264 | ADV7511_PACKET_I2C_ADDR_DEFAULT); |
|---|
| 1180 | | - if (!adv7511->i2c_packet) { |
|---|
| 1181 | | - ret = -EINVAL; |
|---|
| 1265 | + if (IS_ERR(adv7511->i2c_packet)) { |
|---|
| 1266 | + ret = PTR_ERR(adv7511->i2c_packet); |
|---|
| 1182 | 1267 | goto err_i2c_unregister_edid; |
|---|
| 1183 | 1268 | } |
|---|
| 1184 | 1269 | |
|---|
| .. | .. |
|---|
| 1188 | 1273 | ret = adv7511_init_cec_regmap(adv7511); |
|---|
| 1189 | 1274 | if (ret) |
|---|
| 1190 | 1275 | goto err_i2c_unregister_packet; |
|---|
| 1191 | | - |
|---|
| 1192 | | - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, |
|---|
| 1193 | | - adv7511->i2c_cec->addr << 1); |
|---|
| 1194 | 1276 | |
|---|
| 1195 | 1277 | INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); |
|---|
| 1196 | 1278 | |
|---|
| .. | .. |
|---|
| 1217 | 1299 | goto err_unregister_cec; |
|---|
| 1218 | 1300 | |
|---|
| 1219 | 1301 | adv7511->bridge.funcs = &adv7511_bridge_funcs; |
|---|
| 1302 | + adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
|---|
| 1303 | + | DRM_BRIDGE_OP_HPD; |
|---|
| 1220 | 1304 | adv7511->bridge.of_node = dev->of_node; |
|---|
| 1305 | + adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA; |
|---|
| 1221 | 1306 | |
|---|
| 1222 | 1307 | drm_bridge_add(&adv7511->bridge); |
|---|
| 1223 | 1308 | |
|---|
| .. | .. |
|---|
| 1225 | 1310 | return 0; |
|---|
| 1226 | 1311 | |
|---|
| 1227 | 1312 | err_unregister_cec: |
|---|
| 1313 | + cec_unregister_adapter(adv7511->cec_adap); |
|---|
| 1228 | 1314 | i2c_unregister_device(adv7511->i2c_cec); |
|---|
| 1229 | 1315 | if (adv7511->cec_clk) |
|---|
| 1230 | 1316 | clk_disable_unprepare(adv7511->cec_clk); |
|---|
| .. | .. |
|---|
| 1242 | 1328 | { |
|---|
| 1243 | 1329 | struct adv7511 *adv7511 = i2c_get_clientdata(i2c); |
|---|
| 1244 | 1330 | |
|---|
| 1245 | | - if (adv7511->type == ADV7533) |
|---|
| 1331 | + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) |
|---|
| 1246 | 1332 | adv7533_detach_dsi(adv7511); |
|---|
| 1247 | 1333 | i2c_unregister_device(adv7511->i2c_cec); |
|---|
| 1248 | 1334 | if (adv7511->cec_clk) |
|---|
| .. | .. |
|---|
| 1266 | 1352 | { "adv7511", ADV7511 }, |
|---|
| 1267 | 1353 | { "adv7511w", ADV7511 }, |
|---|
| 1268 | 1354 | { "adv7513", ADV7511 }, |
|---|
| 1269 | | -#ifdef CONFIG_DRM_I2C_ADV7533 |
|---|
| 1270 | 1355 | { "adv7533", ADV7533 }, |
|---|
| 1271 | | -#endif |
|---|
| 1356 | + { "adv7535", ADV7535 }, |
|---|
| 1272 | 1357 | { } |
|---|
| 1273 | 1358 | }; |
|---|
| 1274 | 1359 | MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids); |
|---|
| .. | .. |
|---|
| 1277 | 1362 | { .compatible = "adi,adv7511", .data = (void *)ADV7511 }, |
|---|
| 1278 | 1363 | { .compatible = "adi,adv7511w", .data = (void *)ADV7511 }, |
|---|
| 1279 | 1364 | { .compatible = "adi,adv7513", .data = (void *)ADV7511 }, |
|---|
| 1280 | | -#ifdef CONFIG_DRM_I2C_ADV7533 |
|---|
| 1281 | 1365 | { .compatible = "adi,adv7533", .data = (void *)ADV7533 }, |
|---|
| 1282 | | -#endif |
|---|
| 1366 | + { .compatible = "adi,adv7535", .data = (void *)ADV7535 }, |
|---|
| 1283 | 1367 | { } |
|---|
| 1284 | 1368 | }; |
|---|
| 1285 | 1369 | MODULE_DEVICE_TABLE(of, adv7511_of_ids); |
|---|
| .. | .. |
|---|
| 1300 | 1384 | |
|---|
| 1301 | 1385 | static int __init adv7511_init(void) |
|---|
| 1302 | 1386 | { |
|---|
| 1303 | | - if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) |
|---|
| 1304 | | - mipi_dsi_driver_register(&adv7533_dsi_driver); |
|---|
| 1387 | + int ret; |
|---|
| 1305 | 1388 | |
|---|
| 1306 | | - return i2c_add_driver(&adv7511_driver); |
|---|
| 1389 | + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { |
|---|
| 1390 | + ret = mipi_dsi_driver_register(&adv7533_dsi_driver); |
|---|
| 1391 | + if (ret) |
|---|
| 1392 | + return ret; |
|---|
| 1393 | + } |
|---|
| 1394 | + |
|---|
| 1395 | + ret = i2c_add_driver(&adv7511_driver); |
|---|
| 1396 | + if (ret) { |
|---|
| 1397 | + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) |
|---|
| 1398 | + mipi_dsi_driver_unregister(&adv7533_dsi_driver); |
|---|
| 1399 | + } |
|---|
| 1400 | + |
|---|
| 1401 | + return ret; |
|---|
| 1307 | 1402 | } |
|---|
| 1308 | 1403 | module_init(adv7511_init); |
|---|
| 1309 | 1404 | |
|---|