162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2009 Nokia Corporation
462306a36Sopenharmony_ci * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Some code and ideas taken from drivers/video/omap/ driver
762306a36Sopenharmony_ci * by Imre Deak.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define DSS_SUBSYS_NAME "OVERLAY"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/err.h>
1462306a36Sopenharmony_ci#include <linux/sysfs.h>
1562306a36Sopenharmony_ci#include <linux/kobject.h>
1662306a36Sopenharmony_ci#include <linux/kstrtox.h>
1762306a36Sopenharmony_ci#include <linux/platform_device.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <video/omapfb_dss.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include "dss.h"
2262306a36Sopenharmony_ci#include "dss_features.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	return sysfs_emit(buf, "%s\n", ovl->name);
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	return sysfs_emit(buf, "%s\n",
3262306a36Sopenharmony_ci			ovl->manager ? ovl->manager->name : "<none>");
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
3662306a36Sopenharmony_ci		size_t size)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	int i, r;
3962306a36Sopenharmony_ci	struct omap_overlay_manager *mgr = NULL;
4062306a36Sopenharmony_ci	struct omap_overlay_manager *old_mgr;
4162306a36Sopenharmony_ci	int len = size;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (buf[size-1] == '\n')
4462306a36Sopenharmony_ci		--len;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	if (len > 0) {
4762306a36Sopenharmony_ci		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
4862306a36Sopenharmony_ci			mgr = omap_dss_get_overlay_manager(i);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci			if (sysfs_streq(buf, mgr->name))
5162306a36Sopenharmony_ci				break;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci			mgr = NULL;
5462306a36Sopenharmony_ci		}
5562306a36Sopenharmony_ci	}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	if (len > 0 && mgr == NULL)
5862306a36Sopenharmony_ci		return -EINVAL;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	if (mgr)
6162306a36Sopenharmony_ci		DSSDBG("manager %s found\n", mgr->name);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	if (mgr == ovl->manager)
6462306a36Sopenharmony_ci		return size;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	old_mgr = ovl->manager;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	r = dispc_runtime_get();
6962306a36Sopenharmony_ci	if (r)
7062306a36Sopenharmony_ci		return r;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	/* detach old manager */
7362306a36Sopenharmony_ci	if (old_mgr) {
7462306a36Sopenharmony_ci		r = ovl->unset_manager(ovl);
7562306a36Sopenharmony_ci		if (r) {
7662306a36Sopenharmony_ci			DSSERR("detach failed\n");
7762306a36Sopenharmony_ci			goto err;
7862306a36Sopenharmony_ci		}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci		r = old_mgr->apply(old_mgr);
8162306a36Sopenharmony_ci		if (r)
8262306a36Sopenharmony_ci			goto err;
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	if (mgr) {
8662306a36Sopenharmony_ci		r = ovl->set_manager(ovl, mgr);
8762306a36Sopenharmony_ci		if (r) {
8862306a36Sopenharmony_ci			DSSERR("Failed to attach overlay\n");
8962306a36Sopenharmony_ci			goto err;
9062306a36Sopenharmony_ci		}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci		r = mgr->apply(mgr);
9362306a36Sopenharmony_ci		if (r)
9462306a36Sopenharmony_ci			goto err;
9562306a36Sopenharmony_ci	}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	dispc_runtime_put();
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	return size;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cierr:
10262306a36Sopenharmony_ci	dispc_runtime_put();
10362306a36Sopenharmony_ci	return r;
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	struct omap_overlay_info info;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	return sysfs_emit(buf, "%d,%d\n",
11362306a36Sopenharmony_ci			info.width, info.height);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	struct omap_overlay_info info;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", info.screen_width);
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	struct omap_overlay_info info;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	return sysfs_emit(buf, "%d,%d\n",
13262306a36Sopenharmony_ci			info.pos_x, info.pos_y);
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic ssize_t overlay_position_store(struct omap_overlay *ovl,
13662306a36Sopenharmony_ci		const char *buf, size_t size)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	int r;
13962306a36Sopenharmony_ci	char *last;
14062306a36Sopenharmony_ci	struct omap_overlay_info info;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	info.pos_x = simple_strtoul(buf, &last, 10);
14562306a36Sopenharmony_ci	++last;
14662306a36Sopenharmony_ci	if (last - buf >= size)
14762306a36Sopenharmony_ci		return -EINVAL;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	info.pos_y = simple_strtoul(last, &last, 10);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	r = ovl->set_overlay_info(ovl, &info);
15262306a36Sopenharmony_ci	if (r)
15362306a36Sopenharmony_ci		return r;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	if (ovl->manager) {
15662306a36Sopenharmony_ci		r = ovl->manager->apply(ovl->manager);
15762306a36Sopenharmony_ci		if (r)
15862306a36Sopenharmony_ci			return r;
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	return size;
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	struct omap_overlay_info info;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	return sysfs_emit(buf, "%d,%d\n",
17162306a36Sopenharmony_ci			info.out_width, info.out_height);
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic ssize_t overlay_output_size_store(struct omap_overlay *ovl,
17562306a36Sopenharmony_ci		const char *buf, size_t size)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	int r;
17862306a36Sopenharmony_ci	char *last;
17962306a36Sopenharmony_ci	struct omap_overlay_info info;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	info.out_width = simple_strtoul(buf, &last, 10);
18462306a36Sopenharmony_ci	++last;
18562306a36Sopenharmony_ci	if (last - buf >= size)
18662306a36Sopenharmony_ci		return -EINVAL;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	info.out_height = simple_strtoul(last, &last, 10);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	r = ovl->set_overlay_info(ovl, &info);
19162306a36Sopenharmony_ci	if (r)
19262306a36Sopenharmony_ci		return r;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	if (ovl->manager) {
19562306a36Sopenharmony_ci		r = ovl->manager->apply(ovl->manager);
19662306a36Sopenharmony_ci		if (r)
19762306a36Sopenharmony_ci			return r;
19862306a36Sopenharmony_ci	}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	return size;
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_cistatic ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", ovl->is_enabled(ovl));
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistatic ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
20962306a36Sopenharmony_ci		size_t size)
21062306a36Sopenharmony_ci{
21162306a36Sopenharmony_ci	int r;
21262306a36Sopenharmony_ci	bool enable;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	r = kstrtobool(buf, &enable);
21562306a36Sopenharmony_ci	if (r)
21662306a36Sopenharmony_ci		return r;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	if (enable)
21962306a36Sopenharmony_ci		r = ovl->enable(ovl);
22062306a36Sopenharmony_ci	else
22162306a36Sopenharmony_ci		r = ovl->disable(ovl);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	if (r)
22462306a36Sopenharmony_ci		return r;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	return size;
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	struct omap_overlay_info info;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n",
23662306a36Sopenharmony_ci			info.global_alpha);
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
24062306a36Sopenharmony_ci		const char *buf, size_t size)
24162306a36Sopenharmony_ci{
24262306a36Sopenharmony_ci	int r;
24362306a36Sopenharmony_ci	u8 alpha;
24462306a36Sopenharmony_ci	struct omap_overlay_info info;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
24762306a36Sopenharmony_ci		return -ENODEV;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	r = kstrtou8(buf, 0, &alpha);
25062306a36Sopenharmony_ci	if (r)
25162306a36Sopenharmony_ci		return r;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	info.global_alpha = alpha;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	r = ovl->set_overlay_info(ovl, &info);
25862306a36Sopenharmony_ci	if (r)
25962306a36Sopenharmony_ci		return r;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	if (ovl->manager) {
26262306a36Sopenharmony_ci		r = ovl->manager->apply(ovl->manager);
26362306a36Sopenharmony_ci		if (r)
26462306a36Sopenharmony_ci			return r;
26562306a36Sopenharmony_ci	}
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	return size;
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistatic ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
27162306a36Sopenharmony_ci		char *buf)
27262306a36Sopenharmony_ci{
27362306a36Sopenharmony_ci	struct omap_overlay_info info;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n",
27862306a36Sopenharmony_ci			info.pre_mult_alpha);
27962306a36Sopenharmony_ci}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_cistatic ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
28262306a36Sopenharmony_ci		const char *buf, size_t size)
28362306a36Sopenharmony_ci{
28462306a36Sopenharmony_ci	int r;
28562306a36Sopenharmony_ci	u8 alpha;
28662306a36Sopenharmony_ci	struct omap_overlay_info info;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
28962306a36Sopenharmony_ci		return -ENODEV;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	r = kstrtou8(buf, 0, &alpha);
29262306a36Sopenharmony_ci	if (r)
29362306a36Sopenharmony_ci		return r;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	info.pre_mult_alpha = alpha;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	r = ovl->set_overlay_info(ovl, &info);
30062306a36Sopenharmony_ci	if (r)
30162306a36Sopenharmony_ci		return r;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	if (ovl->manager) {
30462306a36Sopenharmony_ci		r = ovl->manager->apply(ovl->manager);
30562306a36Sopenharmony_ci		if (r)
30662306a36Sopenharmony_ci			return r;
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	return size;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci	struct omap_overlay_info info;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", info.zorder);
31962306a36Sopenharmony_ci}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_cistatic ssize_t overlay_zorder_store(struct omap_overlay *ovl,
32262306a36Sopenharmony_ci		const char *buf, size_t size)
32362306a36Sopenharmony_ci{
32462306a36Sopenharmony_ci	int r;
32562306a36Sopenharmony_ci	u8 zorder;
32662306a36Sopenharmony_ci	struct omap_overlay_info info;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
32962306a36Sopenharmony_ci		return -ENODEV;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	r = kstrtou8(buf, 0, &zorder);
33262306a36Sopenharmony_ci	if (r)
33362306a36Sopenharmony_ci		return r;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	ovl->get_overlay_info(ovl, &info);
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	info.zorder = zorder;
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	r = ovl->set_overlay_info(ovl, &info);
34062306a36Sopenharmony_ci	if (r)
34162306a36Sopenharmony_ci		return r;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	if (ovl->manager) {
34462306a36Sopenharmony_ci		r = ovl->manager->apply(ovl->manager);
34562306a36Sopenharmony_ci		if (r)
34662306a36Sopenharmony_ci			return r;
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	return size;
35062306a36Sopenharmony_ci}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_cistruct overlay_attribute {
35362306a36Sopenharmony_ci	struct attribute attr;
35462306a36Sopenharmony_ci	ssize_t (*show)(struct omap_overlay *, char *);
35562306a36Sopenharmony_ci	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
35662306a36Sopenharmony_ci};
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci#define OVERLAY_ATTR(_name, _mode, _show, _store) \
35962306a36Sopenharmony_ci	struct overlay_attribute overlay_attr_##_name = \
36062306a36Sopenharmony_ci	__ATTR(_name, _mode, _show, _store)
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cistatic OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
36362306a36Sopenharmony_cistatic OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
36462306a36Sopenharmony_ci		overlay_manager_show, overlay_manager_store);
36562306a36Sopenharmony_cistatic OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
36662306a36Sopenharmony_cistatic OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
36762306a36Sopenharmony_cistatic OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
36862306a36Sopenharmony_ci		overlay_position_show, overlay_position_store);
36962306a36Sopenharmony_cistatic OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
37062306a36Sopenharmony_ci		overlay_output_size_show, overlay_output_size_store);
37162306a36Sopenharmony_cistatic OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
37262306a36Sopenharmony_ci		overlay_enabled_show, overlay_enabled_store);
37362306a36Sopenharmony_cistatic OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
37462306a36Sopenharmony_ci		overlay_global_alpha_show, overlay_global_alpha_store);
37562306a36Sopenharmony_cistatic OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
37662306a36Sopenharmony_ci		overlay_pre_mult_alpha_show,
37762306a36Sopenharmony_ci		overlay_pre_mult_alpha_store);
37862306a36Sopenharmony_cistatic OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
37962306a36Sopenharmony_ci		overlay_zorder_show, overlay_zorder_store);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistatic struct attribute *overlay_sysfs_attrs[] = {
38262306a36Sopenharmony_ci	&overlay_attr_name.attr,
38362306a36Sopenharmony_ci	&overlay_attr_manager.attr,
38462306a36Sopenharmony_ci	&overlay_attr_input_size.attr,
38562306a36Sopenharmony_ci	&overlay_attr_screen_width.attr,
38662306a36Sopenharmony_ci	&overlay_attr_position.attr,
38762306a36Sopenharmony_ci	&overlay_attr_output_size.attr,
38862306a36Sopenharmony_ci	&overlay_attr_enabled.attr,
38962306a36Sopenharmony_ci	&overlay_attr_global_alpha.attr,
39062306a36Sopenharmony_ci	&overlay_attr_pre_mult_alpha.attr,
39162306a36Sopenharmony_ci	&overlay_attr_zorder.attr,
39262306a36Sopenharmony_ci	NULL
39362306a36Sopenharmony_ci};
39462306a36Sopenharmony_ciATTRIBUTE_GROUPS(overlay_sysfs);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cistatic ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
39762306a36Sopenharmony_ci		char *buf)
39862306a36Sopenharmony_ci{
39962306a36Sopenharmony_ci	struct omap_overlay *overlay;
40062306a36Sopenharmony_ci	struct overlay_attribute *overlay_attr;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	overlay = container_of(kobj, struct omap_overlay, kobj);
40362306a36Sopenharmony_ci	overlay_attr = container_of(attr, struct overlay_attribute, attr);
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	if (!overlay_attr->show)
40662306a36Sopenharmony_ci		return -ENOENT;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	return overlay_attr->show(overlay, buf);
40962306a36Sopenharmony_ci}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_cistatic ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
41262306a36Sopenharmony_ci		const char *buf, size_t size)
41362306a36Sopenharmony_ci{
41462306a36Sopenharmony_ci	struct omap_overlay *overlay;
41562306a36Sopenharmony_ci	struct overlay_attribute *overlay_attr;
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	overlay = container_of(kobj, struct omap_overlay, kobj);
41862306a36Sopenharmony_ci	overlay_attr = container_of(attr, struct overlay_attribute, attr);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	if (!overlay_attr->store)
42162306a36Sopenharmony_ci		return -ENOENT;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	return overlay_attr->store(overlay, buf, size);
42462306a36Sopenharmony_ci}
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistatic const struct sysfs_ops overlay_sysfs_ops = {
42762306a36Sopenharmony_ci	.show = overlay_attr_show,
42862306a36Sopenharmony_ci	.store = overlay_attr_store,
42962306a36Sopenharmony_ci};
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cistatic struct kobj_type overlay_ktype = {
43262306a36Sopenharmony_ci	.sysfs_ops = &overlay_sysfs_ops,
43362306a36Sopenharmony_ci	.default_groups = overlay_sysfs_groups,
43462306a36Sopenharmony_ci};
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ciint dss_overlay_kobj_init(struct omap_overlay *ovl,
43762306a36Sopenharmony_ci		struct platform_device *pdev)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
44062306a36Sopenharmony_ci			&pdev->dev.kobj, "overlay%d", ovl->id);
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_civoid dss_overlay_kobj_uninit(struct omap_overlay *ovl)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	kobject_del(&ovl->kobj);
44662306a36Sopenharmony_ci	kobject_put(&ovl->kobj);
44762306a36Sopenharmony_ci}
448