diff options
Diffstat (limited to 'drivers/video/omap2/dss/overlay.c')
| -rw-r--r-- | drivers/video/omap2/dss/overlay.c | 492 | 
1 files changed, 7 insertions, 485 deletions
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 952c6fad9a8..45f4994bc6b 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -26,13 +26,11 @@  #include <linux/module.h>  #include <linux/err.h>  #include <linux/sysfs.h> -#include <linux/kobject.h>  #include <linux/platform_device.h>  #include <linux/delay.h>  #include <linux/slab.h>  #include <video/omapdss.h> -#include <plat/cpu.h>  #include "dss.h"  #include "dss_features.h" @@ -40,417 +38,13 @@  static int num_overlays;  static struct omap_overlay *overlays; -static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) +static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)  { -	return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); +	return ovl->manager ? +		(ovl->manager->output ? ovl->manager->output->device : NULL) : +		NULL;  } -static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf) -{ -	return snprintf(buf, PAGE_SIZE, "%s\n", -			ovl->manager ? ovl->manager->name : "<none>"); -} - -static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, -		size_t size) -{ -	int i, r; -	struct omap_overlay_manager *mgr = NULL; -	struct omap_overlay_manager *old_mgr; -	int len = size; - -	if (buf[size-1] == '\n') -		--len; - -	if (len > 0) { -		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { -			mgr = omap_dss_get_overlay_manager(i); - -			if (sysfs_streq(buf, mgr->name)) -				break; - -			mgr = NULL; -		} -	} - -	if (len > 0 && mgr == NULL) -		return -EINVAL; - -	if (mgr) -		DSSDBG("manager %s found\n", mgr->name); - -	if (mgr == ovl->manager) -		return size; - -	old_mgr = ovl->manager; - -	r = dispc_runtime_get(); -	if (r) -		return r; - -	/* detach old manager */ -	if (old_mgr) { -		r = ovl->unset_manager(ovl); -		if (r) { -			DSSERR("detach failed\n"); -			goto err; -		} - -		r = old_mgr->apply(old_mgr); -		if (r) -			goto err; -	} - -	if (mgr) { -		r = ovl->set_manager(ovl, mgr); -		if (r) { -			DSSERR("Failed to attach overlay\n"); -			goto err; -		} - -		r = mgr->apply(mgr); -		if (r) -			goto err; -	} - -	dispc_runtime_put(); - -	return size; - -err: -	dispc_runtime_put(); -	return r; -} - -static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d,%d\n", -			info.width, info.height); -} - -static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width); -} - -static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d,%d\n", -			info.pos_x, info.pos_y); -} - -static ssize_t overlay_position_store(struct omap_overlay *ovl, -		const char *buf, size_t size) -{ -	int r; -	char *last; -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	info.pos_x = simple_strtoul(buf, &last, 10); -	++last; -	if (last - buf >= size) -		return -EINVAL; - -	info.pos_y = simple_strtoul(last, &last, 10); - -	r = ovl->set_overlay_info(ovl, &info); -	if (r) -		return r; - -	if (ovl->manager) { -		r = ovl->manager->apply(ovl->manager); -		if (r) -			return r; -	} - -	return size; -} - -static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d,%d\n", -			info.out_width, info.out_height); -} - -static ssize_t overlay_output_size_store(struct omap_overlay *ovl, -		const char *buf, size_t size) -{ -	int r; -	char *last; -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	info.out_width = simple_strtoul(buf, &last, 10); -	++last; -	if (last - buf >= size) -		return -EINVAL; - -	info.out_height = simple_strtoul(last, &last, 10); - -	r = ovl->set_overlay_info(ovl, &info); -	if (r) -		return r; - -	if (ovl->manager) { -		r = ovl->manager->apply(ovl->manager); -		if (r) -			return r; -	} - -	return size; -} - -static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) -{ -	return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl)); -} - -static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, -		size_t size) -{ -	int r; -	bool enable; - -	r = strtobool(buf, &enable); -	if (r) -		return r; - -	if (enable) -		r = ovl->enable(ovl); -	else -		r = ovl->disable(ovl); - -	if (r) -		return r; - -	return size; -} - -static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d\n", -			info.global_alpha); -} - -static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, -		const char *buf, size_t size) -{ -	int r; -	u8 alpha; -	struct omap_overlay_info info; - -	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) -		return -ENODEV; - -	r = kstrtou8(buf, 0, &alpha); -	if (r) -		return r; - -	ovl->get_overlay_info(ovl, &info); - -	info.global_alpha = alpha; - -	r = ovl->set_overlay_info(ovl, &info); -	if (r) -		return r; - -	if (ovl->manager) { -		r = ovl->manager->apply(ovl->manager); -		if (r) -			return r; -	} - -	return size; -} - -static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl, -		char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d\n", -			info.pre_mult_alpha); -} - -static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, -		const char *buf, size_t size) -{ -	int r; -	u8 alpha; -	struct omap_overlay_info info; - -	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) -		return -ENODEV; - -	r = kstrtou8(buf, 0, &alpha); -	if (r) -		return r; - -	ovl->get_overlay_info(ovl, &info); - -	info.pre_mult_alpha = alpha; - -	r = ovl->set_overlay_info(ovl, &info); -	if (r) -		return r; - -	if (ovl->manager) { -		r = ovl->manager->apply(ovl->manager); -		if (r) -			return r; -	} - -	return size; -} - -static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) -{ -	struct omap_overlay_info info; - -	ovl->get_overlay_info(ovl, &info); - -	return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder); -} - -static ssize_t overlay_zorder_store(struct omap_overlay *ovl, -		const char *buf, size_t size) -{ -	int r; -	u8 zorder; -	struct omap_overlay_info info; - -	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) -		return -ENODEV; - -	r = kstrtou8(buf, 0, &zorder); -	if (r) -		return r; - -	ovl->get_overlay_info(ovl, &info); - -	info.zorder = zorder; - -	r = ovl->set_overlay_info(ovl, &info); -	if (r) -		return r; - -	if (ovl->manager) { -		r = ovl->manager->apply(ovl->manager); -		if (r) -			return r; -	} - -	return size; -} - -struct overlay_attribute { -	struct attribute attr; -	ssize_t (*show)(struct omap_overlay *, char *); -	ssize_t	(*store)(struct omap_overlay *, const char *, size_t); -}; - -#define OVERLAY_ATTR(_name, _mode, _show, _store) \ -	struct overlay_attribute overlay_attr_##_name = \ -	__ATTR(_name, _mode, _show, _store) - -static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); -static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, -		overlay_manager_show, overlay_manager_store); -static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); -static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); -static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, -		overlay_position_show, overlay_position_store); -static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, -		overlay_output_size_show, overlay_output_size_store); -static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, -		overlay_enabled_show, overlay_enabled_store); -static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, -		overlay_global_alpha_show, overlay_global_alpha_store); -static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, -		overlay_pre_mult_alpha_show, -		overlay_pre_mult_alpha_store); -static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, -		overlay_zorder_show, overlay_zorder_store); - -static struct attribute *overlay_sysfs_attrs[] = { -	&overlay_attr_name.attr, -	&overlay_attr_manager.attr, -	&overlay_attr_input_size.attr, -	&overlay_attr_screen_width.attr, -	&overlay_attr_position.attr, -	&overlay_attr_output_size.attr, -	&overlay_attr_enabled.attr, -	&overlay_attr_global_alpha.attr, -	&overlay_attr_pre_mult_alpha.attr, -	&overlay_attr_zorder.attr, -	NULL -}; - -static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr, -		char *buf) -{ -	struct omap_overlay *overlay; -	struct overlay_attribute *overlay_attr; - -	overlay = container_of(kobj, struct omap_overlay, kobj); -	overlay_attr = container_of(attr, struct overlay_attribute, attr); - -	if (!overlay_attr->show) -		return -ENOENT; - -	return overlay_attr->show(overlay, buf); -} - -static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, -		const char *buf, size_t size) -{ -	struct omap_overlay *overlay; -	struct overlay_attribute *overlay_attr; - -	overlay = container_of(kobj, struct omap_overlay, kobj); -	overlay_attr = container_of(attr, struct overlay_attribute, attr); - -	if (!overlay_attr->store) -		return -ENOENT; - -	return overlay_attr->store(overlay, buf, size); -} - -static const struct sysfs_ops overlay_sysfs_ops = { -	.show = overlay_attr_show, -	.store = overlay_attr_store, -}; - -static struct kobj_type overlay_ktype = { -	.sysfs_ops = &overlay_sysfs_ops, -	.default_attrs = overlay_sysfs_attrs, -}; -  int omap_dss_get_num_overlays(void)  {  	return num_overlays; @@ -507,97 +101,25 @@ void dss_init_overlays(struct platform_device *pdev)  		ovl->set_overlay_info = &dss_ovl_set_info;  		ovl->get_overlay_info = &dss_ovl_get_info;  		ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; +		ovl->get_device = &dss_ovl_get_device;  		ovl->caps = dss_feat_get_overlay_caps(ovl->id);  		ovl->supported_modes =  			dss_feat_get_supported_color_modes(ovl->id); -		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, -				&pdev->dev.kobj, "overlay%d", i); - +		r = dss_overlay_kobj_init(ovl, pdev);  		if (r)  			DSSERR("failed to create sysfs file\n");  	}  } -/* connect overlays to the new device, if not already connected. if force - * selected, connect always. */ -void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) -{ -	int i; -	struct omap_overlay_manager *lcd_mgr; -	struct omap_overlay_manager *tv_mgr; -	struct omap_overlay_manager *lcd2_mgr = NULL; -	struct omap_overlay_manager *lcd3_mgr = NULL; -	struct omap_overlay_manager *mgr = NULL; - -	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD); -	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT); -	if (dss_has_feature(FEAT_MGR_LCD3)) -		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3); -	if (dss_has_feature(FEAT_MGR_LCD2)) -		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2); - -	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) { -		if (!lcd3_mgr->device || force) { -			if (lcd3_mgr->device) -				lcd3_mgr->unset_device(lcd3_mgr); -			lcd3_mgr->set_device(lcd3_mgr, dssdev); -			mgr = lcd3_mgr; -		} -	} else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { -		if (!lcd2_mgr->device || force) { -			if (lcd2_mgr->device) -				lcd2_mgr->unset_device(lcd2_mgr); -			lcd2_mgr->set_device(lcd2_mgr, dssdev); -			mgr = lcd2_mgr; -		} -	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC -			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { -		if (!lcd_mgr->device || force) { -			if (lcd_mgr->device) -				lcd_mgr->unset_device(lcd_mgr); -			lcd_mgr->set_device(lcd_mgr, dssdev); -			mgr = lcd_mgr; -		} -	} - -	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC -			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { -		if (!tv_mgr->device || force) { -			if (tv_mgr->device) -				tv_mgr->unset_device(tv_mgr); -			tv_mgr->set_device(tv_mgr, dssdev); -			mgr = tv_mgr; -		} -	} - -	if (mgr) { -		dispc_runtime_get(); - -		for (i = 0; i < dss_feat_get_num_ovls(); i++) { -			struct omap_overlay *ovl; -			ovl = omap_dss_get_overlay(i); -			if (!ovl->manager || force) { -				if (ovl->manager) -					ovl->unset_manager(ovl); -				ovl->set_manager(ovl, mgr); -			} -		} - -		dispc_runtime_put(); -	} -} -  void dss_uninit_overlays(struct platform_device *pdev)  {  	int i;  	for (i = 0; i < num_overlays; ++i) {  		struct omap_overlay *ovl = &overlays[i]; - -		kobject_del(&ovl->kobj); -		kobject_put(&ovl->kobj); +		dss_overlay_kobj_uninit(ovl);  	}  	kfree(overlays);  |