Commit 2c6d1fff authored by Hans Verkuil's avatar Hans Verkuil Committed by Ville Syrjälä

drm: add support for DisplayPort CEC-Tunneling-over-AUX

This adds support for the DisplayPort CEC-Tunneling-over-AUX
feature that is part of the DisplayPort 1.3 standard.

Unfortunately, not all DisplayPort/USB-C to HDMI adapters with a
chip that has this capability actually hook up the CEC pin, so
even though a CEC device is created, it may not actually work.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180711132909.25409-2-hverkuil@xs4all.nl
parent cf19fa2c
...@@ -122,6 +122,16 @@ config DRM_LOAD_EDID_FIRMWARE ...@@ -122,6 +122,16 @@ config DRM_LOAD_EDID_FIRMWARE
default case is N. Details and instructions how to build your own default case is N. Details and instructions how to build your own
EDID data are given in Documentation/EDID/HOWTO.txt. EDID data are given in Documentation/EDID/HOWTO.txt.
config DRM_DP_CEC
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
select CEC_CORE
help
Choose this option if you want to enable HDMI CEC support for
DisplayPort/USB-C to HDMI adapters.
Note: not all adapters support this feature, and even for those
that do support this they often do not hook up the CEC pin.
config DRM_TTM config DRM_TTM
tristate tristate
depends on DRM && MMU depends on DRM && MMU
......
...@@ -41,6 +41,7 @@ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o ...@@ -41,6 +41,7 @@ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
......
This diff is collapsed.
...@@ -1087,6 +1087,7 @@ static void drm_dp_aux_crc_work(struct work_struct *work) ...@@ -1087,6 +1087,7 @@ static void drm_dp_aux_crc_work(struct work_struct *work)
void drm_dp_aux_init(struct drm_dp_aux *aux) void drm_dp_aux_init(struct drm_dp_aux *aux)
{ {
mutex_init(&aux->hw_mutex); mutex_init(&aux->hw_mutex);
mutex_init(&aux->cec.lock);
INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work); INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
aux->ddc.algo = &drm_dp_i2c_algo; aux->ddc.algo = &drm_dp_i2c_algo;
......
...@@ -1078,6 +1078,25 @@ struct drm_dp_aux_msg { ...@@ -1078,6 +1078,25 @@ struct drm_dp_aux_msg {
size_t size; size_t size;
}; };
struct cec_adapter;
struct edid;
/**
* struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
* @lock: mutex protecting this struct
* @adap: the CEC adapter for CEC-Tunneling-over-AUX support.
* @name: name of the CEC adapter
* @parent: parent device of the CEC adapter
* @unregister_work: unregister the CEC adapter
*/
struct drm_dp_aux_cec {
struct mutex lock;
struct cec_adapter *adap;
const char *name;
struct device *parent;
struct delayed_work unregister_work;
};
/** /**
* struct drm_dp_aux - DisplayPort AUX channel * struct drm_dp_aux - DisplayPort AUX channel
* @name: user-visible name of this AUX channel and the I2C-over-AUX adapter * @name: user-visible name of this AUX channel and the I2C-over-AUX adapter
...@@ -1136,6 +1155,10 @@ struct drm_dp_aux { ...@@ -1136,6 +1155,10 @@ struct drm_dp_aux {
* @i2c_defer_count: Counts I2C DEFERs, used for DP validation. * @i2c_defer_count: Counts I2C DEFERs, used for DP validation.
*/ */
unsigned i2c_defer_count; unsigned i2c_defer_count;
/**
* @cec: struct containing fields used for CEC-Tunneling-over-AUX.
*/
struct drm_dp_aux_cec cec;
}; };
ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
...@@ -1258,4 +1281,37 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk) ...@@ -1258,4 +1281,37 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)
return desc->quirks & BIT(quirk); return desc->quirks & BIT(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_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);
#else
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_unregister_connector(struct drm_dp_aux *aux)
{
}
static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
const struct edid *edid)
{
}
static inline void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
{
}
#endif
#endif /* _DRM_DP_HELPER_H_ */ #endif /* _DRM_DP_HELPER_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment