OMAPDSS: SDI: Add ops
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 24 May 2013 10:19:14 +0000 (13:19 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 17 Jun 2013 11:00:59 +0000 (14:00 +0300)
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
include/video/omapdss.h

index 69d907f7df4a3e29dd137e4c75e5073df4a6a5cb..856af2e89760937d01d3459a1bd879ca84b6d4cd 100644 (file)
@@ -234,6 +234,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;
@@ -333,6 +353,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;
@@ -342,6 +419,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);
index 71fe1566ce011ca276b66216afe8697ae22eaee8..c5935a824ec5ab0d80024e046f1880b310754db0 100644 (file)
@@ -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;
@@ -659,6 +678,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 */