Merge tag 'trace-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux/fpc-iii.git] / drivers / video / fbdev / omap2 / omapfb / dss / overlay-sysfs.c
blob36acf366213a27aae39abc567fdfca8ef023128f
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2009 Nokia Corporation
4 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 * Some code and ideas taken from drivers/video/omap/ driver
7 * by Imre Deak.
8 */
10 #define DSS_SUBSYS_NAME "OVERLAY"
12 #include <linux/module.h>
13 #include <linux/err.h>
14 #include <linux/sysfs.h>
15 #include <linux/kobject.h>
16 #include <linux/platform_device.h>
18 #include <video/omapfb_dss.h>
20 #include "dss.h"
21 #include "dss_features.h"
23 static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
25 return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
28 static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
30 return snprintf(buf, PAGE_SIZE, "%s\n",
31 ovl->manager ? ovl->manager->name : "<none>");
34 static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
35 size_t size)
37 int i, r;
38 struct omap_overlay_manager *mgr = NULL;
39 struct omap_overlay_manager *old_mgr;
40 int len = size;
42 if (buf[size-1] == '\n')
43 --len;
45 if (len > 0) {
46 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
47 mgr = omap_dss_get_overlay_manager(i);
49 if (sysfs_streq(buf, mgr->name))
50 break;
52 mgr = NULL;
56 if (len > 0 && mgr == NULL)
57 return -EINVAL;
59 if (mgr)
60 DSSDBG("manager %s found\n", mgr->name);
62 if (mgr == ovl->manager)
63 return size;
65 old_mgr = ovl->manager;
67 r = dispc_runtime_get();
68 if (r)
69 return r;
71 /* detach old manager */
72 if (old_mgr) {
73 r = ovl->unset_manager(ovl);
74 if (r) {
75 DSSERR("detach failed\n");
76 goto err;
79 r = old_mgr->apply(old_mgr);
80 if (r)
81 goto err;
84 if (mgr) {
85 r = ovl->set_manager(ovl, mgr);
86 if (r) {
87 DSSERR("Failed to attach overlay\n");
88 goto err;
91 r = mgr->apply(mgr);
92 if (r)
93 goto err;
96 dispc_runtime_put();
98 return size;
100 err:
101 dispc_runtime_put();
102 return r;
105 static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
107 struct omap_overlay_info info;
109 ovl->get_overlay_info(ovl, &info);
111 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
112 info.width, info.height);
115 static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
117 struct omap_overlay_info info;
119 ovl->get_overlay_info(ovl, &info);
121 return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
124 static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
126 struct omap_overlay_info info;
128 ovl->get_overlay_info(ovl, &info);
130 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
131 info.pos_x, info.pos_y);
134 static ssize_t overlay_position_store(struct omap_overlay *ovl,
135 const char *buf, size_t size)
137 int r;
138 char *last;
139 struct omap_overlay_info info;
141 ovl->get_overlay_info(ovl, &info);
143 info.pos_x = simple_strtoul(buf, &last, 10);
144 ++last;
145 if (last - buf >= size)
146 return -EINVAL;
148 info.pos_y = simple_strtoul(last, &last, 10);
150 r = ovl->set_overlay_info(ovl, &info);
151 if (r)
152 return r;
154 if (ovl->manager) {
155 r = ovl->manager->apply(ovl->manager);
156 if (r)
157 return r;
160 return size;
163 static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
165 struct omap_overlay_info info;
167 ovl->get_overlay_info(ovl, &info);
169 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
170 info.out_width, info.out_height);
173 static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
174 const char *buf, size_t size)
176 int r;
177 char *last;
178 struct omap_overlay_info info;
180 ovl->get_overlay_info(ovl, &info);
182 info.out_width = simple_strtoul(buf, &last, 10);
183 ++last;
184 if (last - buf >= size)
185 return -EINVAL;
187 info.out_height = simple_strtoul(last, &last, 10);
189 r = ovl->set_overlay_info(ovl, &info);
190 if (r)
191 return r;
193 if (ovl->manager) {
194 r = ovl->manager->apply(ovl->manager);
195 if (r)
196 return r;
199 return size;
202 static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
204 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
207 static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
208 size_t size)
210 int r;
211 bool enable;
213 r = strtobool(buf, &enable);
214 if (r)
215 return r;
217 if (enable)
218 r = ovl->enable(ovl);
219 else
220 r = ovl->disable(ovl);
222 if (r)
223 return r;
225 return size;
228 static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
230 struct omap_overlay_info info;
232 ovl->get_overlay_info(ovl, &info);
234 return snprintf(buf, PAGE_SIZE, "%d\n",
235 info.global_alpha);
238 static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
239 const char *buf, size_t size)
241 int r;
242 u8 alpha;
243 struct omap_overlay_info info;
245 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
246 return -ENODEV;
248 r = kstrtou8(buf, 0, &alpha);
249 if (r)
250 return r;
252 ovl->get_overlay_info(ovl, &info);
254 info.global_alpha = alpha;
256 r = ovl->set_overlay_info(ovl, &info);
257 if (r)
258 return r;
260 if (ovl->manager) {
261 r = ovl->manager->apply(ovl->manager);
262 if (r)
263 return r;
266 return size;
269 static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
270 char *buf)
272 struct omap_overlay_info info;
274 ovl->get_overlay_info(ovl, &info);
276 return snprintf(buf, PAGE_SIZE, "%d\n",
277 info.pre_mult_alpha);
280 static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
281 const char *buf, size_t size)
283 int r;
284 u8 alpha;
285 struct omap_overlay_info info;
287 if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
288 return -ENODEV;
290 r = kstrtou8(buf, 0, &alpha);
291 if (r)
292 return r;
294 ovl->get_overlay_info(ovl, &info);
296 info.pre_mult_alpha = alpha;
298 r = ovl->set_overlay_info(ovl, &info);
299 if (r)
300 return r;
302 if (ovl->manager) {
303 r = ovl->manager->apply(ovl->manager);
304 if (r)
305 return r;
308 return size;
311 static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
313 struct omap_overlay_info info;
315 ovl->get_overlay_info(ovl, &info);
317 return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
320 static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
321 const char *buf, size_t size)
323 int r;
324 u8 zorder;
325 struct omap_overlay_info info;
327 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
328 return -ENODEV;
330 r = kstrtou8(buf, 0, &zorder);
331 if (r)
332 return r;
334 ovl->get_overlay_info(ovl, &info);
336 info.zorder = zorder;
338 r = ovl->set_overlay_info(ovl, &info);
339 if (r)
340 return r;
342 if (ovl->manager) {
343 r = ovl->manager->apply(ovl->manager);
344 if (r)
345 return r;
348 return size;
351 struct overlay_attribute {
352 struct attribute attr;
353 ssize_t (*show)(struct omap_overlay *, char *);
354 ssize_t (*store)(struct omap_overlay *, const char *, size_t);
357 #define OVERLAY_ATTR(_name, _mode, _show, _store) \
358 struct overlay_attribute overlay_attr_##_name = \
359 __ATTR(_name, _mode, _show, _store)
361 static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
362 static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
363 overlay_manager_show, overlay_manager_store);
364 static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
365 static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
366 static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
367 overlay_position_show, overlay_position_store);
368 static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
369 overlay_output_size_show, overlay_output_size_store);
370 static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
371 overlay_enabled_show, overlay_enabled_store);
372 static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
373 overlay_global_alpha_show, overlay_global_alpha_store);
374 static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
375 overlay_pre_mult_alpha_show,
376 overlay_pre_mult_alpha_store);
377 static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
378 overlay_zorder_show, overlay_zorder_store);
380 static struct attribute *overlay_sysfs_attrs[] = {
381 &overlay_attr_name.attr,
382 &overlay_attr_manager.attr,
383 &overlay_attr_input_size.attr,
384 &overlay_attr_screen_width.attr,
385 &overlay_attr_position.attr,
386 &overlay_attr_output_size.attr,
387 &overlay_attr_enabled.attr,
388 &overlay_attr_global_alpha.attr,
389 &overlay_attr_pre_mult_alpha.attr,
390 &overlay_attr_zorder.attr,
391 NULL
394 static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
395 char *buf)
397 struct omap_overlay *overlay;
398 struct overlay_attribute *overlay_attr;
400 overlay = container_of(kobj, struct omap_overlay, kobj);
401 overlay_attr = container_of(attr, struct overlay_attribute, attr);
403 if (!overlay_attr->show)
404 return -ENOENT;
406 return overlay_attr->show(overlay, buf);
409 static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
410 const char *buf, size_t size)
412 struct omap_overlay *overlay;
413 struct overlay_attribute *overlay_attr;
415 overlay = container_of(kobj, struct omap_overlay, kobj);
416 overlay_attr = container_of(attr, struct overlay_attribute, attr);
418 if (!overlay_attr->store)
419 return -ENOENT;
421 return overlay_attr->store(overlay, buf, size);
424 static const struct sysfs_ops overlay_sysfs_ops = {
425 .show = overlay_attr_show,
426 .store = overlay_attr_store,
429 static struct kobj_type overlay_ktype = {
430 .sysfs_ops = &overlay_sysfs_ops,
431 .default_attrs = overlay_sysfs_attrs,
434 int dss_overlay_kobj_init(struct omap_overlay *ovl,
435 struct platform_device *pdev)
437 return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
438 &pdev->dev.kobj, "overlay%d", ovl->id);
441 void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
443 kobject_del(&ovl->kobj);
444 kobject_put(&ovl->kobj);