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