Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc2 529 lines 12 kB view raw
1/* 2 * Copyright (C) 2009 Nokia Corporation 3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 4 * 5 * Some code and ideas taken from drivers/video/omap/ driver 6 * by Imre Deak. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 as published by 10 * the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#define DSS_SUBSYS_NAME "MANAGER" 22 23#include <linux/kernel.h> 24#include <linux/slab.h> 25#include <linux/module.h> 26#include <linux/platform_device.h> 27#include <linux/jiffies.h> 28 29#include <video/omapdss.h> 30 31#include "dss.h" 32#include "dss_features.h" 33 34static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) 35{ 36 return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name); 37} 38 39static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) 40{ 41 struct omap_dss_device *dssdev = mgr->get_device(mgr); 42 43 return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ? 44 dssdev->name : "<none>"); 45} 46 47static ssize_t manager_display_store(struct omap_overlay_manager *mgr, 48 const char *buf, size_t size) 49{ 50 int r = 0; 51 size_t len = size; 52 struct omap_dss_device *dssdev = NULL; 53 struct omap_dss_device *old_dssdev; 54 55 int match(struct omap_dss_device *dssdev, void *data) 56 { 57 const char *str = data; 58 return sysfs_streq(dssdev->name, str); 59 } 60 61 if (buf[size-1] == '\n') 62 --len; 63 64 if (len > 0) 65 dssdev = omap_dss_find_device((void *)buf, match); 66 67 if (len > 0 && dssdev == NULL) 68 return -EINVAL; 69 70 if (dssdev) { 71 DSSDBG("display %s found\n", dssdev->name); 72 73 if (omapdss_device_is_connected(dssdev)) { 74 DSSERR("new display is already connected\n"); 75 r = -EINVAL; 76 goto put_device; 77 } 78 79 if (omapdss_device_is_enabled(dssdev)) { 80 DSSERR("new display is not disabled\n"); 81 r = -EINVAL; 82 goto put_device; 83 } 84 } 85 86 old_dssdev = mgr->get_device(mgr); 87 if (old_dssdev) { 88 if (omapdss_device_is_enabled(old_dssdev)) { 89 DSSERR("old display is not disabled\n"); 90 r = -EINVAL; 91 goto put_device; 92 } 93 94 old_dssdev->driver->disconnect(old_dssdev); 95 } 96 97 if (dssdev) { 98 r = dssdev->driver->connect(dssdev); 99 if (r) { 100 DSSERR("failed to connect new device\n"); 101 goto put_device; 102 } 103 104 old_dssdev = mgr->get_device(mgr); 105 if (old_dssdev != dssdev) { 106 DSSERR("failed to connect device to this manager\n"); 107 dssdev->driver->disconnect(dssdev); 108 goto put_device; 109 } 110 111 r = mgr->apply(mgr); 112 if (r) { 113 DSSERR("failed to apply dispc config\n"); 114 goto put_device; 115 } 116 } 117 118put_device: 119 if (dssdev) 120 omap_dss_put_device(dssdev); 121 122 return r ? r : size; 123} 124 125static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, 126 char *buf) 127{ 128 struct omap_overlay_manager_info info; 129 130 mgr->get_manager_info(mgr, &info); 131 132 return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color); 133} 134 135static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, 136 const char *buf, size_t size) 137{ 138 struct omap_overlay_manager_info info; 139 u32 color; 140 int r; 141 142 r = kstrtouint(buf, 0, &color); 143 if (r) 144 return r; 145 146 mgr->get_manager_info(mgr, &info); 147 148 info.default_color = color; 149 150 r = mgr->set_manager_info(mgr, &info); 151 if (r) 152 return r; 153 154 r = mgr->apply(mgr); 155 if (r) 156 return r; 157 158 return size; 159} 160 161static const char *trans_key_type_str[] = { 162 "gfx-destination", 163 "video-source", 164}; 165 166static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, 167 char *buf) 168{ 169 enum omap_dss_trans_key_type key_type; 170 struct omap_overlay_manager_info info; 171 172 mgr->get_manager_info(mgr, &info); 173 174 key_type = info.trans_key_type; 175 BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); 176 177 return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); 178} 179 180static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, 181 const char *buf, size_t size) 182{ 183 enum omap_dss_trans_key_type key_type; 184 struct omap_overlay_manager_info info; 185 int r; 186 187 for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST; 188 key_type < ARRAY_SIZE(trans_key_type_str); key_type++) { 189 if (sysfs_streq(buf, trans_key_type_str[key_type])) 190 break; 191 } 192 193 if (key_type == ARRAY_SIZE(trans_key_type_str)) 194 return -EINVAL; 195 196 mgr->get_manager_info(mgr, &info); 197 198 info.trans_key_type = key_type; 199 200 r = mgr->set_manager_info(mgr, &info); 201 if (r) 202 return r; 203 204 r = mgr->apply(mgr); 205 if (r) 206 return r; 207 208 return size; 209} 210 211static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, 212 char *buf) 213{ 214 struct omap_overlay_manager_info info; 215 216 mgr->get_manager_info(mgr, &info); 217 218 return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key); 219} 220 221static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, 222 const char *buf, size_t size) 223{ 224 struct omap_overlay_manager_info info; 225 u32 key_value; 226 int r; 227 228 r = kstrtouint(buf, 0, &key_value); 229 if (r) 230 return r; 231 232 mgr->get_manager_info(mgr, &info); 233 234 info.trans_key = key_value; 235 236 r = mgr->set_manager_info(mgr, &info); 237 if (r) 238 return r; 239 240 r = mgr->apply(mgr); 241 if (r) 242 return r; 243 244 return size; 245} 246 247static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, 248 char *buf) 249{ 250 struct omap_overlay_manager_info info; 251 252 mgr->get_manager_info(mgr, &info); 253 254 return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled); 255} 256 257static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, 258 const char *buf, size_t size) 259{ 260 struct omap_overlay_manager_info info; 261 bool enable; 262 int r; 263 264 r = strtobool(buf, &enable); 265 if (r) 266 return r; 267 268 mgr->get_manager_info(mgr, &info); 269 270 info.trans_enabled = enable; 271 272 r = mgr->set_manager_info(mgr, &info); 273 if (r) 274 return r; 275 276 r = mgr->apply(mgr); 277 if (r) 278 return r; 279 280 return size; 281} 282 283static ssize_t manager_alpha_blending_enabled_show( 284 struct omap_overlay_manager *mgr, char *buf) 285{ 286 struct omap_overlay_manager_info info; 287 288 if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) 289 return -ENODEV; 290 291 mgr->get_manager_info(mgr, &info); 292 293 return snprintf(buf, PAGE_SIZE, "%d\n", 294 info.partial_alpha_enabled); 295} 296 297static ssize_t manager_alpha_blending_enabled_store( 298 struct omap_overlay_manager *mgr, 299 const char *buf, size_t size) 300{ 301 struct omap_overlay_manager_info info; 302 bool enable; 303 int r; 304 305 if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) 306 return -ENODEV; 307 308 r = strtobool(buf, &enable); 309 if (r) 310 return r; 311 312 mgr->get_manager_info(mgr, &info); 313 314 info.partial_alpha_enabled = enable; 315 316 r = mgr->set_manager_info(mgr, &info); 317 if (r) 318 return r; 319 320 r = mgr->apply(mgr); 321 if (r) 322 return r; 323 324 return size; 325} 326 327static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, 328 char *buf) 329{ 330 struct omap_overlay_manager_info info; 331 332 mgr->get_manager_info(mgr, &info); 333 334 return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable); 335} 336 337static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, 338 const char *buf, size_t size) 339{ 340 struct omap_overlay_manager_info info; 341 int r; 342 bool enable; 343 344 if (!dss_has_feature(FEAT_CPR)) 345 return -ENODEV; 346 347 r = strtobool(buf, &enable); 348 if (r) 349 return r; 350 351 mgr->get_manager_info(mgr, &info); 352 353 if (info.cpr_enable == enable) 354 return size; 355 356 info.cpr_enable = enable; 357 358 r = mgr->set_manager_info(mgr, &info); 359 if (r) 360 return r; 361 362 r = mgr->apply(mgr); 363 if (r) 364 return r; 365 366 return size; 367} 368 369static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, 370 char *buf) 371{ 372 struct omap_overlay_manager_info info; 373 374 mgr->get_manager_info(mgr, &info); 375 376 return snprintf(buf, PAGE_SIZE, 377 "%d %d %d %d %d %d %d %d %d\n", 378 info.cpr_coefs.rr, 379 info.cpr_coefs.rg, 380 info.cpr_coefs.rb, 381 info.cpr_coefs.gr, 382 info.cpr_coefs.gg, 383 info.cpr_coefs.gb, 384 info.cpr_coefs.br, 385 info.cpr_coefs.bg, 386 info.cpr_coefs.bb); 387} 388 389static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, 390 const char *buf, size_t size) 391{ 392 struct omap_overlay_manager_info info; 393 struct omap_dss_cpr_coefs coefs; 394 int r, i; 395 s16 *arr; 396 397 if (!dss_has_feature(FEAT_CPR)) 398 return -ENODEV; 399 400 if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", 401 &coefs.rr, &coefs.rg, &coefs.rb, 402 &coefs.gr, &coefs.gg, &coefs.gb, 403 &coefs.br, &coefs.bg, &coefs.bb) != 9) 404 return -EINVAL; 405 406 arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, 407 coefs.gr, coefs.gg, coefs.gb, 408 coefs.br, coefs.bg, coefs.bb }; 409 410 for (i = 0; i < 9; ++i) { 411 if (arr[i] < -512 || arr[i] > 511) 412 return -EINVAL; 413 } 414 415 mgr->get_manager_info(mgr, &info); 416 417 info.cpr_coefs = coefs; 418 419 r = mgr->set_manager_info(mgr, &info); 420 if (r) 421 return r; 422 423 r = mgr->apply(mgr); 424 if (r) 425 return r; 426 427 return size; 428} 429 430struct manager_attribute { 431 struct attribute attr; 432 ssize_t (*show)(struct omap_overlay_manager *, char *); 433 ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t); 434}; 435 436#define MANAGER_ATTR(_name, _mode, _show, _store) \ 437 struct manager_attribute manager_attr_##_name = \ 438 __ATTR(_name, _mode, _show, _store) 439 440static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); 441static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, 442 manager_display_show, manager_display_store); 443static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, 444 manager_default_color_show, manager_default_color_store); 445static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, 446 manager_trans_key_type_show, manager_trans_key_type_store); 447static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, 448 manager_trans_key_value_show, manager_trans_key_value_store); 449static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, 450 manager_trans_key_enabled_show, 451 manager_trans_key_enabled_store); 452static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, 453 manager_alpha_blending_enabled_show, 454 manager_alpha_blending_enabled_store); 455static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, 456 manager_cpr_enable_show, 457 manager_cpr_enable_store); 458static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, 459 manager_cpr_coef_show, 460 manager_cpr_coef_store); 461 462 463static struct attribute *manager_sysfs_attrs[] = { 464 &manager_attr_name.attr, 465 &manager_attr_display.attr, 466 &manager_attr_default_color.attr, 467 &manager_attr_trans_key_type.attr, 468 &manager_attr_trans_key_value.attr, 469 &manager_attr_trans_key_enabled.attr, 470 &manager_attr_alpha_blending_enabled.attr, 471 &manager_attr_cpr_enable.attr, 472 &manager_attr_cpr_coef.attr, 473 NULL 474}; 475 476static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, 477 char *buf) 478{ 479 struct omap_overlay_manager *manager; 480 struct manager_attribute *manager_attr; 481 482 manager = container_of(kobj, struct omap_overlay_manager, kobj); 483 manager_attr = container_of(attr, struct manager_attribute, attr); 484 485 if (!manager_attr->show) 486 return -ENOENT; 487 488 return manager_attr->show(manager, buf); 489} 490 491static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, 492 const char *buf, size_t size) 493{ 494 struct omap_overlay_manager *manager; 495 struct manager_attribute *manager_attr; 496 497 manager = container_of(kobj, struct omap_overlay_manager, kobj); 498 manager_attr = container_of(attr, struct manager_attribute, attr); 499 500 if (!manager_attr->store) 501 return -ENOENT; 502 503 return manager_attr->store(manager, buf, size); 504} 505 506static const struct sysfs_ops manager_sysfs_ops = { 507 .show = manager_attr_show, 508 .store = manager_attr_store, 509}; 510 511static struct kobj_type manager_ktype = { 512 .sysfs_ops = &manager_sysfs_ops, 513 .default_attrs = manager_sysfs_attrs, 514}; 515 516int dss_manager_kobj_init(struct omap_overlay_manager *mgr, 517 struct platform_device *pdev) 518{ 519 return kobject_init_and_add(&mgr->kobj, &manager_ktype, 520 &pdev->dev.kobj, "manager%d", mgr->id); 521} 522 523void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr) 524{ 525 kobject_del(&mgr->kobj); 526 kobject_put(&mgr->kobj); 527 528 memset(&mgr->kobj, 0, sizeof(mgr->kobj)); 529}