xref: /linux/drivers/gpu/drm/display/drm_hdmi_cec_notifier_helper.c (revision a4871e6201c46c8e1d04308265b4b4c5753c8209)
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