diff options
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 93 | ||||
-rw-r--r-- | include/video/omapdss.h | 58 |
2 files changed, 151 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 58fbff94e018..99a043b08f0d 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 709e8015f324..b39463553845 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -691,6 +691,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; @@ -762,6 +819,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 */ |