media: cec: expose HDMI connector to CEC dev mapping
Subsystems (16)
RFC PATCH v2 1/1 media: cec: expose HDMI connector to CEC dev mapping
This patch proposes to expose explicit mapping between HDMI connectors and /dev/cecX adapters to userland.
New structure with connector info (card number and connector id in case of DRM connectors) is added to cec_adapter. That connector info is expected to be provided when an adapter is created.
CEC notifier is extended so that it can be used to communicate the connector's info to CEC adapters' creators.
New ioctl, exposing connector info to userland, is added to /dev/cec.
Changes since v2:
- cec_s_connector_info removed, the connector info is now passed to cec_allocate_adapter
- updated commit message
Changes since v1:
- removed the unnecessary event,
- extended cec_connctor_info to allow for various types of connectors.
--- Documentation/media/kapi/cec-core.rst | 6 +++- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 3 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 2 +- drivers/gpu/drm/drm_dp_cec.c | 24 ++++++++------ drivers/gpu/drm/i2c/tda9950.c | 3 +- drivers/gpu/drm/i915/intel_dp.c | 5 ++- drivers/gpu/drm/i915/intel_hdmi.c | 11 ++++++- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- drivers/media/cec/cec-api.c | 12 +++++++ drivers/media/cec/cec-core.c | 13 ++++++-- drivers/media/cec/cec-notifier.c | 19 +++++++++++- drivers/media/i2c/tc358743.c | 3 +- .../media/platform/cros-ec-cec/cros-ec-cec.c | 4 ++- drivers/media/platform/meson/ao-cec.c | 3 +- drivers/media/platform/s5p-cec/s5p_cec.c | 3 +- drivers/media/platform/sti/cec/stih-cec.c | 2 +- drivers/media/platform/stm32/stm32-cec.c | 2 +- drivers/media/platform/tegra-cec/tegra_cec.c | 2 +- drivers/media/platform/vivid/vivid-cec.c | 2 +- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +- .../media/usb/rainshadow-cec/rainshadow-cec.c | 3 +- include/drm/drm_dp_helper.h | 14 ++++----- include/media/cec-notifier.h | 31 +++++++++++++++++-- include/media/cec.h | 6 ++-- include/uapi/linux/cec.h | 24 ++++++++++++++ 27 files changed, 161 insertions(+), 46 deletions(-)
Documentation/media/kapi/cec-core.rst +5 -1
@@ -37,7 +37,7 @@ calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): .. c:function:: struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, - const char *name, u32 caps, u8 available_las); + const char *name, u32 caps, u8 available_las, struct cec_connector_info* connector_info); .. c:function:: void cec_delete_adapter(struct cec_adapter *adap);
@@ -65,6 +65,10 @@ available_las: the number of simultaneous logical addresses that this adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. +cec_connector_info: + poiner to a struct describing connector this adapter is associated with, + can be NULL. + To obtain the priv pointer use this helper function: .. c:function::
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -1
@@ -394,7 +394,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,drm_dp_aux_register (&aconnector->dm_dp_aux.aux);drm_dp_cec_register_connector (&aconnector->dm_dp_aux.aux, - aconnector->base.name, dm->adev->dev); + &aconnector->base); aconnector->mst_mgr.cbs = &dm_mst_cbs; drm_dp_mst_topology_mgr_init( &aconnector->mst_mgr,
drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +2 -1
@@ -310,7 +310,8 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_parse_dt; adv7511->cec_adap =cec_allocate_adapter (&adv7511_cec_adap_ops, - adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS ); + adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS , +NULL );if (IS_ERR (adv7511->cec_adap)) { ret =PTR_ERR (adv7511->cec_adap); goto err_cec_alloc;
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1 -1
@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );if (IS_ERR (cec->adap))return PTR_ERR (cec->adap);
drivers/gpu/drm/drm_dp_cec.c +15 -9
@@ -8,7 +8,9 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <drm/drm_connector.h> #include <drm/drm_dp_helper.h> +#include <drm/drmP.h> #include <media/cec.h> /*
@@ -295,7 +297,13 @@ static void drm_dp_cec_unregister_work(struct work_struct *work)*/ void drm_dp_cec_set_edid (struct drm_dp_aux *aux,const struct edid *edid) { +struct drm_connector *connector = aux->cec.connector;u32 cec_caps =CEC_CAP_DEFAULTS |CEC_CAP_NEEDS_HPD ; +struct cec_connector_info connector_info = { + .type =CEC_CONNECTOR_TYPE_DRM , + .drm.card_no = connector->dev->primary->index, + .drm.connector_id = connector->base.id + };unsigned int num_las =1 ;u8 cap;
@@ -344,13 +352,13 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)/* Create a new adapter */ aux->cec.adap =cec_allocate_adapter (&drm_dp_cec_adap_ops, - aux, aux->cec.name, cec_caps, - num_las); + aux, connector->name, cec_caps, + num_las, &connector_info);if (IS_ERR (aux->cec.adap)) { aux->cec.adap =NULL ; goto unlock; } -if (cec_register_adapter (aux->cec.adap, aux->cec.parent)) { +if (cec_register_adapter (aux->cec.adap, connector->dev->dev)) {cec_delete_adapter (aux->cec.adap); aux->cec.adap =NULL ; }else {
@@ -406,22 +414,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);/** * drm_dp_cec_register_connector() - register a new connector * @aux: DisplayPort AUX channel -* @name: name of the CEC device -* @parent: parent device +* @connector: drm connector * * A new connector was registered with associated CEC adapter name and * CEC adapter parent device. After registering the name and parent * drm_dp_cec_set_edid() is called to check if the connector supports * CEC and to register a CEC adapter if that is the case. */ -void drm_dp_cec_register_connector (struct drm_dp_aux *aux,const char *name, -struct device *parent) +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector) {WARN_ON (aux->cec.adap);if (WARN_ON (!aux->transfer))return ; - aux->cec.name = name; - aux->cec.parent = parent; + aux->cec.connector = connector;INIT_DELAYED_WORK (&aux->cec.unregister_work, drm_dp_cec_unregister_work); }
drivers/gpu/drm/i2c/tda9950.c +2 -1
@@ -424,7 +424,8 @@ static int tda9950_probe(struct i2c_client *client, priv->adap =cec_allocate_adapter (&tda9950_cec_ops, priv,"tda9950" ,CEC_CAP_DEFAULTS , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS , +NULL );if (IS_ERR (priv->adap))return PTR_ERR (priv->adap);
drivers/gpu/drm/i915/intel_dp.c +2 -3
@@ -5550,7 +5550,6 @@ static int intel_dp_connector_register(struct drm_connector *connector) {struct intel_dp *intel_dp =intel_attached_dp (connector); -struct drm_device *dev = connector->dev;int ret; ret =intel_connector_register (connector);
@@ -5565,8 +5564,7 @@ intel_dp_connector_register(struct drm_connector *connector) intel_dp->aux.dev = connector->kdev; ret =drm_dp_aux_register (&intel_dp->aux);if (!ret) -drm_dp_cec_register_connector (&intel_dp->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&intel_dp->aux, connector);return ret; }
@@ -7435,3 +7433,4 @@ void intel_dp_mst_resume(struct drm_i915_private *dev_priv) } } } +
drivers/gpu/drm/i915/intel_hdmi.c +10 -1
@@ -3021,8 +3021,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->cec_notifier =cec_notifier_get_conn (dev->dev,port_identifier (port)); -if (!intel_hdmi->cec_notifier) +if (intel_hdmi->cec_notifier) { +struct cec_connector_info info; + + info.type =CEC_CONNECTOR_TYPE_DRM ; + info.drm.card_no = connector->dev->primary->index; + info.drm.connector_id = connector->base.id; +cec_notifier_set_connector_info (intel_hdmi->cec_notifier, + &info); + }else {DRM_DEBUG_KMS ("CEC notifier get failed\n" ); + } } void intel_hdmi_init(struct drm_i915_private *dev_priv,
drivers/gpu/drm/nouveau/nouveau_connector.c +1 -2
@@ -1413,8 +1413,7 @@ nouveau_connector_create(struct drm_device *dev,switch (type) {case DRM_MODE_CONNECTOR_DisplayPort:case DRM_MODE_CONNECTOR_eDP: -drm_dp_cec_register_connector (&nv_connector->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&nv_connector->aux, connector);break ; }
drivers/gpu/drm/vc4/vc4_hdmi.c +1 -1
@@ -1418,7 +1418,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)CEC_CAP_TRANSMIT |CEC_CAP_LOG_ADDRS |CEC_CAP_PASSTHROUGH | - CEC_CAP_RC, 1); + CEC_CAP_RC, 1, NULL); ret =PTR_ERR_OR_ZERO (hdmi->cec_adap);if (ret <0 ) goto err_destroy_conn;
drivers/media/cec/cec-api.c +12 -0
@@ -187,6 +187,15 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,return 0 ; } +static long cec_adap_g_connector_info (struct cec_adapter *adap, +struct cec_log_addrs __user *parg) +{ +if (copy_to_user (parg, &adap->connector_info, +sizeof (adap->connector_info))) +return -EFAULT ; +return 0 ; +} +static long cec_transmit (struct cec_adapter *adap,struct cec_fh *fh,bool block,struct cec_msg __user *parg) {
@@ -514,6 +523,9 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)case CEC_ADAP_S_LOG_ADDRS :return cec_adap_s_log_addrs (adap, fh, block, parg); +case CEC_ADAP_G_CONNECTOR_INFO : +return cec_adap_g_connector_info (adap, parg); +case CEC_TRANSMIT :return cec_transmit (adap, fh, block, parg);
drivers/media/cec/cec-core.c +10 -3
@@ -195,7 +195,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,return ; adap->notifier = notifier; - cec_notifier_register(adap->notifier, adap, cec_cec_notify); +cec_notifier_register (adap->notifier, adap, + cec_cec_notify); }EXPORT_SYMBOL_GPL (cec_register_cec_notifier);#endif
@@ -250,8 +251,9 @@ static const struct file_operations cec_error_inj_fops = {#endif struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps, -u8 available_las) +void *priv,const char *name,u32 caps, +u8 available_las, +struct cec_connector_info *connector_info) {struct cec_adapter *adap;int res;
@@ -288,6 +290,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,INIT_LIST_HEAD (&adap->wait_queue);init_waitqueue_head (&adap->kthread_waitq); +if (connector_info) + adap->connector_info = *connector_info; +else + adap->connector_info.type =CEC_CONNECTOR_TYPE_NO_CONNECTOR ; +/* adap->devnode initialization */ INIT_LIST_HEAD (&adap->devnode.fhs);mutex_init (&adap->devnode.lock);
drivers/media/cec/cec-notifier.c +18 -1
@@ -26,6 +26,7 @@ struct cec_notifier {void (*callback)(struct cec_adapter *adap,u16 pa);u16 phys_addr; +struct cec_connector_info connector_info; };static LIST_HEAD (cec_notifiers);
@@ -51,6 +52,7 @@ struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)if (conn) n->conn =kstrdup (conn,GFP_KERNEL ); n->phys_addr =CEC_PHYS_ADDR_INVALID ; + n->connector_info.type =CEC_CONNECTOR_TYPE_NO_CONNECTOR ;mutex_init (&n->lock);kref_init (&n->kref);list_add_tail (&n->head, &cec_notifiers);
@@ -106,9 +108,24 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, }EXPORT_SYMBOL_GPL (cec_notifier_set_phys_addr_from_edid); +void cec_notifier_set_connector_info (struct cec_notifier *n, +struct cec_connector_info *c) +{ +memcpy (&n->connector_info, c,sizeof (*c)); +} +EXPORT_SYMBOL_GPL (cec_notifier_set_connector_info); + +struct cec_connector_info *cec_notifier_get_connector_info ( +struct cec_notifier *n) +{ +return &n->connector_info; +} +EXPORT_SYMBOL_GPL (cec_notifier_get_connector_info); +void cec_notifier_register (struct cec_notifier *n,struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +void (*callback)(struct cec_adapter *adap, +u16 pa)) {kref_get (&n->kref);mutex_lock (&n->lock);
drivers/media/i2c/tc358743.c +2 -1
@@ -2117,7 +2117,8 @@ static int tc358743_probe(struct i2c_client *client,#ifdef CONFIG_VIDEO_TC358743_CEC state->cec_adap =cec_allocate_adapter (&tc358743_cec_adap_ops, state,dev_name (&client->dev), -CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS ); +CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS , +NULL );if (IS_ERR (state->cec_adap)) { err =PTR_ERR (state->cec_adap); goto err_hdl;
drivers/media/platform/cros-ec-cec/cros-ec-cec.c +3 -1
@@ -282,7 +282,9 @@ static int cros_ec_cec_probe(struct platform_device *pdev) } cros_ec_cec->adap =cec_allocate_adapter (&cros_ec_cec_ops, cros_ec_cec, -DRV_NAME ,CEC_CAP_DEFAULTS ,1 ); +DRV_NAME ,CEC_CAP_DEFAULTS ,1 , +cec_notifier_get_connector_info ( + cros_ec_cec->notify));if (IS_ERR (cros_ec_cec->adap))return PTR_ERR (cros_ec_cec->adap);
drivers/media/platform/meson/ao-cec.c +2 -1
@@ -632,7 +632,8 @@ static int meson_ao_cec_probe(struct platform_device *pdev)CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , - 1); /* Use 1 for now */ +1 /* Use 1 for now */ , + NULL);if (IS_ERR (ao_cec->adap)) { ret =PTR_ERR (ao_cec->adap); goto out_probe_notify;
drivers/media/platform/s5p-cec/s5p_cec.c +2 -1
@@ -229,7 +229,8 @@ static int s5p_cec_probe(struct platform_device *pdev)return -ENOMEM ; cec->adap =cec_allocate_adapter (&s5p_cec_adap_ops, cec,CEC_NAME , -CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 ); +CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 , +NULL ); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/sti/cec/stih-cec.c +1 -1
@@ -348,7 +348,7 @@ static int stih_cec_probe(struct platform_device *pdev) } cec->adap =cec_allocate_adapter (&sti_cec_adap_ops, cec, -CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS ); +CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS ,NULL ); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/stm32/stm32-cec.c +1 -1
@@ -304,7 +304,7 @@ static int stm32_cec_probe(struct platform_device *pdev)* available for example when a drm driver can provide edid */ cec->adap =cec_allocate_adapter (&stm32_cec_adap_ops, cec, -CEC_NAME , caps,CEC_MAX_LOG_ADDRS ); +CEC_NAME , caps,CEC_MAX_LOG_ADDRS ,NULL ); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;
drivers/media/platform/tegra-cec/tegra_cec.c +1 -1
@@ -408,7 +408,7 @@ static int tegra_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&tegra_cec_ops, cec,TEGRA_CEC_NAME ,CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,0 );if (IS_ERR (cec->adap)) { ret = -ENOMEM ;dev_err (&pdev->dev,"Couldn't create cec adapter\n" );
drivers/media/platform/vivid/vivid-cec.c +1 -1
@@ -283,5 +283,5 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, idx);return cec_allocate_adapter (&vivid_cec_adap_ops, dev, - name, caps,1 ); + name, caps,1 ,NULL ); }
drivers/media/usb/pulse8-cec/pulse8-cec.c +2 -1
@@ -656,7 +656,8 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->serio = serio; pulse8->adap =cec_allocate_adapter (&pulse8_cec_adap_ops, pulse8, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (pulse8->adap);if (err <0 ) goto free_device;
drivers/media/usb/rainshadow-cec/rainshadow-cec.c +2 -1
@@ -323,7 +323,8 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv) rain->serio = serio; rain->adap =cec_allocate_adapter (&rain_cec_adap_ops, rain, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (rain->adap);if (err <0 ) goto free_device;
include/drm/drm_dp_helper.h +7 -7
@@ -1208,6 +1208,7 @@ struct drm_dp_aux_msg {struct cec_adapter ;struct edid ; +struct drm_connector ;/** * struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
@@ -1220,8 +1221,7 @@ struct edid;struct drm_dp_aux_cec {struct mutex lock;struct cec_adapter *adap; -const char *name; -struct device *parent; +struct drm_connector *connector;struct delayed_work unregister_work; };
@@ -1418,8 +1418,8 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)#ifdef CONFIG_DRM_DP_CEC void drm_dp_cec_irq (struct drm_dp_aux *aux); -void drm_dp_cec_register_connector (struct drm_dp_aux *aux,const char *name, -struct device *parent); +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector);void drm_dp_cec_unregister_connector (struct drm_dp_aux *aux);void drm_dp_cec_set_edid (struct drm_dp_aux *aux,const struct edid *edid);void drm_dp_cec_unset_edid (struct drm_dp_aux *aux);
@@ -1428,9 +1428,9 @@ static inline void drm_dp_cec_irq(struct drm_dp_aux *aux) { } -static inline void drm_dp_cec_register_connector (struct drm_dp_aux *aux, -const char *name, -struct device *parent) +static inline +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector) { }
include/media/cec-notifier.h +29 -2
@@ -63,6 +63,21 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);void cec_notifier_set_phys_addr_from_edid (struct cec_notifier *n,const struct edid *edid); +/** +* cec_notifier_get_connector_info - get connector info associatied with +* a notifier +* @n: the CEC notifier +*/ +struct cec_connector_info *cec_notifier_get_connector_info ( +struct cec_notifier *n); + +/** +* cec_notifier_set_connector_info - associates connector info with a notifier +* @n: the CEC notifier +* @c: the connector info +*/ +void cec_notifier_set_connector_info (struct cec_notifier *n, +struct cec_connector_info *c);/** * cec_notifier_register - register a callback with the notifier * @n: the CEC notifier
@@ -108,9 +123,21 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, { } +static inline const struct cec_connector_info * +cec_notifier_get_connector_info (struct cec_notifier *n) +{ +return NULL ; +} + +static inline void cec_notifier_set_connector_info ( +struct cec_notifier *n, +struct cec_connector_info *c) +{ +} +static inline void cec_notifier_register (struct cec_notifier *n, -struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +struct cec_adapter *adap, +void (*callback)(struct cec_adapter *adap,u16 pa)) { }
include/media/cec.h +4 -2
@@ -200,6 +200,8 @@ struct cec_adapter {u32 sequence;char input_phys[32 ]; + +struct cec_connector_info connector_info; };static inline void *cec_get_drvdata (const struct cec_adapter *adap)
@@ -236,7 +238,8 @@ struct edid;#if IS_REACHABLE (CONFIG_CEC_CORE )struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps,u8 available_las); +void *priv,const char *name,u32 caps,u8 available_las, +struct cec_connector_info *connector_info);int cec_register_adapter (struct cec_adapter *adap,struct device *parent);void cec_unregister_adapter (struct cec_adapter *adap);void cec_delete_adapter (struct cec_adapter *adap);
@@ -249,7 +252,6 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, const struct edid *edid);int cec_transmit_msg (struct cec_adapter *adap,struct cec_msg *msg,bool block); -/* Called by the adapter */ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
include/uapi/linux/cec.h +24 -0
@@ -411,6 +411,27 @@ struct cec_event_lost_msgs {__u32 lost_msgs; }; +/** +* struct cec_event_connector - tells if and which connector is associated +* with the CEC adapter. +* @card_no: drm card number, -1 if no connector +* @connector_id: drm connector id. +*/ +struct cec_drm_connector_info { +int card_no; +__u32 connector_id; +}; + +#define CEC_CONNECTOR_TYPE_NO_CONNECTOR 0 +#define CEC_CONNECTOR_TYPE_DRM 1 +struct cec_connector_info { +int type; +union { +struct cec_drm_connector_info drm; +__u32 raw[16 ]; + }; +}; +/** * struct cec_event - CEC event structure * @ts: the timestamp of when the event was sent.
@@ -475,6 +496,9 @@ struct cec_event {#define CEC_G_MODE _IOR('a', 8, __u32)#define CEC_S_MODE _IOW('a', 9, __u32) +/* Gets the connector info */ +#define CEC_ADAP_G_CONNECTOR_INFO _IOR('a', 10, struct cec_connector_info) +/* * The remainder of this header defines all CEC messages and operands. * The format matters since it the cec-ctl utility parses it to generate
Signature · 1 line
2.18.1
Hi Dariusz,
This is getting close, so I think for the next version you can drop the RFC tag.
Some comments:
Quoted 56 lines · Dariusz Marcinkiewicz
This patch proposes to expose explicit mapping between HDMI connectors and
/dev/cecXadapters to userland.New structure with connector info (card number and connector id in case of DRM connectors) is added to
cec_adapter. That connector info is expected to be provided when an adapter is created.CEC notifier is extended so that it can be used to communicate the connector's info to CEC adapters' creators.
New ioctl, exposing connector info to userland, is added to
/dev/cec.Changes since v2:
-cec_s_connector_inforemoved, the connector info is now passed tocec_allocate_adapter
- updated commit message
Changes since v1:
- removed the unnecessary event,
- extendedcec_connctor_infoto allow for various types of connectors.Signed-off-by Dariusz Marcinkiewicz <[email protected]>--- Documentation/media/kapi/cec-core.rst | 6 +++- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 3 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 2 +- drivers/gpu/drm/drm_dp_cec.c | 24 ++++++++------ drivers/gpu/drm/i2c/tda9950.c | 3 +- drivers/gpu/drm/i915/intel_dp.c | 5 ++- drivers/gpu/drm/i915/intel_hdmi.c | 11 ++++++- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- drivers/media/cec/cec-api.c | 12 +++++++ drivers/media/cec/cec-core.c | 13 ++++++-- drivers/media/cec/cec-notifier.c | 19 +++++++++++- drivers/media/i2c/tc358743.c | 3 +- .../media/platform/cros-ec-cec/cros-ec-cec.c | 4 ++- drivers/media/platform/meson/ao-cec.c | 3 +- drivers/media/platform/s5p-cec/s5p_cec.c | 3 +- drivers/media/platform/sti/cec/stih-cec.c | 2 +- drivers/media/platform/stm32/stm32-cec.c | 2 +- drivers/media/platform/tegra-cec/tegra_cec.c | 2 +- drivers/media/platform/vivid/vivid-cec.c | 2 +- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +- .../media/usb/rainshadow-cec/rainshadow-cec.c | 3 +- include/drm/drm_dp_helper.h | 14 ++++----- include/media/cec-notifier.h | 31 +++++++++++++++++-- include/media/cec.h | 6 ++-- include/uapi/linux/cec.h | 24 ++++++++++++++ 27 files changed, 161 insertions(+), 46 deletions(-)Documentation/media/kapi/cec-core.rst +0
-0
Documentation/media/kapi/cec-core.rst calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): · line 40
Quoted 5 lines
Documentation/media/kapi/cec-core.rst +1
-1@@ -37,7 +37,7 @@ calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): .. c:function:: struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, - const char *name, u32 caps, u8 available_las); + const char *name, u32 caps, u8 available_las, struct cec_connector_info* connector_info);
Make this const and put the space before the *:
const struct cec_connector_info *connector_info
Documentation/media/kapi/cec-core.rst available_las: · line 69
Quoted 9 lines
Documentation/media/kapi/cec-core.rst +2
-0.. c:function:: void cec_delete_adapter(struct cec_adapter *adap);@@ -65,6 +65,10 @@ available_las: the number of simultaneous logical addresses that this adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. +cec_connector_info: + poiner to a struct describing connector this adapter is associated with,
pointer
Quoted 37 lines
Documentation/media/kapi/cec-core.rst +2
-0+ can be NULL. + To obtain the priv pointer use this helper function: .. c:function::drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1
-1@@ -394,7 +394,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,drm_dp_aux_register (&aconnector->dm_dp_aux.aux);drm_dp_cec_register_connector (&aconnector->dm_dp_aux.aux, - aconnector->base.name, dm->adev->dev); + &aconnector->base); aconnector->mst_mgr.cbs = &dm_mst_cbs; drm_dp_mst_topology_mgr_init( &aconnector->mst_mgr,drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +2
-1@@ -310,7 +310,8 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_parse_dt; adv7511->cec_adap =cec_allocate_adapter (&adv7511_cec_adap_ops, - adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS ); + adv7511,dev_name (dev),CEC_CAP_DEFAULTS ,ADV7511_MAX_ADDRS , +NULL );if (IS_ERR (adv7511->cec_adap)) { ret =PTR_ERR (adv7511->cec_adap); goto err_cec_alloc;drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +0
-0
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c static int dw_hdmi_cec_probe(struct platform_device *pdev) · line 264
Quoted 5 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1
-1@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );
Hmm, the connector information is actually available through cec->hdmi.
I think it would make sense to create a helper function that fills in struct cec_connector_info based on a struct drm_connector pointer. And add a function to drivers/gpu/drm/bridge/synopsys/dw-hdmi.c that dw-hdmi-cec.c can call that does the same.
Quoted 80 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +0
-0if (IS_ERR (cec->adap))return PTR_ERR (cec->adap);drivers/gpu/drm/drm_dp_cec.c +15
-9@@ -8,7 +8,9 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <drm/drm_connector.h> #include <drm/drm_dp_helper.h> +#include <drm/drmP.h> #include <media/cec.h> /* @@ -295,7 +297,13 @@ static void drm_dp_cec_unregister_work(struct work_struct *work)*/ void drm_dp_cec_set_edid (struct drm_dp_aux *aux,const struct edid *edid) { +struct drm_connector *connector = aux->cec.connector;u32 cec_caps =CEC_CAP_DEFAULTS |CEC_CAP_NEEDS_HPD ; +struct cec_connector_info connector_info = { + .type =CEC_CONNECTOR_TYPE_DRM , + .drm.card_no = connector->dev->primary->index, + .drm.connector_id = connector->base.id + };unsigned int num_las =1 ;u8 cap;@@ -344,13 +352,13 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)/* Create a new adapter */ aux->cec.adap =cec_allocate_adapter (&drm_dp_cec_adap_ops, - aux, aux->cec.name, cec_caps, - num_las); + aux, connector->name, cec_caps, + num_las, &connector_info);if (IS_ERR (aux->cec.adap)) { aux->cec.adap =NULL ; goto unlock; } -if (cec_register_adapter (aux->cec.adap, aux->cec.parent)) { +if (cec_register_adapter (aux->cec.adap, connector->dev->dev)) {cec_delete_adapter (aux->cec.adap); aux->cec.adap =NULL ; }else {@@ -406,22 +414,20 @@ EXPORT_SYMBOL(drm_dp_cec_unset_edid);/** * drm_dp_cec_register_connector() - register a new connector * @aux: DisplayPort AUX channel -* @name: name of the CEC device -* @parent: parent device +* @connector: drm connector * * A new connector was registered with associated CEC adapter name and * CEC adapter parent device. After registering the name and parent * drm_dp_cec_set_edid() is called to check if the connector supports * CEC and to register a CEC adapter if that is the case. */ -void drm_dp_cec_register_connector (struct drm_dp_aux *aux,const char *name, -struct device *parent) +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector) {WARN_ON (aux->cec.adap);if (WARN_ON (!aux->transfer))return ; - aux->cec.name = name; - aux->cec.parent = parent; + aux->cec.connector = connector;INIT_DELAYED_WORK (&aux->cec.unregister_work, drm_dp_cec_unregister_work); }drivers/gpu/drm/i2c/tda9950.c +0
-0
drivers/gpu/drm/i2c/tda9950.c static int tda9950_probe(struct i2c_client *client, · line 428
Quoted 6 lines
drivers/gpu/drm/i2c/tda9950.c +2
-1@@ -424,7 +424,8 @@ static int tda9950_probe(struct i2c_client *client, priv->adap =cec_allocate_adapter (&tda9950_cec_ops, priv,"tda9950" ,CEC_CAP_DEFAULTS , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS , +NULL );
Here too the drm_connector can be found via struct tda9950_glue. So it is easy to provide proper connector information.
Quoted 35 lines
drivers/gpu/drm/i2c/tda9950.c +0
-0if (IS_ERR (priv->adap))return PTR_ERR (priv->adap);drivers/gpu/drm/i915/intel_dp.c +2
-3@@ -5550,7 +5550,6 @@ static int intel_dp_connector_register(struct drm_connector *connector) {struct intel_dp *intel_dp =intel_attached_dp (connector); -struct drm_device *dev = connector->dev;int ret; ret =intel_connector_register (connector);@@ -5565,8 +5564,7 @@ intel_dp_connector_register(struct drm_connector *connector) intel_dp->aux.dev = connector->kdev; ret =drm_dp_aux_register (&intel_dp->aux);if (!ret) -drm_dp_cec_register_connector (&intel_dp->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&intel_dp->aux, connector);return ret; }@@ -7435,3 +7433,4 @@ void intel_dp_mst_resume(struct drm_i915_private *dev_priv) } } } +drivers/gpu/drm/i915/intel_hdmi.c +0
-0
drivers/gpu/drm/i915/intel_hdmi.c void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, · line 3023
Quoted 3 lines
drivers/gpu/drm/i915/intel_hdmi.c +0
-0@@ -3021,8 +3021,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->cec_notifier =cec_notifier_get_conn (dev->dev,port_identifier (port));
The connector information should be added as an argument to cec_notifier_get_conn(). That way the notifier connector information is always set atomically.
drivers/gpu/drm/i915/intel_hdmi.c void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, · line 3031
Quoted 9 lines
drivers/gpu/drm/i915/intel_hdmi.c +8
-1-if (!intel_hdmi->cec_notifier) +if (intel_hdmi->cec_notifier) { +struct cec_connector_info info; + + info.type =CEC_CONNECTOR_TYPE_DRM ; + info.drm.card_no = connector->dev->primary->index; + info.drm.connector_id = connector->base.id; +cec_notifier_set_connector_info (intel_hdmi->cec_notifier, + &info);
So drop this function.
Quoted 25 lines
drivers/gpu/drm/i915/intel_hdmi.c +2
-0+ }else {DRM_DEBUG_KMS ("CEC notifier get failed\n" ); + } } void intel_hdmi_init(struct drm_i915_private *dev_priv,drivers/gpu/drm/nouveau/nouveau_connector.c +1
-2@@ -1413,8 +1413,7 @@ nouveau_connector_create(struct drm_device *dev,switch (type) {case DRM_MODE_CONNECTOR_DisplayPort:case DRM_MODE_CONNECTOR_eDP: -drm_dp_cec_register_connector (&nv_connector->aux, - connector->name, dev->dev); +drm_dp_cec_register_connector (&nv_connector->aux, connector);break ; }drivers/gpu/drm/vc4/vc4_hdmi.c +0
-0
drivers/gpu/drm/vc4/vc4_hdmi.c static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) · line 1421
Quoted 5 lines
drivers/gpu/drm/vc4/vc4_hdmi.c +1
-1@@ -1418,7 +1418,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)CEC_CAP_TRANSMIT |CEC_CAP_LOG_ADDRS |CEC_CAP_PASSTHROUGH | - CEC_CAP_RC, 1); + CEC_CAP_RC, 1, NULL);
Here too the drm_connector pointer is readily available.
Quoted 24 lines
drivers/gpu/drm/vc4/vc4_hdmi.c +0
-0ret =PTR_ERR_OR_ZERO (hdmi->cec_adap);if (ret <0 ) goto err_destroy_conn;drivers/media/cec/cec-api.c +9
-0@@ -187,6 +187,15 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,return 0 ; } +static long cec_adap_g_connector_info (struct cec_adapter *adap, +struct cec_log_addrs __user *parg) +{ +if (copy_to_user (parg, &adap->connector_info, +sizeof (adap->connector_info))) +return -EFAULT ; +return 0 ; +} +static long cec_transmit (struct cec_adapter *adap,struct cec_fh *fh,bool block,struct cec_msg __user *parg) {
drivers/media/cec/cec-api.c static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · line 528
Quoted 6 lines
drivers/media/cec/cec-api.c +3
-0@@ -514,6 +523,9 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)case CEC_ADAP_S_LOG_ADDRS :return cec_adap_s_log_addrs (adap, fh, block, parg); +case CEC_ADAP_G_CONNECTOR_INFO : +return cec_adap_g_connector_info (adap, parg); +
Note that this should be documented in Documentation/media/uapi/cec/.
Quoted 8 lines
drivers/media/cec/cec-api.c +0
-0case CEC_TRANSMIT :return cec_transmit (adap, fh, block, parg);drivers/media/cec/cec-core.c +0
-0
drivers/media/cec/cec-core.c void cec_register_cec_notifier(struct cec_adapter *adap, · line 199
Quoted 6 lines
drivers/media/cec/cec-core.c +2
-1@@ -195,7 +195,8 @@ void cec_register_cec_notifier(struct cec_adapter *adap,return ; adap->notifier = notifier; -cec_notifier_register (adap->notifier, adap, cec_cec_notify); +cec_notifier_register (adap->notifier, adap, + cec_cec_notify);
Unnecessary change.
drivers/media/cec/cec-core.c static const struct file_operations cec_error_inj_fops = { · line 256
Quoted 12 lines
drivers/media/cec/cec-core.c +3
-2}EXPORT_SYMBOL_GPL (cec_register_cec_notifier);#endif @@ -250,8 +251,9 @@ static const struct file_operations cec_error_inj_fops = {#endif struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps, -u8 available_las) +void *priv,const char *name,u32 caps, +u8 available_las, +struct cec_connector_info *connector_info)
Should be a const pointer.
drivers/media/cec/cec-notifier.c struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)
Quoted 28 lines
drivers/media/cec/cec-core.c +5
-0{struct cec_adapter *adap;int res;@@ -288,6 +290,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,INIT_LIST_HEAD (&adap->wait_queue);init_waitqueue_head (&adap->kthread_waitq); +if (connector_info) + adap->connector_info = *connector_info; +else + adap->connector_info.type =CEC_CONNECTOR_TYPE_NO_CONNECTOR ; +/* adap->devnode initialization */ INIT_LIST_HEAD (&adap->devnode.fhs);mutex_init (&adap->devnode.lock);drivers/media/cec/cec-notifier.c +1
-0@@ -26,6 +26,7 @@ struct cec_notifier {void (*callback)(struct cec_adapter *adap,u16 pa);u16 phys_addr; +struct cec_connector_info connector_info; };static LIST_HEAD (cec_notifiers);@@ -51,6 +52,7 @@ struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)
The connector info should be passed as an argument.
Quoted 8 lines
drivers/media/cec/cec-notifier.c +1
-0if (conn) n->conn =kstrdup (conn,GFP_KERNEL ); n->phys_addr =CEC_PHYS_ADDR_INVALID ; + n->connector_info.type =CEC_CONNECTOR_TYPE_NO_CONNECTOR ;mutex_init (&n->lock);kref_init (&n->kref);list_add_tail (&n->head, &cec_notifiers);
drivers/media/cec/cec-notifier.c void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 116
Quoted 9 lines
drivers/media/cec/cec-notifier.c +6
-0@@ -106,9 +108,24 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, }EXPORT_SYMBOL_GPL (cec_notifier_set_phys_addr_from_edid); +void cec_notifier_set_connector_info (struct cec_notifier *n, +struct cec_connector_info *c) +{ +memcpy (&n->connector_info, c,sizeof (*c)); +} +EXPORT_SYMBOL_GPL (cec_notifier_set_connector_info);
Drop this function.
drivers/media/cec/cec-notifier.c void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 118
Quoted 2 lines
drivers/media/cec/cec-notifier.c +2
-0+ +struct cec_connector_info *cec_notifier_get_connector_info(
const
drivers/media/cec/cec-notifier.c void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 119
Quoted 1 line
drivers/media/cec/cec-notifier.c +1
-0+ struct cec_notifier *n)
const
drivers/media/cec/cec-notifier.c void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 128
Quoted 10 lines
drivers/media/cec/cec-notifier.c +7
-1+{ +return &n->connector_info; +} +EXPORT_SYMBOL_GPL (cec_notifier_get_connector_info); +void cec_notifier_register (struct cec_notifier *n,struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +void (*callback)(struct cec_adapter *adap, +u16 pa))
Unnecessary change.
Quoted 22 lines
drivers/media/cec/cec-notifier.c +0
-0{kref_get (&n->kref);mutex_lock (&n->lock);drivers/media/i2c/tc358743.c +2
-1@@ -2117,7 +2117,8 @@ static int tc358743_probe(struct i2c_client *client,#ifdef CONFIG_VIDEO_TC358743_CEC state->cec_adap =cec_allocate_adapter (&tc358743_cec_adap_ops, state,dev_name (&client->dev), -CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS ); +CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL ,CEC_MAX_LOG_ADDRS , +NULL );if (IS_ERR (state->cec_adap)) { err =PTR_ERR (state->cec_adap); goto err_hdl;drivers/media/platform/cros-ec-cec/cros-ec-cec.c +0
-0
drivers/media/platform/cros-ec-cec/cros-ec-cec.c static int cros_ec_cec_probe(struct platform_device *pdev) · line 287
Quoted 7 lines
drivers/media/platform/cros-ec-cec/cros-ec-cec.c +3
-1@@ -282,7 +282,9 @@ static int cros_ec_cec_probe(struct platform_device *pdev) } cros_ec_cec->adap =cec_allocate_adapter (&cros_ec_cec_ops, cros_ec_cec, -DRV_NAME ,CEC_CAP_DEFAULTS ,1 ); +DRV_NAME ,CEC_CAP_DEFAULTS ,1 , +cec_notifier_get_connector_info ( + cros_ec_cec->notify));
This is probably more readable if the connector info is assigned to a temp variable first.
drivers/media/platform/meson/ao-cec.c static int meson_ao_cec_probe(struct platform_device *pdev) · line 635
Quoted 13 lines
drivers/media/platform/cros-ec-cec/cros-ec-cec.c +0
-0if (IS_ERR (cros_ec_cec->adap))return PTR_ERR (cros_ec_cec->adap);drivers/media/platform/meson/ao-cec.c +1
-1@@ -632,7 +632,8 @@ static int meson_ao_cec_probe(struct platform_device *pdev)CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , - 1); /* Use 1 for now */ + 1 /* Use 1 for now */,
Please put the , after 1, so: 1, /* Use 1 for now */
drivers/media/platform/meson/ao-cec.c static int meson_ao_cec_probe(struct platform_device *pdev) · line 636
Quoted 1 line
drivers/media/platform/meson/ao-cec.c +1
-0+ NULL);
Here too you need to pass the connector info obtained from the notifier. This is true for all drivers that call cec_register_cec_notifier().
Quoted 8 lines
drivers/media/platform/meson/ao-cec.c +0
-0if (IS_ERR (ao_cec->adap)) { ret =PTR_ERR (ao_cec->adap); goto out_probe_notify;drivers/media/platform/s5p-cec/s5p_cec.c +0
-0
drivers/media/platform/s5p-cec/s5p_cec.c static int s5p_cec_probe(struct platform_device *pdev) · line 233
Quoted 6 lines
drivers/media/platform/s5p-cec/s5p_cec.c +2
-1@@ -229,7 +229,8 @@ static int s5p_cec_probe(struct platform_device *pdev)return -ENOMEM ; cec->adap =cec_allocate_adapter (&s5p_cec_adap_ops, cec,CEC_NAME , -CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 ); +CEC_CAP_DEFAULTS | (needs_hpd ?CEC_CAP_NEEDS_HPD :0 ),1 , +NULL );
Ditto.
drivers/media/platform/sti/cec/stih-cec.c static int stih_cec_probe(struct platform_device *pdev) · line 351
Quoted 13 lines
drivers/media/platform/s5p-cec/s5p_cec.c +0
-0ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;drivers/media/platform/sti/cec/stih-cec.c +1
-1@@ -348,7 +348,7 @@ static int stih_cec_probe(struct platform_device *pdev) } cec->adap =cec_allocate_adapter (&sti_cec_adap_ops, cec, -CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS ); +CEC_NAME ,CEC_CAP_DEFAULTS ,CEC_MAX_LOG_ADDRS ,NULL );
Ditto.
Quoted 21 lines
drivers/media/platform/sti/cec/stih-cec.c +0
-0ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;drivers/media/platform/stm32/stm32-cec.c +1
-1@@ -304,7 +304,7 @@ static int stm32_cec_probe(struct platform_device *pdev)* available for example when a drm driver can provide edid */ cec->adap =cec_allocate_adapter (&stm32_cec_adap_ops, cec, -CEC_NAME , caps,CEC_MAX_LOG_ADDRS ); +CEC_NAME , caps,CEC_MAX_LOG_ADDRS ,NULL ); ret =PTR_ERR_OR_ZERO (cec->adap);if (ret)return ret;drivers/media/platform/tegra-cec/tegra_cec.c +0
-0
drivers/media/platform/tegra-cec/tegra_cec.c static int tegra_cec_probe(struct platform_device *pdev) · line 411
Quoted 5 lines
drivers/media/platform/tegra-cec/tegra_cec.c +1
-1@@ -408,7 +408,7 @@ static int tegra_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&tegra_cec_ops, cec,TEGRA_CEC_NAME ,CEC_CAP_DEFAULTS |CEC_CAP_MONITOR_ALL , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,0 );
Ditto.
Quoted 119 lines
drivers/media/platform/tegra-cec/tegra_cec.c +0
-0if (IS_ERR (cec->adap)) { ret = -ENOMEM ;dev_err (&pdev->dev,"Couldn't create cec adapter\n" );drivers/media/platform/vivid/vivid-cec.c +1
-1@@ -283,5 +283,5 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, idx);return cec_allocate_adapter (&vivid_cec_adap_ops, dev, - name, caps,1 ); + name, caps,1 ,NULL ); }drivers/media/usb/pulse8-cec/pulse8-cec.c +2
-1@@ -656,7 +656,8 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->serio = serio; pulse8->adap =cec_allocate_adapter (&pulse8_cec_adap_ops, pulse8, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (pulse8->adap);if (err <0 ) goto free_device;drivers/media/usb/rainshadow-cec/rainshadow-cec.c +2
-1@@ -323,7 +323,8 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv) rain->serio = serio; rain->adap =cec_allocate_adapter (&rain_cec_adap_ops, rain, -dev_name (&serio->dev), caps,1 ); +dev_name (&serio->dev), caps,1 , +NULL ); err =PTR_ERR_OR_ZERO (rain->adap);if (err <0 ) goto free_device;include/drm/drm_dp_helper.h +7
-7@@ -1208,6 +1208,7 @@ struct drm_dp_aux_msg {struct cec_adapter ;struct edid ; +struct drm_connector ;/** * struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX @@ -1220,8 +1221,7 @@ struct edid;struct drm_dp_aux_cec {struct mutex lock;struct cec_adapter *adap; -const char *name; -struct device *parent; +struct drm_connector *connector;struct delayed_work unregister_work; };@@ -1418,8 +1418,8 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)#ifdef CONFIG_DRM_DP_CEC void drm_dp_cec_irq (struct drm_dp_aux *aux); -void drm_dp_cec_register_connector (struct drm_dp_aux *aux,const char *name, -struct device *parent); +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector);void drm_dp_cec_unregister_connector (struct drm_dp_aux *aux);void drm_dp_cec_set_edid (struct drm_dp_aux *aux,const struct edid *edid);void drm_dp_cec_unset_edid (struct drm_dp_aux *aux);@@ -1428,9 +1428,9 @@ static inline void drm_dp_cec_irq(struct drm_dp_aux *aux) { } -static inline void drm_dp_cec_register_connector (struct drm_dp_aux *aux, -const char *name, -struct device *parent) +static inline +void drm_dp_cec_register_connector (struct drm_dp_aux *aux, +struct drm_connector *connector) { }include/media/cec-notifier.h +16
-0@@ -63,6 +63,21 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);void cec_notifier_set_phys_addr_from_edid (struct cec_notifier *n,const struct edid *edid); +/** +* cec_notifier_get_connector_info - get connector info associatied with +* a notifier +* @n: the CEC notifier +*/ +struct cec_connector_info *cec_notifier_get_connector_info ( +struct cec_notifier *n); + +/** +* cec_notifier_set_connector_info - associates connector info with a notifier +* @n: the CEC notifier +* @c: the connector info +*/ +void cec_notifier_set_connector_info (struct cec_notifier *n, +struct cec_connector_info *c);/** * cec_notifier_register - register a callback with the notifier * @n: the CEC notifier @@ -108,9 +123,21 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, { } +static inline const struct cec_connector_info*
include/media/cec-notifier.h static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 136
Quoted 10 lines
include/media/cec-notifier.h +10
-0+ cec_notifier_get_connector_info(struct cec_notifier *n) +{ +return NULL ; +} + +static inline void cec_notifier_set_connector_info ( +struct cec_notifier *n, +struct cec_connector_info *c) +{ +}
Can be dropped.
include/media/cec-notifier.h static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, · line 142
Quoted 8 lines
include/media/cec-notifier.h +3
-2+static inline void cec_notifier_register (struct cec_notifier *n, -struct cec_adapter *adap, -void (*callback)(struct cec_adapter *adap,u16 pa)) +struct cec_adapter *adap, +void (*callback)(struct cec_adapter *adap,u16 pa)) { }
Unnecessary change.
Quoted 37 lines
include/media/cec.h +4
-2@@ -200,6 +200,8 @@ struct cec_adapter {u32 sequence;char input_phys[32 ]; + +struct cec_connector_info connector_info; };static inline void *cec_get_drvdata (const struct cec_adapter *adap)@@ -236,7 +238,8 @@ struct edid;#if IS_REACHABLE (CONFIG_CEC_CORE )struct cec_adapter *cec_allocate_adapter (const struct cec_adap_ops *ops, -void *priv,const char *name,u32 caps,u8 available_las); +void *priv,const char *name,u32 caps,u8 available_las, +struct cec_connector_info *connector_info);int cec_register_adapter (struct cec_adapter *adap,struct device *parent);void cec_unregister_adapter (struct cec_adapter *adap);void cec_delete_adapter (struct cec_adapter *adap);@@ -249,7 +252,6 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, const struct edid *edid);int cec_transmit_msg (struct cec_adapter *adap,struct cec_msg *msg,bool block); -/* Called by the adapter */ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,include/uapi/linux/cec.h +0
-0
include/uapi/linux/cec.h struct cec_event_lost_msgs { · line 417
Quoted 7 lines
include/uapi/linux/cec.h +4
-0@@ -411,6 +411,27 @@ struct cec_event_lost_msgs {__u32 lost_msgs; }; +/** +* struct cec_event_connector - tells if and which connector is associated +* with the CEC adapter. +* @card_no: drm card number, -1 if no connector
If there is no connector, then type is NO_CONNECTOR. So this doesn't make sense. Wouldn't it be better to just use '__u32 card_no'?
include/uapi/linux/cec.h struct cec_event_lost_msgs { · line 428
Quoted 11 lines
include/uapi/linux/cec.h +11
-0+* @connector_id: drm connector id. +*/ +struct cec_drm_connector_info { +int card_no; +__u32 connector_id; +}; + +#define CEC_CONNECTOR_TYPE_NO_CONNECTOR 0 +#define CEC_CONNECTOR_TYPE_DRM 1 +struct cec_connector_info { +int type;
__u32 type;
Quoted 11 lines
include/uapi/linux/cec.h +6
-0+union { +struct cec_drm_connector_info drm; +__u32 raw[16 ]; + }; +}; +/** * struct cec_event - CEC event structure * @ts: the timestamp of when the event was sent.
include/uapi/linux/cec.h struct cec_event { · line 504
Quoted 9 lines
include/uapi/linux/cec.h +3
-0@@ -475,6 +496,9 @@ struct cec_event {#define CEC_G_MODE _IOR('a', 8, __u32)#define CEC_S_MODE _IOW('a', 9, __u32) +/* Gets the connector info */ +#define CEC_ADAP_G_CONNECTOR_INFO _IOR('a', 10, struct cec_connector_info) +/* * The remainder of this header defines all CEC messages and operands. * The format matters since it the cec-ctl utility parses it to generate
Regards,
Hans
Hi Hans.
Quoted 8 lines · Hans Verkuil
Hi Dariusz,
This is getting close, so I think for the next version you can drop the RFC tag.
Some comments:
...
Quoted 10 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c static int dw_hdmi_cec_probe(struct platform_device *pdev) · line 264
Quoted 7 lines
+++
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.cdrivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1
-1@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );Hmm, the connector information is actually available through
cec->hdmi.
Quoted 4 lines
I think it would make sense to create a helper function that fills in struct
cec_connector_infobased on a structdrm_connectorpointer. And add a function todrivers/gpu/drm/bridge/synopsys/dw-hdmi.cthatdw-hdmi-cec.ccan call that does the same.
Looking at the code here, is the connector info guaranteed to be available at the time cec_allocate_adapter is called here? drm_connector won't be initialized until dw_hdmi_bridge_attach is called, which happens after the cec platform device is created.
...
Quoted 8 lines
drivers/gpu/drm/i2c/tda9950.c static int tda9950_probe(struct i2c_client *client, · line 428
Quoted 5 lines
drivers/gpu/drm/i2c/tda9950.c +2
-1priv->adap =cec_allocate_adapter (&tda9950_cec_ops, priv,"tda9950" ,CEC_CAP_DEFAULTS , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS , +NULL );Here too the
drm_connectorcan be found via structtda9950_glue. So it is easy to provide proper connector information.
The same concern as with the comment before.
...
Quoted 8 lines
Quoted 4 lines
+/**
+ * structcec_event_connector- tells if and which connector is associated
+ * with the CEC adapter.
+ * @card_no: drm card number, -1 if no connectorIf there is no connector, then type is
NO_CONNECTOR. So this doesn't make sense. Wouldn't it be better to just use '__u32card_no'?
Yes, removed (leftover from previous revision where there was no connector type field).
This and remaining comments are (hopefully) resolved in the new version of the patch, I've just sent.
Will add more docs in subsequent revs.
Thank you!
Quoted 27 lines · Dariusz Marcinkiewicz
Hi Hans.
Quoted 8 lines · Hans Verkuil
Hi Dariusz,
This is getting close, so I think for the next version you can drop the RFC tag.
Some comments:
...
Quoted 10 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c static int dw_hdmi_cec_probe(struct platform_device *pdev) · line 264
Quoted 7 lines
+++
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.cdrivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1
-1@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );Hmm, the connector information is actually available through
cec->hdmi.Quoted 4 lines
I think it would make sense to create a helper function that fills in struct
cec_connector_infobased on a structdrm_connectorpointer. And add a function todrivers/gpu/drm/bridge/synopsys/dw-hdmi.cthatdw-hdmi-cec.ccan call that does the same.
Quoted 4 lines
Looking at the code here, is the connector info guaranteed to be available at the time
cec_allocate_adapteris called here?drm_connectorwon't be initialized untildw_hdmi_bridge_attachis called, which happens after the cec platform device is created.
Good point. The creation of the cec platform device should probably be moved to dw_hdmi_bridge_attach.
Quoted 11 lines
...
Quoted 8 lines
drivers/gpu/drm/i2c/tda9950.c static int tda9950_probe(struct i2c_client *client, · line 428
Quoted 5 lines
priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950", CEC_CAP_DEFAULTS,drivers/gpu/drm/i2c/tda9950.c +2
-1- CEC_MAX_LOG_ADDRS); +CEC_MAX_LOG_ADDRS , + NULL);Here too the
drm_connectorcan be found via structtda9950_glue. So it is easy to provide proper connector information.The same concern as with the comment before.
Same solution: this has to be moved.
I have hardware to test patches for both drivers. It might take 2-3 weeks before I can test as I don't always has access to the hardware, but at least I can verify that moving this code won't break anything.
It's best to first move the code in separate patches before applying the "expose HDMI connector to CEC dev mapping" patch on top of them.
Quoted 9 lines
...
Quoted 8 lines
Quoted 4 lines
+/**
+ * structcec_event_connector- tells if and which connector is associated
+ * with the CEC adapter.
+ * @card_no: drm card number, -1 if no connectorIf there is no connector, then type is
NO_CONNECTOR. So this doesn't make sense. Wouldn't it be better to just use '__u32card_no'?
Quoted 9 lines
Yes, removed (leftover from previous revision where there was no connector type field).
This and remaining comments are (hopefully) resolved in the new version of the patch, I've just sent.Will add more docs in subsequent revs.
Thank you!
Regards,
Hans
Hi Hans.
From: Hans Verkuil <[email protected]>
Date: Thu, May 9, 2019 at 11:31 AM
To: Dariusz Marcinkiewicz
Cc: <[email protected]>, <[email protected]>, <[email protected]>
Quoted 48 lines · Dariusz Marcinkiewicz
Quoted 27 lines
Hi Hans.
Quoted 8 lines · Hans Verkuil
Hi Dariusz,
This is getting close, so I think for the next version you can drop the RFC tag.
Some comments:
...
Quoted 10 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c static int dw_hdmi_cec_probe(struct platform_device *pdev) · line 264
Quoted 7 lines
+++
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.cdrivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1
-1@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );Hmm, the connector information is actually available through
cec->hdmi.Quoted 4 lines
I think it would make sense to create a helper function that fills in struct
cec_connector_infobased on a structdrm_connectorpointer. And add a function todrivers/gpu/drm/bridge/synopsys/dw-hdmi.cthatdw-hdmi-cec.ccan call that does the same.Quoted 4 lines
Looking at the code here, is the connector info guaranteed to be available at the time
cec_allocate_adapteris called here?drm_connectorwon't be initialized untildw_hdmi_bridge_attachis called, which happens after the cec platform device is created.Good point. The creation of the cec platform device should probably be moved to
dw_hdmi_bridge_attach.Quoted 11 lines
...
Quoted 8 lines
drivers/gpu/drm/i2c/tda9950.c static int tda9950_probe(struct i2c_client *client, · line 428
Quoted 5 lines
priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950", CEC_CAP_DEFAULTS,drivers/gpu/drm/i2c/tda9950.c +2
-1- CEC_MAX_LOG_ADDRS); +CEC_MAX_LOG_ADDRS , + NULL);Here too the
drm_connectorcan be found via structtda9950_glue. So it is easy to provide proper connector information.The same concern as with the comment before.
Quoted 9 lines
Same solution: this has to be moved.
I have hardware to test patches for both drivers. It might take 2-3 weeks before I can test as I don't always has access to the hardware, but at least I can verify that moving this code won't break anything.
It's best to first move the code in separate patches before applying the "expose HDMI connector to CEC dev mapping" patch on top of them.
I've submitted another revision of the changes, with those 2 patches added on top. Hope that is ok.
Please take a look. It would be great if you could give those 2 patches a go on an actual hardware.
Thank you and best regards.
Quoted 66 lines · Dariusz Marcinkiewicz
Hi Hans.
From: Hans Verkuil <[email protected]>
Date: Thu, May 9, 2019 at 11:31 AM
To: Dariusz Marcinkiewicz
Cc: <[email protected]>, <[email protected]>, <[email protected]>Quoted 48 lines · Dariusz Marcinkiewicz
Quoted 27 lines
Hi Hans.
Quoted 8 lines · Hans Verkuil
Hi Dariusz,
This is getting close, so I think for the next version you can drop the RFC tag.
Some comments:
...
Quoted 10 lines
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c static int dw_hdmi_cec_probe(struct platform_device *pdev) · line 264
Quoted 7 lines
+++
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.cdrivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +1
-1@@ -261,7 +261,7 @@ static int dw_hdmi_cec_probe(struct platform_device *pdev) cec->adap =cec_allocate_adapter (&dw_hdmi_cec_ops, cec,"dw_hdmi" ,CEC_CAP_LOG_ADDRS |CEC_CAP_TRANSMIT |CEC_CAP_RC |CEC_CAP_PASSTHROUGH , -CEC_MAX_LOG_ADDRS ); +CEC_MAX_LOG_ADDRS ,NULL );Hmm, the connector information is actually available through
cec->hdmi.Quoted 4 lines
I think it would make sense to create a helper function that fills in struct
cec_connector_infobased on a structdrm_connectorpointer. And add a function todrivers/gpu/drm/bridge/synopsys/dw-hdmi.cthatdw-hdmi-cec.ccan call that does the same.Quoted 4 lines
Looking at the code here, is the connector info guaranteed to be available at the time
cec_allocate_adapteris called here?drm_connectorwon't be initialized untildw_hdmi_bridge_attachis called, which happens after the cec platform device is created.Good point. The creation of the cec platform device should probably be moved to
dw_hdmi_bridge_attach.Quoted 11 lines
...
Quoted 8 lines
drivers/gpu/drm/i2c/tda9950.c static int tda9950_probe(struct i2c_client *client, · line 428
Quoted 5 lines
priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950", CEC_CAP_DEFAULTS,drivers/gpu/drm/i2c/tda9950.c +2
-1- CEC_MAX_LOG_ADDRS); +CEC_MAX_LOG_ADDRS , + NULL);Here too the
drm_connectorcan be found via structtda9950_glue. So it is easy to provide proper connector information.The same concern as with the comment before.
Quoted 9 lines
Same solution: this has to be moved.
I have hardware to test patches for both drivers. It might take 2-3 weeks before I can test as I don't always has access to the hardware, but at least I can verify that moving this code won't break anything.
It's best to first move the code in separate patches before applying the "expose HDMI connector to CEC dev mapping" patch on top of them.
Quoted 5 lines
I've submitted another revision of the changes, with those 2 patches added on top. Hope that is ok.
Please take a look. It would be great if you could give those 2 patches a go on an actual hardware.
I should be able to test the dw-hdmi patch next week, but testing the tda9950 patch has to wait until the week after that.
Regards,
Hans
Quoted 3 lines
Thank you and best regards.