[PATCH 4/4] drm/panel: Add helper for simple panel connector

Noralf Trønnes noralf at tronnes.org
Thu May 5 13:24:34 UTC 2016


Add function to create a simple connector for a panel.

Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
---
 drivers/gpu/drm/Makefile           |   1 +
 drivers/gpu/drm/drm_panel_helper.c | 117 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/panel/Kconfig      |   7 +++
 include/drm/drm_panel_helper.h     |  20 +++++++
 4 files changed, 145 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panel_helper.c
 create mode 100644 include/drm/drm_panel_helper.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7e99923..3f3696c 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,6 +18,7 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
 drm-$(CONFIG_PCI) += ati_pcigart.o
 drm-$(CONFIG_DRM_PANEL) += drm_panel.o
+drm-$(CONFIG_DRM_PANEL_HELPER) += drm_panel_helper.o
 drm-$(CONFIG_OF) += drm_of.o
 drm-$(CONFIG_AGP) += drm_agpsupport.o
 
diff --git a/drivers/gpu/drm/drm_panel_helper.c b/drivers/gpu/drm/drm_panel_helper.c
new file mode 100644
index 0000000..5d8b623
--- /dev/null
+++ b/drivers/gpu/drm/drm_panel_helper.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+
+struct drm_panel_connector {
+	struct drm_connector base;
+	struct drm_panel *panel;
+};
+
+static inline struct drm_panel_connector *
+to_drm_panel_connector(struct drm_connector *connector)
+{
+	return container_of(connector, struct drm_panel_connector, base);
+}
+
+static int drm_panel_connector_get_modes(struct drm_connector *connector)
+{
+	return drm_panel_get_modes(to_drm_panel_connector(connector)->panel);
+}
+
+static struct drm_encoder *
+drm_panel_connector_best_encoder(struct drm_connector *connector)
+{
+	return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+}
+
+static const struct drm_connector_helper_funcs drm_panel_connector_hfuncs = {
+	.get_modes = drm_panel_connector_get_modes,
+	.best_encoder = drm_panel_connector_best_encoder,
+};
+
+static enum drm_connector_status
+drm_panel_connector_detect(struct drm_connector *connector, bool force)
+{
+	if (drm_device_is_unplugged(connector->dev))
+		return connector_status_disconnected;
+
+	return connector->status;
+}
+
+static void drm_panel_connector_destroy(struct drm_connector *connector)
+{
+	struct drm_panel_connector *panel_connector;
+
+	panel_connector = to_drm_panel_connector(connector);
+	drm_panel_detach(panel_connector->panel);
+	drm_panel_remove(panel_connector->panel);
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+	kfree(panel_connector);
+}
+
+static const struct drm_connector_funcs drm_panel_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.reset = drm_atomic_helper_connector_reset,
+	.detect = drm_panel_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_panel_connector_destroy,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+/**
+ * drm_panel_connector_create - Create simple connector for panel
+ * @dev: DRM device
+ * @panel: DRM panel
+ * @connector_type: user visible type of the connector
+ *
+ * Creates a simple connector for a panel.
+ * The panel needs to provide a get_modes() function.
+ *
+ * Returns:
+ * Pointer to new connector or ERR_PTR on failure.
+ */
+struct drm_connector *drm_panel_connector_create(struct drm_device *dev,
+						 struct drm_panel *panel,
+						 int connector_type)
+{
+	struct drm_panel_connector *panel_connector;
+	struct drm_connector *connector;
+	int ret;
+
+	panel_connector = kzalloc(sizeof(*panel_connector), GFP_KERNEL);
+	if (!panel_connector)
+		return ERR_PTR(-ENOMEM);
+
+	panel_connector->panel = panel;
+	connector = &panel_connector->base;
+	drm_connector_helper_add(connector, &drm_panel_connector_hfuncs);
+	ret = drm_connector_init(dev, connector, &drm_panel_connector_funcs,
+				 connector_type);
+	if (ret) {
+		kfree(panel_connector);
+		return ERR_PTR(ret);
+	}
+
+	connector->status = connector_status_connected;
+	drm_panel_init(panel);
+	drm_panel_add(panel);
+	drm_panel_attach(panel, connector);
+
+	return connector;
+}
+EXPORT_SYMBOL(drm_panel_connector_create);
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 1500ab9..87264a3 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -4,6 +4,13 @@ config DRM_PANEL
 	help
 	  Panel registration and lookup framework.
 
+config DRM_PANEL_HELPER
+	bool
+	depends on DRM
+	select DRM_PANEL
+	help
+	  Panel helper.
+
 menu "Display Panels"
 	depends on DRM && DRM_PANEL
 
diff --git a/include/drm/drm_panel_helper.h b/include/drm/drm_panel_helper.h
new file mode 100644
index 0000000..c3355e3
--- /dev/null
+++ b/include/drm/drm_panel_helper.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DRM_PANEL_HELPER_H__
+#define __DRM_PANEL_HELPER_H__
+
+struct drm_device;
+struct drm_panel;
+
+struct drm_connector *drm_panel_connector_create(struct drm_device *dev,
+						 struct drm_panel *panel,
+						 int connector_type);
+
+#endif
-- 
2.2.2



More information about the dri-devel mailing list