On Wed, Jan 27, 2010 at 8:16 AM,  <yakui.z...@intel.com> wrote:
> From: Zhao Yakui <yakui.z...@intel.com>
>
> Sometimes one connector can support more than one connector type. And it
> will switch the connector type/id dynamically according to the external
> connected device.

I very much doubt it's the connector that is physically changing. It's
a plug, a piece of metal with connection points/wires. What you want
is multiple connectors with the same encoder, to accurately reflect
what is happening.

>
> Add a generic function to change connector type/id of the connector
> dynamically.
>
> Signed-off-by: Zhao Yakui <yakui.z...@intel.com>
> ---
> One multi-function SDVO card device can support SDVO-VGA/SDVO-TV(S-Video/
> Composite). We should give them the correct connector type according
> to the external connected device. For example: VGA/TV. The connector id
> should be re-initialized when connector type is changed. Otherwise we will
> get one conflict connector id.
>
> One list is added to save the connector type/id that is already used by the
> connector. If the target type is already in the list, we can change the
> connector type/ide directly by using the saved result.
> If the new connector type is not in the list, we will dynamically
> allocate the connector id for it and then save the connector type/id to the
> list.
>
>  drivers/gpu/drm/drm_crtc.c |   81 
> ++++++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_crtc.h     |    5 +++
>  2 files changed, 86 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 5124401..a64e389 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -39,6 +39,11 @@ struct drm_prop_enum_list {
>        char *name;
>  };
>
> +struct connector_type_id {
> +       struct list_head head;
> +       int connector_type;
> +       int connector_id;
> +};
>  /* Avoid boilerplate.  I'm tired of typing. */
>  #define DRM_ENUM_NAME_FN(fnname, list)                         \
>        char *fnname(int val)                                   \
> @@ -443,6 +448,13 @@ void drm_connector_init(struct drm_device *dev,
>                     const struct drm_connector_funcs *funcs,
>                     int connector_type)
>  {
> +       struct connector_type_id *p_type_id = NULL;
> +
> +       p_type_id = kzalloc(sizeof(*p_type_id), GFP_KERNEL);
> +
> +       if (!p_type_id)
> +               DRM_DEBUG_KMS("Can't allocate the memory\n");
> +
>        mutex_lock(&dev->mode_config.mutex);
>
>        connector->dev = dev;
> @@ -465,11 +477,73 @@ void drm_connector_init(struct drm_device *dev,
>        drm_connector_attach_property(connector,
>                                      dev->mode_config.dpms_property, 0);
>
> +       INIT_LIST_HEAD(&connector->connector_type_list);
> +       if (p_type_id) {
> +               p_type_id->connector_type = connector_type;
> +               p_type_id->connector_id = connector->connector_type_id;
> +               list_add_tail(&p_type_id->head,
> +                                       &connector->connector_type_list);
> +       }
>        mutex_unlock(&dev->mode_config.mutex);
>  }
>  EXPORT_SYMBOL(drm_connector_init);
>
>  /**
> + * drm_rename_connector_type - Rename the connector type for one connector
> + * @connector: the connector to be named
> + * @target_type: the renamed target connector type
> + *
> + * Rename the connector type for one connector. Sometimes we will
> + * need get a new connector type id.
> + *
> + * RETURNS:
> + * Zero on success, errno on failure.
> + */
> +
> +int drm_rename_connector_type(struct drm_connector *connector,
> +                    int target_type)
> +{
> +       struct connector_type_id *type_id, *temp;
> +       int connector_id, found = 0;
> +       struct drm_device *dev = connector->dev;
> +
> +       if (connector->connector_type == target_type)
> +               return 0;
> +
> +       list_for_each_entry_safe(type_id, temp,
> +                       &connector->connector_type_list, head) {
> +               if (type_id->connector_type == target_type) {
> +                       connector_id = type_id->connector_id;
> +                       found = 1;
> +                       break;
> +               }
> +       }
> +       if (found) {
> +               connector->connector_type = target_type;
> +               connector->connector_type_id = connector_id;
> +               return 0;
> +       }
> +
> +       type_id = kzalloc(sizeof(*type_id), GFP_KERNEL);
> +
> +       if (!type_id) {
> +               DRM_DEBUG_KMS("Can't allocate the memory\n");
> +               return -ENOMEM;
> +       }
> +
> +       connector->connector_type = target_type;
> +       connector->connector_type_id =
> +               ++drm_connector_enum_list[target_type].count;
> +
> +       type_id->connector_type = target_type;
> +       type_id->connector_id = connector->connector_type_id;
> +       list_add_tail(&type_id->head, &connector->connector_type_list);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_rename_connector_type);
> +
> +/**
>  * drm_connector_cleanup - cleans up an initialised connector
>  * @connector: connector to cleanup
>  *
> @@ -482,6 +556,7 @@ void drm_connector_cleanup(struct drm_connector 
> *connector)
>  {
>        struct drm_device *dev = connector->dev;
>        struct drm_display_mode *mode, *t;
> +       struct connector_type_id *type_id, *temp;
>
>        list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
>                drm_mode_remove(connector, mode);
> @@ -492,6 +567,12 @@ void drm_connector_cleanup(struct drm_connector 
> *connector)
>        list_for_each_entry_safe(mode, t, &connector->user_modes, head)
>                drm_mode_remove(connector, mode);
>
> +       list_for_each_entry_safe(type_id, temp,
> +                       &connector->connector_type_list, head) {
> +               list_del(&type_id->head);
> +               kfree(type_id);
> +       }
> +
>        kfree(connector->fb_helper_private);
>        mutex_lock(&dev->mode_config.mutex);
>        drm_mode_object_put(dev, &connector->base);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index fdf43ab..3862e32 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -521,6 +521,8 @@ struct drm_connector {
>        uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
>        uint32_t force_encoder_id;
>        struct drm_encoder *encoder; /* currently active encoder */
> +       /* the list of possible connector type/id for this connector */
> +       struct list_head connector_type_list;
>        void *fb_helper_private;
>  };
>
> @@ -647,6 +649,9 @@ extern void drm_connector_init(struct drm_device *dev,
>                            const struct drm_connector_funcs *funcs,
>                            int connector_type);
>
> +extern int drm_rename_connector_type(struct drm_connector *connector,
> +                           int target_type);
> +
>  extern void drm_connector_cleanup(struct drm_connector *connector);
>
>  extern void drm_encoder_init(struct drm_device *dev,
> --
> 1.5.4.5
>
>
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> --
> _______________________________________________
> Dri-devel mailing list
> Dri-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/dri-devel
>

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to