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