1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright (c) 2024 Linaro Ltd 4 */ 5 6 #include <drm/drm_bridge.h> 7 #include <drm/drm_connector.h> 8 #include <drm/drm_managed.h> 9 #include <drm/display/drm_hdmi_cec_helper.h> 10 11 #include <linux/mutex.h> 12 13 #include <media/cec.h> 14 #include <media/cec-notifier.h> 15 16 static void drm_connector_hdmi_cec_notifier_phys_addr_invalidate(struct drm_connector *connector) 17 { 18 cec_notifier_phys_addr_invalidate(connector->cec.data); 19 } 20 21 static void drm_connector_hdmi_cec_notifier_phys_addr_set(struct drm_connector *connector, 22 u16 addr) 23 { 24 cec_notifier_set_phys_addr(connector->cec.data, addr); 25 } 26 27 static void drm_connector_hdmi_cec_notifier_unregister(struct drm_device *dev, void *res) 28 { 29 struct drm_connector *connector = res; 30 31 cec_notifier_conn_unregister(connector->cec.data); 32 connector->cec.data = NULL; 33 } 34 35 static const struct drm_connector_cec_funcs drm_connector_cec_notifier_funcs = { 36 .phys_addr_invalidate = drm_connector_hdmi_cec_notifier_phys_addr_invalidate, 37 .phys_addr_set = drm_connector_hdmi_cec_notifier_phys_addr_set, 38 }; 39 40 int drmm_connector_hdmi_cec_notifier_register(struct drm_connector *connector, 41 const char *port_name, 42 struct device *dev) 43 { 44 struct cec_connector_info conn_info; 45 struct cec_notifier *notifier; 46 47 cec_fill_conn_info_from_drm(&conn_info, connector); 48 49 notifier = cec_notifier_conn_register(dev, port_name, &conn_info); 50 if (!notifier) 51 return -ENOMEM; 52 53 mutex_lock(&connector->cec.mutex); 54 55 connector->cec.data = notifier; 56 connector->cec.funcs = &drm_connector_cec_notifier_funcs; 57 58 mutex_unlock(&connector->cec.mutex); 59 60 return drmm_add_action_or_reset(connector->dev, 61 drm_connector_hdmi_cec_notifier_unregister, 62 connector); 63 } 64 EXPORT_SYMBOL(drmm_connector_hdmi_cec_notifier_register); 65