brintos

brintos / linux-shallow public Read only

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