summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/msm/Makefile3
-rw-r--r--drivers/video/fbdev/msm/lcd_effect.c761
-rw-r--r--drivers/video/fbdev/msm/lcd_effect.h90
-rw-r--r--drivers/video/fbdev/msm/mdp3.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_ams520.h286
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_cmd.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c225
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_status.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c16
9 files changed, 1388 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/Makefile b/drivers/video/fbdev/msm/Makefile
index dfbc604dafa5..7e910eb58334 100644
--- a/drivers/video/fbdev/msm/Makefile
+++ b/drivers/video/fbdev/msm/Makefile
@@ -8,6 +8,9 @@ mdss-mdp3-objs += mdp3_ppp.o mdp3_ppp_hwio.o mdp3_ppp_data.o
obj-$(CONFIG_FB_MSM_MDSS_MDP3) += mdss-mdp3.o
mdss-mdp-objs := mdss_mdp.o mdss_mdp_ctl.o mdss_mdp_pipe.o mdss_mdp_util.o dsi_status_6g.o
+ifeq ($(CONFIG_MACH_ZUK_Z2_ROW), y)
+mdss-mdp-objs += lcd_effect.o
+endif
mdss-mdp-objs += mdss_mdp_pp.o mdss_mdp_pp_debug.o mdss_mdp_pp_cache_config.o
mdss-mdp-objs += mdss_mdp_intf_video.o
mdss-mdp-objs += mdss_mdp_intf_cmd.o
diff --git a/drivers/video/fbdev/msm/lcd_effect.c b/drivers/video/fbdev/msm/lcd_effect.c
new file mode 100644
index 000000000000..567e33ac750e
--- /dev/null
+++ b/drivers/video/fbdev/msm/lcd_effect.c
@@ -0,0 +1,761 @@
+#include "lcd_effect.h"
+
+extern int is_show_lcd_param;
+extern void show_lcd_param(struct dsi_cmd_desc *cmds, int cmd_cnt);
+#ifdef CONFIG_BACKLIGHT_LM36923
+int lm36923_sunlight_settings (int level);
+#endif
+
+#define TAG "[LCD_EFFECT: ]"
+//#define LCDDEBUG
+#ifdef LCDDEBUG
+#define lcd_effect_info(fmt, ...) printk(TAG fmt, ##__VA_ARGS__);
+#else
+#define lcd_effect_info(fmt, ...) do {} while (0)
+#endif
+
+#ifdef READ_LCD_PARAM
+static int read_lcd_file = 0;
+struct lcd_cmds lcd_txt_cmds;
+
+#define BUFSIZE 3
+#define LENGHT 256
+#define LENGHT_POS 0
+#define TYPE_POS 1
+#define DELAY_POS 2
+#define DATA_POS 3
+#define FILEPATH "/data/lcd.txt"
+static char data_buf[LENGHT] = {0};
+static char *data_pos[LENGHT];
+
+static int get_data(char *buf)
+{
+ char a, b;
+
+ if (buf[0] >= 'A' && buf[0] <= 'F') {
+ a = buf[0] - 55;
+ } else if (buf[0] >= 'a' && buf[0] <= 'f') {
+ a = buf[0] - 87;
+ } else {
+ a = buf[0] - 48;
+ }
+ if (buf[1] >= 'A' && buf[1] <= 'F') {
+ b = buf[1] - 55;
+ } else if (buf[1] >= 'a' && buf[1] <= 'f') {
+ b = buf[1] - 87;
+ } else {
+ b = buf[1] - 48;
+ }
+ return a * 16 + b;
+}
+static void clear_data_and_mem(void)
+{
+ int i;
+
+ if (lcd_txt_cmds.cnt) {
+ pr_info("Free mem for lcd txt file's cmds buf.\n");
+ for (i = 0; i < lcd_txt_cmds.cnt; i++) {
+ if (data_pos[i])
+ kfree(data_pos[i]);
+ }
+ if (lcd_txt_cmds.cmd)
+ kfree(lcd_txt_cmds.cmd);
+ lcd_txt_cmds.cnt = 0;
+ }
+}
+static int open_lcd_and_get_data(void)
+{
+ struct file *fp;
+ int ret, lenght = 0;
+ int i = 0, j = 0;
+ char buf[BUFSIZE] = {0};
+ char *filepath = FILEPATH;
+ mm_segment_t old_fs;
+
+ lcd_txt_cmds.cnt = 0;
+ //清空BUF
+ for (i = 0; i < LENGHT; i++) {
+ data_buf[i] = 0;
+ }
+ fp = filp_open(filepath, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ pr_info("open file failure\n");
+ return -1;
+ } else {
+ pr_info("open file success, begin to read\n");
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ do {
+ ret = vfs_read(fp, buf, BUFSIZE, &fp->f_pos);
+ if (ret == -1) {
+ pr_info("read file failure\n");
+ goto read_err;
+ }
+ if (ret == BUFSIZE) {
+ lenght++;
+ //buf里留一个位置给lenght
+ data_buf[lenght] = get_data(buf); //数据格式为:长度+格式 + 延时+数据,现在长度data_buf[0]为空
+
+ if (buf[2] == '\n') { //标记一行结束
+ if (lenght > LENGHT) { //如果一行的数据超过buf的大小
+ pr_info("data too long !!!!!!!!!!!!!!!\n");
+ goto large_err;
+ }
+
+ //把data_buf[0]赋值为长度
+ data_buf[LENGHT_POS] = lenght + 1;
+ data_pos[lcd_txt_cmds.cnt] = kmalloc(sizeof(char) * data_buf[LENGHT_POS], GFP_KERNEL);
+ if (!data_pos[lcd_txt_cmds.cnt]) {
+ pr_info("kmalloc failure !!!!\n");
+ goto mem_err;
+ }
+
+ memcpy(data_pos[lcd_txt_cmds.cnt], data_buf, data_buf[0]); //把数据拷贝到新分配的空间
+
+ //pr_info("buf[%d] lenght = %d\n", lcd_txt_cmds.cnt, lenght);
+ lcd_txt_cmds.cnt++; //数据的行号+1
+ lenght = 0;
+ }
+ }
+ } while (ret != 0);
+ j = 0;
+
+ lcd_txt_cmds.cmd = kmalloc(sizeof(struct dsi_cmd_desc) * lcd_txt_cmds.cnt, GFP_KERNEL);
+ if (!lcd_txt_cmds.cmd) {
+ pr_info("kmalloc failure !!!!\n");
+ goto cmds_err;
+ }
+
+ for (i = 0; i < lcd_txt_cmds.cnt; i++) {
+ lcd_txt_cmds.cmd[i].dchdr.dtype = data_pos[i][TYPE_POS];
+ lcd_txt_cmds.cmd[i].dchdr.last = 1;
+ lcd_txt_cmds.cmd[i].dchdr.vc = 0;
+ lcd_txt_cmds.cmd[i].dchdr.ack = 0;
+ lcd_txt_cmds.cmd[i].dchdr.wait = data_pos[i][DELAY_POS];
+ lcd_txt_cmds.cmd[i].dchdr.dlen = data_pos[i][LENGHT_POS] - DATA_POS;
+ lcd_txt_cmds.cmd[i].payload = &data_pos[i][DATA_POS];
+ }
+
+ filp_close(fp, NULL);
+ }
+ return 0;
+cmds_err:
+large_err:
+read_err:
+mem_err:
+ for (i = 0; i < lcd_txt_cmds.cnt; i++) {
+ kfree(data_pos[i]);
+ }
+ lcd_txt_cmds.cnt = 0;
+ return -1;
+}
+
+
+#endif
+static int is_custom_mode(struct lcd_mode_data *mode_data)
+{
+ return !mode_data->current_mode;
+}
+
+int get_effect_index_by_name(char *name, struct panel_effect_data *lcd_data)
+{
+ int i;
+ struct lcd_effect *effect = lcd_data->effect_data->effect;
+
+ for (i = 0; i < lcd_data->effect_data->supported_effect; i++) {
+ if (!strcmp(name, effect[i].name))
+ return i;
+ }
+ return -EINVAL;
+}
+int get_mode_index_by_name(char *name, struct panel_effect_data *lcd_data)
+{
+ int i;
+ struct lcd_mode *mode= lcd_data->mode_data->mode;
+
+ for (i = 0; i < lcd_data->mode_data->supported_mode; i++) {
+ if (!strcmp(name, mode[i].name))
+ return i;
+ }
+ return -EINVAL;
+}
+static void update_effect_cmds(struct lcd_effect *effect, int level)
+{
+ struct lcd_effect_cmd_data *effect_cmd_data = &effect->effect_cmd_data;
+ struct lcd_effect_cmds *effect_cmd = effect_cmd_data->effect_cmd;
+ int cmd_cnt = effect_cmd_data->cnt;
+ int code_cnt ;
+ int i;
+
+ for (i = 0; i < cmd_cnt; i++) {
+ code_cnt = effect_cmd[i].effect_code.cnt;
+ effect_cmd[i].lcd_cmd.cmd->payload = effect_cmd[i].effect_code.code[level >= code_cnt ? code_cnt -1 : level];
+ }
+}
+
+static void inline update_level(struct lcd_effect *effect, int level)
+{
+ effect->level = level;
+}
+
+static inline void update_mode(struct lcd_mode_data *mode_data, int index)
+{
+ mode_data->current_mode = index;
+}
+
+static inline int get_level(struct lcd_effect *effect)
+{
+ return effect->level;
+}
+
+static inline int get_effect_cmd_cnt(struct lcd_effect *effect)
+{
+ return effect->effect_cmd_data.cnt;
+}
+
+static inline int get_head_cmd_cnt(struct lcd_cmds *head_cmd)
+{
+ return head_cmd->cnt;
+}
+
+static inline struct dsi_cmd_desc *get_head_cmd(struct lcd_cmds *head_cmd)
+{
+ return head_cmd->cmd;
+}
+static inline struct lcd_cmds *get_lcd_cmd(struct lcd_effect_cmds *effect_cmd)
+{
+ return &effect_cmd->lcd_cmd;
+}
+static inline struct lcd_effect_cmds * get_effect_cmd(struct lcd_effect *effect)
+{
+ return effect->effect_cmd_data.effect_cmd;
+}
+
+static inline struct dsi_cmd_desc *get_effect_cmd_desc(struct lcd_effect_cmds *effect_cmd)
+{
+ return effect_cmd->lcd_cmd.cmd;
+}
+static inline struct dsi_cmd_desc * get_mode_cmd(struct lcd_mode *mode)
+{
+ return mode->mode_cmd.cmd;
+}
+static inline int get_mode_cmd_cnt(struct lcd_mode *mode)
+{
+ return mode->mode_cmd.cnt;
+}
+
+static int get_mode_max_cnt(struct lcd_mode_data *mode_data)
+{
+ int i;
+ int temp;
+ int cnt = 0;
+
+ for (i = 0; i < mode_data->supported_mode; i++) {
+ temp = mode_data->mode[i].mode_cmd.cnt;
+ cnt = (cnt > temp) ? cnt : temp;
+ lcd_effect_info("%s cnt = %d temp = %d\n", __func__, cnt, temp);
+ }
+
+ return cnt;
+}
+
+static int get_effect_max_cnt(struct lcd_effect_data *effect_data)
+{
+ int cnt = 0;
+ int temp;
+ int i;
+
+ for (i = 0; i < effect_data->supported_effect; i++) {
+ temp = effect_data->effect[i].effect_cmd_data.cnt;
+ cnt = cnt + temp;
+ lcd_effect_info("%s cnt = %d temp = %d\n", __func__, cnt, temp);
+ }
+
+ return cnt;
+}
+
+static int get_init_code_max_cnt(struct panel_effect_data *panel_data, struct lcd_cmds *save_cmd)
+{
+ int cnt = save_cmd->cnt;
+
+ cnt += get_mode_max_cnt(panel_data->mode_data);
+ cnt += get_effect_max_cnt(panel_data->effect_data);
+ lcd_effect_info("%s cnt: %d\n", __func__, cnt);
+ return cnt;
+}
+
+static int send_lcd_cmds(struct msm_fb_data_type *mfd, struct lcd_cmds *cmds)
+{
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ struct dcs_cmd_req cmdreq;
+ struct mdss_panel_data *pdata;
+ struct mdss_panel_info *pinfo;
+
+ int ret;
+
+ pdata = dev_get_platdata(&mfd->pdev->dev);
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data);
+ if (mfd->panel_power_state == false) {
+ pr_err("%s: LCD panel have powered off\n", __func__);
+ return -EPERM;
+ }
+
+ pinfo = &(ctrl_pdata->panel_data.panel_info);
+ if (pinfo->dcs_cmd_by_left) {
+ if (ctrl_pdata->ndx != DSI_CTRL_LEFT)
+ return 1;
+ }
+
+ memset(&cmdreq, 0, sizeof(cmdreq));
+ cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_LP_MODE;
+ cmdreq.rlen = 0;
+ cmdreq.cb = NULL;
+ cmdreq.cmds = cmds->cmd;
+ cmdreq.cmds_cnt = cmds->cnt;
+
+ ret = mdss_dsi_cmdlist_put(ctrl_pdata, &cmdreq);
+
+ return ret;
+}
+
+static struct dsi_cmd_desc *copy_init_code(struct panel_effect_data *panel_data, int *cnt)
+{
+ int init_cnt = panel_data->save_cmd.cnt;
+
+ memcpy(panel_data->buf, panel_data->save_cmd.cmd, (init_cnt - CMDS_LAST_CNT) * sizeof (struct dsi_cmd_desc));
+ *cnt += (init_cnt - CMDS_LAST_CNT);
+ lcd_effect_info("%s: line=%d\n", __func__,__LINE__);
+ return (panel_data->buf + (init_cnt - CMDS_LAST_CNT));
+}
+
+static struct dsi_cmd_desc *copy_sleep_out_code(
+ struct panel_effect_data *panel_data,
+ struct dsi_cmd_desc *buf,
+ int *cnt)
+{
+ memcpy(buf, panel_data->save_cmd.cmd + panel_data->save_cmd.cnt - CMDS_LAST_CNT, CMDS_LAST_CNT * sizeof (struct dsi_cmd_desc));
+ *cnt += CMDS_LAST_CNT;
+ lcd_effect_info("%s: line=%d\n", __func__,__LINE__);
+ return (buf + CMDS_LAST_CNT);
+}
+static struct dsi_cmd_desc *copy_head_code(struct panel_effect_data *panel_data, struct dsi_cmd_desc *buf, int *cnt)
+{
+ struct lcd_cmds *head_cmds = panel_data->effect_data->head_cmd;
+ int head_cnt = get_head_cmd_cnt(head_cmds);
+
+ memcpy(buf, head_cmds->cmd, head_cnt * sizeof (struct dsi_cmd_desc));
+ *cnt += head_cnt;
+
+ lcd_effect_info("%s: line=%d\n", __func__,__LINE__);
+ return (buf + head_cnt);
+}
+
+static struct dsi_cmd_desc * copy_single_effect_code(
+ struct panel_effect_data *panel_data,
+ struct dsi_cmd_desc *buf,
+ int index,
+ int level,
+ int *cnt)
+{
+ struct lcd_effect_data *effect_data = panel_data->effect_data;
+ struct lcd_effect *effect = &effect_data->effect[index];
+ struct dsi_cmd_desc *temp = buf;
+ struct lcd_effect_cmds *effect_cmd;
+ int cmd_cnt;
+ int i;
+
+ update_effect_cmds(effect, level);
+ cmd_cnt = get_effect_cmd_cnt(effect);
+ effect_cmd = get_effect_cmd(effect);
+ *cnt += cmd_cnt;
+ for (i = 0; i < cmd_cnt; i++)
+ memcpy(temp++, get_effect_cmd_desc(&effect_cmd[i]), sizeof (struct dsi_cmd_desc));
+
+ return (buf + cmd_cnt);
+}
+
+static struct dsi_cmd_desc *copy_used_effect_code(struct panel_effect_data *panel_data, struct dsi_cmd_desc *buf, int *cnt)
+{
+ struct dsi_cmd_desc *temp;
+ struct lcd_effect_data *effect_data = panel_data->effect_data;
+ struct lcd_effect *effect = effect_data->effect;
+
+ temp = buf;
+ //protect eys mode(ct level 3) is highest priority
+ if((effect[EFFECT_CE].level) && (effect[EFFECT_CT].level!=3))
+ temp = copy_single_effect_code(panel_data, temp, EFFECT_CE, effect[EFFECT_CE].level, cnt);
+ else
+ temp = copy_single_effect_code(panel_data, temp, EFFECT_CT, effect[EFFECT_CT].level, cnt);
+
+ temp = copy_single_effect_code(panel_data, temp, EFFECT_CABC, effect[EFFECT_CABC].level, cnt);
+ temp = copy_single_effect_code(panel_data, temp, EFFECT_HBM, effect[EFFECT_HBM].level, cnt);
+
+ lcd_effect_info("%s,EFFECT_CE level:%d,EFFECT_CT level:%d,EFFECT_CABC level:%d,EFFECT_HBM level:%d\n",__func__,
+ effect[EFFECT_CE].level,effect[EFFECT_CT].level,effect[EFFECT_CABC].level,effect[EFFECT_HBM].level);
+
+ return temp;
+}
+
+static struct dsi_cmd_desc *copy_all_effect_code(struct panel_effect_data *panel_data, struct dsi_cmd_desc *buf, int *cnt)
+{
+ struct dsi_cmd_desc *temp;
+ struct lcd_effect_data *effect_data = panel_data->effect_data;
+ struct lcd_effect *effect = effect_data->effect;
+ struct lcd_effect_cmds *effect_cmd;
+ int i, j;
+ int cmd_cnt;
+
+ temp = buf;
+ for (i = 0; i < effect_data->supported_effect; i++) {
+ update_effect_cmds(&effect[i], effect[i].level);
+ cmd_cnt = get_effect_cmd_cnt(&effect[i]);
+ effect_cmd = get_effect_cmd(&effect[i]);
+ lcd_effect_info("%s name: [%s] level: [%d],cmd_cnt:[%d]\n", __func__,
+ effect[i].name, effect[i].level,cmd_cnt);
+ *cnt += cmd_cnt;
+ for (j = 0; j < cmd_cnt; j++)
+ memcpy(temp++, get_effect_cmd_desc(&effect_cmd[j]), sizeof (struct dsi_cmd_desc));
+ }
+
+ return temp;
+}
+
+static struct dsi_cmd_desc * copy_mode_code(
+ struct panel_effect_data *panel_data,
+ struct dsi_cmd_desc *buf,
+ int mode_index,
+ int *cnt)
+{
+ struct lcd_mode *mode = &panel_data->mode_data->mode[mode_index];
+ struct lcd_cmds *mode_cmds = &mode->mode_cmd;
+ struct dsi_cmd_desc *temp;
+ int count = 0;
+ int mode_cnt = get_mode_cmd_cnt(mode);
+ lcd_effect_info("%s: line=%d mode_cnt=%d\n", __func__,__LINE__,mode_cnt);
+ if (mode_index == 0) {
+ lcd_effect_info("%s: current is custom mode\n", __func__);
+ temp = copy_all_effect_code(panel_data, buf, &count);
+ *cnt += count;
+ } else {
+ lcd_effect_info("%s: current is %s\n", __func__, mode->name);
+ memcpy(buf, mode_cmds->cmd, mode_cnt * sizeof (struct dsi_cmd_desc));
+ temp = buf + mode_cnt;
+ *cnt += mode_cnt;
+ }
+
+ return temp;
+}
+
+static int set_mode(struct msm_fb_data_type *mfd, struct panel_effect_data *panel_data, int index)
+{
+ struct lcd_cmds lcd_cmd;
+ struct dsi_cmd_desc *temp;
+ int cnt = 0;
+ int ret;
+
+ lcd_cmd.cmd = panel_data->buf;
+
+ temp = copy_head_code(panel_data, panel_data->buf, &cnt);
+ copy_mode_code(panel_data, temp, index, &cnt);
+
+ lcd_cmd.cnt = cnt;
+
+ ret = send_lcd_cmds(mfd, &lcd_cmd);
+ if (ret >= 0 || ret == -EPERM) {
+ panel_data->mode_data->current_mode = index;
+ lcd_effect_info("%s %s success\n", __func__, panel_data->mode_data->mode[index].name);
+ ret = 0;
+ }
+ if (is_show_lcd_param)
+ show_lcd_param(lcd_cmd.cmd, lcd_cmd.cnt);
+
+ return ret;
+}
+
+static int set_effect(struct msm_fb_data_type *mfd, struct panel_effect_data *panel_data, int index, int level)
+{
+ struct lcd_cmds lcd_cmd;
+ struct dsi_cmd_desc *temp;
+ int cnt = 0;
+ int ret;
+
+ lcd_cmd.cmd = panel_data->buf;
+
+ temp = copy_head_code(panel_data, panel_data->buf, &cnt);
+ copy_single_effect_code(panel_data, temp, index, level, &cnt);
+
+ lcd_cmd.cnt = cnt;
+
+ ret = send_lcd_cmds(mfd, &lcd_cmd);
+
+ if (ret >= 0 || ret == -EPERM) {
+ panel_data->effect_data->effect[index].level = level;
+ lcd_effect_info("%s name: [%s] level: [%d] success\n", __func__, panel_data->effect_data->effect[index].name, level);
+ ret = 0;
+ }
+ if (is_show_lcd_param)
+ show_lcd_param(lcd_cmd.cmd, lcd_cmd.cnt);
+
+ return ret;
+}
+
+static int lcd_get_mode(struct lcd_mode_data *mode_data)
+{
+ if (mode_data == NULL)
+ return -EINVAL;
+
+ lcd_effect_info("%s name: [%s] index: [%d]\n", __func__, mode_data->mode[mode_data->current_mode].name, mode_data->current_mode);
+ return mode_data->current_mode;
+}
+
+static int lcd_get_supported_effect_level(struct lcd_effect_data *effect_data, int index)
+{
+ if (effect_data == NULL || index < 0) {
+ lcd_effect_info("%s index: %d invalid, max index is: 0 - %d\n", __func__, index, effect_data->supported_effect - 1);
+ return -EINVAL;
+ }
+
+ lcd_effect_info("%s name: [%s] index: [%d] max_level: [%d]\n", __func__, effect_data->effect[index].name, index, effect_data->effect[index].max_level);
+ return effect_data->effect[index].max_level;
+}
+static int lcd_get_effect_level(struct lcd_effect_data *effect_data, int index)
+{
+ if (effect_data == NULL || index < 0) {
+ lcd_effect_info("%s index: %d invalid, max index is: 0 - %d\n", __func__, index, effect_data->supported_effect - 1);
+ return -EINVAL;
+ }
+
+ lcd_effect_info("%s name: [%s] index: [%d] level: [%d]\n", __func__, effect_data->effect[index].name, index, effect_data->effect[index].level);
+ return effect_data->effect[index].level;
+}
+
+static int lcd_get_supported_effect(struct lcd_effect_data *effect_data, struct hal_panel_data *data)
+{
+ int i;
+
+ if (effect_data == NULL || data == NULL)
+ return -EINVAL;
+
+ if (EFFECT_COUNT < effect_data->supported_effect)
+ return -ENOMEM;
+
+ for (i = 0; i < effect_data->supported_effect; i++) {
+ memcpy(data->effect[i].name, effect_data->effect[i].name, strlen(effect_data->effect[i].name));
+ }
+ data->effect_cnt = effect_data->supported_effect;
+
+ return data->effect_cnt;
+}
+
+static int lcd_get_supported_mode(struct lcd_mode_data *mode_data, struct hal_panel_data *data)
+{
+ int i;
+
+ if (mode_data == NULL || data == NULL)
+ return -EINVAL;
+
+ if (MODE_COUNT < mode_data->supported_mode)
+ return -ENOMEM;
+
+ for (i = 0; i < mode_data->supported_mode; i++) {
+ memcpy(data->mode[i].name, mode_data->mode[i].name, strlen(mode_data->mode[i].name));
+ }
+ data->mode_cnt = mode_data->supported_mode;
+
+ return data->mode_cnt;
+}
+
+static int lcd_set_mode(struct msm_fb_data_type *mfd, struct panel_effect_data *panel_data, int mode)
+{
+ int ret;
+ struct lcd_mode_data *mode_data = panel_data->mode_data;
+
+ if (mode >= mode_data->supported_mode || mode < 0) {
+ lcd_effect_info("%s mode invalid, max mode is: 0 - %d\n", __func__, mode_data->supported_mode - 1);
+ return -EINVAL;
+ }
+
+ ret = set_mode(mfd, panel_data, mode);
+
+ return ret;
+}
+
+static int lcd_set_effect(struct msm_fb_data_type *mfd, struct panel_effect_data *panel_data, int index, int level)
+{
+ int ret = 0;
+ struct lcd_effect_data *effect_data = panel_data->effect_data;
+
+#ifdef CONFIG_BACKLIGHT_LM36923
+ if(index == 3){
+ ret = lm36923_sunlight_settings(level);
+ }
+#endif
+
+ if (index >= effect_data->supported_effect || index < 0) {
+ lcd_effect_info("%s index invalid, max index is: 0 - %d\n", __func__, effect_data->supported_effect - 1);
+ return -EINVAL;
+ }
+
+ if (level >= effect_data->effect[index].max_level || level < 0) {
+ lcd_effect_info("%s level invalid, max level is: 0 - %d\n", __func__, effect_data->effect[index].max_level - 1);
+ return -EINVAL;
+ }
+
+ ret = set_effect(mfd, panel_data, index, level);
+
+ return ret;
+}
+
+int update_init_code(
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata,
+ struct panel_effect_data *panel_data,
+ void (*mdss_dsi_panel_cmds_send)(struct mdss_dsi_ctrl_pdata *ctrl,struct dsi_panel_cmds *pcmds,u32 flags))
+{
+ struct lcd_cmds lcd_cmd;
+ struct dsi_cmd_desc *temp;
+ struct lcd_cmds *save_cmd = &panel_data->save_cmd;
+ int cnt = 0;
+ int ret = 0;
+ lcd_cmd.cmd = panel_data->buf;
+
+ temp = copy_init_code(panel_data, &cnt);
+
+ temp = copy_used_effect_code(panel_data, temp, &cnt);
+ temp = copy_sleep_out_code(panel_data, temp, &cnt);
+
+ lcd_cmd.cnt = cnt;
+
+#ifdef READ_LCD_PARAM
+ if (read_lcd_file)
+ {
+ if (!open_lcd_and_get_data()) {
+ ctrl_pdata->on_cmds.cmds = lcd_txt_cmds.cmd;
+ ctrl_pdata->on_cmds.cmd_cnt = lcd_txt_cmds.cnt;
+ lcd_effect_info("%s Use Txt file param\n", __func__);
+ }
+ } else
+#endif
+ {
+ ctrl_pdata->on_cmds.cmds = lcd_cmd.cmd;
+ ctrl_pdata->on_cmds.cmd_cnt = lcd_cmd.cnt;
+ lcd_effect_info("%s Use system param\n", __func__);
+ }
+
+ mdss_dsi_panel_cmds_send(ctrl_pdata, &ctrl_pdata->on_cmds,CMD_REQ_COMMIT);
+
+ if (is_show_lcd_param)
+ show_lcd_param(ctrl_pdata->on_cmds.cmds, ctrl_pdata->on_cmds.cmd_cnt);
+
+ ctrl_pdata->on_cmds.cmds = save_cmd->cmd;
+ ctrl_pdata->on_cmds.cmd_cnt = save_cmd->cnt;
+#ifdef READ_LCD_PARAM
+ clear_data_and_mem();
+#endif
+ return ret;
+}
+
+
+int handle_lcd_effect_data(
+ struct msm_fb_data_type *mfd,
+ struct panel_effect_data *panel_data,
+ struct hal_panel_ctrl_data *ctrl_data)
+{
+ struct lcd_effect_data *effect_data = panel_data->effect_data;
+ struct lcd_mode_data *mode_data = panel_data->mode_data;
+ int mode_index = mode_data->current_mode;
+ int ret = 0;
+
+ switch(ctrl_data->id) {
+ case GET_EFFECT_NUM:
+ ret = lcd_get_supported_effect(effect_data, &ctrl_data->panel_data);
+ break;
+ case GET_EFFECT_LEVEL:
+ ret = lcd_get_supported_effect_level(effect_data, ctrl_data->index);
+ break;
+ case GET_EFFECT:
+ ret = lcd_get_effect_level(effect_data, ctrl_data->index);
+ break;
+ case GET_MODE_NUM:
+ ret = lcd_get_supported_mode(mode_data, &ctrl_data->panel_data);
+ break;
+ case GET_MODE:
+ ret = lcd_get_mode(mode_data);
+ break;
+ case SET_EFFECT:
+ if (is_custom_mode(mode_data)) {
+ pr_info("%s:SET_EFFECT,index=%d,level=%d\n",__func__,ctrl_data->index,ctrl_data->level);
+ ret = lcd_set_effect(mfd, panel_data, ctrl_data->index, ctrl_data->level);
+ } else {
+ lcd_effect_info("(%s) can't support change effect\n", mode_data->mode[mode_index].name);
+ ret = -EINVAL;
+ }
+ break;
+ case SET_MODE:
+ ret = lcd_set_mode(mfd, panel_data, ctrl_data->mode);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+int malloc_lcd_effect_code_buf(struct panel_effect_data *panel_data)
+{
+ struct lcd_cmds *save_cmd = &panel_data->save_cmd;
+ if (panel_data->buf == NULL) {
+ panel_data->buf_size = get_init_code_max_cnt(panel_data, save_cmd);
+ panel_data->buf = kmalloc(sizeof(struct dsi_cmd_desc) * panel_data->buf_size, GFP_KERNEL);
+ if ( !panel_data->buf)
+ return -ENOMEM;
+ return 0;
+ }
+ return 0;
+}
+#ifdef READ_LCD_PARAM
+static int get_lcd_param_func(const char *val, struct kernel_param *kp)
+{
+ int value;
+ int ret = param_set_int(val, kp);
+
+ if(ret < 0)
+ {
+ pr_info(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ value = *((int*)kp->arg);
+ if (value) {
+ read_lcd_file = 1;
+ pr_info("prepare to read lcd param...\n");
+ } else {
+ read_lcd_file = 0;
+ pr_info("show lcd param off...\n");
+ }
+ return 0;
+}
+
+module_param_call(read_txt_file, get_lcd_param_func, param_get_int, &read_lcd_file, S_IRUSR | S_IWUSR);
+#endif
+static int show_lcd_param_func(const char *val, struct kernel_param *kp)
+{
+ int value;
+ int ret = param_set_int(val, kp);
+
+ if(ret < 0)
+ {
+ pr_info(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ value = *((int*)kp->arg);
+ if (value) {
+ is_show_lcd_param = 1;
+ pr_info("show lcd param on...\n");
+ } else {
+ is_show_lcd_param = 0;
+ pr_info("show lcd param off...\n");
+ }
+ return 0;
+}
+
+module_param_call(show_lcd_cmd, show_lcd_param_func, param_get_int, &is_show_lcd_param, S_IRUSR | S_IWUSR);
diff --git a/drivers/video/fbdev/msm/lcd_effect.h b/drivers/video/fbdev/msm/lcd_effect.h
new file mode 100644
index 000000000000..b7f4848b9c3a
--- /dev/null
+++ b/drivers/video/fbdev/msm/lcd_effect.h
@@ -0,0 +1,90 @@
+#ifndef __LCD_EFFECT_H__
+#define __LCD_EFFECT_H__
+
+#include <linux/msm_mdp.h>
+#include <linux/moduleparam.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include "mdss_panel.h"
+#include "mdss_dsi.h"
+#include "mdss_fb.h"
+#include "mdss_dsi_cmd.h"
+
+#define CMDS_LAST_CNT 1
+enum {
+ EFFECT_CE = 0,
+ EFFECT_CT,
+ EFFECT_CABC,
+ EFFECT_HBM,
+};
+
+struct lcd_cmds {
+ struct dsi_cmd_desc *cmd;
+ int cnt;
+};
+
+struct lcd_effect_code {
+ char **code;
+ const int cnt;
+};
+
+struct lcd_effect_cmds {
+ struct lcd_effect_code effect_code;
+ struct lcd_cmds lcd_cmd;
+};
+
+struct lcd_effect_cmd_data {
+ struct lcd_effect_cmds *effect_cmd;
+ const int cnt;
+};
+
+struct lcd_effect {
+ //char *aliases;
+ const char *name;
+ const int max_level;
+ int level;
+ struct lcd_effect_cmd_data effect_cmd_data;
+};
+
+struct lcd_mode {
+ //char *aliases;
+ const char *name;
+ const int bl_ctrl;
+ struct lcd_cmds mode_cmd;
+};
+
+typedef enum {
+ EFFECT = 0,
+ MODE = 1,
+}control_mode;
+
+struct lcd_effect_data {
+ struct lcd_effect *effect;
+ struct lcd_cmds *head_cmd;
+ const int supported_effect;
+};
+
+struct lcd_mode_data {
+ struct lcd_mode *mode;
+ struct lcd_cmds *head_cmd;
+ const int supported_mode;
+ int current_mode;
+};
+struct panel_effect_data {
+ struct lcd_effect_data *effect_data;
+ struct lcd_mode_data *mode_data;
+ struct lcd_cmds save_cmd;
+ struct dsi_cmd_desc *buf;
+ int buf_size;
+};
+
+
+int malloc_lcd_effect_code_buf(struct panel_effect_data *panel_data);
+int update_init_code(
+ struct mdss_dsi_ctrl_pdata*,
+ struct panel_effect_data *,
+ void (*)(struct mdss_dsi_ctrl_pdata *ctrl,struct dsi_panel_cmds *pcmds,u32 flags));
+int handle_lcd_effect_data(struct msm_fb_data_type *, struct panel_effect_data *, struct hal_panel_ctrl_data *);
+int get_effect_index_by_name(char *, struct panel_effect_data *);
+int get_mode_index_by_name(char *, struct panel_effect_data *);
+#endif
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index 7454bba68117..f5fbada08c0e 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -2914,7 +2914,7 @@ static int mdp3_resume(struct platform_device *pdev)
#endif
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
static int mdp3_runtime_resume(struct device *dev)
{
bool device_on = true;
diff --git a/drivers/video/fbdev/msm/mdss_ams520.h b/drivers/video/fbdev/msm/mdss_ams520.h
new file mode 100644
index 000000000000..dc7bf55a4fef
--- /dev/null
+++ b/drivers/video/fbdev/msm/mdss_ams520.h
@@ -0,0 +1,286 @@
+#ifndef MDSS_AMS520_H
+#define MDSS_AMS520_H
+#include "lcd_effect.h"
+#include "mdss_panel.h"
+
+/*********************************** head cmd *************************************/
+//static char ams520_addr_mode[] = {0x36,0x00};
+
+static struct dsi_cmd_desc ams520_packet_head_cmds[] = {
+// {{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ams520_addr_mode)}, ams520_addr_mode},
+};
+/*********************************** ce head cmd *************************************/
+//struct dsi_ctrl_hdr cmd_head={0x29,1,0,0,0,2};
+static char ams520_normal_mode_cmd[] = {0x00,0x00};
+
+static struct dsi_cmd_desc ams520_ct_cold_cmd[] = {
+ {{0x29,1,0,0,0,2},ams520_normal_mode_cmd},
+};
+
+static struct dsi_cmd_desc ams520_ct_default_cmd[] = {
+ {{0x29,1,0,0,0,2},ams520_normal_mode_cmd},
+};
+
+static struct dsi_cmd_desc ams520_ct_warm_cmd[] = {
+ {{0x29,1,0,0,0,2},ams520_normal_mode_cmd},
+};
+
+static char ams520_ce_soft_cmd1[] = {0x00,0x00};
+static char ams520_ce_default_cmd1[] = {0x00,0x00};
+static char ams520_ce_bright_cmd1[] = {0x00,0x00};
+
+static struct dsi_cmd_desc ams520_ce_soft_cmd[] = {
+ {{0x29,0,0,0,0,2},ams520_normal_mode_cmd},
+ {{0x29,1,0,0,0,2},ams520_ce_soft_cmd1},
+};
+static struct dsi_cmd_desc ams520_ce_default_cmd[] = {
+ {{0x29,0,0,0,0,2},ams520_normal_mode_cmd},
+ {{0x29,1,0,0,0,2},ams520_ce_default_cmd1},
+};
+static struct dsi_cmd_desc ams520_ce_bright_cmd[] = {
+ {{0x29,0,0,0,0,2},ams520_normal_mode_cmd},
+ {{0x29,1,0,0,0,2},ams520_ce_bright_cmd1},
+};
+
+/*********************************** ce *************************************/
+static char ams520_ce_enable0[] = {0xF0,0x5A,0x5A};
+static char ams520_seed_edbe[] = {0xED,0xBE};
+static char ams520_seed_b008[] = {0xB0,0x08};
+static char ams520_ce_seed_setv1[] = {0xED,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,
+ 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+ 0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF};//original 7300K
+static char ams520_seed_b01d[] = {0xB0,0x1D};
+static char ams520_ce_seed_setv2[] = {0xED,0xA3,0x01,0x04,0x44,0xE0,0x12,0x03,
+ 0x08,0xB7,0x4B,0xF4,0xD9,0xAB,0x09,
+ 0xBB,0xEB,0xE7,0x17,0xFF,0xFF,0xFF};//sRGB 7300K
+static char ams520_seed_b032[] = {0xB0,0x32};
+static char ams520_ce_seed_setv3[] = {0xED,0xEA,0x01,0x06,0x00,0xD2,0x06,0x04,
+ 0x09,0xCC,0x00,0xEB,0xD0,0xFC,0x0B,
+ 0xD8,0xE9,0xE6,0x0D,0xFF,0xFF,0xE7};//adobe 7300K
+
+static char ams520_ce0[] = {0x57,0x4C};//Set1
+static char ams520_ce1[] = {0x57,0x44};//Set2
+static char ams520_ce2[] = {0x57,0xA4};//Set3
+//static char ams520_ce3[] = {0x57,0xA4};//CRC off
+static char ams520_ce_lock0[] = {0xF0,0xA5,0xA5};
+
+char *ams520_ce[] = {
+ ams520_ce0,
+ ams520_ce1,
+ ams520_ce2,
+ ams520_ce0,
+};
+static char *ams520_ce_enable[] = {
+ ams520_ce_enable0,
+};
+static char *ams520_seed_ed[] = {
+ ams520_seed_edbe,
+};
+static char *ams520_seed_b01[] = {
+ ams520_seed_b008,
+};
+static char *ams520_ce_seed_set1[] = {
+ ams520_ce_seed_setv1,
+};
+static char *ams520_seed_b02[] = {
+ ams520_seed_b01d,
+};
+static char *ams520_ce_seed_set2[] = {
+ ams520_ce_seed_setv2,
+};
+static char *ams520_seed_b03[] = {
+ ams520_seed_b032,
+};
+static char *ams520_ce_seed_set3[] = {
+ ams520_ce_seed_setv3,
+};
+
+static char *ams520_ce_lock[] = {
+ ams520_ce_lock0,
+};
+
+static struct dsi_cmd_desc ams520_effect_ce[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ce0)}, ams520_ce0},
+};
+static struct dsi_cmd_desc ams520_effect_ce_enable[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ce_enable0)}, ams520_ce_enable0},
+};
+static struct dsi_cmd_desc ams520_effect_ed[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_seed_edbe)}, ams520_seed_edbe},
+};
+static struct dsi_cmd_desc ams520_effect_b01[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_seed_b008)}, ams520_seed_b008},
+};
+static struct dsi_cmd_desc ams520_effect_ce_seed_set1[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ce_seed_setv1)}, ams520_ce_seed_setv1},
+};
+static struct dsi_cmd_desc ams520_effect_b02[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_seed_b01d)}, ams520_seed_b01d},
+};
+static struct dsi_cmd_desc ams520_effect_ce_seed_set2[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ce_seed_setv2)}, ams520_ce_seed_setv2},
+};
+static struct dsi_cmd_desc ams520_effect_b03[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_seed_b032)}, ams520_seed_b032},
+};
+static struct dsi_cmd_desc ams520_effect_ce_seed_set3[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ce_seed_setv3)}, ams520_ce_seed_setv3},
+};
+static struct dsi_cmd_desc ams520_effect_ce_lock[] = {
+ {{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ams520_ce_lock0)}, ams520_ce_lock0},
+};
+
+struct lcd_effect_cmds ams520_effect_ce_cmd[] = {
+ {{ams520_ce_enable, ARRAY_SIZE(ams520_ce_enable)}, {ams520_effect_ce_enable, ARRAY_SIZE(ams520_effect_ce_enable)}},
+ {{ams520_seed_ed, ARRAY_SIZE(ams520_seed_ed)}, {ams520_effect_ed, ARRAY_SIZE(ams520_effect_ed)}},
+ {{ams520_seed_b01, ARRAY_SIZE(ams520_seed_b01)}, {ams520_effect_b01, ARRAY_SIZE(ams520_effect_b01)}},
+ {{ams520_ce_seed_set1, ARRAY_SIZE(ams520_ce_seed_set1)}, {ams520_effect_ce_seed_set1, ARRAY_SIZE(ams520_effect_ce_seed_set1)}},
+ {{ams520_seed_b02, ARRAY_SIZE(ams520_seed_b02)}, {ams520_effect_b02, ARRAY_SIZE(ams520_effect_b02)}},
+ {{ams520_ce_seed_set2, ARRAY_SIZE(ams520_ce_seed_set2)}, {ams520_effect_ce_seed_set2, ARRAY_SIZE(ams520_effect_ce_seed_set2)}},
+ {{ams520_seed_b03, ARRAY_SIZE(ams520_seed_b03)}, {ams520_effect_b03, ARRAY_SIZE(ams520_effect_b03)}},
+ {{ams520_ce_seed_set3, ARRAY_SIZE(ams520_ce_seed_set3)}, {ams520_effect_ce_seed_set3, ARRAY_SIZE(ams520_effect_ce_seed_set3)}},
+ {{ams520_ce_lock, ARRAY_SIZE(ams520_ce_lock)}, {ams520_effect_ce_lock, ARRAY_SIZE(ams520_effect_ce_lock)}},
+ {{ams520_ce_enable, ARRAY_SIZE(ams520_ce_enable)}, {ams520_effect_ce_enable, ARRAY_SIZE(ams520_effect_ce_enable)}},
+ {{ams520_seed_ed, ARRAY_SIZE(ams520_seed_ed)}, {ams520_effect_ed, ARRAY_SIZE(ams520_effect_ed)}},
+ {{ams520_ce, ARRAY_SIZE(ams520_ce)}, {ams520_effect_ce, ARRAY_SIZE(ams520_effect_ce)}},
+ {{ams520_ce_lock, ARRAY_SIZE(ams520_ce_lock)}, {ams520_effect_ce_lock, ARRAY_SIZE(ams520_effect_ce_lock)}},
+};
+
+/*********************************** ct *************************************/
+static char ams520_ct_seed_setv1[] = {0xED,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,
+ 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+ 0xFF,0xFF,0xFF,0x00,0xFF,0xF6,0xD1,};//original 6000
+static char ams520_ct_seed_setv2[] = {0xED,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,
+ 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+ 0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF};//original 7300K
+static char ams520_ct_seed_setv3[] = {0xED,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,
+ 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+ 0xFF,0xFF,0xFF,0x00,0xD0,0xE8,0xFF,
+};
+static char ams520_ct_seed_setv4[] = {0xED,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,
+ 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,
+ 0xFF,0xFF,0xFF,0x00,0xD0,0xc6,0x73,
+};
+
+static char *ams520_ct_seed_set1[] = {
+ ams520_ct_seed_setv1,
+ ams520_ct_seed_setv1,
+ ams520_ct_seed_setv1,
+ ams520_ct_seed_setv4,
+};
+static char *ams520_ct_seed_set2[] = {
+ ams520_ct_seed_setv2,
+};
+static char *ams520_ct_seed_set3[] = {
+ ams520_ct_seed_setv3,
+};
+
+static struct dsi_cmd_desc ams520_effect_ct_seed_set1[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ct_seed_setv1)}, ams520_ct_seed_setv1},
+};
+static struct dsi_cmd_desc ams520_effect_ct_seed_set2[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ct_seed_setv2)}, ams520_ct_seed_setv2},
+};
+static struct dsi_cmd_desc ams520_effect_ct_seed_set3[] = {
+ {{DTYPE_GEN_LWRITE, 0, 0, 0, 0, sizeof(ams520_ct_seed_setv3)}, ams520_ct_seed_setv3},
+};
+
+struct lcd_effect_cmds ams520_effect_ct_cmd[] = {
+ {{ams520_ce_enable, ARRAY_SIZE(ams520_ce_enable)}, {ams520_effect_ce_enable, ARRAY_SIZE(ams520_effect_ce_enable)}},
+ {{ams520_seed_ed, ARRAY_SIZE(ams520_seed_ed)}, {ams520_effect_ed, ARRAY_SIZE(ams520_effect_ed)}},
+ {{ams520_seed_b01, ARRAY_SIZE(ams520_seed_b01)}, {ams520_effect_b01, ARRAY_SIZE(ams520_effect_b01)}},
+ {{ams520_ct_seed_set1, ARRAY_SIZE(ams520_ct_seed_set1)}, {ams520_effect_ct_seed_set1, ARRAY_SIZE(ams520_effect_ct_seed_set1)}},
+ {{ams520_seed_b02, ARRAY_SIZE(ams520_seed_b02)}, {ams520_effect_b02, ARRAY_SIZE(ams520_effect_b02)}},
+ {{ams520_ct_seed_set2, ARRAY_SIZE(ams520_ct_seed_set2)}, {ams520_effect_ct_seed_set2, ARRAY_SIZE(ams520_effect_ct_seed_set2)}},
+ {{ams520_seed_b03, ARRAY_SIZE(ams520_seed_b03)}, {ams520_effect_b03, ARRAY_SIZE(ams520_effect_b03)}},
+ {{ams520_ct_seed_set3, ARRAY_SIZE(ams520_ct_seed_set3)}, {ams520_effect_ct_seed_set3, ARRAY_SIZE(ams520_effect_ct_seed_set3)}},
+ {{ams520_ce_lock, ARRAY_SIZE(ams520_ce_lock)}, {ams520_effect_ce_lock, ARRAY_SIZE(ams520_effect_ce_lock)}},
+ {{ams520_ce_enable, ARRAY_SIZE(ams520_ce_enable)}, {ams520_effect_ce_enable, ARRAY_SIZE(ams520_effect_ce_enable)}},
+ {{ams520_seed_ed, ARRAY_SIZE(ams520_seed_ed)}, {ams520_effect_ed, ARRAY_SIZE(ams520_effect_ed)}},
+ {{ams520_ce, ARRAY_SIZE(ams520_ce)}, {ams520_effect_ce, ARRAY_SIZE(ams520_effect_ce)}},
+ {{ams520_ce_lock, ARRAY_SIZE(ams520_ce_lock)}, {ams520_effect_ce_lock, ARRAY_SIZE(ams520_effect_ce_lock)}},
+};
+
+/************************************ cabc ***********************************/
+static char ams520_cabc0[] = {0x55, 0x00};
+static char ams520_cabc1[] = {0x55, 0x01};
+static char ams520_cabc2[] = {0x55, 0x02};
+static char ams520_cabc3[] = {0x55, 0x03};
+
+char *ams520_cabc[] = {
+ ams520_cabc0,
+ ams520_cabc1,
+ ams520_cabc2,
+ ams520_cabc3,
+};
+
+static struct dsi_cmd_desc ams520_effect_cabc[] = {
+ {{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ams520_cabc0)}, ams520_cabc0},
+};
+struct lcd_effect_cmds ams520_effect_cabc_cmd[] = {
+ {{ams520_cabc, ARRAY_SIZE(ams520_cabc)}, {ams520_effect_cabc, ARRAY_SIZE(ams520_effect_cabc)}},
+};
+/************************************* hbm ***********************************/
+static char ams520_hbm0[] = {0x53,0x20};//dimming speed 1frames
+static char ams520_hbm1[] = {0x53,0xe0};
+static char ams520_hbm2[] = {0x53,0x28};//dimming speed 32frames
+static char ams520_hbm3[] = {0x53,0xe8};
+
+
+static char *ams520_hbm[] = {
+ ams520_hbm0,//32frames
+ ams520_hbm1,
+ ams520_hbm2,
+ ams520_hbm3,
+};
+
+static struct dsi_cmd_desc ams520_effect_hbm[] = {
+ {{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ams520_hbm0)}, ams520_hbm0},
+};
+
+struct lcd_effect_cmds ams520_effect_hbm_cmd[] = {
+ {{ams520_hbm, ARRAY_SIZE(ams520_hbm)}, {ams520_effect_hbm, ARRAY_SIZE(ams520_effect_hbm)}},
+};
+
+
+/************************************** normal mode **************************************/
+static struct dsi_cmd_desc ams520_normal_mode[] = {
+ {{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ams520_normal_mode_cmd)}, ams520_normal_mode_cmd},
+};
+
+/*********************************** all effect ************************************/
+struct lcd_effect ams520_effect[] = {
+ {"ce", ARRAY_SIZE(ams520_ce), 0, {ams520_effect_ce_cmd, ARRAY_SIZE(ams520_effect_ce_cmd)}},
+ {"ct", ARRAY_SIZE(ams520_ce), 0, {ams520_effect_ct_cmd, ARRAY_SIZE(ams520_effect_ct_cmd)}},
+ {"cabc", ARRAY_SIZE(ams520_cabc), 0, {ams520_effect_cabc_cmd, ARRAY_SIZE(ams520_effect_cabc_cmd)}},
+ {"hbm", ARRAY_SIZE(ams520_hbm), 0, {ams520_effect_hbm_cmd, ARRAY_SIZE(ams520_effect_hbm_cmd)}},
+};
+/**************************************************************************************/
+
+/************************************** all mode **************************************/
+struct lcd_mode ams520_mode[] = {
+ {"custom_mode", 0, {ams520_normal_mode, ARRAY_SIZE(ams520_normal_mode)}},
+ {"ct_warm_mode", 0, {ams520_ct_warm_cmd, ARRAY_SIZE(ams520_ct_warm_cmd)}},
+ {"ct_default_mode", 0, {ams520_ct_default_cmd, ARRAY_SIZE(ams520_ct_default_cmd)}},
+ {"ct_cold_mode", 0, {ams520_ct_cold_cmd, ARRAY_SIZE(ams520_ct_cold_cmd)}},
+ {"ce_soft_mode", 0, {ams520_ce_soft_cmd, ARRAY_SIZE(ams520_ce_soft_cmd)}},
+ {"ce_default_mode", 0, {ams520_ce_default_cmd, ARRAY_SIZE(ams520_ce_default_cmd)}},
+ {"ce_bright_mode", 0, {ams520_ce_bright_cmd, ARRAY_SIZE(ams520_ce_bright_cmd)}},
+};
+/**************************************************************************************/
+static struct lcd_cmds ams520_head_cmds =
+ {ams520_packet_head_cmds, ARRAY_SIZE(ams520_packet_head_cmds)};
+
+static struct lcd_effect_data ams520_effect_data =
+ {ams520_effect, &ams520_head_cmds, ARRAY_SIZE(ams520_effect)};
+
+static struct lcd_mode_data ams520_mode_data =
+ {ams520_mode, &ams520_head_cmds, ARRAY_SIZE(ams520_mode), 0};
+
+/**************************************************************************************/
+struct panel_effect_data lcd_ams520_data = {
+ &ams520_effect_data,
+ &ams520_mode_data,
+};
+
+#endif
diff --git a/drivers/video/fbdev/msm/mdss_dsi_cmd.h b/drivers/video/fbdev/msm/mdss_dsi_cmd.h
index f323a2b665b6..24fe6795d071 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_cmd.h
+++ b/drivers/video/fbdev/msm/mdss_dsi_cmd.h
@@ -98,6 +98,9 @@ struct dsi_cmd_desc {
#define CMD_REQ_MAX 4
#define CMD_REQ_RX 0x0001
#define CMD_REQ_COMMIT 0x0002
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+#define CMD_CLK_CTRL 0x0004
+#endif
#define CMD_CLK_CTRL 0x0004
#define CMD_REQ_UNICAST 0x0008
#define CMD_REQ_DMA_TPG 0x0040
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 1ab256cd08af..dd5b5c4b5d10 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -22,6 +22,24 @@
#include <linux/qpnp/pwm.h>
#include <linux/err.h>
#include <linux/string.h>
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/time.h>
+ #include <linux/fs.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+#include "mdss_fb.h"
+#include "mdss_ams520.h"
+ #include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/regulator/consumer.h>
+#endif
#include "mdss_dsi.h"
#include "mdss_dba_utils.h"
@@ -33,6 +51,31 @@
#define VSYNC_DELAY msecs_to_jiffies(17)
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+struct panel_effect_data lcd_data;
+ int is_show_lcd_param = 0;
+extern struct msm_fb_data_type *mfd_priv;
+ int show_lcd_param(struct dsi_cmd_desc *cmds, int cmd_cnt)
+{
+ int i, j;
+ printk("======================================= cmds_cnt %d =========================================\n", cmd_cnt);
+ for (i = 0; i < cmd_cnt; i++) {
+ printk("%2x %2x %2x %2x %2x %2x ", cmds[i].dchdr.dtype,
+ cmds[i].dchdr.last,
+ cmds[i].dchdr.vc,
+ cmds[i].dchdr.ack,
+ cmds[i].dchdr.wait,
+ cmds[i].dchdr.dlen);
+ for (j = 0; j < cmds[i].dchdr.dlen; j++) {
+ printk("%2x ", cmds[i].payload[j]);
+ }
+ printk("\n");
+ }
+ pr_debug("===========================================================================================\n");
+ return 0;
+}
+#endif
+
DEFINE_LED_TRIGGER(bl_led_trigger);
void mdss_dsi_panel_pwm_cfg(struct mdss_dsi_ctrl_pdata *ctrl)
@@ -247,6 +290,167 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level)
mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+static int lcd_register_rwlen=2;
+static int lcd_register_id=0;
+static int lcd_register_value=0;
+static char lcd_register[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; /* DTYPE_DCS_WRITE1 */
+static struct mdss_dsi_ctrl_pdata *registerctrl;
+static struct dsi_cmd_desc write_register_cmd = {
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 1, 2},
+ lcd_register
+};
+static struct dsi_cmd_desc read_register_cmd = {
+ {DTYPE_GEN_READ, 1, 0, 1, 5, 2},
+ lcd_register
+};
+ static int mdss_dsi_read_register(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ struct dcs_cmd_req cmdreq;
+ int i = 0;
+ memset(&cmdreq, 0, sizeof(cmdreq));
+ cmdreq.cmds = &read_register_cmd;
+ cmdreq.cmds_cnt = 1;
+ cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_RX;
+ cmdreq.rlen = 2;//ctrl->status_cmds_rlen;
+ cmdreq.cb = NULL;
+ if(ctrl && ctrl->panel_data.panel_info.panel_power_state) {
+ cmdreq.rbuf = ctrl->status_buf.data;
+ mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+ printk("%s: LCD register 0x%02x value:\n", __func__,lcd_register_id);
+ for(i=0; i<lcd_register_rwlen; i++){
+ printk("0x%02x ", ctrl->status_buf.data[i]);
+ }
+ printk("\n");
+ return ctrl->status_buf.data[0];
+ } else {
+ pr_err("%s: LCD panel have powered off\n", __func__);
+ return -1;
+ }
+}
+void mdss_dsi_write_register(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ struct dcs_cmd_req cmdreq;
+ //pr_err(KERN_ERR"%s,ndx=%d \n", __func__,ctrl->ndx);
+ memset(&cmdreq, 0, sizeof(cmdreq));
+ cmdreq.cmds = &write_register_cmd;
+ cmdreq.cmds_cnt = 1;
+ cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL;
+ cmdreq.rlen = 0;
+ cmdreq.cb = NULL;
+ if(ctrl && ctrl->panel_data.panel_info.panel_power_state)
+ mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+ else
+ pr_err("%s: LCD panel have powered off\n", __func__);
+ }
+ static int set_lcd_register_rwlen_func(const char *val, struct kernel_param *kp)
+{
+ int ret = param_set_int(val, kp);
+ if(ret < 0)
+ {
+ pr_err(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ lcd_register_rwlen = *((int*)kp->arg);
+ if(lcd_register_rwlen > sizeof(lcd_register)){
+ printk("%s register read write max length is %d\n", __func__,(int)sizeof(lcd_register));
+ lcd_register_rwlen = 2;
+ return 0;
+ }
+ write_register_cmd.dchdr.dlen = (short)lcd_register_rwlen;
+ read_register_cmd.dchdr.dlen = (short)lcd_register_rwlen;
+ printk("%s register read write length is:%d\n", __func__,lcd_register_rwlen);
+ return 0;
+}
+ static int get_lcd_register_rwlen_func(char *val, struct kernel_param *kp)
+{
+ int ret=sprintf(val, "0x%02x\n", lcd_register_rwlen);
+ printk("%s register read write leagth is:0x%02x\n", __func__,lcd_register_rwlen);
+ return ret;
+}
+ static int set_lcd_register_id_func(const char *val, struct kernel_param *kp)
+{
+ int ret = param_set_int(val, kp);
+ if(ret < 0)
+ {
+ pr_err(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ lcd_register_id = *((int*)kp->arg);
+ lcd_register[0]=lcd_register_id;
+ printk("%s register id is:%d\n", __func__,lcd_register_id);
+ return 0;
+}
+ static int get_lcd_register_id_func(char *val, struct kernel_param *kp)
+{
+ int ret=sprintf(val, "0x%02x\n", lcd_register_id);
+ printk("%s register id is:0x%02x\n", __func__,lcd_register_id);
+ return ret;
+}
+ static int set_lcd_register_value_func(const char *val, struct kernel_param *kp)
+{
+ int ret = param_set_ulong(val, kp);
+ int i = 0;
+ if(ret < 0)
+ {
+ pr_err(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ lcd_register_value = *((int*)kp->arg);
+ printk("%s register value is:0x%08x ", __func__,lcd_register_value);
+ for(i=0; i<lcd_register_rwlen; i++){
+ lcd_register[i] = (lcd_register_value >> (lcd_register_rwlen - 1 - i)*8);
+ printk("0x%02x ", lcd_register[i]);
+ }
+ printk("\n");
+ mdss_dsi_write_register(registerctrl);
+ for(i=0; i<sizeof(lcd_register); i++)//8 need change with length
+ lcd_register[i] = 0x00;
+ lcd_register_rwlen = 2;
+ write_register_cmd.dchdr.dlen = (short)lcd_register_rwlen;
+ read_register_cmd.dchdr.dlen = (short)lcd_register_rwlen;
+ return 0;
+}
+ static int get_lcd_register_value_func(char *val, struct kernel_param *kp)
+{
+ int ret=0;
+ lcd_register_value = mdss_dsi_read_register(registerctrl);
+ ret=sprintf(val, "0x%02x\n", lcd_register_value);
+ pr_err(KERN_ERR"%s register value is:0x%02x\n", __func__,lcd_register_value);
+ //pr_err(KERN_ERR"%s register value 2 is:0x%02x\n", __func__,registerctrl->status_buf.data[1]);
+ return ret;
+}
+module_param_call(lcdrwlen, set_lcd_register_rwlen_func,get_lcd_register_rwlen_func, &lcd_register_rwlen, S_IRUSR | S_IWUSR);
+module_param_call(lcdid, set_lcd_register_id_func,get_lcd_register_id_func, &lcd_register_id, S_IRUSR | S_IWUSR);
+module_param_call(lcdvalue, set_lcd_register_value_func,get_lcd_register_value_func, &lcd_register_value, S_IRUSR | S_IWUSR);
+static int lcd_overturn = 0;
+static int get_lcd_overturn_func(char *val, struct kernel_param *kp)
+{
+ int ret=sprintf(val, "0x%02x\n", lcd_overturn);
+ pr_err(KERN_ERR"%s lcd_overturn is:0x%02x\n", __func__,lcd_overturn);
+ return ret;
+}
+static int set_lcd_overturn_func(const char *val, struct kernel_param *kp)
+{
+ int ret = param_set_int(val, kp);
+ if(ret < 0)
+ {
+ pr_err(KERN_ERR"%s Invalid argument\n", __func__);
+ return -EINVAL;
+ }
+ lcd_overturn = *((int*)kp->arg);
+ lcd_register[0]=0x36;
+ if(lcd_overturn)
+ lcd_register[1]=0xc0;
+ else
+ lcd_register[1]=0x0;
+ mdss_dsi_write_register(registerctrl);
+ pr_err(KERN_ERR"%s lcdoverturn is:%d\n", __func__,lcd_overturn);
+ return 0;
+}
+module_param_call(lcdoverturn, set_lcd_overturn_func,get_lcd_overturn_func, &lcd_overturn, S_IRUSR | S_IWUSR);
+#endif
+
static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
int rc = 0;
@@ -948,8 +1152,12 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
pr_debug("%s: ndx=%d cmd_cnt=%d\n", __func__,
ctrl->ndx, on_cmds->cmd_cnt);
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+ update_init_code(ctrl, &lcd_data, (void *)mdss_dsi_panel_cmds_send);
+#else
if (on_cmds->cmd_cnt)
mdss_dsi_panel_cmds_send(ctrl, on_cmds, CMD_REQ_COMMIT);
+#endif
if (pinfo->compression_mode == COMPRESSION_DSC)
mdss_dsi_panel_dsc_pps_send(ctrl, pinfo);
@@ -2627,12 +2835,29 @@ static int mdss_dsi_panel_config_res_properties(struct device_node *np,
bool default_timing)
{
int rc = 0;
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+ lcd_data = lcd_ams520_data;
+#endif
mdss_dsi_parse_roi_alignment(np, pt);
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+ rc = mdss_dsi_parse_dcs_cmds(np, &pt->on_cmds,
+#else
mdss_dsi_parse_dcs_cmds(np, &pt->on_cmds,
+#endif
"qcom,mdss-dsi-on-command",
"qcom,mdss-dsi-on-command-state");
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+ if (!rc) {
+ lcd_data.save_cmd.cmd = pt->on_cmds.cmds;
+ lcd_data.save_cmd.cnt = pt->on_cmds.cmd_cnt;
+ rc = malloc_lcd_effect_code_buf(&lcd_data);
+ if (rc) {
+ printk("malloc_lcd_effect_code_buf failure\n");
+ }
+ }
+#endif
mdss_dsi_parse_dcs_cmds(np, &pt->post_panel_on_cmds,
"qcom,mdss-dsi-post-panel-on-command", NULL);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_status.c b/drivers/video/fbdev/msm/mdss_dsi_status.c
index 64e9739a46f5..ef07291d4d9a 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_status.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_status.c
@@ -30,7 +30,11 @@
#include "mdss_panel.h"
#include "mdss_mdp.h"
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+#define STATUS_CHECK_INTERVAL_MS 2000
+#else
#define STATUS_CHECK_INTERVAL_MS 5000
+#endif
#define STATUS_CHECK_INTERVAL_MIN_MS 50
#define DSI_STATUS_CHECK_INIT -1
#define DSI_STATUS_CHECK_DISABLE 1
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 64f86084b01d..ee5f15664fd3 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -55,6 +55,9 @@
#include "mdss_debug.h"
#include "mdss_smmu.h"
#include "mdss_mdp.h"
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+#include "lcd_effect.h"
+#endif
#include "mdss_livedisplay.h"
@@ -83,6 +86,10 @@
* Default value is set to 1 sec.
*/
#define MDP_TIME_PERIOD_CALC_FPS_US 1000000
+#ifdef CONFIG_MACH_ZUK_Z2_ROW
+extern struct panel_effect_data lcd_data;
+struct msm_fb_data_type *mfd_priv;
+#endif
static struct fb_info *fbi_list[MAX_FBI_LIST];
static int fbi_list_index;
@@ -5356,7 +5363,14 @@ void mdss_fb_calc_fps(struct msm_fb_data_type *mfd)
void mdss_fb_idle_pc(struct msm_fb_data_type *mfd)
{
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
+ struct mdss_overlay_private *mdp5_data = NULL;
+
+ if (mfd)
+ mdp5_data = mfd_to_mdp5_data(mfd);
+ else {
+ pr_warn("%s: mfd is NULL\n", __func__);
+ return;
+ }
if (mdss_fb_is_power_off(mfd))
return;