]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
Revert "drm/i2c: adv7511: Convert to drm_bridge"
authorHyun Kwon <hyun.kwon@xilinx.com>
Fri, 31 Mar 2017 00:39:13 +0000 (17:39 -0700)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 19 Apr 2017 05:59:18 +0000 (07:59 +0200)
This reverts commit e12c2f645557708932e15afdf77f5965549cf156
("drm/i2c: adv7511: Convert to drm_bridge").

This is a temporary solution to enable adv7511 based on the encoder
slave. The DRM driver needs to support the atomic modesetting
as well as the drm bridge. When those changes are in, this can be
removed.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/gpu/drm/i2c/Kconfig
drivers/gpu/drm/i2c/adv7511.c

index 1c2e5032334f8d24bb7f1b9e60a3c44d8625e6c1..088f2781d3036add3a252e8ba864e132087c7eec 100644 (file)
@@ -3,7 +3,6 @@ menu "I2C encoder or helper chips"
 
 config DRM_I2C_ADV7511
        tristate "AV7511 encoder"
-       depends on OF
        select REGMAP_I2C
        help
          Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
index c2642f99865dcb4035abd1cb9e0e0c88480affd5..a02112ba1c3df692b3a089a3ab24a8f30d35b7ec 100644 (file)
 #include <linux/slab.h>
 
 #include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
 
 #include "adv7511.h"
 
@@ -37,8 +36,7 @@ struct adv7511 {
        bool edid_read;
 
        wait_queue_head_t wq;
-       struct drm_bridge bridge;
-       struct drm_connector connector;
+       struct drm_encoder *encoder;
 
        bool embedded_sync;
        enum adv7511_sync_polarity vsync_polarity;
@@ -50,6 +48,11 @@ struct adv7511 {
        struct gpio_desc *gpio_pd;
 };
 
+static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
+{
+       return to_encoder_slave(encoder)->slave_priv;
+}
+
 /* ADI recommended values for proper operation. */
 static const struct reg_sequence adv7511_fixed_registers[] = {
        { 0x98, 0x03 },
@@ -443,8 +446,8 @@ static int adv7511_irq_process(struct adv7511 *adv7511)
        regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
        regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
 
-       if (irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)
-               drm_helper_hpd_irq_event(adv7511->connector.dev);
+       if (irq0 & ADV7511_INT0_HPD && adv7511->encoder)
+               drm_helper_hpd_irq_event(adv7511->encoder->dev);
 
        if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
                adv7511->edid_read = true;
@@ -560,12 +563,13 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
 }
 
 /* -----------------------------------------------------------------------------
- * ADV75xx helpers
+ * Encoder operations
  */
 
-static int adv7511_get_modes(struct adv7511 *adv7511,
+static int adv7511_get_modes(struct drm_encoder *encoder,
                             struct drm_connector *connector)
 {
+       struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
        struct edid *edid;
        unsigned int count;
 
@@ -602,9 +606,21 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
        return count;
 }
 
+static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
+
+       if (mode == DRM_MODE_DPMS_ON)
+               adv7511_power_on(adv7511);
+       else
+               adv7511_power_off(adv7511);
+}
+
 static enum drm_connector_status
-adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
+adv7511_encoder_detect(struct drm_encoder *encoder,
+                      struct drm_connector *connector)
 {
+       struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
        enum drm_connector_status status;
        unsigned int val;
        bool hpd;
@@ -628,7 +644,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
        if (status == connector_status_connected && hpd && adv7511->powered) {
                regcache_mark_dirty(adv7511->regmap);
                adv7511_power_on(adv7511);
-               adv7511_get_modes(adv7511, connector);
+               adv7511_get_modes(encoder, connector);
                if (adv7511->status == connector_status_connected)
                        status = connector_status_disconnected;
        } else {
@@ -642,8 +658,8 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
        return status;
 }
 
-static int adv7511_mode_valid(struct adv7511 *adv7511,
-                             struct drm_display_mode *mode)
+static int adv7511_encoder_mode_valid(struct drm_encoder *encoder,
+                                     struct drm_display_mode *mode)
 {
        if (mode->clock > 165000)
                return MODE_CLOCK_HIGH;
@@ -651,10 +667,11 @@ static int adv7511_mode_valid(struct adv7511 *adv7511,
        return MODE_OK;
 }
 
-static void adv7511_mode_set(struct adv7511 *adv7511,
-                            struct drm_display_mode *mode,
-                            struct drm_display_mode *adj_mode)
+static void adv7511_encoder_mode_set(struct drm_encoder *encoder,
+                                    struct drm_display_mode *mode,
+                                    struct drm_display_mode *adj_mode)
 {
+       struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
        unsigned int low_refresh_rate;
        unsigned int hsync_polarity = 0;
        unsigned int vsync_polarity = 0;
@@ -745,111 +762,12 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
        adv7511->f_tmds = mode->clock;
 }
 
-/* Connector funcs */
-static struct adv7511 *connector_to_adv7511(struct drm_connector *connector)
-{
-       return container_of(connector, struct adv7511, connector);
-}
-
-static int adv7511_connector_get_modes(struct drm_connector *connector)
-{
-       struct adv7511 *adv = connector_to_adv7511(connector);
-
-       return adv7511_get_modes(adv, connector);
-}
-
-static enum drm_mode_status
-adv7511_connector_mode_valid(struct drm_connector *connector,
-                            struct drm_display_mode *mode)
-{
-       struct adv7511 *adv = connector_to_adv7511(connector);
-
-       return adv7511_mode_valid(adv, mode);
-}
-
-static struct drm_connector_helper_funcs adv7511_connector_helper_funcs = {
-       .get_modes = adv7511_connector_get_modes,
-       .mode_valid = adv7511_connector_mode_valid,
-};
-
-static enum drm_connector_status
-adv7511_connector_detect(struct drm_connector *connector, bool force)
-{
-       struct adv7511 *adv = connector_to_adv7511(connector);
-
-       return adv7511_detect(adv, connector);
-}
-
-static struct drm_connector_funcs adv7511_connector_funcs = {
-       .dpms = drm_atomic_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = adv7511_connector_detect,
-       .destroy = drm_connector_cleanup,
-       .reset = drm_atomic_helper_connector_reset,
-       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-/* Bridge funcs */
-static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
-{
-       return container_of(bridge, struct adv7511, bridge);
-}
-
-static void adv7511_bridge_enable(struct drm_bridge *bridge)
-{
-       struct adv7511 *adv = bridge_to_adv7511(bridge);
-
-       adv7511_power_on(adv);
-}
-
-static void adv7511_bridge_disable(struct drm_bridge *bridge)
-{
-       struct adv7511 *adv = bridge_to_adv7511(bridge);
-
-       adv7511_power_off(adv);
-}
-
-static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
-                                   struct drm_display_mode *mode,
-                                   struct drm_display_mode *adj_mode)
-{
-       struct adv7511 *adv = bridge_to_adv7511(bridge);
-
-       adv7511_mode_set(adv, mode, adj_mode);
-}
-
-static int adv7511_bridge_attach(struct drm_bridge *bridge)
-{
-       struct adv7511 *adv = bridge_to_adv7511(bridge);
-       int ret;
-
-       if (!bridge->encoder) {
-               DRM_ERROR("Parent encoder object not found");
-               return -ENODEV;
-       }
-
-       adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
-
-       ret = drm_connector_init(bridge->dev, &adv->connector,
-                                &adv7511_connector_funcs,
-                                DRM_MODE_CONNECTOR_HDMIA);
-       if (ret) {
-               DRM_ERROR("Failed to initialize connector with drm\n");
-               return ret;
-       }
-       drm_connector_helper_add(&adv->connector,
-                                &adv7511_connector_helper_funcs);
-       drm_mode_connector_attach_encoder(&adv->connector, bridge->encoder);
-
-       return ret;
-}
-
-static struct drm_bridge_funcs adv7511_bridge_funcs = {
-       .enable = adv7511_bridge_enable,
-       .disable = adv7511_bridge_disable,
-       .mode_set = adv7511_bridge_mode_set,
-       .attach = adv7511_bridge_attach,
+static const struct drm_encoder_slave_funcs adv7511_encoder_funcs = {
+       .dpms = adv7511_encoder_dpms,
+       .mode_valid = adv7511_encoder_mode_valid,
+       .mode_set = adv7511_encoder_mode_set,
+       .detect = adv7511_encoder_detect,
+       .get_modes = adv7511_get_modes,
 };
 
 /* -----------------------------------------------------------------------------
@@ -1026,15 +944,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 
        adv7511_set_link_config(adv7511, &link_config);
 
-       adv7511->bridge.funcs = &adv7511_bridge_funcs;
-       adv7511->bridge.of_node = dev->of_node;
-
-       ret = drm_bridge_add(&adv7511->bridge);
-       if (ret) {
-               dev_err(dev, "failed to add adv7511 bridge\n");
-               goto err_i2c_unregister_device;
-       }
-
        return 0;
 
 err_i2c_unregister_device:
@@ -1047,8 +956,6 @@ static int adv7511_remove(struct i2c_client *i2c)
 {
        struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
 
-       drm_bridge_remove(&adv7511->bridge);
-
        i2c_unregister_device(adv7511->i2c_edid);
 
        kfree(adv7511->edid);
@@ -1056,6 +963,20 @@ static int adv7511_remove(struct i2c_client *i2c)
        return 0;
 }
 
+static int adv7511_encoder_init(struct i2c_client *i2c, struct drm_device *dev,
+                               struct drm_encoder_slave *encoder)
+{
+
+       struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+
+       encoder->slave_priv = adv7511;
+       encoder->slave_funcs = &adv7511_encoder_funcs;
+
+       adv7511->encoder = &encoder->base;
+
+       return 0;
+}
+
 static const struct i2c_device_id adv7511_i2c_ids[] = {
        { "adv7511", 0 },
        { "adv7511w", 0 },
@@ -1072,17 +993,31 @@ static const struct of_device_id adv7511_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, adv7511_of_ids);
 
-static struct i2c_driver adv7511_driver = {
-       .driver = {
-               .name = "adv7511",
-               .of_match_table = adv7511_of_ids,
+static struct drm_i2c_encoder_driver adv7511_driver = {
+       .i2c_driver = {
+               .driver = {
+                       .name = "adv7511",
+                       .of_match_table = adv7511_of_ids,
+               },
+               .id_table = adv7511_i2c_ids,
+               .probe = adv7511_probe,
+               .remove = adv7511_remove,
        },
-       .id_table = adv7511_i2c_ids,
-       .probe = adv7511_probe,
-       .remove = adv7511_remove,
+
+       .encoder_init = adv7511_encoder_init,
 };
 
-module_i2c_driver(adv7511_driver);
+static int __init adv7511_init(void)
+{
+       return drm_i2c_encoder_register(THIS_MODULE, &adv7511_driver);
+}
+module_init(adv7511_init);
+
+static void __exit adv7511_exit(void)
+{
+       drm_i2c_encoder_unregister(&adv7511_driver);
+}
+module_exit(adv7511_exit);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver");