aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbsysfs.c
diff options
context:
space:
mode:
authorMichael Hanselmann <linux-kernel@hansmi.ch>2006-06-25 08:47:08 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:00:59 -0400
commit5474c120aafe78ca54bf272f7a01107c42da2b21 (patch)
treec1b002a27703ce92c816bfb9844752186e33d403 /drivers/video/fbsysfs.c
parent17660bdd5c1f1a165273c1a59cb5b87670a81cc4 (diff)
[PATCH] Rewritten backlight infrastructure for portable Apple computers
This patch contains a total rewrite of the backlight infrastructure for portable Apple computers. Backward compatibility is retained. A sysfs interface allows userland to control the brightness with more steps than before. Userland is allowed to upload a brightness curve for different monitors, similar to Mac OS X. [akpm@osdl.org: add needed exports] Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Richard Purdie <rpurdie@rpsys.net> Cc: "Antonino A. Daplas" <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/fbsysfs.c')
-rw-r--r--drivers/video/fbsysfs.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 34e07399756b..3ceb8c1b392e 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -18,6 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/console.h> 20#include <linux/console.h>
21#include <linux/module.h>
21 22
22/** 23/**
23 * framebuffer_alloc - creates a new frame buffer info structure 24 * framebuffer_alloc - creates a new frame buffer info structure
@@ -55,6 +56,10 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
55 56
56 info->device = dev; 57 info->device = dev;
57 58
59#ifdef CONFIG_FB_BACKLIGHT
60 mutex_init(&info->bl_mutex);
61#endif
62
58 return info; 63 return info;
59#undef PADDING 64#undef PADDING
60#undef BYTES_PER_LONG 65#undef BYTES_PER_LONG
@@ -414,6 +419,65 @@ static ssize_t show_fbstate(struct class_device *class_device, char *buf)
414 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); 419 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
415} 420}
416 421
422#ifdef CONFIG_FB_BACKLIGHT
423static ssize_t store_bl_curve(struct class_device *class_device,
424 const char *buf, size_t count)
425{
426 struct fb_info *fb_info = class_get_devdata(class_device);
427 u8 tmp_curve[FB_BACKLIGHT_LEVELS];
428 unsigned int i;
429
430 if (count != (FB_BACKLIGHT_LEVELS / 8 * 24))
431 return -EINVAL;
432
433 for (i = 0; i < (FB_BACKLIGHT_LEVELS / 8); ++i)
434 if (sscanf(&buf[i * 24],
435 "%2hhx %2hhx %2hhx %2hhx %2hhx %2hhx %2hhx %2hhx\n",
436 &tmp_curve[i * 8 + 0],
437 &tmp_curve[i * 8 + 1],
438 &tmp_curve[i * 8 + 2],
439 &tmp_curve[i * 8 + 3],
440 &tmp_curve[i * 8 + 4],
441 &tmp_curve[i * 8 + 5],
442 &tmp_curve[i * 8 + 6],
443 &tmp_curve[i * 8 + 7]) != 8)
444 return -EINVAL;
445
446 /* If there has been an error in the input data, we won't
447 * reach this loop.
448 */
449 mutex_lock(&fb_info->bl_mutex);
450 for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i)
451 fb_info->bl_curve[i] = tmp_curve[i];
452 mutex_unlock(&fb_info->bl_mutex);
453
454 return count;
455}
456
457static ssize_t show_bl_curve(struct class_device *class_device, char *buf)
458{
459 struct fb_info *fb_info = class_get_devdata(class_device);
460 ssize_t len = 0;
461 unsigned int i;
462
463 mutex_lock(&fb_info->bl_mutex);
464 for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
465 len += snprintf(&buf[len], PAGE_SIZE,
466 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
467 fb_info->bl_curve[i + 0],
468 fb_info->bl_curve[i + 1],
469 fb_info->bl_curve[i + 2],
470 fb_info->bl_curve[i + 3],
471 fb_info->bl_curve[i + 4],
472 fb_info->bl_curve[i + 5],
473 fb_info->bl_curve[i + 6],
474 fb_info->bl_curve[i + 7]);
475 mutex_unlock(&fb_info->bl_mutex);
476
477 return len;
478}
479#endif
480
417/* When cmap is added back in it should be a binary attribute 481/* When cmap is added back in it should be a binary attribute
418 * not a text one. Consideration should also be given to converting 482 * not a text one. Consideration should also be given to converting
419 * fbdev to use configfs instead of sysfs */ 483 * fbdev to use configfs instead of sysfs */
@@ -432,6 +496,9 @@ static struct class_device_attribute class_device_attrs[] = {
432 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), 496 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
433 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), 497 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
434 __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), 498 __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate),
499#ifdef CONFIG_FB_BACKLIGHT
500 __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve),
501#endif
435}; 502};
436 503
437int fb_init_class_device(struct fb_info *fb_info) 504int fb_init_class_device(struct fb_info *fb_info)
@@ -454,4 +521,25 @@ void fb_cleanup_class_device(struct fb_info *fb_info)
454 &class_device_attrs[i]); 521 &class_device_attrs[i]);
455} 522}
456 523
524#ifdef CONFIG_FB_BACKLIGHT
525/* This function generates a linear backlight curve
526 *
527 * 0: off
528 * 1-7: min
529 * 8-127: linear from min to max
530 */
531void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
532{
533 unsigned int i, flat, count, range = (max - min);
534
535 fb_info->bl_curve[0] = off;
457 536
537 for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
538 fb_info->bl_curve[flat] = min;
539
540 count = FB_BACKLIGHT_LEVELS * 15 / 16;
541 for (i = 0; i < count; ++i)
542 fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count);
543}
544EXPORT_SYMBOL_GPL(fb_bl_default_curve);
545#endif