* [PATCH 19/27] OMAPDSS: Add new HDMI Connector driver
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add HDMI Connector driver which uses the new DSS device model and DSS
ops.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays-new/Kconfig | 5 +
drivers/video/omap2/displays-new/Makefile | 1 +
drivers/video/omap2/displays-new/connector-hdmi.c | 375 ++++++++++++++++++++++
3 files changed, 381 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/connector-hdmi.c
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 76570fc..9a66413 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -18,4 +18,9 @@ config DISPLAY_CONNECTOR_DVI
help
Driver for a generic DVI connector.
+config DISPLAY_CONNECTOR_HDMI
+ tristate "HDMI Connector"
+ help
+ Driver for a generic HDMI connector.
+
endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index ed7dd06..1007b5f 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o
obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o
+obj-$(CONFIG_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/omap2/displays-new/connector-hdmi.c
new file mode 100644
index 0000000..c582671
--- /dev/null
+++ b/drivers/video/omap2/displays-new/connector-hdmi.c
@@ -0,0 +1,375 @@
+/*
+ * HDMI Connector driver
+ *
+ * Copyright (C) 2013 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_edid.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+static const struct omap_video_timings hdmic_default_timings = {
+ .x_res = 640,
+ .y_res = 480,
+ .pixel_clock = 25175,
+ .hsw = 96,
+ .hfp = 16,
+ .hbp = 48,
+ .vsw = 2,
+ .vfp = 11,
+ .vbp = 31,
+
+ .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+ .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+
+ .interlace = false,
+};
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ struct device *dev;
+
+ struct omap_video_timings timings;
+};
+
+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
+
+static int hdmic_connect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ dev_dbg(ddata->dev, "connect\n");
+
+ if (omapdss_device_is_connected(dssdev))
+ return 0;
+
+ r = in->ops.hdmi->connect(in, dssdev);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void hdmic_disconnect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ dev_dbg(ddata->dev, "disconnect\n");
+
+ if (!omapdss_device_is_connected(dssdev))
+ return;
+
+ in->ops.hdmi->disconnect(in, dssdev);
+}
+
+static int hdmic_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ dev_dbg(ddata->dev, "enable\n");
+
+ if (!omapdss_device_is_connected(dssdev))
+ return -ENODEV;
+
+ if (omapdss_device_is_enabled(dssdev))
+ return 0;
+
+ in->ops.hdmi->set_timings(in, &ddata->timings);
+
+ r = in->ops.hdmi->enable(in);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return r;
+}
+
+static void hdmic_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ dev_dbg(ddata->dev, "disable\n");
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return;
+
+ in->ops.hdmi->disable(in);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void hdmic_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->timings = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.hdmi->set_timings(in, timings);
+}
+
+static void hdmic_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->timings;
+}
+
+static int hdmic_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->check_timings(in, timings);
+}
+
+static int hdmic_read_edid(struct omap_dss_device *dssdev,
+ u8 *edid, int len)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->read_edid(in, edid, len);
+}
+
+static bool hdmic_detect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->detect(in);
+}
+
+static int hdmic_audio_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ /* enable audio only if the display is active */
+ if (!omapdss_device_is_enabled(dssdev))
+ return -EPERM;
+
+ r = in->ops.hdmi->audio_enable(in);
+ if (r)
+ return r;
+
+ dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
+
+ return 0;
+}
+
+static void hdmic_audio_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ in->ops.hdmi->audio_disable(in);
+
+ dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
+}
+
+static int hdmic_audio_start(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ /*
+ * No need to check the panel state. It was checked when trasitioning
+ * to AUDIO_ENABLED.
+ */
+ if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED)
+ return -EPERM;
+
+ r = in->ops.hdmi->audio_start(in);
+ if (r)
+ return r;
+
+ dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
+
+ return 0;
+}
+
+static void hdmic_audio_stop(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ in->ops.hdmi->audio_stop(in);
+
+ dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
+}
+
+static bool hdmic_audio_supported(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return false;
+
+ return in->ops.hdmi->audio_supported(in);
+}
+
+static int hdmic_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ /* config audio only if the display is active */
+ if (!omapdss_device_is_enabled(dssdev))
+ return -EPERM;
+
+ r = in->ops.hdmi->audio_config(in, audio);
+ if (r)
+ return r;
+
+ dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
+
+ return 0;
+}
+
+static struct omap_dss_driver hdmic_driver = {
+ .connect = hdmic_connect,
+ .disconnect = hdmic_disconnect,
+
+ .enable = hdmic_enable,
+ .disable = hdmic_disable,
+
+ .set_timings = hdmic_set_timings,
+ .get_timings = hdmic_get_timings,
+ .check_timings = hdmic_check_timings,
+
+ .get_resolution = omapdss_default_get_resolution,
+
+ .read_edid = hdmic_read_edid,
+ .detect = hdmic_detect,
+
+ .audio_enable = hdmic_audio_enable,
+ .audio_disable = hdmic_audio_disable,
+ .audio_start = hdmic_audio_start,
+ .audio_stop = hdmic_audio_stop,
+ .audio_supported = hdmic_audio_supported,
+ .audio_config = hdmic_audio_config,
+};
+
+static int hdmic_probe_pdata(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct connector_hdmi_platform_data *pdata;
+ struct omap_dss_device *in, *dssdev;
+
+ pdata = dev_get_platdata(&pdev->dev);
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&pdev->dev, "Failed to find video source\n");
+ return -ENODEV;
+ }
+
+ ddata->in = in;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int hdmic_probe(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ddata);
+ ddata->dev = &pdev->dev;
+
+ if (dev_get_platdata(&pdev->dev)) {
+ r = hdmic_probe_pdata(pdev);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ ddata->timings = hdmic_default_timings;
+
+ dssdev = &ddata->dssdev;
+ dssdev->driver = &hdmic_driver;
+ dssdev->dev = &pdev->dev;
+ dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
+ dssdev->owner = THIS_MODULE;
+ dssdev->panel.timings = hdmic_default_timings;
+
+ r = omapdss_register_display(dssdev);
+ if (r) {
+ dev_err(&pdev->dev, "Failed to register panel\n");
+ goto err_reg;
+ }
+
+ return 0;
+err_reg:
+ omap_dss_put_device(ddata->in);
+ return r;
+}
+
+static int __exit hdmic_remove(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct omap_dss_device *dssdev = &ddata->dssdev;
+ struct omap_dss_device *in = ddata->in;
+
+ omapdss_unregister_display(&ddata->dssdev);
+
+ hdmic_disable(dssdev);
+ hdmic_disconnect(dssdev);
+
+ omap_dss_put_device(in);
+
+ return 0;
+}
+
+static struct platform_driver hdmi_connector_driver = {
+ .probe = hdmic_probe,
+ .remove = __exit_p(hdmic_remove),
+ .driver = {
+ .name = "connector-hdmi",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(hdmi_connector_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("HDMI Connector driver");
+MODULE_LICENSE("GPL");
--
1.8.1.2
^ permalink raw reply related
* [PATCH 18/27] OMAPDSS: Add new DVI Connector driver
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add DVI Connector driver which uses the new DSS device model and DSS
ops.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays-new/Kconfig | 6 +
drivers/video/omap2/displays-new/Makefile | 1 +
drivers/video/omap2/displays-new/connector-dvi.c | 351 +++++++++++++++++++++++
3 files changed, 358 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/connector-dvi.c
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 6e4af85..76570fc 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -12,4 +12,10 @@ config DISPLAY_ENCODER_TPD12S015
Driver for TPD12S015, which offers HDMI ESD protection and level
shifting.
+config DISPLAY_CONNECTOR_DVI
+ tristate "DVI Connector"
+ depends on I2C
+ help
+ Driver for a generic DVI connector.
+
endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index c2ee45e..ed7dd06 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o
+obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/omap2/displays-new/connector-dvi.c
new file mode 100644
index 0000000..a427460
--- /dev/null
+++ b/drivers/video/omap2/displays-new/connector-dvi.c
@@ -0,0 +1,351 @@
+/*
+ * Generic DVI Connector driver
+ *
+ * Copyright (C) 2013 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <drm/drm_edid.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+static const struct omap_video_timings dvic_default_timings = {
+ .x_res = 640,
+ .y_res = 480,
+
+ .pixel_clock = 23500,
+
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 7,
+
+ .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
+ .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
+ .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
+ .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
+ .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+};
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ struct omap_video_timings timings;
+
+ struct i2c_adapter *i2c_adapter;
+};
+
+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
+
+static int dvic_connect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (omapdss_device_is_connected(dssdev))
+ return 0;
+
+ r = in->ops.dvi->connect(in, dssdev);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void dvic_disconnect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return;
+
+ in->ops.dvi->disconnect(in, dssdev);
+}
+
+static int dvic_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return -ENODEV;
+
+ if (omapdss_device_is_enabled(dssdev))
+ return 0;
+
+ in->ops.dvi->set_timings(in, &ddata->timings);
+
+ r = in->ops.dvi->enable(in);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static void dvic_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return;
+
+ in->ops.dvi->disable(in);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void dvic_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->timings = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.dvi->set_timings(in, timings);
+}
+
+static void dvic_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->timings;
+}
+
+static int dvic_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.dvi->check_timings(in, timings);
+}
+
+static int dvic_ddc_read(struct i2c_adapter *adapter,
+ unsigned char *buf, u16 count, u8 offset)
+{
+ int r, retries;
+
+ for (retries = 3; retries > 0; retries--) {
+ struct i2c_msg msgs[] = {
+ {
+ .addr = DDC_ADDR,
+ .flags = 0,
+ .len = 1,
+ .buf = &offset,
+ }, {
+ .addr = DDC_ADDR,
+ .flags = I2C_M_RD,
+ .len = count,
+ .buf = buf,
+ }
+ };
+
+ r = i2c_transfer(adapter, msgs, 2);
+ if (r = 2)
+ return 0;
+
+ if (r != -EAGAIN)
+ break;
+ }
+
+ return r < 0 ? r : -EIO;
+}
+
+static int dvic_read_edid(struct omap_dss_device *dssdev,
+ u8 *edid, int len)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ int r, l, bytes_read;
+
+ if (!ddata->i2c_adapter)
+ return -ENODEV;
+
+ l = min(EDID_LENGTH, len);
+ r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0);
+ if (r)
+ return r;
+
+ bytes_read = l;
+
+ /* if there are extensions, read second block */
+ if (len > EDID_LENGTH && edid[0x7e] > 0) {
+ l = min(EDID_LENGTH, len - EDID_LENGTH);
+
+ r = dvic_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH,
+ l, EDID_LENGTH);
+ if (r)
+ return r;
+
+ bytes_read += l;
+ }
+
+ return bytes_read;
+}
+
+static bool dvic_detect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ unsigned char out;
+ int r;
+
+ if (!ddata->i2c_adapter)
+ return true;
+
+ r = dvic_ddc_read(ddata->i2c_adapter, &out, 1, 0);
+
+ return r = 0;
+}
+
+static struct omap_dss_driver dvic_driver = {
+ .connect = dvic_connect,
+ .disconnect = dvic_disconnect,
+
+ .enable = dvic_enable,
+ .disable = dvic_disable,
+
+ .set_timings = dvic_set_timings,
+ .get_timings = dvic_get_timings,
+ .check_timings = dvic_check_timings,
+
+ .get_resolution = omapdss_default_get_resolution,
+
+ .read_edid = dvic_read_edid,
+ .detect = dvic_detect,
+};
+
+static int dvic_probe_pdata(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct connector_dvi_platform_data *pdata;
+ struct omap_dss_device *in, *dssdev;
+ int i2c_bus_num;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ i2c_bus_num = pdata->i2c_bus_num;
+
+ if (i2c_bus_num != -1) {
+ struct i2c_adapter *adapter;
+
+ adapter = i2c_get_adapter(i2c_bus_num);
+ if (!adapter) {
+ dev_err(&pdev->dev,
+ "Failed to get I2C adapter, bus %d\n",
+ i2c_bus_num);
+ return -EINVAL;
+ }
+
+ ddata->i2c_adapter = adapter;
+ }
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&pdev->dev, "Failed to find video source\n");
+ return -ENODEV;
+ }
+
+ ddata->in = in;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int dvic_probe(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ddata);
+
+ if (dev_get_platdata(&pdev->dev)) {
+ r = dvic_probe_pdata(pdev);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ ddata->timings = dvic_default_timings;
+
+ dssdev = &ddata->dssdev;
+ dssdev->driver = &dvic_driver;
+ dssdev->dev = &pdev->dev;
+ dssdev->type = OMAP_DISPLAY_TYPE_DVI;
+ dssdev->owner = THIS_MODULE;
+ dssdev->panel.timings = dvic_default_timings;
+
+ r = omapdss_register_display(dssdev);
+ if (r) {
+ dev_err(&pdev->dev, "Failed to register panel\n");
+ goto err_reg;
+ }
+
+ return 0;
+
+err_reg:
+ omap_dss_put_device(ddata->in);
+ return r;
+}
+
+static int __exit dvic_remove(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct omap_dss_device *dssdev = &ddata->dssdev;
+ struct omap_dss_device *in = ddata->in;
+
+ omapdss_unregister_display(&ddata->dssdev);
+
+ dvic_disable(dssdev);
+ dvic_disconnect(dssdev);
+
+ omap_dss_put_device(in);
+
+ if (ddata->i2c_adapter)
+ i2c_put_adapter(ddata->i2c_adapter);
+
+ return 0;
+}
+
+static struct platform_driver dvi_connector_driver = {
+ .probe = dvic_probe,
+ .remove = __exit_p(dvic_remove),
+ .driver = {
+ .name = "connector-dvi",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(dvi_connector_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("Generic DVI Connector driver");
+MODULE_LICENSE("GPL");
--
1.8.1.2
^ permalink raw reply related
* [PATCH 17/27] OMAPDSS: Add new TPD12S015 Encoder driver
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add TPD12S015 HDMI ESD protection and level shifter encoder driver which
uses the new DSS device model and DSS ops.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays-new/Kconfig | 6 +
drivers/video/omap2/displays-new/Makefile | 1 +
.../video/omap2/displays-new/encoder-tpd12s015.c | 395 +++++++++++++++++++++
3 files changed, 402 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/encoder-tpd12s015.c
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 92c2324..6e4af85 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -6,4 +6,10 @@ config DISPLAY_ENCODER_TFP410
help
Driver for TFP410 DPI to DVI encoder.
+config DISPLAY_ENCODER_TPD12S015
+ tristate "TPD12S015 HDMI ESD protection and level shifter"
+ help
+ Driver for TPD12S015, which offers HDMI ESD protection and level
+ shifting.
+
endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index b0d3457..c2ee45e 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
+obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o
diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/omap2/displays-new/encoder-tpd12s015.c
new file mode 100644
index 0000000..d510c8e
--- /dev/null
+++ b/drivers/video/omap2/displays-new/encoder-tpd12s015.c
@@ -0,0 +1,395 @@
+/*
+ * TPD12S015 HDMI ESD protection & level shifter chip driver
+ *
+ * Copyright (C) 2013 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ int ct_cp_hpd_gpio;
+ int ls_oe_gpio;
+ int hpd_gpio;
+
+ struct omap_video_timings timings;
+};
+
+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
+
+static int tpd_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ r = gpio_request_one(ddata->ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW,
+ "hdmi_ct_cp_hpd");
+ if (r)
+ goto err_ct_cp_hpd;
+
+ if (gpio_is_valid(ddata->ls_oe_gpio)) {
+ r = gpio_request_one(ddata->ls_oe_gpio, GPIOF_OUT_INIT_LOW,
+ "hdmi_ls_oe");
+ if (r)
+ goto err_ls_oe;
+ }
+
+ r = gpio_request_one(ddata->hpd_gpio, GPIOF_DIR_IN,
+ "hdmi_hpd");
+ if (r)
+ goto err_hpd;
+
+
+ /* XXX */
+ in->ops.hdmi->set_hpd_gpio(in, ddata->hpd_gpio);
+
+ r = in->ops.hdmi->connect(in, dssdev);
+ if (r)
+ goto err_conn;
+
+ dst->output = dssdev;
+ dssdev->device = dst;
+
+ return 0;
+
+err_conn:
+ gpio_free(ddata->hpd_gpio);
+err_hpd:
+ if (gpio_is_valid(ddata->ls_oe_gpio))
+ gpio_free(ddata->ls_oe_gpio);
+err_ls_oe:
+ gpio_free(ddata->ct_cp_hpd_gpio);
+err_ct_cp_hpd:
+ return r;
+}
+
+static void tpd_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ dst->output = NULL;
+ dssdev->device = NULL;
+
+ in->ops.hdmi->disconnect(in, &ddata->dssdev);
+
+ gpio_free(ddata->hpd_gpio);
+ if (gpio_is_valid(ddata->ls_oe_gpio))
+ gpio_free(ddata->ls_oe_gpio);
+ gpio_free(ddata->ct_cp_hpd_gpio);
+}
+
+static int tpd_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 1);
+ gpio_set_value(ddata->ls_oe_gpio, 1);
+
+ in->ops.hdmi->set_timings(in, &ddata->timings);
+
+ r = in->ops.hdmi->enable(in);
+ if (r)
+ return r;
+
+ if (gpio_is_valid(ddata->ls_oe_gpio))
+ gpio_set_value_cansleep(ddata->ls_oe_gpio, 1);
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return r;
+}
+
+static void tpd_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ if (gpio_is_valid(ddata->ls_oe_gpio))
+ gpio_set_value_cansleep(ddata->ls_oe_gpio, 0);
+
+ in->ops.hdmi->disable(in);
+
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 0);
+ gpio_set_value(ddata->ls_oe_gpio, 0);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void tpd_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->timings = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.hdmi->set_timings(in, timings);
+}
+
+static void tpd_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->timings;
+}
+
+static int tpd_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ r = in->ops.hdmi->check_timings(in, timings);
+
+ return r;
+}
+
+static int tpd_read_edid(struct omap_dss_device *dssdev,
+ u8 *edid, int len)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ bool need_enable;
+ int r;
+
+ need_enable = dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+ if (need_enable) {
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 1);
+ gpio_set_value(ddata->ls_oe_gpio, 1);
+ }
+
+ r = in->ops.hdmi->read_edid(in, edid, len);
+
+ if (need_enable) {
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 0);
+ gpio_set_value(ddata->ls_oe_gpio, 0);
+ }
+
+ return r;
+}
+
+static bool tpd_detect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ bool need_enable;
+ bool det;
+
+ need_enable = dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+ if (need_enable) {
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 1);
+ gpio_set_value(ddata->ls_oe_gpio, 1);
+ }
+
+ det = in->ops.hdmi->detect(in);
+
+ if (need_enable) {
+ gpio_set_value(ddata->ct_cp_hpd_gpio, 0);
+ gpio_set_value(ddata->ls_oe_gpio, 0);
+ }
+
+ return det;
+}
+
+static int tpd_audio_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->audio_enable(in);
+}
+
+static void tpd_audio_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ in->ops.hdmi->audio_disable(in);
+}
+
+static int tpd_audio_start(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->audio_start(in);
+}
+
+static void tpd_audio_stop(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ in->ops.hdmi->audio_stop(in);
+}
+
+static bool tpd_audio_supported(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->audio_supported(in);
+}
+
+static int tpd_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.hdmi->audio_config(in, audio);
+}
+
+static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
+ .connect = tpd_connect,
+ .disconnect = tpd_disconnect,
+
+ .enable = tpd_enable,
+ .disable = tpd_disable,
+
+ .check_timings = tpd_check_timings,
+ .set_timings = tpd_set_timings,
+ .get_timings = tpd_get_timings,
+
+ .read_edid = tpd_read_edid,
+ .detect = tpd_detect,
+
+ .audio_enable = tpd_audio_enable,
+ .audio_disable = tpd_audio_disable,
+ .audio_start = tpd_audio_start,
+ .audio_stop = tpd_audio_stop,
+ .audio_supported = tpd_audio_supported,
+ .audio_config = tpd_audio_config,
+};
+
+static int tpd_probe_pdata(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct encoder_tpd12s015_platform_data *pdata;
+ struct omap_dss_device *dssdev, *in;
+
+ pdata = dev_get_platdata(&pdev->dev);
+
+ ddata->ct_cp_hpd_gpio = pdata->ct_cp_hpd_gpio;
+ ddata->ls_oe_gpio = pdata->ls_oe_gpio;
+ ddata->hpd_gpio = pdata->hpd_gpio;
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&pdev->dev, "Failed to find video source\n");
+ return -ENODEV;
+ }
+
+ ddata->in = in;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int tpd_probe(struct platform_device *pdev)
+{
+ struct omap_dss_device *in, *dssdev;
+ struct panel_drv_data *ddata;
+ int r;
+
+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ddata);
+
+ if (dev_get_platdata(&pdev->dev)) {
+ r = tpd_probe_pdata(pdev);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ dssdev = &ddata->dssdev;
+ dssdev->ops.hdmi = &tpd_hdmi_ops;
+ dssdev->dev = &pdev->dev;
+ dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
+ dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
+ dssdev->owner = THIS_MODULE;
+
+ in = ddata->in;
+
+ r = omapdss_register_output(dssdev);
+ if (r) {
+ dev_err(&pdev->dev, "Failed to register output\n");
+ goto err_reg;
+ }
+
+ return 0;
+err_reg:
+ omap_dss_put_device(in);
+ return r;
+}
+
+static int __exit tpd_remove(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct omap_dss_device *in = ddata->in;
+
+ omapdss_unregister_output(&ddata->dssdev);
+
+ if (ddata->dssdev.output)
+ in->ops.hdmi->disconnect(in, &ddata->dssdev);
+
+ omap_dss_put_device(in);
+
+ return 0;
+}
+
+static struct platform_driver tpd_driver = {
+ .probe = tpd_probe,
+ .remove = __exit_p(tpd_remove),
+ .driver = {
+ .name = "tpd12s015",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(tpd_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("TPD12S015 driver");
+MODULE_LICENSE("GPL");
--
1.8.1.2
^ permalink raw reply related
* [PATCH 16/27] OMAPDSS: Add new TFP410 Encoder driver
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add TFP410 DPI-to-DVI Encoder driver which uses the new DSS device
model and DSS ops.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/Kconfig | 1 +
drivers/video/omap2/Makefile | 1 +
drivers/video/omap2/displays-new/Kconfig | 9 +
drivers/video/omap2/displays-new/Makefile | 1 +
drivers/video/omap2/displays-new/encoder-tfp410.c | 270 ++++++++++++++++++++++
5 files changed, 282 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/Kconfig
create mode 100644 drivers/video/omap2/displays-new/Makefile
create mode 100644 drivers/video/omap2/displays-new/encoder-tfp410.c
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index b07b2b0..56cad0f 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -6,5 +6,6 @@ if ARCH_OMAP2PLUS
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/omapfb/Kconfig"
source "drivers/video/omap2/displays/Kconfig"
+source "drivers/video/omap2/displays-new/Kconfig"
endif
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 296e5c5..86873c2 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
obj-$(CONFIG_OMAP2_DSS) += dss/
obj-y += displays/
+obj-y += displays-new/
obj-$(CONFIG_FB_OMAP2) += omapfb/
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
new file mode 100644
index 0000000..92c2324
--- /dev/null
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -0,0 +1,9 @@
+menu "OMAP Display Device Drivers"
+ depends on OMAP2_DSS
+
+config DISPLAY_ENCODER_TFP410
+ tristate "TFP410 DPI to DVI Encoder"
+ help
+ Driver for TFP410 DPI to DVI encoder.
+
+endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
new file mode 100644
index 0000000..b0d3457
--- /dev/null
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o
diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/omap2/displays-new/encoder-tfp410.c
new file mode 100644
index 0000000..5fff526
--- /dev/null
+++ b/drivers/video/omap2/displays-new/encoder-tfp410.c
@@ -0,0 +1,270 @@
+/*
+ * TFP410 DPI-to-DVI encoder driver
+ *
+ * Copyright (C) 2013 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ int pd_gpio;
+ int data_lines;
+
+ struct omap_video_timings timings;
+};
+
+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
+
+static int tfp410_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (omapdss_device_is_connected(dssdev))
+ return -EBUSY;
+
+ r = in->ops.dpi->connect(in, dssdev);
+ if (r)
+ return r;
+
+ dst->output = dssdev;
+ dssdev->device = dst;
+
+ return 0;
+}
+
+static void tfp410_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ WARN_ON(!omapdss_device_is_connected(dssdev));
+ if (!omapdss_device_is_connected(dssdev))
+ return;
+
+ WARN_ON(dst != dssdev->device);
+ if (dst != dssdev->device)
+ return;
+
+ dst->output = NULL;
+ dssdev->device = NULL;
+
+ in->ops.dpi->disconnect(in, &ddata->dssdev);
+}
+
+static int tfp410_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return -ENODEV;
+
+ if (omapdss_device_is_enabled(dssdev))
+ return 0;
+
+ in->ops.dpi->set_timings(in, &ddata->timings);
+ in->ops.dpi->set_data_lines(in, ddata->data_lines);
+
+ r = in->ops.dpi->enable(in);
+ if (r)
+ return r;
+
+ if (gpio_is_valid(ddata->pd_gpio))
+ gpio_set_value_cansleep(ddata->pd_gpio, 1);
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static void tfp410_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return;
+
+ if (gpio_is_valid(ddata->pd_gpio))
+ gpio_set_value_cansleep(ddata->pd_gpio, 0);
+
+ in->ops.dpi->disable(in);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void tfp410_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->timings = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.dpi->set_timings(in, timings);
+}
+
+static void tfp410_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->timings;
+}
+
+static int tfp410_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.dpi->check_timings(in, timings);
+}
+
+static const struct omapdss_dvi_ops tfp410_dvi_ops = {
+ .connect = tfp410_connect,
+ .disconnect = tfp410_disconnect,
+
+ .enable = tfp410_enable,
+ .disable = tfp410_disable,
+
+ .check_timings = tfp410_check_timings,
+ .set_timings = tfp410_set_timings,
+ .get_timings = tfp410_get_timings,
+};
+
+static int tfp410_probe_pdata(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct encoder_tfp410_platform_data *pdata;
+ struct omap_dss_device *dssdev, *in;
+ int r, gpio;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ gpio = pdata->power_down_gpio;
+
+ if (gpio_is_valid(gpio)) {
+ r = devm_gpio_request_one(&pdev->dev, gpio,
+ GPIOF_OUT_INIT_LOW, "tfp410 pd");
+ if (r) {
+ dev_err(&pdev->dev, "Failed to request PD GPIO %d\n",
+ gpio);
+ return r;
+ }
+
+ ddata->pd_gpio = gpio;
+ } else {
+ ddata->pd_gpio = -1;
+ }
+
+ ddata->data_lines = pdata->data_lines;
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&pdev->dev, "Failed to find video source\n");
+ return -ENODEV;
+ }
+
+ ddata->in = in;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int tfp410_probe(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ddata);
+
+ if (dev_get_platdata(&pdev->dev)) {
+ r = tfp410_probe_pdata(pdev);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ dssdev = &ddata->dssdev;
+ dssdev->ops.dvi = &tfp410_dvi_ops;
+ dssdev->dev = &pdev->dev;
+ dssdev->type = OMAP_DISPLAY_TYPE_DPI;
+ dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
+ dssdev->owner = THIS_MODULE;
+ dssdev->phy.dpi.data_lines = ddata->data_lines;
+
+ r = omapdss_register_output(dssdev);
+ if (r) {
+ dev_err(&pdev->dev, "Failed to register output\n");
+ goto err_reg;
+ }
+
+ return 0;
+err_reg:
+ omap_dss_put_device(ddata->in);
+ return r;
+}
+
+static int __exit tfp410_remove(struct platform_device *pdev)
+{
+ struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+ struct omap_dss_device *dssdev = &ddata->dssdev;
+ struct omap_dss_device *in = ddata->in;
+
+ omapdss_unregister_output(&ddata->dssdev);
+
+ WARN_ON(omapdss_device_is_enabled(dssdev));
+ if (omapdss_device_is_enabled(dssdev))
+ tfp410_disable(dssdev);
+
+ WARN_ON(omapdss_device_is_connected(dssdev));
+ if (omapdss_device_is_connected(dssdev))
+ tfp410_disconnect(dssdev, dssdev->device);
+
+ omap_dss_put_device(in);
+
+ return 0;
+}
+
+static struct platform_driver tfp410_driver = {
+ .probe = tfp410_probe,
+ .remove = __exit_p(tfp410_remove),
+ .driver = {
+ .name = "tfp410",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(tfp410_driver);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("TFP410 DPI to DVI encoder driver");
+MODULE_LICENSE("GPL");
--
1.8.1.2
^ permalink raw reply related
* [PATCH 15/27] OMAPDSS: DSI: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using DSI functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 93 +++++++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 58 +++++++++++++++++++++++++++
2 files changed, 151 insertions(+)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 4ecc0c1..a6b7d85 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -383,6 +383,15 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{
+ /* HACK: dssdev can be either the panel device, when using old API, or
+ * the dsi device itself, when using the new API. So we solve this for
+ * now by checking the dssdev->id. This will be removed when the old API
+ * is removed.
+ */
+ if (dssdev->id = OMAP_DSS_OUTPUT_DSI1 ||
+ dssdev->id = OMAP_DSS_OUTPUT_DSI2)
+ return to_platform_device(dssdev->dev);
+
return to_platform_device(dssdev->output->dev);
}
@@ -5412,6 +5421,89 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
return 0;
}
+static int dsi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = dsi_regulator_init(dsidev);
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void dsi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_dsi_ops dsi_ops = {
+ .connect = dsi_connect,
+ .disconnect = dsi_disconnect,
+
+ .bus_lock = dsi_bus_lock,
+ .bus_unlock = dsi_bus_unlock,
+
+ .enable = omapdss_dsi_display_enable,
+ .disable = omapdss_dsi_display_disable,
+
+ .enable_hs = omapdss_dsi_vc_enable_hs,
+
+ .configure_pins = omapdss_dsi_configure_pins,
+ .set_config = omapdss_dsi_set_config,
+
+ .enable_video_output = dsi_enable_video_output,
+ .disable_video_output = dsi_disable_video_output,
+
+ .update = omap_dsi_update,
+
+ .enable_te = omapdss_dsi_enable_te,
+
+ .request_vc = omap_dsi_request_vc,
+ .set_vc_id = omap_dsi_set_vc_id,
+ .release_vc = omap_dsi_release_vc,
+
+ .dcs_write = dsi_vc_dcs_write,
+ .dcs_write_nosync = dsi_vc_dcs_write_nosync,
+ .dcs_read = dsi_vc_dcs_read,
+
+ .gen_write = dsi_vc_generic_write,
+ .gen_write_nosync = dsi_vc_generic_write_nosync,
+ .gen_read = dsi_vc_generic_read,
+
+ .bta_sync = dsi_vc_send_bta_sync,
+
+ .set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size,
+};
+
static void dsi_init_output(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -5424,6 +5516,7 @@ static void dsi_init_output(struct platform_device *dsidev)
out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id = 0 ? "dsi.0" : "dsi.1";
out->dispc_channel = dsi_get_channel(dsi->module_id);
+ out->ops.dsi = &dsi_ops;
out->owner = THIS_MODULE;
omapdss_register_output(out);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index f0aee54..f8c26c5 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -694,6 +694,63 @@ struct omapdss_hdmi_ops {
void (*audio_stop)(struct omap_dss_device *dssdev);
};
+struct omapdss_dsi_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev, bool disconnect_lanes,
+ bool enter_ulps);
+
+ /* bus configuration */
+ int (*set_config)(struct omap_dss_device *dssdev,
+ const struct omap_dss_dsi_config *cfg);
+ int (*configure_pins)(struct omap_dss_device *dssdev,
+ const struct omap_dsi_pin_config *pin_cfg);
+
+ void (*enable_hs)(struct omap_dss_device *dssdev, int channel,
+ bool enable);
+ int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
+
+ int (*update)(struct omap_dss_device *dssdev, int channel,
+ void (*callback)(int, void *), void *data);
+
+ void (*bus_lock)(struct omap_dss_device *dssdev);
+ void (*bus_unlock)(struct omap_dss_device *dssdev);
+
+ int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
+ void (*disable_video_output)(struct omap_dss_device *dssdev,
+ int channel);
+
+ int (*request_vc)(struct omap_dss_device *dssdev, int *channel);
+ int (*set_vc_id)(struct omap_dss_device *dssdev, int channel,
+ int vc_id);
+ void (*release_vc)(struct omap_dss_device *dssdev, int channel);
+
+ /* data transfer */
+ int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
+ u8 *data, int len);
+ int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
+ u8 *data, int len);
+ int (*dcs_read)(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+ u8 *data, int len);
+
+ int (*gen_write)(struct omap_dss_device *dssdev, int channel,
+ u8 *data, int len);
+ int (*gen_write_nosync)(struct omap_dss_device *dssdev, int channel,
+ u8 *data, int len);
+ int (*gen_read)(struct omap_dss_device *dssdev, int channel,
+ u8 *reqdata, int reqlen,
+ u8 *data, int len);
+
+ int (*bta_sync)(struct omap_dss_device *dssdev, int channel);
+
+ int (*set_max_rx_packet_size)(struct omap_dss_device *dssdev,
+ int channel, u16 plen);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -772,6 +829,7 @@ struct omap_dss_device {
const struct omapdss_dvi_ops *dvi;
const struct omapdss_hdmi_ops *hdmi;
const struct omapdss_atv_ops *atv;
+ const struct omapdss_dsi_ops *dsi;
} ops;
/* helper variable for driver suspend/resume */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 14/27] OMAPDSS: HDMI: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using HDMI functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 248 ++++++++++++++++++++++++++++++++++++++++-
include/video/omapdss.h | 47 +++++++-
2 files changed, 284 insertions(+), 11 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 42376d1..9420923 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -70,6 +70,8 @@ static struct {
int ls_oe_gpio;
int hpd_gpio;
+ bool core_enabled;
+
struct omap_dss_device output;
} hdmi;
@@ -521,8 +523,10 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
{
int r;
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
- gpio_set_value(hdmi.ls_oe_gpio, 1);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 1);
/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
udelay(300);
@@ -538,22 +542,30 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
+ hdmi.core_enabled = true;
+
return 0;
err_runtime_get:
regulator_disable(hdmi.vdda_hdmi_dac_reg);
err_vdac_enable:
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
return r;
}
static void hdmi_power_off_core(struct omap_dss_device *dssdev)
{
+ hdmi.core_enabled = false;
+
hdmi_runtime_put();
regulator_disable(hdmi.vdda_hdmi_dac_reg);
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
}
static int hdmi_power_on_full(struct omap_dss_device *dssdev)
@@ -666,6 +678,18 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
mutex_unlock(&hdmi.lock);
}
+static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ const struct hdmi_config *cfg;
+
+ cfg = hdmi_get_timings();
+ if (cfg = NULL)
+ cfg = &vesa_timings[0];
+
+ memcpy(timings, &cfg->timings, sizeof(cfg->timings));
+}
+
static void hdmi_dump_regs(struct seq_file *s)
{
mutex_lock(&hdmi.lock);
@@ -1033,6 +1057,213 @@ static int hdmi_probe_pdata(struct platform_device *pdev)
return 0;
}
+static int hdmi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
+
+ r = hdmi_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void hdmi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static void omapdss_hdmi_set_hpd_gpio(struct omap_dss_device *dssdev,
+ int hpd_gpio)
+{
+ hdmi.hpd_gpio = hpd_gpio;
+}
+
+static int hdmi_read_edid(struct omap_dss_device *dssdev,
+ u8 *edid, int len)
+{
+ bool need_enable;
+ int r;
+
+ need_enable = hdmi.core_enabled = false;
+
+ if (need_enable) {
+ r = omapdss_hdmi_core_enable(dssdev);
+ if (r)
+ return r;
+ }
+
+ r = omapdss_hdmi_read_edid(edid, len);
+
+ if (need_enable)
+ omapdss_hdmi_core_disable(dssdev);
+
+ return r;
+}
+
+static bool hdmi_detect(struct omap_dss_device *dssdev)
+{
+ return omapdss_hdmi_detect();
+}
+
+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
+static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&hdmi.lock);
+
+ if (!hdmi_mode_has_audio()) {
+ r = -EPERM;
+ goto err;
+ }
+
+ r = hdmi_audio_enable();
+ if (r)
+ goto err;
+
+ mutex_unlock(&hdmi.lock);
+ return 0;
+
+err:
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+
+static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
+{
+ hdmi_audio_disable();
+}
+
+static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
+{
+ return hdmi_audio_start();
+}
+
+static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
+{
+ hdmi_audio_stop();
+}
+
+static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
+{
+ bool r;
+
+ mutex_lock(&hdmi.lock);
+
+ r = hdmi_mode_has_audio();
+
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+
+static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ int r;
+
+ mutex_lock(&hdmi.lock);
+
+ if (!hdmi_mode_has_audio()) {
+ r = -EPERM;
+ goto err;
+ }
+
+ r = hdmi_audio_config(audio);
+ if (r)
+ goto err;
+
+ mutex_unlock(&hdmi.lock);
+ return 0;
+
+err:
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+#else
+static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
+{
+ return -EPERM;
+}
+
+static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
+{
+}
+
+static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
+{
+ return -EPERM;
+}
+
+static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
+{
+}
+
+static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
+{
+ return false;
+}
+
+static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ return -EPERM;
+}
+#endif
+
+static const struct omapdss_hdmi_ops hdmi_ops = {
+ .connect = hdmi_connect,
+ .disconnect = hdmi_disconnect,
+
+ .enable = omapdss_hdmi_display_enable,
+ .disable = omapdss_hdmi_display_disable,
+
+ .check_timings = omapdss_hdmi_display_check_timing,
+ .set_timings = omapdss_hdmi_display_set_timing,
+ .get_timings = omapdss_hdmi_display_get_timings,
+
+ .set_hpd_gpio = omapdss_hdmi_set_hpd_gpio,
+
+ .read_edid = hdmi_read_edid,
+ .detect = hdmi_detect,
+
+ .audio_enable = omapdss_hdmi_audio_enable,
+ .audio_disable = omapdss_hdmi_audio_disable,
+ .audio_start = omapdss_hdmi_audio_start,
+ .audio_stop = omapdss_hdmi_audio_stop,
+ .audio_supported = omapdss_hdmi_audio_supported,
+ .audio_config = omapdss_hdmi_audio_config,
+};
+
static void hdmi_init_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &hdmi.output;
@@ -1042,6 +1273,7 @@ static void hdmi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->ops.hdmi = &hdmi_ops;
out->owner = THIS_MODULE;
omapdss_register_output(out);
@@ -1089,6 +1321,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
hdmi.ip_data.phy_offset = HDMI_PHY;
+ hdmi.ct_cp_hpd_gpio = -1;
+ hdmi.ls_oe_gpio = -1;
+ hdmi.hpd_gpio = -1;
+
hdmi_init_output(pdev);
r = hdmi_panel_init();
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index cb6c478..f0aee54 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -172,6 +172,11 @@ enum omap_dss_audio_state {
OMAP_DSS_AUDIO_PLAYING,
};
+struct omap_dss_audio {
+ struct snd_aes_iec958 *iec;
+ struct snd_cea_861_aud_if *cea;
+};
+
enum omap_dss_rotation_type {
OMAP_DSS_ROT_DMA = 1 << 0,
OMAP_DSS_ROT_VRFB = 1 << 1,
@@ -653,6 +658,42 @@ struct omapdss_atv_ops {
u32 (*get_wss)(struct omap_dss_device *dssdev);
};
+struct omapdss_hdmi_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev);
+
+ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+
+ void (*set_hpd_gpio)(struct omap_dss_device *dssdev,
+ int hpd_gpio);
+
+ int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
+ bool (*detect)(struct omap_dss_device *dssdev);
+
+ /*
+ * Note: These functions might sleep. Do not call while
+ * holding a spinlock/readlock.
+ */
+ int (*audio_enable)(struct omap_dss_device *dssdev);
+ void (*audio_disable)(struct omap_dss_device *dssdev);
+ bool (*audio_supported)(struct omap_dss_device *dssdev);
+ int (*audio_config)(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio);
+ /* Note: These functions may not sleep */
+ int (*audio_start)(struct omap_dss_device *dssdev);
+ void (*audio_stop)(struct omap_dss_device *dssdev);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -729,6 +770,7 @@ struct omap_dss_device {
const struct omapdss_dpi_ops *dpi;
const struct omapdss_sdi_ops *sdi;
const struct omapdss_dvi_ops *dvi;
+ const struct omapdss_hdmi_ops *hdmi;
const struct omapdss_atv_ops *atv;
} ops;
@@ -773,11 +815,6 @@ struct omap_dss_hdmi_data
int hpd_gpio;
};
-struct omap_dss_audio {
- struct snd_aes_iec958 *iec;
- struct snd_cea_861_aud_if *cea;
-};
-
struct omap_dss_driver {
struct device_driver driver;
--
1.8.1.2
^ permalink raw reply related
* [PATCH 13/27] OMAPDSS: AnalogTV: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using analog TV functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/venc.c | 72 ++++++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 26 +++++++++++++++
2 files changed, 98 insertions(+)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 291a40d..f5ee767 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -568,6 +568,16 @@ int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
return -EINVAL;
}
+static void venc_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ mutex_lock(&venc.venc_lock);
+
+ *timings = venc.timings;
+
+ mutex_unlock(&venc.venc_lock);
+}
+
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
{
/* Invert due to VENC_L21_WC_CTL:INV=1 */
@@ -783,6 +793,67 @@ static int venc_probe_pdata(struct platform_device *vencdev)
return 0;
}
+static int venc_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = venc_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void venc_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_atv_ops venc_ops = {
+ .connect = venc_connect,
+ .disconnect = venc_disconnect,
+
+ .enable = omapdss_venc_display_enable,
+ .disable = omapdss_venc_display_disable,
+
+ .check_timings = omapdss_venc_check_timings,
+ .set_timings = omapdss_venc_set_timings,
+ .get_timings = venc_get_timings,
+
+ .set_type = omapdss_venc_set_type,
+ .invert_vid_out_polarity = omapdss_venc_invert_vid_out_polarity,
+
+ .set_wss = omapdss_venc_set_wss,
+ .get_wss = omapdss_venc_get_wss,
+};
+
static void venc_init_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &venc.output;
@@ -792,6 +863,7 @@ static void venc_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->ops.atv = &venc_ops;
out->owner = THIS_MODULE;
omapdss_register_output(out);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 9f87fc0..cb6c478 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -628,6 +628,31 @@ struct omapdss_dvi_ops {
struct omap_video_timings *timings);
};
+struct omapdss_atv_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev);
+
+ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+
+ void (*set_type)(struct omap_dss_device *dssdev,
+ enum omap_dss_venc_type type);
+ void (*invert_vid_out_polarity)(struct omap_dss_device *dssdev,
+ bool invert_polarity);
+
+ int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
+ u32 (*get_wss)(struct omap_dss_device *dssdev);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -704,6 +729,7 @@ struct omap_dss_device {
const struct omapdss_dpi_ops *dpi;
const struct omapdss_sdi_ops *sdi;
const struct omapdss_dvi_ops *dvi;
+ const struct omapdss_atv_ops *atv;
} ops;
/* helper variable for driver suspend/resume */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 12/27] OMAPDSS: DVI: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using DVI functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
include/video/omapdss.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 79e9ec8..9f87fc0 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -611,6 +611,23 @@ struct omapdss_sdi_ops {
void (*set_datapairs)(struct omap_dss_device *dssdev, int datapairs);
};
+struct omapdss_dvi_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev);
+
+ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -686,6 +703,7 @@ struct omap_dss_device {
union {
const struct omapdss_dpi_ops *dpi;
const struct omapdss_sdi_ops *sdi;
+ const struct omapdss_dvi_ops *dvi;
} ops;
/* helper variable for driver suspend/resume */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 11/27] OMAPDSS: SDI: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using SDI functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/sdi.c | 78 +++++++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 20 +++++++++++
2 files changed, 98 insertions(+)
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0343d08..a676864 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -235,6 +235,26 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_sdi_set_timings);
+static void sdi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ *timings = sdi.timings;
+}
+
+static int sdi_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct omap_overlay_manager *mgr = sdi.output.manager;
+
+ if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
+ return -EINVAL;
+
+ if (timings->pixel_clock = 0)
+ return -EINVAL;
+
+ return 0;
+}
+
void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
{
sdi.datapairs = datapairs;
@@ -339,6 +359,63 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
return 0;
}
+static int sdi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = sdi_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void sdi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_sdi_ops sdi_ops = {
+ .connect = sdi_connect,
+ .disconnect = sdi_disconnect,
+
+ .enable = omapdss_sdi_display_enable,
+ .disable = omapdss_sdi_display_disable,
+
+ .check_timings = sdi_check_timings,
+ .set_timings = omapdss_sdi_set_timings,
+ .get_timings = sdi_get_timings,
+
+ .set_datapairs = omapdss_sdi_set_datapairs,
+};
+
static void sdi_init_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &sdi.output;
@@ -348,6 +425,7 @@ static void sdi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_SDI;
out->name = "sdi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+ out->ops.sdi = &sdi_ops;
out->owner = THIS_MODULE;
omapdss_register_output(out);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index d458e43..79e9ec8 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -592,6 +592,25 @@ struct omapdss_dpi_ops {
void (*set_data_lines)(struct omap_dss_device *dssdev, int data_lines);
};
+struct omapdss_sdi_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev);
+
+ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+
+ void (*set_datapairs)(struct omap_dss_device *dssdev, int datapairs);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -666,6 +685,7 @@ struct omap_dss_device {
union {
const struct omapdss_dpi_ops *dpi;
+ const struct omapdss_sdi_ops *sdi;
} ops;
/* helper variable for driver suspend/resume */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 10/27] OMAPDSS: DPI: Add ops
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add "ops" style method for using DPI functionality.
Ops style calls will allow us to have arbitrarily long display
pipelines, where each entity can call ops in the previous display
entity.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dpi.c | 70 +++++++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 23 ++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3299e27..a7d40dd 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -462,6 +462,16 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_dpi_set_timings);
+static void dpi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ mutex_lock(&dpi.lock);
+
+ *timings = dpi.timings;
+
+ mutex_unlock(&dpi.lock);
+}
+
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -682,6 +692,65 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
return 0;
}
+static int dpi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = dpi_init_regulator();
+ if (r)
+ return r;
+
+ dpi_init_pll();
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void dpi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_dpi_ops dpi_ops = {
+ .connect = dpi_connect,
+ .disconnect = dpi_disconnect,
+
+ .enable = omapdss_dpi_display_enable,
+ .disable = omapdss_dpi_display_disable,
+
+ .check_timings = dpi_check_timings,
+ .set_timings = omapdss_dpi_set_timings,
+ .get_timings = dpi_get_timings,
+
+ .set_data_lines = omapdss_dpi_set_data_lines,
+};
+
static void dpi_init_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &dpi.output;
@@ -691,6 +760,7 @@ static void dpi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_DPI;
out->name = "dpi.0";
out->dispc_channel = dpi_get_channel();
+ out->ops.dpi = &dpi_ops;
out->owner = THIS_MODULE;
omapdss_register_output(out);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6796b0d..d458e43 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -573,6 +573,25 @@ struct omap_dss_writeback_info {
u8 pre_mult_alpha;
};
+struct omapdss_dpi_ops {
+ int (*connect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+ void (*disconnect)(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst);
+
+ int (*enable)(struct omap_dss_device *dssdev);
+ void (*disable)(struct omap_dss_device *dssdev);
+
+ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+
+ void (*set_data_lines)(struct omap_dss_device *dssdev, int data_lines);
+};
+
struct omap_dss_device {
/* old device, to be removed */
struct device old_dev;
@@ -645,6 +664,10 @@ struct omap_dss_device {
struct omap_dss_driver *driver;
+ union {
+ const struct omapdss_dpi_ops *dpi;
+ } ops;
+
/* helper variable for driver suspend/resume */
bool activate_after_resume;
--
1.8.1.2
^ permalink raw reply related
* [PATCH 09/27] drm/omap: DVI connector fix
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
The omapdrm driver currently uses a string comparison to find out if the
display is a DVI display. This is not reliable, and as we now have a
specific display type for DVI, let's use that.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/gpu/drm/omapdrm/omap_drv.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 4c0bc40..8949246 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -65,10 +65,8 @@ static int get_connector_type(struct omap_dss_device *dssdev)
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_HDMI:
return DRM_MODE_CONNECTOR_HDMIA;
- case OMAP_DISPLAY_TYPE_DPI:
- if (!strcmp(dssdev->name, "dvi"))
- return DRM_MODE_CONNECTOR_DVID;
- /* fallthrough */
+ case OMAP_DISPLAY_TYPE_DVI:
+ return DRM_MODE_CONNECTOR_DVID;
default:
return DRM_MODE_CONNECTOR_Unknown;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 08/27] OMAPDSS: add OMAP_DISPLAY_TYPE_DVI
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Add new display bus type for DVI. This is not used by omapdss driver
itself, but is used by external encoder chips that output DVI.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/display.c | 1 +
include/video/omapdss.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 0daf3e3..fafe7c9 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -61,6 +61,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
case OMAP_DISPLAY_TYPE_VENC:
case OMAP_DISPLAY_TYPE_SDI:
case OMAP_DISPLAY_TYPE_HDMI:
+ case OMAP_DISPLAY_TYPE_DVI:
return 24;
default:
BUG();
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 3582edf..6796b0d 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -70,6 +70,7 @@ enum omap_display_type {
OMAP_DISPLAY_TYPE_DSI = 1 << 3,
OMAP_DISPLAY_TYPE_VENC = 1 << 4,
OMAP_DISPLAY_TYPE_HDMI = 1 << 5,
+ OMAP_DISPLAY_TYPE_DVI = 1 << 6,
};
enum omap_plane {
--
1.8.1.2
^ permalink raw reply related
* [PATCH 07/27] ARM: OMAP: beagle: use new display drivers
From: Tomi Valkeinen @ 2013-05-30 9:36 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Use the new display drivers for Beagleboard.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/board-omap3beagle.c | 56 +++++++++++++++++++++------------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 04c1165..30724e8 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -225,35 +225,46 @@ static struct mtd_partition omap3beagle_nand_partitions[] = {
/* DSS */
-static struct tfp410_platform_data dvi_panel = {
- .i2c_bus_num = 3,
- .power_down_gpio = -1,
+static struct connector_dvi_platform_data beagle_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = 3,
};
-static struct omap_dss_device beagle_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "tfp410",
- .data = &dvi_panel,
- .phy.dpi.data_lines = 24,
+static struct platform_device beagle_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &beagle_dvi_connector_pdata,
};
-static struct omap_dss_device beagle_tv_device = {
+static struct encoder_tfp410_platform_data beagle_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = -1,
+};
+
+static struct platform_device beagle_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &beagle_tfp410_pdata,
+};
+
+static struct connector_atv_platform_data beagle_tv_pdata = {
.name = "tv",
- .driver_name = "venc",
- .type = OMAP_DISPLAY_TYPE_VENC,
- .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
};
-static struct omap_dss_device *beagle_dss_devices[] = {
- &beagle_dvi_device,
- &beagle_tv_device,
+static struct platform_device beagle_tv_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &beagle_tv_pdata,
};
static struct omap_dss_board_info beagle_dss_data = {
- .num_devices = ARRAY_SIZE(beagle_dss_devices),
- .devices = beagle_dss_devices,
- .default_device = &beagle_dvi_device,
+ .default_display_name = "dvi",
};
#include "sdram-micron-mt46h32m32lf-6.h"
@@ -332,7 +343,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
pr_err("%s: unable to configure EHCI_nOC\n", __func__);
}
- dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
+ beagle_tfp410_pdata.power_down_gpio = beagle_config.dvi_pd_gpio;
/* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */
phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX;
@@ -547,6 +558,11 @@ static void __init omap3_beagle_init(void)
if (gpio_is_valid(beagle_config.dvi_pd_gpio))
omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT);
omap_display_init(&beagle_dss_data);
+
+ platform_device_register(&beagle_tfp410_device);
+ platform_device_register(&beagle_dvi_connector_device);
+ platform_device_register(&beagle_tv_device);
+
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 06/27] ARM: OMAP: rx51: use new display drivers
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Use the new display drivers for RX51 board.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/board-rx51-peripherals.c | 12 ++++++++++
arch/arm/mach-omap2/board-rx51-video.c | 35 ++++++++++------------------
2 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 18ca61e..e35e0b6 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -45,6 +45,8 @@
#include <linux/platform_data/tsl2563.h>
#include <linux/lis3lv02d.h>
+#include <video/omap-panel-data.h>
+
#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
#include <media/ir-rx51.h>
#endif
@@ -226,6 +228,15 @@ static struct lp55xx_platform_data rx51_lp5523_platform_data = {
};
#endif
+#define RX51_LCD_RESET_GPIO 90
+
+static struct panel_acx565akm_platform_data acx_pdata = {
+ .name = "lcd",
+ .source = "sdi.0",
+ .reset_gpio = RX51_LCD_RESET_GPIO,
+ .datapairs = 2,
+};
+
static struct omap2_mcspi_device_config wl1251_mcspi_config = {
.turbo_mode = 0,
};
@@ -254,6 +265,7 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
.chip_select = 2,
.max_speed_hz = 6000000,
.controller_data = &mipid_mcspi_config,
+ .platform_data = &acx_pdata,
},
[RX51_SPI_TSC2005] = {
.modalias = "tsc2005",
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index bd74f9f..b007fd3 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -29,34 +29,21 @@
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
-static struct panel_acx565akm_data lcd_data = {
- .reset_gpio = RX51_LCD_RESET_GPIO,
+static struct connector_atv_platform_data rx51_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+ .invert_polarity = false,
};
-static struct omap_dss_device rx51_lcd_device = {
- .name = "lcd",
- .driver_name = "panel-acx565akm",
- .type = OMAP_DISPLAY_TYPE_SDI,
- .phy.sdi.datapairs = 2,
- .data = &lcd_data,
-};
-
-static struct omap_dss_device rx51_tv_device = {
- .name = "tv",
- .type = OMAP_DISPLAY_TYPE_VENC,
- .driver_name = "venc",
- .phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
-};
-
-static struct omap_dss_device *rx51_dss_devices[] = {
- &rx51_lcd_device,
- &rx51_tv_device,
+static struct platform_device rx51_tv_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &rx51_tv_pdata,
};
static struct omap_dss_board_info rx51_dss_board_info = {
- .num_devices = ARRAY_SIZE(rx51_dss_devices),
- .devices = rx51_dss_devices,
- .default_device = &rx51_lcd_device,
+ .default_display_name = "lcd",
};
static int __init rx51_video_init(void)
@@ -71,6 +58,8 @@ static int __init rx51_video_init(void)
omap_display_init(&rx51_dss_board_info);
+ platform_device_register(&rx51_tv_device);
+
return 0;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 05/27] ARM: OMAP: overo: use new display drivers
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Use the new display drivers for OMAP3 Overo board.
Note that the LCD add-on boards for lcd43 and lcd35 use the same GPIOs
for the panels. This means that both panel devices cannot be probed at
the same time.
DT will handle this correctly, i.e. the DT data will contain the panel
device only for the add-on board that is attached. However, for the
board file we need a hackish solution: We parse the kernel boot command
line, and see whether lcd43 or lcd35 is set as a default display, and
add the given one. Or, if neither is given, default to lcd43.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/board-overo.c | 160 ++++++++++++++++++++++++--------------
1 file changed, 100 insertions(+), 60 deletions(-)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index a496774..51fdac6 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -71,6 +71,9 @@
#define OVERO_SMSC911X2_CS 4
#define OVERO_SMSC911X2_GPIO 65
+/* whether to register LCD35 instead of LCD43 */
+static bool overo_use_lcd35;
+
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
@@ -148,78 +151,94 @@ static inline void __init overo_init_smsc911x(void) { return; }
#define OVERO_GPIO_LCD_EN 144
#define OVERO_GPIO_LCD_BL 145
-static struct tfp410_platform_data dvi_panel = {
- .i2c_bus_num = 3,
- .power_down_gpio = -1,
+static struct connector_atv_platform_data overo_tv_pdata = {
+ .name = "tv",
+ .source = "venc.0",
+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .invert_polarity = false,
};
-static struct omap_dss_device overo_dvi_device = {
- .name = "dvi",
- .type = OMAP_DISPLAY_TYPE_DPI,
- .driver_name = "tfp410",
- .data = &dvi_panel,
- .phy.dpi.data_lines = 24,
+static struct platform_device overo_tv_device = {
+ .name = "connector-analog-tv",
+ .id = 0,
+ .dev.platform_data = &overo_tv_pdata,
};
-static struct omap_dss_device overo_tv_device = {
- .name = "tv",
- .driver_name = "venc",
- .type = OMAP_DISPLAY_TYPE_VENC,
- .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+static const struct display_timing overo_lcd43_videomode = {
+ .pixelclock = { 0, 9200000, 0 },
+
+ .hactive = { 0, 480, 0 },
+ .hfront_porch = { 0, 8, 0 },
+ .hback_porch = { 0, 4, 0 },
+ .hsync_len = { 0, 41, 0 },
+
+ .vactive = { 0, 272, 0 },
+ .vfront_porch = { 0, 4, 0 },
+ .vback_porch = { 0, 2, 0 },
+ .vsync_len = { 0, 10, 0 },
+
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
};
-static struct panel_generic_dpi_data lcd43_panel = {
- .name = "samsung_lte430wq_f0c",
- .num_gpios = 2,
- .gpios = {
- OVERO_GPIO_LCD_EN,
- OVERO_GPIO_LCD_BL
- },
+static struct panel_dpi_platform_data overo_lcd43_pdata = {
+ .name = "lcd43",
+ .source = "dpi.0",
+
+ .data_lines = 24,
+
+ .display_timing = &overo_lcd43_videomode,
+
+ .enable_gpio = OVERO_GPIO_LCD_EN,
+ .backlight_gpio = OVERO_GPIO_LCD_BL,
};
-static struct omap_dss_device overo_lcd43_device = {
- .name = "lcd43",
- .type = OMAP_DISPLAY_TYPE_DPI,
- .driver_name = "generic_dpi_panel",
- .data = &lcd43_panel,
- .phy.dpi.data_lines = 24,
+static struct platform_device overo_lcd43_device = {
+ .name = "panel-dpi",
+ .id = 0,
+ .dev.platform_data = &overo_lcd43_pdata,
};
-#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
- defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
-static struct panel_generic_dpi_data lcd35_panel = {
- .num_gpios = 2,
- .gpios = {
- OVERO_GPIO_LCD_EN,
- OVERO_GPIO_LCD_BL
- },
+static struct connector_dvi_platform_data overo_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = 3,
};
-static struct omap_dss_device overo_lcd35_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "lcd35",
- .driver_name = "lgphilips_lb035q02_panel",
- .phy.dpi.data_lines = 24,
- .data = &lcd35_panel,
+static struct platform_device overo_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &overo_dvi_connector_pdata,
};
-#endif
-static struct omap_dss_device *overo_dss_devices[] = {
- &overo_dvi_device,
- &overo_tv_device,
-#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
- defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
- &overo_lcd35_device,
-#endif
- &overo_lcd43_device,
+static struct encoder_tfp410_platform_data overo_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = -1,
+};
+
+static struct platform_device overo_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &overo_tfp410_pdata,
};
static struct omap_dss_board_info overo_dss_data = {
- .num_devices = ARRAY_SIZE(overo_dss_devices),
- .devices = overo_dss_devices,
- .default_device = &overo_dvi_device,
+ .default_display_name = "lcd43",
};
+static void __init overo_display_init(void)
+{
+ omap_display_init(&overo_dss_data);
+
+ if (!overo_use_lcd35)
+ platform_device_register(&overo_lcd43_device);
+ platform_device_register(&overo_tfp410_device);
+ platform_device_register(&overo_dvi_connector_device);
+ platform_device_register(&overo_tv_device);
+}
+
static struct mtd_partition overo_nand_partitions[] = {
{
.name = "xloader",
@@ -407,24 +426,41 @@ static int __init overo_i2c_init(void)
return 0;
}
+static struct panel_lb035q02_platform_data overo_lcd35_pdata = {
+ .name = "lcd35",
+ .source = "dpi.0",
+
+ .data_lines = 24,
+
+ .enable_gpio = OVERO_GPIO_LCD_EN,
+ .backlight_gpio = OVERO_GPIO_LCD_BL,
+};
+
+/*
+ * NOTE: We need to add either the lgphilips panel, or the lcd43 panel. The
+ * selection is done based on the overo_use_lcd35 field. If new SPI
+ * devices are added here, extra work is needed to make only the lgphilips panel
+ * affected by the overo_use_lcd35 field.
+ */
static struct spi_board_info overo_spi_board_info[] __initdata = {
-#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
- defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
{
- .modalias = "lgphilips_lb035q02_panel-spi",
+ .modalias = "panel_lgphilips_lb035q02",
.bus_num = 1,
.chip_select = 1,
.max_speed_hz = 500000,
.mode = SPI_MODE_3,
+ .platform_data = &overo_lcd35_pdata,
},
-#endif
};
static int __init overo_spi_init(void)
{
overo_ads7846_init();
- spi_register_board_info(overo_spi_board_info,
- ARRAY_SIZE(overo_spi_board_info));
+
+ if (overo_use_lcd35) {
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ }
return 0;
}
@@ -462,11 +498,13 @@ static void __init overo_init(void)
{
int ret;
+ if (strstr(boot_command_line, "omapdss.def_disp=lcd35"))
+ overo_use_lcd35 = true;
+
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
overo_i2c_init();
omap_hsmmc_init(mmc);
- omap_display_init(&overo_dss_data);
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
@@ -483,6 +521,8 @@ static void __init overo_init(void)
overo_init_keys();
omap_twl4030_audio_init("overo", NULL);
+ overo_display_init();
+
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 04/27] ARM: OMAP: dss-common: use new display drivers
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
Use the new display drivers for OMAP4 Panda and OMAP4 SDP boards.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/dss-common.c | 185 +++++++++++++++++++++++----------------
1 file changed, 108 insertions(+), 77 deletions(-)
diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c
index 393aeef..17e0a08 100644
--- a/arch/arm/mach-omap2/dss-common.c
+++ b/arch/arm/mach-omap2/dss-common.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/gpio.h>
+#include <linux/platform_device.h>
#include <video/omapdss.h>
#include <video/omap-panel-data.h>
@@ -37,53 +38,76 @@
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
#define HDMI_GPIO_HPD 63 /* Hotplug detect */
-/* Display DVI */
#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
-/* Using generic display panel */
-static struct tfp410_platform_data omap4_dvi_panel = {
- .i2c_bus_num = 3,
- .power_down_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+/* DVI Connector */
+static struct connector_dvi_platform_data omap4_panda_dvi_connector_pdata = {
+ .name = "dvi",
+ .source = "tfp410.0",
+ .i2c_bus_num = 3,
};
-static struct omap_dss_device omap4_panda_dvi_device = {
- .type = OMAP_DISPLAY_TYPE_DPI,
- .name = "dvi",
- .driver_name = "tfp410",
- .data = &omap4_dvi_panel,
- .phy.dpi.data_lines = 24,
- .channel = OMAP_DSS_CHANNEL_LCD2,
+static struct platform_device omap4_panda_dvi_connector_device = {
+ .name = "connector-dvi",
+ .id = 0,
+ .dev.platform_data = &omap4_panda_dvi_connector_pdata,
+};
+
+/* TFP410 DPI-to-DVI chip */
+static struct encoder_tfp410_platform_data omap4_panda_tfp410_pdata = {
+ .name = "tfp410.0",
+ .source = "dpi.0",
+ .data_lines = 24,
+ .power_down_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+};
+
+static struct platform_device omap4_panda_tfp410_device = {
+ .name = "tfp410",
+ .id = 0,
+ .dev.platform_data = &omap4_panda_tfp410_pdata,
};
-static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+/* HDMI Connector */
+static struct connector_hdmi_platform_data omap4_panda_hdmi_connector_pdata = {
+ .name = "hdmi",
+ .source = "tpd12s015.0",
+};
+
+static struct platform_device omap4_panda_hdmi_connector_device = {
+ .name = "connector-hdmi",
+ .id = 0,
+ .dev.platform_data = &omap4_panda_hdmi_connector_pdata,
+};
+
+/* TPD12S015 HDMI ESD protection & level shifter chip */
+static struct encoder_tpd12s015_platform_data omap4_panda_tpd_pdata = {
+ .name = "tpd12s015.0",
+ .source = "hdmi.0",
+
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
.ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
-static struct omap_dss_device omap4_panda_hdmi_device = {
- .name = "hdmi",
- .driver_name = "hdmi_panel",
- .type = OMAP_DISPLAY_TYPE_HDMI,
- .channel = OMAP_DSS_CHANNEL_DIGIT,
- .data = &omap4_panda_hdmi_data,
-};
-
-static struct omap_dss_device *omap4_panda_dss_devices[] = {
- &omap4_panda_dvi_device,
- &omap4_panda_hdmi_device,
+static struct platform_device omap4_panda_tpd_device = {
+ .name = "tpd12s015",
+ .id = 0,
+ .dev.platform_data = &omap4_panda_tpd_pdata,
};
static struct omap_dss_board_info omap4_panda_dss_data = {
- .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
- .devices = omap4_panda_dss_devices,
- .default_device = &omap4_panda_dvi_device,
+ .default_display_name = "dvi",
};
void __init omap4_panda_display_init(void)
{
omap_display_init(&omap4_panda_dss_data);
+ platform_device_register(&omap4_panda_tfp410_device);
+ platform_device_register(&omap4_panda_dvi_connector_device);
+
+ platform_device_register(&omap4_panda_tpd_device);
+ platform_device_register(&omap4_panda_hdmi_connector_device);
/*
* OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
* later have external pull up on the HDMI I2C lines
@@ -109,67 +133,71 @@ void __init omap4_panda_display_init_of(void)
#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
#define DLP_POWER_ON_GPIO 40
-static struct nokia_dsi_panel_data dsi1_panel = {
- .name = "taal",
- .reset_gpio = 102,
- .use_ext_te = false,
- .ext_te_gpio = 101,
- .esd_interval = 0,
- .pin_config = {
- .num_pins = 6,
- .pins = { 0, 1, 2, 3, 4, 5 },
- },
-};
-
-static struct omap_dss_device sdp4430_lcd_device = {
- .name = "lcd",
- .driver_name = "taal",
- .type = OMAP_DISPLAY_TYPE_DSI,
- .data = &dsi1_panel,
- .phy.dsi = {
- .module = 0,
+static struct panel_dsicm_platform_data dsi1_panel = {
+ .name = "lcd",
+ .source = "dsi.0",
+ .reset_gpio = 102,
+ .use_ext_te = false,
+ .ext_te_gpio = 101,
+ .pin_config = {
+ .num_pins = 6,
+ .pins = { 0, 1, 2, 3, 4, 5 },
},
- .channel = OMAP_DSS_CHANNEL_LCD,
};
-static struct nokia_dsi_panel_data dsi2_panel = {
- .name = "taal",
- .reset_gpio = 104,
- .use_ext_te = false,
- .ext_te_gpio = 103,
- .esd_interval = 0,
- .pin_config = {
- .num_pins = 6,
- .pins = { 0, 1, 2, 3, 4, 5 },
- },
+static struct platform_device sdp4430_lcd_device = {
+ .name = "panel-dsi-cm",
+ .id = 0,
+ .dev.platform_data = &dsi1_panel,
};
-static struct omap_dss_device sdp4430_lcd2_device = {
- .name = "lcd2",
- .driver_name = "taal",
- .type = OMAP_DISPLAY_TYPE_DSI,
- .data = &dsi2_panel,
- .phy.dsi = {
-
- .module = 1,
+static struct panel_dsicm_platform_data dsi2_panel = {
+ .name = "lcd2",
+ .source = "dsi.1",
+ .reset_gpio = 104,
+ .use_ext_te = false,
+ .ext_te_gpio = 103,
+ .pin_config = {
+ .num_pins = 6,
+ .pins = { 0, 1, 2, 3, 4, 5 },
},
- .channel = OMAP_DSS_CHANNEL_LCD2,
};
-static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+static struct platform_device sdp4430_lcd2_device = {
+ .name = "panel-dsi-cm",
+ .id = 1,
+ .dev.platform_data = &dsi2_panel,
+};
+
+/* HDMI Connector */
+static struct connector_hdmi_platform_data sdp4430_hdmi_connector_pdata = {
+ .name = "hdmi",
+ .source = "tpd12s015.0",
+};
+
+static struct platform_device sdp4430_hdmi_connector_device = {
+ .name = "connector-hdmi",
+ .id = 0,
+ .dev.platform_data = &sdp4430_hdmi_connector_pdata,
+};
+
+/* TPD12S015 HDMI ESD protection & level shifter chip */
+static struct encoder_tpd12s015_platform_data sdp4430_tpd_pdata = {
+ .name = "tpd12s015.0",
+ .source = "hdmi.0",
+
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
.ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
-static struct omap_dss_device sdp4430_hdmi_device = {
- .name = "hdmi",
- .driver_name = "hdmi_panel",
- .type = OMAP_DISPLAY_TYPE_HDMI,
- .channel = OMAP_DSS_CHANNEL_DIGIT,
- .data = &sdp4430_hdmi_data,
+static struct platform_device sdp4430_tpd_device = {
+ .name = "tpd12s015",
+ .id = 0,
+ .dev.platform_data = &sdp4430_tpd_pdata,
};
+
static struct picodlp_panel_data sdp4430_picodlp_pdata = {
.picodlp_adapter_id = 2,
.emu_done_gpio = 44,
@@ -186,16 +214,13 @@ static struct omap_dss_device sdp4430_picodlp_device = {
};
static struct omap_dss_device *sdp4430_dss_devices[] = {
- &sdp4430_lcd_device,
- &sdp4430_lcd2_device,
- &sdp4430_hdmi_device,
&sdp4430_picodlp_device,
};
static struct omap_dss_board_info sdp4430_dss_data = {
.num_devices = ARRAY_SIZE(sdp4430_dss_devices),
.devices = sdp4430_dss_devices,
- .default_device = &sdp4430_lcd_device,
+ .default_display_name = "lcd",
};
/*
@@ -231,6 +256,12 @@ void __init omap_4430sdp_display_init(void)
omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+
+ platform_device_register(&sdp4430_lcd_device);
+ platform_device_register(&sdp4430_lcd2_device);
+
+ platform_device_register(&sdp4430_tpd_device);
+ platform_device_register(&sdp4430_hdmi_connector_device);
}
void __init omap_4430sdp_display_init_of(void)
--
1.8.1.2
^ permalink raw reply related
* [PATCH 03/27] OMAPDSS: add platform data structs for new panel drivers
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
With the new DSS device model, we'll have new panel and encoder drivers.
This patch adds the platform data structs for all the new drivers.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
include/video/omap-panel-data.h | 150 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index 0c3b46d..317ee36 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -27,6 +27,8 @@
#ifndef __OMAP_PANEL_DATA_H
#define __OMAP_PANEL_DATA_H
+#include <video/omapdss.h>
+
struct omap_dss_device;
/**
@@ -147,4 +149,152 @@ struct panel_tpo_td043_data {
int nreset_gpio;
};
+/**
+ * panel_dpi platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @data_lines: number of DPI datalines
+ * @display_timing: timings for this panel
+ * @backlight_gpio: gpio to enable/disable the backlight (or -1)
+ * @enable_gpio: gpio to enable/disable the panel (or -1)
+ */
+struct panel_dpi_platform_data {
+ const char *name;
+ const char *source;
+
+ int data_lines;
+
+ const struct display_timing *display_timing;
+
+ int backlight_gpio;
+ int enable_gpio;
+};
+
+/**
+ * panel_dsicm platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @reset_gpio: gpio to reset the panel (or -1)
+ * @use_ext_te: use external TE GPIO
+ * @ext_te_gpio: external TE GPIO
+ * @ulps_timeout: time to wait before entering ULPS, 0 = disabled (ms)
+ * @use_dsi_backlight: true if panel uses DSI command to control backlight
+ * @pin_config: DSI pin configuration
+ */
+struct panel_dsicm_platform_data {
+ const char *name;
+ const char *source;
+
+ int reset_gpio;
+
+ bool use_ext_te;
+ int ext_te_gpio;
+
+ unsigned ulps_timeout;
+
+ bool use_dsi_backlight;
+
+ struct omap_dsi_pin_config pin_config;
+};
+
+/**
+ * panel_acx565akm platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @reset_gpio: gpio to reset the panel (or -1)
+ * @datapairs: number of SDI datapairs
+ */
+struct panel_acx565akm_platform_data {
+ const char *name;
+ const char *source;
+
+ int reset_gpio;
+
+ int datapairs;
+};
+
+/**
+ * panel_lb035q02 platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @data_lines: number of DPI datalines
+ * @backlight_gpio: gpio to enable/disable the backlight (or -1)
+ * @enable_gpio: gpio to enable/disable the panel (or -1)
+ */
+struct panel_lb035q02_platform_data {
+ const char *name;
+ const char *source;
+
+ int data_lines;
+
+ int backlight_gpio;
+ int enable_gpio;
+};
+
+/**
+ * connector_dvi platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @i2c_bus_num: i2c bus number to be used for reading EDID
+ */
+struct connector_dvi_platform_data {
+ const char *name;
+ const char *source;
+ int i2c_bus_num;
+};
+
+/**
+ * connector_hdmi platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ */
+struct connector_hdmi_platform_data {
+ const char *name;
+ const char *source;
+};
+
+/**
+ * connector_atv platform data
+ * @name: name for this display entity
+ * @source: name of the display entity used as a video source
+ * @connector_type: composite/svideo
+ * @invert_polarity: invert signal polarity
+ */
+struct connector_atv_platform_data {
+ const char *name;
+ const char *source;
+
+ enum omap_dss_venc_type connector_type;
+ bool invert_polarity;
+};
+
+/**
+ * encoder_tfp410 platform data
+ * @name: name for this display entity
+ * @power_down_gpio: gpio number for PD pin (or -1 if not available)
+ * @data_lines: number of DPI datalines
+ */
+struct encoder_tfp410_platform_data {
+ const char *name;
+ const char *source;
+ int power_down_gpio;
+ int data_lines;
+};
+
+/**
+ * encoder_tpd12s015 platform data
+ * @name: name for this display entity
+ * @ct_cp_hpd_gpio: CT_CP_HPD gpio number
+ * @ls_oe_gpio: LS_OE gpio number
+ * @hpd_gpio: HPD gpio number
+ */
+struct encoder_tpd12s015_platform_data {
+ const char *name;
+ const char *source;
+
+ int ct_cp_hpd_gpio;
+ int ls_oe_gpio;
+ int hpd_gpio;
+};
+
#endif /* __OMAP_PANEL_DATA_H */
--
1.8.1.2
^ permalink raw reply related
* [PATCH 02/27] OMAPDSS: modify get/find functions to go through the device chain
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
In the future will have arbitrarily long video pipeline chains, instead
of the current two-entities-per-pipeline model.
This patch changes the affected get/find style functions so that they
properly go through the video pipeline chain, for example when getting
the overlay manager connected to a given display.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 14 +++++++++++++-
drivers/video/omap2/dss/output.c | 8 +++++++-
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 752b985..d6212d63 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -422,7 +422,19 @@ static void wait_pending_extra_info_updates(void)
static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
{
- return mgr->output ? mgr->output->device : NULL;
+ struct omap_dss_device *dssdev;
+
+ dssdev = mgr->output;
+ if (dssdev = NULL)
+ return NULL;
+
+ while (dssdev->device)
+ dssdev = dssdev->device;
+
+ if (dssdev->driver)
+ return dssdev;
+ else
+ return NULL;
}
static struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 0ba168e..3f5c0a7 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -146,7 +146,13 @@ EXPORT_SYMBOL(omap_dss_find_output_by_node);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
{
- return omap_dss_get_device(dssdev->output);
+ while (dssdev->output)
+ dssdev = dssdev->output;
+
+ if (dssdev->id != 0)
+ return omap_dss_get_device(dssdev);
+
+ return NULL;
}
EXPORT_SYMBOL(omapdss_find_output_from_display);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 01/27] OMAPDSS: public omapdss_register_output()
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906580-27585-1-git-send-email-tomi.valkeinen@ti.com>
In order to allow multiple display block in a video pipeline, we need to
give the drivers way to register themselves. For now we have
the omapdss_register_display() which is used to register panels, and
dss_register_output() which is used to register DSS encoders.
This patch makes dss_register_output() public (with the name of
omapdss_register_output), which can be used to register also external
encoders. The distinction between register_output and register_display
is that a "display" is an entity at the end of the videopipeline, and
"output" is something inside the pipeline.
The registration and naming will be made saner in the future, but the
current names and functions are kept to minimize changes during the dss
device model transition.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dpi.c | 4 ++--
drivers/video/omap2/dss/dsi.c | 4 ++--
drivers/video/omap2/dss/dss.h | 4 ----
drivers/video/omap2/dss/hdmi.c | 4 ++--
drivers/video/omap2/dss/output.c | 7 +++++--
drivers/video/omap2/dss/rfbi.c | 4 ++--
drivers/video/omap2/dss/sdi.c | 4 ++--
drivers/video/omap2/dss/venc.c | 4 ++--
include/video/omapdss.h | 2 ++
9 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 0afbcd5..3299e27 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -693,14 +693,14 @@ static void dpi_init_output(struct platform_device *pdev)
out->dispc_channel = dpi_get_channel();
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit dpi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &dpi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
static int omap_dpi_probe(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 2f90019..4ecc0c1 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5426,7 +5426,7 @@ static void dsi_init_output(struct platform_device *dsidev)
out->dispc_channel = dsi_get_channel(dsi->module_id);
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void dsi_uninit_output(struct platform_device *dsidev)
@@ -5434,7 +5434,7 @@ static void dsi_uninit_output(struct platform_device *dsidev)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_dss_device *out = &dsi->output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* DSI1 HW IP initialisation */
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 67a509e..902d458 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -179,10 +179,6 @@ void dss_put_device(struct omap_dss_device *dssdev);
void dss_copy_device_pdata(struct omap_dss_device *dst,
const struct omap_dss_device *src);
-/* output */
-void dss_register_output(struct omap_dss_device *out);
-void dss_unregister_output(struct omap_dss_device *out);
-
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 1a7b179..42376d1 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -1044,14 +1044,14 @@ static void hdmi_init_output(struct platform_device *pdev)
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit hdmi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &hdmi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* HDMI HW IP initialisation */
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 9ad7d21..0ba168e 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -92,15 +92,18 @@ err:
}
EXPORT_SYMBOL(omapdss_output_unset_device);
-void dss_register_output(struct omap_dss_device *out)
+int omapdss_register_output(struct omap_dss_device *out)
{
list_add_tail(&out->list, &output_list);
+ return 0;
}
+EXPORT_SYMBOL(omapdss_register_output);
-void dss_unregister_output(struct omap_dss_device *out)
+void omapdss_unregister_output(struct omap_dss_device *out)
{
list_del(&out->list);
}
+EXPORT_SYMBOL(omapdss_unregister_output);
struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
{
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index f18c946..fdfe6e6 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -1022,14 +1022,14 @@ static void rfbi_init_output(struct platform_device *pdev)
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit rfbi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &rfbi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* RFBI HW IP initialisation */
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 10268a2..0343d08 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -350,14 +350,14 @@ static void sdi_init_output(struct platform_device *pdev)
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit sdi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &sdi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
static int omap_sdi_probe(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 0deb771..291a40d 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -794,14 +794,14 @@ static void venc_init_output(struct platform_device *pdev)
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit venc_uninit_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &venc.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* VENC HW IP initialisation */
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b2e6160..3582edf 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -793,6 +793,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
+int omapdss_register_output(struct omap_dss_device *output);
+void omapdss_unregister_output(struct omap_dss_device *output);
struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id);
struct omap_dss_device *omap_dss_find_output(const char *name);
struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 00/27] OMAPDSS: dss-dev-model (Part 2/2)
From: Tomi Valkeinen @ 2013-05-30 9:35 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja
Cc: Tomi Valkeinen, Tony Lindgren, Igor Grinberg
Hi,
Here's are the first sets of patches targeting towards enabling DT for DSS and
changing the DSS device model to be more versatile. The exact division of the
sets of patches is still a bit open, and some splitting up for arch/driver
changes is needed, but most likely there will be at least the following major
sets, each based on the former one:
- base, containing cleanups and changes that do not yet really bring bigger new
features
- dev-model, implements the new DSS device model, including new panel drivers
- dt, adds DSS DT support (not at all ready yet, although works for a few boards)
The patches can be found from the following branches:
git://gitorious.org/linux-omap-dss2/linux.git work/dss-dev-model-base
git://gitorious.org/linux-omap-dss2/linux.git work/dss-dev-model
git://gitorious.org/linux-omap-dss2/linux.git work/dss-dev-model-dt
The set you are looking at is the "dev-model" set.
The "dev-model" implements a new model for display drivers. The model is very
much in the direction of CDF (Common Display Framework) as has been discussed
on the mailing lists. However, it's still OMAP specific, and, for example, the
display ops have not been improved but they were just copied from the old DSS
API to make the conversion simpler.
The first main change with the "dev-model" is that display devices/drivers are
no longer special omapdss device/driver types, but they are (usually)
devices/drivers of their control bus. This means that many devices/drivers are
platform devices/drivers, but some are i2c or spi devices/drivers.
The other main change is the use of "ops" instead of direct function calls.
This allows us to create "chains" of display entities, which allows us to
(finally) create proper drivers for external encoders. As an example, a board
with an external DSI-to-LVDS encoder chip and an LVDS panel was previously
modelled with a single display driver, handling both the encoder and the panel.
Now we can have separate drivers for the encoder and for the panel.
Note that to keep the old drivers and board files working, the old drivers and
the omapdss support needed for those is not removed yet. This makes the code
quite messy in a few places. The old code can be removed after all the panels
and board files have been converted.
In this set, the following board files have been converted so far:
- OMAP4 Blaze
- OMAP4 Panda
- Overo
- Beagle
- RX51 (not tested)
The panel drivers needed for the above have been converted, but there's still a
bunch of panel drivers not converted. Also, DSS RFBI driver has not been
converted.
The "dev-model" set brings back the support to have multiple panel devices
connected to the same video output, of which only one can be enabled at a time.
For example, DVI and a panel connected to OMAP's DPI output.
Overo board has an added difficulty to support the above: Overo board file adds
two panel devices, lcd43 and lcd35 (in reality those panels are not attached at
the same time, as they are located in add-on boards). Both panels have the same
GPIO used for reset. This causes a problem as when the panel drivers are
loaded, both drivers try to acquire the same GPIO, and the latter one fails.
To solve the problem, I added kernel boot command line parsing to Overo's board
file. The code looks for "default display" parameter for omapdss, and uses that
to decide which panel device to add.
Note that the above is not Overo specific, but as far as I know, Overo is the
only board having such a setup.
Tomi
Tomi Valkeinen (27):
OMAPDSS: public omapdss_register_output()
OMAPDSS: modify get/find functions to go through the device chain
OMAPDSS: add platform data structs for new panel drivers
ARM: OMAP: dss-common: use new display drivers
ARM: OMAP: overo: use new display drivers
ARM: OMAP: rx51: use new display drivers
ARM: OMAP: beagle: use new display drivers
OMAPDSS: add OMAP_DISPLAY_TYPE_DVI
drm/omap: DVI connector fix
OMAPDSS: DPI: Add ops
OMAPDSS: SDI: Add ops
OMAPDSS: DVI: Add ops
OMAPDSS: AnalogTV: Add ops
OMAPDSS: HDMI: Add ops
OMAPDSS: DSI: Add ops
OMAPDSS: Add new TFP410 Encoder driver
OMAPDSS: Add new TPD12S015 Encoder driver
OMAPDSS: Add new DVI Connector driver
OMAPDSS: Add new HDMI Connector driver
OMAPDSS: Add new Analog TV Connector driver
OMAPDSS: Add new simple DPI panel driver
OMAPDSS: Add new DSI Command Mode panel driver
OMAPDSS: Add Sony ACX565AKM panel driver
OMAPDSS: Add LG.Philips LB035Q02 panel driver
ARM: OMAP: fix dsi regulator names
ARM: OMAP: add vdds_dsi supply for dpi.0
ARM: OMAP: add vdds_sdi supply for sdi.0
arch/arm/mach-omap2/board-cm-t35.c | 3 +-
arch/arm/mach-omap2/board-devkit8000.c | 1 +
arch/arm/mach-omap2/board-ldp.c | 3 +-
arch/arm/mach-omap2/board-omap3beagle.c | 56 +-
arch/arm/mach-omap2/board-omap3pandora.c | 1 +
arch/arm/mach-omap2/board-overo.c | 160 ++-
arch/arm/mach-omap2/board-rx51-peripherals.c | 13 +
arch/arm/mach-omap2/board-rx51-video.c | 35 +-
arch/arm/mach-omap2/dss-common.c | 185 +--
arch/arm/mach-omap2/twl-common.c | 1 +
drivers/gpu/drm/omapdrm/omap_drv.c | 6 +-
drivers/video/omap2/Kconfig | 1 +
drivers/video/omap2/Makefile | 1 +
drivers/video/omap2/displays-new/Kconfig | 52 +
drivers/video/omap2/displays-new/Makefile | 9 +
.../video/omap2/displays-new/connector-analog-tv.c | 265 ++++
drivers/video/omap2/displays-new/connector-dvi.c | 351 +++++
drivers/video/omap2/displays-new/connector-hdmi.c | 375 ++++++
drivers/video/omap2/displays-new/encoder-tfp410.c | 270 ++++
.../video/omap2/displays-new/encoder-tpd12s015.c | 395 ++++++
drivers/video/omap2/displays-new/panel-dpi.c | 270 ++++
drivers/video/omap2/displays-new/panel-dsi-cm.c | 1336 ++++++++++++++++++++
.../omap2/displays-new/panel-lgphilips-lb035q02.c | 358 ++++++
.../omap2/displays-new/panel-sony-acx565akm.c | 864 +++++++++++++
drivers/video/omap2/dss/apply.c | 14 +-
drivers/video/omap2/dss/display.c | 1 +
drivers/video/omap2/dss/dpi.c | 74 +-
drivers/video/omap2/dss/dsi.c | 97 +-
drivers/video/omap2/dss/dss.h | 4 -
drivers/video/omap2/dss/hdmi.c | 252 +++-
drivers/video/omap2/dss/output.c | 15 +-
drivers/video/omap2/dss/rfbi.c | 4 +-
drivers/video/omap2/dss/sdi.c | 82 +-
drivers/video/omap2/dss/venc.c | 76 +-
include/video/omap-panel-data.h | 150 +++
include/video/omapdss.h | 195 ++-
36 files changed, 5758 insertions(+), 217 deletions(-)
create mode 100644 drivers/video/omap2/displays-new/Kconfig
create mode 100644 drivers/video/omap2/displays-new/Makefile
create mode 100644 drivers/video/omap2/displays-new/connector-analog-tv.c
create mode 100644 drivers/video/omap2/displays-new/connector-dvi.c
create mode 100644 drivers/video/omap2/displays-new/connector-hdmi.c
create mode 100644 drivers/video/omap2/displays-new/encoder-tfp410.c
create mode 100644 drivers/video/omap2/displays-new/encoder-tpd12s015.c
create mode 100644 drivers/video/omap2/displays-new/panel-dpi.c
create mode 100644 drivers/video/omap2/displays-new/panel-dsi-cm.c
create mode 100644 drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
create mode 100644 drivers/video/omap2/displays-new/panel-sony-acx565akm.c
--
1.8.1.2
^ permalink raw reply
* [PATCH 32/32] OMAPFB: use EPROBE_DEFER if default display is not present
From: Tomi Valkeinen @ 2013-05-30 9:34 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906493-27538-1-git-send-email-tomi.valkeinen@ti.com>
Currently omapfb returns EPROBE_DEFER if no displays have been probed at
the time omapfb is probed. However, sometimes some of the displays have
been probed at that time, but not all. We can't return EPROBE_DEFER in
that case, because then one missing driver would cause omapfb to defer
always, preventing any display from working.
However, if the user has defined a default display, we can presume that
the driver for that display is eventually loaded. Thus, this patch
changes omapfb to return EPROBE_DEFER in case default display is not
found.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index eacbafa..0c0d078 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2500,7 +2500,7 @@ static int omapfb_probe(struct platform_device *pdev)
if (def_display = NULL) {
dev_err(fbdev->dev, "failed to find default display\n");
- r = -EINVAL;
+ r = -EPROBE_DEFER;
goto cleanup;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 31/32] OMAPDSS: output: increase refcount in find_output funcs
From: Tomi Valkeinen @ 2013-05-30 9:34 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906493-27538-1-git-send-email-tomi.valkeinen@ti.com>
Now that omap_dss_output has been combined into omap_dss_device, we can
add ref counting for the relevant output functions also.
This patch adds omap_dss_get_device() calls to the various find_output()
style functions. This, of course, means that the users of those
find_output functions need to do a omap_dss_put_device() after use.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/gpu/drm/omapdrm/omap_drv.c | 2 ++
drivers/video/omap2/dss/output.c | 13 +++++++++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index a72100c..4c0bc40 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -277,6 +277,8 @@ static int omap_modeset_init(struct drm_device *dev)
if (supported_outputs & output->id)
encoder->possible_crtcs |= (1 << id);
}
+
+ omap_dss_put_device(output);
}
DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index cc81fec..9ad7d21 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -121,7 +121,7 @@ struct omap_dss_device *omap_dss_find_output(const char *name)
list_for_each_entry(out, &output_list, list) {
if (strcmp(out->name, name) = 0)
- return out;
+ return omap_dss_get_device(out);
}
return NULL;
@@ -134,7 +134,7 @@ struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
list_for_each_entry(out, &output_list, list) {
if (out->dev->of_node = node)
- return out;
+ return omap_dss_get_device(out);
}
return NULL;
@@ -143,20 +143,25 @@ EXPORT_SYMBOL(omap_dss_find_output_by_node);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
{
- return dssdev->output;
+ return omap_dss_get_device(dssdev->output);
}
EXPORT_SYMBOL(omapdss_find_output_from_display);
struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out;
+ struct omap_overlay_manager *mgr;
out = omapdss_find_output_from_display(dssdev);
if (out = NULL)
return NULL;
- return out->manager;
+ mgr = out->manager;
+
+ omap_dss_put_device(out);
+
+ return mgr;
}
EXPORT_SYMBOL(omapdss_find_mgr_from_display);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 30/32] OMAPDSS: add THIS_MODULE owner to DSS outputs
From: Tomi Valkeinen @ 2013-05-30 9:34 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906493-27538-1-git-send-email-tomi.valkeinen@ti.com>
Setup the owner field for DSS output's omap_dss_device so that module
refcounting works.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dpi.c | 1 +
drivers/video/omap2/dss/dsi.c | 1 +
drivers/video/omap2/dss/hdmi.c | 1 +
drivers/video/omap2/dss/rfbi.c | 1 +
drivers/video/omap2/dss/sdi.c | 1 +
drivers/video/omap2/dss/venc.c | 1 +
6 files changed, 6 insertions(+)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 03d8afd..0afbcd5 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -691,6 +691,7 @@ static void dpi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_DPI;
out->name = "dpi.0";
out->dispc_channel = dpi_get_channel();
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 9aafefc..2f90019 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5424,6 +5424,7 @@ static void dsi_init_output(struct platform_device *dsidev)
out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id = 0 ? "dsi.0" : "dsi.1";
out->dispc_channel = dsi_get_channel(dsi->module_id);
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index e33e708..1a7b179 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -1042,6 +1042,7 @@ static void hdmi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 35836eb..f18c946 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -1020,6 +1020,7 @@ static void rfbi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_DBI;
out->name = "rfbi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index a226c37..10268a2 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -348,6 +348,7 @@ static void sdi_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_SDI;
out->name = "sdi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7bfcba4..0deb771 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -792,6 +792,7 @@ static void venc_init_output(struct platform_device *pdev)
out->output_type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->owner = THIS_MODULE;
dss_register_output(out);
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 29/32] OMAPDSS: add module_get/put to omap_dss_get/put_device()
From: Tomi Valkeinen @ 2013-05-30 9:34 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906493-27538-1-git-send-email-tomi.valkeinen@ti.com>
omap_dss_get_device() should be called for omap_dss_device before it is
used to increase its refcount. Currently we only increase the refcount
for the underlying device.
This patch adds managing the ref count to the underlying module also,
which contains the ops for the omap_dss_device.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/display.c | 13 +++++++++++--
include/video/omapdss.h | 2 +-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 8096764..0daf3e3 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -158,15 +158,24 @@ void omapdss_unregister_display(struct omap_dss_device *dssdev)
}
EXPORT_SYMBOL(omapdss_unregister_display);
-void omap_dss_get_device(struct omap_dss_device *dssdev)
+struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
{
- get_device(dssdev->dev);
+ if (!try_module_get(dssdev->owner))
+ return NULL;
+
+ if (get_device(dssdev->dev) = NULL) {
+ module_put(dssdev->owner);
+ return NULL;
+ }
+
+ return dssdev;
}
EXPORT_SYMBOL(omap_dss_get_device);
void omap_dss_put_device(struct omap_dss_device *dssdev)
{
put_device(dssdev->dev);
+ module_put(dssdev->owner);
}
EXPORT_SYMBOL(omap_dss_put_device);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index c32d90e..b2e6160 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -766,7 +766,7 @@ void omap_dss_unregister_driver(struct omap_dss_driver *);
int omapdss_register_display(struct omap_dss_device *dssdev);
void omapdss_unregister_display(struct omap_dss_device *dssdev);
-void omap_dss_get_device(struct omap_dss_device *dssdev);
+struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev);
void omap_dss_put_device(struct omap_dss_device *dssdev);
#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
--
1.8.1.2
^ permalink raw reply related
* [PATCH 28/32] OMAPDSS: omapdss.h: add owner field to omap_dss_device
From: Tomi Valkeinen @ 2013-05-30 9:34 UTC (permalink / raw)
To: linux-fbdev, linux-omap, Archit Taneja; +Cc: Tomi Valkeinen
In-Reply-To: <1369906493-27538-1-git-send-email-tomi.valkeinen@ti.com>
Add struct module *owner field to omap_dss_device, which points to the
module containing the ops for this omap_dss_device. This will be used to
manage the ref count for the module.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
include/video/omapdss.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 5046264..c32d90e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -579,6 +579,8 @@ struct omap_dss_device {
/* new device, pointer to panel device */
struct device *dev;
+ struct module *owner;
+
struct list_head panel_list;
/* alias in the form of "display%d" */
--
1.8.1.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox