19960aa7cSTomi Valkeinen /* 2bb5cdf8dSAndrew F. Davis * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 39960aa7cSTomi Valkeinen * Author: Archit Taneja <archit@ti.com> 49960aa7cSTomi Valkeinen * 59960aa7cSTomi Valkeinen * This program is free software; you can redistribute it and/or modify it 69960aa7cSTomi Valkeinen * under the terms of the GNU General Public License version 2 as published by 79960aa7cSTomi Valkeinen * the Free Software Foundation. 89960aa7cSTomi Valkeinen * 99960aa7cSTomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT 109960aa7cSTomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 119960aa7cSTomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 129960aa7cSTomi Valkeinen * more details. 139960aa7cSTomi Valkeinen * 149960aa7cSTomi Valkeinen * You should have received a copy of the GNU General Public License along with 159960aa7cSTomi Valkeinen * this program. If not, see <http://www.gnu.org/licenses/>. 169960aa7cSTomi Valkeinen */ 179960aa7cSTomi Valkeinen 189960aa7cSTomi Valkeinen #include <linux/kernel.h> 199960aa7cSTomi Valkeinen #include <linux/module.h> 209960aa7cSTomi Valkeinen #include <linux/platform_device.h> 219960aa7cSTomi Valkeinen #include <linux/slab.h> 229960aa7cSTomi Valkeinen #include <linux/of.h> 239960aa7cSTomi Valkeinen 24845417b3SLaurent Pinchart #include "dss.h" 2532043da7SPeter Ujfalusi #include "omapdss.h" 269960aa7cSTomi Valkeinen 279960aa7cSTomi Valkeinen static DEFINE_MUTEX(output_lock); 289960aa7cSTomi Valkeinen 299960aa7cSTomi Valkeinen int omapdss_output_set_device(struct omap_dss_device *out, 309960aa7cSTomi Valkeinen struct omap_dss_device *dssdev) 319960aa7cSTomi Valkeinen { 329960aa7cSTomi Valkeinen int r; 339960aa7cSTomi Valkeinen 349960aa7cSTomi Valkeinen mutex_lock(&output_lock); 359960aa7cSTomi Valkeinen 369960aa7cSTomi Valkeinen if (out->dst) { 3739637e10STomi Valkeinen dev_err(out->dev, 3839637e10STomi Valkeinen "output already has device %s connected to it\n", 399960aa7cSTomi Valkeinen out->dst->name); 409960aa7cSTomi Valkeinen r = -EINVAL; 419960aa7cSTomi Valkeinen goto err; 429960aa7cSTomi Valkeinen } 439960aa7cSTomi Valkeinen 449960aa7cSTomi Valkeinen if (out->output_type != dssdev->type) { 4539637e10STomi Valkeinen dev_err(out->dev, "output type and display type don't match\n"); 469960aa7cSTomi Valkeinen r = -EINVAL; 479960aa7cSTomi Valkeinen goto err; 489960aa7cSTomi Valkeinen } 499960aa7cSTomi Valkeinen 509960aa7cSTomi Valkeinen mutex_unlock(&output_lock); 519960aa7cSTomi Valkeinen 529960aa7cSTomi Valkeinen return 0; 539960aa7cSTomi Valkeinen err: 549960aa7cSTomi Valkeinen mutex_unlock(&output_lock); 559960aa7cSTomi Valkeinen 569960aa7cSTomi Valkeinen return r; 579960aa7cSTomi Valkeinen } 589960aa7cSTomi Valkeinen EXPORT_SYMBOL(omapdss_output_set_device); 599960aa7cSTomi Valkeinen 609960aa7cSTomi Valkeinen int omapdss_output_unset_device(struct omap_dss_device *out) 619960aa7cSTomi Valkeinen { 629960aa7cSTomi Valkeinen int r; 639960aa7cSTomi Valkeinen 649960aa7cSTomi Valkeinen mutex_lock(&output_lock); 659960aa7cSTomi Valkeinen 669960aa7cSTomi Valkeinen if (!out->dst) { 6739637e10STomi Valkeinen dev_err(out->dev, 6839637e10STomi Valkeinen "output doesn't have a device connected to it\n"); 699960aa7cSTomi Valkeinen r = -EINVAL; 709960aa7cSTomi Valkeinen goto err; 719960aa7cSTomi Valkeinen } 729960aa7cSTomi Valkeinen 739960aa7cSTomi Valkeinen if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { 7439637e10STomi Valkeinen dev_err(out->dev, 7539637e10STomi Valkeinen "device %s is not disabled, cannot unset device\n", 769960aa7cSTomi Valkeinen out->dst->name); 779960aa7cSTomi Valkeinen r = -EINVAL; 789960aa7cSTomi Valkeinen goto err; 799960aa7cSTomi Valkeinen } 809960aa7cSTomi Valkeinen 819960aa7cSTomi Valkeinen mutex_unlock(&output_lock); 829960aa7cSTomi Valkeinen 839960aa7cSTomi Valkeinen return 0; 849960aa7cSTomi Valkeinen err: 859960aa7cSTomi Valkeinen mutex_unlock(&output_lock); 869960aa7cSTomi Valkeinen 879960aa7cSTomi Valkeinen return r; 889960aa7cSTomi Valkeinen } 899960aa7cSTomi Valkeinen EXPORT_SYMBOL(omapdss_output_unset_device); 909960aa7cSTomi Valkeinen 91845417b3SLaurent Pinchart int dss_install_mgr_ops(struct dss_device *dss, 92845417b3SLaurent Pinchart const struct dss_mgr_ops *mgr_ops, 9364cb8179SLaurent Pinchart struct omap_drm_private *priv) 949960aa7cSTomi Valkeinen { 95845417b3SLaurent Pinchart if (dss->mgr_ops) 969960aa7cSTomi Valkeinen return -EBUSY; 979960aa7cSTomi Valkeinen 98845417b3SLaurent Pinchart dss->mgr_ops = mgr_ops; 99845417b3SLaurent Pinchart dss->mgr_ops_priv = priv; 1009960aa7cSTomi Valkeinen 1019960aa7cSTomi Valkeinen return 0; 1029960aa7cSTomi Valkeinen } 1039960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_install_mgr_ops); 1049960aa7cSTomi Valkeinen 105845417b3SLaurent Pinchart void dss_uninstall_mgr_ops(struct dss_device *dss) 1069960aa7cSTomi Valkeinen { 107845417b3SLaurent Pinchart dss->mgr_ops = NULL; 108845417b3SLaurent Pinchart dss->mgr_ops_priv = NULL; 1099960aa7cSTomi Valkeinen } 1109960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_uninstall_mgr_ops); 1119960aa7cSTomi Valkeinen 112*a48bc6acSLaurent Pinchart int dss_mgr_connect(struct omap_dss_device *dssdev) 1139960aa7cSTomi Valkeinen { 114845417b3SLaurent Pinchart return dssdev->dss->mgr_ops->connect(dssdev->dss->mgr_ops_priv, 115*a48bc6acSLaurent Pinchart dssdev->dispc_channel, dssdev); 1169960aa7cSTomi Valkeinen } 1179960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_connect); 1189960aa7cSTomi Valkeinen 119*a48bc6acSLaurent Pinchart void dss_mgr_disconnect(struct omap_dss_device *dssdev) 1209960aa7cSTomi Valkeinen { 121845417b3SLaurent Pinchart dssdev->dss->mgr_ops->disconnect(dssdev->dss->mgr_ops_priv, 122*a48bc6acSLaurent Pinchart dssdev->dispc_channel, dssdev); 1239960aa7cSTomi Valkeinen } 1249960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_disconnect); 1259960aa7cSTomi Valkeinen 12628d79f3eSLaurent Pinchart void dss_mgr_set_timings(struct omap_dss_device *dssdev, 12728d79f3eSLaurent Pinchart const struct videomode *vm) 1289960aa7cSTomi Valkeinen { 129845417b3SLaurent Pinchart dssdev->dss->mgr_ops->set_timings(dssdev->dss->mgr_ops_priv, 130845417b3SLaurent Pinchart dssdev->dispc_channel, vm); 1319960aa7cSTomi Valkeinen } 1329960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_set_timings); 1339960aa7cSTomi Valkeinen 13428d79f3eSLaurent Pinchart void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev, 1359960aa7cSTomi Valkeinen const struct dss_lcd_mgr_config *config) 1369960aa7cSTomi Valkeinen { 137845417b3SLaurent Pinchart dssdev->dss->mgr_ops->set_lcd_config(dssdev->dss->mgr_ops_priv, 13864cb8179SLaurent Pinchart dssdev->dispc_channel, config); 1399960aa7cSTomi Valkeinen } 1409960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_set_lcd_config); 1419960aa7cSTomi Valkeinen 14228d79f3eSLaurent Pinchart int dss_mgr_enable(struct omap_dss_device *dssdev) 1439960aa7cSTomi Valkeinen { 144845417b3SLaurent Pinchart return dssdev->dss->mgr_ops->enable(dssdev->dss->mgr_ops_priv, 145845417b3SLaurent Pinchart dssdev->dispc_channel); 1469960aa7cSTomi Valkeinen } 1479960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_enable); 1489960aa7cSTomi Valkeinen 14928d79f3eSLaurent Pinchart void dss_mgr_disable(struct omap_dss_device *dssdev) 1509960aa7cSTomi Valkeinen { 151845417b3SLaurent Pinchart dssdev->dss->mgr_ops->disable(dssdev->dss->mgr_ops_priv, 152845417b3SLaurent Pinchart dssdev->dispc_channel); 1539960aa7cSTomi Valkeinen } 1549960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_disable); 1559960aa7cSTomi Valkeinen 15628d79f3eSLaurent Pinchart void dss_mgr_start_update(struct omap_dss_device *dssdev) 1579960aa7cSTomi Valkeinen { 158845417b3SLaurent Pinchart dssdev->dss->mgr_ops->start_update(dssdev->dss->mgr_ops_priv, 159845417b3SLaurent Pinchart dssdev->dispc_channel); 1609960aa7cSTomi Valkeinen } 1619960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_start_update); 1629960aa7cSTomi Valkeinen 16328d79f3eSLaurent Pinchart int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev, 1649960aa7cSTomi Valkeinen void (*handler)(void *), void *data) 1659960aa7cSTomi Valkeinen { 166845417b3SLaurent Pinchart struct dss_device *dss = dssdev->dss; 167845417b3SLaurent Pinchart 168845417b3SLaurent Pinchart return dss->mgr_ops->register_framedone_handler(dss->mgr_ops_priv, 16964cb8179SLaurent Pinchart dssdev->dispc_channel, 17028d79f3eSLaurent Pinchart handler, data); 1719960aa7cSTomi Valkeinen } 1729960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_register_framedone_handler); 1739960aa7cSTomi Valkeinen 17428d79f3eSLaurent Pinchart void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev, 1759960aa7cSTomi Valkeinen void (*handler)(void *), void *data) 1769960aa7cSTomi Valkeinen { 177845417b3SLaurent Pinchart struct dss_device *dss = dssdev->dss; 178845417b3SLaurent Pinchart 179845417b3SLaurent Pinchart dss->mgr_ops->unregister_framedone_handler(dss->mgr_ops_priv, 18064cb8179SLaurent Pinchart dssdev->dispc_channel, 18128d79f3eSLaurent Pinchart handler, data); 1829960aa7cSTomi Valkeinen } 1839960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler); 184