1 // SPDX-License-Identifier: GPL-2.0-only
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
10 #define DSS_SUBSYS_NAME "MANAGER"
12 #include <linux/kernel.h>
13 #include <linux/kstrtox.h>
14 #include <linux/slab.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/jiffies.h>
19 #include <video/omapfb_dss.h>
22 #include "dss_features.h"
24 static ssize_t
manager_name_show(struct omap_overlay_manager
*mgr
, char *buf
)
26 return sysfs_emit(buf
, "%s\n", mgr
->name
);
29 static ssize_t
manager_display_show(struct omap_overlay_manager
*mgr
, char *buf
)
31 struct omap_dss_device
*dssdev
= mgr
->get_device(mgr
);
33 return sysfs_emit(buf
, "%s\n", dssdev
?
34 dssdev
->name
: "<none>");
37 static int manager_display_match(struct omap_dss_device
*dssdev
, void *data
)
39 const char *str
= data
;
41 return sysfs_streq(dssdev
->name
, str
);
44 static ssize_t
manager_display_store(struct omap_overlay_manager
*mgr
,
45 const char *buf
, size_t size
)
49 struct omap_dss_device
*dssdev
= NULL
;
50 struct omap_dss_device
*old_dssdev
;
52 if (buf
[size
-1] == '\n')
56 dssdev
= omap_dss_find_device((void *)buf
,
57 manager_display_match
);
59 if (len
> 0 && dssdev
== NULL
)
63 DSSDBG("display %s found\n", dssdev
->name
);
65 if (omapdss_device_is_connected(dssdev
)) {
66 DSSERR("new display is already connected\n");
71 if (omapdss_device_is_enabled(dssdev
)) {
72 DSSERR("new display is not disabled\n");
78 old_dssdev
= mgr
->get_device(mgr
);
80 if (omapdss_device_is_enabled(old_dssdev
)) {
81 DSSERR("old display is not disabled\n");
86 old_dssdev
->driver
->disconnect(old_dssdev
);
90 r
= dssdev
->driver
->connect(dssdev
);
92 DSSERR("failed to connect new device\n");
96 old_dssdev
= mgr
->get_device(mgr
);
97 if (old_dssdev
!= dssdev
) {
98 DSSERR("failed to connect device to this manager\n");
99 dssdev
->driver
->disconnect(dssdev
);
105 DSSERR("failed to apply dispc config\n");
112 omap_dss_put_device(dssdev
);
117 static ssize_t
manager_default_color_show(struct omap_overlay_manager
*mgr
,
120 struct omap_overlay_manager_info info
;
122 mgr
->get_manager_info(mgr
, &info
);
124 return sysfs_emit(buf
, "%#x\n", info
.default_color
);
127 static ssize_t
manager_default_color_store(struct omap_overlay_manager
*mgr
,
128 const char *buf
, size_t size
)
130 struct omap_overlay_manager_info info
;
134 r
= kstrtouint(buf
, 0, &color
);
138 mgr
->get_manager_info(mgr
, &info
);
140 info
.default_color
= color
;
142 r
= mgr
->set_manager_info(mgr
, &info
);
153 static const char *trans_key_type_str
[] = {
158 static ssize_t
manager_trans_key_type_show(struct omap_overlay_manager
*mgr
,
161 enum omap_dss_trans_key_type key_type
;
162 struct omap_overlay_manager_info info
;
164 mgr
->get_manager_info(mgr
, &info
);
166 key_type
= info
.trans_key_type
;
167 BUG_ON(key_type
>= ARRAY_SIZE(trans_key_type_str
));
169 return sysfs_emit(buf
, "%s\n", trans_key_type_str
[key_type
]);
172 static ssize_t
manager_trans_key_type_store(struct omap_overlay_manager
*mgr
,
173 const char *buf
, size_t size
)
175 struct omap_overlay_manager_info info
;
178 r
= sysfs_match_string(trans_key_type_str
, buf
);
182 mgr
->get_manager_info(mgr
, &info
);
184 info
.trans_key_type
= r
;
186 r
= mgr
->set_manager_info(mgr
, &info
);
197 static ssize_t
manager_trans_key_value_show(struct omap_overlay_manager
*mgr
,
200 struct omap_overlay_manager_info info
;
202 mgr
->get_manager_info(mgr
, &info
);
204 return sysfs_emit(buf
, "%#x\n", info
.trans_key
);
207 static ssize_t
manager_trans_key_value_store(struct omap_overlay_manager
*mgr
,
208 const char *buf
, size_t size
)
210 struct omap_overlay_manager_info info
;
214 r
= kstrtouint(buf
, 0, &key_value
);
218 mgr
->get_manager_info(mgr
, &info
);
220 info
.trans_key
= key_value
;
222 r
= mgr
->set_manager_info(mgr
, &info
);
233 static ssize_t
manager_trans_key_enabled_show(struct omap_overlay_manager
*mgr
,
236 struct omap_overlay_manager_info info
;
238 mgr
->get_manager_info(mgr
, &info
);
240 return sysfs_emit(buf
, "%d\n", info
.trans_enabled
);
243 static ssize_t
manager_trans_key_enabled_store(struct omap_overlay_manager
*mgr
,
244 const char *buf
, size_t size
)
246 struct omap_overlay_manager_info info
;
250 r
= kstrtobool(buf
, &enable
);
254 mgr
->get_manager_info(mgr
, &info
);
256 info
.trans_enabled
= enable
;
258 r
= mgr
->set_manager_info(mgr
, &info
);
269 static ssize_t
manager_alpha_blending_enabled_show(
270 struct omap_overlay_manager
*mgr
, char *buf
)
272 struct omap_overlay_manager_info info
;
274 if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER
))
277 mgr
->get_manager_info(mgr
, &info
);
279 return sysfs_emit(buf
, "%d\n",
280 info
.partial_alpha_enabled
);
283 static ssize_t
manager_alpha_blending_enabled_store(
284 struct omap_overlay_manager
*mgr
,
285 const char *buf
, size_t size
)
287 struct omap_overlay_manager_info info
;
291 if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER
))
294 r
= kstrtobool(buf
, &enable
);
298 mgr
->get_manager_info(mgr
, &info
);
300 info
.partial_alpha_enabled
= enable
;
302 r
= mgr
->set_manager_info(mgr
, &info
);
313 static ssize_t
manager_cpr_enable_show(struct omap_overlay_manager
*mgr
,
316 struct omap_overlay_manager_info info
;
318 mgr
->get_manager_info(mgr
, &info
);
320 return sysfs_emit(buf
, "%d\n", info
.cpr_enable
);
323 static ssize_t
manager_cpr_enable_store(struct omap_overlay_manager
*mgr
,
324 const char *buf
, size_t size
)
326 struct omap_overlay_manager_info info
;
330 if (!dss_has_feature(FEAT_CPR
))
333 r
= kstrtobool(buf
, &enable
);
337 mgr
->get_manager_info(mgr
, &info
);
339 if (info
.cpr_enable
== enable
)
342 info
.cpr_enable
= enable
;
344 r
= mgr
->set_manager_info(mgr
, &info
);
355 static ssize_t
manager_cpr_coef_show(struct omap_overlay_manager
*mgr
,
358 struct omap_overlay_manager_info info
;
360 mgr
->get_manager_info(mgr
, &info
);
362 return sysfs_emit(buf
,
363 "%d %d %d %d %d %d %d %d %d\n",
375 static ssize_t
manager_cpr_coef_store(struct omap_overlay_manager
*mgr
,
376 const char *buf
, size_t size
)
378 struct omap_overlay_manager_info info
;
379 struct omap_dss_cpr_coefs coefs
;
383 if (!dss_has_feature(FEAT_CPR
))
386 if (sscanf(buf
, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
387 &coefs
.rr
, &coefs
.rg
, &coefs
.rb
,
388 &coefs
.gr
, &coefs
.gg
, &coefs
.gb
,
389 &coefs
.br
, &coefs
.bg
, &coefs
.bb
) != 9)
392 arr
= (s16
[]){ coefs
.rr
, coefs
.rg
, coefs
.rb
,
393 coefs
.gr
, coefs
.gg
, coefs
.gb
,
394 coefs
.br
, coefs
.bg
, coefs
.bb
};
396 for (i
= 0; i
< 9; ++i
) {
397 if (arr
[i
] < -512 || arr
[i
] > 511)
401 mgr
->get_manager_info(mgr
, &info
);
403 info
.cpr_coefs
= coefs
;
405 r
= mgr
->set_manager_info(mgr
, &info
);
416 struct manager_attribute
{
417 struct attribute attr
;
418 ssize_t (*show
)(struct omap_overlay_manager
*, char *);
419 ssize_t (*store
)(struct omap_overlay_manager
*, const char *, size_t);
422 #define MANAGER_ATTR(_name, _mode, _show, _store) \
423 struct manager_attribute manager_attr_##_name = \
424 __ATTR(_name, _mode, _show, _store)
426 static MANAGER_ATTR(name
, S_IRUGO
, manager_name_show
, NULL
);
427 static MANAGER_ATTR(display
, S_IRUGO
|S_IWUSR
,
428 manager_display_show
, manager_display_store
);
429 static MANAGER_ATTR(default_color
, S_IRUGO
|S_IWUSR
,
430 manager_default_color_show
, manager_default_color_store
);
431 static MANAGER_ATTR(trans_key_type
, S_IRUGO
|S_IWUSR
,
432 manager_trans_key_type_show
, manager_trans_key_type_store
);
433 static MANAGER_ATTR(trans_key_value
, S_IRUGO
|S_IWUSR
,
434 manager_trans_key_value_show
, manager_trans_key_value_store
);
435 static MANAGER_ATTR(trans_key_enabled
, S_IRUGO
|S_IWUSR
,
436 manager_trans_key_enabled_show
,
437 manager_trans_key_enabled_store
);
438 static MANAGER_ATTR(alpha_blending_enabled
, S_IRUGO
|S_IWUSR
,
439 manager_alpha_blending_enabled_show
,
440 manager_alpha_blending_enabled_store
);
441 static MANAGER_ATTR(cpr_enable
, S_IRUGO
|S_IWUSR
,
442 manager_cpr_enable_show
,
443 manager_cpr_enable_store
);
444 static MANAGER_ATTR(cpr_coef
, S_IRUGO
|S_IWUSR
,
445 manager_cpr_coef_show
,
446 manager_cpr_coef_store
);
449 static struct attribute
*manager_sysfs_attrs
[] = {
450 &manager_attr_name
.attr
,
451 &manager_attr_display
.attr
,
452 &manager_attr_default_color
.attr
,
453 &manager_attr_trans_key_type
.attr
,
454 &manager_attr_trans_key_value
.attr
,
455 &manager_attr_trans_key_enabled
.attr
,
456 &manager_attr_alpha_blending_enabled
.attr
,
457 &manager_attr_cpr_enable
.attr
,
458 &manager_attr_cpr_coef
.attr
,
461 ATTRIBUTE_GROUPS(manager_sysfs
);
463 static ssize_t
manager_attr_show(struct kobject
*kobj
, struct attribute
*attr
,
466 struct omap_overlay_manager
*manager
;
467 struct manager_attribute
*manager_attr
;
469 manager
= container_of(kobj
, struct omap_overlay_manager
, kobj
);
470 manager_attr
= container_of(attr
, struct manager_attribute
, attr
);
472 if (!manager_attr
->show
)
475 return manager_attr
->show(manager
, buf
);
478 static ssize_t
manager_attr_store(struct kobject
*kobj
, struct attribute
*attr
,
479 const char *buf
, size_t size
)
481 struct omap_overlay_manager
*manager
;
482 struct manager_attribute
*manager_attr
;
484 manager
= container_of(kobj
, struct omap_overlay_manager
, kobj
);
485 manager_attr
= container_of(attr
, struct manager_attribute
, attr
);
487 if (!manager_attr
->store
)
490 return manager_attr
->store(manager
, buf
, size
);
493 static const struct sysfs_ops manager_sysfs_ops
= {
494 .show
= manager_attr_show
,
495 .store
= manager_attr_store
,
498 static struct kobj_type manager_ktype
= {
499 .sysfs_ops
= &manager_sysfs_ops
,
500 .default_groups
= manager_sysfs_groups
,
503 int dss_manager_kobj_init(struct omap_overlay_manager
*mgr
,
504 struct platform_device
*pdev
)
506 return kobject_init_and_add(&mgr
->kobj
, &manager_ktype
,
507 &pdev
->dev
.kobj
, "manager%d", mgr
->id
);
510 void dss_manager_kobj_uninit(struct omap_overlay_manager
*mgr
)
512 kobject_del(&mgr
->kobj
);
513 kobject_put(&mgr
->kobj
);
515 memset(&mgr
->kobj
, 0, sizeof(mgr
->kobj
));