drm_panel_backlight_quirks.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/array_size.h>
  3. #include <linux/dmi.h>
  4. #include <linux/mod_devicetable.h>
  5. #include <linux/module.h>
  6. #include <drm/drm_edid.h>
  7. #include <drm/drm_utils.h>
  8. struct drm_panel_min_backlight_quirk {
  9. struct {
  10. enum dmi_field field;
  11. const char * const value;
  12. } dmi_match;
  13. struct drm_edid_ident ident;
  14. u8 min_brightness;
  15. };
  16. static const struct drm_panel_min_backlight_quirk drm_panel_min_backlight_quirks[] = {
  17. /* 13 inch matte panel */
  18. {
  19. .dmi_match.field = DMI_BOARD_VENDOR,
  20. .dmi_match.value = "Framework",
  21. .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0bca),
  22. .ident.name = "NE135FBM-N41",
  23. .min_brightness = 0,
  24. },
  25. /* 13 inch glossy panel */
  26. {
  27. .dmi_match.field = DMI_BOARD_VENDOR,
  28. .dmi_match.value = "Framework",
  29. .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x095f),
  30. .ident.name = "NE135FBM-N41",
  31. .min_brightness = 0,
  32. },
  33. /* 13 inch 2.8k panel */
  34. {
  35. .dmi_match.field = DMI_BOARD_VENDOR,
  36. .dmi_match.value = "Framework",
  37. .ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0cb4),
  38. .ident.name = "NE135A1M-NY1",
  39. .min_brightness = 0,
  40. },
  41. };
  42. static bool drm_panel_min_backlight_quirk_matches(const struct drm_panel_min_backlight_quirk *quirk,
  43. const struct drm_edid *edid)
  44. {
  45. if (!dmi_match(quirk->dmi_match.field, quirk->dmi_match.value))
  46. return false;
  47. if (!drm_edid_match(edid, &quirk->ident))
  48. return false;
  49. return true;
  50. }
  51. /**
  52. * drm_get_panel_min_brightness_quirk - Get minimum supported brightness level for a panel.
  53. * @edid: EDID of the panel to check
  54. *
  55. * This function checks for platform specific (e.g. DMI based) quirks
  56. * providing info on the minimum backlight brightness for systems where this
  57. * cannot be probed correctly from the hard-/firm-ware.
  58. *
  59. * Returns:
  60. * A negative error value or
  61. * an override value in the range [0, 255] representing 0-100% to be scaled to
  62. * the drivers target range.
  63. */
  64. int drm_get_panel_min_brightness_quirk(const struct drm_edid *edid)
  65. {
  66. const struct drm_panel_min_backlight_quirk *quirk;
  67. size_t i;
  68. if (!IS_ENABLED(CONFIG_DMI))
  69. return -ENODATA;
  70. if (!edid)
  71. return -EINVAL;
  72. for (i = 0; i < ARRAY_SIZE(drm_panel_min_backlight_quirks); i++) {
  73. quirk = &drm_panel_min_backlight_quirks[i];
  74. if (drm_panel_min_backlight_quirk_matches(quirk, edid))
  75. return quirk->min_brightness;
  76. }
  77. return -ENODATA;
  78. }
  79. EXPORT_SYMBOL(drm_get_panel_min_brightness_quirk);
  80. MODULE_DESCRIPTION("Quirks for panel backlight overrides");
  81. MODULE_LICENSE("GPL");