mbp_nvidia_bl.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Backlight Driver for Nvidia 8600 in Macbook Pro
  3. *
  4. * Copyright (c) Red Hat <mjg@redhat.com>
  5. * Based on code from Pommed:
  6. * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
  7. * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
  8. * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. * This driver triggers SMIs which cause the firmware to change the
  15. * backlight brightness. This is icky in many ways, but it's impractical to
  16. * get at the firmware code in order to figure out what it's actually doing.
  17. */
  18. #include <linux/module.h>
  19. #include <linux/kernel.h>
  20. #include <linux/init.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/backlight.h>
  23. #include <linux/err.h>
  24. #include <linux/dmi.h>
  25. #include <linux/io.h>
  26. static struct backlight_device *mbp_backlight_device;
  27. static struct dmi_system_id __initdata mbp_device_table[] = {
  28. {
  29. .ident = "3,1",
  30. .matches = {
  31. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  32. DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
  33. },
  34. },
  35. {
  36. .ident = "3,2",
  37. .matches = {
  38. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  39. DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
  40. },
  41. },
  42. {
  43. .ident = "4,1",
  44. .matches = {
  45. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  46. DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
  47. },
  48. },
  49. { }
  50. };
  51. static int mbp_send_intensity(struct backlight_device *bd)
  52. {
  53. int intensity = bd->props.brightness;
  54. outb(0x04 | (intensity << 4), 0xb3);
  55. outb(0xbf, 0xb2);
  56. return 0;
  57. }
  58. static int mbp_get_intensity(struct backlight_device *bd)
  59. {
  60. outb(0x03, 0xb3);
  61. outb(0xbf, 0xb2);
  62. return inb(0xb3) >> 4;
  63. }
  64. static struct backlight_ops mbp_ops = {
  65. .get_brightness = mbp_get_intensity,
  66. .update_status = mbp_send_intensity,
  67. };
  68. static int __init mbp_init(void)
  69. {
  70. if (!dmi_check_system(mbp_device_table))
  71. return -ENODEV;
  72. if (!request_region(0xb2, 2, "Macbook Pro backlight"))
  73. return -ENXIO;
  74. mbp_backlight_device = backlight_device_register("mbp_backlight",
  75. NULL, NULL,
  76. &mbp_ops);
  77. if (IS_ERR(mbp_backlight_device)) {
  78. release_region(0xb2, 2);
  79. return PTR_ERR(mbp_backlight_device);
  80. }
  81. mbp_backlight_device->props.max_brightness = 15;
  82. mbp_backlight_device->props.brightness =
  83. mbp_get_intensity(mbp_backlight_device);
  84. backlight_update_status(mbp_backlight_device);
  85. return 0;
  86. }
  87. static void __exit mbp_exit(void)
  88. {
  89. backlight_device_unregister(mbp_backlight_device);
  90. release_region(0xb2, 2);
  91. }
  92. module_init(mbp_init);
  93. module_exit(mbp_exit);
  94. MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
  95. MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
  96. MODULE_LICENSE("GPL");
  97. MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1");
  98. MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2");
  99. MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1");