diff options
Diffstat (limited to 'drivers/video/samsung/s3cfb_s6e8aa0.c')
-rw-r--r-- | drivers/video/samsung/s3cfb_s6e8aa0.c | 390 |
1 files changed, 209 insertions, 181 deletions
diff --git a/drivers/video/samsung/s3cfb_s6e8aa0.c b/drivers/video/samsung/s3cfb_s6e8aa0.c index ff94492..00b543e 100644 --- a/drivers/video/samsung/s3cfb_s6e8aa0.c +++ b/drivers/video/samsung/s3cfb_s6e8aa0.c @@ -88,7 +88,7 @@ struct lcd_info { unsigned int bl; unsigned int auto_brightness; unsigned int acl_enable; - unsigned int cur_acl; + unsigned int current_acl; unsigned int current_bl; unsigned int current_elvss; @@ -131,6 +131,7 @@ struct lcd_info { #ifdef CONFIG_AID_DIMMING static const unsigned int candela_table[GAMMA_MAX] = { 20, 30, 40, 50, 60, 70, 80, 90, 100, + 102, 104, 106, 108, 110, 120, 130, 140, 150, 160, 170, 180, 182, 184, 186, 188, 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1 @@ -138,9 +139,9 @@ static const unsigned int candela_table[GAMMA_MAX] = { static unsigned int aid_candela_table[GAMMA_MAX] = { base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, - AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150, - AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, AOR40_BASE_182, AOR40_BASE_184, - AOR40_BASE_186, AOR40_BASE_188, + AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108, + AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150, AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, + AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188, 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1 }; @@ -181,6 +182,9 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = { }; #endif +extern void (*lcd_early_suspend)(void); +extern void (*lcd_late_resume)(void); + #if defined(GPIO_OLED_DET) static void oled_detection_work(struct work_struct *work) { @@ -286,76 +290,100 @@ static int get_backlight_level_from_brightness(int brightness) switch (brightness) { case 0 ... 29: - backlightlevel = GAMMA_30CD; //GAMMA_20CD; + backlightlevel = GAMMA_20CD; break; case 30 ... 39: - backlightlevel = GAMMA_40CD; //GAMMA_30CD; + backlightlevel = GAMMA_30CD; break; case 40 ... 49: - backlightlevel = GAMMA_50CD; //GAMMA_40CD; + backlightlevel = GAMMA_40CD; break; case 50 ... 59: - backlightlevel = GAMMA_60CD; //GAMMA_50CD; + backlightlevel = GAMMA_50CD; break; case 60 ... 69: - backlightlevel = GAMMA_70CD; //GAMMA_60CD; + backlightlevel = GAMMA_60CD; break; case 70 ... 79: - backlightlevel = GAMMA_80CD; //GAMMA_70CD; + backlightlevel = GAMMA_70CD; break; case 80 ... 89: - backlightlevel = GAMMA_90CD; //GAMMA_80CD; + backlightlevel = GAMMA_80CD; break; case 90 ... 99: - backlightlevel = GAMMA_100CD; //GAMMA_90CD; + backlightlevel = GAMMA_90CD; + break; + case 100 ... 101: + backlightlevel = GAMMA_100CD; + break; + case 102 ... 103: + backlightlevel = GAMMA_102CD; + break; + case 104 ... 105: + backlightlevel = GAMMA_104CD; + break; + case 106 ... 107: + backlightlevel = GAMMA_106CD; break; - case 100 ... 109: - backlightlevel = GAMMA_110CD; //GAMMA_100CD; + case 108 ... 109: + backlightlevel = GAMMA_108CD; break; case 110 ... 119: - backlightlevel = GAMMA_130CD; //GAMMA_110CD; + backlightlevel = GAMMA_110CD; break; case 120 ... 129: - backlightlevel = GAMMA_140CD; //GAMMA_120CD; + backlightlevel = GAMMA_120CD; break; case 130 ... 139: - backlightlevel = GAMMA_150CD; //GAMMA_130CD; + backlightlevel = GAMMA_130CD; break; case 140 ... 149: - backlightlevel = GAMMA_160CD; //GAMMA_140CD; + backlightlevel = GAMMA_140CD; break; case 150 ... 159: - backlightlevel = GAMMA_180CD; //GAMMA_150CD; + backlightlevel = GAMMA_150CD; break; case 160 ... 169: - backlightlevel = GAMMA_190CD; //GAMMA_160CD; + backlightlevel = GAMMA_160CD; break; case 170 ... 179: - backlightlevel = GAMMA_200CD; //GAMMA_170CD; + backlightlevel = GAMMA_170CD; break; - case 180 ... 189: - backlightlevel = GAMMA_210CD; + case 180 ... 181: + backlightlevel = GAMMA_180CD; + break; + case 182 ... 183: + backlightlevel = GAMMA_182CD; + break; + case 184 ... 185: + backlightlevel = GAMMA_184CD; + break; + case 186 ... 187: + backlightlevel = GAMMA_186CD; + break; + case 188 ... 189: + backlightlevel = GAMMA_188CD; break; case 190 ... 199: - backlightlevel = GAMMA_220CD; //GAMMA_190CD; + backlightlevel = GAMMA_190CD; break; case 200 ... 209: - backlightlevel = GAMMA_230CD; //GAMMA_200CD; + backlightlevel = GAMMA_200CD; break; case 210 ... 219: - backlightlevel = GAMMA_240CD; //GAMMA_210CD; + backlightlevel = GAMMA_210CD; break; case 220 ... 229: - backlightlevel = GAMMA_240CD; //GAMMA_220CD; + backlightlevel = GAMMA_220CD; break; case 230 ... 239: - backlightlevel = GAMMA_250CD; //GAMMA_230CD; + backlightlevel = GAMMA_230CD; break; case 240 ... 249: - backlightlevel = GAMMA_250CD; //GAMMA_240CD; + backlightlevel = GAMMA_240CD; break; case 250 ... 254: - backlightlevel = GAMMA_300CD; //GAMMA_250CD; + backlightlevel = GAMMA_250CD; break; case 255: backlightlevel = GAMMA_300CD; @@ -367,14 +395,24 @@ static int get_backlight_level_from_brightness(int brightness) return backlightlevel; } -static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd , u8 force) +static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd, u8 force) { - if (likely(lcd->support_aid)) { - if ((lcd->f8[lcd->bl][0x12] != lcd->f8[lcd->current_bl][0x12]) || - (lcd->f8[lcd->bl][0x01] != lcd->f8[lcd->current_bl][0x01]) || (force)) - s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE); - } + if (unlikely(!lcd->support_aid)) + goto exit; + + if (force) + goto aid_update; + else if (aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0]) + goto aid_update; + else if (aid_command_table[lcd->bl][1] != aid_command_table[lcd->current_bl][1]) + goto aid_update; + else + goto exit; +aid_update: + s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE); + +exit: return 0; } #else @@ -414,149 +452,112 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd) } #if defined(CONFIG_S6E8AA0_AMS529HA01) -static int s6e8ax0_set_acl(struct lcd_info *lcd) +static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force) { - int ret = 0; + int ret = 0, enable, level; + u32 candela = candela_table[lcd->bl]; - if (lcd->acl_enable) { - if (lcd->cur_acl == 0) { - if (lcd->bl == 0 || lcd->bl == 1) { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl); - } else { - s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON)); - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl); - } - } - switch (lcd->bl) { - case GAMMA_30CD... GAMMA_40CD: - if (lcd->cur_acl != 0) { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - lcd->cur_acl = 0; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_50CD: - if (lcd->cur_acl != 200) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P], ACL_PARAM_SIZE); - lcd->cur_acl = 200; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_60CD: - if (lcd->cur_acl != 330) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE); - lcd->cur_acl = 330; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_70CD: - if (lcd->cur_acl != 430) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_43P], ACL_PARAM_SIZE); - lcd->cur_acl = 430; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_80CD: - if (lcd->cur_acl != 450) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P_80CD], ACL_PARAM_SIZE); - lcd->cur_acl = 450; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_90CD ... GAMMA_150CD: - if (lcd->cur_acl != 451) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P], ACL_PARAM_SIZE); - lcd->cur_acl = 451; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_160CD: /* 160cd */ - if (lcd->cur_acl != 460) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P_160CD], ACL_PARAM_SIZE); - lcd->cur_acl = 460; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case GAMMA_170CD ... GAMMA_250CD: - if (lcd->cur_acl != 461) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P], ACL_PARAM_SIZE); - lcd->cur_acl = 461; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - default: - if (lcd->cur_acl != 550) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE); - lcd->cur_acl = 550; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - } - } else { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - lcd->cur_acl = 0; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl); + switch (candela) { + case 0 ... 49: + level = ACL_STATUS_0P; + break; + case 50 ... 59: + level = ACL_STATUS_20P; + break; + case 60 ... 69: + level = ACL_STATUS_33P; + break; + case 70 ... 79: + level = ACL_STATUS_43P; + break; + case 80 ... 89: + level = ACL_STATUS_45P_80CD; + break; + case 90 ... 159: + level = ACL_STATUS_45P; + break; + case 160 ... 169: + level = ACL_STATUS_46P_160CD; + break; + case 170 ... 250: + level = ACL_STATUS_46P; + break; + default: + level = ACL_STATUS_50P; + break; } - if (ret) { + if (!lcd->acl_enable) + level = ACL_STATUS_0P; + + enable = !!level; + + //if (force || lcd->acl_enable != enable) { + dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off"); + if (enable) + ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON)); + else { + ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); + goto exit; + } + //} + + //if (force || lcd->current_acl != level) { + ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE); + lcd->current_acl = level; + dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl); + //} + + if (ret) ret = -EPERM; - goto acl_err; - } -acl_err: +exit: return ret; } #else -static int s6e8ax0_set_acl(struct lcd_info *lcd) +static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force) { - if (lcd->acl_enable) { - if (lcd->cur_acl == 0) { - if (lcd->bl == 0) { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl); - } else { - s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON)); - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl); - } - } - switch (lcd->bl) { - case 0: - if (lcd->cur_acl != 0) { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - lcd->cur_acl = 0; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case 1: - if (lcd->cur_acl != 33) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE); - lcd->cur_acl = 33; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - case 2 ... GAMMA_250CD: - if (lcd->cur_acl != 40) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_40P], ACL_PARAM_SIZE); - lcd->cur_acl = 40; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - default: - if (lcd->cur_acl != 50) { - s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE); - lcd->cur_acl = 50; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl); - } - break; - } - } else { - s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); - lcd->cur_acl = 0; - dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl); + int ret = 0, enable, level; + u32 candela = candela_table[lcd->bl]; + + switch (candela) { + case 0 ... 29: + level = ACL_STATUS_0P; + break; + case 30 ... 39: + level = ACL_STATUS_33P; + break; + default: + level = ACL_STATUS_40P; + break; } - return 0; + if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5)) + level = ACL_STATUS_0P; + + enable = !!level; + + //if (force || lcd->acl_enable != enable) { + dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off"); + if (enable) + ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON)); + else { + ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF)); + goto exit; + } + //} + + //if (force || lcd->current_acl != level) { + ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE); + lcd->current_acl = level; + dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl); + //} + + if (ret) + ret = -EPERM; + +exit: + return ret; } #endif @@ -630,7 +631,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force) break; } - if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) { + if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) { ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE); lcd->current_elvss = lcd->elvss_table[elvss_level][2]; } @@ -668,7 +669,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force) break; } - if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) { + if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) { ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE); lcd->current_elvss = lcd->elvss_table[elvss_level][2]; } @@ -893,16 +894,12 @@ static int update_brightness(struct lcd_info *lcd, u8 force) lcd->bl = get_backlight_level_from_brightness(brightness); if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) { + s6e8ax0_gamma_ctl(lcd); #ifdef CONFIG_AID_DIMMING - if ((force) || unlikely(aid_candela_table[lcd->bl] != aid_candela_table[lcd->current_bl])) -#endif - s6e8ax0_gamma_ctl(lcd); - -#ifdef CONFIG_AID_DIMMING - s6e8ax0_aid_parameter_ctl(lcd , force); + s6e8ax0_aid_parameter_ctl(lcd, force); #endif - s6e8ax0_set_acl(lcd); + s6e8ax0_set_acl(lcd, force); s6e8ax0_set_elvss(lcd, force); @@ -1152,9 +1149,9 @@ static ssize_t power_reduce_store(struct device *dev, dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value); mutex_lock(&lcd->bl_lock); lcd->acl_enable = value; - if (lcd->ldi_enable) - s6e8ax0_set_acl(lcd); mutex_unlock(&lcd->bl_lock); + if (lcd->ldi_enable) + update_brightness(lcd, 1); } } return size; @@ -1228,7 +1225,7 @@ static ssize_t auto_brightness_store(struct device *dev, lcd->auto_brightness = value; mutex_unlock(&lcd->bl_lock); if (lcd->ldi_enable) - update_brightness(lcd, 0); + update_brightness(lcd, 1); } } return size; @@ -1336,6 +1333,29 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf) #endif #endif +static ssize_t read_acl_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lcd_info *lcd = dev_get_drvdata(dev); + char *pos = buf; + char temp[ACL_PARAM_SIZE] = {0,}; + u32 i; + + s6e8ax0_read(lcd, 0xC0, 3, temp, 0); + pos += sprintf(pos, "0xC0=0x%02x, 0x%02x\n", temp[0], temp[1]); + + s6e8ax0_read(lcd, 0xC1, ACL_PARAM_SIZE, temp, 0); + for (i = 0; i < ACL_PARAM_SIZE; i++) { + pos += sprintf(pos, "0x%02x, ", temp[i]); + if ((i % 5) == 0) + pos += sprintf(pos, "\n"); + } + pos += sprintf(pos, "\n"); + + return pos - buf; +} +static DEVICE_ATTR(read_acl, 0444, read_acl_show, NULL); + static int s6e8ax0_probe(struct device *dev) { int ret = 0; @@ -1375,7 +1395,7 @@ static int s6e8ax0_probe(struct device *dev) lcd->current_bl = lcd->bl; lcd->acl_enable = 0; - lcd->cur_acl = 0; + lcd->current_acl = 0; lcd->power = FB_BLANK_UNBLANK; lcd->ldi_enable = 1; @@ -1394,6 +1414,10 @@ static int s6e8ax0_probe(struct device *dev) if (ret < 0) dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__); + ret = device_create_file(&lcd->ld->dev, &dev_attr_read_acl); + if (ret < 0) + dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__); + ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness); if (ret < 0) dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__); @@ -1461,6 +1485,10 @@ static int s6e8ax0_probe(struct device *dev) pr_err("failed to reqeust irq. %d\n", lcd->irq); } #endif + + lcd_early_suspend = s6e8ax0_early_suspend; + lcd_late_resume = s6e8ax0_late_resume; + return 0; out_free_backlight: @@ -1518,5 +1546,5 @@ static void s6e8ax0_exit(void) module_init(s6e8ax0_init); module_exit(s6e8ax0_exit); -MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver"); +MODULE_DESCRIPTION("MIPI-DSI S6E8AA0: AMS529HA01 (800x1280) / AMS480GYXX (720x1280) Panel Driver"); MODULE_LICENSE("GPL"); |