1caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f76ee892STomi Valkeinen /*
3f76ee892STomi Valkeinen  * Copyright (C) 2009 Nokia Corporation
4f76ee892STomi Valkeinen  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
5f76ee892STomi Valkeinen  *
6f76ee892STomi Valkeinen  * Some code and ideas taken from drivers/video/omap/ driver
7f76ee892STomi Valkeinen  * by Imre Deak.
8f76ee892STomi Valkeinen  */
9f76ee892STomi Valkeinen 
10f76ee892STomi Valkeinen #define DSS_SUBSYS_NAME "OVERLAY"
11f76ee892STomi Valkeinen 
12f76ee892STomi Valkeinen #include <linux/module.h>
13f76ee892STomi Valkeinen #include <linux/err.h>
14f76ee892STomi Valkeinen #include <linux/sysfs.h>
15f76ee892STomi Valkeinen #include <linux/kobject.h>
16*ee9fffdcSChristophe JAILLET #include <linux/kstrtox.h>
17f76ee892STomi Valkeinen #include <linux/platform_device.h>
18f76ee892STomi Valkeinen 
1962d9e44eSPeter Ujfalusi #include <video/omapfb_dss.h>
20f76ee892STomi Valkeinen 
21f76ee892STomi Valkeinen #include "dss.h"
22f76ee892STomi Valkeinen #include "dss_features.h"
23f76ee892STomi Valkeinen 
overlay_name_show(struct omap_overlay * ovl,char * buf)24f76ee892STomi Valkeinen static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
25f76ee892STomi Valkeinen {
26cc83ff24SQing Wang 	return sysfs_emit(buf, "%s\n", ovl->name);
27f76ee892STomi Valkeinen }
28f76ee892STomi Valkeinen 
overlay_manager_show(struct omap_overlay * ovl,char * buf)29f76ee892STomi Valkeinen static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
30f76ee892STomi Valkeinen {
31cc83ff24SQing Wang 	return sysfs_emit(buf, "%s\n",
32f76ee892STomi Valkeinen 			ovl->manager ? ovl->manager->name : "<none>");
33f76ee892STomi Valkeinen }
34f76ee892STomi Valkeinen 
overlay_manager_store(struct omap_overlay * ovl,const char * buf,size_t size)35f76ee892STomi Valkeinen static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
36f76ee892STomi Valkeinen 		size_t size)
37f76ee892STomi Valkeinen {
38f76ee892STomi Valkeinen 	int i, r;
39f76ee892STomi Valkeinen 	struct omap_overlay_manager *mgr = NULL;
40f76ee892STomi Valkeinen 	struct omap_overlay_manager *old_mgr;
41f76ee892STomi Valkeinen 	int len = size;
42f76ee892STomi Valkeinen 
43f76ee892STomi Valkeinen 	if (buf[size-1] == '\n')
44f76ee892STomi Valkeinen 		--len;
45f76ee892STomi Valkeinen 
46f76ee892STomi Valkeinen 	if (len > 0) {
47f76ee892STomi Valkeinen 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
48f76ee892STomi Valkeinen 			mgr = omap_dss_get_overlay_manager(i);
49f76ee892STomi Valkeinen 
50f76ee892STomi Valkeinen 			if (sysfs_streq(buf, mgr->name))
51f76ee892STomi Valkeinen 				break;
52f76ee892STomi Valkeinen 
53f76ee892STomi Valkeinen 			mgr = NULL;
54f76ee892STomi Valkeinen 		}
55f76ee892STomi Valkeinen 	}
56f76ee892STomi Valkeinen 
57f76ee892STomi Valkeinen 	if (len > 0 && mgr == NULL)
58f76ee892STomi Valkeinen 		return -EINVAL;
59f76ee892STomi Valkeinen 
60f76ee892STomi Valkeinen 	if (mgr)
61f76ee892STomi Valkeinen 		DSSDBG("manager %s found\n", mgr->name);
62f76ee892STomi Valkeinen 
63f76ee892STomi Valkeinen 	if (mgr == ovl->manager)
64f76ee892STomi Valkeinen 		return size;
65f76ee892STomi Valkeinen 
66f76ee892STomi Valkeinen 	old_mgr = ovl->manager;
67f76ee892STomi Valkeinen 
68f76ee892STomi Valkeinen 	r = dispc_runtime_get();
69f76ee892STomi Valkeinen 	if (r)
70f76ee892STomi Valkeinen 		return r;
71f76ee892STomi Valkeinen 
72f76ee892STomi Valkeinen 	/* detach old manager */
73f76ee892STomi Valkeinen 	if (old_mgr) {
74f76ee892STomi Valkeinen 		r = ovl->unset_manager(ovl);
75f76ee892STomi Valkeinen 		if (r) {
76f76ee892STomi Valkeinen 			DSSERR("detach failed\n");
77f76ee892STomi Valkeinen 			goto err;
78f76ee892STomi Valkeinen 		}
79f76ee892STomi Valkeinen 
80f76ee892STomi Valkeinen 		r = old_mgr->apply(old_mgr);
81f76ee892STomi Valkeinen 		if (r)
82f76ee892STomi Valkeinen 			goto err;
83f76ee892STomi Valkeinen 	}
84f76ee892STomi Valkeinen 
85f76ee892STomi Valkeinen 	if (mgr) {
86f76ee892STomi Valkeinen 		r = ovl->set_manager(ovl, mgr);
87f76ee892STomi Valkeinen 		if (r) {
88f76ee892STomi Valkeinen 			DSSERR("Failed to attach overlay\n");
89f76ee892STomi Valkeinen 			goto err;
90f76ee892STomi Valkeinen 		}
91f76ee892STomi Valkeinen 
92f76ee892STomi Valkeinen 		r = mgr->apply(mgr);
93f76ee892STomi Valkeinen 		if (r)
94f76ee892STomi Valkeinen 			goto err;
95f76ee892STomi Valkeinen 	}
96f76ee892STomi Valkeinen 
97f76ee892STomi Valkeinen 	dispc_runtime_put();
98f76ee892STomi Valkeinen 
99f76ee892STomi Valkeinen 	return size;
100f76ee892STomi Valkeinen 
101f76ee892STomi Valkeinen err:
102f76ee892STomi Valkeinen 	dispc_runtime_put();
103f76ee892STomi Valkeinen 	return r;
104f76ee892STomi Valkeinen }
105f76ee892STomi Valkeinen 
overlay_input_size_show(struct omap_overlay * ovl,char * buf)106f76ee892STomi Valkeinen static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
107f76ee892STomi Valkeinen {
108f76ee892STomi Valkeinen 	struct omap_overlay_info info;
109f76ee892STomi Valkeinen 
110f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
111f76ee892STomi Valkeinen 
112cc83ff24SQing Wang 	return sysfs_emit(buf, "%d,%d\n",
113f76ee892STomi Valkeinen 			info.width, info.height);
114f76ee892STomi Valkeinen }
115f76ee892STomi Valkeinen 
overlay_screen_width_show(struct omap_overlay * ovl,char * buf)116f76ee892STomi Valkeinen static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
117f76ee892STomi Valkeinen {
118f76ee892STomi Valkeinen 	struct omap_overlay_info info;
119f76ee892STomi Valkeinen 
120f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
121f76ee892STomi Valkeinen 
122cc83ff24SQing Wang 	return sysfs_emit(buf, "%d\n", info.screen_width);
123f76ee892STomi Valkeinen }
124f76ee892STomi Valkeinen 
overlay_position_show(struct omap_overlay * ovl,char * buf)125f76ee892STomi Valkeinen static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
126f76ee892STomi Valkeinen {
127f76ee892STomi Valkeinen 	struct omap_overlay_info info;
128f76ee892STomi Valkeinen 
129f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
130f76ee892STomi Valkeinen 
131cc83ff24SQing Wang 	return sysfs_emit(buf, "%d,%d\n",
132f76ee892STomi Valkeinen 			info.pos_x, info.pos_y);
133f76ee892STomi Valkeinen }
134f76ee892STomi Valkeinen 
overlay_position_store(struct omap_overlay * ovl,const char * buf,size_t size)135f76ee892STomi Valkeinen static ssize_t overlay_position_store(struct omap_overlay *ovl,
136f76ee892STomi Valkeinen 		const char *buf, size_t size)
137f76ee892STomi Valkeinen {
138f76ee892STomi Valkeinen 	int r;
139f76ee892STomi Valkeinen 	char *last;
140f76ee892STomi Valkeinen 	struct omap_overlay_info info;
141f76ee892STomi Valkeinen 
142f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
143f76ee892STomi Valkeinen 
144f76ee892STomi Valkeinen 	info.pos_x = simple_strtoul(buf, &last, 10);
145f76ee892STomi Valkeinen 	++last;
146f76ee892STomi Valkeinen 	if (last - buf >= size)
147f76ee892STomi Valkeinen 		return -EINVAL;
148f76ee892STomi Valkeinen 
149f76ee892STomi Valkeinen 	info.pos_y = simple_strtoul(last, &last, 10);
150f76ee892STomi Valkeinen 
151f76ee892STomi Valkeinen 	r = ovl->set_overlay_info(ovl, &info);
152f76ee892STomi Valkeinen 	if (r)
153f76ee892STomi Valkeinen 		return r;
154f76ee892STomi Valkeinen 
155f76ee892STomi Valkeinen 	if (ovl->manager) {
156f76ee892STomi Valkeinen 		r = ovl->manager->apply(ovl->manager);
157f76ee892STomi Valkeinen 		if (r)
158f76ee892STomi Valkeinen 			return r;
159f76ee892STomi Valkeinen 	}
160f76ee892STomi Valkeinen 
161f76ee892STomi Valkeinen 	return size;
162f76ee892STomi Valkeinen }
163f76ee892STomi Valkeinen 
overlay_output_size_show(struct omap_overlay * ovl,char * buf)164f76ee892STomi Valkeinen static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
165f76ee892STomi Valkeinen {
166f76ee892STomi Valkeinen 	struct omap_overlay_info info;
167f76ee892STomi Valkeinen 
168f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
169f76ee892STomi Valkeinen 
170cc83ff24SQing Wang 	return sysfs_emit(buf, "%d,%d\n",
171f76ee892STomi Valkeinen 			info.out_width, info.out_height);
172f76ee892STomi Valkeinen }
173f76ee892STomi Valkeinen 
overlay_output_size_store(struct omap_overlay * ovl,const char * buf,size_t size)174f76ee892STomi Valkeinen static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
175f76ee892STomi Valkeinen 		const char *buf, size_t size)
176f76ee892STomi Valkeinen {
177f76ee892STomi Valkeinen 	int r;
178f76ee892STomi Valkeinen 	char *last;
179f76ee892STomi Valkeinen 	struct omap_overlay_info info;
180f76ee892STomi Valkeinen 
181f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
182f76ee892STomi Valkeinen 
183f76ee892STomi Valkeinen 	info.out_width = simple_strtoul(buf, &last, 10);
184f76ee892STomi Valkeinen 	++last;
185f76ee892STomi Valkeinen 	if (last - buf >= size)
186f76ee892STomi Valkeinen 		return -EINVAL;
187f76ee892STomi Valkeinen 
188f76ee892STomi Valkeinen 	info.out_height = simple_strtoul(last, &last, 10);
189f76ee892STomi Valkeinen 
190f76ee892STomi Valkeinen 	r = ovl->set_overlay_info(ovl, &info);
191f76ee892STomi Valkeinen 	if (r)
192f76ee892STomi Valkeinen 		return r;
193f76ee892STomi Valkeinen 
194f76ee892STomi Valkeinen 	if (ovl->manager) {
195f76ee892STomi Valkeinen 		r = ovl->manager->apply(ovl->manager);
196f76ee892STomi Valkeinen 		if (r)
197f76ee892STomi Valkeinen 			return r;
198f76ee892STomi Valkeinen 	}
199f76ee892STomi Valkeinen 
200f76ee892STomi Valkeinen 	return size;
201f76ee892STomi Valkeinen }
202f76ee892STomi Valkeinen 
overlay_enabled_show(struct omap_overlay * ovl,char * buf)203f76ee892STomi Valkeinen static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
204f76ee892STomi Valkeinen {
205cc83ff24SQing Wang 	return sysfs_emit(buf, "%d\n", ovl->is_enabled(ovl));
206f76ee892STomi Valkeinen }
207f76ee892STomi Valkeinen 
overlay_enabled_store(struct omap_overlay * ovl,const char * buf,size_t size)208f76ee892STomi Valkeinen static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
209f76ee892STomi Valkeinen 		size_t size)
210f76ee892STomi Valkeinen {
211f76ee892STomi Valkeinen 	int r;
212f76ee892STomi Valkeinen 	bool enable;
213f76ee892STomi Valkeinen 
214*ee9fffdcSChristophe JAILLET 	r = kstrtobool(buf, &enable);
215f76ee892STomi Valkeinen 	if (r)
216f76ee892STomi Valkeinen 		return r;
217f76ee892STomi Valkeinen 
218f76ee892STomi Valkeinen 	if (enable)
219f76ee892STomi Valkeinen 		r = ovl->enable(ovl);
220f76ee892STomi Valkeinen 	else
221f76ee892STomi Valkeinen 		r = ovl->disable(ovl);
222f76ee892STomi Valkeinen 
223f76ee892STomi Valkeinen 	if (r)
224f76ee892STomi Valkeinen 		return r;
225f76ee892STomi Valkeinen 
226f76ee892STomi Valkeinen 	return size;
227f76ee892STomi Valkeinen }
228f76ee892STomi Valkeinen 
overlay_global_alpha_show(struct omap_overlay * ovl,char * buf)229f76ee892STomi Valkeinen static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
230f76ee892STomi Valkeinen {
231f76ee892STomi Valkeinen 	struct omap_overlay_info info;
232f76ee892STomi Valkeinen 
233f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
234f76ee892STomi Valkeinen 
235cc83ff24SQing Wang 	return sysfs_emit(buf, "%d\n",
236f76ee892STomi Valkeinen 			info.global_alpha);
237f76ee892STomi Valkeinen }
238f76ee892STomi Valkeinen 
overlay_global_alpha_store(struct omap_overlay * ovl,const char * buf,size_t size)239f76ee892STomi Valkeinen static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
240f76ee892STomi Valkeinen 		const char *buf, size_t size)
241f76ee892STomi Valkeinen {
242f76ee892STomi Valkeinen 	int r;
243f76ee892STomi Valkeinen 	u8 alpha;
244f76ee892STomi Valkeinen 	struct omap_overlay_info info;
245f76ee892STomi Valkeinen 
246f76ee892STomi Valkeinen 	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
247f76ee892STomi Valkeinen 		return -ENODEV;
248f76ee892STomi Valkeinen 
249f76ee892STomi Valkeinen 	r = kstrtou8(buf, 0, &alpha);
250f76ee892STomi Valkeinen 	if (r)
251f76ee892STomi Valkeinen 		return r;
252f76ee892STomi Valkeinen 
253f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
254f76ee892STomi Valkeinen 
255f76ee892STomi Valkeinen 	info.global_alpha = alpha;
256f76ee892STomi Valkeinen 
257f76ee892STomi Valkeinen 	r = ovl->set_overlay_info(ovl, &info);
258f76ee892STomi Valkeinen 	if (r)
259f76ee892STomi Valkeinen 		return r;
260f76ee892STomi Valkeinen 
261f76ee892STomi Valkeinen 	if (ovl->manager) {
262f76ee892STomi Valkeinen 		r = ovl->manager->apply(ovl->manager);
263f76ee892STomi Valkeinen 		if (r)
264f76ee892STomi Valkeinen 			return r;
265f76ee892STomi Valkeinen 	}
266f76ee892STomi Valkeinen 
267f76ee892STomi Valkeinen 	return size;
268f76ee892STomi Valkeinen }
269f76ee892STomi Valkeinen 
overlay_pre_mult_alpha_show(struct omap_overlay * ovl,char * buf)270f76ee892STomi Valkeinen static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
271f76ee892STomi Valkeinen 		char *buf)
272f76ee892STomi Valkeinen {
273f76ee892STomi Valkeinen 	struct omap_overlay_info info;
274f76ee892STomi Valkeinen 
275f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
276f76ee892STomi Valkeinen 
277cc83ff24SQing Wang 	return sysfs_emit(buf, "%d\n",
278f76ee892STomi Valkeinen 			info.pre_mult_alpha);
279f76ee892STomi Valkeinen }
280f76ee892STomi Valkeinen 
overlay_pre_mult_alpha_store(struct omap_overlay * ovl,const char * buf,size_t size)281f76ee892STomi Valkeinen static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
282f76ee892STomi Valkeinen 		const char *buf, size_t size)
283f76ee892STomi Valkeinen {
284f76ee892STomi Valkeinen 	int r;
285f76ee892STomi Valkeinen 	u8 alpha;
286f76ee892STomi Valkeinen 	struct omap_overlay_info info;
287f76ee892STomi Valkeinen 
288f76ee892STomi Valkeinen 	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
289f76ee892STomi Valkeinen 		return -ENODEV;
290f76ee892STomi Valkeinen 
291f76ee892STomi Valkeinen 	r = kstrtou8(buf, 0, &alpha);
292f76ee892STomi Valkeinen 	if (r)
293f76ee892STomi Valkeinen 		return r;
294f76ee892STomi Valkeinen 
295f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
296f76ee892STomi Valkeinen 
297f76ee892STomi Valkeinen 	info.pre_mult_alpha = alpha;
298f76ee892STomi Valkeinen 
299f76ee892STomi Valkeinen 	r = ovl->set_overlay_info(ovl, &info);
300f76ee892STomi Valkeinen 	if (r)
301f76ee892STomi Valkeinen 		return r;
302f76ee892STomi Valkeinen 
303f76ee892STomi Valkeinen 	if (ovl->manager) {
304f76ee892STomi Valkeinen 		r = ovl->manager->apply(ovl->manager);
305f76ee892STomi Valkeinen 		if (r)
306f76ee892STomi Valkeinen 			return r;
307f76ee892STomi Valkeinen 	}
308f76ee892STomi Valkeinen 
309f76ee892STomi Valkeinen 	return size;
310f76ee892STomi Valkeinen }
311f76ee892STomi Valkeinen 
overlay_zorder_show(struct omap_overlay * ovl,char * buf)312f76ee892STomi Valkeinen static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
313f76ee892STomi Valkeinen {
314f76ee892STomi Valkeinen 	struct omap_overlay_info info;
315f76ee892STomi Valkeinen 
316f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
317f76ee892STomi Valkeinen 
318cc83ff24SQing Wang 	return sysfs_emit(buf, "%d\n", info.zorder);
319f76ee892STomi Valkeinen }
320f76ee892STomi Valkeinen 
overlay_zorder_store(struct omap_overlay * ovl,const char * buf,size_t size)321f76ee892STomi Valkeinen static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
322f76ee892STomi Valkeinen 		const char *buf, size_t size)
323f76ee892STomi Valkeinen {
324f76ee892STomi Valkeinen 	int r;
325f76ee892STomi Valkeinen 	u8 zorder;
326f76ee892STomi Valkeinen 	struct omap_overlay_info info;
327f76ee892STomi Valkeinen 
328f76ee892STomi Valkeinen 	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
329f76ee892STomi Valkeinen 		return -ENODEV;
330f76ee892STomi Valkeinen 
331f76ee892STomi Valkeinen 	r = kstrtou8(buf, 0, &zorder);
332f76ee892STomi Valkeinen 	if (r)
333f76ee892STomi Valkeinen 		return r;
334f76ee892STomi Valkeinen 
335f76ee892STomi Valkeinen 	ovl->get_overlay_info(ovl, &info);
336f76ee892STomi Valkeinen 
337f76ee892STomi Valkeinen 	info.zorder = zorder;
338f76ee892STomi Valkeinen 
339f76ee892STomi Valkeinen 	r = ovl->set_overlay_info(ovl, &info);
340f76ee892STomi Valkeinen 	if (r)
341f76ee892STomi Valkeinen 		return r;
342f76ee892STomi Valkeinen 
343f76ee892STomi Valkeinen 	if (ovl->manager) {
344f76ee892STomi Valkeinen 		r = ovl->manager->apply(ovl->manager);
345f76ee892STomi Valkeinen 		if (r)
346f76ee892STomi Valkeinen 			return r;
347f76ee892STomi Valkeinen 	}
348f76ee892STomi Valkeinen 
349f76ee892STomi Valkeinen 	return size;
350f76ee892STomi Valkeinen }
351f76ee892STomi Valkeinen 
352f76ee892STomi Valkeinen struct overlay_attribute {
353f76ee892STomi Valkeinen 	struct attribute attr;
354f76ee892STomi Valkeinen 	ssize_t (*show)(struct omap_overlay *, char *);
355f76ee892STomi Valkeinen 	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
356f76ee892STomi Valkeinen };
357f76ee892STomi Valkeinen 
358f76ee892STomi Valkeinen #define OVERLAY_ATTR(_name, _mode, _show, _store) \
359f76ee892STomi Valkeinen 	struct overlay_attribute overlay_attr_##_name = \
360f76ee892STomi Valkeinen 	__ATTR(_name, _mode, _show, _store)
361f76ee892STomi Valkeinen 
362f76ee892STomi Valkeinen static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
363f76ee892STomi Valkeinen static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
364f76ee892STomi Valkeinen 		overlay_manager_show, overlay_manager_store);
365f76ee892STomi Valkeinen static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
366f76ee892STomi Valkeinen static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
367f76ee892STomi Valkeinen static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
368f76ee892STomi Valkeinen 		overlay_position_show, overlay_position_store);
369f76ee892STomi Valkeinen static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
370f76ee892STomi Valkeinen 		overlay_output_size_show, overlay_output_size_store);
371f76ee892STomi Valkeinen static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
372f76ee892STomi Valkeinen 		overlay_enabled_show, overlay_enabled_store);
373f76ee892STomi Valkeinen static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
374f76ee892STomi Valkeinen 		overlay_global_alpha_show, overlay_global_alpha_store);
375f76ee892STomi Valkeinen static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
376f76ee892STomi Valkeinen 		overlay_pre_mult_alpha_show,
377f76ee892STomi Valkeinen 		overlay_pre_mult_alpha_store);
378f76ee892STomi Valkeinen static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
379f76ee892STomi Valkeinen 		overlay_zorder_show, overlay_zorder_store);
380f76ee892STomi Valkeinen 
381f76ee892STomi Valkeinen static struct attribute *overlay_sysfs_attrs[] = {
382f76ee892STomi Valkeinen 	&overlay_attr_name.attr,
383f76ee892STomi Valkeinen 	&overlay_attr_manager.attr,
384f76ee892STomi Valkeinen 	&overlay_attr_input_size.attr,
385f76ee892STomi Valkeinen 	&overlay_attr_screen_width.attr,
386f76ee892STomi Valkeinen 	&overlay_attr_position.attr,
387f76ee892STomi Valkeinen 	&overlay_attr_output_size.attr,
388f76ee892STomi Valkeinen 	&overlay_attr_enabled.attr,
389f76ee892STomi Valkeinen 	&overlay_attr_global_alpha.attr,
390f76ee892STomi Valkeinen 	&overlay_attr_pre_mult_alpha.attr,
391f76ee892STomi Valkeinen 	&overlay_attr_zorder.attr,
392f76ee892STomi Valkeinen 	NULL
393f76ee892STomi Valkeinen };
39419d10a83SGreg Kroah-Hartman ATTRIBUTE_GROUPS(overlay_sysfs);
395f76ee892STomi Valkeinen 
overlay_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)396f76ee892STomi Valkeinen static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
397f76ee892STomi Valkeinen 		char *buf)
398f76ee892STomi Valkeinen {
399f76ee892STomi Valkeinen 	struct omap_overlay *overlay;
400f76ee892STomi Valkeinen 	struct overlay_attribute *overlay_attr;
401f76ee892STomi Valkeinen 
402f76ee892STomi Valkeinen 	overlay = container_of(kobj, struct omap_overlay, kobj);
403f76ee892STomi Valkeinen 	overlay_attr = container_of(attr, struct overlay_attribute, attr);
404f76ee892STomi Valkeinen 
405f76ee892STomi Valkeinen 	if (!overlay_attr->show)
406f76ee892STomi Valkeinen 		return -ENOENT;
407f76ee892STomi Valkeinen 
408f76ee892STomi Valkeinen 	return overlay_attr->show(overlay, buf);
409f76ee892STomi Valkeinen }
410f76ee892STomi Valkeinen 
overlay_attr_store(struct kobject * kobj,struct attribute * attr,const char * buf,size_t size)411f76ee892STomi Valkeinen static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
412f76ee892STomi Valkeinen 		const char *buf, size_t size)
413f76ee892STomi Valkeinen {
414f76ee892STomi Valkeinen 	struct omap_overlay *overlay;
415f76ee892STomi Valkeinen 	struct overlay_attribute *overlay_attr;
416f76ee892STomi Valkeinen 
417f76ee892STomi Valkeinen 	overlay = container_of(kobj, struct omap_overlay, kobj);
418f76ee892STomi Valkeinen 	overlay_attr = container_of(attr, struct overlay_attribute, attr);
419f76ee892STomi Valkeinen 
420f76ee892STomi Valkeinen 	if (!overlay_attr->store)
421f76ee892STomi Valkeinen 		return -ENOENT;
422f76ee892STomi Valkeinen 
423f76ee892STomi Valkeinen 	return overlay_attr->store(overlay, buf, size);
424f76ee892STomi Valkeinen }
425f76ee892STomi Valkeinen 
426f76ee892STomi Valkeinen static const struct sysfs_ops overlay_sysfs_ops = {
427f76ee892STomi Valkeinen 	.show = overlay_attr_show,
428f76ee892STomi Valkeinen 	.store = overlay_attr_store,
429f76ee892STomi Valkeinen };
430f76ee892STomi Valkeinen 
431f76ee892STomi Valkeinen static struct kobj_type overlay_ktype = {
432f76ee892STomi Valkeinen 	.sysfs_ops = &overlay_sysfs_ops,
43319d10a83SGreg Kroah-Hartman 	.default_groups = overlay_sysfs_groups,
434f76ee892STomi Valkeinen };
435f76ee892STomi Valkeinen 
dss_overlay_kobj_init(struct omap_overlay * ovl,struct platform_device * pdev)436f76ee892STomi Valkeinen int dss_overlay_kobj_init(struct omap_overlay *ovl,
437f76ee892STomi Valkeinen 		struct platform_device *pdev)
438f76ee892STomi Valkeinen {
439f76ee892STomi Valkeinen 	return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
440f76ee892STomi Valkeinen 			&pdev->dev.kobj, "overlay%d", ovl->id);
441f76ee892STomi Valkeinen }
442f76ee892STomi Valkeinen 
dss_overlay_kobj_uninit(struct omap_overlay * ovl)443f76ee892STomi Valkeinen void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
444f76ee892STomi Valkeinen {
445f76ee892STomi Valkeinen 	kobject_del(&ovl->kobj);
446f76ee892STomi Valkeinen 	kobject_put(&ovl->kobj);
447f76ee892STomi Valkeinen }
448