backlight.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Miscellaneous procedures for dealing with the PowerMac hardware.
  3. * Contains support for the backlight.
  4. *
  5. * Copyright (C) 2000 Benjamin Herrenschmidt
  6. * Copyright (C) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
  7. *
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/fb.h>
  11. #include <linux/backlight.h>
  12. #include <asm/prom.h>
  13. #include <asm/backlight.h>
  14. #define OLD_BACKLIGHT_MAX 15
  15. /* Protect the pmac_backlight variable */
  16. DEFINE_MUTEX(pmac_backlight_mutex);
  17. /* Main backlight storage
  18. *
  19. * Backlight drivers in this variable are required to have the "props"
  20. * attribute set and to have an update_status function.
  21. *
  22. * We can only store one backlight here, but since Apple laptops have only one
  23. * internal display, it doesn't matter. Other backlight drivers can be used
  24. * independently.
  25. *
  26. * Lock ordering:
  27. * pmac_backlight_mutex (global, main backlight)
  28. * pmac_backlight->sem (backlight class)
  29. */
  30. struct backlight_device *pmac_backlight;
  31. int pmac_has_backlight_type(const char *type)
  32. {
  33. struct device_node* bk_node = find_devices("backlight");
  34. if (bk_node) {
  35. char *prop = get_property(bk_node, "backlight-control", NULL);
  36. if (prop && strncmp(prop, type, strlen(type)) == 0)
  37. return 1;
  38. }
  39. return 0;
  40. }
  41. int pmac_backlight_curve_lookup(struct fb_info *info, int value)
  42. {
  43. int level = (FB_BACKLIGHT_LEVELS - 1);
  44. if (info && info->bl_dev) {
  45. int i, max = 0;
  46. /* Look for biggest value */
  47. for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
  48. max = max((int)info->bl_curve[i], max);
  49. /* Look for nearest value */
  50. for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
  51. int diff = abs(info->bl_curve[i] - value);
  52. if (diff < max) {
  53. max = diff;
  54. level = i;
  55. }
  56. }
  57. }
  58. return level;
  59. }
  60. static void pmac_backlight_key(int direction)
  61. {
  62. mutex_lock(&pmac_backlight_mutex);
  63. if (pmac_backlight) {
  64. struct backlight_properties *props;
  65. int brightness;
  66. down(&pmac_backlight->sem);
  67. props = pmac_backlight->props;
  68. brightness = props->brightness +
  69. ((direction?-1:1) * (props->max_brightness / 15));
  70. if (brightness < 0)
  71. brightness = 0;
  72. else if (brightness > props->max_brightness)
  73. brightness = props->max_brightness;
  74. props->brightness = brightness;
  75. props->update_status(pmac_backlight);
  76. up(&pmac_backlight->sem);
  77. }
  78. mutex_unlock(&pmac_backlight_mutex);
  79. }
  80. void pmac_backlight_key_up()
  81. {
  82. pmac_backlight_key(0);
  83. }
  84. void pmac_backlight_key_down()
  85. {
  86. pmac_backlight_key(1);
  87. }
  88. int pmac_backlight_set_legacy_brightness(int brightness)
  89. {
  90. int error = -ENXIO;
  91. mutex_lock(&pmac_backlight_mutex);
  92. if (pmac_backlight) {
  93. struct backlight_properties *props;
  94. down(&pmac_backlight->sem);
  95. props = pmac_backlight->props;
  96. props->brightness = brightness *
  97. (props->max_brightness + 1) /
  98. (OLD_BACKLIGHT_MAX + 1);
  99. if (props->brightness > props->max_brightness)
  100. props->brightness = props->max_brightness;
  101. else if (props->brightness < 0)
  102. props->brightness = 0;
  103. props->update_status(pmac_backlight);
  104. up(&pmac_backlight->sem);
  105. error = 0;
  106. }
  107. mutex_unlock(&pmac_backlight_mutex);
  108. return error;
  109. }
  110. int pmac_backlight_get_legacy_brightness()
  111. {
  112. int result = -ENXIO;
  113. mutex_lock(&pmac_backlight_mutex);
  114. if (pmac_backlight) {
  115. struct backlight_properties *props;
  116. down(&pmac_backlight->sem);
  117. props = pmac_backlight->props;
  118. result = props->brightness *
  119. (OLD_BACKLIGHT_MAX + 1) /
  120. (props->max_brightness + 1);
  121. up(&pmac_backlight->sem);
  122. }
  123. mutex_unlock(&pmac_backlight_mutex);
  124. return result;
  125. }