.. | .. |
---|
| 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 | |
---|