aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2016-01-09 03:54:54 -0500
committerArchit Taneja <architt@codeaurora.org>2016-07-13 04:54:35 -0400
commite12c2f645557708932e15afdf77f5965549cf156 (patch)
tree8e5c0ee998b00c287ed3426a6a11a9b8e6eacd33
parent2ae995887830b335f9bdab3040018071da54bcdb (diff)
drm/i2c: adv7511: Convert to drm_bridge
We don't want to use the old i2c slave encoder interface anymore. Remove that and make the i2c driver create a drm_bridge entity instead. Converting to bridges helps because the kms drivers don't need to exract encoder slave ops from this driver and use it within their own encoder/connector ops. The driver now creates its own connector when a kms driver attaches itself to the bridge. Therefore, kms drivers don't need to create their own connectors anymore. The old encoder slave ops are now used by the new bridge and connector entities. The of_node member in drm_bridge is accessible only when CONFIG_OF is enabled. The driver anyway only works only when OF is available. Make the driver depend on OF in its Kconfig. Signed-off-by: Archit Taneja <architt@codeaurora.org>
-rw-r--r--drivers/gpu/drm/i2c/Kconfig1
-rw-r--r--drivers/gpu/drm/i2c/adv7511.c213
2 files changed, 140 insertions, 74 deletions
diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed63a001..8bb06977343a 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -3,6 +3,7 @@ menu "I2C encoder or helper chips"
3 3
4config DRM_I2C_ADV7511 4config DRM_I2C_ADV7511
5 tristate "AV7511 encoder" 5 tristate "AV7511 encoder"
6 depends on OF
6 select REGMAP_I2C 7 select REGMAP_I2C
7 help 8 help
8 Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders. 9 Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index a02112ba1c3d..c2642f99865d 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -14,9 +14,10 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15 15
16#include <drm/drmP.h> 16#include <drm/drmP.h>
17#include <drm/drm_atomic.h>
18#include <drm/drm_atomic_helper.h>
17#include <drm/drm_crtc_helper.h> 19#include <drm/drm_crtc_helper.h>
18#include <drm/drm_edid.h> 20#include <drm/drm_edid.h>
19#include <drm/drm_encoder_slave.h>
20 21
21#include "adv7511.h" 22#include "adv7511.h"
22 23
@@ -36,7 +37,8 @@ struct adv7511 {
36 bool edid_read; 37 bool edid_read;
37 38
38 wait_queue_head_t wq; 39 wait_queue_head_t wq;
39 struct drm_encoder *encoder; 40 struct drm_bridge bridge;
41 struct drm_connector connector;
40 42
41 bool embedded_sync; 43 bool embedded_sync;
42 enum adv7511_sync_polarity vsync_polarity; 44 enum adv7511_sync_polarity vsync_polarity;
@@ -48,11 +50,6 @@ struct adv7511 {
48 struct gpio_desc *gpio_pd; 50 struct gpio_desc *gpio_pd;
49}; 51};
50 52
51static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
52{
53 return to_encoder_slave(encoder)->slave_priv;
54}
55
56/* ADI recommended values for proper operation. */ 53/* ADI recommended values for proper operation. */
57static const struct reg_sequence adv7511_fixed_registers[] = { 54static const struct reg_sequence adv7511_fixed_registers[] = {
58 { 0x98, 0x03 }, 55 { 0x98, 0x03 },
@@ -446,8 +443,8 @@ static int adv7511_irq_process(struct adv7511 *adv7511)
446 regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0); 443 regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
447 regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); 444 regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
448 445
449 if (irq0 & ADV7511_INT0_HPD && adv7511->encoder) 446 if (irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)
450 drm_helper_hpd_irq_event(adv7511->encoder->dev); 447 drm_helper_hpd_irq_event(adv7511->connector.dev);
451 448
452 if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { 449 if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
453 adv7511->edid_read = true; 450 adv7511->edid_read = true;
@@ -563,13 +560,12 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
563} 560}
564 561
565/* ----------------------------------------------------------------------------- 562/* -----------------------------------------------------------------------------
566 * Encoder operations 563 * ADV75xx helpers
567 */ 564 */
568 565
569static int adv7511_get_modes(struct drm_encoder *encoder, 566static int adv7511_get_modes(struct adv7511 *adv7511,
570 struct drm_connector *connector) 567 struct drm_connector *connector)
571{ 568{
572 struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
573 struct edid *edid; 569 struct edid *edid;
574 unsigned int count; 570 unsigned int count;
575 571
@@ -606,21 +602,9 @@ static int adv7511_get_modes(struct drm_encoder *encoder,
606 return count; 602 return count;
607} 603}
608 604
609static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode)
610{
611 struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
612
613 if (mode == DRM_MODE_DPMS_ON)
614 adv7511_power_on(adv7511);
615 else
616 adv7511_power_off(adv7511);
617}
618
619static enum drm_connector_status 605static enum drm_connector_status
620adv7511_encoder_detect(struct drm_encoder *encoder, 606adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
621 struct drm_connector *connector)
622{ 607{
623 struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
624 enum drm_connector_status status; 608 enum drm_connector_status status;
625 unsigned int val; 609 unsigned int val;
626 bool hpd; 610 bool hpd;
@@ -644,7 +628,7 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
644 if (status == connector_status_connected && hpd && adv7511->powered) { 628 if (status == connector_status_connected && hpd && adv7511->powered) {
645 regcache_mark_dirty(adv7511->regmap); 629 regcache_mark_dirty(adv7511->regmap);
646 adv7511_power_on(adv7511); 630 adv7511_power_on(adv7511);
647 adv7511_get_modes(encoder, connector); 631 adv7511_get_modes(adv7511, connector);
648 if (adv7511->status == connector_status_connected) 632 if (adv7511->status == connector_status_connected)
649 status = connector_status_disconnected; 633 status = connector_status_disconnected;
650 } else { 634 } else {
@@ -658,8 +642,8 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
658 return status; 642 return status;
659} 643}
660 644
661static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, 645static int adv7511_mode_valid(struct adv7511 *adv7511,
662 struct drm_display_mode *mode) 646 struct drm_display_mode *mode)
663{ 647{
664 if (mode->clock > 165000) 648 if (mode->clock > 165000)
665 return MODE_CLOCK_HIGH; 649 return MODE_CLOCK_HIGH;
@@ -667,11 +651,10 @@ static int adv7511_encoder_mode_valid(struct drm_encoder *encoder,
667 return MODE_OK; 651 return MODE_OK;
668} 652}
669 653
670static void adv7511_encoder_mode_set(struct drm_encoder *encoder, 654static void adv7511_mode_set(struct adv7511 *adv7511,
671 struct drm_display_mode *mode, 655 struct drm_display_mode *mode,
672 struct drm_display_mode *adj_mode) 656 struct drm_display_mode *adj_mode)
673{ 657{
674 struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
675 unsigned int low_refresh_rate; 658 unsigned int low_refresh_rate;
676 unsigned int hsync_polarity = 0; 659 unsigned int hsync_polarity = 0;
677 unsigned int vsync_polarity = 0; 660 unsigned int vsync_polarity = 0;
@@ -762,12 +745,111 @@ static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
762 adv7511->f_tmds = mode->clock; 745 adv7511->f_tmds = mode->clock;
763} 746}
764 747
765static const struct drm_encoder_slave_funcs adv7511_encoder_funcs = { 748/* Connector funcs */
766 .dpms = adv7511_encoder_dpms, 749static struct adv7511 *connector_to_adv7511(struct drm_connector *connector)
767 .mode_valid = adv7511_encoder_mode_valid, 750{
768 .mode_set = adv7511_encoder_mode_set, 751 return container_of(connector, struct adv7511, connector);
769 .detect = adv7511_encoder_detect, 752}
770 .get_modes = adv7511_get_modes, 753
754static int adv7511_connector_get_modes(struct drm_connector *connector)
755{
756 struct adv7511 *adv = connector_to_adv7511(connector);
757
758 return adv7511_get_modes(adv, connector);
759}
760
761static enum drm_mode_status
762adv7511_connector_mode_valid(struct drm_connector *connector,
763 struct drm_display_mode *mode)
764{
765 struct adv7511 *adv = connector_to_adv7511(connector);
766
767 return adv7511_mode_valid(adv, mode);
768}
769
770static struct drm_connector_helper_funcs adv7511_connector_helper_funcs = {
771 .get_modes = adv7511_connector_get_modes,
772 .mode_valid = adv7511_connector_mode_valid,
773};
774
775static enum drm_connector_status
776adv7511_connector_detect(struct drm_connector *connector, bool force)
777{
778 struct adv7511 *adv = connector_to_adv7511(connector);
779
780 return adv7511_detect(adv, connector);
781}
782
783static struct drm_connector_funcs adv7511_connector_funcs = {
784 .dpms = drm_atomic_helper_connector_dpms,
785 .fill_modes = drm_helper_probe_single_connector_modes,
786 .detect = adv7511_connector_detect,
787 .destroy = drm_connector_cleanup,
788 .reset = drm_atomic_helper_connector_reset,
789 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
790 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
791};
792
793/* Bridge funcs */
794static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
795{
796 return container_of(bridge, struct adv7511, bridge);
797}
798
799static void adv7511_bridge_enable(struct drm_bridge *bridge)
800{
801 struct adv7511 *adv = bridge_to_adv7511(bridge);
802
803 adv7511_power_on(adv);
804}
805
806static void adv7511_bridge_disable(struct drm_bridge *bridge)
807{
808 struct adv7511 *adv = bridge_to_adv7511(bridge);
809
810 adv7511_power_off(adv);
811}
812
813static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
814 struct drm_display_mode *mode,
815 struct drm_display_mode *adj_mode)
816{
817 struct adv7511 *adv = bridge_to_adv7511(bridge);
818
819 adv7511_mode_set(adv, mode, adj_mode);
820}
821
822static int adv7511_bridge_attach(struct drm_bridge *bridge)
823{
824 struct adv7511 *adv = bridge_to_adv7511(bridge);
825 int ret;
826
827 if (!bridge->encoder) {
828 DRM_ERROR("Parent encoder object not found");
829 return -ENODEV;
830 }
831
832 adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
833
834 ret = drm_connector_init(bridge->dev, &adv->connector,
835 &adv7511_connector_funcs,
836 DRM_MODE_CONNECTOR_HDMIA);
837 if (ret) {
838 DRM_ERROR("Failed to initialize connector with drm\n");
839 return ret;
840 }
841 drm_connector_helper_add(&adv->connector,
842 &adv7511_connector_helper_funcs);
843 drm_mode_connector_attach_encoder(&adv->connector, bridge->encoder);
844
845 return ret;
846}
847
848static struct drm_bridge_funcs adv7511_bridge_funcs = {
849 .enable = adv7511_bridge_enable,
850 .disable = adv7511_bridge_disable,
851 .mode_set = adv7511_bridge_mode_set,
852 .attach = adv7511_bridge_attach,
771}; 853};
772 854
773/* ----------------------------------------------------------------------------- 855/* -----------------------------------------------------------------------------
@@ -944,6 +1026,15 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
944 1026
945 adv7511_set_link_config(adv7511, &link_config); 1027 adv7511_set_link_config(adv7511, &link_config);
946 1028
1029 adv7511->bridge.funcs = &adv7511_bridge_funcs;
1030 adv7511->bridge.of_node = dev->of_node;
1031
1032 ret = drm_bridge_add(&adv7511->bridge);
1033 if (ret) {
1034 dev_err(dev, "failed to add adv7511 bridge\n");
1035 goto err_i2c_unregister_device;
1036 }
1037
947 return 0; 1038 return 0;
948 1039
949err_i2c_unregister_device: 1040err_i2c_unregister_device:
@@ -956,6 +1047,8 @@ static int adv7511_remove(struct i2c_client *i2c)
956{ 1047{
957 struct adv7511 *adv7511 = i2c_get_clientdata(i2c); 1048 struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
958 1049
1050 drm_bridge_remove(&adv7511->bridge);
1051
959 i2c_unregister_device(adv7511->i2c_edid); 1052 i2c_unregister_device(adv7511->i2c_edid);
960 1053
961 kfree(adv7511->edid); 1054 kfree(adv7511->edid);
@@ -963,20 +1056,6 @@ static int adv7511_remove(struct i2c_client *i2c)
963 return 0; 1056 return 0;
964} 1057}
965 1058
966static int adv7511_encoder_init(struct i2c_client *i2c, struct drm_device *dev,
967 struct drm_encoder_slave *encoder)
968{
969
970 struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
971
972 encoder->slave_priv = adv7511;
973 encoder->slave_funcs = &adv7511_encoder_funcs;
974
975 adv7511->encoder = &encoder->base;
976
977 return 0;
978}
979
980static const struct i2c_device_id adv7511_i2c_ids[] = { 1059static const struct i2c_device_id adv7511_i2c_ids[] = {
981 { "adv7511", 0 }, 1060 { "adv7511", 0 },
982 { "adv7511w", 0 }, 1061 { "adv7511w", 0 },
@@ -993,31 +1072,17 @@ static const struct of_device_id adv7511_of_ids[] = {
993}; 1072};
994MODULE_DEVICE_TABLE(of, adv7511_of_ids); 1073MODULE_DEVICE_TABLE(of, adv7511_of_ids);
995 1074
996static struct drm_i2c_encoder_driver adv7511_driver = { 1075static struct i2c_driver adv7511_driver = {
997 .i2c_driver = { 1076 .driver = {
998 .driver = { 1077 .name = "adv7511",
999 .name = "adv7511", 1078 .of_match_table = adv7511_of_ids,
1000 .of_match_table = adv7511_of_ids,
1001 },
1002 .id_table = adv7511_i2c_ids,
1003 .probe = adv7511_probe,
1004 .remove = adv7511_remove,
1005 }, 1079 },
1006 1080 .id_table = adv7511_i2c_ids,
1007 .encoder_init = adv7511_encoder_init, 1081 .probe = adv7511_probe,
1082 .remove = adv7511_remove,
1008}; 1083};
1009 1084
1010static int __init adv7511_init(void) 1085module_i2c_driver(adv7511_driver);
1011{
1012 return drm_i2c_encoder_register(THIS_MODULE, &adv7511_driver);
1013}
1014module_init(adv7511_init);
1015
1016static void __exit adv7511_exit(void)
1017{
1018 drm_i2c_encoder_unregister(&adv7511_driver);
1019}
1020module_exit(adv7511_exit);
1021 1086
1022MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 1087MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1023MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver"); 1088MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver");