diff options
Diffstat (limited to 'drivers/video/omap2/dss/overlay.c')
-rw-r--r-- | drivers/video/omap2/dss/overlay.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 11d21e3347a..ab8e40e4875 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -311,6 +311,42 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, return size; } +static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->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 *); @@ -337,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, 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, @@ -348,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = { &overlay_attr_enabled.attr, &overlay_attr_global_alpha.attr, &overlay_attr_pre_mult_alpha.attr, + &overlay_attr_zorder.attr, NULL }; @@ -397,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) struct omap_overlay_info *info; u16 outw, outh; u16 dw, dh; + int i; if (!dssdev) return 0; @@ -452,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) return -EINVAL; } + if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) { + if (info->zorder < 0 || info->zorder > 3) { + DSSERR("zorder out of range: %d\n", + info->zorder); + return -EINVAL; + } + /* + * Check that zorder doesn't match with zorder of any other + * overlay which is enabled and is also connected to the same + * manager + */ + for (i = 0; i < omap_dss_get_num_overlays(); i++) { + struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i); + + if (tmp_ovl->id != ovl->id && + tmp_ovl->manager == ovl->manager && + tmp_ovl->info.enabled == true && + tmp_ovl->info.zorder == info->zorder) { + DSSERR("%s and %s have same zorder: %d\n", + ovl->name, tmp_ovl->name, info->zorder); + return -EINVAL; + } + } + } + return 0; } @@ -604,21 +669,28 @@ void dss_init_overlays(struct platform_device *pdev) ovl->name = "gfx"; ovl->id = OMAP_DSS_GFX; ovl->info.global_alpha = 255; + ovl->info.zorder = 0; break; case 1: ovl->name = "vid1"; ovl->id = OMAP_DSS_VIDEO1; ovl->info.global_alpha = 255; + ovl->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0; break; case 2: ovl->name = "vid2"; ovl->id = OMAP_DSS_VIDEO2; ovl->info.global_alpha = 255; + ovl->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0; break; case 3: ovl->name = "vid3"; ovl->id = OMAP_DSS_VIDEO3; ovl->info.global_alpha = 255; + ovl->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0; break; } |