Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
17static 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
22static 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
28static 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
36static 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
41int 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}
65EXPORT_SYMBOL(drmm_connector_hdmi_cec_notifier_register);