diff --git a/drivers/gpu/drm/panel/msm8916-generated/Kconfig b/drivers/gpu/drm/panel/msm8916-generated/Kconfig index 9d07cc04390052..2c5fff91ff874f 100644 --- a/drivers/gpu/drm/panel/msm8916-generated/Kconfig +++ b/drivers/gpu/drm/panel/msm8916-generated/Kconfig @@ -94,7 +94,11 @@ config DRM_PANEL_SAMSUNG_EA8061_AMS549BU19_ID400418 default DRM_PANEL_MSM8916_GENERATED config DRM_PANEL_SAMSUNG_EA8061V_AMS497EE01 - tristate "Samsung EA8061V AMS497EE01" + tristate "Samsung AMS497EE01 panel with EA8061V DSI video mode controller" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS default DRM_PANEL_MSM8916_GENERATED config DRM_PANEL_SAMSUNG_HX8389C_GH9607501A diff --git a/drivers/gpu/drm/panel/msm8916-generated/panel-samsung-ea8061v-ams497ee01.c b/drivers/gpu/drm/panel/msm8916-generated/panel-samsung-ea8061v-ams497ee01.c index 995320bcfce00e..877ad5e5fe1a97 100644 --- a/drivers/gpu/drm/panel/msm8916-generated/panel-samsung-ea8061v-ams497ee01.c +++ b/drivers/gpu/drm/panel/msm8916-generated/panel-samsung-ea8061v-ams497ee01.c @@ -2,23 +2,456 @@ // Copyright (c) 2023 FIXME // Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: // Copyright (c) 2013, The Linux Foundation. All rights reserved. (FIXME) +// +// Mostly based on s6e3fa2 and s6e63m0. Table values dumped from +// Samsung's SM-A500F android kernel +#include +#include +#include + +#include #include #include #include #include #include -#include -#include -#include + +#define EA8061V_AMS497EE01_NUM_GAMMA_LEVELS 62 +#define EA8061V_AMS497EE01_GAMMA_CMD_CNT 34 + +#define EA8061V_AMS497EE01_MIN_BRIGHTNESS 0 +#define EA8061V_AMS497EE01_MAX_BRIGHTNESS (EA8061V_AMS497EE01_NUM_GAMMA_LEVELS - 1) +#define EA8061V_AMS497EE01_DEFAULT_BRIGHTNESS 40 + +/* Commands from manufacturer */ +#define MCS_ACL_OFF 0x5c +#define MCS_ACL_ON 0x4c +#define MCS_ACL_CONTROL 0x55 +#define MCS_AID_CONTROL 0xb2 /* Samsung AMOLED Impulsive Driving */ +#define MCS_ACL_OPR_CONTROL 0xb5 +#define MCS_ELVSS_CONTROL 0xb6 /* Amoled negative power supply */ +#define MCS_TSET 0xb8 /* Set reference conditions */ +#define MCS_GAMMA 0xca +#define MCS_GAMMA_UPDATE 0xf7 + +/* Which ELVSS sequence to use for which candela level. + */ +static const u8 map_candela_to_elvss[EA8061V_AMS497EE01_NUM_GAMMA_LEVELS] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 3, 4, 4, 5, 6, + 7, 7, 7, 8, 9, 10, + 11, 11, 11, 12, 13, 14, 15, 16, 17 +}; + +static const u8 seq_ea8061v_ams497ee01_lux[EA8061V_AMS497EE01_NUM_GAMMA_LEVELS][EA8061V_AMS497EE01_GAMMA_CMD_CNT] = { + { MCS_GAMMA, + 0x00, 0x92, 0x00, 0xac, 0x00, 0x7e, 0x8a, 0x8f, 0x8b, + 0x8d, 0x91, 0x8d, 0x96, 0xa1, 0x99, 0x9b, 0xa5, 0x00, + 0x9c, 0x95, 0xa1, 0x8d, 0x9d, 0xa3, 0xa1, 0xba, 0xbb, + 0xec, 0xbd, 0xd5, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x93, 0x00, 0xac, 0x00, 0x7e, 0x8b, 0x8e, 0x8b, + 0x8d, 0x90, 0x8c, 0x93, 0x9e, 0x96, 0x94, 0xa1, 0x00, + 0x96, 0x96, 0xa2, 0x8d, 0x9e, 0xa2, 0xa1, 0xb9, 0xba, + 0xe1, 0xb4, 0xcd, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x94, 0x00, 0xac, 0x00, 0x7f, 0x8a, 0x8d, 0x8a, + 0x89, 0x8e, 0x8a, 0x92, 0x9d, 0x95, 0x95, 0xa1, 0x00, + 0x97, 0x97, 0xa1, 0x8e, 0x98, 0xa0, 0x9d, 0xb3, 0xb7, + 0xe0, 0xb3, 0xcb, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x94, 0x00, 0xac, 0x00, 0x7f, 0x8b, 0x8d, 0x8b, + 0x89, 0x8e, 0x8a, 0x92, 0x9c, 0x94, 0x93, 0x9e, 0x00, + 0x96, 0x95, 0x9f, 0x8d, 0x98, 0xa0, 0x9c, 0xb2, 0xb4, + 0xe9, 0xba, 0xd2, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x94, 0x00, 0xac, 0x00, 0x7f, 0x8a, 0x8c, 0x8b, + 0x89, 0x8d, 0x89, 0x91, 0x9b, 0x94, 0x93, 0x9e, 0x00, + 0x95, 0x94, 0x9e, 0x8c, 0x97, 0x9e, 0x9c, 0xb3, 0xb4, + 0xde, 0xb1, 0xc5, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x95, 0x00, 0xac, 0x00, 0x80, 0x89, 0x8c, 0x8a, + 0x8a, 0x8d, 0x8b, 0x90, 0x99, 0x92, 0x8f, 0x9a, 0x00, + 0x93, 0x93, 0x9e, 0x8c, 0x99, 0x9e, 0x9c, 0xb1, 0xb3, + 0xd9, 0xae, 0xbf, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x96, 0x00, 0xac, 0x00, 0x81, 0x89, 0x8c, 0x8a, + 0x89, 0x8b, 0x89, 0x90, 0x98, 0x92, 0x92, 0x9c, 0x00, + 0x95, 0x90, 0x9b, 0x88, 0x98, 0x9e, 0x9c, 0xb1, 0xb1, + 0xdd, 0xb0, 0xc3, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x96, 0x00, 0xac, 0x00, 0x81, 0x89, 0x8c, 0x8a, + 0x8a, 0x8b, 0x8a, 0x8e, 0x96, 0x91, 0x92, 0x9b, 0x00, + 0x97, 0x92, 0x9b, 0x8a, 0x92, 0x9d, 0x96, 0xae, 0xae, + 0xdc, 0xb0, 0xc2, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x96, 0x00, 0xac, 0x00, 0x81, 0x89, 0x8b, 0x88, + 0x8b, 0x8c, 0x8b, 0x8f, 0x96, 0x92, 0x8f, 0x99, 0x00, + 0x93, 0x91, 0x9b, 0x88, 0x93, 0x9a, 0x98, 0xaf, 0xad, + 0xe0, 0xb3, 0xc6, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x96, 0x00, 0xac, 0x00, 0x81, 0x8a, 0x8b, 0x89, + 0x89, 0x8b, 0x87, 0x91, 0x97, 0x94, 0x8b, 0x96, 0x00, + 0x91, 0x90, 0x9b, 0x89, 0x93, 0x9b, 0x95, 0xad, 0xac, + 0xdf, 0xb3, 0xc5, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8b, 0x88, + 0x89, 0x8b, 0x88, 0x90, 0x96, 0x92, 0x8f, 0x98, 0x00, + 0x94, 0x8d, 0x98, 0x87, 0x93, 0x9a, 0x95, 0xad, 0xac, + 0xdf, 0xb3, 0xc5, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8b, 0x88, + 0x8a, 0x8b, 0x88, 0x90, 0x96, 0x92, 0x8c, 0x95, 0x00, + 0x92, 0x8d, 0x98, 0x87, 0x92, 0x9a, 0x93, 0xae, 0xac, + 0xd9, 0xae, 0xbf, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8b, 0x88, + 0x8a, 0x8b, 0x88, 0x8e, 0x93, 0x90, 0x8e, 0x97, 0x00, + 0x93, 0x8d, 0x98, 0x88, 0x92, 0x9a, 0x93, 0xa7, 0xa6, + 0xea, 0xbb, 0xd1, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8b, 0x8a, + 0x88, 0x8a, 0x87, 0x8c, 0x93, 0x90, 0x8e, 0x96, 0x00, + 0x93, 0x8a, 0x95, 0x84, 0x90, 0x98, 0x8f, 0xad, 0xab, + 0xdb, 0xb0, 0xc2, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8b, 0x8a, + 0x88, 0x8a, 0x87, 0x8d, 0x93, 0x91, 0x8b, 0x93, 0x00, + 0x91, 0x8e, 0x96, 0x88, 0x90, 0x98, 0x8e, 0xa6, 0xa5, + 0xe3, 0xb7, 0xca, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8b, 0x8a, + 0x88, 0x8a, 0x87, 0x8d, 0x93, 0x91, 0x8c, 0x93, 0x00, + 0x92, 0x89, 0x94, 0x83, 0x8c, 0x94, 0x8b, 0xab, 0xab, + 0xd2, 0xab, 0xba, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8b, 0x8a, + 0x88, 0x8a, 0x87, 0x8c, 0x91, 0x8e, 0x8d, 0x93, 0x00, + 0x92, 0x8c, 0x96, 0x86, 0x91, 0x98, 0x8f, 0xa6, 0xa6, + 0xe7, 0xba, 0xce, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8a, 0x89, + 0x89, 0x8a, 0x88, 0x8d, 0x92, 0x8f, 0x8d, 0x93, 0x00, + 0x92, 0x89, 0x93, 0x83, 0x8f, 0x97, 0x8f, 0xa4, 0xa4, + 0xd7, 0xae, 0xbf, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8b, 0x8a, + 0x88, 0x89, 0x87, 0x8d, 0x92, 0x8f, 0x8d, 0x92, 0x00, + 0x92, 0x89, 0x93, 0x83, 0x8c, 0x94, 0x8b, 0xa2, 0xa2, + 0xe7, 0xba, 0xce, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8a, 0x89, + 0x89, 0x8a, 0x88, 0x8d, 0x91, 0x90, 0x89, 0x8f, 0x00, + 0x8f, 0x8c, 0x95, 0x84, 0x8b, 0x94, 0x8a, 0xa2, 0xa0, + 0xe1, 0xb6, 0xc8, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8a, 0x89, + 0x89, 0x8a, 0x88, 0x8e, 0x91, 0x90, 0x89, 0x8f, 0x00, + 0x90, 0x88, 0x91, 0x81, 0x8c, 0x94, 0x8a, 0xa6, 0xa6, + 0xd6, 0xae, 0xbe, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8a, 0x89, + 0x89, 0x8a, 0x88, 0x8d, 0x90, 0x90, 0x89, 0x8f, 0x00, + 0x8f, 0x88, 0x91, 0x81, 0x8c, 0x93, 0x8a, 0xa7, 0xa6, + 0xd1, 0xaa, 0xb8, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x8a, 0x89, + 0x89, 0x8a, 0x88, 0x8e, 0x90, 0x90, 0x86, 0x8c, 0x00, + 0x8e, 0x87, 0x90, 0x7f, 0x8f, 0x96, 0x8e, 0xa2, 0xa0, + 0xd6, 0xad, 0xbd, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x88, 0x89, 0x87, 0x8d, 0x8f, 0x8f, 0x88, 0x8d, 0x00, + 0x90, 0x87, 0x90, 0x7f, 0x8f, 0x96, 0x8e, 0xa2, 0xa0, + 0xd6, 0xad, 0xbd, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x89, 0x87, 0x8c, 0x8f, 0x8f, 0x8a, 0x8d, 0x00, + 0x91, 0x88, 0x90, 0x81, 0x8b, 0x93, 0x8a, 0xa1, 0x9e, + 0xcf, 0xa9, 0xb7, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x89, 0x87, 0x8a, 0x8e, 0x8e, 0x89, 0x8c, 0x00, + 0x91, 0x87, 0x8f, 0x7f, 0x90, 0x96, 0x90, 0x99, 0x97, + 0xe0, 0xb5, 0xc8, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x89, 0x87, 0x8b, 0x8e, 0x8f, 0x89, 0x8c, 0x00, + 0x91, 0x87, 0x8f, 0x7f, 0x89, 0x91, 0x88, 0x9f, 0x9e, + 0xda, 0xb1, 0xc2, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x89, 0x87, 0x8b, 0x8e, 0x8f, 0x87, 0x89, 0x00, + 0x8f, 0x87, 0x8d, 0x7e, 0x8f, 0x95, 0x8d, 0x9a, 0x97, + 0xd4, 0xad, 0xbc, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x8a, 0x89, 0x88, 0x8a, 0x8e, 0x8e, 0x88, 0x89, 0x00, + 0x90, 0x81, 0x8a, 0x79, 0x93, 0x98, 0x92, 0x9b, 0x98, + 0xd4, 0xad, 0xbc, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x87, 0x89, 0x8d, 0x8d, 0x8a, 0x8b, 0x00, + 0x91, 0x81, 0x8a, 0x79, 0x93, 0x97, 0x92, 0x9b, 0x98, + 0xba, 0x9d, 0xa8, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x87, 0x8a, 0x8d, 0x8e, 0x86, 0x88, 0x00, + 0x8e, 0x87, 0x8d, 0x7d, 0x8e, 0x93, 0x8e, 0x94, 0x91, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x87, 0x8a, 0x8d, 0x8e, 0x87, 0x88, 0x00, + 0x8f, 0x82, 0x89, 0x79, 0x8d, 0x92, 0x8b, 0x97, 0x95, + 0xdf, 0xb5, 0xc7, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x87, 0x8b, 0x8d, 0x8e, 0x86, 0x88, 0x00, + 0x8f, 0x82, 0x88, 0x79, 0x8c, 0x92, 0x8b, 0x99, 0x96, + 0xd2, 0xad, 0xbc, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x8a, 0x8a, 0x89, + 0x89, 0x88, 0x87, 0x8b, 0x8d, 0x8e, 0x86, 0x87, 0x00, + 0x8f, 0x82, 0x88, 0x79, 0x8d, 0x92, 0x8c, 0x9b, 0x97, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x97, 0x00, 0xac, 0x00, 0x82, 0x89, 0x89, 0x88, + 0x8a, 0x89, 0x88, 0x8b, 0x8d, 0x8e, 0x86, 0x87, 0x00, + 0x8f, 0x83, 0x88, 0x7a, 0x8e, 0x92, 0x8d, 0x93, 0x8f, + 0xbc, 0xa1, 0xac, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0x9b, 0x00, 0xaf, 0x00, 0x87, 0x88, 0x89, 0x88, + 0x89, 0x88, 0x87, 0x8b, 0x8d, 0x8e, 0x87, 0x86, 0x00, + 0x8f, 0x83, 0x88, 0x7a, 0x8e, 0x92, 0x8d, 0x94, 0x90, + 0xa1, 0x91, 0x97, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xa0, 0x00, 0xb3, 0x00, 0x8d, 0x89, 0x89, 0x88, + 0x89, 0x88, 0x86, 0x8b, 0x8c, 0x8d, 0x85, 0x85, 0x00, + 0x8d, 0x84, 0x89, 0x7c, 0x8a, 0x8e, 0x89, 0x93, 0x8f, + 0xca, 0xa9, 0xb7, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xa4, 0x00, 0xb6, 0x00, 0x92, 0x88, 0x89, 0x89, + 0x88, 0x87, 0x86, 0x8a, 0x8b, 0x8b, 0x87, 0x86, 0x00, + 0x8c, 0x81, 0x86, 0x79, 0x89, 0x8e, 0x88, 0x9b, 0x98, + 0x81, 0x7d, 0x7d, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xa8, 0x00, 0xba, 0x00, 0x97, 0x88, 0x88, 0x88, + 0x88, 0x87, 0x86, 0x87, 0x8b, 0x8a, 0x8a, 0x88, 0x00, + 0x8f, 0x83, 0x88, 0x7d, 0x87, 0x8c, 0x87, 0x95, 0x91, + 0xa9, 0x95, 0x9d, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xad, 0x00, 0xbe, 0x00, 0x9d, 0x87, 0x88, 0x88, + 0x88, 0x87, 0x86, 0x8a, 0x8b, 0x8c, 0x86, 0x85, 0x00, + 0x89, 0x82, 0x88, 0x7d, 0x87, 0x8b, 0x87, 0x96, 0x91, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xb1, 0x00, 0xc1, 0x00, 0xa2, 0x87, 0x88, 0x88, + 0x88, 0x87, 0x86, 0x87, 0x89, 0x89, 0x87, 0x86, 0x00, + 0x8b, 0x80, 0x85, 0x7b, 0x8c, 0x8f, 0x8c, 0x8f, 0x8c, + 0xc4, 0xa5, 0xb2, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xb7, 0x00, 0xc5, 0x00, 0xa8, 0x86, 0x87, 0x87, + 0x88, 0x86, 0x85, 0x88, 0x89, 0x89, 0x87, 0x86, 0x00, + 0x8a, 0x81, 0x86, 0x7d, 0x8a, 0x8d, 0x88, 0x8f, 0x8c, + 0xb7, 0x9d, 0xa7, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xbc, 0x00, 0xc9, 0x00, 0xae, 0x86, 0x87, 0x87, + 0x87, 0x86, 0x85, 0x87, 0x88, 0x87, 0x86, 0x87, 0x00, + 0x8a, 0x80, 0x84, 0x7b, 0x8a, 0x8c, 0x88, 0x90, 0x8d, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xc1, 0x00, 0xcd, 0x00, 0xb4, 0x86, 0x87, 0x87, + 0x87, 0x86, 0x86, 0x86, 0x88, 0x87, 0x87, 0x86, 0x00, + 0x88, 0x82, 0x84, 0x7c, 0x85, 0x89, 0x86, 0x91, 0x8e, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xc6, 0x00, 0xd1, 0x00, 0xba, 0x85, 0x86, 0x86, + 0x86, 0x85, 0x85, 0x85, 0x86, 0x86, 0x88, 0x87, 0x00, + 0x89, 0x82, 0x86, 0x7d, 0x80, 0x86, 0x82, 0x91, 0x8e, + 0xb7, 0x9d, 0xa7, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xca, 0x00, 0xd4, 0x00, 0xbf, 0x86, 0x87, 0x87, + 0x86, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x84, 0x00, + 0x86, 0x82, 0x85, 0x7f, 0x80, 0x86, 0x82, 0x91, 0x8e, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xd0, 0x00, 0xd9, 0x00, 0xc6, 0x84, 0x85, 0x85, + 0x85, 0x84, 0x84, 0x83, 0x85, 0x84, 0x86, 0x85, 0x00, + 0x86, 0x7f, 0x82, 0x7c, 0x87, 0x8a, 0x87, 0x8e, 0x8a, + 0x9c, 0x8d, 0x92, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xd5, 0x00, 0xdd, 0x00, 0xcc, 0x85, 0x86, 0x86, + 0x85, 0x84, 0x84, 0x82, 0x84, 0x83, 0x86, 0x85, 0x00, + 0x85, 0x80, 0x83, 0x7e, 0x83, 0x86, 0x84, 0x8d, 0x89, + 0xa9, 0x95, 0x9d, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd3, 0x84, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x82, 0x83, 0x83, 0x86, 0x85, 0x00, + 0x85, 0x83, 0x85, 0x7f, 0x7f, 0x84, 0x81, 0x8f, 0x8b, + 0x8f, 0x85, 0x88, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x82, 0x83, 0x83, 0x86, 0x85, 0x00, + 0x85, 0x84, 0x85, 0x80, 0x7f, 0x83, 0x81, 0x8f, 0x8b, + 0x74, 0x75, 0x73, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x83, 0x84, 0x00, + 0x84, 0x82, 0x83, 0x7f, 0x7f, 0x81, 0x80, 0x8e, 0x8a, + 0x85, 0x81, 0x81, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x83, 0x84, 0x00, + 0x84, 0x7f, 0x80, 0x7b, 0x83, 0x85, 0x85, 0x87, 0x84, + 0xa5, 0x94, 0x9c, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x83, 0x83, 0x83, 0x82, 0x83, 0x83, 0x82, 0x82, 0x00, + 0x83, 0x82, 0x82, 0x7e, 0x82, 0x85, 0x85, 0x89, 0x85, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x83, 0x83, 0x83, 0x82, 0x83, 0x83, 0x83, 0x82, 0x00, + 0x84, 0x81, 0x82, 0x7d, 0x83, 0x85, 0x85, 0x86, 0x86, + 0x97, 0x8c, 0x91, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x84, 0x84, 0x84, + 0x82, 0x82, 0x82, 0x83, 0x84, 0x84, 0x84, 0x82, 0x00, + 0x84, 0x82, 0x82, 0x7e, 0x7e, 0x80, 0x80, 0x8d, 0x8b, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xda, 0x00, 0xe1, 0x00, 0xd2, 0x83, 0x84, 0x84, + 0x84, 0x84, 0x84, 0x82, 0x83, 0x83, 0x82, 0x82, 0x00, + 0x85, 0x82, 0x82, 0x7e, 0x84, 0x85, 0x85, 0x8b, 0x8a, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xe0, 0x00, 0xe6, 0x00, 0xda, 0x83, 0x83, 0x83, + 0x83, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x81, 0x00, + 0x84, 0x83, 0x83, 0x80, 0x81, 0x81, 0x81, 0x8b, 0x8a, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xe6, 0x00, 0xeb, 0x00, 0xe1, 0x82, 0x83, 0x83, + 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x00, + 0x83, 0x84, 0x84, 0x82, 0x83, 0x83, 0x83, 0x86, 0x85, + 0x89, 0x84, 0x86, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xec, 0x00, 0xf0, 0x00, 0xe8, 0x82, 0x83, 0x83, + 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x82, 0x82, 0x00, + 0x83, 0x81, 0x81, 0x80, 0x83, 0x83, 0x83, 0x86, 0x85, + 0x89, 0x84, 0x86, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xee, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x00, + 0x82, 0x81, 0x81, 0x80, 0x83, 0x83, 0x83, 0x86, 0x85, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x00, 0xf6, 0x00, 0xf8, 0x00, 0xf4, 0x82, 0x82, 0x82, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, + 0x81, 0x82, 0x82, 0x81, 0x7f, 0x7f, 0x7f, 0x86, 0x85, + 0x7b, 0x7c, 0x7b, 0x00, 0x00, 0x00 }, + { MCS_GAMMA, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x00, 0x00, 0x00 } +}; + +/* ELVSS (Amoled negative power supply) tables */ +#define EA8061V_AMS497EE01_NUM_ELVSS_SEQUENCES 18 +#define ELVSS_SEQUENCE_LEN 3 +static const u8 seq_ea8061v_ams497ee01_elvss[EA8061V_AMS497EE01_NUM_ELVSS_SEQUENCES][ELVSS_SEQUENCE_LEN] = { + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x9b }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x9a }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x99 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x98 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x97 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x96 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x95 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x94 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x93 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x92 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x91 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x90 }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8f }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8e }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8d }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8c }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8b }, + { MCS_ELVSS_CONTROL, MCS_ACL_OFF, 0x8a } +}; + +#define EA8061V_AMS497EE01_NUM_AID_LEVELS 42 +#define EA8061V_AMS497EE01_AID_CMD_CNT 5 +/* Which AID sequence to use for each candela level. + */ +static const u8 map_candela_to_aid[EA8061V_AMS497EE01_NUM_GAMMA_LEVELS] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 41, 41, + 41, 41 +}; + +static const u8 seq_ea8061v_ams497ee01_aid[EA8061V_AMS497EE01_NUM_AID_LEVELS][EA8061V_AMS497EE01_AID_CMD_CNT] = { + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xdf }, /* 95.63 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xd3 }, /* 94.71 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xc7 }, /* 93.79 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xbb }, /* 92.87 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xb0 }, /* 92.02 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0xa4 }, /* 91.10 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x99 }, /* 90.26 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x8d }, /* 89.34 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x82 }, /* 88.50 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x76 }, /* 87.58 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x6a }, /* 86.66 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x5f }, /* 85.81 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x52 }, /* 84.82 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x3b }, /* 83.05 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x31 }, /* 82.29 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x25 }, /* 81.37 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x18 }, /* 80.37 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x04, 0x01 }, /* 78.60 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0xf5 }, /* 77.68 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0xdb }, /* 75.69 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0xc5 }, /* 74.00 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0xb7 }, /* 72.93 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x9e }, /* 71.01 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x88 }, /* 69.33 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x64 }, /* 66.56 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x4b }, /* 64.64 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x32 }, /* 62.73 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x03, 0x0d }, /* 59.89 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0xe7 }, /* 56.98 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0xc2 }, /* 54.14 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0x9d }, /* 51.30 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0x79 }, /* 48.54 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0x45 }, /* 44.56 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x02, 0x13 }, /* 40.72 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x01, 0xe7 }, /* 37.35 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x01, 0xae }, /* 32.98 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x01, 0x76 }, /* 28.68 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x01, 0x39 }, /* 24.00 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x00, 0xf8 }, /* 19.02 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x00, 0xb4 }, /* 13.80 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x00, 0x63 }, /* 7.59 % */ + { MCS_AID_CONTROL, 0x00, 0x00, 0x00, 0x0a } /* 0.77 % */ +}; struct ea8061v_ams497ee01 { struct drm_panel panel; struct mipi_dsi_device *dsi; + + struct backlight_device *bl_dev; + struct regulator_bulk_data supplies[2]; struct gpio_desc *reset_gpio; + bool prepared; + bool enabled; }; static inline @@ -27,42 +460,223 @@ struct ea8061v_ams497ee01 *to_ea8061v_ams497ee01(struct drm_panel *panel) return container_of(panel, struct ea8061v_ams497ee01, panel); } -static void ea8061v_ams497ee01_reset(struct ea8061v_ams497ee01 *ctx) +static int ea8061v_ams497ee01_unlock(struct ea8061v_ams497ee01 *ctx, u8 lock) { - gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(20); - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - usleep_range(1000, 2000); - gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(20); + switch (lock) { + case 0xf0: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xf0, 0x5a, 0x5a); + break; + case 0xf1: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xf1, 0x5a, 0x5a); + break; + case 0xfc: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xfc, 0x5a, 0x5a); + break; + default: + return -EINVAL; + } + return 0; } -static int ea8061v_ams497ee01_on(struct ea8061v_ams497ee01 *ctx) +static int ea8061v_ams497ee01_lock(struct ea8061v_ams497ee01 *ctx, u8 lock) { + switch (lock) { + case 0xf0: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xf0, 0xa5, 0xa5); + break; + case 0xf1: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xf1, 0xa5, 0xa5); + break; + case 0xfc: + mipi_dsi_dcs_write_seq(ctx->dsi, 0xfc, 0xa5, 0xa5); + break; + default: + return -EINVAL; + } + return 0; +} + +static int ea8061v_ams497ee01_apply_gamma(struct ea8061v_ams497ee01 *ctx) +{ + mipi_dsi_dcs_write_seq(ctx->dsi, MCS_GAMMA_UPDATE, 0x01); + return 0; +} + +static int ea8061v_ams497ee01_update_aid(struct ea8061v_ams497ee01 *ctx, + unsigned int brightness) +{ + int ret; + int index = map_candela_to_aid[brightness]; + + ret = mipi_dsi_dcs_write_buffer(ctx->dsi, + seq_ea8061v_ams497ee01_aid[index], + EA8061V_AMS497EE01_AID_CMD_CNT); + if (ret < 0) + return ret; + return 0; +} + +static int ea8061v_ams497ee01_update_elvss(struct ea8061v_ams497ee01 *ctx, + unsigned int brightness) +{ + int ret; + int index = map_candela_to_elvss[brightness]; + + ret = mipi_dsi_dcs_write_buffer(ctx->dsi, + seq_ea8061v_ams497ee01_elvss[index], + ELVSS_SEQUENCE_LEN); + if (ret < 0) + return ret; + return 0; +} + +static int ea8061v_ams497ee01_update_gamma(struct ea8061v_ams497ee01 *ctx, + unsigned int brightness) +{ + int ret; + struct backlight_device *bl_dev = ctx->bl_dev; + + ret = mipi_dsi_dcs_write_buffer(ctx->dsi, + seq_ea8061v_ams497ee01_lux[brightness], + EA8061V_AMS497EE01_GAMMA_CMD_CNT); + if (ret < 0) + return ret; + + bl_dev->props.brightness = brightness; + + return 0; +} + +static int ea8061v_ams497ee01_set_brightness(struct backlight_device *bl_dev) +{ + struct ea8061v_ams497ee01 *ctx = bl_get_data(bl_dev); + unsigned int brightness = bl_dev->props.brightness; struct mipi_dsi_device *dsi = ctx->dsi; struct device *dev = &dsi->dev; int ret; + ret = ea8061v_ams497ee01_unlock(ctx, 0xf0); + if (ret < 0) { + dev_err(dev, "Failed to unlock 0xf0: %d\n", ret); + return ret; + } + ret = ea8061v_ams497ee01_unlock(ctx, 0xf1); + if (ret < 0) { + dev_err(dev, "Failed to unlock 0xf1: %d\n", ret); + return ret; + } + + /* aid/aor */ + ret = ea8061v_ams497ee01_update_aid(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to send aid sequence: %d\n", ret); + return ret; + } + mipi_dsi_dcs_write_seq(dsi, MCS_ACL_OPR_CONTROL, 0x29); + mipi_dsi_dcs_write_seq(dsi, MCS_ACL_CONTROL, 0x00); + + ret = ea8061v_ams497ee01_update_elvss(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to update elvss: %d\n", ret); + return ret; + } + + ret = ea8061v_ams497ee01_update_gamma(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to update gamma: %d\n", ret); + return ret; + } + + ret = ea8061v_ams497ee01_apply_gamma(ctx); + if (ret < 0) { + dev_err(dev, "Failed to apply gamma update: %d\n", ret); + return ret; + } + + ea8061v_ams497ee01_lock(ctx, 0xf1); + if (ret < 0) { + dev_err(dev, "Failed to lock 0xf1: %d\n", ret); + return ret; + } + ea8061v_ams497ee01_lock(ctx, 0xf0); + if (ret < 0) { + dev_err(dev, "Failed to lock 0xf0: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct backlight_ops ea8061v_ams497ee01_bl_ops = { + .update_status = ea8061v_ams497ee01_set_brightness, +}; + +static int ea8061v_ams497ee01_init(struct ea8061v_ams497ee01 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + unsigned int brightness = ctx->bl_dev->props.brightness; + dsi->mode_flags |= MIPI_DSI_MODE_LPM; - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a); - mipi_dsi_dcs_write_seq(dsi, 0xf1, 0x5a, 0x5a); - mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x19, 0x10); + ret = ea8061v_ams497ee01_unlock(ctx, 0xf0); + if (ret < 0) { + dev_err(dev, "Failed to unlock 0xf0: %d\n", ret); + return ret; + } + ret = ea8061v_ams497ee01_unlock(ctx, 0xf1); + if (ret < 0) { + dev_err(dev, "Failed to unlock 0xf1: %d\n", ret); + return ret; + } + + /* Common conditions */ + /* set ref temperature/voltage (0x19 = 25 degC, 0x10 = 7.6 V) */ + mipi_dsi_dcs_write_seq(dsi, MCS_TSET, 0x19, 0x10); + /* ? */ mipi_dsi_dcs_write_seq(dsi, 0xba, 0x57); - mipi_dsi_dcs_write_seq(dsi, 0xfc, 0x5a, 0x5a); + + ret = ea8061v_ams497ee01_unlock(ctx, 0xfc); + if (ret < 0) { + dev_err(dev, "Failed to unlock 0xfc: %d\n", ret); + return ret; + } + + /* skip 11 parameters in HBM sequence? */ mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x0b); + /* ? */ mipi_dsi_dcs_write_seq(dsi, 0xd2, 0x00, 0x85); + /* ? */ mipi_dsi_dcs_write_seq(dsi, 0xcb, 0x70); - mipi_dsi_dcs_write_seq(dsi, 0xfc, 0xa5, 0xa5); - mipi_dsi_dcs_write_seq(dsi, 0xca, - 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, - 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x00, 0x00, 0x00, 0x0a); - mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x5c, 0x8a); - mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x01); + + ret = ea8061v_ams497ee01_lock(ctx, 0xfc); + if (ret < 0) { + dev_err(dev, "Failed to lock 0xfc: %d\n", ret); + return ret; + } + /* Brightness control */ + ret = ea8061v_ams497ee01_update_gamma(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to update gamma: %d\n", ret); + return ret; + } + ret = ea8061v_ams497ee01_update_aid(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to send aid sequence: %d\n", ret); + return ret; + } + ret = ea8061v_ams497ee01_update_elvss(ctx, brightness); + if (ret < 0) { + dev_err(dev, "Failed to update elvss: %d\n", ret); + return ret; + } + ret = ea8061v_ams497ee01_apply_gamma(ctx); + if (ret < 0) { + dev_err(dev, "Failed to apply gamma update: %d\n", ret); + return ret; + } ret = mipi_dsi_dcs_exit_sleep_mode(dsi); if (ret < 0) { @@ -71,7 +685,11 @@ static int ea8061v_ams497ee01_on(struct ea8061v_ams497ee01 *ctx) } msleep(120); - mipi_dsi_dcs_write_seq(dsi, 0xf1, 0xa5, 0xa5); + ret = ea8061v_ams497ee01_lock(ctx, 0xf1); + if (ret < 0) { + dev_err(dev, "Failed to lock 0xf1: %d\n", ret); + return ret; + } ret = mipi_dsi_dcs_set_display_on(dsi); if (ret < 0) { @@ -82,28 +700,91 @@ static int ea8061v_ams497ee01_on(struct ea8061v_ams497ee01 *ctx) return 0; } -static int ea8061v_ams497ee01_off(struct ea8061v_ams497ee01 *ctx) +static int ea8061v_ams497ee01_power_on(struct ea8061v_ams497ee01 *ctx) +{ + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) { + dev_err(&ctx->dsi->dev, + "Failed to enable regulators: %d\n", ret); + return ret; + } + + /* send reset pulse */ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + msleep(20); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + msleep(20); + + return 0; +} + +static int ea8061v_ams497ee01_power_off(struct ea8061v_ams497ee01 *ctx) { + int ret; + + gpiod_set_value(ctx->reset_gpio, 1); + + ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) + return ret; + + return 0; +} + +static int ea8061v_ams497ee01_enable(struct drm_panel *panel) +{ + struct ea8061v_ams497ee01 *ctx = to_ea8061v_ams497ee01(panel); struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; int ret; + if (ctx->prepared) + return 0; + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + }; + msleep(120); + + backlight_enable(ctx->bl_dev); + + ctx->enabled = true; + return 0; +} + +static int ea8061v_ams497ee01_disable(struct drm_panel *panel) +{ + struct ea8061v_ams497ee01 *ctx = to_ea8061v_ams497ee01(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + int ret; + + if (!ctx->enabled) + return 0; + + backlight_disable(ctx->bl_dev); + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; ret = mipi_dsi_dcs_set_display_off(dsi); if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); + dev_err(&dsi->dev, "Failed to set display off: %d\n", ret); return ret; } msleep(35); ret = mipi_dsi_dcs_enter_sleep_mode(dsi); if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); + dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret); return ret; } msleep(100); + ctx->enabled = false; return 0; } @@ -116,19 +797,16 @@ static int ea8061v_ams497ee01_prepare(struct drm_panel *panel) if (ctx->prepared) return 0; - ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + ret = ea8061v_ams497ee01_power_on(ctx); if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); + dev_err(dev, "Failed to power on panel: %d\n", ret); return ret; } - ea8061v_ams497ee01_reset(ctx); - - ret = ea8061v_ams497ee01_on(ctx); + ret = ea8061v_ams497ee01_init(ctx); if (ret < 0) { dev_err(dev, "Failed to initialize panel: %d\n", ret); - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + ea8061v_ams497ee01_power_off(ctx); return ret; } @@ -145,13 +823,10 @@ static int ea8061v_ams497ee01_unprepare(struct drm_panel *panel) if (!ctx->prepared) return 0; - ret = ea8061v_ams497ee01_off(ctx); + ret = ea8061v_ams497ee01_power_off(ctx); if (ret < 0) dev_err(dev, "Failed to un-initialize panel: %d\n", ret); - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - ctx->prepared = false; return 0; } @@ -191,6 +866,8 @@ static int ea8061v_ams497ee01_get_modes(struct drm_panel *panel, static const struct drm_panel_funcs ea8061v_ams497ee01_panel_funcs = { .prepare = ea8061v_ams497ee01_prepare, + .enable = ea8061v_ams497ee01_enable, + .disable = ea8061v_ams497ee01_disable, .unprepare = ea8061v_ams497ee01_unprepare, .get_modes = ea8061v_ams497ee01_get_modes, }; @@ -205,6 +882,9 @@ static int ea8061v_ams497ee01_probe(struct mipi_dsi_device *dsi) if (!ctx) return -ENOMEM; + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + ctx->supplies[0].supply = "vdd3"; ctx->supplies[1].supply = "vci"; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), @@ -217,14 +897,24 @@ static int ea8061v_ams497ee01_probe(struct mipi_dsi_device *dsi) return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n"); - ctx->dsi = dsi; - mipi_dsi_set_drvdata(dsi, ctx); + ctx->bl_dev = backlight_device_register("panel", dev, ctx, + &ea8061v_ams497ee01_bl_ops, + NULL); dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_NO_EOT_PACKET; + if (IS_ERR(ctx->bl_dev)) { + dev_err(dev, "Failed to register backlight device\n"); + return PTR_ERR(ctx->bl_dev); + } + + ctx->bl_dev->props.max_brightness = EA8061V_AMS497EE01_MAX_BRIGHTNESS; + ctx->bl_dev->props.brightness = EA8061V_AMS497EE01_DEFAULT_BRIGHTNESS; + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; + drm_panel_init(&ctx->panel, dev, &ea8061v_ams497ee01_panel_funcs, DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; @@ -248,13 +938,14 @@ static void ea8061v_ams497ee01_remove(struct mipi_dsi_device *dsi) ret = mipi_dsi_detach(dsi); if (ret < 0) - dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + dev_err(&dsi->dev, + "Failed to detach from DSI host: %d\n", ret); drm_panel_remove(&ctx->panel); } static const struct of_device_id ea8061v_ams497ee01_of_match[] = { - { .compatible = "samsung,ea8061v-ams497ee01" }, // FIXME + { .compatible = "samsung,ea8061v-ams497ee01" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ea8061v_ams497ee01_of_match);