diff options
Diffstat (limited to 'drivers/video/fbdev/omap2/dss/output.c')
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/output.c | 254 | 
1 files changed, 254 insertions, 0 deletions
diff --git a/drivers/video/fbdev/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c new file mode 100644 index 00000000000..2ab3afa615e --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/output.c @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2012 Texas Instruments Ltd + * Author: Archit Taneja <archit@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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <video/omapdss.h> + +#include "dss.h" + +static LIST_HEAD(output_list); +static DEFINE_MUTEX(output_lock); + +int omapdss_output_set_device(struct omap_dss_device *out, +		struct omap_dss_device *dssdev) +{ +	int r; + +	mutex_lock(&output_lock); + +	if (out->dst) { +		DSSERR("output already has device %s connected to it\n", +			out->dst->name); +		r = -EINVAL; +		goto err; +	} + +	if (out->output_type != dssdev->type) { +		DSSERR("output type and display type don't match\n"); +		r = -EINVAL; +		goto err; +	} + +	out->dst = dssdev; +	dssdev->src = out; + +	mutex_unlock(&output_lock); + +	return 0; +err: +	mutex_unlock(&output_lock); + +	return r; +} +EXPORT_SYMBOL(omapdss_output_set_device); + +int omapdss_output_unset_device(struct omap_dss_device *out) +{ +	int r; + +	mutex_lock(&output_lock); + +	if (!out->dst) { +		DSSERR("output doesn't have a device connected to it\n"); +		r = -EINVAL; +		goto err; +	} + +	if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { +		DSSERR("device %s is not disabled, cannot unset device\n", +				out->dst->name); +		r = -EINVAL; +		goto err; +	} + +	out->dst->src = NULL; +	out->dst = NULL; + +	mutex_unlock(&output_lock); + +	return 0; +err: +	mutex_unlock(&output_lock); + +	return r; +} +EXPORT_SYMBOL(omapdss_output_unset_device); + +int omapdss_register_output(struct omap_dss_device *out) +{ +	list_add_tail(&out->list, &output_list); +	return 0; +} +EXPORT_SYMBOL(omapdss_register_output); + +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) +{ +	struct omap_dss_device *out; + +	list_for_each_entry(out, &output_list, list) { +		if (out->id == id) +			return out; +	} + +	return NULL; +} +EXPORT_SYMBOL(omap_dss_get_output); + +struct omap_dss_device *omap_dss_find_output(const char *name) +{ +	struct omap_dss_device *out; + +	list_for_each_entry(out, &output_list, list) { +		if (strcmp(out->name, name) == 0) +			return omap_dss_get_device(out); +	} + +	return NULL; +} +EXPORT_SYMBOL(omap_dss_find_output); + +struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node) +{ +	struct omap_dss_device *out; + +	list_for_each_entry(out, &output_list, list) { +		if (out->dev->of_node == node) +			return omap_dss_get_device(out); +	} + +	return NULL; +} +EXPORT_SYMBOL(omap_dss_find_output_by_node); + +struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) +{ +	while (dssdev->src) +		dssdev = dssdev->src; + +	if (dssdev->id != 0) +		return omap_dss_get_device(dssdev); + +	return NULL; +} +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; + +	mgr = out->manager; + +	omap_dss_put_device(out); + +	return mgr; +} +EXPORT_SYMBOL(omapdss_find_mgr_from_display); + +static const struct dss_mgr_ops *dss_mgr_ops; + +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) +{ +	if (dss_mgr_ops) +		return -EBUSY; + +	dss_mgr_ops = mgr_ops; + +	return 0; +} +EXPORT_SYMBOL(dss_install_mgr_ops); + +void dss_uninstall_mgr_ops(void) +{ +	dss_mgr_ops = NULL; +} +EXPORT_SYMBOL(dss_uninstall_mgr_ops); + +int dss_mgr_connect(struct omap_overlay_manager *mgr, +		struct omap_dss_device *dst) +{ +	return dss_mgr_ops->connect(mgr, dst); +} +EXPORT_SYMBOL(dss_mgr_connect); + +void dss_mgr_disconnect(struct omap_overlay_manager *mgr, +		struct omap_dss_device *dst) +{ +	dss_mgr_ops->disconnect(mgr, dst); +} +EXPORT_SYMBOL(dss_mgr_disconnect); + +void dss_mgr_set_timings(struct omap_overlay_manager *mgr, +		const struct omap_video_timings *timings) +{ +	dss_mgr_ops->set_timings(mgr, timings); +} +EXPORT_SYMBOL(dss_mgr_set_timings); + +void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, +		const struct dss_lcd_mgr_config *config) +{ +	dss_mgr_ops->set_lcd_config(mgr, config); +} +EXPORT_SYMBOL(dss_mgr_set_lcd_config); + +int dss_mgr_enable(struct omap_overlay_manager *mgr) +{ +	return dss_mgr_ops->enable(mgr); +} +EXPORT_SYMBOL(dss_mgr_enable); + +void dss_mgr_disable(struct omap_overlay_manager *mgr) +{ +	dss_mgr_ops->disable(mgr); +} +EXPORT_SYMBOL(dss_mgr_disable); + +void dss_mgr_start_update(struct omap_overlay_manager *mgr) +{ +	dss_mgr_ops->start_update(mgr); +} +EXPORT_SYMBOL(dss_mgr_start_update); + +int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr, +		void (*handler)(void *), void *data) +{ +	return dss_mgr_ops->register_framedone_handler(mgr, handler, data); +} +EXPORT_SYMBOL(dss_mgr_register_framedone_handler); + +void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, +		void (*handler)(void *), void *data) +{ +	dss_mgr_ops->unregister_framedone_handler(mgr, handler, data); +} +EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);  | 
