forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/gpu/drm/drm_dp_cec.c
....@@ -8,15 +8,21 @@
88 #include <linux/kernel.h>
99 #include <linux/module.h>
1010 #include <linux/slab.h>
11
-#include <drm/drm_dp_helper.h>
11
+
1212 #include <media/cec.h>
13
+
14
+#include <drm/drm_connector.h>
15
+#include <drm/drm_device.h>
16
+#include <drm/drm_dp_helper.h>
1317
1418 /*
1519 * Unfortunately it turns out that we have a chicken-and-egg situation
1620 * here. Quite a few active (mini-)DP-to-HDMI or USB-C-to-HDMI adapters
1721 * have a converter chip that supports CEC-Tunneling-over-AUX (usually the
1822 * Parade PS176), but they do not wire up the CEC pin, thus making CEC
19
- * useless.
23
+ * useless. Note that MegaChips 2900-based adapters appear to have good
24
+ * support for CEC tunneling. Those adapters that I have tested using
25
+ * this chipset all have the CEC line connected.
2026 *
2127 * Sadly there is no way for this driver to know this. What happens is
2228 * that a /dev/cecX device is created that is isolated and unable to see
....@@ -238,6 +244,10 @@
238244 u8 cec_irq;
239245 int ret;
240246
247
+ /* No transfer function was set, so not a DP connector */
248
+ if (!aux->transfer)
249
+ return;
250
+
241251 mutex_lock(&aux->cec.lock);
242252 if (!aux->cec.adap)
243253 goto unlock;
....@@ -289,9 +299,16 @@
289299 */
290300 void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
291301 {
292
- u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
302
+ struct drm_connector *connector = aux->cec.connector;
303
+ u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
304
+ CEC_CAP_CONNECTOR_INFO;
305
+ struct cec_connector_info conn_info;
293306 unsigned int num_las = 1;
294307 u8 cap;
308
+
309
+ /* No transfer function was set, so not a DP connector */
310
+ if (!aux->transfer)
311
+ return;
295312
296313 #ifndef CONFIG_MEDIA_CEC_RC
297314 /*
....@@ -334,13 +351,17 @@
334351
335352 /* Create a new adapter */
336353 aux->cec.adap = cec_allocate_adapter(&drm_dp_cec_adap_ops,
337
- aux, aux->cec.name, cec_caps,
354
+ aux, connector->name, cec_caps,
338355 num_las);
339356 if (IS_ERR(aux->cec.adap)) {
340357 aux->cec.adap = NULL;
341358 goto unlock;
342359 }
343
- if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
360
+
361
+ cec_fill_conn_info_from_drm(&conn_info, connector);
362
+ cec_s_conn_info(aux->cec.adap, &conn_info);
363
+
364
+ if (cec_register_adapter(aux->cec.adap, connector->dev->dev)) {
344365 cec_delete_adapter(aux->cec.adap);
345366 aux->cec.adap = NULL;
346367 } else {
....@@ -361,6 +382,10 @@
361382 */
362383 void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
363384 {
385
+ /* No transfer function was set, so not a DP connector */
386
+ if (!aux->transfer)
387
+ return;
388
+
364389 cancel_delayed_work_sync(&aux->cec.unregister_work);
365390
366391 mutex_lock(&aux->cec.lock);
....@@ -392,24 +417,22 @@
392417 /**
393418 * drm_dp_cec_register_connector() - register a new connector
394419 * @aux: DisplayPort AUX channel
395
- * @name: name of the CEC device
396
- * @parent: parent device
420
+ * @connector: drm connector
397421 *
398422 * A new connector was registered with associated CEC adapter name and
399423 * CEC adapter parent device. After registering the name and parent
400424 * drm_dp_cec_set_edid() is called to check if the connector supports
401425 * CEC and to register a CEC adapter if that is the case.
402426 */
403
-void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
404
- struct device *parent)
427
+void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
428
+ struct drm_connector *connector)
405429 {
406430 WARN_ON(aux->cec.adap);
407
- aux->cec.name = name;
408
- aux->cec.parent = parent;
431
+ if (WARN_ON(!aux->transfer))
432
+ return;
433
+ aux->cec.connector = connector;
409434 INIT_DELAYED_WORK(&aux->cec.unregister_work,
410435 drm_dp_cec_unregister_work);
411
-
412
- drm_dp_cec_set_edid(aux, NULL);
413436 }
414437 EXPORT_SYMBOL(drm_dp_cec_register_connector);
415438