1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * cec-notifier.h - notify CEC drivers of physical address changes
4  *
5  * Copyright 2016 Russell King.
6  * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
7  */
8 
9 #ifndef LINUX_CEC_NOTIFIER_H
10 #define LINUX_CEC_NOTIFIER_H
11 
12 #include <linux/err.h>
13 #include <media/cec.h>
14 
15 struct device;
16 struct edid;
17 struct cec_adapter;
18 struct cec_notifier;
19 
20 #if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
21 
22 /**
23  * cec_notifier_conn_register - find or create a new cec_notifier for the given
24  * HDMI device and connector tuple.
25  * @hdmi_dev: HDMI device that sends the events.
26  * @port_name: the connector name from which the event occurs. May be NULL
27  * if there is always only one HDMI connector created by the HDMI device.
28  * @conn_info: the connector info from which the event occurs (may be NULL)
29  *
30  * If a notifier for device @dev and connector @port_name already exists, then
31  * increase the refcount and return that notifier.
32  *
33  * If it doesn't exist, then allocate a new notifier struct and return a
34  * pointer to that new struct.
35  *
36  * Return NULL if the memory could not be allocated.
37  */
38 struct cec_notifier *
39 cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name,
40 			   const struct cec_connector_info *conn_info);
41 
42 /**
43  * cec_notifier_conn_unregister - decrease refcount and delete when the
44  * refcount reaches 0.
45  * @n: notifier. If NULL, then this function does nothing.
46  */
47 void cec_notifier_conn_unregister(struct cec_notifier *n);
48 
49 /**
50  * cec_notifier_cec_adap_register - find or create a new cec_notifier for the
51  * given device.
52  * @hdmi_dev: HDMI device that sends the events.
53  * @port_name: the connector name from which the event occurs. May be NULL
54  * if there is always only one HDMI connector created by the HDMI device.
55  * @adap: the cec adapter that registered this notifier.
56  *
57  * If a notifier for device @dev and connector @port_name already exists, then
58  * increase the refcount and return that notifier.
59  *
60  * If it doesn't exist, then allocate a new notifier struct and return a
61  * pointer to that new struct.
62  *
63  * Return NULL if the memory could not be allocated.
64  */
65 struct cec_notifier *
66 cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name,
67 			       struct cec_adapter *adap);
68 
69 /**
70  * cec_notifier_cec_adap_unregister - decrease refcount and delete when the
71  * refcount reaches 0.
72  * @n: notifier. If NULL, then this function does nothing.
73  * @adap: the cec adapter that registered this notifier.
74  */
75 void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
76 				      struct cec_adapter *adap);
77 
78 /**
79  * cec_notifier_set_phys_addr - set a new physical address.
80  * @n: the CEC notifier
81  * @pa: the CEC physical address
82  *
83  * Set a new CEC physical address.
84  * Does nothing if @n == NULL.
85  */
86 void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);
87 
88 /**
89  * cec_notifier_set_phys_addr_from_edid - set parse the PA from the EDID.
90  * @n: the CEC notifier
91  * @edid: the struct edid pointer
92  *
93  * Parses the EDID to obtain the new CEC physical address and set it.
94  * Does nothing if @n == NULL.
95  */
96 void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
97 					  const struct edid *edid);
98 
99 /**
100  * cec_notifier_parse_hdmi_phandle - find the hdmi device from "hdmi-phandle"
101  * @dev: the device with the "hdmi-phandle" device tree property
102  *
103  * Returns the device pointer referenced by the "hdmi-phandle" property.
104  * Note that the refcount of the returned device is not incremented.
105  * This device pointer is only used as a key value in the notifier
106  * list, but it is never accessed by the CEC driver.
107  */
108 struct device *cec_notifier_parse_hdmi_phandle(struct device *dev);
109 
110 #else
111 
112 static inline struct cec_notifier *
cec_notifier_conn_register(struct device * hdmi_dev,const char * port_name,const struct cec_connector_info * conn_info)113 cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name,
114 			   const struct cec_connector_info *conn_info)
115 {
116 	/* A non-NULL pointer is expected on success */
117 	return (struct cec_notifier *)0xdeadfeed;
118 }
119 
cec_notifier_conn_unregister(struct cec_notifier * n)120 static inline void cec_notifier_conn_unregister(struct cec_notifier *n)
121 {
122 }
123 
124 static inline struct cec_notifier *
cec_notifier_cec_adap_register(struct device * hdmi_dev,const char * port_name,struct cec_adapter * adap)125 cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name,
126 			       struct cec_adapter *adap)
127 {
128 	/* A non-NULL pointer is expected on success */
129 	return (struct cec_notifier *)0xdeadfeed;
130 }
131 
cec_notifier_cec_adap_unregister(struct cec_notifier * n,struct cec_adapter * adap)132 static inline void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
133 						    struct cec_adapter *adap)
134 {
135 }
136 
cec_notifier_set_phys_addr(struct cec_notifier * n,u16 pa)137 static inline void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
138 {
139 }
140 
cec_notifier_set_phys_addr_from_edid(struct cec_notifier * n,const struct edid * edid)141 static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
142 							const struct edid *edid)
143 {
144 }
145 
cec_notifier_parse_hdmi_phandle(struct device * dev)146 static inline struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)
147 {
148 	return ERR_PTR(-ENODEV);
149 }
150 
151 #endif
152 
153 /**
154  * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
155  *
156  * @n: the CEC notifier
157  *
158  * This is a simple helper function to invalidate the physical
159  * address. Does nothing if @n == NULL.
160  */
cec_notifier_phys_addr_invalidate(struct cec_notifier * n)161 static inline void cec_notifier_phys_addr_invalidate(struct cec_notifier *n)
162 {
163 	cec_notifier_set_phys_addr(n, CEC_PHYS_ADDR_INVALID);
164 }
165 
166 #endif
167