18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Nokia Corporation 48c2ecf20Sopenharmony_ci * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Some code and ideas taken from drivers/video/omap/ driver 78c2ecf20Sopenharmony_ci * by Imre Deak. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define DSS_SUBSYS_NAME "MANAGER" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 168c2ecf20Sopenharmony_ci#include <linux/jiffies.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <video/omapfb_dss.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include "dss.h" 218c2ecf20Sopenharmony_ci#include "dss_features.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name); 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci struct omap_dss_device *dssdev = mgr->get_device(mgr); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ? 338c2ecf20Sopenharmony_ci dssdev->name : "<none>"); 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic int manager_display_match(struct omap_dss_device *dssdev, void *data) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci const char *str = data; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return sysfs_streq(dssdev->name, str); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic ssize_t manager_display_store(struct omap_overlay_manager *mgr, 448c2ecf20Sopenharmony_ci const char *buf, size_t size) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci int r = 0; 478c2ecf20Sopenharmony_ci size_t len = size; 488c2ecf20Sopenharmony_ci struct omap_dss_device *dssdev = NULL; 498c2ecf20Sopenharmony_ci struct omap_dss_device *old_dssdev; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci if (buf[size-1] == '\n') 528c2ecf20Sopenharmony_ci --len; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci if (len > 0) 558c2ecf20Sopenharmony_ci dssdev = omap_dss_find_device((void *)buf, 568c2ecf20Sopenharmony_ci manager_display_match); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci if (len > 0 && dssdev == NULL) 598c2ecf20Sopenharmony_ci return -EINVAL; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci if (dssdev) { 628c2ecf20Sopenharmony_ci DSSDBG("display %s found\n", dssdev->name); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (omapdss_device_is_connected(dssdev)) { 658c2ecf20Sopenharmony_ci DSSERR("new display is already connected\n"); 668c2ecf20Sopenharmony_ci r = -EINVAL; 678c2ecf20Sopenharmony_ci goto put_device; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (omapdss_device_is_enabled(dssdev)) { 718c2ecf20Sopenharmony_ci DSSERR("new display is not disabled\n"); 728c2ecf20Sopenharmony_ci r = -EINVAL; 738c2ecf20Sopenharmony_ci goto put_device; 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci } 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci old_dssdev = mgr->get_device(mgr); 788c2ecf20Sopenharmony_ci if (old_dssdev) { 798c2ecf20Sopenharmony_ci if (omapdss_device_is_enabled(old_dssdev)) { 808c2ecf20Sopenharmony_ci DSSERR("old display is not disabled\n"); 818c2ecf20Sopenharmony_ci r = -EINVAL; 828c2ecf20Sopenharmony_ci goto put_device; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci old_dssdev->driver->disconnect(old_dssdev); 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci if (dssdev) { 898c2ecf20Sopenharmony_ci r = dssdev->driver->connect(dssdev); 908c2ecf20Sopenharmony_ci if (r) { 918c2ecf20Sopenharmony_ci DSSERR("failed to connect new device\n"); 928c2ecf20Sopenharmony_ci goto put_device; 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci old_dssdev = mgr->get_device(mgr); 968c2ecf20Sopenharmony_ci if (old_dssdev != dssdev) { 978c2ecf20Sopenharmony_ci DSSERR("failed to connect device to this manager\n"); 988c2ecf20Sopenharmony_ci dssdev->driver->disconnect(dssdev); 998c2ecf20Sopenharmony_ci goto put_device; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 1038c2ecf20Sopenharmony_ci if (r) { 1048c2ecf20Sopenharmony_ci DSSERR("failed to apply dispc config\n"); 1058c2ecf20Sopenharmony_ci goto put_device; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci } 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ciput_device: 1108c2ecf20Sopenharmony_ci if (dssdev) 1118c2ecf20Sopenharmony_ci omap_dss_put_device(dssdev); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return r ? r : size; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, 1178c2ecf20Sopenharmony_ci char *buf) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, 1278c2ecf20Sopenharmony_ci const char *buf, size_t size) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 1308c2ecf20Sopenharmony_ci u32 color; 1318c2ecf20Sopenharmony_ci int r; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci r = kstrtouint(buf, 0, &color); 1348c2ecf20Sopenharmony_ci if (r) 1358c2ecf20Sopenharmony_ci return r; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci info.default_color = color; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 1428c2ecf20Sopenharmony_ci if (r) 1438c2ecf20Sopenharmony_ci return r; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 1468c2ecf20Sopenharmony_ci if (r) 1478c2ecf20Sopenharmony_ci return r; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci return size; 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic const char *trans_key_type_str[] = { 1538c2ecf20Sopenharmony_ci "gfx-destination", 1548c2ecf20Sopenharmony_ci "video-source", 1558c2ecf20Sopenharmony_ci}; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, 1588c2ecf20Sopenharmony_ci char *buf) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci enum omap_dss_trans_key_type key_type; 1618c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci key_type = info.trans_key_type; 1668c2ecf20Sopenharmony_ci BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, 1728c2ecf20Sopenharmony_ci const char *buf, size_t size) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 1758c2ecf20Sopenharmony_ci int r; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci r = sysfs_match_string(trans_key_type_str, buf); 1788c2ecf20Sopenharmony_ci if (r < 0) 1798c2ecf20Sopenharmony_ci return r; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci info.trans_key_type = r; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 1868c2ecf20Sopenharmony_ci if (r) 1878c2ecf20Sopenharmony_ci return r; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 1908c2ecf20Sopenharmony_ci if (r) 1918c2ecf20Sopenharmony_ci return r; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci return size; 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, 1978c2ecf20Sopenharmony_ci char *buf) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key); 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, 2078c2ecf20Sopenharmony_ci const char *buf, size_t size) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2108c2ecf20Sopenharmony_ci u32 key_value; 2118c2ecf20Sopenharmony_ci int r; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci r = kstrtouint(buf, 0, &key_value); 2148c2ecf20Sopenharmony_ci if (r) 2158c2ecf20Sopenharmony_ci return r; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci info.trans_key = key_value; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 2228c2ecf20Sopenharmony_ci if (r) 2238c2ecf20Sopenharmony_ci return r; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 2268c2ecf20Sopenharmony_ci if (r) 2278c2ecf20Sopenharmony_ci return r; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci return size; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, 2338c2ecf20Sopenharmony_ci char *buf) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, 2438c2ecf20Sopenharmony_ci const char *buf, size_t size) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2468c2ecf20Sopenharmony_ci bool enable; 2478c2ecf20Sopenharmony_ci int r; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci r = strtobool(buf, &enable); 2508c2ecf20Sopenharmony_ci if (r) 2518c2ecf20Sopenharmony_ci return r; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci info.trans_enabled = enable; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 2588c2ecf20Sopenharmony_ci if (r) 2598c2ecf20Sopenharmony_ci return r; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 2628c2ecf20Sopenharmony_ci if (r) 2638c2ecf20Sopenharmony_ci return r; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci return size; 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic ssize_t manager_alpha_blending_enabled_show( 2698c2ecf20Sopenharmony_ci struct omap_overlay_manager *mgr, char *buf) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) 2748c2ecf20Sopenharmony_ci return -ENODEV; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%d\n", 2798c2ecf20Sopenharmony_ci info.partial_alpha_enabled); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_cistatic ssize_t manager_alpha_blending_enabled_store( 2838c2ecf20Sopenharmony_ci struct omap_overlay_manager *mgr, 2848c2ecf20Sopenharmony_ci const char *buf, size_t size) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 2878c2ecf20Sopenharmony_ci bool enable; 2888c2ecf20Sopenharmony_ci int r; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) 2918c2ecf20Sopenharmony_ci return -ENODEV; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci r = strtobool(buf, &enable); 2948c2ecf20Sopenharmony_ci if (r) 2958c2ecf20Sopenharmony_ci return r; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci info.partial_alpha_enabled = enable; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 3028c2ecf20Sopenharmony_ci if (r) 3038c2ecf20Sopenharmony_ci return r; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 3068c2ecf20Sopenharmony_ci if (r) 3078c2ecf20Sopenharmony_ci return r; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci return size; 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, 3138c2ecf20Sopenharmony_ci char *buf) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable); 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_cistatic ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, 3238c2ecf20Sopenharmony_ci const char *buf, size_t size) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 3268c2ecf20Sopenharmony_ci int r; 3278c2ecf20Sopenharmony_ci bool enable; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci if (!dss_has_feature(FEAT_CPR)) 3308c2ecf20Sopenharmony_ci return -ENODEV; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci r = strtobool(buf, &enable); 3338c2ecf20Sopenharmony_ci if (r) 3348c2ecf20Sopenharmony_ci return r; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (info.cpr_enable == enable) 3398c2ecf20Sopenharmony_ci return size; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci info.cpr_enable = enable; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 3448c2ecf20Sopenharmony_ci if (r) 3458c2ecf20Sopenharmony_ci return r; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 3488c2ecf20Sopenharmony_ci if (r) 3498c2ecf20Sopenharmony_ci return r; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci return size; 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_cistatic ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, 3558c2ecf20Sopenharmony_ci char *buf) 3568c2ecf20Sopenharmony_ci{ 3578c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci return snprintf(buf, PAGE_SIZE, 3628c2ecf20Sopenharmony_ci "%d %d %d %d %d %d %d %d %d\n", 3638c2ecf20Sopenharmony_ci info.cpr_coefs.rr, 3648c2ecf20Sopenharmony_ci info.cpr_coefs.rg, 3658c2ecf20Sopenharmony_ci info.cpr_coefs.rb, 3668c2ecf20Sopenharmony_ci info.cpr_coefs.gr, 3678c2ecf20Sopenharmony_ci info.cpr_coefs.gg, 3688c2ecf20Sopenharmony_ci info.cpr_coefs.gb, 3698c2ecf20Sopenharmony_ci info.cpr_coefs.br, 3708c2ecf20Sopenharmony_ci info.cpr_coefs.bg, 3718c2ecf20Sopenharmony_ci info.cpr_coefs.bb); 3728c2ecf20Sopenharmony_ci} 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_cistatic ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, 3758c2ecf20Sopenharmony_ci const char *buf, size_t size) 3768c2ecf20Sopenharmony_ci{ 3778c2ecf20Sopenharmony_ci struct omap_overlay_manager_info info; 3788c2ecf20Sopenharmony_ci struct omap_dss_cpr_coefs coefs; 3798c2ecf20Sopenharmony_ci int r, i; 3808c2ecf20Sopenharmony_ci s16 *arr; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci if (!dss_has_feature(FEAT_CPR)) 3838c2ecf20Sopenharmony_ci return -ENODEV; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", 3868c2ecf20Sopenharmony_ci &coefs.rr, &coefs.rg, &coefs.rb, 3878c2ecf20Sopenharmony_ci &coefs.gr, &coefs.gg, &coefs.gb, 3888c2ecf20Sopenharmony_ci &coefs.br, &coefs.bg, &coefs.bb) != 9) 3898c2ecf20Sopenharmony_ci return -EINVAL; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, 3928c2ecf20Sopenharmony_ci coefs.gr, coefs.gg, coefs.gb, 3938c2ecf20Sopenharmony_ci coefs.br, coefs.bg, coefs.bb }; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci for (i = 0; i < 9; ++i) { 3968c2ecf20Sopenharmony_ci if (arr[i] < -512 || arr[i] > 511) 3978c2ecf20Sopenharmony_ci return -EINVAL; 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci mgr->get_manager_info(mgr, &info); 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci info.cpr_coefs = coefs; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci r = mgr->set_manager_info(mgr, &info); 4058c2ecf20Sopenharmony_ci if (r) 4068c2ecf20Sopenharmony_ci return r; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci r = mgr->apply(mgr); 4098c2ecf20Sopenharmony_ci if (r) 4108c2ecf20Sopenharmony_ci return r; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci return size; 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_cistruct manager_attribute { 4168c2ecf20Sopenharmony_ci struct attribute attr; 4178c2ecf20Sopenharmony_ci ssize_t (*show)(struct omap_overlay_manager *, char *); 4188c2ecf20Sopenharmony_ci ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t); 4198c2ecf20Sopenharmony_ci}; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci#define MANAGER_ATTR(_name, _mode, _show, _store) \ 4228c2ecf20Sopenharmony_ci struct manager_attribute manager_attr_##_name = \ 4238c2ecf20Sopenharmony_ci __ATTR(_name, _mode, _show, _store) 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cistatic MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); 4268c2ecf20Sopenharmony_cistatic MANAGER_ATTR(display, S_IRUGO|S_IWUSR, 4278c2ecf20Sopenharmony_ci manager_display_show, manager_display_store); 4288c2ecf20Sopenharmony_cistatic MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, 4298c2ecf20Sopenharmony_ci manager_default_color_show, manager_default_color_store); 4308c2ecf20Sopenharmony_cistatic MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, 4318c2ecf20Sopenharmony_ci manager_trans_key_type_show, manager_trans_key_type_store); 4328c2ecf20Sopenharmony_cistatic MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, 4338c2ecf20Sopenharmony_ci manager_trans_key_value_show, manager_trans_key_value_store); 4348c2ecf20Sopenharmony_cistatic MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, 4358c2ecf20Sopenharmony_ci manager_trans_key_enabled_show, 4368c2ecf20Sopenharmony_ci manager_trans_key_enabled_store); 4378c2ecf20Sopenharmony_cistatic MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, 4388c2ecf20Sopenharmony_ci manager_alpha_blending_enabled_show, 4398c2ecf20Sopenharmony_ci manager_alpha_blending_enabled_store); 4408c2ecf20Sopenharmony_cistatic MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, 4418c2ecf20Sopenharmony_ci manager_cpr_enable_show, 4428c2ecf20Sopenharmony_ci manager_cpr_enable_store); 4438c2ecf20Sopenharmony_cistatic MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, 4448c2ecf20Sopenharmony_ci manager_cpr_coef_show, 4458c2ecf20Sopenharmony_ci manager_cpr_coef_store); 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_cistatic struct attribute *manager_sysfs_attrs[] = { 4498c2ecf20Sopenharmony_ci &manager_attr_name.attr, 4508c2ecf20Sopenharmony_ci &manager_attr_display.attr, 4518c2ecf20Sopenharmony_ci &manager_attr_default_color.attr, 4528c2ecf20Sopenharmony_ci &manager_attr_trans_key_type.attr, 4538c2ecf20Sopenharmony_ci &manager_attr_trans_key_value.attr, 4548c2ecf20Sopenharmony_ci &manager_attr_trans_key_enabled.attr, 4558c2ecf20Sopenharmony_ci &manager_attr_alpha_blending_enabled.attr, 4568c2ecf20Sopenharmony_ci &manager_attr_cpr_enable.attr, 4578c2ecf20Sopenharmony_ci &manager_attr_cpr_coef.attr, 4588c2ecf20Sopenharmony_ci NULL 4598c2ecf20Sopenharmony_ci}; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_cistatic ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, 4628c2ecf20Sopenharmony_ci char *buf) 4638c2ecf20Sopenharmony_ci{ 4648c2ecf20Sopenharmony_ci struct omap_overlay_manager *manager; 4658c2ecf20Sopenharmony_ci struct manager_attribute *manager_attr; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci manager = container_of(kobj, struct omap_overlay_manager, kobj); 4688c2ecf20Sopenharmony_ci manager_attr = container_of(attr, struct manager_attribute, attr); 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci if (!manager_attr->show) 4718c2ecf20Sopenharmony_ci return -ENOENT; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci return manager_attr->show(manager, buf); 4748c2ecf20Sopenharmony_ci} 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_cistatic ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, 4778c2ecf20Sopenharmony_ci const char *buf, size_t size) 4788c2ecf20Sopenharmony_ci{ 4798c2ecf20Sopenharmony_ci struct omap_overlay_manager *manager; 4808c2ecf20Sopenharmony_ci struct manager_attribute *manager_attr; 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci manager = container_of(kobj, struct omap_overlay_manager, kobj); 4838c2ecf20Sopenharmony_ci manager_attr = container_of(attr, struct manager_attribute, attr); 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci if (!manager_attr->store) 4868c2ecf20Sopenharmony_ci return -ENOENT; 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci return manager_attr->store(manager, buf, size); 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic const struct sysfs_ops manager_sysfs_ops = { 4928c2ecf20Sopenharmony_ci .show = manager_attr_show, 4938c2ecf20Sopenharmony_ci .store = manager_attr_store, 4948c2ecf20Sopenharmony_ci}; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cistatic struct kobj_type manager_ktype = { 4978c2ecf20Sopenharmony_ci .sysfs_ops = &manager_sysfs_ops, 4988c2ecf20Sopenharmony_ci .default_attrs = manager_sysfs_attrs, 4998c2ecf20Sopenharmony_ci}; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ciint dss_manager_kobj_init(struct omap_overlay_manager *mgr, 5028c2ecf20Sopenharmony_ci struct platform_device *pdev) 5038c2ecf20Sopenharmony_ci{ 5048c2ecf20Sopenharmony_ci return kobject_init_and_add(&mgr->kobj, &manager_ktype, 5058c2ecf20Sopenharmony_ci &pdev->dev.kobj, "manager%d", mgr->id); 5068c2ecf20Sopenharmony_ci} 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_civoid dss_manager_kobj_uninit(struct omap_overlay_manager *mgr) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci kobject_del(&mgr->kobj); 5118c2ecf20Sopenharmony_ci kobject_put(&mgr->kobj); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci memset(&mgr->kobj, 0, sizeof(mgr->kobj)); 5148c2ecf20Sopenharmony_ci} 515