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