[Intel-gfx] [PATCH] drm: Add a generic function to change connector type/id of connector dynamically

ykzhao yakui.zhao at intel.com
Thu Jan 28 02:43:46 CET 2010


On Wed, 2010-01-27 at 17:07 +0800, Maarten Maathuis wrote:
> On Wed, Jan 27, 2010 at 8:16 AM,  <yakui.zhao at intel.com> wrote:
> > From: Zhao Yakui <yakui.zhao at 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.

Only one plug is used for this encoder. But it can be detected as
different type when the different adaptor is used. For one
multi-function SDVO card, it can be detected as LVDS, VGA,
SDVO-TV(composite/S-video). Before the external device is connected, we
can't know the exact connector type. 

What I want is to report the correct type according to the external
connected device. When the user changes the external connected device,
we can reflect their changes.

Thanks.
   Yakui

> 
> >
> > Add a generic function to change connector type/id of the connector
> > dynamically.
> >
> > Signed-off-by: Zhao Yakui <yakui.zhao at 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 at lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/dri-devel
> >




More information about the Intel-gfx mailing list