From 32a847f9fa40ec1b03ead2c514862764983ff9ca Mon Sep 17 00:00:00 2001 From: Dariusz Marcinkiewicz Date: Thu, 20 Jun 2019 05:17:18 -0400 Subject: [PATCH] media: cec: add struct cec_connector_info support Define struct cec_connector_info in media/cec.h and define CEC_CAP_CONNECTOR_INFO. In a later patch this will be moved to uapi/linux/cec.h. The CEC_CAP_CONNECTOR_INFO capability can be set by drivers, but cec_allocate_adapter() will remove it again until the public API for this can be enabled once all drm drivers wire this up correctly. Also add the cec_fill_conn_info_from_drm and cec_s_conn_info functions, which are needed by drm drivers to fill in the cec_connector info based on a drm_connector. The cec_notifier_(un)register and cec_register_cec_notifier prototypes were moved from cec-notifier.h to cec.h since cec.h no longer includes cec-notifier.h. These headers included each other before, which caused various problems. Due to these changes the seco-cec driver was changed as well: it should include cec-notifier.h, not cec.h. Signed-off-by: Dariusz Marcinkiewicz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 29 +++++++ drivers/media/cec/cec-core.c | 5 ++ drivers/media/platform/seco-cec/seco-cec.c | 2 +- include/media/cec-notifier.h | 39 --------- include/media/cec.h | 98 +++++++++++++++++++++- 5 files changed, 132 insertions(+), 41 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index ac3683a7b2ab..451c61bde4d4 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -16,7 +16,10 @@ #include #include +#include +#include #include +#include #include "cec-priv.h" @@ -75,6 +78,16 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, } EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr); +void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info, + const struct drm_connector *connector) +{ + memset(conn_info, 0, sizeof(*conn_info)); + conn_info->type = CEC_CONNECTOR_TYPE_DRM; + conn_info->drm.card_no = connector->dev->primary->index; + conn_info->drm.connector_id = connector->base.id; +} +EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm); + /* * Queue a new event for this filehandle. If ts == 0, then set it * to the current time. @@ -1598,6 +1611,22 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, } EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid); +void cec_s_conn_info(struct cec_adapter *adap, + const struct cec_connector_info *conn_info) +{ + if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO)) + return; + + mutex_lock(&adap->lock); + if (conn_info) + adap->conn_info = *conn_info; + else + memset(&adap->conn_info, 0, sizeof(adap->conn_info)); + cec_post_state_event(adap); + mutex_unlock(&adap->lock); +} +EXPORT_SYMBOL_GPL(cec_s_conn_info); + /* * Called from either the ioctl or a driver to set the logical addresses. * diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index db7adffcdc76..9c610e1e99b8 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -257,6 +257,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, struct cec_adapter *adap; int res; + /* + * Disable this capability until the connector info public API + * is ready. + */ + caps &= ~CEC_CAP_CONNECTOR_INFO; #ifndef CONFIG_MEDIA_CEC_RC caps &= ~CEC_CAP_RC; #endif diff --git a/drivers/media/platform/seco-cec/seco-cec.c b/drivers/media/platform/seco-cec/seco-cec.c index e5080d6f5b2d..1d0133f01e00 100644 --- a/drivers/media/platform/seco-cec/seco-cec.c +++ b/drivers/media/platform/seco-cec/seco-cec.c @@ -18,7 +18,7 @@ #include /* CEC Framework */ -#include +#include #include "seco-cec.h" diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index 57b3a9f6ea1d..0e3bd3415724 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h @@ -63,30 +63,6 @@ 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_register - register a callback with the notifier - * @n: the CEC notifier - * @adap: the CEC adapter, passed as argument to the callback function - * @callback: the callback function - */ -void cec_notifier_register(struct cec_notifier *n, - struct cec_adapter *adap, - void (*callback)(struct cec_adapter *adap, u16 pa)); - -/** - * cec_notifier_unregister - unregister the callback from the notifier. - * @n: the CEC notifier - */ -void cec_notifier_unregister(struct cec_notifier *n); - -/** - * cec_register_cec_notifier - register the notifier with the cec adapter. - * @adap: the CEC adapter - * @notifier: the CEC notifier - */ -void cec_register_cec_notifier(struct cec_adapter *adap, - struct cec_notifier *notifier); - /** * cec_notifier_parse_hdmi_phandle - find the hdmi device from "hdmi-phandle" * @dev: the device with the "hdmi-phandle" device tree property @@ -119,21 +95,6 @@ static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, { } -static inline void cec_notifier_register(struct cec_notifier *n, - struct cec_adapter *adap, - void (*callback)(struct cec_adapter *adap, u16 pa)) -{ -} - -static inline void cec_notifier_unregister(struct cec_notifier *n) -{ -} - -static inline void cec_register_cec_notifier(struct cec_adapter *adap, - struct cec_notifier *notifier) -{ -} - static inline struct device *cec_notifier_parse_hdmi_phandle(struct device *dev) { return ERR_PTR(-ENODEV); diff --git a/include/media/cec.h b/include/media/cec.h index 707411ef8ba2..4d59387bc61b 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -17,7 +17,9 @@ #include #include #include -#include + +/* CEC_ADAP_G_CONNECTOR_INFO is available */ +#define CEC_CAP_CONNECTOR_INFO (1 << 8) #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \ CEC_CAP_PASSTHROUGH | CEC_CAP_RC) @@ -53,6 +55,7 @@ struct cec_devnode { struct cec_adapter; struct cec_data; struct cec_pin; +struct cec_notifier; struct cec_data { struct list_head list; @@ -144,6 +147,34 @@ struct cec_adap_ops { */ #define CEC_MAX_MSG_TX_QUEUE_SZ (18 * 1) +/** + * struct cec_drm_connector_info - tells which drm connector is + * associated with the CEC adapter. + * @card_no: drm card number + * @connector_id: drm connector ID + */ +struct cec_drm_connector_info { + __u32 card_no; + __u32 connector_id; +}; + +#define CEC_CONNECTOR_TYPE_NO_CONNECTOR 0 +#define CEC_CONNECTOR_TYPE_DRM 1 + +/** + * struct cec_connector_info - tells if and which connector is + * associated with the CEC adapter. + * @type: connector type (if any) + * @drm: drm connector info + */ +struct cec_connector_info { + __u32 type; + union { + struct cec_drm_connector_info drm; + __u32 raw[16]; + }; +}; + struct cec_adapter { struct module *owner; char name[32]; @@ -182,6 +213,7 @@ struct cec_adapter { struct cec_fh *cec_initiator; bool passthrough; struct cec_log_addrs log_addrs; + struct cec_connector_info conn_info; u32 tx_timeouts; @@ -233,6 +265,7 @@ static inline bool cec_is_registered(const struct cec_adapter *adap) ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf struct edid; +struct drm_connector; #if IS_REACHABLE(CONFIG_CEC_CORE) struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, @@ -247,6 +280,8 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block); void cec_s_phys_addr_from_edid(struct cec_adapter *adap, const struct edid *edid); +void cec_s_conn_info(struct cec_adapter *adap, + const struct cec_connector_info *conn_info); int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, bool block); @@ -331,6 +366,9 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts); u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, unsigned int *offset); +void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info, + const struct drm_connector *connector); + #else static inline int cec_register_adapter(struct cec_adapter *adap, @@ -365,6 +403,64 @@ static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, return CEC_PHYS_ADDR_INVALID; } +static inline void cec_s_conn_info(struct cec_adapter *adap, + const struct cec_connector_info *conn_info) +{ +} + +static inline void +cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info, + const struct drm_connector *connector) +{ + memset(conn_info, 0, sizeof(*conn_info)); +} + +#endif + +#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) + +/** + * cec_notifier_register - register a callback with the notifier + * @n: the CEC notifier + * @adap: the CEC adapter, passed as argument to the callback function + * @callback: the callback function + */ +void cec_notifier_register(struct cec_notifier *n, + struct cec_adapter *adap, + void (*callback)(struct cec_adapter *adap, u16 pa)); + +/** + * cec_notifier_unregister - unregister the callback from the notifier. + * @n: the CEC notifier + */ +void cec_notifier_unregister(struct cec_notifier *n); + +/** + * cec_register_cec_notifier - register the notifier with the cec adapter. + * @adap: the CEC adapter + * @notifier: the CEC notifier + */ +void cec_register_cec_notifier(struct cec_adapter *adap, + struct cec_notifier *notifier); + +#else + +static inline void +cec_notifier_register(struct cec_notifier *n, + struct cec_adapter *adap, + void (*callback)(struct cec_adapter *adap, u16 pa)) +{ +} + +static inline void cec_notifier_unregister(struct cec_notifier *n) +{ +} + +static inline void cec_register_cec_notifier(struct cec_adapter *adap, + struct cec_notifier *notifier) +{ +} + #endif /**