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/export.h> 12 #include <linux/mutex.h> 13 14 #include <media/cec.h> 15 #include <media/cec-notifier.h> 16 17 static void drm_connector_hdmi_cec_notifier_phys_addr_invalidate(struct drm_connector *connector) 18 { 19 cec_notifier_phys_addr_invalidate(connector->cec.data); 20 } 21 22 static void drm_connector_hdmi_cec_notifier_phys_addr_set(struct drm_connector *connector, 23 u16 addr) 24 { 25 cec_notifier_set_phys_addr(connector->cec.data, addr); 26 } 27 28 static void drm_connector_hdmi_cec_notifier_unregister(struct drm_device *dev, void *res) 29 { 30 struct drm_connector *connector = res; 31 32 cec_notifier_conn_unregister(connector->cec.data); 33 connector->cec.data = NULL; 34 } 35 36 static const struct drm_connector_cec_funcs drm_connector_cec_notifier_funcs = { 37 .phys_addr_invalidate = drm_connector_hdmi_cec_notifier_phys_addr_invalidate, 38 .phys_addr_set = drm_connector_hdmi_cec_notifier_phys_addr_set, 39 }; 40 41 int drmm_connector_hdmi_cec_notifier_register(struct drm_connector *connector, 42 const char *port_name, 43 struct device *dev) 44 { 45 struct cec_connector_info conn_info; 46 struct cec_notifier *notifier; 47 48 cec_fill_conn_info_from_drm(&conn_info, connector); 49 50 notifier = cec_notifier_conn_register(dev, port_name, &conn_info); 51 if (!notifier) 52 return -ENOMEM; 53 54 mutex_lock(&connector->cec.mutex); 55 56 connector->cec.data = notifier; 57 connector->cec.funcs = &drm_connector_cec_notifier_funcs; 58 59 mutex_unlock(&connector->cec.mutex); 60 61 return drmm_add_action_or_reset(connector->dev, 62 drm_connector_hdmi_cec_notifier_unregister, 63 connector); 64 } 65 EXPORT_SYMBOL(drmm_connector_hdmi_cec_notifier_register); 66