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