0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/dmi.h>
0012 #include <linux/module.h>
0013 #include <drm/drm_connector.h>
0014 #include <drm/drm_utils.h>
0015
0016 #ifdef CONFIG_DMI
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 struct drm_dmi_panel_orientation_data {
0027 int width;
0028 int height;
0029 const char * const *bios_dates;
0030 int orientation;
0031 };
0032
0033 static const struct drm_dmi_panel_orientation_data asus_t100ha = {
0034 .width = 800,
0035 .height = 1280,
0036 .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
0037 };
0038
0039 static const struct drm_dmi_panel_orientation_data gpd_micropc = {
0040 .width = 720,
0041 .height = 1280,
0042 .bios_dates = (const char * const []){ "04/26/2019",
0043 NULL },
0044 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0045 };
0046
0047 static const struct drm_dmi_panel_orientation_data gpd_pocket = {
0048 .width = 1200,
0049 .height = 1920,
0050 .bios_dates = (const char * const []){ "05/26/2017", "06/28/2017",
0051 "07/05/2017", "08/07/2017", NULL },
0052 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0053 };
0054
0055 static const struct drm_dmi_panel_orientation_data gpd_pocket2 = {
0056 .width = 1200,
0057 .height = 1920,
0058 .bios_dates = (const char * const []){ "06/28/2018", "08/28/2018",
0059 "12/07/2018", NULL },
0060 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0061 };
0062
0063 static const struct drm_dmi_panel_orientation_data gpd_win = {
0064 .width = 720,
0065 .height = 1280,
0066 .bios_dates = (const char * const []){
0067 "10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016",
0068 "02/21/2017", "03/20/2017", "05/25/2017", NULL },
0069 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0070 };
0071
0072 static const struct drm_dmi_panel_orientation_data gpd_win2 = {
0073 .width = 720,
0074 .height = 1280,
0075 .bios_dates = (const char * const []){
0076 "12/07/2017", "05/24/2018", "06/29/2018", NULL },
0077 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0078 };
0079
0080 static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
0081 .width = 800,
0082 .height = 1280,
0083 .bios_dates = (const char * const []){ "10/16/2015", NULL },
0084 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0085 };
0086
0087 static const struct drm_dmi_panel_orientation_data onegx1_pro = {
0088 .width = 1200,
0089 .height = 1920,
0090 .bios_dates = (const char * const []){ "12/17/2020", NULL },
0091 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0092 };
0093
0094 static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = {
0095 .width = 720,
0096 .height = 1280,
0097 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0098 };
0099
0100 static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = {
0101 .width = 800,
0102 .height = 1280,
0103 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0104 };
0105
0106 static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
0107 .width = 1200,
0108 .height = 1920,
0109 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0110 };
0111
0112 static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = {
0113 .width = 1280,
0114 .height = 1920,
0115 .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
0116 };
0117
0118 static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = {
0119 .width = 1600,
0120 .height = 2560,
0121 .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
0122 };
0123
0124 static const struct dmi_system_id orientation_data[] = {
0125 {
0126 .matches = {
0127 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
0128 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
0129 },
0130 .driver_data = (void *)&lcd800x1280_rightside_up,
0131 }, {
0132 .matches = {
0133 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0134 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
0135 },
0136 .driver_data = (void *)&asus_t100ha,
0137 }, {
0138 .matches = {
0139 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0140 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T101HA"),
0141 },
0142 .driver_data = (void *)&lcd800x1280_rightside_up,
0143 }, {
0144 .matches = {
0145 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0146 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"),
0147 },
0148 .driver_data = (void *)&lcd800x1280_rightside_up,
0149 }, {
0150 .matches = {
0151 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYADEVICE"),
0152 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"),
0153 },
0154 .driver_data = (void *)&lcd800x1280_rightside_up,
0155 }, {
0156 .matches = {
0157 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
0158 DMI_MATCH(DMI_BOARD_NAME, "NEXT"),
0159 },
0160 .driver_data = (void *)&lcd800x1280_rightside_up,
0161 }, {
0162 .matches = {
0163 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
0164 DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
0165
0166 DMI_MATCH(DMI_BIOS_DATE, "05/07/2016"),
0167 },
0168 .driver_data = (void *)&lcd1200x1920_rightside_up,
0169 }, {
0170 .matches = {
0171 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
0172 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Hi10 pro tablet"),
0173 },
0174 .driver_data = (void *)&lcd1200x1920_rightside_up,
0175 }, {
0176 .matches = {
0177 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
0178 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
0179 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
0180 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
0181 },
0182 .driver_data = (void *)&gpd_micropc,
0183 }, {
0184 .matches = {
0185 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
0186 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"),
0187 },
0188 .driver_data = (void *)&lcd720x1280_rightside_up,
0189 }, {
0190 .matches = {
0191 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
0192 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"),
0193 },
0194 .driver_data = (void *)&lcd800x1280_rightside_up,
0195 }, {
0196
0197
0198
0199
0200
0201 .matches = {
0202 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0203 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
0204 DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
0205 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
0206 },
0207 .driver_data = (void *)&gpd_pocket,
0208 }, {
0209 .matches = {
0210 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
0211 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
0212 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
0213 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
0214 },
0215 .driver_data = (void *)&gpd_pocket2,
0216 }, {
0217 .matches = {
0218 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0219 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
0220 DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
0221 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
0222 },
0223 .driver_data = (void *)&gpd_win,
0224 }, {
0225 .matches = {
0226 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
0227 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
0228 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
0229 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
0230 },
0231 .driver_data = (void *)&gpd_win2,
0232 }, {
0233 .matches = {
0234 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
0235 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03")
0236 },
0237 .driver_data = (void *)&lcd720x1280_rightside_up,
0238 }, {
0239 .matches = {
0240 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
0241 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
0242 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
0243 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
0244 },
0245 .driver_data = (void *)&itworks_tw891,
0246 }, {
0247 .matches = {
0248 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "KD Interactive"),
0249 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Kurio Smart"),
0250 DMI_EXACT_MATCH(DMI_BOARD_NAME, "KDM960BCP"),
0251 },
0252 .driver_data = (void *)&lcd800x1280_rightside_up,
0253 }, {
0254
0255
0256
0257
0258 .matches = {
0259 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0260 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80SG"),
0261 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
0262 },
0263 .driver_data = (void *)&lcd800x1280_rightside_up,
0264 }, {
0265 .matches = {
0266 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0267 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
0268 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
0269 },
0270 .driver_data = (void *)&lcd800x1280_rightside_up,
0271 }, {
0272 .matches = {
0273 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0274 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
0275 },
0276 .driver_data = (void *)&lcd800x1280_rightside_up,
0277 }, {
0278 .matches = {
0279 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0280 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
0281 },
0282 .driver_data = (void *)&lcd1200x1920_rightside_up,
0283 }, {
0284 .matches = {
0285
0286 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
0287 },
0288 .driver_data = (void *)&lcd1200x1920_rightside_up,
0289 }, {
0290 .matches = {
0291
0292
0293
0294
0295
0296
0297 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
0298 DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
0299 DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
0300
0301 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
0302 },
0303 .driver_data = (void *)&lcd1200x1920_rightside_up,
0304 }, {
0305 .matches = {
0306 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
0307 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"),
0308 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"),
0309 },
0310 .driver_data = (void *)&onegx1_pro,
0311 }, {
0312 .matches = {
0313 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."),
0314 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"),
0315 },
0316 .driver_data = (void *)&lcd1600x2560_leftside_up,
0317 }, {
0318 .matches = {
0319 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
0320 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"),
0321 },
0322 .driver_data = (void *)&lcd1280x1920_rightside_up,
0323 }, {
0324 .matches = {
0325 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
0326 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
0327 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
0328 },
0329 .driver_data = (void *)&lcd800x1280_rightside_up,
0330 }, {
0331 .matches = {
0332 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
0333 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
0334 },
0335 .driver_data = (void *)&lcd800x1280_rightside_up,
0336 },
0337 {}
0338 };
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 int drm_get_panel_orientation_quirk(int width, int height)
0360 {
0361 const struct dmi_system_id *match;
0362 const struct drm_dmi_panel_orientation_data *data;
0363 const char *bios_date;
0364 int i;
0365
0366 for (match = dmi_first_match(orientation_data);
0367 match;
0368 match = dmi_first_match(match + 1)) {
0369 data = match->driver_data;
0370
0371 if (data->width != width ||
0372 data->height != height)
0373 continue;
0374
0375 if (!data->bios_dates)
0376 return data->orientation;
0377
0378 bios_date = dmi_get_system_info(DMI_BIOS_DATE);
0379 if (!bios_date)
0380 continue;
0381
0382 i = match_string(data->bios_dates, -1, bios_date);
0383 if (i >= 0)
0384 return data->orientation;
0385 }
0386
0387 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
0388 }
0389 EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
0390
0391 #else
0392
0393
0394 int drm_get_panel_orientation_quirk(int width, int height)
0395 {
0396 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
0397 }
0398 EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
0399
0400 #endif
0401
0402 MODULE_LICENSE("Dual MIT/GPL");