lcd_extern: fix i2c address mistake for dts config
authorWeiming Liu <weiming.liu@amlogic.com>
Fri, 18 Aug 2017 07:47:39 +0000 (15:47 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 23 Aug 2017 04:12:22 +0000 (21:12 -0700)
PD#149233: lcd: add lcd_extern driver za7783
1.add lcd_extern driver za7783
2.modify the axg pll parameters
3.read under the dts lcd_extern i2c address errors

Change-Id: Ib059805a6a82d7896b2394d451d5aedb3f10ecb9
Signed-off-by: Weiming Liu <weiming.liu@amlogic.com>
arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi
drivers/amlogic/media/vout/lcd/lcd_clk_config.c
drivers/amlogic/media/vout/lcd/lcd_clk_config.h
drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c
drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c
include/linux/amlogic/media/vout/lcd/lcd_extern.h

index 7e547ed..ce1ff28 100644 (file)
                status = "okay";
                key_valid = <0>;
 
+               extern_0{
+                       index = <0>;
+                       extern_name = "ext_default";
+                       status = "disabled";
+                       type = <0>; /* 0=i2c, 1=spi, 2=mipi */
+                       i2c_address = <0x37>; /* 7bit i2c address */
+                       /* 7bit i2c address, 0xff for none */
+                       i2c_second_address = <0xff>;
+                       i2c_bus = "i2c_bus_c";
+                       cmd_size = <4>;
+                       /* init on/off: (type, value..., delay),
+                        * must match cmd_size for every group
+                        * type: 0x00=cmd(bit[3:0]=1 for second_addr),
+                        *              0x10=gpio, 0xff=ending
+                        * value: i2c or spi cmd, or gpio index & level,
+                        *              fill 0x0 for no use
+                        * delay: unit ms
+                        */
+                       init_on = <0x00 0x00 0x00 0x00
+                                               0x00 0x08 0x01 0x00
+                                               0x00 0x10 0x3F 0x00
+                                               0x00 0x11 0x00 0x00
+                                               0x00 0x12 0x00 0x00
+                                               0x00 0x13 0xE4 0x00
+                                               0x00 0x14 0x02 0x00
+                                               0x00 0x15 0x02 0x00
+                                               0x00 0x16 0x24 0x00
+                                               0x00 0x17 0x00 0x00
+                                               0x00 0x18 0x21 0x00
+                                               0x00 0x20 0x3F 0x00
+                                               0x00 0x21 0xFF 0x00
+                                               0x00 0x22 0x00 0x00
+                                               0x00 0x23 0x00 0x00
+                                               0x00 0x24 0x00 0x00
+                                               0x00 0x25 0x00 0x00
+                                               0x00 0x26 0xE4 0x00
+                                               0x00 0x27 0x00 0x00
+                                               0x00 0x28 0x28 0x00
+                                               0x00 0x29 0x01 0x00
+                                               0x00 0x2A 0x00 0x00
+                                               0x00 0x2B 0x01 0x00
+                                               0x00 0x2C 0x0E 0x00
+                                               0x00 0x2D 0x00 0x00
+                                               0x00 0x2E 0x18 0x00
+                                               0x00 0x2F 0x02 0x00
+                                               0x00 0x30 0x02 0x00
+                                               0x00 0x31 0x00 0x00
+                                               0x00 0x32 0x63 0x00
+                                               0x00 0x40 0x00 0x00
+                                               0x00 0x41 0x00 0x00
+                                               0x00 0x42 0x00 0x00
+                                               0x00 0x12 0x00 0x00
+                                               0x00 0x13 0xE4 0x00
+                                               0x00 0x14 0x02 0x00
+                                               0x00 0x15 0x00 0x00
+                                               0x00 0x16 0x0D 0x00
+                                               0x00 0x17 0x00 0x00
+                                               0x00 0x18 0x21 0x00
+                                               0x00 0x41 0x06 0x00
+                                               0x00 0x00 0x01 0x00
+                                               0x00 0x08 0x00 0x00
+                                               0x00 0x10 0x00 0x00
+                                               0x00 0x11 0x0F 0x00
+                                               0xff 0x00 0x00 0x00>;
+                       init_off = <0x00 0x00 0x01 0x00
+                                               0x00 0x08 0x00 0x00
+                                               0x00 0x10 0x00 0x00
+                                               0x00 0x11 0x0F 0x00
+                                               0xff 0x00 0x00 0x00>;
+               };
+
                extern_1{
                        index = <1>;
                        extern_name = "mipi_KD080D13";
index a8f8282..a69e6f0 100644 (file)
@@ -1646,7 +1646,7 @@ static void lcd_set_pll_axg(struct lcd_clk_config_s *cConf)
        lcd_hiu_write(HHI_GP0_PLL_CNTL2, pll_ctrl2);
        lcd_hiu_write(HHI_GP0_PLL_CNTL3, 0x0a59a288);
        lcd_hiu_write(HHI_GP0_PLL_CNTL4, 0xc000004d);
-       lcd_hiu_write(HHI_GP0_PLL_CNTL5, 0x00058000);
+       lcd_hiu_write(HHI_GP0_PLL_CNTL5, 0x00078000);
        lcd_hiu_setb(HHI_GP0_PLL_CNTL, 1, LCD_PLL_RST_AXG, 1);
        lcd_hiu_setb(HHI_GP0_PLL_CNTL, 0, LCD_PLL_RST_AXG, 1);
 
index 1db5e45..911a843 100644 (file)
@@ -297,11 +297,11 @@ enum div_sel_e {
 #define PLL_OD_SEL_MAX_AXG          3
 #define PLL_FREF_MIN_AXG            (5 * 1000)
 #define PLL_FREF_MAX_AXG            (25 * 1000)
-#define PLL_VCO_MIN_AXG             (1500 * 1000)
-#define PLL_VCO_MAX_AXG             (3000 * 1000)
+#define PLL_VCO_MIN_AXG             (960 * 1000)
+#define PLL_VCO_MAX_AXG             (1632 * 1000)
 
 /* video */
-#define CRT_VID_CLK_IN_MAX_AXG      (3000 * 1000)
+#define CRT_VID_CLK_IN_MAX_AXG      (1632 * 1000)
 #define ENCL_CLK_IN_MAX_AXG         (200 * 1000)
 
 
index 7c74074..5ef6b50 100644 (file)
@@ -84,6 +84,75 @@ static int lcd_extern_i2c_write(struct i2c_client *i2client,
        return ret;
 }
 
+static void set_lcd_csb(unsigned int v)
+{
+       lcd_extern_gpio_set(ext_config->spi_gpio_cs, v);
+       udelay(ext_config->spi_delay_us);
+}
+
+static void set_lcd_scl(unsigned int v)
+{
+       lcd_extern_gpio_set(ext_config->spi_gpio_clk, v);
+       udelay(ext_config->spi_delay_us);
+}
+
+static void set_lcd_sda(unsigned int v)
+{
+       lcd_extern_gpio_set(ext_config->spi_gpio_data, v);
+       udelay(ext_config->spi_delay_us);
+}
+
+static void spi_gpio_init(void)
+{
+       set_lcd_csb(1);
+       set_lcd_scl(1);
+       set_lcd_sda(1);
+}
+
+static void spi_gpio_off(void)
+{
+       set_lcd_sda(0);
+       set_lcd_scl(0);
+       set_lcd_csb(0);
+}
+
+static void spi_write_byte(unsigned char data)
+{
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               set_lcd_scl(0);
+               if (data & 0x80)
+                       set_lcd_sda(1);
+               else
+                       set_lcd_sda(0);
+               data <<= 1;
+               set_lcd_scl(1);
+       }
+}
+
+static int lcd_extern_spi_write(unsigned char *buf, int len)
+{
+       int i;
+
+       if (len < 2) {
+               EXTERR("%s: len %d error\n", __func__, len);
+               return -1;
+       }
+
+       set_lcd_csb(0);
+
+       for (i = 0; i < len; i++)
+               spi_write_byte(buf[i]);
+
+       set_lcd_csb(1);
+       set_lcd_scl(1);
+       set_lcd_sda(1);
+       udelay(ext_config->spi_delay_us);
+
+       return 0;
+}
+
 static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf)
 {
        int ret = 0;
@@ -98,188 +167,244 @@ static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
        return ret;
 }
 
-static int lcd_extern_spi_write(unsigned char *buf, int len)
+static int lcd_extern_power_cmd_dynamic_size(unsigned char *init_table,
+               int flag)
 {
-       EXTPR("to do\n");
-       return 0;
+       int i = 0, step = 0, max_len = 0;
+       unsigned char type, cmd_size;
+       int ret = 0;
+
+       if (flag)
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       else
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+
+       switch (ext_config->type) {
+       case LCD_EXTERN_I2C:
+               while (i <= max_len) {
+                       type = init_table[i];
+                       if (type == LCD_EXTERN_INIT_END)
+                               break;
+                       if (lcd_debug_print_flag) {
+                               EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                                       __func__, step,
+                                       init_table[i], init_table[i+1]);
+                       }
+                       cmd_size = init_table[i+1];
+                       if (type == LCD_EXTERN_INIT_NONE) {
+                               if (cmd_size < 1) {
+                                       EXTERR("step %d: invalid cmd_size %d\n",
+                                               step, cmd_size);
+                                       i += (cmd_size + 2);
+                                       step++;
+                                       continue;
+                               }
+                               /* do nothing, only for delay */
+                               if (init_table[i+2] > 0)
+                                       mdelay(init_table[i+2]);
+                       } else if (type == LCD_EXTERN_INIT_GPIO) {
+                               if (cmd_size < 3) {
+                                       EXTERR("step %d: invalid cmd_size %d\n",
+                                               step, cmd_size);
+                                       i += (cmd_size + 2);
+                                       step++;
+                                       continue;
+                               }
+                               if (init_table[i+2] < LCD_GPIO_MAX) {
+                                       lcd_extern_gpio_set(init_table[i+2],
+                                               init_table[i+3]);
+                               }
+                               if (init_table[i+4] > 0)
+                                       mdelay(init_table[i+3]);
+                       } else if (type == LCD_EXTERN_INIT_CMD) {
+                               ret = lcd_extern_i2c_write(
+                                       aml_default_i2c_client,
+                                       &init_table[i+2], (cmd_size-1));
+                               if (init_table[i+cmd_size+1] > 0)
+                                       mdelay(init_table[i+cmd_size+1]);
+                       } else if (type == LCD_EXTERN_INIT_CMD2) {
+                               ret = lcd_extern_i2c_write(
+                                       aml_default_i2c2_client,
+                                       &init_table[i+2], (cmd_size-1));
+                               if (init_table[i+cmd_size+1] > 0)
+                                       mdelay(init_table[i+cmd_size+1]);
+                       } else {
+                               EXTERR("%s(%d: %s): type %d invalid\n",
+                                       __func__, ext_config->index,
+                                       ext_config->name, ext_config->type);
+                       }
+                       i += (cmd_size + 2);
+                       step++;
+               }
+               break;
+       case LCD_EXTERN_SPI:
+               while (i <= max_len) {
+                       type = init_table[i];
+                       if (type == LCD_EXTERN_INIT_END)
+                               break;
+                       if (lcd_debug_print_flag) {
+                               EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                                       __func__, step,
+                                       init_table[i], init_table[i+1]);
+                       }
+                       cmd_size = init_table[i+1];
+                       if (type == LCD_EXTERN_INIT_NONE) {
+                               if (cmd_size < 1) {
+                                       EXTERR("step %d: invalid cmd_size %d\n",
+                                               step, cmd_size);
+                                       i += (cmd_size + 2);
+                                       step++;
+                                       continue;
+                               }
+                               /* do nothing, only for delay */
+                               if (init_table[i+2] > 0)
+                                       mdelay(init_table[i+2]);
+                       } else if (type == LCD_EXTERN_INIT_GPIO) {
+                               if (cmd_size < 3) {
+                                       EXTERR("step %d: invalid cmd_size %d\n",
+                                               step, cmd_size);
+                                       i += (cmd_size + 2);
+                                       step++;
+                                       continue;
+                               }
+                               if (init_table[i+2] < LCD_GPIO_MAX) {
+                                       lcd_extern_gpio_set(init_table[i+2],
+                                               init_table[i+3]);
+                               }
+                               if (init_table[i+4] > 0)
+                                       mdelay(init_table[i+4]);
+                       } else if (type == LCD_EXTERN_INIT_CMD) {
+                               ret = lcd_extern_spi_write(
+                                       &init_table[i+2], (cmd_size-1));
+                               if (init_table[i+cmd_size+1] > 0)
+                                       mdelay(init_table[i+cmd_size+1]);
+                       } else {
+                               EXTERR("%s(%d: %s): type %d invalid\n",
+                                       __func__, ext_config->index,
+                                       ext_config->name, ext_config->type);
+                       }
+                       i += (cmd_size + 2);
+                       step++;
+               }
+               break;
+       default:
+               EXTERR("%s(%d: %s): extern_type %d is not support\n",
+                       __func__, ext_config->index,
+                       ext_config->name, ext_config->type);
+               break;
+       }
+
+       return ret;
 }
 
-static int lcd_extern_power_cmd(unsigned char *init_table)
+static int lcd_extern_power_cmd_fixed_size(unsigned char *init_table, int flag)
 {
-       int i = 0, len;
+       int i = 0, step = 0, max_len = 0;
+       unsigned char type, cmd_size;
        int ret = 0;
 
-       len = ext_config->cmd_size;
-       if (len < 1) {
-               EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
-               return -1;
-       }
-       if (len == LCD_EXTERN_DYNAMIC_LEN) {
-               switch (ext_config->type) {
-               case LCD_EXTERN_I2C:
-                       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-                               if (init_table[i] == LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_NONE) {
-                                       /* do nothing, only for delay */
-                                       if (init_table[i+1] > 0)
-                                               mdelay(init_table[i+1]);
-                                       i += 2;
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_GPIO) {
-                                       if (init_table[i+1] < LCD_GPIO_MAX) {
-                                               lcd_extern_gpio_set(
-                                                       init_table[i+1],
-                                                       init_table[i+2]);
-                                       }
-                                       if (init_table[i+3] > 0)
-                                               mdelay(init_table[i+3]);
-                                       i += 4;
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_CMD) {
-                                       ret = lcd_extern_i2c_write(
-                                               aml_default_i2c_client,
-                                               &init_table[i+2],
-                                               init_table[i+1]-1);
-                                       if (init_table[i+init_table[i+1]+1] > 0)
-                                               mdelay(init_table[i+
-                                                       init_table[i+1]+1]);
-                                       i += (init_table[i+1] + 2);
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_CMD2) {
-                                       ret = lcd_extern_i2c_write(
-                                               aml_default_i2c2_client,
-                                               &init_table[i+2],
-                                               init_table[i+1]-1);
-                                       if (init_table[i+init_table[i+1]+1] > 0)
-                                               mdelay(init_table[i+
-                                                       init_table[i+1]+1]);
-                                       i += (init_table[i+1] + 2);
-                               } else {
-                                       EXTERR("%s(%d: %s): type %d invalid\n",
-                                               __func__, ext_config->index,
-                                               ext_config->name,
-                                               ext_config->type);
-                               }
+       if (flag)
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       else
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+
+       cmd_size = ext_config->cmd_size;
+       switch (ext_config->type) {
+       case LCD_EXTERN_I2C:
+               while (i <= max_len) {
+                       type = init_table[i];
+                       if (type == LCD_EXTERN_INIT_END)
+                               break;
+                       if (lcd_debug_print_flag) {
+                               EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                                       __func__, step, type, cmd_size);
                        }
-                       break;
-               case LCD_EXTERN_SPI:
-                       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-                               if (init_table[i] == LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (init_table[i] ==
-                                       LCD_EXTERN_INIT_NONE) {
-                                       /* do nothing, only for delay */
-                                       if (init_table[i+1] > 0)
-                                               mdelay(init_table[i+1]);
-                                       i += 2;
-                               } else if (init_table[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       if (init_table[i+1] < LCD_GPIO_MAX) {
-                                               lcd_extern_gpio_set(
-                                                       init_table[i+1],
-                                                       init_table[i+2]);
-                                       }
-                                       if (init_table[i+3] > 0)
-                                               mdelay(init_table[i+3]);
-                                       i += 4;
-                               } else if (init_table[i] ==
-                                       LCD_EXTERN_INIT_CMD) {
-                                       ret = lcd_extern_spi_write(
-                                               &init_table[i+2],
-                                               init_table[i+1]-1);
-                                       if (init_table[i+init_table[i+1]+1] > 0)
-                                               mdelay(init_table[i+
-                                                       init_table[i+1]+1]);
-                                       i += (init_table[i+1] + 2);
-                               } else {
-                                       EXTERR("%s(%d: %s): type %d invalid\n",
-                                               __func__, ext_config->index,
-                                               ext_config->name,
-                                               ext_config->type);
+                       if (type == LCD_EXTERN_INIT_NONE) {
+                               /* do nothing, only for delay */
+                       } else if (type == LCD_EXTERN_INIT_GPIO) {
+                               if (init_table[i+1] < LCD_GPIO_MAX) {
+                                       lcd_extern_gpio_set(init_table[i+1],
+                                               init_table[i+2]);
                                }
+                       } else if (type == LCD_EXTERN_INIT_CMD) {
+                               ret = lcd_extern_i2c_write(
+                                       aml_default_i2c_client,
+                                       &init_table[i+1], (cmd_size-2));
+                       } else if (type == LCD_EXTERN_INIT_CMD2) {
+                               ret = lcd_extern_i2c_write(
+                                       aml_default_i2c2_client,
+                                       &init_table[i+1], (cmd_size-2));
+                       } else {
+                               EXTERR("%s(%d: %s): type %d invalid\n",
+                                       __func__, ext_config->index,
+                                       ext_config->name, ext_config->type);
                        }
-                       break;
-               default:
-                       EXTERR("%s(%d: %s): extern_type %d is not support\n",
-                               __func__, ext_config->index,
-                               ext_config->name, ext_config->type);
-                       break;
+                       if (init_table[i+cmd_size-1] > 0)
+                               mdelay(init_table[i+cmd_size-1]);
+                       i += cmd_size;
+                       step++;
                }
-       } else {
-               switch (ext_config->type) {
-               case LCD_EXTERN_I2C:
-                       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-                               if (init_table[i] == LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (init_table[i] ==
-                                       LCD_EXTERN_INIT_NONE) {
-                                       /* do nothing, only for delay */
-                               } else if (init_table[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       if (init_table[i+1] < LCD_GPIO_MAX) {
-                                               lcd_extern_gpio_set(
-                                                       init_table[i+1],
-                                                       init_table[i+2]);
-                                       }
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_CMD) {
-                                       ret = lcd_extern_i2c_write(
-                                               aml_default_i2c_client,
-                                               &init_table[i+1], (len-2));
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_CMD2) {
-                                       ret = lcd_extern_i2c_write(
-                                               aml_default_i2c2_client,
-                                               &init_table[i+1], (len-2));
-                               } else {
-                                       EXTERR("%s(%d: %s): type %d invalid\n",
-                                               __func__, ext_config->index,
-                                               ext_config->name,
-                                               ext_config->type);
-                               }
-                               if (init_table[i+len-1] > 0)
-                                       mdelay(init_table[i+len-1]);
-                               i += len;
+               break;
+       case LCD_EXTERN_SPI:
+               while (i <= max_len) {
+                       type = init_table[i];
+                       if (type == LCD_EXTERN_INIT_END)
+                               break;
+                       if (lcd_debug_print_flag) {
+                               EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                                       __func__, step, type, cmd_size);
                        }
-                       break;
-               case LCD_EXTERN_SPI:
-                       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-                               if (init_table[i] == LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_NONE) {
-                                       /* do nothing, only for delay */
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_GPIO) {
-                                       if (init_table[i+1] < LCD_GPIO_MAX) {
-                                               lcd_extern_gpio_set(
-                                                       init_table[i+1],
-                                                       init_table[i+2]);
-                                       }
-                               } else if (init_table[i] ==
-                                               LCD_EXTERN_INIT_CMD) {
-                                       ret = lcd_extern_spi_write(
-                                               &init_table[i+1], (len-1));
-                               } else {
-                                       EXTERR("%s(%d: %s): type %d invalid\n",
-                                               __func__, ext_config->index,
-                                               ext_config->name,
-                                               ext_config->type);
+                       if (type == LCD_EXTERN_INIT_NONE) {
+                               /* do nothing, only for delay */
+                       } else if (type == LCD_EXTERN_INIT_GPIO) {
+                               if (init_table[i+1] < LCD_GPIO_MAX) {
+                                       lcd_extern_gpio_set(init_table[i+1],
+                                               init_table[i+2]);
                                }
-                               if (init_table[i+len-1] > 0)
-                                       mdelay(init_table[i+len-1]);
-                               i += len;
+                       } else if (type == LCD_EXTERN_INIT_CMD) {
+                               ret = lcd_extern_spi_write(&init_table[i+1],
+                                       (cmd_size-2));
+                       } else {
+                               EXTERR("%s(%d: %s): type %d invalid\n",
+                                       __func__, ext_config->index,
+                                       ext_config->name, ext_config->type);
                        }
-                       break;
-               default:
-                       EXTERR("%s(%d: %s): extern_type %d is not support\n",
-                               __func__, ext_config->index,
-                               ext_config->name, ext_config->type);
-                       break;
-               }
+                       if (init_table[i+cmd_size-1] > 0)
+                               mdelay(init_table[i+cmd_size-1]);
+                       i += cmd_size;
+                       step++;
                }
+               break;
+       default:
+               EXTERR("%s(%d: %s): extern_type %d is not support\n",
+                       __func__, ext_config->index,
+                       ext_config->name, ext_config->type);
+               break;
+       }
+
+       return ret;
+}
+
+static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
+{
+       unsigned char cmd_size;
+       int ret = 0;
+
+       cmd_size = ext_config->cmd_size;
+       if (cmd_size < 1) {
+               EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
+               return -1;
+       }
+       if (init_table == NULL) {
+               EXTERR("%s: init_table %d is NULL\n", __func__, flag);
+               return -1;
+       }
+
+       if (cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC)
+               ret = lcd_extern_power_cmd_dynamic_size(init_table, flag);
+       else
+               ret = lcd_extern_power_cmd_fixed_size(init_table, flag);
+
        return ret;
 }
 
@@ -287,10 +412,16 @@ static int lcd_extern_power_ctrl(int flag)
 {
        int ret = 0;
 
+       if (ext_config->type == LCD_EXTERN_SPI)
+               spi_gpio_init();
+
        if (flag)
-               ret = lcd_extern_power_cmd(ext_config->table_init_on);
+               ret = lcd_extern_power_cmd(ext_config->table_init_on, 1);
        else
-               ret = lcd_extern_power_cmd(ext_config->table_init_off);
+               ret = lcd_extern_power_cmd(ext_config->table_init_off, 0);
+
+       if (ext_config->type == LCD_EXTERN_SPI)
+               spi_gpio_off();
 
        EXTPR("%s(%d: %s): %d\n",
                __func__, ext_config->index, ext_config->name, flag);
@@ -346,6 +477,11 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
                ext_drv->config.table_init_on  = init_on_table;
                ext_drv->config.table_init_off = init_off_table;
        }
+       if (ext_drv->config.type == LCD_EXTERN_SPI) {
+               ext_drv->config.spi_delay_us =
+                       1000000 / ext_drv->config.spi_clk_freq;
+       }
+
        ext_drv->reg_read  = lcd_extern_reg_read;
        ext_drv->reg_write = lcd_extern_reg_write;
        ext_drv->power_on  = lcd_extern_power_on;
index 66d337b..b8f6648 100644 (file)
@@ -111,21 +111,39 @@ static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
        return ret;
 }
 
-static int lcd_extern_power_cmd(unsigned char *init_table)
+static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
 {
-       int i = 0, len;
+       int i = 0, max_len = 0, step = 0;
+       unsigned char cmd_size;
        int ret = 0;
 
-       len = ext_config->cmd_size;
-       if (len < 1) {
-               EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
+       cmd_size = ext_config->cmd_size;
+       if (cmd_size < 1) {
+               EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
+               return -1;
+       }
+       if (cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+               EXTPR("%s: cmd_size dynamic length is not support\n", __func__);
+               return -1;
+       }
+       if (init_table == NULL) {
+               EXTERR("%s: init_table %d is NULL\n", __func__, flag);
                return -1;
        }
 
-       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-               if (init_table[i] == LCD_EXTERN_INIT_END) {
+       if (flag)
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       else
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+
+       while (i <= max_len) {
+               if (init_table[i] == LCD_EXTERN_INIT_END)
                        break;
-               } else if (init_table[i] == LCD_EXTERN_INIT_NONE) {
+               if (lcd_debug_print_flag) {
+                       EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                               __func__, step, init_table[i], cmd_size);
+               }
+               if (init_table[i] == LCD_EXTERN_INIT_NONE) {
                        /* do nothing, only for delay */
                } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
                        if (init_table[i+1] < LCD_GPIO_MAX) {
@@ -134,15 +152,16 @@ static int lcd_extern_power_cmd(unsigned char *init_table)
                        }
                } else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
                        ret = lcd_extern_i2c_write(aml_T5800Q_i2c_client,
-                               &init_table[i+1], (len-2));
+                               &init_table[i+1], (cmd_size-2));
                } else {
                        EXTERR("%s(%d: %s): power_type %d is invalid\n",
                                __func__, ext_config->index,
                                ext_config->name, ext_config->type);
                }
-               if (init_table[i+len-1] > 0)
-                       mdelay(init_table[i+len-1]);
-               i += len;
+               if (init_table[i+cmd_size-1] > 0)
+                       mdelay(init_table[i+cmd_size-1]);
+               step++;
+               i += cmd_size;
        }
 
        return ret;
@@ -153,9 +172,9 @@ static int lcd_extern_power_ctrl(int flag)
        int ret = 0;
 
        if (flag)
-               ret = lcd_extern_power_cmd(ext_config->table_init_on);
+               ret = lcd_extern_power_cmd(ext_config->table_init_on, 1);
        else
-               ret = lcd_extern_power_cmd(ext_config->table_init_off);
+               ret = lcd_extern_power_cmd(ext_config->table_init_off, 0);
 
        EXTPR("%s(%d: %s): %d\n",
                __func__, ext_config->index, ext_config->name, flag);
index 6615564..2490664 100644 (file)
@@ -37,14 +37,6 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf);
 static unsigned int lcd_ext_key_valid;
 static unsigned char lcd_ext_config_load;
 
-static unsigned char lcd_extern_init_on_table[LCD_EXTERN_INIT_TABLE_MAX] = {
-       0xff,
-};
-
-static unsigned char lcd_extern_init_off_table[LCD_EXTERN_INIT_TABLE_MAX] = {
-       0xff,
-};
-
 struct lcd_ext_gpio_s {
        char name[15];
        struct gpio_desc *gpio;
@@ -237,20 +229,137 @@ struct device_node *aml_lcd_extern_get_dts_child(int index)
        return child;
 }
 
+static int lcd_extern_init_table_dynamic_size_load_dts(
+               struct device_node *of_node,
+               struct lcd_extern_config_s *extconf, int flag)
+{
+       unsigned char cmd_size, index, type;
+       int i, j, val, max_len, step = 0, ret = 0;
+       unsigned char *init_table;
+       char propname[20];
+
+       if (flag) {
+               init_table = extconf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+               sprintf(propname, "init_on");
+       } else {
+               init_table = extconf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+               sprintf(propname, "init_off");
+       }
+
+       i = 0;
+       while (i < max_len) {
+               /* step1: type */
+               ret = of_property_read_u32_index(of_node, propname, i, &val);
+               if (ret) {
+                       EXTERR("get %s %s type failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       return -1;
+               }
+               init_table[i] = (unsigned char)val;
+               type = init_table[i];
+               if (type == LCD_EXTERN_INIT_END)
+                       break;
+               /* step2: cmd_size */
+               ret = of_property_read_u32_index(
+                       of_node, propname, (i+1), &val);
+               if (ret) {
+                       EXTERR("get %s %s cmd_size failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       return -1;
+               }
+               init_table[i+1] = (unsigned char)val;
+               cmd_size = init_table[i+1];
+               if (cmd_size == 0) {
+                       i += 2;
+                       continue;
+               }
+               /* step3: data */
+               for (j = 0; j < cmd_size; j++) {
+                       ret = of_property_read_u32_index(
+                               of_node, propname, (i+2+j), &val);
+                       if (ret) {
+                               EXTERR("get %s %s data failed, step %d\n",
+                                       extconf->name, propname, step);
+                               init_table[i] = LCD_EXTERN_INIT_END;
+                               return -1;
+                       }
+                       init_table[i+2+j] = (unsigned char)val;
+               }
+               if (type == LCD_EXTERN_INIT_GPIO) {
+                       /* gpio request */
+                       index = init_table[i+2];
+                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
+                               lcd_extern_gpio_register(index);
+               }
+               step++;
+               i += (cmd_size + 2);
+       }
+
+       return 0;
+}
+
+static int lcd_extern_init_table_fixed_size_load_dts(
+               struct device_node *of_node,
+               struct lcd_extern_config_s *extconf, int flag)
+{
+       unsigned char cmd_size, index;
+       int i, j, val, max_len, step = 0, ret = 0;
+       unsigned char *init_table;
+       char propname[20];
+
+       cmd_size = extconf->cmd_size;
+       if (flag) {
+               init_table = extconf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+               sprintf(propname, "init_on");
+       } else {
+               init_table = extconf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+               sprintf(propname, "init_off");
+       }
+
+       i = 0;
+       while (i < max_len) {
+               for (j = 0; j < cmd_size; j++) {
+                       ret = of_property_read_u32_index(
+                               of_node, propname, (i+j), &val);
+                       if (ret) {
+                               EXTERR("get %s %s failed, step %d\n",
+                                       extconf->name, propname, step);
+                               init_table[i] = LCD_EXTERN_INIT_END;
+                               return -1;
+                       }
+                       init_table[i+j] = (unsigned char)val;
+               }
+               if (init_table[i] == LCD_EXTERN_INIT_END) {
+                       break;
+               } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
+                       /* gpio request */
+                       index = init_table[i+1];
+                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
+                               lcd_extern_gpio_register(index);
+               }
+               step++;
+               i += cmd_size;
+       }
+
+       return 0;
+}
+
 static int lcd_extern_get_config_dts(struct device_node *of_node,
                struct lcd_extern_config_s *extconf)
 {
        int ret;
        int val;
        const char *str;
-       unsigned char cmd_size, index;
-       int i, j;
 
        extconf->index = LCD_EXTERN_INDEX_INVALID;
        extconf->type = LCD_EXTERN_MAX;
        extconf->table_init_loaded = 0;
-       extconf->table_init_on = lcd_extern_init_on_table;
-       extconf->table_init_off = lcd_extern_init_off_table;
 
        ret = of_property_read_u32(of_node, "index", &val);
        if (ret)
@@ -305,7 +414,7 @@ static int lcd_extern_get_config_dts(struct device_node *of_node,
                                extconf->name);
                        extconf->i2c_addr2 = 0xff;
                } else {
-                       extconf->i2c_addr = (unsigned char)val;
+                       extconf->i2c_addr2 = (unsigned char)val;
                }
                if (lcd_debug_print_flag) {
                        EXTPR("%s i2c_second_address=0x%02x\n",
@@ -335,66 +444,28 @@ static int lcd_extern_get_config_dts(struct device_node *of_node,
                        EXTPR("%s cmd_size=%d\n",
                                extconf->name, extconf->cmd_size);
                }
-               cmd_size = extconf->cmd_size;
-               if (cmd_size > 1) {
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               for (j = 0; j < cmd_size; j++) {
-                                       ret = of_property_read_u32_index(
-                                               of_node, "init_on",
-                                               (i + j), &val);
-                                       if (ret) {
-                                               EXTERR("get init_on failed\n");
-                                               extconf->table_init_on[i] =
-                                                       LCD_EXTERN_INIT_END;
-                                               goto i2c_get_init_on_dts;
-                                       }
-                                       extconf->table_init_on[i + j] =
-                                               (unsigned char)val;
-                               }
-                               if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_on[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               }
-                               i += cmd_size;
-                       }
-                       extconf->table_init_loaded = 1;
-i2c_get_init_on_dts:
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               for (j = 0; j < cmd_size; j++) {
-                                       ret = of_property_read_u32_index(
-                                               of_node, "init_off",
-                                               (i + j), &val);
-                                       if (ret) {
-                                               EXTERR("get init_off failed\n");
-                                               extconf->table_init_off[i] =
-                                                       LCD_EXTERN_INIT_END;
-                                               goto i2c_get_init_off_dts;
-                                       }
-                                       extconf->table_init_off[i + j] =
-                                               (unsigned char)val;
-                               }
-                               if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_off[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               }
-                               i += cmd_size;
-                       }
+               if (extconf->cmd_size <= 1) {
+                       EXTERR("cmd_size %d is invalid\n", extconf->cmd_size);
+                       break;
                }
-i2c_get_init_off_dts:
+
+               if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       ret = lcd_extern_init_table_dynamic_size_load_dts(
+                               of_node, extconf, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_dynamic_size_load_dts(
+                               of_node, extconf, 0);
+               } else {
+                       ret = lcd_extern_init_table_fixed_size_load_dts(
+                               of_node, extconf, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_fixed_size_load_dts(
+                               of_node, extconf, 0);
+               }
+               if (ret == 0)
+                       extconf->table_init_loaded = 1;
                break;
        case LCD_EXTERN_SPI:
                ret = of_property_read_u32(of_node, "gpio_spi_cs", &val);
@@ -471,66 +542,28 @@ i2c_get_init_off_dts:
                        EXTPR("%s cmd_size=%d\n",
                                extconf->name, extconf->cmd_size);
                }
-               cmd_size = extconf->cmd_size;
-               if (cmd_size > 1) {
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               for (j = 0; j < cmd_size; j++) {
-                                       ret = of_property_read_u32_index(
-                                               of_node, "init_on",
-                                               (i + j), &val);
-                                       if (ret) {
-                                               EXTERR("get init_on failed\n");
-                                               extconf->table_init_on[i] =
-                                                       LCD_EXTERN_INIT_END;
-                                               goto spi_get_init_on_dts;
-                                       }
-                                       extconf->table_init_on[i + j] =
-                                               (unsigned char)val;
-                               }
-                               if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_on[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               }
-                               i += cmd_size;
-                       }
-                       extconf->table_init_loaded = 1;
-spi_get_init_on_dts:
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               for (j = 0; j < cmd_size; j++) {
-                                       ret = of_property_read_u32_index(
-                                               of_node, "init_off",
-                                               (i + j), &val);
-                                       if (ret) {
-                                               EXTERR("get init_off failed\n");
-                                               extconf->table_init_off[i] =
-                                                       LCD_EXTERN_INIT_END;
-                                               goto spi_get_init_off_dts;
-                                       }
-                                       extconf->table_init_off[i + j] =
-                                               (unsigned char)val;
-                               }
-                               if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_off[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               }
-                               i += cmd_size;
-                       }
+               if (extconf->cmd_size <= 1) {
+                       EXTERR("cmd_size %d is invalid\n", extconf->cmd_size);
+                       break;
                }
-spi_get_init_off_dts:
+
+               if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       ret = lcd_extern_init_table_dynamic_size_load_dts(
+                               of_node, extconf, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_dynamic_size_load_dts(
+                               of_node, extconf, 0);
+               } else {
+                       ret = lcd_extern_init_table_fixed_size_load_dts(
+                               of_node, extconf, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_fixed_size_load_dts(
+                               of_node, extconf, 0);
+               }
+               if (ret == 0)
+                       extconf->table_init_loaded = 1;
                break;
        case LCD_EXTERN_MIPI:
                break;
@@ -565,22 +598,150 @@ static unsigned char lcd_extern_get_i2c_bus_unifykey(unsigned char val)
        return i2c_bus;
 }
 
-static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf)
+static int lcd_extern_init_table_dynamic_size_load_unifykey(
+               struct lcd_extern_config_s *extconf, unsigned char *p,
+               int key_len, int len, int flag)
 {
-       unsigned char *para;
-       int i, j, key_len, len;
        unsigned char cmd_size;
-       unsigned char *p;
+       unsigned char index;
+       int i, j, max_len, step = 0, ret = 0;
+       unsigned char *init_table;
+       char propname[20];
+
+       if (flag) {
+               init_table = extconf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+               sprintf(propname, "init_on");
+       } else {
+               init_table = extconf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+               sprintf(propname, "init_off");
+       }
+
+       i = 0;
+       while (i < max_len) {
+               /* step1: type */
+               len += 1;
+               ret = lcd_unifykey_len_check(key_len, len);
+               if (ret) {
+                       EXTERR("get %s %s type failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       return -1;
+               }
+               init_table[i] = *p;
+               p++;
+               if (init_table[i] == LCD_EXTERN_INIT_END)
+                       break;
+
+               /* step2: cmd_size */
+               len += 1;
+               ret = lcd_unifykey_len_check(key_len, len);
+               if (ret) {
+                       EXTERR("get %s %s cmd_size failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       return -1;
+               }
+               init_table[i+1] = *p;
+               cmd_size = init_table[i+1];
+               p++;
+               if (cmd_size == 0) {
+                       i += 2;
+                       continue;
+               }
+
+               /* step3: data */
+               len += cmd_size;
+               ret = lcd_unifykey_len_check(key_len, len);
+               if (ret) {
+                       EXTERR("get %s %s data failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       for (j = 0; j < cmd_size; j++)
+                               init_table[i+2+j] = 0x0;
+                       return -1;
+               }
+               for (j = 0; j < cmd_size; j++) {
+                       init_table[i+2+j] = *p;
+                       p++;
+               }
+               if (init_table[i] == LCD_EXTERN_INIT_END) {
+                       break;
+               } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
+                       /* gpio request */
+                       index = init_table[i+1];
+                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
+                               lcd_extern_gpio_register(index);
+               }
+               step++;
+               i += (cmd_size + 2);
+       }
+
+       return 0;
+}
+
+static int lcd_extern_init_table_fixed_size_load_unifykey(
+               struct lcd_extern_config_s *extconf, unsigned char *p,
+               int key_len, int len, int flag)
+{
+       unsigned char cmd_size;
+       unsigned char index;
+       int i, j, max_len, step = 0, ret = 0;
+       unsigned char *init_table;
+       char propname[20];
+
+       cmd_size = extconf->cmd_size;
+       if (flag) {
+               init_table = extconf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+               sprintf(propname, "init_on");
+       } else {
+               init_table = extconf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+               sprintf(propname, "init_off");
+       }
+
+       i = 0;
+       while (i < max_len) {
+               len += cmd_size;
+               ret = lcd_unifykey_len_check(key_len, len);
+               if (ret) {
+                       EXTERR("get %s %s failed, step %d\n",
+                               extconf->name, propname, step);
+                       init_table[i] = LCD_EXTERN_INIT_END;
+                       return -1;
+               }
+               for (j = 0; j < cmd_size; j++) {
+                       init_table[i+j] = *p;
+                       p++;
+               }
+               if (init_table[i] == LCD_EXTERN_INIT_END) {
+                       break;
+               } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
+                       /* gpio request */
+                       index = init_table[i+1];
+                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
+                               lcd_extern_gpio_register(index);
+               }
+               step++;
+               i += cmd_size;
+       }
+
+       return 0;
+}
+
+static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf)
+{
+       unsigned char *para, *p;
+       int key_len, len;
        const char *str;
        struct aml_lcd_unifykey_header_s ext_header;
-       unsigned char index;
        int ret;
 
        extconf->index = LCD_EXTERN_INDEX_INVALID;
        extconf->type = LCD_EXTERN_MAX;
        extconf->table_init_loaded = 0;
-       extconf->table_init_on = lcd_extern_init_on_table;
-       extconf->table_init_off = lcd_extern_init_off_table;
 
        para = kmalloc((sizeof(unsigned char) * LCD_UKEY_LCD_EXT_SIZE),
                GFP_KERNEL);
@@ -647,72 +808,28 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf)
                p += LCD_UKEY_EXT_TYPE_VAL_8;
                p += LCD_UKEY_EXT_TYPE_VAL_9;
 
-               /* power */
-               cmd_size = extconf->cmd_size;
-               if (cmd_size >= 1) {
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               len += cmd_size;
-                               ret = lcd_unifykey_len_check(key_len, len);
-                               if (ret) {
-                                       extconf->table_init_on[i] =
-                                               LCD_EXTERN_INIT_END;
-                                       for (j = 1; j < cmd_size; j++) {
-                                               extconf->table_init_on[i+j] =
-                                                       0x0;
-                                       }
-                                       kfree(para);
-                                       return -1;
-                               }
-                               for (j = 0; j < cmd_size; j++) {
-                                       extconf->table_init_on[i+j] = *p;
-                                       p++;
-                               }
-                               if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_on[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               }
-                               i += cmd_size;
-                       }
-                       extconf->table_init_loaded = 1;
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               len += cmd_size;
-                               ret = lcd_unifykey_len_check(key_len, len);
-                               if (ret) {
-                                       extconf->table_init_off[i] =
-                                               LCD_EXTERN_INIT_END;
-                                       for (j = 1; j < cmd_size; j++) {
-                                               extconf->table_init_off[i+j] =
-                                                       0x0;
-                                       }
-                                       kfree(para);
-                                       return -1;
-                               }
-                               for (j = 0; j < cmd_size; j++) {
-                                       extconf->table_init_off[i+j] = *p;
-                                       p++;
-                               }
-                               if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_off[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               } else {
-                                       i += cmd_size;
-                               }
-                       }
+               /* init */
+               if (extconf->cmd_size <= 1) {
+                       EXTERR("cmd_size %d is invalid\n", extconf->cmd_size);
+                       break;
                }
+               if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       ret = lcd_extern_init_table_dynamic_size_load_unifykey(
+                               extconf, p, key_len, len, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_dynamic_size_load_unifykey(
+                               extconf, p, key_len, len, 0);
+               } else {
+                       ret = lcd_extern_init_table_fixed_size_load_unifykey(
+                               extconf, p, key_len, len, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_fixed_size_load_unifykey(
+                               extconf, p, key_len, len, 0);
+               }
+               if (ret == 0)
+                       extconf->table_init_loaded = 1;
                break;
        case LCD_EXTERN_SPI:
                extconf->spi_gpio_cs = *p;
@@ -739,72 +856,27 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf)
                p += LCD_UKEY_EXT_TYPE_VAL_9;
 
                /* init */
-               cmd_size = extconf->cmd_size;
-               if (cmd_size >= 1) {
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               len += cmd_size;
-                               ret = lcd_unifykey_len_check(key_len, len);
-                               if (ret) {
-                                       extconf->table_init_on[i] =
-                                               LCD_EXTERN_INIT_END;
-                                       for (j = 1; j < cmd_size; j++) {
-                                               extconf->table_init_on[i+j] =
-                                                       0x0;
-                                       }
-                                       kfree(para);
-                                       return -1;
-                               }
-                               for (j = 0; j < cmd_size; j++) {
-                                       extconf->table_init_on[i+j] = *p;
-                                       p++;
-                               }
-                               if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_on[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_on[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               } else {
-                                       i += cmd_size;
-                               }
-                       }
-                       extconf->table_init_loaded = 1;
-                       i = 0;
-                       while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                               len += cmd_size;
-                               ret = lcd_unifykey_len_check(key_len, len);
-                               if (ret) {
-                                       extconf->table_init_off[i] =
-                                               LCD_EXTERN_INIT_END;
-                                       for (j = 1; j < cmd_size; j++) {
-                                               extconf->table_init_off[i+j] =
-                                                       0x0;
-                                       }
-                                       kfree(para);
-                                       return -1;
-                               }
-                               for (j = 0; j < cmd_size; j++) {
-                                       extconf->table_init_off[i+j] = *p;
-                                       p++;
-                               }
-                               if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_END) {
-                                       break;
-                               } else if (extconf->table_init_off[i] ==
-                                       LCD_EXTERN_INIT_GPIO) {
-                                       /* gpio request */
-                                       index = extconf->table_init_off[i+1];
-                                       if (index < LCD_EXTERN_GPIO_NUM_MAX)
-                                               lcd_extern_gpio_register(index);
-                               } else {
-                                       i += cmd_size;
-                               }
-                       }
+               if (extconf->cmd_size <= 1) {
+                       EXTERR("cmd_size %d is invalid\n", extconf->cmd_size);
+                       break;
+               }
+               if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       ret = lcd_extern_init_table_dynamic_size_load_unifykey(
+                               extconf, p, key_len, len, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_dynamic_size_load_unifykey(
+                               extconf, p, key_len, len, 0);
+               } else {
+                       ret = lcd_extern_init_table_fixed_size_load_unifykey(
+                               extconf, p, key_len, len, 1);
+                       if (ret)
+                               break;
+                       ret = lcd_extern_init_table_fixed_size_load_unifykey(
+                               extconf, p, key_len, len, 0);
                }
+               if (ret == 0)
+                       extconf->table_init_loaded = 1;
                break;
        case LCD_EXTERN_MIPI:
                /* dummy pointer */
@@ -834,6 +906,8 @@ static int lcd_extern_get_config(void)
 {
        struct device_node *child;
        struct lcd_extern_config_s extconf;
+       unsigned char *lcd_ext_init_on_table;
+       unsigned char *lcd_ext_init_off_table;
        int load_id = 0;
        int ret;
 
@@ -841,6 +915,24 @@ static int lcd_extern_get_config(void)
                EXTERR("no lcd_extern of_node exist\n");
                return -1;
        }
+
+       lcd_ext_init_on_table =
+               kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX,
+                       GFP_KERNEL);
+       if (lcd_ext_init_on_table == NULL) {
+               EXTERR("failed to alloc default init table\n");
+               return -1;
+       }
+       lcd_ext_init_off_table =
+               kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX,
+                       GFP_KERNEL);
+       if (lcd_ext_init_off_table == NULL) {
+               EXTERR("failed to alloc default init table\n");
+               return -1;
+       }
+       lcd_ext_init_on_table[0] = LCD_EXTERN_INIT_END;
+       lcd_ext_init_off_table[0] = LCD_EXTERN_INIT_END;
+
        ret = of_property_read_u32(lcd_extern_dev->of_node,
                        "key_valid", &lcd_ext_key_valid);
        if (ret) {
@@ -857,10 +949,12 @@ static int lcd_extern_get_config(void)
                else
                        load_id = 1;
        }
+       memset(&extconf, 0, sizeof(struct lcd_extern_config_s));
+       extconf.table_init_on = lcd_ext_init_on_table;
+       extconf.table_init_off = lcd_ext_init_off_table;
        if (load_id) {
                EXTPR("%s from unifykey\n", __func__);
                lcd_ext_config_load = 1;
-               memset(&extconf, 0, sizeof(struct lcd_extern_config_s));
                ret = lcd_extern_get_config_unifykey(&extconf);
                if (ret == 0)
                        lcd_extern_add_driver(&extconf);
@@ -869,13 +963,15 @@ static int lcd_extern_get_config(void)
                EXTPR("%s from dts\n", __func__);
                lcd_ext_config_load = 0;
                for_each_child_of_node(lcd_extern_dev->of_node, child) {
-                       memset(&extconf, 0, sizeof(struct lcd_extern_config_s));
                        ret = lcd_extern_get_config_dts(child, &extconf);
                        if (ret == 0)
                                lcd_extern_add_driver(&extconf);
                }
 #endif
        }
+
+       kfree(lcd_ext_init_on_table);
+       kfree(lcd_ext_init_off_table);
        return 0;
 }
 
@@ -997,9 +1093,31 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf)
        strcpy(ext_drv->config.name, extconf->name);
        ext_drv->config.type = extconf->type;
        ext_drv->config.status = extconf->status;
+       ext_drv->config.table_init_on = NULL;
+       ext_drv->config.table_init_off = NULL;
        ext_drv->config.table_init_loaded = extconf->table_init_loaded;
-       ext_drv->config.table_init_on = lcd_extern_init_on_table;
-       ext_drv->config.table_init_off = lcd_extern_init_off_table;
+       if (ext_drv->config.table_init_loaded) {
+               ext_drv->config.table_init_on =
+                       kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX,
+                               GFP_KERNEL);
+               if (ext_drv->config.table_init_on == NULL) {
+                       EXTERR("failed to alloc driver %s[%d] init table\n",
+                               extconf->name, extconf->index);
+                       return -1;
+               }
+               ext_drv->config.table_init_off =
+                       kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX,
+                               GFP_KERNEL);
+               if (ext_drv->config.table_init_off == NULL) {
+                       EXTERR("failed to alloc driver %s[%d] init table\n",
+                               extconf->name, extconf->index);
+                       return -1;
+               }
+               memcpy(ext_drv->config.table_init_on, extconf->table_init_on,
+                       LCD_EXTERN_INIT_ON_MAX);
+               memcpy(ext_drv->config.table_init_off, extconf->table_init_off,
+                       LCD_EXTERN_INIT_OFF_MAX);
+       }
 
        /* fill config parameters by different type */
        switch (ext_drv->config.type) {
@@ -1029,6 +1147,8 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf)
        }
        if (ret) {
                EXTERR("add driver failed\n");
+               kfree(lcd_ext_driver[i]->config.table_init_on);
+               kfree(lcd_ext_driver[i]->config.table_init_off);
                kfree(lcd_ext_driver[i]);
                lcd_ext_driver[i] = NULL;
                return -1;
@@ -1039,10 +1159,88 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf)
        return 0;
 }
 
-/* debug function */
+#define EXT_LEN_MAX   200
+static void lcd_extern_init_table_dynamic_size_print(
+               struct lcd_extern_config_s *econf, int flag)
+{
+       int i, j, k, max_len;
+       unsigned char cmd_size;
+       char str[EXT_LEN_MAX];
+       unsigned char *init_table;
+
+       if (flag) {
+               pr_info("power on:\n");
+               init_table = econf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       } else {
+               pr_info("power off:\n");
+               init_table = econf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+       }
+       if (init_table == NULL) {
+               EXTERR("init_table %d is NULL\n", flag);
+               return;
+       }
+
+       i = 0;
+       while (i < max_len) {
+               if (init_table[i] == LCD_EXTERN_INIT_END)
+                       break;
+
+               cmd_size = init_table[i+1];
+               k = snprintf(str, EXT_LEN_MAX, "  0x%02x %d",
+                       init_table[i], cmd_size);
+               if (cmd_size > 0) {
+                       for (j = 0; j < cmd_size; j++) {
+                               k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x",
+                                       init_table[i+2+j]);
+                       }
+               }
+               pr_info("%s\n", str);
+               i += (cmd_size + 2);
+       }
+}
+
+static void lcd_extern_init_table_fixed_size_print(
+               struct lcd_extern_config_s *econf, int flag)
+{
+       int i, j, k, max_len;
+       unsigned char cmd_size;
+       char str[EXT_LEN_MAX];
+       unsigned char *init_table;
+
+       cmd_size = econf->cmd_size;
+       if (flag) {
+               pr_info("power on:\n");
+               init_table = econf->table_init_on;
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       } else {
+               pr_info("power off:\n");
+               init_table = econf->table_init_off;
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+       }
+       if (init_table == NULL) {
+               EXTERR("init_table %d is NULL\n", flag);
+               return;
+       }
+
+       i = 0;
+       while (i < max_len) {
+               if (init_table[i] == LCD_EXTERN_INIT_END)
+                       break;
+
+               k = snprintf(str, EXT_LEN_MAX, " ");
+               for (j = 0; j < cmd_size; j++) {
+                       k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x",
+                               init_table[i+j]);
+               }
+               pr_info("%s\n", str);
+               i += cmd_size;
+       }
+}
+
 static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv)
 {
-       int i, j, len;
        struct lcd_extern_config_s *econf;
 
        if (ext_drv == NULL)
@@ -1062,34 +1260,12 @@ static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv)
                        econf->cmd_size, econf->i2c_addr,
                        econf->i2c_addr2, econf->i2c_bus,
                        econf->table_init_loaded);
-               len = econf->cmd_size;
-               pr_info("power on:\n");
-               i = 0;
-               while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                       if (econf->table_init_on[i] == LCD_EXTERN_INIT_END) {
-                               pr_info("\n");
-                       } else {
-                               for (j = 0; j < len; j++) {
-                                       pr_info("0x%02x ",
-                                               econf->table_init_on[i+j]);
-                               }
-                               pr_info("\n");
-                       }
-                       i += len;
-               }
-               pr_info("power off:\n");
-               i = 0;
-               while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                       if (econf->table_init_off[i] == LCD_EXTERN_INIT_END) {
-                               pr_info("\n");
-                       } else {
-                               for (j = 0; j < len; j++) {
-                                       pr_info("0x%02x ",
-                                               econf->table_init_off[i+j]);
-                               }
-                               pr_info("\n");
-                       }
-                       i += len;
+               if (econf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       lcd_extern_init_table_dynamic_size_print(econf, 1);
+                       lcd_extern_init_table_dynamic_size_print(econf, 0);
+               } else {
+                       lcd_extern_init_table_fixed_size_print(econf, 1);
+                       lcd_extern_init_table_fixed_size_print(econf, 0);
                }
                break;
        case LCD_EXTERN_SPI:
@@ -1099,38 +1275,19 @@ static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv)
                        "spi_gpio_clk:    %d\n"
                        "spi_gpio_data:   %d\n"
                        "spi_clk_freq:    %dHz\n"
+                       "spi_delay_us:    %d\n"
                        "spi_clk_pol:     %d\n"
                        "table_loaded:    %d\n",
                        econf->cmd_size, econf->spi_gpio_cs,
                        econf->spi_gpio_clk, econf->spi_gpio_data,
-                       econf->spi_clk_freq, econf->spi_clk_pol,
-                       econf->table_init_loaded);
-               len = econf->cmd_size;
-               i = 0;
-               while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                       if (econf->table_init_on[i] == LCD_EXTERN_INIT_END) {
-                               pr_info("\n");
-                       } else {
-                               for (j = 0; j < len; j++) {
-                                       pr_info("0x%02x ",
-                                               econf->table_init_on[i+j]);
-                               }
-                               pr_info("\n");
-                       }
-                       i += len;
-               }
-               i = 0;
-               while (i < LCD_EXTERN_INIT_TABLE_MAX) {
-                       if (econf->table_init_off[i] == LCD_EXTERN_INIT_END) {
-                               pr_info("\n");
-                       } else {
-                               for (j = 0; j < len; j++) {
-                                       pr_info("0x%02x ",
-                                               econf->table_init_off[i+j]);
-                               }
-                               pr_info("\n");
-                       }
-                       i += len;
+                       econf->spi_clk_freq, econf->spi_delay_us,
+                       econf->spi_clk_pol, econf->table_init_loaded);
+               if (econf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+                       lcd_extern_init_table_dynamic_size_print(econf, 1);
+                       lcd_extern_init_table_dynamic_size_print(econf, 0);
+               } else {
+                       lcd_extern_init_table_fixed_size_print(econf, 1);
+                       lcd_extern_init_table_fixed_size_print(econf, 0);
                }
                break;
        case LCD_EXTERN_MIPI:
@@ -1178,9 +1335,6 @@ static ssize_t lcd_extern_info_dump(struct class *class,
                break;
        }
 
-       if (ret != 1 || ret != 2)
-               return -EINVAL;
-
        return count;
 }
 
@@ -1196,6 +1350,41 @@ static ssize_t lcd_extern_debug_config_load_show(struct class *class,
        return sprintf(buf, "%d\n", lcd_ext_config_load);
 }
 
+static const char *lcd_extern_debug_test_usage_str = {
+"Usage:\n"
+"    echo <index> <on/off> > test ; test power on/off for index extern device\n"
+"        <on/off>: 1 for power on, 0 for power off\n"
+};
+
+static ssize_t lcd_extern_debug_test_show(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s\n", lcd_extern_debug_test_usage_str);
+}
+
+static ssize_t lcd_extern_debug_test_store(struct class *class,
+               struct class_attribute *attr, const char *buf, size_t count)
+{
+       unsigned int ret;
+       int index, flag = 0;
+       struct aml_lcd_extern_driver_s *ext_drv;
+
+       index = LCD_EXTERN_INDEX_INVALID;
+       ret = sscanf(buf, "%d %d", &index, &flag);
+       ext_drv = aml_lcd_extern_get_driver(index);
+       if (ext_drv) {
+               if (flag) {
+                       if (ext_drv->power_on)
+                               ext_drv->power_on();
+               } else {
+                       if (ext_drv->power_off)
+                               ext_drv->power_off();
+               }
+       }
+
+       return count;
+}
+
 static struct class_attribute lcd_extern_class_attrs[] = {
        __ATTR(info, 0644,
                lcd_extern_debug_help, lcd_extern_info_dump),
@@ -1203,6 +1392,8 @@ static struct class_attribute lcd_extern_class_attrs[] = {
                 lcd_extern_debug_key_valid_show, NULL),
        __ATTR(config_load, 0644,
                lcd_extern_debug_config_load_show, NULL),
+       __ATTR(test, 0644,
+               lcd_extern_debug_test_show, lcd_extern_debug_test_store),
 };
 
 static struct class *debug_class;
@@ -1259,6 +1450,8 @@ static int aml_lcd_extern_remove(struct platform_device *pdev)
 
        remove_lcd_extern_class();
        for (i = 0; i < lcd_ext_driver_num; i++) {
+               kfree(lcd_ext_driver[i]->config.table_init_on);
+               kfree(lcd_ext_driver[i]->config.table_init_off);
                kfree(lcd_ext_driver[i]);
                lcd_ext_driver[i] = NULL;
        }
index 7c2678c..768a402 100644 (file)
@@ -61,20 +61,20 @@ static unsigned char init_off_table[] = {
 
 static void set_lcd_csb(unsigned int v)
 {
-       lcd_extern_gpio_set(ext_config->spi_cs, v);
-       udelay(SPI_DELAY);
+       lcd_extern_gpio_set(ext_config->spi_gpio_cs, v);
+       udelay(ext_config->spi_delay_us);
 }
 
 static void set_lcd_scl(unsigned int v)
 {
-       lcd_extern_gpio_set(ext_config->spi_clk, v);
-       udelay(SPI_DELAY);
+       lcd_extern_gpio_set(ext_config->spi_gpio_clk, v);
+       udelay(ext_config->spi_delay_us);
 }
 
 static void set_lcd_sda(unsigned int v)
 {
-       lcd_extern_gpio_set(ext_config->spi_data, v);
-       udelay(SPI_DELAY);
+       lcd_extern_gpio_set(ext_config->spi_gpio_data, v);
+       udelay(ext_config->spi_delay_us);
 }
 
 static void spi_gpio_init(void)
@@ -119,7 +119,7 @@ static void spi_write_8(unsigned char addr, unsigned char data)
        set_lcd_csb(1);
        set_lcd_scl(1);
        set_lcd_sda(1);
-       udelay(SPI_DELAY);
+       udelay(ext_config->spi_delay_us);
 }
 
 static int lcd_extern_spi_write(unsigned char *buf, int len)
@@ -132,21 +132,39 @@ static int lcd_extern_spi_write(unsigned char *buf, int len)
        return 0;
 }
 
-static int lcd_extern_power_cmd(unsigned char *init_table)
+static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
 {
-       int i = 0, len;
+       int i = 0, max_len, step = 0;
+       unsigned char cmd_size;
        int ret = 0;
 
-       len = ext_config->cmd_size;
-       if (len < 1) {
-               EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
+       cmd_size = ext_config->cmd_size;
+       if (cmd_size < 1) {
+               EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
+               return -1;
+       }
+       if (cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) {
+               EXTPR("%s: cmd_size dynamic length to do\n", __func__);
+               return -1;
+       }
+       if (init_table == NULL) {
+               EXTERR("%s: init_table %d is NULL\n", __func__, flag);
                return -1;
        }
 
-       while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
-               if (init_table[i] == LCD_EXTERN_INIT_END) {
+       if (flag)
+               max_len = LCD_EXTERN_INIT_ON_MAX;
+       else
+               max_len = LCD_EXTERN_INIT_OFF_MAX;
+
+       while (i <= max_len) {
+               if (init_table[i] == LCD_EXTERN_INIT_END)
                        break;
-               } else if (init_table[i] == LCD_EXTERN_INIT_NONE) {
+               if (lcd_debug_print_flag) {
+                       EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
+                               __func__, step, init_table[i], cmd_size);
+               }
+               if (init_table[i] == LCD_EXTERN_INIT_NONE) {
                        /* do nothing, only for delay */
                } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
                        if (init_table[i+1] < LCD_GPIO_MAX) {
@@ -154,15 +172,17 @@ static int lcd_extern_power_cmd(unsigned char *init_table)
                                        init_table[i+2]);
                        }
                } else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
-                       ret = lcd_extern_spi_write(&init_table[i+1], (len-2));
+                       ret = lcd_extern_spi_write(&init_table[i+1],
+                               (cmd_size-2));
                } else {
                        EXTERR("%s(%d: %s): power_type %d is invalid\n",
                                __func__, ext_config->index,
                                ext_config->name, ext_config->type);
                }
-               if (init_table[i+len-1] > 0)
-                       mdelay(init_table[i+len-1]);
-               i += len;
+               if (init_table[i+cmd_size-1] > 0)
+                       mdelay(init_table[i+cmd_size-1]);
+               step++;
+               i += cmd_size;
        }
 
        return ret;
@@ -174,9 +194,9 @@ static int lcd_extern_power_ctrl(int flag)
 
        spi_gpio_init();
        if (flag)
-               ret = lcd_extern_power_cmd(ext_config->table_init_on);
+               ret = lcd_extern_power_cmd(ext_config->table_init_on, 1);
        else
-               ret = lcd_extern_power_cmd(ext_config->table_init_off);
+               ret = lcd_extern_power_cmd(ext_config->table_init_off, 0);
        mdelay(10);
        spi_gpio_off();
 
@@ -212,6 +232,8 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
                ext_drv->config.table_init_on  = init_on_table;
                ext_drv->config.table_init_off = init_off_table;
        }
+       ext_drv->config.spi_delay_us = SPI_DELAY;
+
        ext_drv->power_on  = lcd_extern_power_on;
        ext_drv->power_off = lcd_extern_power_off;
 
index 6c18502..5d3b676 100644 (file)
@@ -33,25 +33,25 @@ enum lcd_extern_i2c_bus_e {
        LCD_EXTERN_I2C_BUS_D,
        LCD_EXTERN_I2C_BUS_MAX,
 };
-#define LCD_EXTERN_I2C_BUS_INVALID   0xff
+#define LCD_EXTERN_I2C_BUS_INVALID    0xff
 
-#define LCD_EXTERN_SPI_CLK_FREQ_DFT  10000 /* default 10k */
+#define LCD_EXTERN_SPI_CLK_FREQ_DFT   10000 /* default 10k */
 
-#define LCD_EXTERN_INIT_TABLE_MAX    500
+#define LCD_EXTERN_INIT_ON_MAX        500
+#define LCD_EXTERN_INIT_OFF_MAX       100
 
-#define LCD_EXTERN_INIT_CMD          0x00
-#define LCD_EXTERN_INIT_CMD2         0x01  /* only for special i2c device */
-#define LCD_EXTERN_INIT_GPIO         0x10
-#define LCD_EXTERN_INIT_NONE         0xf0
-#define LCD_EXTERN_INIT_END          0xff
+#define LCD_EXTERN_INIT_CMD           0x00
+#define LCD_EXTERN_INIT_CMD2          0x01  /* only for special i2c device */
+#define LCD_EXTERN_INIT_GPIO          0x10
+#define LCD_EXTERN_INIT_NONE          0xf0
+#define LCD_EXTERN_INIT_END           0xff
 
+#define LCD_EXTERN_CMD_SIZE_DYNAMIC   0xff
+#define LCD_EXTERN_DYNAMIC_SIZE_INDEX 1
 
-#define LCD_EXTERN_DYNAMIC_LEN         0xff
-
-
-#define LCD_EXTERN_GPIO_NUM_MAX      6
-#define LCD_EXTERN_INDEX_INVALID     0xff
-#define LCD_EXTERN_NAME_LEN_MAX      30
+#define LCD_EXTERN_GPIO_NUM_MAX       6
+#define LCD_EXTERN_INDEX_INVALID      0xff
+#define LCD_EXTERN_NAME_LEN_MAX       30
 struct lcd_extern_config_s {
        unsigned char index;
        char name[LCD_EXTERN_NAME_LEN_MAX];
@@ -64,6 +64,7 @@ struct lcd_extern_config_s {
        unsigned char spi_gpio_clk;
        unsigned char spi_gpio_data;
        unsigned int spi_clk_freq;
+       unsigned int spi_delay_us;
        unsigned char spi_clk_pol;
        unsigned char cmd_size;
        unsigned char table_init_loaded; /* internal use */