lcd_extern: fix i2c address mistake for dts config

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>
This commit is contained in:
Weiming Liu
2017-08-18 15:47:39 +08:00
committed by Jianxin Pan
parent ef37f7699a
commit cfc3eabe2f
8 changed files with 1007 additions and 565 deletions

View File

@@ -106,6 +106,77 @@
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";

View 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);

View 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)

View 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;
}
static int lcd_extern_power_cmd(unsigned char *init_table)
{
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);
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_fixed_size(unsigned char *init_table, int flag)
{
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;
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);
}
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);
}
if (init_table[i+cmd_size-1] > 0)
mdelay(init_table[i+cmd_size-1]);
i += cmd_size;
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, type, cmd_size);
}
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_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);
}
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 (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);
}
}
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);
}
}
break;
default:
EXTERR("%s(%d: %s): extern_type %d is not support\n",
__func__, ext_config->index,
ext_config->name, ext_config->type);
break;
}
} 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 <= 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 (init_table[i+len-1] > 0)
mdelay(init_table[i+len-1]);
i += len;
}
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 == 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;

View 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);

File diff suppressed because it is too large Load Diff

View 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;

View 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 */